rs
1# frozen_string_literal: true
2
3require 'test_helper'
4
5class TimeoutTest < Minitest::Test
6 def setup
7 @uri = URI.parse('https://example.com/test')
8 end
9
10 def test_custom_read_timeout
11 client = Net::Hippie::Client.new(read_timeout: 5)
12 connection = client.send(:connection_for, @uri)
13 backend = connection.instance_variable_get(:@backend)
14 http = backend.instance_variable_get(:@http)
15 assert_equal 5, http.read_timeout
16 end
17
18 def test_custom_open_timeout
19 client = Net::Hippie::Client.new(open_timeout: 8)
20 connection = client.send(:connection_for, @uri)
21 backend = connection.instance_variable_get(:@backend)
22 http = backend.instance_variable_get(:@http)
23 assert_equal 8, http.open_timeout
24 end
25
26 def test_default_timeouts
27 client = Net::Hippie::Client.new
28 connection = client.send(:connection_for, @uri)
29 backend = connection.instance_variable_get(:@backend)
30 http = backend.instance_variable_get(:@http)
31 assert_equal 10, http.read_timeout
32 assert_equal 10, http.open_timeout
33 end
34
35 def test_read_timeout_triggers_retry
36 WebMock.stub_request(:get, @uri.to_s)
37 .to_timeout.then
38 .to_return(status: 200, body: 'success')
39
40 client = Net::Hippie::Client.new
41 response = client.with_retry(retries: 1) { |c| c.get(@uri) }
42
43 assert_equal Net::HTTPOK, response.class
44 assert_equal 'success', response.body
45 end
46
47 def test_open_timeout_triggers_retry
48 WebMock.stub_request(:get, @uri.to_s)
49 .to_raise(Net::OpenTimeout).then
50 .to_return(status: 200, body: 'success')
51
52 client = Net::Hippie::Client.new
53 response = client.with_retry(retries: 1) { |c| c.get(@uri) }
54
55 assert_equal Net::HTTPOK, response.class
56 assert_equal 'success', response.body
57 end
58
59 def test_timeout_with_zero_retries
60 WebMock.stub_request(:get, @uri.to_s).to_timeout
61
62 client = Net::Hippie::Client.new
63 # WebMock.to_timeout raises different timeout errors, so check for any timeout error
64 assert_raises(*Net::Hippie::CONNECTION_ERRORS.select { |e| e.name.include?('Timeout') }) do
65 client.with_retry(retries: 0) { |c| c.get(@uri) }
66 end
67 end
68
69 def test_multiple_timeout_types_in_sequence
70 call_count = 0
71 WebMock.stub_request(:get, @uri.to_s).to_return do
72 call_count += 1
73 case call_count
74 when 1
75 raise Net::OpenTimeout
76 when 2
77 raise Net::ReadTimeout
78 when 3
79 raise Timeout::Error
80 else
81 { status: 200, body: 'success' }
82 end
83 end
84
85 client = Net::Hippie::Client.new
86 response = client.with_retry(retries: 4) { |c| c.get(@uri) }
87
88 assert_equal Net::HTTPOK, response.class
89 assert_equal 'success', response.body
90 assert_equal 4, call_count
91 end
92
93 def test_timeout_settings_per_connection
94 uri1 = URI.parse('https://example1.com/test')
95 uri2 = URI.parse('https://example2.com/test')
96
97 client = Net::Hippie::Client.new(read_timeout: 15, open_timeout: 20)
98
99 connection1 = client.send(:connection_for, uri1)
100 connection2 = client.send(:connection_for, uri2)
101
102 backend1 = connection1.instance_variable_get(:@backend)
103 backend2 = connection2.instance_variable_get(:@backend)
104 http1 = backend1.instance_variable_get(:@http)
105 http2 = backend2.instance_variable_get(:@http)
106
107 assert_equal 15, http1.read_timeout
108 assert_equal 20, http1.open_timeout
109 assert_equal 15, http2.read_timeout
110 assert_equal 20, http2.open_timeout
111 end
112
113 def test_timeout_preserves_connection_pooling
114 client = Net::Hippie::Client.new(read_timeout: 25)
115
116 # First call should create connection
117 connection1 = client.send(:connection_for, @uri)
118 # Second call should reuse same connection
119 connection2 = client.send(:connection_for, @uri)
120
121 assert_same connection1, connection2
122
123 backend = connection1.instance_variable_get(:@backend)
124 http = backend.instance_variable_get(:@http)
125 assert_equal 25, http.read_timeout
126 end
127end