sonixlabs-eventmachine-java 1.0.0.rc.4-java
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.
- data/.gitignore +22 -0
- data/.yardopts +7 -0
- data/GNU +281 -0
- data/Gemfile +3 -0
- data/LICENSE +60 -0
- data/README.md +109 -0
- data/Rakefile +20 -0
- data/docs/DocumentationGuidesIndex.md +27 -0
- data/docs/GettingStarted.md +521 -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/eventmachine.gemspec +34 -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 +46 -0
- data/ext/cmain.cpp +876 -0
- data/ext/ed.cpp +1973 -0
- data/ext/ed.h +422 -0
- data/ext/em.cpp +2353 -0
- data/ext/em.h +239 -0
- data/ext/eventmachine.h +127 -0
- data/ext/extconf.rb +176 -0
- data/ext/fastfilereader/extconf.rb +103 -0
- data/ext/fastfilereader/mapper.cpp +214 -0
- data/ext/fastfilereader/mapper.h +59 -0
- data/ext/fastfilereader/rubymain.cpp +127 -0
- data/ext/kb.cpp +79 -0
- data/ext/page.cpp +107 -0
- data/ext/page.h +51 -0
- data/ext/pipe.cpp +347 -0
- data/ext/project.h +156 -0
- data/ext/rubymain.cpp +1297 -0
- data/ext/ssl.cpp +468 -0
- data/ext/ssl.h +94 -0
- data/java/.classpath +8 -0
- data/java/.project +17 -0
- data/java/src/com/rubyeventmachine/EmReactor.java +588 -0
- data/java/src/com/rubyeventmachine/EmReactorException.java +40 -0
- data/java/src/com/rubyeventmachine/EventableChannel.java +70 -0
- data/java/src/com/rubyeventmachine/EventableDatagramChannel.java +195 -0
- data/java/src/com/rubyeventmachine/EventableSocketChannel.java +364 -0
- data/lib/em/buftok.rb +110 -0
- data/lib/em/callback.rb +58 -0
- data/lib/em/channel.rb +64 -0
- data/lib/em/completion.rb +304 -0
- data/lib/em/connection.rb +712 -0
- data/lib/em/deferrable.rb +210 -0
- data/lib/em/deferrable/pool.rb +2 -0
- data/lib/em/file_watch.rb +73 -0
- data/lib/em/future.rb +61 -0
- data/lib/em/iterator.rb +270 -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.rb +36 -0
- data/lib/em/protocols/header_and_content.rb +138 -0
- data/lib/em/protocols/httpclient.rb +279 -0
- data/lib/em/protocols/httpclient2.rb +600 -0
- data/lib/em/protocols/line_and_text.rb +125 -0
- data/lib/em/protocols/line_protocol.rb +29 -0
- data/lib/em/protocols/linetext2.rb +161 -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 +365 -0
- data/lib/em/protocols/smtpserver.rb +640 -0
- data/lib/em/protocols/socks4.rb +66 -0
- data/lib/em/protocols/stomp.rb +202 -0
- data/lib/em/protocols/tcptest.rb +54 -0
- data/lib/em/pure_ruby.rb +1017 -0
- data/lib/em/queue.rb +71 -0
- data/lib/em/resolver.rb +192 -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 +1532 -0
- data/lib/jeventmachine.rb +284 -0
- data/lib/sonixlabs-eventmachine-java.rb +1 -0
- data/rakelib/cpp.rake_example +77 -0
- data/rakelib/package.rake +98 -0
- data/rakelib/test.rake +8 -0
- data/tests/client.crt +31 -0
- data/tests/client.key +51 -0
- data/tests/em_test_helper.rb +64 -0
- data/tests/test_attach.rb +126 -0
- data/tests/test_basic.rb +294 -0
- data/tests/test_channel.rb +62 -0
- data/tests/test_completion.rb +177 -0
- data/tests/test_connection_count.rb +33 -0
- data/tests/test_defer.rb +18 -0
- data/tests/test_deferrable.rb +35 -0
- data/tests/test_epoll.rb +130 -0
- data/tests/test_error_handler.rb +38 -0
- data/tests/test_exc.rb +28 -0
- data/tests/test_file_watch.rb +65 -0
- data/tests/test_futures.rb +170 -0
- data/tests/test_get_sock_opt.rb +37 -0
- data/tests/test_handler_check.rb +35 -0
- data/tests/test_hc.rb +155 -0
- data/tests/test_httpclient.rb +190 -0
- data/tests/test_httpclient2.rb +128 -0
- data/tests/test_idle_connection.rb +23 -0
- data/tests/test_inactivity_timeout.rb +54 -0
- data/tests/test_kb.rb +34 -0
- data/tests/test_ltp.rb +138 -0
- data/tests/test_ltp2.rb +288 -0
- data/tests/test_next_tick.rb +104 -0
- data/tests/test_object_protocol.rb +36 -0
- data/tests/test_pause.rb +78 -0
- data/tests/test_pending_connect_timeout.rb +52 -0
- data/tests/test_pool.rb +194 -0
- data/tests/test_process_watch.rb +48 -0
- data/tests/test_processes.rb +128 -0
- data/tests/test_proxy_connection.rb +180 -0
- data/tests/test_pure.rb +88 -0
- data/tests/test_queue.rb +50 -0
- data/tests/test_resolver.rb +55 -0
- data/tests/test_running.rb +14 -0
- data/tests/test_sasl.rb +47 -0
- data/tests/test_send_file.rb +217 -0
- data/tests/test_servers.rb +33 -0
- data/tests/test_set_sock_opt.rb +37 -0
- data/tests/test_shutdown_hooks.rb +23 -0
- data/tests/test_smtpclient.rb +55 -0
- data/tests/test_smtpserver.rb +57 -0
- data/tests/test_spawn.rb +293 -0
- data/tests/test_ssl_args.rb +78 -0
- data/tests/test_ssl_methods.rb +48 -0
- data/tests/test_ssl_verify.rb +82 -0
- data/tests/test_threaded_resource.rb +53 -0
- data/tests/test_tick_loop.rb +59 -0
- data/tests/test_timers.rb +123 -0
- data/tests/test_ud.rb +8 -0
- data/tests/test_unbind_reason.rb +48 -0
- metadata +301 -0
data/tests/test_ltp2.rb
ADDED
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
require 'em_test_helper'
|
|
2
|
+
|
|
3
|
+
# TODO!!! Need tests for overlength headers and text bodies.
|
|
4
|
+
|
|
5
|
+
class TestLineText2 < Test::Unit::TestCase
|
|
6
|
+
|
|
7
|
+
# Run each of these tests two ways: passing in the whole test-dataset in one chunk,
|
|
8
|
+
# and passing it in one character at a time.
|
|
9
|
+
|
|
10
|
+
class Basic
|
|
11
|
+
include EM::Protocols::LineText2
|
|
12
|
+
attr_reader :lines
|
|
13
|
+
def receive_line line
|
|
14
|
+
(@lines ||= []) << line
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
def test_basic
|
|
18
|
+
testdata = "Line 1\nLine 2\r\nLine 3\n"
|
|
19
|
+
|
|
20
|
+
a = Basic.new
|
|
21
|
+
a.receive_data testdata
|
|
22
|
+
assert_equal( ["Line 1", "Line 2", "Line 3"], a.lines )
|
|
23
|
+
|
|
24
|
+
a = Basic.new
|
|
25
|
+
testdata.length.times {|i| a.receive_data( testdata[i...i+1] ) }
|
|
26
|
+
assert_equal( ["Line 1", "Line 2", "Line 3"], a.lines )
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
class ChangeDelimiter
|
|
30
|
+
include EM::Protocols::LineText2
|
|
31
|
+
attr_reader :lines
|
|
32
|
+
def initialize *args
|
|
33
|
+
super
|
|
34
|
+
@delim = "A"
|
|
35
|
+
set_delimiter @delim
|
|
36
|
+
end
|
|
37
|
+
def receive_line line
|
|
38
|
+
(@lines ||= []) << line
|
|
39
|
+
set_delimiter( @delim.succ! )
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def test_change_delimiter
|
|
44
|
+
testdata = %Q(LineaALinebBLinecCLinedD)
|
|
45
|
+
|
|
46
|
+
a = ChangeDelimiter.new
|
|
47
|
+
a.receive_data testdata
|
|
48
|
+
assert_equal( ["Linea", "Lineb", "Linec", "Lined"], a.lines )
|
|
49
|
+
|
|
50
|
+
a = ChangeDelimiter.new
|
|
51
|
+
testdata.length.times {|i| a.receive_data( testdata[i...i+1] ) }
|
|
52
|
+
assert_equal( ["Linea", "Lineb", "Linec", "Lined"], a.lines )
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
#--
|
|
57
|
+
# Test two lines followed by an empty line, ten bytes of binary data, then
|
|
58
|
+
# two more lines.
|
|
59
|
+
|
|
60
|
+
class Binary
|
|
61
|
+
include EM::Protocols::LineText2
|
|
62
|
+
attr_reader :lines, :body
|
|
63
|
+
def initialize *args
|
|
64
|
+
super
|
|
65
|
+
@lines = []
|
|
66
|
+
@body = nil
|
|
67
|
+
end
|
|
68
|
+
def receive_line ln
|
|
69
|
+
if ln == ""
|
|
70
|
+
set_text_mode 10
|
|
71
|
+
else
|
|
72
|
+
@lines << ln
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
def receive_binary_data data
|
|
76
|
+
@body = data
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def test_binary
|
|
81
|
+
testdata = %Q(Line 1
|
|
82
|
+
Line 2
|
|
83
|
+
|
|
84
|
+
0000000000Line 3
|
|
85
|
+
Line 4
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
a = Binary.new
|
|
89
|
+
a.receive_data testdata
|
|
90
|
+
assert_equal( ["Line 1", "Line 2", "Line 3", "Line 4"], a.lines)
|
|
91
|
+
assert_equal( "0000000000", a.body )
|
|
92
|
+
|
|
93
|
+
a = Binary.new
|
|
94
|
+
testdata.length.times {|i| a.receive_data( testdata[i...i+1] ) }
|
|
95
|
+
assert_equal( ["Line 1", "Line 2", "Line 3", "Line 4"], a.lines)
|
|
96
|
+
assert_equal( "0000000000", a.body )
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
# Test unsized binary data. The expectation is that each chunk of it
|
|
101
|
+
# will be passed to us as it it received.
|
|
102
|
+
class UnsizedBinary
|
|
103
|
+
include EM::Protocols::LineText2
|
|
104
|
+
attr_reader :n_calls, :body
|
|
105
|
+
def initialize *args
|
|
106
|
+
super
|
|
107
|
+
set_text_mode
|
|
108
|
+
end
|
|
109
|
+
def receive_binary_data data
|
|
110
|
+
@n_calls ||= 0
|
|
111
|
+
@n_calls += 1
|
|
112
|
+
(@body ||= "") << data
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def test_unsized_binary
|
|
117
|
+
testdata = "X\0" * 1000
|
|
118
|
+
|
|
119
|
+
a = UnsizedBinary.new
|
|
120
|
+
a.receive_data testdata
|
|
121
|
+
assert_equal( 1, a.n_calls )
|
|
122
|
+
assert_equal( testdata, a.body )
|
|
123
|
+
|
|
124
|
+
a = UnsizedBinary.new
|
|
125
|
+
testdata.length.times {|i| a.receive_data( testdata[i...i+1] ) }
|
|
126
|
+
assert_equal( 2000, a.n_calls )
|
|
127
|
+
assert_equal( testdata, a.body )
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
# Test binary data with a "throw back" into line-mode.
|
|
132
|
+
class ThrowBack
|
|
133
|
+
include EM::Protocols::LineText2
|
|
134
|
+
attr_reader :headers
|
|
135
|
+
def initialize *args
|
|
136
|
+
super
|
|
137
|
+
@headers = []
|
|
138
|
+
@n_bytes = 0
|
|
139
|
+
set_text_mode
|
|
140
|
+
end
|
|
141
|
+
def receive_binary_data data
|
|
142
|
+
wanted = 25 - @n_bytes
|
|
143
|
+
will_take = if data.length > wanted
|
|
144
|
+
data.length - wanted
|
|
145
|
+
else
|
|
146
|
+
data.length
|
|
147
|
+
end
|
|
148
|
+
@n_bytes += will_take
|
|
149
|
+
|
|
150
|
+
if @n_bytes == 25
|
|
151
|
+
set_line_mode( data[will_take..-1] )
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
def receive_line ln
|
|
155
|
+
@headers << ln
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
def test_throw_back
|
|
159
|
+
testdata = "Line\n" * 10
|
|
160
|
+
|
|
161
|
+
a = ThrowBack.new
|
|
162
|
+
a.receive_data testdata
|
|
163
|
+
assert_equal( ["Line"] * 5, a.headers )
|
|
164
|
+
|
|
165
|
+
a = ThrowBack.new
|
|
166
|
+
testdata.length.times {|i| a.receive_data( testdata[i...i+1] ) }
|
|
167
|
+
assert_equal( ["Line"] * 5, a.headers )
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
# Test multi-character line delimiters.
|
|
171
|
+
# Also note that the test data has a "tail" with no delimiter, that will be
|
|
172
|
+
# discarded, but cf. the BinaryTail test.
|
|
173
|
+
# TODO!!! This test doesn't work in the byte-by-byte case.
|
|
174
|
+
class Multichar
|
|
175
|
+
include EM::Protocols::LineText2
|
|
176
|
+
attr_reader :lines
|
|
177
|
+
def initialize *args
|
|
178
|
+
super
|
|
179
|
+
@lines = []
|
|
180
|
+
set_delimiter "012"
|
|
181
|
+
end
|
|
182
|
+
def receive_line ln
|
|
183
|
+
@lines << ln
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
def test_multichar
|
|
187
|
+
testdata = "Line012Line012Line012Line"
|
|
188
|
+
|
|
189
|
+
a = Multichar.new
|
|
190
|
+
a.receive_data testdata
|
|
191
|
+
assert_equal( ["Line"]*3, a.lines )
|
|
192
|
+
|
|
193
|
+
a = Multichar.new
|
|
194
|
+
testdata.length.times {|i| a.receive_data( testdata[i...i+1] ) }
|
|
195
|
+
# DOESN'T WORK in this case. Multi-character delimiters are broken.
|
|
196
|
+
#assert_equal( ["Line"]*3, a.lines )
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
# Test a binary "tail," when a sized binary transfer doesn't complete because
|
|
200
|
+
# of an unbind. We get a partial result.
|
|
201
|
+
class BinaryTail
|
|
202
|
+
include EM::Protocols::LineText2
|
|
203
|
+
attr_reader :data
|
|
204
|
+
def initialize *args
|
|
205
|
+
super
|
|
206
|
+
@data = ""
|
|
207
|
+
set_text_mode 1000
|
|
208
|
+
end
|
|
209
|
+
def receive_binary_data data
|
|
210
|
+
# we expect to get all the data in one chunk, even in the byte-by-byte case,
|
|
211
|
+
# because sized transfers by definition give us exactly one call to
|
|
212
|
+
# #receive_binary_data.
|
|
213
|
+
@data = data
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
def test_binary_tail
|
|
217
|
+
testdata = "0" * 500
|
|
218
|
+
|
|
219
|
+
a = BinaryTail.new
|
|
220
|
+
a.receive_data testdata
|
|
221
|
+
a.unbind
|
|
222
|
+
assert_equal( "0" * 500, a.data )
|
|
223
|
+
|
|
224
|
+
a = BinaryTail.new
|
|
225
|
+
testdata.length.times {|i| a.receive_data( testdata[i...i+1] ) }
|
|
226
|
+
a.unbind
|
|
227
|
+
assert_equal( "0" * 500, a.data )
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
# Test an end-of-binary call. Arrange to receive binary data but don't bother counting it
|
|
232
|
+
# as it comes. Rely on getting receive_end_of_binary_data to signal the transition back to
|
|
233
|
+
# line mode.
|
|
234
|
+
# At the present time, this isn't strictly necessary with sized binary chunks because by
|
|
235
|
+
# definition we accumulate them and make exactly one call to receive_binary_data, but
|
|
236
|
+
# we may want to support a mode in the future that would break up large chunks into multiple
|
|
237
|
+
# calls.
|
|
238
|
+
class LazyBinary
|
|
239
|
+
include EM::Protocols::LineText2
|
|
240
|
+
attr_reader :data, :end
|
|
241
|
+
def initialize *args
|
|
242
|
+
super
|
|
243
|
+
@data = ""
|
|
244
|
+
set_text_mode 1000
|
|
245
|
+
end
|
|
246
|
+
def receive_binary_data data
|
|
247
|
+
# we expect to get all the data in one chunk, even in the byte-by-byte case,
|
|
248
|
+
# because sized transfers by definition give us exactly one call to
|
|
249
|
+
# #receive_binary_data.
|
|
250
|
+
@data = data
|
|
251
|
+
end
|
|
252
|
+
def receive_end_of_binary_data
|
|
253
|
+
@end = true
|
|
254
|
+
end
|
|
255
|
+
end
|
|
256
|
+
def test_receive_end_of_binary_data
|
|
257
|
+
testdata = "_" * 1000
|
|
258
|
+
a = LazyBinary.new
|
|
259
|
+
testdata.length.times {|i| a.receive_data( testdata[i...i+1] ) }
|
|
260
|
+
assert_equal( "_" * 1000, a.data )
|
|
261
|
+
assert( a.end )
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
# This tests a bug fix in which calling set_text_mode failed when called
|
|
266
|
+
# inside receive_binary_data.
|
|
267
|
+
#
|
|
268
|
+
class BinaryPair
|
|
269
|
+
include EM::Protocols::LineText2
|
|
270
|
+
attr_reader :sizes
|
|
271
|
+
def initialize *args
|
|
272
|
+
super
|
|
273
|
+
set_text_mode 1
|
|
274
|
+
@sizes = []
|
|
275
|
+
end
|
|
276
|
+
def receive_binary_data dt
|
|
277
|
+
@sizes << dt.length
|
|
278
|
+
set_text_mode( (dt.length == 1) ? 2 : 1 )
|
|
279
|
+
end
|
|
280
|
+
end
|
|
281
|
+
def test_binary_pairs
|
|
282
|
+
test_data = "123" * 5
|
|
283
|
+
a = BinaryPair.new
|
|
284
|
+
a.receive_data test_data
|
|
285
|
+
assert_equal( [1,2,1,2,1,2,1,2,1,2], a.sizes )
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
end
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
require 'em_test_helper'
|
|
2
|
+
|
|
3
|
+
class TestNextTick < Test::Unit::TestCase
|
|
4
|
+
|
|
5
|
+
def test_tick_arg
|
|
6
|
+
pr = proc {EM.stop}
|
|
7
|
+
EM.run {
|
|
8
|
+
EM.next_tick pr
|
|
9
|
+
}
|
|
10
|
+
assert true
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def test_tick_block
|
|
14
|
+
EM.run {
|
|
15
|
+
EM.next_tick {EM.stop}
|
|
16
|
+
}
|
|
17
|
+
assert true
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# This illustrates the solution to a long-standing problem.
|
|
21
|
+
# It's now possible to correctly nest calls to EM#run.
|
|
22
|
+
# See the source code commentary for EM#run for more info.
|
|
23
|
+
#
|
|
24
|
+
def test_run_run
|
|
25
|
+
EM.run {
|
|
26
|
+
EM.run {
|
|
27
|
+
EM.next_tick {EM.stop}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def test_pre_run_queue
|
|
33
|
+
x = false
|
|
34
|
+
EM.next_tick { EM.stop; x = true }
|
|
35
|
+
EM.run { EM.add_timer(0.01) { EM.stop } }
|
|
36
|
+
assert x
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def test_cleanup_after_stop
|
|
40
|
+
x = true
|
|
41
|
+
EM.run{
|
|
42
|
+
EM.next_tick{
|
|
43
|
+
EM.stop
|
|
44
|
+
EM.next_tick{ x=false }
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
EM.run{
|
|
48
|
+
EM.next_tick{ EM.stop }
|
|
49
|
+
}
|
|
50
|
+
assert x
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# We now support an additional parameter for EM#run.
|
|
54
|
+
# You can pass two procs to EM#run now. The first is executed as the normal
|
|
55
|
+
# run block. The second (if given) is scheduled for execution after the
|
|
56
|
+
# reactor loop completes.
|
|
57
|
+
# The reason for supporting this is subtle. There has always been an expectation
|
|
58
|
+
# that EM#run doesn't return until after the reactor loop ends. But now it's
|
|
59
|
+
# possible to nest calls to EM#run, which means that a nested call WILL
|
|
60
|
+
# RETURN. In order to write code that will run correctly either way, it's
|
|
61
|
+
# recommended to put any code which must execute after the reactor completes
|
|
62
|
+
# in the second parameter.
|
|
63
|
+
#
|
|
64
|
+
def test_run_run_2
|
|
65
|
+
a = proc {EM.stop}
|
|
66
|
+
b = proc {assert true}
|
|
67
|
+
EM.run a, b
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
# This illustrates that EM#run returns when it's called nested.
|
|
72
|
+
# This isn't a feature, rather it's something to be wary of when writing code
|
|
73
|
+
# that must run correctly even if EM#run is called while a reactor is already
|
|
74
|
+
# running.
|
|
75
|
+
def test_run_run_3
|
|
76
|
+
a = []
|
|
77
|
+
EM.run {
|
|
78
|
+
EM.run proc {EM.stop}, proc {a << 2}
|
|
79
|
+
a << 1
|
|
80
|
+
}
|
|
81
|
+
assert_equal( [1,2], a )
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def test_schedule_on_reactor_thread
|
|
86
|
+
x = false
|
|
87
|
+
EM.run do
|
|
88
|
+
EM.schedule { x = true }
|
|
89
|
+
EM.stop
|
|
90
|
+
end
|
|
91
|
+
assert x
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def test_schedule_from_thread
|
|
95
|
+
x = false
|
|
96
|
+
EM.run do
|
|
97
|
+
Thread.new { EM.schedule { x = true } }.join
|
|
98
|
+
assert !x
|
|
99
|
+
EM.next_tick { EM.stop }
|
|
100
|
+
end
|
|
101
|
+
assert x
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
require 'em_test_helper'
|
|
2
|
+
|
|
3
|
+
class TestObjectProtocol < Test::Unit::TestCase
|
|
4
|
+
module Server
|
|
5
|
+
include EM::P::ObjectProtocol
|
|
6
|
+
def post_init
|
|
7
|
+
send_object :hello=>'world'
|
|
8
|
+
end
|
|
9
|
+
def receive_object obj
|
|
10
|
+
$server = obj
|
|
11
|
+
EM.stop
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
module Client
|
|
16
|
+
include EM::P::ObjectProtocol
|
|
17
|
+
def receive_object obj
|
|
18
|
+
$client = obj
|
|
19
|
+
send_object 'you_said'=>obj
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def setup
|
|
24
|
+
@port = next_port
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def test_send_receive
|
|
28
|
+
EM.run{
|
|
29
|
+
EM.start_server "127.0.0.1", @port, Server
|
|
30
|
+
EM.connect "127.0.0.1", @port, Client
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
assert($client == {:hello=>'world'})
|
|
34
|
+
assert($server == {'you_said'=>{:hello=>'world'}})
|
|
35
|
+
end
|
|
36
|
+
end
|
data/tests/test_pause.rb
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
require 'em_test_helper'
|
|
2
|
+
|
|
3
|
+
class TestPause < Test::Unit::TestCase
|
|
4
|
+
if EM.respond_to? :pause_connection
|
|
5
|
+
def setup
|
|
6
|
+
@port = next_port
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def teardown
|
|
10
|
+
assert(!EM.reactor_running?)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def test_pause_resume
|
|
14
|
+
server = nil
|
|
15
|
+
|
|
16
|
+
s_rx = c_rx = 0
|
|
17
|
+
|
|
18
|
+
test_server = Module.new do
|
|
19
|
+
define_method :post_init do
|
|
20
|
+
server = self
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
define_method :receive_data do |data|
|
|
24
|
+
s_rx += 1
|
|
25
|
+
|
|
26
|
+
EM.add_periodic_timer(0.01) { send_data 'hi' }
|
|
27
|
+
send_data 'hi'
|
|
28
|
+
|
|
29
|
+
# pause server, now no outgoing data will actually
|
|
30
|
+
# be sent and no more incoming data will be received
|
|
31
|
+
pause
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
test_client = Module.new do
|
|
36
|
+
def post_init
|
|
37
|
+
EM.add_periodic_timer(0.01) do
|
|
38
|
+
send_data 'hello'
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
define_method :receive_data do |data|
|
|
43
|
+
c_rx += 1
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
EM.run do
|
|
48
|
+
EM.start_server "127.0.0.1", @port, test_server
|
|
49
|
+
EM.connect "127.0.0.1", @port, test_client
|
|
50
|
+
|
|
51
|
+
EM.add_timer(0.05) do
|
|
52
|
+
assert_equal 1, s_rx
|
|
53
|
+
assert_equal 0, c_rx
|
|
54
|
+
assert server.paused?
|
|
55
|
+
|
|
56
|
+
# resume server, queued outgoing and incoming data will be flushed
|
|
57
|
+
server.resume
|
|
58
|
+
|
|
59
|
+
assert !server.paused?
|
|
60
|
+
|
|
61
|
+
EM.add_timer(0.05) do
|
|
62
|
+
assert server.paused?
|
|
63
|
+
assert s_rx > 1
|
|
64
|
+
assert c_rx > 0
|
|
65
|
+
EM.stop
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
else
|
|
71
|
+
warn "EM.pause_connection not implemented, skipping tests in #{__FILE__}"
|
|
72
|
+
|
|
73
|
+
# Because some rubies will complain if a TestCase class has no tests
|
|
74
|
+
def test_em_pause_connection_not_implemented
|
|
75
|
+
assert true
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|