fluentd 0.14.7-x64-mingw32 → 0.14.10-x64-mingw32
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of fluentd might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/.travis.yml +2 -0
- data/CONTRIBUTING.md +6 -1
- data/ChangeLog +95 -0
- data/Rakefile +21 -0
- data/appveyor.yml +1 -0
- data/code-of-conduct.md +3 -0
- data/example/out_exec_filter.conf +42 -0
- data/fluentd.gemspec +1 -1
- data/lib/fluent/agent.rb +2 -2
- data/lib/fluent/command/binlog_reader.rb +1 -1
- data/lib/fluent/command/cat.rb +15 -4
- data/lib/fluent/compat/output.rb +14 -9
- data/lib/fluent/compat/parser.rb +141 -11
- data/lib/fluent/config/configure_proxy.rb +2 -11
- data/lib/fluent/config/section.rb +8 -1
- data/lib/fluent/configurable.rb +1 -3
- data/lib/fluent/env.rb +1 -1
- data/lib/fluent/log.rb +1 -1
- data/lib/fluent/plugin/base.rb +17 -0
- data/lib/fluent/plugin/filter_parser.rb +108 -0
- data/lib/fluent/plugin/filter_record_transformer.rb +14 -35
- data/lib/fluent/plugin/filter_stdout.rb +1 -1
- data/lib/fluent/plugin/formatter.rb +5 -0
- data/lib/fluent/plugin/formatter_msgpack.rb +4 -0
- data/lib/fluent/plugin/formatter_stdout.rb +3 -2
- data/lib/fluent/plugin/formatter_tsv.rb +34 -0
- data/lib/fluent/plugin/in_exec.rb +48 -93
- data/lib/fluent/plugin/in_forward.rb +66 -265
- data/lib/fluent/plugin/in_http.rb +68 -65
- data/lib/fluent/plugin/in_monitor_agent.rb +8 -4
- data/lib/fluent/plugin/in_syslog.rb +42 -58
- data/lib/fluent/plugin/in_tail.rb +29 -14
- data/lib/fluent/plugin/in_tcp.rb +54 -14
- data/lib/fluent/plugin/in_udp.rb +49 -13
- data/lib/fluent/plugin/multi_output.rb +1 -3
- data/lib/fluent/plugin/out_exec.rb +58 -71
- data/lib/fluent/plugin/out_exec_filter.rb +199 -279
- data/lib/fluent/plugin/out_file.rb +172 -81
- data/lib/fluent/plugin/out_forward.rb +229 -206
- data/lib/fluent/plugin/out_stdout.rb +6 -21
- data/lib/fluent/plugin/output.rb +90 -59
- data/lib/fluent/plugin/parser.rb +121 -61
- data/lib/fluent/plugin/parser_csv.rb +9 -3
- data/lib/fluent/plugin/parser_json.rb +37 -35
- data/lib/fluent/plugin/parser_ltsv.rb +11 -19
- data/lib/fluent/plugin/parser_msgpack.rb +50 -0
- data/lib/fluent/plugin/parser_regexp.rb +15 -42
- data/lib/fluent/plugin/parser_tsv.rb +8 -3
- data/lib/fluent/plugin_helper.rb +10 -1
- data/lib/fluent/plugin_helper/child_process.rb +139 -73
- data/lib/fluent/plugin_helper/compat_parameters.rb +93 -4
- data/lib/fluent/plugin_helper/event_emitter.rb +14 -1
- data/lib/fluent/plugin_helper/event_loop.rb +24 -6
- data/lib/fluent/plugin_helper/extract.rb +16 -4
- data/lib/fluent/plugin_helper/formatter.rb +9 -11
- data/lib/fluent/plugin_helper/inject.rb +16 -1
- data/lib/fluent/plugin_helper/parser.rb +3 -3
- data/lib/fluent/plugin_helper/server.rb +494 -0
- data/lib/fluent/plugin_helper/socket.rb +101 -0
- data/lib/fluent/plugin_helper/socket_option.rb +84 -0
- data/lib/fluent/plugin_helper/timer.rb +1 -0
- data/lib/fluent/root_agent.rb +1 -1
- data/lib/fluent/test/driver/base.rb +95 -49
- data/lib/fluent/test/driver/base_owner.rb +18 -8
- data/lib/fluent/test/driver/multi_output.rb +2 -1
- data/lib/fluent/test/driver/output.rb +29 -6
- data/lib/fluent/test/helpers.rb +3 -1
- data/lib/fluent/test/log.rb +4 -0
- data/lib/fluent/test/startup_shutdown.rb +13 -0
- data/lib/fluent/time.rb +14 -8
- data/lib/fluent/version.rb +1 -1
- data/lib/fluent/winsvc.rb +1 -1
- data/test/command/test_binlog_reader.rb +5 -1
- data/test/compat/test_parser.rb +10 -0
- data/test/config/test_configurable.rb +193 -0
- data/test/config/test_configure_proxy.rb +0 -43
- data/test/helper.rb +36 -1
- data/test/plugin/test_base.rb +16 -0
- data/test/plugin/test_filter_parser.rb +665 -0
- data/test/plugin/test_filter_record_transformer.rb +36 -100
- data/test/plugin/test_filter_stdout.rb +18 -27
- data/test/plugin/test_in_dummy.rb +1 -1
- data/test/plugin/test_in_exec.rb +206 -94
- data/test/plugin/test_in_forward.rb +268 -347
- data/test/plugin/test_in_http.rb +310 -186
- data/test/plugin/test_in_monitor_agent.rb +65 -35
- data/test/plugin/test_in_syslog.rb +39 -3
- data/test/plugin/test_in_tcp.rb +78 -62
- data/test/plugin/test_in_udp.rb +101 -80
- data/test/plugin/test_out_exec.rb +223 -68
- data/test/plugin/test_out_exec_filter.rb +520 -169
- data/test/plugin/test_out_file.rb +637 -177
- data/test/plugin/test_out_forward.rb +242 -234
- data/test/plugin/test_out_null.rb +1 -1
- data/test/plugin/test_out_secondary_file.rb +4 -2
- data/test/plugin/test_out_stdout.rb +14 -35
- data/test/plugin/test_output_as_buffered.rb +60 -2
- data/test/plugin/test_parser.rb +359 -0
- data/test/plugin/test_parser_csv.rb +1 -2
- data/test/plugin/test_parser_json.rb +3 -4
- data/test/plugin/test_parser_labeled_tsv.rb +1 -2
- data/test/plugin/test_parser_none.rb +1 -2
- data/test/plugin/test_parser_regexp.rb +8 -4
- data/test/plugin/test_parser_tsv.rb +4 -3
- data/test/plugin_helper/test_child_process.rb +184 -0
- data/test/plugin_helper/test_compat_parameters.rb +88 -1
- data/test/plugin_helper/test_extract.rb +0 -1
- data/test/plugin_helper/test_formatter.rb +5 -2
- data/test/plugin_helper/test_inject.rb +21 -0
- data/test/plugin_helper/test_parser.rb +6 -5
- data/test/plugin_helper/test_server.rb +905 -0
- data/test/test_event_time.rb +3 -1
- data/test/test_output.rb +53 -2
- data/test/test_plugin_classes.rb +20 -0
- data/test/test_root_agent.rb +139 -0
- data/test/test_test_drivers.rb +135 -0
- metadata +28 -8
- data/test/plugin/test_parser_base.rb +0 -32
@@ -28,6 +28,9 @@ class ParserHelperTest < Test::Unit::TestCase
|
|
28
28
|
end
|
29
29
|
class Dummy < Fluent::Plugin::TestBase
|
30
30
|
helpers :parser
|
31
|
+
config_section :parse do
|
32
|
+
config_set_default :@type, 'example'
|
33
|
+
end
|
31
34
|
end
|
32
35
|
|
33
36
|
class Dummy2 < Fluent::Plugin::TestBase
|
@@ -88,12 +91,10 @@ class ParserHelperTest < Test::Unit::TestCase
|
|
88
91
|
end
|
89
92
|
end
|
90
93
|
|
91
|
-
test 'can be configured without parse sections' do
|
94
|
+
test 'can be configured with default type without parse sections' do
|
92
95
|
d = Dummy.new
|
93
|
-
|
94
|
-
|
95
|
-
end
|
96
|
-
assert_equal 0, d._parsers.size
|
96
|
+
d.configure(config_element())
|
97
|
+
assert_equal 1, d._parsers.size
|
97
98
|
end
|
98
99
|
|
99
100
|
test 'can be configured with a parse section' do
|
@@ -0,0 +1,905 @@
|
|
1
|
+
require_relative '../helper'
|
2
|
+
require 'fluent/plugin_helper/server'
|
3
|
+
require 'fluent/plugin/base'
|
4
|
+
require 'timeout'
|
5
|
+
|
6
|
+
require 'serverengine'
|
7
|
+
require 'fileutils'
|
8
|
+
|
9
|
+
class ServerPluginHelperTest < Test::Unit::TestCase
|
10
|
+
class Dummy < Fluent::Plugin::TestBase
|
11
|
+
helpers :server
|
12
|
+
end
|
13
|
+
|
14
|
+
PORT = unused_port
|
15
|
+
|
16
|
+
setup do
|
17
|
+
@socket_manager_path = ServerEngine::SocketManager::Server.generate_path
|
18
|
+
if @socket_manager_path.is_a?(String) && File.exist?(@socket_manager_path)
|
19
|
+
FileUtils.rm_f @socket_manager_path
|
20
|
+
end
|
21
|
+
@socket_manager_server = ServerEngine::SocketManager::Server.open(@socket_manager_path)
|
22
|
+
ENV['SERVERENGINE_SOCKETMANAGER_PATH'] = @socket_manager_path.to_s
|
23
|
+
|
24
|
+
@d = Dummy.new
|
25
|
+
@d.start
|
26
|
+
@d.after_start
|
27
|
+
end
|
28
|
+
|
29
|
+
teardown do
|
30
|
+
@d.stopped? || @d.stop
|
31
|
+
@d.before_shutdown? || @d.before_shutdown
|
32
|
+
@d.shutdown? || @d.shutdown
|
33
|
+
@d.after_shutdown? || @d.after_shutdown
|
34
|
+
@d.closed? || @d.close
|
35
|
+
@d.terminated? || @d.terminate
|
36
|
+
|
37
|
+
@socket_manager_server.close
|
38
|
+
if @socket_manager_server.is_a?(String) && File.exist?(@socket_manager_path)
|
39
|
+
FileUtils.rm_f @socket_manager_path
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
sub_test_case 'plugin instance' do
|
44
|
+
test 'can be instantiated to be able to create threads' do
|
45
|
+
d = Dummy.new
|
46
|
+
assert d.respond_to?(:_servers)
|
47
|
+
assert d._servers.empty?
|
48
|
+
|
49
|
+
assert d.respond_to?(:server_wait_until_start)
|
50
|
+
assert d.respond_to?(:server_wait_until_stop)
|
51
|
+
assert d.respond_to?(:server_create_connection)
|
52
|
+
assert d.respond_to?(:server_create)
|
53
|
+
assert d.respond_to?(:server_create_tcp)
|
54
|
+
assert d.respond_to?(:server_create_udp)
|
55
|
+
assert d.respond_to?(:server_create_tls)
|
56
|
+
end
|
57
|
+
|
58
|
+
test 'can be configured' do
|
59
|
+
d = Dummy.new
|
60
|
+
assert_nothing_raised do
|
61
|
+
d.configure(config_element())
|
62
|
+
end
|
63
|
+
assert d.plugin_id
|
64
|
+
assert d.log
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# run tests for tcp, udp, tls and unix
|
69
|
+
sub_test_case '#server_create and #server_create_connection' do
|
70
|
+
methods = {server_create: :server_create, server_create_connection: :server_create_connection}
|
71
|
+
|
72
|
+
data(methods)
|
73
|
+
test 'raise error if title is not specified or not a symbol' do |m|
|
74
|
+
assert_raise(ArgumentError.new("BUG: title must be a symbol")) do
|
75
|
+
@d.__send__(m, nil, PORT){|x| x }
|
76
|
+
end
|
77
|
+
assert_raise(ArgumentError.new("BUG: title must be a symbol")) do
|
78
|
+
@d.__send__(m, "", PORT){|x| x }
|
79
|
+
end
|
80
|
+
assert_raise(ArgumentError.new("BUG: title must be a symbol")) do
|
81
|
+
@d.__send__(m, "title", PORT){|x| x }
|
82
|
+
end
|
83
|
+
assert_nothing_raised do
|
84
|
+
@d.__send__(m, :myserver, PORT){|x| x }
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
data(methods)
|
89
|
+
test 'raise error if port is not specified or not an integer' do |m|
|
90
|
+
assert_raise(ArgumentError.new("BUG: port must be an integer")) do
|
91
|
+
@d.__send__(m, :myserver, nil){|x| x }
|
92
|
+
end
|
93
|
+
assert_raise(ArgumentError.new("BUG: port must be an integer")) do
|
94
|
+
@d.__send__(m, :myserver, "1"){|x| x }
|
95
|
+
end
|
96
|
+
assert_raise(ArgumentError.new("BUG: port must be an integer")) do
|
97
|
+
@d.__send__(m, :myserver, 1.5){|x| x }
|
98
|
+
end
|
99
|
+
assert_nothing_raised do
|
100
|
+
@d.__send__(m, :myserver, PORT){|x| x }
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
data(methods)
|
105
|
+
test 'raise error if block is not specified' do |m|
|
106
|
+
assert_raise(ArgumentError) do
|
107
|
+
@d.__send__(m, :myserver, PORT)
|
108
|
+
end
|
109
|
+
assert_nothing_raised do
|
110
|
+
@d.__send__(m, :myserver, PORT){|x| x }
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
data(methods)
|
115
|
+
test 'creates tcp server, binds 0.0.0.0 in default' do |m|
|
116
|
+
@d.__send__(m, :myserver, PORT){|x| x }
|
117
|
+
|
118
|
+
assert_equal 1, @d._servers.size
|
119
|
+
|
120
|
+
created_server_info = @d._servers.first
|
121
|
+
|
122
|
+
assert_equal :myserver, created_server_info.title
|
123
|
+
assert_equal PORT, created_server_info.port
|
124
|
+
|
125
|
+
assert_equal :tcp, created_server_info.proto
|
126
|
+
assert_equal "0.0.0.0", created_server_info.bind
|
127
|
+
|
128
|
+
created_server = created_server_info.server
|
129
|
+
|
130
|
+
assert created_server.is_a?(Coolio::TCPServer)
|
131
|
+
assert_equal "0.0.0.0", created_server.instance_eval{ @listen_socket }.addr[3]
|
132
|
+
end
|
133
|
+
|
134
|
+
data(methods)
|
135
|
+
test 'creates tcp server if specified in proto' do |m|
|
136
|
+
@d.__send__(m, :myserver, PORT, proto: :tcp){|x| x }
|
137
|
+
|
138
|
+
created_server_info = @d._servers.first
|
139
|
+
assert_equal :tcp, created_server_info.proto
|
140
|
+
created_server = created_server_info.server
|
141
|
+
assert created_server.is_a?(Coolio::TCPServer)
|
142
|
+
end
|
143
|
+
|
144
|
+
# tests about "proto: :udp" is in #server_create
|
145
|
+
|
146
|
+
data(methods)
|
147
|
+
test 'creates tls server if specified in proto' do |m|
|
148
|
+
# pend "not implemented yet"
|
149
|
+
end
|
150
|
+
|
151
|
+
data(methods)
|
152
|
+
test 'creates unix server if specified in proto' do |m|
|
153
|
+
# pend "not implemented yet"
|
154
|
+
end
|
155
|
+
|
156
|
+
data(methods)
|
157
|
+
test 'raise error if unknown protocol specified' do |m|
|
158
|
+
assert_raise(ArgumentError.new("BUG: invalid protocol name")) do
|
159
|
+
@d.__send__(m, :myserver, PORT, proto: :quic){|x| x }
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
data(
|
164
|
+
'server_create tcp' => [:server_create, :tcp],
|
165
|
+
# 'server_create tls' => [:server_create, :tls],
|
166
|
+
# 'server_create unix' => [:server_create, :unix],
|
167
|
+
'server_create_connection tcp' => [:server_create_connection, :tcp],
|
168
|
+
# 'server_create_connection tcp' => [:server_create_connection, :tls],
|
169
|
+
# 'server_create_connection tcp' => [:server_create_connection, :unix],
|
170
|
+
)
|
171
|
+
test 'raise error if udp options specified for tcp/tls/unix' do |(m, proto)|
|
172
|
+
assert_raise ArgumentError do
|
173
|
+
@d.__send__(m, :myserver, PORT, proto: proto, max_bytes: 128){|x| x }
|
174
|
+
end
|
175
|
+
assert_raise ArgumentError do
|
176
|
+
@d.__send__(m, :myserver, PORT, proto: proto, flags: 1){|x| x }
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
data(
|
181
|
+
'server_create udp' => [:server_create, :udp],
|
182
|
+
)
|
183
|
+
test 'raise error if tcp/tls options specified for udp' do |(m, proto)|
|
184
|
+
assert_raise(ArgumentError.new("BUG: linger_timeout is available for tcp/tls")) do
|
185
|
+
@d.__send__(m, :myserver, PORT, proto: proto, linger_timeout: 1, max_bytes: 128){|x| x }
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
data(
|
190
|
+
'server_create udp' => [:server_create, :udp],
|
191
|
+
)
|
192
|
+
test 'raise error if tcp/tls/unix options specified for udp' do |(m, proto)|
|
193
|
+
assert_raise(ArgumentError.new("BUG: backlog is available for tcp/tls")) do
|
194
|
+
@d.__send__(m, :myserver, PORT, proto: proto, backlog: 500){|x| x }
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
data(
|
199
|
+
'server_create tcp' => [:server_create, :tcp, {}],
|
200
|
+
'server_create udp' => [:server_create, :udp, {max_bytes: 128}],
|
201
|
+
# 'server_create unix' => [:server_create, :unix, {}],
|
202
|
+
'server_create_connection tcp' => [:server_create_connection, :tcp, {}],
|
203
|
+
# 'server_create_connection unix' => [:server_create_connection, :unix, {}],
|
204
|
+
)
|
205
|
+
test 'raise error if tls options specified for tcp/udp/unix' do |(m, proto, kwargs)|
|
206
|
+
assert_raise(ArgumentError.new("BUG: certopts is available only for tls")) do
|
207
|
+
@d.__send__(m, :myserver, PORT, proto: proto, certopts: {}, **kwargs){|x| x }
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
data(
|
212
|
+
'server_create tcp' => [:server_create, :tcp, {}],
|
213
|
+
'server_create udp' => [:server_create, :udp, {max_bytes: 128}],
|
214
|
+
# 'server_create tls' => [:server_create, :tls, {}],
|
215
|
+
'server_create_connection tcp' => [:server_create_connection, :tcp, {}],
|
216
|
+
# 'server_create_connection tls' => [:server_create_connection, :tls, {}],
|
217
|
+
)
|
218
|
+
test 'can bind specified IPv4 address' do |(m, proto, kwargs)|
|
219
|
+
@d.__send__(m, :myserver, PORT, proto: proto, bind: "127.0.0.1", **kwargs){|x| x }
|
220
|
+
assert_equal "127.0.0.1", @d._servers.first.bind
|
221
|
+
assert_equal "127.0.0.1", @d._servers.first.server.instance_eval{ instance_variable_defined?(:@listen_socket) ? @listen_socket : @_io }.addr[3]
|
222
|
+
end
|
223
|
+
|
224
|
+
data(
|
225
|
+
'server_create tcp' => [:server_create, :tcp, {}],
|
226
|
+
'server_create udp' => [:server_create, :udp, {max_bytes: 128}],
|
227
|
+
# 'server_create tls' => [:server_create, :tls, {}],
|
228
|
+
'server_create_connection tcp' => [:server_create_connection, :tcp, {}],
|
229
|
+
# 'server_create_connection tls' => [:server_create_connection, :tls, {}],
|
230
|
+
)
|
231
|
+
test 'can bind specified IPv6 address' do |(m, proto, kwargs)| # if available
|
232
|
+
omit "IPv6 unavailable here" unless ipv6_enabled?
|
233
|
+
@d.__send__(m, :myserver, PORT, proto: proto, bind: "::1", **kwargs){|x| x }
|
234
|
+
assert_equal "::1", @d._servers.first.bind
|
235
|
+
assert_equal "::1", @d._servers.first.server.instance_eval{ instance_variable_defined?(:@listen_socket) ? @listen_socket : @_io }.addr[3]
|
236
|
+
end
|
237
|
+
|
238
|
+
data(
|
239
|
+
'server_create tcp' => [:server_create, :tcp, {}],
|
240
|
+
'server_create udp' => [:server_create, :udp, {max_bytes: 128}],
|
241
|
+
# 'server_create tls' => [:server_create, :tls, {}],
|
242
|
+
# 'server_create unix' => [:server_create, :unix, {}],
|
243
|
+
'server_create_connection tcp' => [:server_create, :tcp, {}],
|
244
|
+
# 'server_create_connection tls' => [:server_create, :tls, {}],
|
245
|
+
# 'server_create_connection unix' => [:server_create, :unix, {}],
|
246
|
+
)
|
247
|
+
test 'can create 2 or more servers which share same bind address and port if shared option is true' do |(m, proto, kwargs)|
|
248
|
+
begin
|
249
|
+
d2 = Dummy.new; d2.start; d2.after_start
|
250
|
+
|
251
|
+
assert_nothing_raised do
|
252
|
+
@d.__send__(m, :myserver, PORT, proto: proto, **kwargs){|x| x }
|
253
|
+
d2.__send__(m, :myserver, PORT, proto: proto, **kwargs){|x| x }
|
254
|
+
end
|
255
|
+
ensure
|
256
|
+
d2.stop; d2.before_shutdown; d2.shutdown; d2.after_shutdown; d2.close; d2.terminate
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
data(
|
261
|
+
'server_create tcp' => [:server_create, :tcp, {}],
|
262
|
+
'server_create udp' => [:server_create, :udp, {max_bytes: 128}],
|
263
|
+
# 'server_create tls' => [:server_create, :tls, {}],
|
264
|
+
# 'server_create unix' => [:server_create, :unix, {}],
|
265
|
+
'server_create_connection tcp' => [:server_create, :tcp, {}],
|
266
|
+
# 'server_create_connection tls' => [:server_create, :tls, {}],
|
267
|
+
# 'server_create_connection unix' => [:server_create, :unix, {}],
|
268
|
+
)
|
269
|
+
test 'cannot create 2 or more servers using same bind address and port if shared option is false' do |(m, proto, kwargs)|
|
270
|
+
begin
|
271
|
+
d2 = Dummy.new; d2.start; d2.after_start
|
272
|
+
|
273
|
+
assert_nothing_raised do
|
274
|
+
@d.__send__(m, :myserver, PORT, proto: proto, shared: false, **kwargs){|x| x }
|
275
|
+
end
|
276
|
+
assert_raise(Errno::EADDRINUSE, Errno::EACCES) do
|
277
|
+
d2.__send__(m, :myserver, PORT, proto: proto, **kwargs){|x| x }
|
278
|
+
end
|
279
|
+
ensure
|
280
|
+
d2.stop; d2.before_shutdown; d2.shutdown; d2.after_shutdown; d2.close; d2.terminate
|
281
|
+
end
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
sub_test_case '#server_create' do
|
286
|
+
data(
|
287
|
+
'tcp' => [:tcp, {}],
|
288
|
+
'udp' => [:udp, {max_bytes: 128}],
|
289
|
+
# 'tls' => [:tls, {}],
|
290
|
+
# 'unix' => [:unix, {}],
|
291
|
+
)
|
292
|
+
test 'raise error if block argument is not specified or too many' do |(proto, kwargs)|
|
293
|
+
assert_raise(ArgumentError.new("BUG: block must have 1 or 2 arguments")) do
|
294
|
+
@d.server_create(:myserver, PORT, proto: proto, **kwargs){ 1 }
|
295
|
+
end
|
296
|
+
assert_raise(ArgumentError.new("BUG: block must have 1 or 2 arguments")) do
|
297
|
+
@d.server_create(:myserver, PORT, proto: proto, **kwargs){|sock, conn, what_is_this| 1 }
|
298
|
+
end
|
299
|
+
end
|
300
|
+
|
301
|
+
test 'creates udp server if specified in proto' do
|
302
|
+
@d.server_create(:myserver, PORT, proto: :udp, max_bytes: 512){|x| x }
|
303
|
+
|
304
|
+
created_server_info = @d._servers.first
|
305
|
+
assert_equal :udp, created_server_info.proto
|
306
|
+
created_server = created_server_info.server
|
307
|
+
assert created_server.is_a?(Fluent::PluginHelper::Server::EventHandler::UDPServer)
|
308
|
+
end
|
309
|
+
end
|
310
|
+
|
311
|
+
sub_test_case '#server_create_tcp' do
|
312
|
+
test 'can accept all keyword arguments valid for tcp server' do
|
313
|
+
assert_nothing_raised do
|
314
|
+
@d.server_create_tcp(:s, PORT, bind: '127.0.0.1', shared: false, resolve_name: true, linger_timeout: 10, backlog: 500) do |data, conn|
|
315
|
+
# ...
|
316
|
+
end
|
317
|
+
end
|
318
|
+
end
|
319
|
+
|
320
|
+
test 'creates a tcp server just to read data' do
|
321
|
+
received = ""
|
322
|
+
@d.server_create_tcp(:s, PORT) do |data|
|
323
|
+
received << data
|
324
|
+
end
|
325
|
+
3.times do
|
326
|
+
sock = TCPSocket.new("127.0.0.1", PORT)
|
327
|
+
sock.puts "yay"
|
328
|
+
sock.puts "foo"
|
329
|
+
sock.close
|
330
|
+
end
|
331
|
+
waiting(10){ sleep 0.1 until received.bytesize == 24 }
|
332
|
+
assert_equal "yay\nfoo\nyay\nfoo\nyay\nfoo\n", received
|
333
|
+
end
|
334
|
+
|
335
|
+
test 'creates a tcp server to read and write data' do
|
336
|
+
received = ""
|
337
|
+
responses = []
|
338
|
+
@d.server_create_tcp(:s, PORT) do |data, conn|
|
339
|
+
received << data
|
340
|
+
conn.write "ack\n"
|
341
|
+
end
|
342
|
+
3.times do
|
343
|
+
TCPSocket.open("127.0.0.1", PORT) do |sock|
|
344
|
+
sock.puts "yay"
|
345
|
+
sock.puts "foo"
|
346
|
+
responses << sock.readline
|
347
|
+
end
|
348
|
+
end
|
349
|
+
waiting(10){ sleep 0.1 until received.bytesize == 24 }
|
350
|
+
assert_equal "yay\nfoo\nyay\nfoo\nyay\nfoo\n", received
|
351
|
+
assert_equal ["ack\n","ack\n","ack\n"], responses
|
352
|
+
end
|
353
|
+
|
354
|
+
test 'creates a tcp server to read and write data using IPv6' do
|
355
|
+
omit "IPv6 unavailable here" unless ipv6_enabled?
|
356
|
+
|
357
|
+
received = ""
|
358
|
+
responses = []
|
359
|
+
@d.server_create_tcp(:s, PORT, bind: "::1") do |data, conn|
|
360
|
+
received << data
|
361
|
+
conn.write "ack\n"
|
362
|
+
end
|
363
|
+
3.times do
|
364
|
+
TCPSocket.open("::1", PORT) do |sock|
|
365
|
+
sock.puts "yay"
|
366
|
+
sock.puts "foo"
|
367
|
+
responses << sock.readline
|
368
|
+
end
|
369
|
+
end
|
370
|
+
waiting(10){ sleep 0.1 until received.bytesize == 24 }
|
371
|
+
assert_equal "yay\nfoo\nyay\nfoo\nyay\nfoo\n", received
|
372
|
+
assert_equal ["ack\n","ack\n","ack\n"], responses
|
373
|
+
end
|
374
|
+
|
375
|
+
test 'does not resolve name of client address in default' do
|
376
|
+
received = ""
|
377
|
+
sources = []
|
378
|
+
@d.server_create_tcp(:s, PORT) do |data, conn|
|
379
|
+
received << data
|
380
|
+
sources << conn.remote_host
|
381
|
+
end
|
382
|
+
3.times do
|
383
|
+
TCPSocket.open("127.0.0.1", PORT) do |sock|
|
384
|
+
sock.puts "yay"
|
385
|
+
end
|
386
|
+
end
|
387
|
+
waiting(10){ sleep 0.1 until received.bytesize == 12 }
|
388
|
+
assert_equal "yay\nyay\nyay\n", received
|
389
|
+
assert{ sources.all?{|s| s == "127.0.0.1" } }
|
390
|
+
end
|
391
|
+
|
392
|
+
test 'does resolve name of client address if resolve_name is true' do
|
393
|
+
hostname = Socket.getnameinfo([nil, nil, nil, "127.0.0.1"])[0]
|
394
|
+
|
395
|
+
received = ""
|
396
|
+
sources = []
|
397
|
+
@d.server_create_tcp(:s, PORT, resolve_name: true) do |data, conn|
|
398
|
+
received << data
|
399
|
+
sources << conn.remote_host
|
400
|
+
end
|
401
|
+
3.times do
|
402
|
+
TCPSocket.open("127.0.0.1", PORT) do |sock|
|
403
|
+
sock.puts "yay"
|
404
|
+
end
|
405
|
+
end
|
406
|
+
waiting(10){ sleep 0.1 until received.bytesize == 12 }
|
407
|
+
assert_equal "yay\nyay\nyay\n", received
|
408
|
+
assert{ sources.all?{|s| s == hostname } }
|
409
|
+
end
|
410
|
+
|
411
|
+
test 'can keep connections alive for tcp if keepalive specified' do
|
412
|
+
# pend "not implemented yet"
|
413
|
+
end
|
414
|
+
|
415
|
+
test 'raises error if plugin registers data callback for connection object from #server_create' do
|
416
|
+
received = ""
|
417
|
+
errors = []
|
418
|
+
@d.server_create_tcp(:s, PORT) do |data, conn|
|
419
|
+
received << data
|
420
|
+
begin
|
421
|
+
conn.data{|d| received << d.upcase }
|
422
|
+
rescue => e
|
423
|
+
errors << e
|
424
|
+
end
|
425
|
+
end
|
426
|
+
TCPSocket.open("127.0.0.1", PORT) do |sock|
|
427
|
+
sock.puts "foo"
|
428
|
+
end
|
429
|
+
waiting(10){ sleep 0.1 until received.bytesize == 4 || errors.size == 1 }
|
430
|
+
assert_equal "foo\n", received
|
431
|
+
assert_equal 1, errors.size
|
432
|
+
assert_equal "data callback can be registered just once, but registered twice", errors.first.message
|
433
|
+
end
|
434
|
+
|
435
|
+
test 'can call write_complete callback if registered' do
|
436
|
+
buffer = ""
|
437
|
+
lines = []
|
438
|
+
responses = []
|
439
|
+
response_completes = []
|
440
|
+
@d.server_create_tcp(:s, PORT) do |data, conn|
|
441
|
+
conn.on(:write_complete){|c| response_completes << true }
|
442
|
+
buffer << data
|
443
|
+
if idx = buffer.index("\n")
|
444
|
+
lines << buffer.slice!(0,idx+1)
|
445
|
+
conn.write "ack\n"
|
446
|
+
end
|
447
|
+
end
|
448
|
+
3.times do
|
449
|
+
TCPSocket.open("127.0.0.1", PORT) do |sock|
|
450
|
+
sock.write "yay"
|
451
|
+
sock.write "foo\n"
|
452
|
+
begin
|
453
|
+
responses << sock.readline
|
454
|
+
rescue EOFError, IOError, Errno::ECONNRESET
|
455
|
+
# ignore
|
456
|
+
end
|
457
|
+
sock.close
|
458
|
+
end
|
459
|
+
end
|
460
|
+
waiting(10){ sleep 0.1 until lines.size == 3 && response_completes.size == 3 }
|
461
|
+
assert_equal ["yayfoo\n", "yayfoo\n", "yayfoo\n"], lines
|
462
|
+
assert_equal ["ack\n","ack\n","ack\n"], responses
|
463
|
+
assert_equal [true, true, true], response_completes
|
464
|
+
end
|
465
|
+
|
466
|
+
test 'can call close callback if registered' do
|
467
|
+
buffer = ""
|
468
|
+
lines = []
|
469
|
+
callback_results = []
|
470
|
+
@d.server_create_tcp(:s, PORT) do |data, conn|
|
471
|
+
conn.on(:close){|c| callback_results << "closed" }
|
472
|
+
buffer << data
|
473
|
+
if idx = buffer.index("\n")
|
474
|
+
lines << buffer.slice!(0,idx+1)
|
475
|
+
conn.write "ack\n"
|
476
|
+
end
|
477
|
+
end
|
478
|
+
3.times do
|
479
|
+
TCPSocket.open("127.0.0.1", PORT) do |sock|
|
480
|
+
sock.write "yay"
|
481
|
+
sock.write "foo\n"
|
482
|
+
begin
|
483
|
+
while line = sock.readline
|
484
|
+
if line == "ack\n"
|
485
|
+
sock.close
|
486
|
+
end
|
487
|
+
end
|
488
|
+
rescue EOFError, IOError, Errno::ECONNRESET
|
489
|
+
# ignore
|
490
|
+
end
|
491
|
+
end
|
492
|
+
end
|
493
|
+
waiting(10){ sleep 0.1 until lines.size == 3 && callback_results.size == 3 }
|
494
|
+
assert_equal ["yayfoo\n", "yayfoo\n", "yayfoo\n"], lines
|
495
|
+
assert_equal ["closed", "closed", "closed"], callback_results
|
496
|
+
end
|
497
|
+
end
|
498
|
+
|
499
|
+
sub_test_case '#server_create_udp' do
|
500
|
+
test 'can accept all keyword arguments valid for udp server' do
|
501
|
+
assert_nothing_raised do
|
502
|
+
@d.server_create_udp(:s, PORT, bind: '127.0.0.1', shared: false, resolve_name: true, max_bytes: 100, flags: 1) do |data, conn|
|
503
|
+
# ...
|
504
|
+
end
|
505
|
+
end
|
506
|
+
end
|
507
|
+
|
508
|
+
test 'creates a udp server just to read data' do
|
509
|
+
received = ""
|
510
|
+
@d.server_create_udp(:s, PORT, max_bytes: 128) do |data|
|
511
|
+
received << data
|
512
|
+
end
|
513
|
+
bind_port = unused_port(protocol: :udp, bind: "127.0.0.1")
|
514
|
+
3.times do
|
515
|
+
sock = UDPSocket.new(Socket::AF_INET)
|
516
|
+
sock.bind("127.0.0.1", bind_port)
|
517
|
+
sock.connect("127.0.0.1", PORT)
|
518
|
+
sock.puts "yay"
|
519
|
+
sock.puts "foo"
|
520
|
+
sock.close
|
521
|
+
end
|
522
|
+
waiting(10){ sleep 0.1 until received.bytesize == 24 }
|
523
|
+
assert_equal "yay\nfoo\nyay\nfoo\nyay\nfoo\n", received
|
524
|
+
end
|
525
|
+
|
526
|
+
test 'creates a udp server to read and write data' do
|
527
|
+
received = ""
|
528
|
+
responses = []
|
529
|
+
@d.server_create_udp(:s, PORT, max_bytes: 128) do |data, sock|
|
530
|
+
received << data
|
531
|
+
sock.write "ack\n"
|
532
|
+
end
|
533
|
+
bind_port = unused_port
|
534
|
+
3.times do
|
535
|
+
begin
|
536
|
+
sock = UDPSocket.new(Socket::AF_INET)
|
537
|
+
sock.bind("127.0.0.1", bind_port)
|
538
|
+
sock.connect("127.0.0.1", PORT)
|
539
|
+
th = Thread.new do
|
540
|
+
while true
|
541
|
+
begin
|
542
|
+
in_data, _addr = sock.recvfrom_nonblock(16)
|
543
|
+
if in_data
|
544
|
+
responses << in_data
|
545
|
+
break
|
546
|
+
end
|
547
|
+
rescue IO::WaitReadable
|
548
|
+
IO.select([sock])
|
549
|
+
end
|
550
|
+
end
|
551
|
+
true
|
552
|
+
end
|
553
|
+
sock.write "yay\nfoo\n"
|
554
|
+
th.join(5)
|
555
|
+
ensure
|
556
|
+
sock.close
|
557
|
+
end
|
558
|
+
end
|
559
|
+
waiting(10){ sleep 0.1 until received.bytesize == 24 }
|
560
|
+
assert_equal "yay\nfoo\nyay\nfoo\nyay\nfoo\n", received
|
561
|
+
assert_equal ["ack\n","ack\n","ack\n"], responses
|
562
|
+
end
|
563
|
+
|
564
|
+
test 'creates a udp server to read and write data using IPv6' do
|
565
|
+
omit "IPv6 unavailable here" unless ipv6_enabled?
|
566
|
+
|
567
|
+
received = ""
|
568
|
+
responses = []
|
569
|
+
@d.server_create_udp(:s, PORT, bind: "::1", max_bytes: 128) do |data, sock|
|
570
|
+
received << data
|
571
|
+
sock.write "ack\n"
|
572
|
+
end
|
573
|
+
bind_port = unused_port
|
574
|
+
3.times do
|
575
|
+
begin
|
576
|
+
sock = UDPSocket.new(Socket::AF_INET6)
|
577
|
+
sock.bind("::1", bind_port)
|
578
|
+
th = Thread.new do
|
579
|
+
responses << sock.recv(16)
|
580
|
+
true
|
581
|
+
end
|
582
|
+
sock.connect("::1", PORT)
|
583
|
+
sock.write "yay\nfoo\n"
|
584
|
+
th.join(5)
|
585
|
+
ensure
|
586
|
+
sock.close
|
587
|
+
end
|
588
|
+
end
|
589
|
+
waiting(10){ sleep 0.1 until received.bytesize == 24 }
|
590
|
+
assert_equal "yay\nfoo\nyay\nfoo\nyay\nfoo\n", received
|
591
|
+
assert_equal ["ack\n","ack\n","ack\n"], responses
|
592
|
+
end
|
593
|
+
|
594
|
+
test 'does not resolve name of client address in default' do
|
595
|
+
received = ""
|
596
|
+
sources = []
|
597
|
+
@d.server_create_udp(:s, PORT, max_bytes: 128) do |data, sock|
|
598
|
+
received << data
|
599
|
+
sources << sock.remote_host
|
600
|
+
end
|
601
|
+
3.times do
|
602
|
+
sock = UDPSocket.new(Socket::AF_INET)
|
603
|
+
sock.connect("127.0.0.1", PORT)
|
604
|
+
sock.puts "yay"
|
605
|
+
sock.close
|
606
|
+
end
|
607
|
+
waiting(10){ sleep 0.1 until received.bytesize == 12 }
|
608
|
+
assert_equal "yay\nyay\nyay\n", received
|
609
|
+
assert{ sources.all?{|s| s == "127.0.0.1" } }
|
610
|
+
end
|
611
|
+
|
612
|
+
test 'does resolve name of client address if resolve_name is true' do
|
613
|
+
hostname = Socket.getnameinfo([nil, nil, nil, "127.0.0.1"])[0]
|
614
|
+
|
615
|
+
received = ""
|
616
|
+
sources = []
|
617
|
+
@d.server_create_udp(:s, PORT, resolve_name: true, max_bytes: 128) do |data, sock|
|
618
|
+
received << data
|
619
|
+
sources << sock.remote_host
|
620
|
+
end
|
621
|
+
3.times do
|
622
|
+
sock = UDPSocket.new(Socket::AF_INET)
|
623
|
+
sock.connect("127.0.0.1", PORT)
|
624
|
+
sock.puts "yay"
|
625
|
+
sock.close
|
626
|
+
end
|
627
|
+
waiting(10){ sleep 0.1 until received.bytesize == 12 }
|
628
|
+
assert_equal "yay\nyay\nyay\n", received
|
629
|
+
assert{ sources.all?{|s| s == hostname } }
|
630
|
+
end
|
631
|
+
|
632
|
+
test 'raises error if plugin registers data callback for connection object from #server_create' do
|
633
|
+
received = ""
|
634
|
+
errors = []
|
635
|
+
@d.server_create_udp(:s, PORT, max_bytes: 128) do |data, sock|
|
636
|
+
received << data
|
637
|
+
begin
|
638
|
+
sock.data{|d| received << d.upcase }
|
639
|
+
rescue => e
|
640
|
+
errors << e
|
641
|
+
end
|
642
|
+
end
|
643
|
+
sock = UDPSocket.new(Socket::AF_INET)
|
644
|
+
sock.connect("127.0.0.1", PORT)
|
645
|
+
sock.write "foo\n"
|
646
|
+
sock.close
|
647
|
+
|
648
|
+
waiting(10){ sleep 0.1 until received.bytesize == 4 || errors.size == 1 }
|
649
|
+
assert_equal "foo\n", received
|
650
|
+
assert_equal 1, errors.size
|
651
|
+
assert_equal "BUG: this event is disabled for udp: data", errors.first.message
|
652
|
+
end
|
653
|
+
|
654
|
+
test 'raise error if plugin registers write_complete callback for udp' do
|
655
|
+
received = ""
|
656
|
+
errors = []
|
657
|
+
@d.server_create_udp(:s, PORT, max_bytes: 128) do |data, sock|
|
658
|
+
received << data
|
659
|
+
begin
|
660
|
+
sock.on(:write_complete){|conn| "" }
|
661
|
+
rescue => e
|
662
|
+
errors << e
|
663
|
+
end
|
664
|
+
end
|
665
|
+
sock = UDPSocket.new(Socket::AF_INET)
|
666
|
+
sock.connect("127.0.0.1", PORT)
|
667
|
+
sock.write "foo\n"
|
668
|
+
sock.close
|
669
|
+
|
670
|
+
waiting(10){ sleep 0.1 until received.bytesize == 4 || errors.size == 1 }
|
671
|
+
assert_equal "foo\n", received
|
672
|
+
assert_equal 1, errors.size
|
673
|
+
assert_equal "BUG: this event is disabled for udp: write_complete", errors.first.message
|
674
|
+
end
|
675
|
+
|
676
|
+
test 'raises error if plugin registers close callback for udp' do
|
677
|
+
received = ""
|
678
|
+
errors = []
|
679
|
+
@d.server_create_udp(:s, PORT, max_bytes: 128) do |data, sock|
|
680
|
+
received << data
|
681
|
+
begin
|
682
|
+
sock.on(:close){|d| "" }
|
683
|
+
rescue => e
|
684
|
+
errors << e
|
685
|
+
end
|
686
|
+
end
|
687
|
+
sock = UDPSocket.new(Socket::AF_INET)
|
688
|
+
sock.connect("127.0.0.1", PORT)
|
689
|
+
sock.write "foo\n"
|
690
|
+
sock.close
|
691
|
+
|
692
|
+
waiting(10){ sleep 0.1 until received.bytesize == 4 || errors.size == 1 }
|
693
|
+
assert_equal "foo\n", received
|
694
|
+
assert_equal 1, errors.size
|
695
|
+
assert_equal "BUG: this event is disabled for udp: close", errors.first.message
|
696
|
+
end
|
697
|
+
end
|
698
|
+
|
699
|
+
sub_test_case '#server_create_tls' do
|
700
|
+
# not implemented yet
|
701
|
+
|
702
|
+
# test 'can accept all keyword arguments valid for tcp/tls server'
|
703
|
+
# test 'creates a tls server just to read data'
|
704
|
+
# test 'creates a tls server to read and write data'
|
705
|
+
# test 'creates a tls server to read and write data using IPv6'
|
706
|
+
|
707
|
+
# many tests about certops
|
708
|
+
|
709
|
+
# test 'does not resolve name of client address in default'
|
710
|
+
# test 'does resolve name of client address if resolve_name is true'
|
711
|
+
# test 'can keep connections alive for tls if keepalive specified' do
|
712
|
+
# pend "not implemented yet"
|
713
|
+
# end
|
714
|
+
|
715
|
+
# test 'raises error if plugin registers data callback for connection object from #server_create'
|
716
|
+
# test 'can call write_complete callback if registered'
|
717
|
+
# test 'can call close callback if registered'
|
718
|
+
end
|
719
|
+
|
720
|
+
sub_test_case '#server_create_unix' do
|
721
|
+
# not implemented yet
|
722
|
+
|
723
|
+
# test 'can accept all keyword arguments valid for unix server'
|
724
|
+
# test 'creates a unix server just to read data'
|
725
|
+
# test 'creates a unix server to read and write data'
|
726
|
+
|
727
|
+
# test 'raises error if plugin registers data callback for connection object from #server_create'
|
728
|
+
# test 'can call write_complete callback if registered'
|
729
|
+
# test 'can call close callback if registered'
|
730
|
+
end
|
731
|
+
|
732
|
+
# run tests for tcp, tls and unix
|
733
|
+
sub_test_case '#server_create_connection' do
|
734
|
+
test 'raise error if udp is specified in proto' do
|
735
|
+
assert_raise(ArgumentError.new("BUG: cannot create connection for UDP")) do
|
736
|
+
@d.server_create_connection(:myserver, PORT, proto: :udp){|c| c }
|
737
|
+
end
|
738
|
+
end
|
739
|
+
|
740
|
+
# def server_create_connection(title, port, proto: :tcp, bind: '0.0.0.0', shared: true, certopts: nil, resolve_name: false, linger_timeout: 0, backlog: nil, &block)
|
741
|
+
protocols = {
|
742
|
+
'tcp' => [:tcp, {}],
|
743
|
+
# 'tls' => [:tls, {certopts: {}}],
|
744
|
+
# 'unix' => [:unix, {path: ""}],
|
745
|
+
}
|
746
|
+
|
747
|
+
data(protocols)
|
748
|
+
test 'raise error if block argument is not specified or too many' do |(proto, kwargs)|
|
749
|
+
empty_block = ->(){}
|
750
|
+
assert_raise(ArgumentError.new("BUG: block must have just one argument")) do
|
751
|
+
@d.server_create_connection(:myserver, PORT, proto: proto, **kwargs, &empty_block)
|
752
|
+
end
|
753
|
+
assert_raise(ArgumentError.new("BUG: block must have just one argument")) do
|
754
|
+
@d.server_create_connection(:myserver, PORT, proto: proto, **kwargs){|conn, what_is_this| [conn, what_is_this] }
|
755
|
+
end
|
756
|
+
end
|
757
|
+
|
758
|
+
data(protocols)
|
759
|
+
test 'does not resolve name of client address in default' do |(proto, kwargs)|
|
760
|
+
received = ""
|
761
|
+
sources = []
|
762
|
+
@d.server_create_connection(:s, PORT, proto: proto, **kwargs) do |conn|
|
763
|
+
sources << conn.remote_host
|
764
|
+
conn.data do |d|
|
765
|
+
received << d
|
766
|
+
end
|
767
|
+
end
|
768
|
+
3.times do
|
769
|
+
TCPSocket.open("127.0.0.1", PORT) do |sock|
|
770
|
+
sock.puts "yay"
|
771
|
+
end
|
772
|
+
end
|
773
|
+
waiting(10){ sleep 0.1 until received.bytesize == 12 }
|
774
|
+
assert_equal "yay\nyay\nyay\n", received
|
775
|
+
assert{ sources.all?{|s| s == "127.0.0.1" } }
|
776
|
+
end
|
777
|
+
|
778
|
+
data(protocols)
|
779
|
+
test 'does resolve name of client address if resolve_name is true' do |(proto, kwargs)|
|
780
|
+
hostname = Socket.getnameinfo([nil, nil, nil, "127.0.0.1"])[0]
|
781
|
+
|
782
|
+
received = ""
|
783
|
+
sources = []
|
784
|
+
@d.server_create_connection(:s, PORT, proto: proto, resolve_name: true, **kwargs) do |conn|
|
785
|
+
sources << conn.remote_host
|
786
|
+
conn.data do |d|
|
787
|
+
received << d
|
788
|
+
end
|
789
|
+
end
|
790
|
+
3.times do
|
791
|
+
TCPSocket.open("127.0.0.1", PORT) do |sock|
|
792
|
+
sock.puts "yay"
|
793
|
+
end
|
794
|
+
end
|
795
|
+
waiting(10){ sleep 0.1 until received.bytesize == 12 }
|
796
|
+
assert_equal "yay\nyay\nyay\n", received
|
797
|
+
assert{ sources.all?{|s| s == hostname } }
|
798
|
+
end
|
799
|
+
|
800
|
+
data(protocols)
|
801
|
+
test 'creates a server to provide connection, which can read, write and close' do |(proto, kwargs)|
|
802
|
+
lines = []
|
803
|
+
buffer = ""
|
804
|
+
@d.server_create_connection(:s, PORT, proto: proto, **kwargs) do |conn|
|
805
|
+
conn.data do |d|
|
806
|
+
buffer << d
|
807
|
+
if buffer == "x"
|
808
|
+
buffer.slice!(0, 1)
|
809
|
+
conn.close
|
810
|
+
end
|
811
|
+
if idx = buffer.index("\n")
|
812
|
+
lines << buffer.slice!(0, idx + 1)
|
813
|
+
conn.write "foo!\n"
|
814
|
+
end
|
815
|
+
end
|
816
|
+
end
|
817
|
+
replied = []
|
818
|
+
disconnecteds = []
|
819
|
+
3.times do
|
820
|
+
TCPSocket.open("127.0.0.1", PORT) do |sock|
|
821
|
+
sock.puts "yay"
|
822
|
+
while line = sock.readline
|
823
|
+
replied << line
|
824
|
+
break
|
825
|
+
end
|
826
|
+
sock.write "x"
|
827
|
+
begin
|
828
|
+
sock.read
|
829
|
+
rescue => e
|
830
|
+
if e.is_a?(Errno::ECONNRESET)
|
831
|
+
disconnecteds << e.class
|
832
|
+
end
|
833
|
+
end
|
834
|
+
end
|
835
|
+
end
|
836
|
+
waiting(10){ sleep 0.1 until lines.size == 3 }
|
837
|
+
waiting(10){ sleep 0.1 until replied.size == 3 }
|
838
|
+
waiting(10){ sleep 0.1 until disconnecteds.size == 3 }
|
839
|
+
assert_equal ["yay\n", "yay\n", "yay\n"], lines
|
840
|
+
assert_equal ["foo!\n", "foo!\n", "foo!\n"], replied
|
841
|
+
assert_equal [Errno::ECONNRESET, Errno::ECONNRESET, Errno::ECONNRESET], disconnecteds
|
842
|
+
end
|
843
|
+
|
844
|
+
data(protocols)
|
845
|
+
test 'creates a server to provide connection, which accepts callbacks for data, write_complete, and close' do |(proto, kwargs)|
|
846
|
+
lines = []
|
847
|
+
buffer = ""
|
848
|
+
written = 0
|
849
|
+
closed = 0
|
850
|
+
@d.server_create_connection(:s, PORT, proto: proto, **kwargs) do |conn|
|
851
|
+
conn.on(:write_complete){|_conn| written += 1 }
|
852
|
+
conn.on(:close){|_conn| closed += 1 }
|
853
|
+
conn.on(:data) do |d|
|
854
|
+
buffer << d
|
855
|
+
if idx = buffer.index("\n")
|
856
|
+
lines << buffer.slice!(0, idx + 1)
|
857
|
+
conn.write "foo!\n"
|
858
|
+
end
|
859
|
+
end
|
860
|
+
end
|
861
|
+
replied = []
|
862
|
+
3.times do
|
863
|
+
TCPSocket.open("127.0.0.1", PORT) do |sock|
|
864
|
+
sock.puts "yay"
|
865
|
+
while line = sock.readline
|
866
|
+
replied << line
|
867
|
+
break
|
868
|
+
end
|
869
|
+
end # TCP socket is closed here
|
870
|
+
end
|
871
|
+
waiting(10){ sleep 0.1 until lines.size == 3 }
|
872
|
+
waiting(10){ sleep 0.1 until replied.size == 3 }
|
873
|
+
waiting(10){ sleep 0.1 until closed == 3 }
|
874
|
+
assert_equal ["yay\n", "yay\n", "yay\n"], lines
|
875
|
+
assert_equal 3, written
|
876
|
+
assert_equal 3, closed
|
877
|
+
assert_equal ["foo!\n", "foo!\n", "foo!\n"], replied
|
878
|
+
end
|
879
|
+
|
880
|
+
data(protocols)
|
881
|
+
test 'creates a server, and does not leak connections' do |(proto, kwargs)|
|
882
|
+
buffer = ""
|
883
|
+
closed = 0
|
884
|
+
@d.server_create_connection(:s, PORT, proto: proto, **kwargs) do |conn|
|
885
|
+
conn.on(:close){|_c| closed += 1 }
|
886
|
+
conn.on(:data) do |d|
|
887
|
+
buffer << d
|
888
|
+
end
|
889
|
+
end
|
890
|
+
3.times do
|
891
|
+
TCPSocket.open("127.0.0.1", PORT) do |sock|
|
892
|
+
sock.puts "yay"
|
893
|
+
end
|
894
|
+
end
|
895
|
+
waiting(10){ sleep 0.1 until buffer.bytesize == 12 }
|
896
|
+
waiting(10){ sleep 0.1 until closed == 3 }
|
897
|
+
assert_equal 0, @d.instance_eval{ @_server_connections.size }
|
898
|
+
end
|
899
|
+
|
900
|
+
test 'can keep connections alive for tcp/tls if keepalive specified' do
|
901
|
+
# pend "not implemented yet"
|
902
|
+
end
|
903
|
+
end
|
904
|
+
|
905
|
+
end
|