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.
Files changed (182) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +179 -0
  3. data/GNU +281 -0
  4. data/LICENSE +60 -0
  5. data/README.md +110 -0
  6. data/docs/DocumentationGuidesIndex.md +27 -0
  7. data/docs/GettingStarted.md +520 -0
  8. data/docs/old/ChangeLog +211 -0
  9. data/docs/old/DEFERRABLES +246 -0
  10. data/docs/old/EPOLL +141 -0
  11. data/docs/old/INSTALL +13 -0
  12. data/docs/old/KEYBOARD +42 -0
  13. data/docs/old/LEGAL +25 -0
  14. data/docs/old/LIGHTWEIGHT_CONCURRENCY +130 -0
  15. data/docs/old/PURE_RUBY +75 -0
  16. data/docs/old/RELEASE_NOTES +94 -0
  17. data/docs/old/SMTP +4 -0
  18. data/docs/old/SPAWNED_PROCESSES +148 -0
  19. data/docs/old/TODO +8 -0
  20. data/examples/guides/getting_started/01_eventmachine_echo_server.rb +18 -0
  21. data/examples/guides/getting_started/02_eventmachine_echo_server_that_recognizes_exit_command.rb +22 -0
  22. data/examples/guides/getting_started/03_simple_chat_server.rb +149 -0
  23. data/examples/guides/getting_started/04_simple_chat_server_step_one.rb +27 -0
  24. data/examples/guides/getting_started/05_simple_chat_server_step_two.rb +43 -0
  25. data/examples/guides/getting_started/06_simple_chat_server_step_three.rb +98 -0
  26. data/examples/guides/getting_started/07_simple_chat_server_step_four.rb +121 -0
  27. data/examples/guides/getting_started/08_simple_chat_server_step_five.rb +141 -0
  28. data/examples/old/ex_channel.rb +43 -0
  29. data/examples/old/ex_queue.rb +2 -0
  30. data/examples/old/ex_tick_loop_array.rb +15 -0
  31. data/examples/old/ex_tick_loop_counter.rb +32 -0
  32. data/examples/old/helper.rb +2 -0
  33. data/ext/binder.cpp +124 -0
  34. data/ext/binder.h +52 -0
  35. data/ext/cmain.cpp +1046 -0
  36. data/ext/ed.cpp +2243 -0
  37. data/ext/ed.h +463 -0
  38. data/ext/em.cpp +2378 -0
  39. data/ext/em.h +266 -0
  40. data/ext/eventmachine.h +152 -0
  41. data/ext/extconf.rb +291 -0
  42. data/ext/fastfilereader/extconf.rb +120 -0
  43. data/ext/fastfilereader/mapper.cpp +214 -0
  44. data/ext/fastfilereader/mapper.h +59 -0
  45. data/ext/fastfilereader/rubymain.cpp +126 -0
  46. data/ext/kb.cpp +79 -0
  47. data/ext/page.cpp +107 -0
  48. data/ext/page.h +51 -0
  49. data/ext/pipe.cpp +354 -0
  50. data/ext/project.h +174 -0
  51. data/ext/rubymain.cpp +1643 -0
  52. data/ext/ssl.cpp +701 -0
  53. data/ext/ssl.h +103 -0
  54. data/ext/wait_for_single_fd.h +36 -0
  55. data/java/.classpath +8 -0
  56. data/java/.project +17 -0
  57. data/java/src/com/rubyeventmachine/EmReactor.java +625 -0
  58. data/java/src/com/rubyeventmachine/EmReactorException.java +40 -0
  59. data/java/src/com/rubyeventmachine/EmReactorInterface.java +70 -0
  60. data/java/src/com/rubyeventmachine/EventableChannel.java +72 -0
  61. data/java/src/com/rubyeventmachine/EventableDatagramChannel.java +201 -0
  62. data/java/src/com/rubyeventmachine/EventableSocketChannel.java +415 -0
  63. data/java/src/com/rubyeventmachine/NullEmReactor.java +157 -0
  64. data/java/src/com/rubyeventmachine/NullEventableChannel.java +81 -0
  65. data/lib/em/buftok.rb +59 -0
  66. data/lib/em/callback.rb +58 -0
  67. data/lib/em/channel.rb +69 -0
  68. data/lib/em/completion.rb +307 -0
  69. data/lib/em/connection.rb +802 -0
  70. data/lib/em/deferrable/pool.rb +2 -0
  71. data/lib/em/deferrable.rb +210 -0
  72. data/lib/em/file_watch.rb +73 -0
  73. data/lib/em/future.rb +61 -0
  74. data/lib/em/io_streamer.rb +68 -0
  75. data/lib/em/iterator.rb +252 -0
  76. data/lib/em/messages.rb +66 -0
  77. data/lib/em/pool.rb +151 -0
  78. data/lib/em/process_watch.rb +45 -0
  79. data/lib/em/processes.rb +123 -0
  80. data/lib/em/protocols/header_and_content.rb +138 -0
  81. data/lib/em/protocols/httpclient.rb +303 -0
  82. data/lib/em/protocols/httpclient2.rb +602 -0
  83. data/lib/em/protocols/line_and_text.rb +125 -0
  84. data/lib/em/protocols/line_protocol.rb +33 -0
  85. data/lib/em/protocols/linetext2.rb +179 -0
  86. data/lib/em/protocols/memcache.rb +331 -0
  87. data/lib/em/protocols/object_protocol.rb +46 -0
  88. data/lib/em/protocols/postgres3.rb +246 -0
  89. data/lib/em/protocols/saslauth.rb +175 -0
  90. data/lib/em/protocols/smtpclient.rb +394 -0
  91. data/lib/em/protocols/smtpserver.rb +666 -0
  92. data/lib/em/protocols/socks4.rb +66 -0
  93. data/lib/em/protocols/stomp.rb +205 -0
  94. data/lib/em/protocols/tcptest.rb +54 -0
  95. data/lib/em/protocols.rb +37 -0
  96. data/lib/em/pure_ruby.rb +1300 -0
  97. data/lib/em/queue.rb +80 -0
  98. data/lib/em/resolver.rb +232 -0
  99. data/lib/em/spawnable.rb +84 -0
  100. data/lib/em/streamer.rb +118 -0
  101. data/lib/em/threaded_resource.rb +90 -0
  102. data/lib/em/tick_loop.rb +85 -0
  103. data/lib/em/timers.rb +61 -0
  104. data/lib/em/version.rb +3 -0
  105. data/lib/eventmachine.rb +1602 -0
  106. data/lib/jeventmachine.rb +319 -0
  107. data/rakelib/package.rake +120 -0
  108. data/rakelib/test.rake +6 -0
  109. data/rakelib/test_pure.rake +11 -0
  110. data/tests/client.crt +31 -0
  111. data/tests/client.key +51 -0
  112. data/tests/dhparam.pem +13 -0
  113. data/tests/em_ssl_handlers.rb +165 -0
  114. data/tests/em_test_helper.rb +198 -0
  115. data/tests/encoded_client.key +54 -0
  116. data/tests/jruby/test_jeventmachine.rb +38 -0
  117. data/tests/test_attach.rb +199 -0
  118. data/tests/test_basic.rb +321 -0
  119. data/tests/test_channel.rb +75 -0
  120. data/tests/test_completion.rb +178 -0
  121. data/tests/test_connection_count.rb +83 -0
  122. data/tests/test_connection_write.rb +35 -0
  123. data/tests/test_defer.rb +35 -0
  124. data/tests/test_deferrable.rb +35 -0
  125. data/tests/test_epoll.rb +141 -0
  126. data/tests/test_error_handler.rb +38 -0
  127. data/tests/test_exc.rb +37 -0
  128. data/tests/test_file_watch.rb +86 -0
  129. data/tests/test_fork.rb +75 -0
  130. data/tests/test_futures.rb +170 -0
  131. data/tests/test_handler_check.rb +35 -0
  132. data/tests/test_hc.rb +155 -0
  133. data/tests/test_httpclient.rb +238 -0
  134. data/tests/test_httpclient2.rb +132 -0
  135. data/tests/test_idle_connection.rb +31 -0
  136. data/tests/test_inactivity_timeout.rb +102 -0
  137. data/tests/test_io_streamer.rb +48 -0
  138. data/tests/test_ipv4.rb +96 -0
  139. data/tests/test_ipv6.rb +107 -0
  140. data/tests/test_iterator.rb +122 -0
  141. data/tests/test_kb.rb +28 -0
  142. data/tests/test_keepalive.rb +113 -0
  143. data/tests/test_line_protocol.rb +33 -0
  144. data/tests/test_ltp.rb +155 -0
  145. data/tests/test_ltp2.rb +332 -0
  146. data/tests/test_many_fds.rb +21 -0
  147. data/tests/test_next_tick.rb +104 -0
  148. data/tests/test_object_protocol.rb +36 -0
  149. data/tests/test_pause.rb +109 -0
  150. data/tests/test_pending_connect_timeout.rb +52 -0
  151. data/tests/test_pool.rb +196 -0
  152. data/tests/test_process_watch.rb +50 -0
  153. data/tests/test_processes.rb +147 -0
  154. data/tests/test_proxy_connection.rb +180 -0
  155. data/tests/test_pure.rb +156 -0
  156. data/tests/test_queue.rb +64 -0
  157. data/tests/test_resolver.rb +129 -0
  158. data/tests/test_running.rb +14 -0
  159. data/tests/test_sasl.rb +46 -0
  160. data/tests/test_send_file.rb +217 -0
  161. data/tests/test_servers.rb +32 -0
  162. data/tests/test_shutdown_hooks.rb +23 -0
  163. data/tests/test_smtpclient.rb +75 -0
  164. data/tests/test_smtpserver.rb +90 -0
  165. data/tests/test_sock_opt.rb +53 -0
  166. data/tests/test_spawn.rb +290 -0
  167. data/tests/test_ssl_args.rb +70 -0
  168. data/tests/test_ssl_dhparam.rb +57 -0
  169. data/tests/test_ssl_ecdh_curve.rb +57 -0
  170. data/tests/test_ssl_extensions.rb +24 -0
  171. data/tests/test_ssl_inline_cert.rb +222 -0
  172. data/tests/test_ssl_methods.rb +31 -0
  173. data/tests/test_ssl_protocols.rb +190 -0
  174. data/tests/test_ssl_verify.rb +108 -0
  175. data/tests/test_stomp.rb +38 -0
  176. data/tests/test_system.rb +46 -0
  177. data/tests/test_threaded_resource.rb +68 -0
  178. data/tests/test_tick_loop.rb +58 -0
  179. data/tests/test_timers.rb +150 -0
  180. data/tests/test_ud.rb +8 -0
  181. data/tests/test_unbind_reason.rb +40 -0
  182. metadata +389 -0
@@ -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