Skip to content

Commit 1de252d

Browse files
committed
Merge code
2 parents 9dfe69d + e163b60 commit 1de252d

File tree

3 files changed

+210
-21
lines changed

3 files changed

+210
-21
lines changed

config/initializers/okcomputer.rb

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# frozen_string_literal: true
22

3+
require 'net/smtp'
4+
35
# Health check configuration
46
require 'berkeley_library/util/uris/head_check'
57

@@ -19,6 +21,44 @@ def check
1921
end
2022
end
2123

24+
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize
25+
class MailConnectivityCheck < OkComputer::Check
26+
27+
# Check that the mail password is set
28+
def check
29+
settings = ActionMailer::Base.smtp_settings
30+
begin
31+
Net::SMTP.start(
32+
settings[:address],
33+
settings[:port],
34+
settings[:domain],
35+
settings[:user_name],
36+
settings[:password],
37+
settings[:authentication],
38+
tls: true
39+
) { mark_message 'Connection for smtp successful' }
40+
rescue Net::SMTPAuthenticationError => e
41+
mark_failure
42+
Rails.logger.warn "SMTP authentication error: #{e}"
43+
mark_message 'SMTP Error: Authentication failed. Check logs for more details'
44+
rescue Net::SMTPServerBusy, Net::SMTPSyntaxError, Net::SMTPFatalError, Net::SMTPUnknownError => e
45+
mark_failure
46+
Rails.logger.warn "SMTP Error: #{e}"
47+
mark_message 'SMTP error. Check logs for more details'
48+
rescue IOError, Net::ReadTimeout => e
49+
mark_failure
50+
Rails.logger.warn "SMTP Timeout: #{e}"
51+
mark_message 'SMTP Connection error: Timeout. Check logs for more details'
52+
rescue StandardError => e
53+
# Catch any other unexpected errors
54+
mark_failure
55+
Rails.logger.warn "SMTP standard error: #{e}"
56+
mark_message 'SMTP ERROR: Could not connect. Check logs for more details'
57+
end
58+
end
59+
end
60+
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize
61+
2262
# Ensure Alma API is working.
2363
OkComputer::Registry.register 'alma-patron-lookup', AlmaPatronCheck.new
2464

@@ -45,3 +85,5 @@ def check
4585
OkComputer::Registry.register 'paypal-payflow', OkComputer::HttpCheck.new(Rails.application.config.paypal_payflow_url)
4686

4787
# Since the WorldCat API service requests dynamically generated OCLC tokens, we are not doing a health check for it.
88+
# Ensure SMTP can connect
89+
OkComputer::Registry.register 'mail-connectivity', MailConnectivityCheck.new if ActionMailer::Base.delivery_method == :smtp
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
require 'rails_helper'
2+
require 'net/smtp'
3+
4+
RSpec.describe MailConnectivityCheck do
5+
subject(:check) { described_class.new }
6+
7+
let(:smtp_settings) do
8+
{
9+
address: 'smtp.example.com',
10+
port: 587,
11+
domain: 'example.com',
12+
user_name: 'user',
13+
password: 'password',
14+
authentication: 'plain',
15+
tls: true
16+
}
17+
end
18+
19+
before do
20+
allow(ActionMailer::Base).to receive(:smtp_settings).and_return(smtp_settings)
21+
allow(Rails.logger).to receive(:warn)
22+
end
23+
24+
describe '#check' do
25+
context 'when SMTP connection succeeds' do
26+
before do
27+
allow(Net::SMTP).to receive(:start).and_yield
28+
end
29+
30+
it 'marks the check as successful' do
31+
check.check
32+
33+
expect(check.success?).to be(true)
34+
expect(check.message).to eq('Connection for smtp successful')
35+
end
36+
end
37+
38+
context 'when authentication fails' do
39+
before do
40+
allow(Net::SMTP).to receive(:start)
41+
.and_raise(Net::SMTPAuthenticationError.new('auth failed'))
42+
end
43+
44+
it 'marks failure and logs authentication error' do
45+
check.check
46+
47+
expect(check.success?).to be(false)
48+
expect(check.message)
49+
.to eq('SMTP Error: Authentication failed. Check logs for more details')
50+
expect(Rails.logger)
51+
.to have_received(:warn).with(/SMTP authentication error/)
52+
end
53+
end
54+
55+
context 'when SMTP protocol errors occur' do
56+
[
57+
Net::SMTPServerBusy,
58+
Net::SMTPSyntaxError,
59+
Net::SMTPFatalError,
60+
Net::SMTPUnknownError
61+
].each do |error_class|
62+
it "handles #{error_class.name}" do
63+
allow(Net::SMTP).to receive(:start)
64+
.and_raise(error_class.new('smtp error'))
65+
66+
check.check
67+
68+
expect(check.success?).to be(false)
69+
expect(check.message)
70+
.to eq('SMTP error. Check logs for more details')
71+
expect(Rails.logger)
72+
.to have_received(:warn).with(/SMTP Error/)
73+
end
74+
end
75+
end
76+
77+
context 'when a timeout occurs' do
78+
[IOError, Net::ReadTimeout].each do |error_class|
79+
it "handles #{error_class.name}" do
80+
allow(Net::SMTP).to receive(:start)
81+
.and_raise(error_class.new('timeout'))
82+
83+
check.check
84+
85+
expect(check.success?).to be(false)
86+
expect(check.message)
87+
.to eq('SMTP Connection error: Timeout. Check logs for more details')
88+
expect(Rails.logger)
89+
.to have_received(:warn).with(/SMTP Timeout/)
90+
end
91+
end
92+
end
93+
94+
context 'when an unexpected error occurs' do
95+
before do
96+
allow(Net::SMTP).to receive(:start)
97+
.and_raise(StandardError.new('failed'))
98+
end
99+
100+
it 'marks failure and logs standard error' do
101+
check.check
102+
103+
expect(check.success?).to be(false)
104+
expect(check.message)
105+
.to eq('SMTP ERROR: Could not connect. Check logs for more details')
106+
expect(Rails.logger)
107+
.to have_received(:warn).with(/SMTP standard error/)
108+
end
109+
end
110+
end
111+
end

