net_tcp_client 2.0.1 → 2.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/README.md +20 -20
- data/Rakefile +10 -17
- data/lib/net/tcp_client/address.rb +11 -6
- data/lib/net/tcp_client/exceptions.rb +3 -3
- data/lib/net/tcp_client/policy/base.rb +0 -1
- data/lib/net/tcp_client/policy/custom.rb +5 -3
- data/lib/net/tcp_client/policy/ordered.rb +1 -2
- data/lib/net/tcp_client/policy/random.rb +1 -2
- data/lib/net/tcp_client/tcp_client.rb +149 -122
- data/lib/net/tcp_client/version.rb +2 -2
- data/lib/net/tcp_client.rb +10 -10
- data/lib/net_tcp_client.rb +1 -1
- metadata +11 -32
- data/test/address_test.rb +0 -91
- data/test/policy/custom_policy_test.rb +0 -42
- data/test/policy/ordered_policy_test.rb +0 -36
- data/test/policy/random_policy_test.rb +0 -46
- data/test/simple_tcp_server.rb +0 -140
- data/test/ssl_files/ca.pem +0 -19
- data/test/ssl_files/localhost-server-key.pem +0 -27
- data/test/ssl_files/localhost-server.pem +0 -18
- data/test/tcp_client_test.rb +0 -245
- data/test/test_helper.rb +0 -14
data/test/tcp_client_test.rb
DELETED
@@ -1,245 +0,0 @@
|
|
1
|
-
require 'socket'
|
2
|
-
require_relative 'test_helper'
|
3
|
-
require_relative 'simple_tcp_server'
|
4
|
-
require 'securerandom'
|
5
|
-
|
6
|
-
# Unit Test for Net::TCPClient
|
7
|
-
class TCPClientTest < Minitest::Test
|
8
|
-
describe Net::TCPClient do
|
9
|
-
[false, true].each do |with_ssl|
|
10
|
-
describe (with_ssl ? 'ssl' : 'non-ssl') do
|
11
|
-
describe '#connect' do
|
12
|
-
it 'raises an exception when cannot reach server after 5 retries' do
|
13
|
-
exception = assert_raises Net::TCPClient::ConnectionFailure do
|
14
|
-
new_net_tcp_client(with_ssl,
|
15
|
-
server: 'localhost:3300',
|
16
|
-
connect_retry_interval: 0.1,
|
17
|
-
connect_retry_count: 5
|
18
|
-
)
|
19
|
-
end
|
20
|
-
assert_match(/Failed to connect to any of localhost:3300 after 5 retries/, exception.message)
|
21
|
-
assert_match Errno::ECONNREFUSED.to_s, exception.cause.class.to_s
|
22
|
-
end
|
23
|
-
|
24
|
-
it 'times out on connect' do
|
25
|
-
# Create a TCP Server, but do not respond to connections
|
26
|
-
server = TCPServer.open(2001)
|
27
|
-
|
28
|
-
exception = assert_raises Net::TCPClient::ConnectionFailure do
|
29
|
-
1000.times do
|
30
|
-
new_net_tcp_client(with_ssl,
|
31
|
-
server: 'localhost:2001',
|
32
|
-
connect_timeout: 0.5,
|
33
|
-
connect_retry_count: 3
|
34
|
-
)
|
35
|
-
end
|
36
|
-
end
|
37
|
-
assert_match(/Failed to connect to any of localhost:2001 after 3 retries/, exception.message)
|
38
|
-
server.close
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
describe 'with server' do
|
43
|
-
before do
|
44
|
-
@port = 2000 + SecureRandom.random_number(1000)
|
45
|
-
options = {port: @port}
|
46
|
-
if with_ssl
|
47
|
-
options[:ssl] = {
|
48
|
-
cert: OpenSSL::X509::Certificate.new(File.open(ssl_file_path('localhost-server.pem'))),
|
49
|
-
key: OpenSSL::PKey::RSA.new(File.open(ssl_file_path('localhost-server-key.pem'))),
|
50
|
-
ca_file: ssl_file_path('ca.pem')
|
51
|
-
}
|
52
|
-
end
|
53
|
-
count = 0
|
54
|
-
begin
|
55
|
-
@server = SimpleTCPServer.new(options)
|
56
|
-
rescue Errno::EADDRINUSE => exc
|
57
|
-
@server.stop if @server
|
58
|
-
# Give previous test server time to stop
|
59
|
-
count += 1
|
60
|
-
sleep 1
|
61
|
-
retry if count <= 30
|
62
|
-
raise exc
|
63
|
-
end
|
64
|
-
|
65
|
-
@server_name = "localhost:#{@port}"
|
66
|
-
end
|
67
|
-
|
68
|
-
after do
|
69
|
-
@client.close if @client
|
70
|
-
@server.stop if @server
|
71
|
-
end
|
72
|
-
|
73
|
-
describe '#read' do
|
74
|
-
it 'read timeout, followed by successful read' do
|
75
|
-
@read_timeout = 3.0
|
76
|
-
# Need a custom client that does not auto close on error:
|
77
|
-
@client = new_net_tcp_client(with_ssl,
|
78
|
-
server: @server_name,
|
79
|
-
read_timeout: @read_timeout,
|
80
|
-
close_on_error: false
|
81
|
-
)
|
82
|
-
|
83
|
-
request = {'action' => 'sleep', 'duration' => @read_timeout + 0.5}
|
84
|
-
@client.write(BSON.serialize(request))
|
85
|
-
|
86
|
-
exception = assert_raises Net::TCPClient::ReadTimeout do
|
87
|
-
# Read 4 bytes from server
|
88
|
-
@client.read(4)
|
89
|
-
end
|
90
|
-
assert_equal false, @client.close_on_error
|
91
|
-
assert @client.alive?, 'The client connection is not alive after the read timed out with close_on_error: false'
|
92
|
-
assert_equal "Timed out after #{@read_timeout} seconds trying to read from localhost[127.0.0.1]:#{@port}", exception.message
|
93
|
-
reply = read_bson_document(@client)
|
94
|
-
assert_equal 'sleep', reply['result']
|
95
|
-
@client.close
|
96
|
-
end
|
97
|
-
|
98
|
-
it 'infinite timeout' do
|
99
|
-
@client = new_net_tcp_client(with_ssl,
|
100
|
-
server: @server_name,
|
101
|
-
connect_timeout: -1
|
102
|
-
)
|
103
|
-
request = {'action' => 'test1'}
|
104
|
-
@client.write(BSON.serialize(request))
|
105
|
-
reply = read_bson_document(@client)
|
106
|
-
assert_equal 'test1', reply['result']
|
107
|
-
@client.close
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
describe '#connect' do
|
112
|
-
it 'calls on_connect after connection' do
|
113
|
-
@client = new_net_tcp_client(with_ssl,
|
114
|
-
server: @server_name,
|
115
|
-
read_timeout: 3,
|
116
|
-
on_connect: Proc.new do |socket|
|
117
|
-
# Reset user_data on each connection
|
118
|
-
socket.user_data = {sequence: 1}
|
119
|
-
end
|
120
|
-
)
|
121
|
-
assert_equal "localhost[127.0.0.1]:#{@port}", @client.address.to_s
|
122
|
-
assert_equal 1, @client.user_data[:sequence]
|
123
|
-
|
124
|
-
request = {'action' => 'test1'}
|
125
|
-
@client.write(BSON.serialize(request))
|
126
|
-
reply = read_bson_document(@client)
|
127
|
-
assert_equal 'test1', reply['result']
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
describe 'failover' do
|
132
|
-
it 'connects to second server when the first is down' do
|
133
|
-
@client = new_net_tcp_client(with_ssl,
|
134
|
-
servers: ['localhost:1999', @server_name],
|
135
|
-
read_timeout: 3
|
136
|
-
)
|
137
|
-
assert_equal "localhost[127.0.0.1]:#{@port}", @client.address.to_s
|
138
|
-
|
139
|
-
request = {'action' => 'test1'}
|
140
|
-
@client.write(BSON.serialize(request))
|
141
|
-
reply = read_bson_document(@client)
|
142
|
-
assert_equal 'test1', reply['result']
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
|
-
describe 'with client' do
|
147
|
-
before do
|
148
|
-
@read_timeout = 3.0
|
149
|
-
@client = new_net_tcp_client(with_ssl,
|
150
|
-
server: @server_name,
|
151
|
-
read_timeout: @read_timeout
|
152
|
-
)
|
153
|
-
assert @client.alive?, @client.ai
|
154
|
-
assert_equal true, @client.close_on_error
|
155
|
-
end
|
156
|
-
|
157
|
-
describe '#alive?' do
|
158
|
-
it 'returns false once the connection is closed' do
|
159
|
-
assert @client.alive?
|
160
|
-
@client.close
|
161
|
-
refute @client.alive?
|
162
|
-
end
|
163
|
-
end
|
164
|
-
|
165
|
-
describe '#closed?' do
|
166
|
-
it 'returns true once the connection is closed' do
|
167
|
-
refute @client.closed?
|
168
|
-
@client.close
|
169
|
-
assert @client.closed?
|
170
|
-
end
|
171
|
-
end
|
172
|
-
|
173
|
-
describe '#close' do
|
174
|
-
it 'closes the connection, repeatedly without error' do
|
175
|
-
@client.close
|
176
|
-
@client.close
|
177
|
-
end
|
178
|
-
end
|
179
|
-
|
180
|
-
describe '#write' do
|
181
|
-
it 'writes data' do
|
182
|
-
request = {'action' => 'test1'}
|
183
|
-
@client.write(BSON.serialize(request))
|
184
|
-
end
|
185
|
-
end
|
186
|
-
|
187
|
-
describe '#read' do
|
188
|
-
it 'reads a response' do
|
189
|
-
request = {'action' => 'test1'}
|
190
|
-
@client.write(BSON.serialize(request))
|
191
|
-
reply = read_bson_document(@client)
|
192
|
-
assert_equal 'test1', reply['result']
|
193
|
-
end
|
194
|
-
|
195
|
-
it 'times out on receive' do
|
196
|
-
request = {'action' => 'sleep', 'duration' => @read_timeout + 0.5}
|
197
|
-
@client.write(BSON.serialize(request))
|
198
|
-
|
199
|
-
exception = assert_raises Net::TCPClient::ReadTimeout do
|
200
|
-
# Read 4 bytes from server
|
201
|
-
@client.read(4)
|
202
|
-
end
|
203
|
-
# Due to close_on_error: true, a timeout will close the connection
|
204
|
-
# to prevent use of a socket connection in an inconsistent state
|
205
|
-
assert_equal false, @client.alive?
|
206
|
-
assert_equal "Timed out after #{@read_timeout} seconds trying to read from localhost[127.0.0.1]:#{@port}", exception.message
|
207
|
-
end
|
208
|
-
end
|
209
|
-
|
210
|
-
describe '#retry_on_connection_failure' do
|
211
|
-
it 'retries on connection failure' do
|
212
|
-
attempt = 0
|
213
|
-
reply = @client.retry_on_connection_failure do
|
214
|
-
request = {'action' => 'fail', 'attempt' => (attempt+=1)}
|
215
|
-
@client.write(BSON.serialize(request))
|
216
|
-
read_bson_document(@client)
|
217
|
-
end
|
218
|
-
assert_equal 'fail', reply['result']
|
219
|
-
end
|
220
|
-
end
|
221
|
-
end
|
222
|
-
end
|
223
|
-
end
|
224
|
-
|
225
|
-
end
|
226
|
-
|
227
|
-
def ssl_file_path(name)
|
228
|
-
File.join(File.dirname(__FILE__), 'ssl_files', name)
|
229
|
-
end
|
230
|
-
|
231
|
-
def new_net_tcp_client(with_ssl, params)
|
232
|
-
params = params.dup
|
233
|
-
if with_ssl
|
234
|
-
params.merge!(
|
235
|
-
ssl: {
|
236
|
-
ca_file: ssl_file_path('ca.pem'),
|
237
|
-
verify_mode: OpenSSL::SSL::VERIFY_NONE
|
238
|
-
}
|
239
|
-
)
|
240
|
-
end
|
241
|
-
Net::TCPClient.new(params)
|
242
|
-
end
|
243
|
-
|
244
|
-
end
|
245
|
-
end
|
data/test/test_helper.rb
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
# Allow test to be run in-place without requiring a gem install
|
2
|
-
$LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
|
3
|
-
|
4
|
-
# Configure Rails Environment
|
5
|
-
ENV['RAILS_ENV'] = 'test'
|
6
|
-
|
7
|
-
require 'minitest/autorun'
|
8
|
-
require 'minitest/reporters'
|
9
|
-
require 'net/tcp_client'
|
10
|
-
|
11
|
-
Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new
|
12
|
-
|
13
|
-
SemanticLogger.default_level = :trace
|
14
|
-
SemanticLogger.add_appender(file_name: 'test.log', formatter: :color)
|