rs
1# frozen_string_literal: true
2
3require 'test_helper'
4
5class ErrorHandlingTest < Minitest::Test
6 def setup
7 @client = Net::Hippie::Client.new
8 @uri = URI.parse('https://example.com/test')
9 end
10
11 def test_handles_eof_error
12 WebMock.stub_request(:get, @uri.to_s).to_raise(EOFError)
13
14 assert_raises EOFError do
15 @client.with_retry(retries: 0) { |client| client.get(@uri) }
16 end
17 end
18
19 def test_handles_connection_refused
20 WebMock.stub_request(:get, @uri.to_s).to_raise(Errno::ECONNREFUSED)
21
22 assert_raises Errno::ECONNREFUSED do
23 @client.with_retry(retries: 0) { |client| client.get(@uri) }
24 end
25 end
26
27 def test_handles_connection_reset
28 WebMock.stub_request(:get, @uri.to_s).to_raise(Errno::ECONNRESET)
29
30 assert_raises Errno::ECONNRESET do
31 @client.with_retry(retries: 0) { |client| client.get(@uri) }
32 end
33 end
34
35 def test_handles_host_unreachable
36 WebMock.stub_request(:get, @uri.to_s).to_raise(Errno::EHOSTUNREACH)
37
38 assert_raises Errno::EHOSTUNREACH do
39 @client.with_retry(retries: 0) { |client| client.get(@uri) }
40 end
41 end
42
43 def test_handles_invalid_argument
44 WebMock.stub_request(:get, @uri.to_s).to_raise(Errno::EINVAL)
45
46 assert_raises Errno::EINVAL do
47 @client.with_retry(retries: 0) { |client| client.get(@uri) }
48 end
49 end
50
51 def test_handles_net_open_timeout
52 WebMock.stub_request(:get, @uri.to_s).to_raise(Net::OpenTimeout)
53
54 assert_raises Net::OpenTimeout do
55 @client.with_retry(retries: 0) { |client| client.get(@uri) }
56 end
57 end
58
59 def test_handles_net_protocol_error
60 WebMock.stub_request(:get, @uri.to_s).to_raise(Net::ProtocolError)
61
62 assert_raises Net::ProtocolError do
63 @client.with_retry(retries: 0) { |client| client.get(@uri) }
64 end
65 end
66
67 def test_handles_net_read_timeout
68 WebMock.stub_request(:get, @uri.to_s).to_raise(Net::ReadTimeout)
69
70 assert_raises Net::ReadTimeout do
71 @client.with_retry(retries: 0) { |client| client.get(@uri) }
72 end
73 end
74
75 def test_handles_openssl_error
76 WebMock.stub_request(:get, @uri.to_s).to_raise(OpenSSL::OpenSSLError)
77
78 assert_raises OpenSSL::OpenSSLError do
79 @client.with_retry(retries: 0) { |client| client.get(@uri) }
80 end
81 end
82
83 def test_handles_ssl_error
84 WebMock.stub_request(:get, @uri.to_s).to_raise(OpenSSL::SSL::SSLError)
85
86 assert_raises OpenSSL::SSL::SSLError do
87 @client.with_retry(retries: 0) { |client| client.get(@uri) }
88 end
89 end
90
91 def test_handles_socket_error
92 WebMock.stub_request(:get, @uri.to_s).to_raise(SocketError)
93
94 assert_raises SocketError do
95 @client.with_retry(retries: 0) { |client| client.get(@uri) }
96 end
97 end
98
99 def test_handles_timeout_error
100 WebMock.stub_request(:get, @uri.to_s).to_raise(Timeout::Error)
101
102 assert_raises Timeout::Error do
103 @client.with_retry(retries: 0) { |client| client.get(@uri) }
104 end
105 end
106
107 def test_retry_with_exponential_backoff
108 call_count = 0
109 WebMock.stub_request(:get, @uri.to_s).to_return do
110 call_count += 1
111 if call_count < 3
112 raise Net::ReadTimeout
113 else
114 { status: 200, body: 'success' }
115 end
116 end
117
118 start_time = Time.now
119 response = @client.with_retry(retries: 3) { |client| client.get(@uri) }
120 end_time = Time.now
121
122 assert_equal Net::HTTPOK, response.class
123 assert_equal 'success', response.body
124 assert_equal 3, call_count
125 # Should have some delay due to exponential backoff
126 assert_operator end_time - start_time, :>, 0.3
127 end
128
129 def test_retry_eventually_fails_after_max_retries
130 WebMock.stub_request(:get, @uri.to_s).to_raise(Net::ReadTimeout)
131
132 start_time = Time.now
133
134 assert_raises Net::ReadTimeout do
135 @client.with_retry(retries: 2) { |client| client.get(@uri) }
136 end
137
138 end_time = Time.now
139 # Should have attempted 3 times (initial + 2 retries) with delays
140 assert_operator end_time - start_time, :>, 0.3
141 end
142
143 def test_retry_with_nil_retries
144 WebMock.stub_request(:get, @uri.to_s).to_raise(Net::ReadTimeout)
145
146 assert_raises Net::ReadTimeout do
147 @client.with_retry(retries: nil) { |client| client.get(@uri) }
148 end
149 end
150
151 def test_retry_with_negative_retries
152 WebMock.stub_request(:get, @uri.to_s).to_raise(Net::ReadTimeout)
153
154 assert_raises Net::ReadTimeout do
155 @client.with_retry(retries: -1) { |client| client.get(@uri) }
156 end
157 end
158
159 def test_connection_errors_constant_includes_all_expected_errors
160 expected_errors = [
161 EOFError,
162 Errno::ECONNREFUSED,
163 Errno::ECONNRESET,
164 Errno::ECONNRESET, # Listed twice in original
165 Errno::EHOSTUNREACH,
166 Errno::EINVAL,
167 Net::OpenTimeout,
168 Net::ProtocolError,
169 Net::ReadTimeout,
170 OpenSSL::OpenSSLError,
171 OpenSSL::SSL::SSLError,
172 SocketError,
173 Timeout::Error
174 ]
175
176 expected_errors.each do |error_class|
177 assert_includes Net::Hippie::CONNECTION_ERRORS, error_class
178 end
179 end
180end