eventmachine-mkroman 1.3.0.dev.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 +7 -0
- data/CHANGELOG.md +179 -0
- data/GNU +281 -0
- data/LICENSE +60 -0
- data/README.md +110 -0
- data/docs/DocumentationGuidesIndex.md +27 -0
- data/docs/GettingStarted.md +520 -0
- data/docs/old/ChangeLog +211 -0
- data/docs/old/DEFERRABLES +246 -0
- data/docs/old/EPOLL +141 -0
- data/docs/old/INSTALL +13 -0
- data/docs/old/KEYBOARD +42 -0
- data/docs/old/LEGAL +25 -0
- data/docs/old/LIGHTWEIGHT_CONCURRENCY +130 -0
- data/docs/old/PURE_RUBY +75 -0
- data/docs/old/RELEASE_NOTES +94 -0
- data/docs/old/SMTP +4 -0
- data/docs/old/SPAWNED_PROCESSES +148 -0
- data/docs/old/TODO +8 -0
- data/examples/guides/getting_started/01_eventmachine_echo_server.rb +18 -0
- data/examples/guides/getting_started/02_eventmachine_echo_server_that_recognizes_exit_command.rb +22 -0
- data/examples/guides/getting_started/03_simple_chat_server.rb +149 -0
- data/examples/guides/getting_started/04_simple_chat_server_step_one.rb +27 -0
- data/examples/guides/getting_started/05_simple_chat_server_step_two.rb +43 -0
- data/examples/guides/getting_started/06_simple_chat_server_step_three.rb +98 -0
- data/examples/guides/getting_started/07_simple_chat_server_step_four.rb +121 -0
- data/examples/guides/getting_started/08_simple_chat_server_step_five.rb +141 -0
- data/examples/old/ex_channel.rb +43 -0
- data/examples/old/ex_queue.rb +2 -0
- data/examples/old/ex_tick_loop_array.rb +15 -0
- data/examples/old/ex_tick_loop_counter.rb +32 -0
- data/examples/old/helper.rb +2 -0
- data/ext/binder.cpp +124 -0
- data/ext/binder.h +52 -0
- data/ext/cmain.cpp +1046 -0
- data/ext/ed.cpp +2243 -0
- data/ext/ed.h +463 -0
- data/ext/em.cpp +2378 -0
- data/ext/em.h +266 -0
- data/ext/eventmachine.h +152 -0
- data/ext/extconf.rb +291 -0
- data/ext/fastfilereader/extconf.rb +120 -0
- data/ext/fastfilereader/mapper.cpp +214 -0
- data/ext/fastfilereader/mapper.h +59 -0
- data/ext/fastfilereader/rubymain.cpp +126 -0
- data/ext/kb.cpp +79 -0
- data/ext/page.cpp +107 -0
- data/ext/page.h +51 -0
- data/ext/pipe.cpp +354 -0
- data/ext/project.h +174 -0
- data/ext/rubymain.cpp +1643 -0
- data/ext/ssl.cpp +701 -0
- data/ext/ssl.h +103 -0
- data/ext/wait_for_single_fd.h +36 -0
- data/java/.classpath +8 -0
- data/java/.project +17 -0
- data/java/src/com/rubyeventmachine/EmReactor.java +625 -0
- data/java/src/com/rubyeventmachine/EmReactorException.java +40 -0
- data/java/src/com/rubyeventmachine/EmReactorInterface.java +70 -0
- data/java/src/com/rubyeventmachine/EventableChannel.java +72 -0
- data/java/src/com/rubyeventmachine/EventableDatagramChannel.java +201 -0
- data/java/src/com/rubyeventmachine/EventableSocketChannel.java +415 -0
- data/java/src/com/rubyeventmachine/NullEmReactor.java +157 -0
- data/java/src/com/rubyeventmachine/NullEventableChannel.java +81 -0
- data/lib/em/buftok.rb +59 -0
- data/lib/em/callback.rb +58 -0
- data/lib/em/channel.rb +69 -0
- data/lib/em/completion.rb +307 -0
- data/lib/em/connection.rb +802 -0
- data/lib/em/deferrable/pool.rb +2 -0
- data/lib/em/deferrable.rb +210 -0
- data/lib/em/file_watch.rb +73 -0
- data/lib/em/future.rb +61 -0
- data/lib/em/io_streamer.rb +68 -0
- data/lib/em/iterator.rb +252 -0
- data/lib/em/messages.rb +66 -0
- data/lib/em/pool.rb +151 -0
- data/lib/em/process_watch.rb +45 -0
- data/lib/em/processes.rb +123 -0
- data/lib/em/protocols/header_and_content.rb +138 -0
- data/lib/em/protocols/httpclient.rb +303 -0
- data/lib/em/protocols/httpclient2.rb +602 -0
- data/lib/em/protocols/line_and_text.rb +125 -0
- data/lib/em/protocols/line_protocol.rb +33 -0
- data/lib/em/protocols/linetext2.rb +179 -0
- data/lib/em/protocols/memcache.rb +331 -0
- data/lib/em/protocols/object_protocol.rb +46 -0
- data/lib/em/protocols/postgres3.rb +246 -0
- data/lib/em/protocols/saslauth.rb +175 -0
- data/lib/em/protocols/smtpclient.rb +394 -0
- data/lib/em/protocols/smtpserver.rb +666 -0
- data/lib/em/protocols/socks4.rb +66 -0
- data/lib/em/protocols/stomp.rb +205 -0
- data/lib/em/protocols/tcptest.rb +54 -0
- data/lib/em/protocols.rb +37 -0
- data/lib/em/pure_ruby.rb +1300 -0
- data/lib/em/queue.rb +80 -0
- data/lib/em/resolver.rb +232 -0
- data/lib/em/spawnable.rb +84 -0
- data/lib/em/streamer.rb +118 -0
- data/lib/em/threaded_resource.rb +90 -0
- data/lib/em/tick_loop.rb +85 -0
- data/lib/em/timers.rb +61 -0
- data/lib/em/version.rb +3 -0
- data/lib/eventmachine.rb +1602 -0
- data/lib/jeventmachine.rb +319 -0
- data/rakelib/package.rake +120 -0
- data/rakelib/test.rake +6 -0
- data/rakelib/test_pure.rake +11 -0
- data/tests/client.crt +31 -0
- data/tests/client.key +51 -0
- data/tests/dhparam.pem +13 -0
- data/tests/em_ssl_handlers.rb +165 -0
- data/tests/em_test_helper.rb +198 -0
- data/tests/encoded_client.key +54 -0
- data/tests/jruby/test_jeventmachine.rb +38 -0
- data/tests/test_attach.rb +199 -0
- data/tests/test_basic.rb +321 -0
- data/tests/test_channel.rb +75 -0
- data/tests/test_completion.rb +178 -0
- data/tests/test_connection_count.rb +83 -0
- data/tests/test_connection_write.rb +35 -0
- data/tests/test_defer.rb +35 -0
- data/tests/test_deferrable.rb +35 -0
- data/tests/test_epoll.rb +141 -0
- data/tests/test_error_handler.rb +38 -0
- data/tests/test_exc.rb +37 -0
- data/tests/test_file_watch.rb +86 -0
- data/tests/test_fork.rb +75 -0
- data/tests/test_futures.rb +170 -0
- data/tests/test_handler_check.rb +35 -0
- data/tests/test_hc.rb +155 -0
- data/tests/test_httpclient.rb +238 -0
- data/tests/test_httpclient2.rb +132 -0
- data/tests/test_idle_connection.rb +31 -0
- data/tests/test_inactivity_timeout.rb +102 -0
- data/tests/test_io_streamer.rb +48 -0
- data/tests/test_ipv4.rb +96 -0
- data/tests/test_ipv6.rb +107 -0
- data/tests/test_iterator.rb +122 -0
- data/tests/test_kb.rb +28 -0
- data/tests/test_keepalive.rb +113 -0
- data/tests/test_line_protocol.rb +33 -0
- data/tests/test_ltp.rb +155 -0
- data/tests/test_ltp2.rb +332 -0
- data/tests/test_many_fds.rb +21 -0
- data/tests/test_next_tick.rb +104 -0
- data/tests/test_object_protocol.rb +36 -0
- data/tests/test_pause.rb +109 -0
- data/tests/test_pending_connect_timeout.rb +52 -0
- data/tests/test_pool.rb +196 -0
- data/tests/test_process_watch.rb +50 -0
- data/tests/test_processes.rb +147 -0
- data/tests/test_proxy_connection.rb +180 -0
- data/tests/test_pure.rb +156 -0
- data/tests/test_queue.rb +64 -0
- data/tests/test_resolver.rb +129 -0
- data/tests/test_running.rb +14 -0
- data/tests/test_sasl.rb +46 -0
- data/tests/test_send_file.rb +217 -0
- data/tests/test_servers.rb +32 -0
- data/tests/test_shutdown_hooks.rb +23 -0
- data/tests/test_smtpclient.rb +75 -0
- data/tests/test_smtpserver.rb +90 -0
- data/tests/test_sock_opt.rb +53 -0
- data/tests/test_spawn.rb +290 -0
- data/tests/test_ssl_args.rb +70 -0
- data/tests/test_ssl_dhparam.rb +57 -0
- data/tests/test_ssl_ecdh_curve.rb +57 -0
- data/tests/test_ssl_extensions.rb +24 -0
- data/tests/test_ssl_inline_cert.rb +222 -0
- data/tests/test_ssl_methods.rb +31 -0
- data/tests/test_ssl_protocols.rb +190 -0
- data/tests/test_ssl_verify.rb +108 -0
- data/tests/test_stomp.rb +38 -0
- data/tests/test_system.rb +46 -0
- data/tests/test_threaded_resource.rb +68 -0
- data/tests/test_tick_loop.rb +58 -0
- data/tests/test_timers.rb +150 -0
- data/tests/test_ud.rb +8 -0
- data/tests/test_unbind_reason.rb +40 -0
- metadata +389 -0
data/tests/test_basic.rb
ADDED
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
require_relative 'em_test_helper'
|
|
2
|
+
|
|
3
|
+
class TestBasic < Test::Unit::TestCase
|
|
4
|
+
def setup
|
|
5
|
+
@port = next_port
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
INVALID = "(not known|no data of the requested|No such host is known|Temporary failure in name resolution)"
|
|
9
|
+
|
|
10
|
+
def test_connection_class_cache
|
|
11
|
+
mod = Module.new
|
|
12
|
+
a, b = nil, nil
|
|
13
|
+
EM.run {
|
|
14
|
+
EM.start_server '127.0.0.1', @port, mod
|
|
15
|
+
a = EM.connect '127.0.0.1', @port, mod
|
|
16
|
+
b = EM.connect '127.0.0.1', @port, mod
|
|
17
|
+
EM.stop
|
|
18
|
+
}
|
|
19
|
+
assert_equal a.class, b.class
|
|
20
|
+
assert_kind_of EM::Connection, a
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
#-------------------------------------
|
|
24
|
+
|
|
25
|
+
def test_em
|
|
26
|
+
assert_nothing_raised do
|
|
27
|
+
EM.run {
|
|
28
|
+
setup_timeout
|
|
29
|
+
EM.add_timer 0 do
|
|
30
|
+
EM.stop
|
|
31
|
+
end
|
|
32
|
+
}
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
#-------------------------------------
|
|
37
|
+
|
|
38
|
+
def test_timer
|
|
39
|
+
assert_nothing_raised do
|
|
40
|
+
EM.run {
|
|
41
|
+
setup_timeout(darwin? ? 0.6 : 0.4)
|
|
42
|
+
n = 0
|
|
43
|
+
EM.add_periodic_timer(0.1) {
|
|
44
|
+
n += 1
|
|
45
|
+
EM.stop if n == 2
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
#-------------------------------------
|
|
52
|
+
|
|
53
|
+
# This test once threw an already-running exception.
|
|
54
|
+
module Trivial
|
|
55
|
+
def post_init
|
|
56
|
+
EM.stop
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def test_server
|
|
61
|
+
assert_nothing_raised do
|
|
62
|
+
EM.run {
|
|
63
|
+
setup_timeout
|
|
64
|
+
EM.start_server "127.0.0.1", @port, Trivial
|
|
65
|
+
EM.connect "127.0.0.1", @port
|
|
66
|
+
}
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
#--------------------------------------
|
|
71
|
+
|
|
72
|
+
# EM#run_block starts the reactor loop, runs the supplied block, and then STOPS
|
|
73
|
+
# the loop automatically. Contrast with EM#run, which keeps running the reactor
|
|
74
|
+
# even after the supplied block completes.
|
|
75
|
+
def test_run_block
|
|
76
|
+
assert !EM.reactor_running?
|
|
77
|
+
a = nil
|
|
78
|
+
EM.run_block { a = "Worked" }
|
|
79
|
+
assert a
|
|
80
|
+
assert !EM.reactor_running?
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
class UnbindError < EM::Connection
|
|
84
|
+
ERR = Class.new(StandardError)
|
|
85
|
+
def initialize *args
|
|
86
|
+
super
|
|
87
|
+
end
|
|
88
|
+
def connection_completed
|
|
89
|
+
close_connection_after_writing
|
|
90
|
+
end
|
|
91
|
+
def unbind
|
|
92
|
+
raise ERR
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def test_unbind_error_during_stop
|
|
97
|
+
assert_raises( UnbindError::ERR ) {
|
|
98
|
+
EM.run {
|
|
99
|
+
EM.start_server "127.0.0.1", @port
|
|
100
|
+
EM.connect "127.0.0.1", @port, UnbindError do
|
|
101
|
+
EM.stop
|
|
102
|
+
end
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def test_unbind_error
|
|
108
|
+
EM.run {
|
|
109
|
+
EM.error_handler do |e|
|
|
110
|
+
assert(e.is_a?(UnbindError::ERR))
|
|
111
|
+
EM.stop
|
|
112
|
+
end
|
|
113
|
+
EM.start_server "127.0.0.1", @port
|
|
114
|
+
EM.connect "127.0.0.1", @port, UnbindError
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
# Remove the error handler before the next test
|
|
118
|
+
EM.error_handler(nil)
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
module BrsTestSrv
|
|
122
|
+
def receive_data data
|
|
123
|
+
$received << data
|
|
124
|
+
end
|
|
125
|
+
def unbind
|
|
126
|
+
EM.stop
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
module BrsTestCli
|
|
130
|
+
def post_init
|
|
131
|
+
send_data $sent
|
|
132
|
+
close_connection_after_writing
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# From ticket #50
|
|
137
|
+
def test_byte_range_send
|
|
138
|
+
$received = ''
|
|
139
|
+
$sent = (0..255).to_a.pack('C*')
|
|
140
|
+
EM::run {
|
|
141
|
+
EM::start_server "127.0.0.1", @port, BrsTestSrv
|
|
142
|
+
EM::connect "127.0.0.1", @port, BrsTestCli
|
|
143
|
+
|
|
144
|
+
setup_timeout
|
|
145
|
+
}
|
|
146
|
+
assert_equal($sent, $received)
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def test_bind_connect
|
|
150
|
+
local_ip = UDPSocket.open {|s| s.connect('localhost', 80); s.addr.last }
|
|
151
|
+
|
|
152
|
+
bind_port = next_port
|
|
153
|
+
|
|
154
|
+
port, ip = nil
|
|
155
|
+
bound_server = Module.new do
|
|
156
|
+
define_method :post_init do
|
|
157
|
+
begin
|
|
158
|
+
port, ip = Socket.unpack_sockaddr_in(get_peername)
|
|
159
|
+
ensure
|
|
160
|
+
EM.stop
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
EM.run do
|
|
166
|
+
darwin? ? setup_timeout(0.3) : setup_timeout
|
|
167
|
+
EM.start_server "127.0.0.1", @port, bound_server
|
|
168
|
+
EM.bind_connect local_ip, bind_port, "127.0.0.1", @port
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
assert_equal bind_port, port
|
|
172
|
+
assert_equal local_ip, ip
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
def test_invalid_address_bind_connect_dst
|
|
176
|
+
pend("\nFIXME: Windows as of 2018-06-23 on 32 bit >= 2.4 (#{RUBY_VERSION} #{RUBY_PLATFORM})") if RUBY_PLATFORM[/i386-mingw/] && RUBY_VERSION >= '2.4'
|
|
177
|
+
e = nil
|
|
178
|
+
EM.run do
|
|
179
|
+
begin
|
|
180
|
+
EM.bind_connect('localhost', nil, 'invalid.invalid', 80)
|
|
181
|
+
rescue Exception => e
|
|
182
|
+
# capture the exception
|
|
183
|
+
ensure
|
|
184
|
+
EM.stop
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
assert_kind_of(EventMachine::ConnectionError, e)
|
|
189
|
+
assert_match(/unable to resolve address:.*#{INVALID}/, e.message)
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
def test_invalid_address_bind_connect_src
|
|
193
|
+
pend("\nFIXME: Windows as of 2018-06-23 on 32 bit >= 2.4 (#{RUBY_VERSION} #{RUBY_PLATFORM})") if RUBY_PLATFORM[/i386-mingw/] && RUBY_VERSION >= '2.4'
|
|
194
|
+
e = nil
|
|
195
|
+
EM.run do
|
|
196
|
+
begin
|
|
197
|
+
EM.bind_connect('invalid.invalid', nil, 'localhost', 80)
|
|
198
|
+
rescue Exception => e
|
|
199
|
+
# capture the exception
|
|
200
|
+
ensure
|
|
201
|
+
EM.stop
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
assert_kind_of(EventMachine::ConnectionError, e)
|
|
206
|
+
assert_match(/invalid bind address:.*#{INVALID}/, e.message)
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
def test_reactor_thread?
|
|
210
|
+
assert !EM.reactor_thread?
|
|
211
|
+
EM.run { assert EM.reactor_thread?; EM.stop }
|
|
212
|
+
assert !EM.reactor_thread?
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
def test_schedule_on_reactor_thread
|
|
216
|
+
x = false
|
|
217
|
+
EM.run do
|
|
218
|
+
EM.schedule { x = true }
|
|
219
|
+
EM.stop
|
|
220
|
+
end
|
|
221
|
+
assert x
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
def test_schedule_from_thread
|
|
225
|
+
x = false
|
|
226
|
+
EM.run do
|
|
227
|
+
Thread.new { EM.schedule { x = true; EM.stop } }.join
|
|
228
|
+
end
|
|
229
|
+
assert x
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
def test_set_heartbeat_interval
|
|
233
|
+
omit_if(jruby?)
|
|
234
|
+
interval = 0.5
|
|
235
|
+
EM.run {
|
|
236
|
+
EM.set_heartbeat_interval interval
|
|
237
|
+
$interval = EM.get_heartbeat_interval
|
|
238
|
+
EM.stop
|
|
239
|
+
}
|
|
240
|
+
assert_equal(interval, $interval)
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
module PostInitRaiser
|
|
244
|
+
ERR = Class.new(StandardError)
|
|
245
|
+
def post_init
|
|
246
|
+
raise ERR
|
|
247
|
+
end
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
def test_bubble_errors_from_post_init
|
|
251
|
+
assert_raises(PostInitRaiser::ERR) do
|
|
252
|
+
EM.run do
|
|
253
|
+
EM.start_server "127.0.0.1", @port
|
|
254
|
+
EM.connect "127.0.0.1", @port, PostInitRaiser
|
|
255
|
+
end
|
|
256
|
+
end
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
module InitializeRaiser
|
|
260
|
+
ERR = Class.new(StandardError)
|
|
261
|
+
def initialize
|
|
262
|
+
raise ERR
|
|
263
|
+
end
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
def test_bubble_errors_from_initialize
|
|
267
|
+
assert_raises(InitializeRaiser::ERR) do
|
|
268
|
+
EM.run do
|
|
269
|
+
EM.start_server "127.0.0.1", @port
|
|
270
|
+
EM.connect "127.0.0.1", @port, InitializeRaiser
|
|
271
|
+
end
|
|
272
|
+
end
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
def test_schedule_close
|
|
276
|
+
omit_if(jruby?)
|
|
277
|
+
localhost, port = '127.0.0.1', 9000
|
|
278
|
+
timer_ran = false
|
|
279
|
+
num_close_scheduled = nil
|
|
280
|
+
EM.run do
|
|
281
|
+
assert_equal 0, EM.num_close_scheduled
|
|
282
|
+
EM.add_timer(1) { timer_ran = true; EM.stop }
|
|
283
|
+
EM.start_server localhost, port do |s|
|
|
284
|
+
s.close_connection
|
|
285
|
+
num_close_scheduled = EM.num_close_scheduled
|
|
286
|
+
end
|
|
287
|
+
EM.connect localhost, port do |c|
|
|
288
|
+
def c.unbind
|
|
289
|
+
EM.stop
|
|
290
|
+
end
|
|
291
|
+
end
|
|
292
|
+
end
|
|
293
|
+
assert !timer_ran
|
|
294
|
+
assert_equal 1, num_close_scheduled
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
def test_error_handler_idempotent # issue 185
|
|
298
|
+
errors = []
|
|
299
|
+
ticks = []
|
|
300
|
+
EM.error_handler do |e|
|
|
301
|
+
errors << e
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
EM.run do
|
|
305
|
+
EM.next_tick do
|
|
306
|
+
ticks << :first
|
|
307
|
+
raise
|
|
308
|
+
end
|
|
309
|
+
EM.next_tick do
|
|
310
|
+
ticks << :second
|
|
311
|
+
end
|
|
312
|
+
EM.add_timer(0.001) { EM.stop }
|
|
313
|
+
end
|
|
314
|
+
|
|
315
|
+
# Remove the error handler before the next test
|
|
316
|
+
EM.error_handler(nil)
|
|
317
|
+
|
|
318
|
+
assert_equal 1, errors.size
|
|
319
|
+
assert_equal [:first, :second], ticks
|
|
320
|
+
end
|
|
321
|
+
end
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
require_relative 'em_test_helper'
|
|
2
|
+
|
|
3
|
+
class TestEMChannel < Test::Unit::TestCase
|
|
4
|
+
def test_channel_subscribe
|
|
5
|
+
s = 0
|
|
6
|
+
EM.run do
|
|
7
|
+
c = EM::Channel.new
|
|
8
|
+
c.subscribe { |v| s = v; EM.stop }
|
|
9
|
+
c << 1
|
|
10
|
+
end
|
|
11
|
+
assert_equal 1, s
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def test_channel_unsubscribe
|
|
15
|
+
s = 0
|
|
16
|
+
EM.run do
|
|
17
|
+
c = EM::Channel.new
|
|
18
|
+
subscription = c.subscribe { |v| s = v }
|
|
19
|
+
c.unsubscribe(subscription)
|
|
20
|
+
c << 1
|
|
21
|
+
EM.next_tick { EM.stop }
|
|
22
|
+
end
|
|
23
|
+
assert_not_equal 1, s
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def test_channel_pop
|
|
27
|
+
s = 0
|
|
28
|
+
EM.run do
|
|
29
|
+
c = EM::Channel.new
|
|
30
|
+
c.pop{ |v| s = v }
|
|
31
|
+
c.push(1,2,3)
|
|
32
|
+
c << 4
|
|
33
|
+
c << 5
|
|
34
|
+
EM.next_tick { EM.stop }
|
|
35
|
+
end
|
|
36
|
+
assert_equal 1, s
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def test_channel_reactor_thread_push
|
|
40
|
+
out = []
|
|
41
|
+
c = EM::Channel.new
|
|
42
|
+
c.subscribe { |v| out << v }
|
|
43
|
+
Thread.new { c.push(1,2,3) }.join
|
|
44
|
+
assert out.empty?
|
|
45
|
+
|
|
46
|
+
EM.run { EM.next_tick { EM.stop } }
|
|
47
|
+
|
|
48
|
+
assert_equal [1,2,3], out
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def test_channel_reactor_thread_callback
|
|
52
|
+
out = []
|
|
53
|
+
c = EM::Channel.new
|
|
54
|
+
Thread.new { c.subscribe { |v| out << v } }.join
|
|
55
|
+
c.push(1,2,3)
|
|
56
|
+
assert out.empty?
|
|
57
|
+
|
|
58
|
+
EM.run { EM.next_tick { EM.stop } }
|
|
59
|
+
|
|
60
|
+
assert_equal [1,2,3], out
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def test_channel_num_subscribers
|
|
64
|
+
subs = 0
|
|
65
|
+
EM.run do
|
|
66
|
+
c = EM::Channel.new
|
|
67
|
+
c.subscribe { |v| }
|
|
68
|
+
c.subscribe { |v| }
|
|
69
|
+
EM.next_tick { EM.stop }
|
|
70
|
+
subs = c.num_subscribers
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
assert_equal subs, 2
|
|
74
|
+
end
|
|
75
|
+
end
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
require_relative 'em_test_helper'
|
|
2
|
+
require 'em/completion'
|
|
3
|
+
|
|
4
|
+
class TestCompletion < Test::Unit::TestCase
|
|
5
|
+
def completion
|
|
6
|
+
@completion ||= EM::Completion.new
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def crank
|
|
10
|
+
# This is a slow solution, but this just executes the next tick queue
|
|
11
|
+
# once. It's the easiest way for now.
|
|
12
|
+
EM.run { EM.stop }
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def results
|
|
16
|
+
@results ||= []
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def test_state
|
|
20
|
+
assert_equal :unknown, completion.state
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def test_succeed
|
|
24
|
+
completion.callback { |val| results << val }
|
|
25
|
+
completion.succeed :object
|
|
26
|
+
crank
|
|
27
|
+
assert_equal :succeeded, completion.state
|
|
28
|
+
assert_equal [:object], results
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def test_fail
|
|
32
|
+
completion.errback { |val| results << val }
|
|
33
|
+
completion.fail :object
|
|
34
|
+
crank
|
|
35
|
+
assert_equal :failed, completion.state
|
|
36
|
+
assert_equal [:object], results
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def test_callback
|
|
40
|
+
completion.callback { results << :callback }
|
|
41
|
+
completion.errback { results << :errback }
|
|
42
|
+
completion.succeed
|
|
43
|
+
crank
|
|
44
|
+
assert_equal [:callback], results
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def test_errback
|
|
48
|
+
completion.callback { results << :callback }
|
|
49
|
+
completion.errback { results << :errback }
|
|
50
|
+
completion.fail
|
|
51
|
+
crank
|
|
52
|
+
assert_equal [:errback], results
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def test_stateback
|
|
56
|
+
completion.stateback(:magic) { results << :stateback }
|
|
57
|
+
completion.change_state(:magic)
|
|
58
|
+
crank
|
|
59
|
+
assert_equal [:stateback], results
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def test_does_not_enqueue_when_completed
|
|
63
|
+
completion.callback { results << :callback }
|
|
64
|
+
completion.succeed
|
|
65
|
+
completion.errback { results << :errback }
|
|
66
|
+
completion.fail
|
|
67
|
+
crank
|
|
68
|
+
assert_equal [:callback], results
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def test_completed
|
|
72
|
+
assert_equal false, completion.completed?
|
|
73
|
+
completion.succeed
|
|
74
|
+
assert_equal true, completion.completed?
|
|
75
|
+
completion.fail
|
|
76
|
+
assert_equal true, completion.completed?
|
|
77
|
+
completion.change_state :magic
|
|
78
|
+
assert_equal false, completion.completed?
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def test_recursive_callbacks
|
|
82
|
+
completion.callback do |val|
|
|
83
|
+
results << val
|
|
84
|
+
completion.succeed :two
|
|
85
|
+
end
|
|
86
|
+
completion.callback do |val|
|
|
87
|
+
results << val
|
|
88
|
+
completion.succeed :three
|
|
89
|
+
end
|
|
90
|
+
completion.callback do |val|
|
|
91
|
+
results << val
|
|
92
|
+
end
|
|
93
|
+
completion.succeed :one
|
|
94
|
+
crank
|
|
95
|
+
assert_equal [:one, :two, :three], results
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def test_late_defined_callbacks
|
|
99
|
+
completion.callback { results << :one }
|
|
100
|
+
completion.succeed
|
|
101
|
+
crank
|
|
102
|
+
assert_equal [:one], results
|
|
103
|
+
completion.callback { results << :two }
|
|
104
|
+
crank
|
|
105
|
+
assert_equal [:one, :two], results
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def test_cleared_completions
|
|
109
|
+
completion.callback { results << :callback }
|
|
110
|
+
completion.errback { results << :errback }
|
|
111
|
+
|
|
112
|
+
completion.succeed
|
|
113
|
+
crank
|
|
114
|
+
completion.fail
|
|
115
|
+
crank
|
|
116
|
+
completion.succeed
|
|
117
|
+
crank
|
|
118
|
+
|
|
119
|
+
assert_equal [:callback], results
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def test_skip_completed_callbacks
|
|
123
|
+
completion.callback { results << :callback }
|
|
124
|
+
completion.succeed
|
|
125
|
+
crank
|
|
126
|
+
|
|
127
|
+
completion.errback { results << :errback }
|
|
128
|
+
completion.fail
|
|
129
|
+
crank
|
|
130
|
+
|
|
131
|
+
assert_equal [:callback], results
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def test_completions
|
|
135
|
+
completion.completion { results << :completion }
|
|
136
|
+
completion.succeed
|
|
137
|
+
crank
|
|
138
|
+
assert_equal [:completion], results
|
|
139
|
+
|
|
140
|
+
completion.change_state(:unknown)
|
|
141
|
+
results.clear
|
|
142
|
+
|
|
143
|
+
completion.completion { results << :completion }
|
|
144
|
+
completion.fail
|
|
145
|
+
crank
|
|
146
|
+
assert_equal [:completion], results
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def test_latent_completion
|
|
150
|
+
completion.completion { results << :completion }
|
|
151
|
+
completion.succeed
|
|
152
|
+
crank
|
|
153
|
+
completion.completion { results << :completion }
|
|
154
|
+
crank
|
|
155
|
+
assert_equal [:completion, :completion], results
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def test_timeout
|
|
159
|
+
args = [1, 2, 3]
|
|
160
|
+
EM.run do
|
|
161
|
+
completion.timeout(0.0001, *args)
|
|
162
|
+
completion.errback { |*errargs| results << errargs }
|
|
163
|
+
completion.completion { EM.stop }
|
|
164
|
+
EM.add_timer(0.1) { flunk 'test timed out' }
|
|
165
|
+
end
|
|
166
|
+
assert_equal [[1,2,3]], results
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def test_timeout_gets_cancelled
|
|
170
|
+
EM.run do
|
|
171
|
+
completion.timeout(0.0001, :timeout)
|
|
172
|
+
completion.errback { results << :errback }
|
|
173
|
+
completion.succeed
|
|
174
|
+
EM.add_timer(0.0002) { EM.stop }
|
|
175
|
+
end
|
|
176
|
+
assert_equal [], results
|
|
177
|
+
end
|
|
178
|
+
end
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
require_relative 'em_test_helper'
|
|
2
|
+
|
|
3
|
+
class TestConnectionCount < Test::Unit::TestCase
|
|
4
|
+
def teardown
|
|
5
|
+
EM.epoll = false
|
|
6
|
+
EM.kqueue = false
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def test_idle_connection_count
|
|
10
|
+
count = nil
|
|
11
|
+
EM.run {
|
|
12
|
+
count = EM.connection_count
|
|
13
|
+
EM.stop_event_loop
|
|
14
|
+
}
|
|
15
|
+
assert_equal(0, count)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Run this again with epoll enabled (if available)
|
|
19
|
+
def test_idle_connection_count_epoll
|
|
20
|
+
EM.epoll if EM.epoll?
|
|
21
|
+
|
|
22
|
+
count = nil
|
|
23
|
+
EM.run {
|
|
24
|
+
count = EM.connection_count
|
|
25
|
+
EM.stop_event_loop
|
|
26
|
+
}
|
|
27
|
+
assert_equal(0, count)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Run this again with kqueue enabled (if available)
|
|
31
|
+
def test_idle_connection_count_kqueue
|
|
32
|
+
EM.kqueue if EM.kqueue?
|
|
33
|
+
|
|
34
|
+
count = nil
|
|
35
|
+
EM.run {
|
|
36
|
+
count = EM.connection_count
|
|
37
|
+
EM.stop_event_loop
|
|
38
|
+
}
|
|
39
|
+
assert_equal(0, count)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
module Client
|
|
43
|
+
def connection_completed
|
|
44
|
+
$client_conns += 1
|
|
45
|
+
EM.stop if $client_conns == 3
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def test_with_some_connections
|
|
50
|
+
EM.run {
|
|
51
|
+
$client_conns = 0
|
|
52
|
+
$initial_conns = EM.connection_count
|
|
53
|
+
EM.start_server("127.0.0.1", 9999)
|
|
54
|
+
$server_conns = EM.connection_count
|
|
55
|
+
3.times { EM.connect("127.0.0.1", 9999, Client) }
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
assert_equal(0, $initial_conns)
|
|
59
|
+
assert_equal(1, $server_conns)
|
|
60
|
+
assert_equal(4, $client_conns + $server_conns)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
module DoubleCloseClient
|
|
64
|
+
def unbind
|
|
65
|
+
close_connection
|
|
66
|
+
$num_close_scheduled_1 = EM.num_close_scheduled
|
|
67
|
+
EM.next_tick do
|
|
68
|
+
$num_close_scheduled_2 = EM.num_close_scheduled
|
|
69
|
+
EM.stop
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def test_num_close_scheduled
|
|
75
|
+
omit_if(jruby?)
|
|
76
|
+
EM.run {
|
|
77
|
+
assert_equal(0, EM.num_close_scheduled)
|
|
78
|
+
EM.connect("127.0.0.1", 9999, DoubleCloseClient) # nothing listening on 9999
|
|
79
|
+
}
|
|
80
|
+
assert_equal(1, $num_close_scheduled_1)
|
|
81
|
+
assert_equal(0, $num_close_scheduled_2)
|
|
82
|
+
end
|
|
83
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
require_relative 'em_test_helper'
|
|
2
|
+
|
|
3
|
+
class TestConnectionWrite < Test::Unit::TestCase
|
|
4
|
+
|
|
5
|
+
# This test takes advantage of the fact that EM::_RunSelectOnce iterates over the connections twice:
|
|
6
|
+
# - once to determine which ones to call Write() on
|
|
7
|
+
# - and once to call Write() on each of them.
|
|
8
|
+
#
|
|
9
|
+
# But state may change in the meantime before Write() is finally called.
|
|
10
|
+
# And that is what we try to exploit to get Write() to be called when bWatchOnly is true, and bNotifyWritable is false,
|
|
11
|
+
# to cause an assertion failure.
|
|
12
|
+
|
|
13
|
+
module SimpleClient
|
|
14
|
+
def notify_writable
|
|
15
|
+
$conn2.notify_writable = false # Being naughty in callback
|
|
16
|
+
# If this doesn't crash anything, the test passed!
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def test_with_naughty_callback
|
|
21
|
+
EM.run do
|
|
22
|
+
r1, _ = IO.pipe
|
|
23
|
+
r2, _ = IO.pipe
|
|
24
|
+
|
|
25
|
+
# Adding EM.watches
|
|
26
|
+
$conn1 = EM.watch(r1, SimpleClient)
|
|
27
|
+
$conn2 = EM.watch(r2, SimpleClient)
|
|
28
|
+
|
|
29
|
+
$conn1.notify_writable = true
|
|
30
|
+
$conn2.notify_writable = true
|
|
31
|
+
|
|
32
|
+
EM.stop
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|