spec/request/okcomputer_spec.rb

Lines changed: 57 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -16,28 +16,64 @@
1616
expect(response).to have_http_status :ok
1717
end
1818

19-
it 'returns all checks to /health' do
20-
21-
get '/health'
22-
expect(response.parsed_body.keys).to match_array %w[
23-
action-mailer
24-
alma-patron-lookup
25-
default
26-
database
27-
database-migrations
28-
thind-api
29-
whois-arin-api
30-
paypal-payflow
31-
hathitrust-api
32-
berkeley-service-now
33-
]
34-
pending 'https://github.com/emmahsax/okcomputer/pull/21'
35-
expect(response).to have_http_status :ok
19+
context 'without SMTP enabled' do
20+
before do
21+
allow(ActionMailer::Base).to receive(:delivery_method).and_return(:test)
22+
23+
OkComputer::Registry.instance_variable_set(:@checks, {})
24+
load Rails.root.join('config/initializers/okcomputer.rb')
25+
end
26+
27+
it 'returns checks to /health' do
28+
get '/health'
29+
expect(response.parsed_body.keys).to match_array %w[
30+
default
31+
database
32+
alma-patron-lookup
33+
database-migrations
34+
thind-api
35+
whois-arin-api
36+
paypal-payflow
37+
hathitrust-api
38+
berkeley-service-now
39+
action-mailer
40+
]
41+
end
42+
end
43+
44+
context 'with SMTP enabled' do
45+
before do
46+
allow(ActionMailer::Base).to receive(:delivery_method).and_return(:smtp)
47+
allow(Net::SMTP).to receive(:start)
48+
49+
OkComputer::Registry.instance_variable_set(:@checks, {})
50+
load Rails.root.join('config/initializers/okcomputer.rb')
51+
end
52+
53+
it 'returns all checks to /health' do
54+
get '/health'
55+
expect(response.parsed_body.keys).to match_array %w[
56+
default
57+
database
58+
alma-patron-lookup
59+
database-migrations
60+
thind-api
61+
whois-arin-api
62+
paypal-payflow
63+
hathitrust-api
64+
berkeley-service-now
65+
mail-connectivity
66+
action-mailer
67+
]
68+
end
3669
end
3770

38-
it 'fails when Alma lookups fail' do
39-
expect(Alma::User).to receive(:find).and_raise('Uh oh!')
40-
get '/health'
41-
expect(response).not_to have_http_status :ok
71+
context 'when Alma lookups fail' do
72+
it 'returns a non-200 response' do
73+
expect(Alma::User).to receive(:find).and_raise('Uh oh!')
74+
get '/health'
75+
expect(response).not_to have_http_status :ok
76+
end
4277
end
78+
4379
end

0 commit comments

Comments
 (0)