eventmachine 0.12.6-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (136) hide show
  1. data/.gitignore +13 -0
  2. data/Rakefile +262 -0
  3. data/docs/COPYING +60 -0
  4. data/docs/ChangeLog +211 -0
  5. data/docs/DEFERRABLES +138 -0
  6. data/docs/EPOLL +141 -0
  7. data/docs/GNU +281 -0
  8. data/docs/INSTALL +15 -0
  9. data/docs/KEYBOARD +38 -0
  10. data/docs/LEGAL +25 -0
  11. data/docs/LIGHTWEIGHT_CONCURRENCY +72 -0
  12. data/docs/PURE_RUBY +77 -0
  13. data/docs/README +74 -0
  14. data/docs/RELEASE_NOTES +96 -0
  15. data/docs/SMTP +9 -0
  16. data/docs/SPAWNED_PROCESSES +93 -0
  17. data/docs/TODO +10 -0
  18. data/eventmachine.gemspec +32 -0
  19. data/ext/binder.cpp +126 -0
  20. data/ext/binder.h +48 -0
  21. data/ext/cmain.cpp +586 -0
  22. data/ext/cplusplus.cpp +193 -0
  23. data/ext/ed.cpp +1522 -0
  24. data/ext/ed.h +380 -0
  25. data/ext/em.cpp +1937 -0
  26. data/ext/em.h +186 -0
  27. data/ext/emwin.cpp +300 -0
  28. data/ext/emwin.h +94 -0
  29. data/ext/epoll.cpp +26 -0
  30. data/ext/epoll.h +25 -0
  31. data/ext/eventmachine.h +98 -0
  32. data/ext/eventmachine_cpp.h +95 -0
  33. data/ext/extconf.rb +129 -0
  34. data/ext/fastfilereader/extconf.rb +77 -0
  35. data/ext/fastfilereader/mapper.cpp +214 -0
  36. data/ext/fastfilereader/mapper.h +59 -0
  37. data/ext/fastfilereader/rubymain.cpp +127 -0
  38. data/ext/files.cpp +94 -0
  39. data/ext/files.h +65 -0
  40. data/ext/kb.cpp +82 -0
  41. data/ext/page.cpp +107 -0
  42. data/ext/page.h +51 -0
  43. data/ext/pipe.cpp +351 -0
  44. data/ext/project.h +119 -0
  45. data/ext/rubymain.cpp +847 -0
  46. data/ext/sigs.cpp +89 -0
  47. data/ext/sigs.h +32 -0
  48. data/ext/ssl.cpp +423 -0
  49. data/ext/ssl.h +90 -0
  50. data/java/.classpath +8 -0
  51. data/java/.project +17 -0
  52. data/java/src/com/rubyeventmachine/Application.java +196 -0
  53. data/java/src/com/rubyeventmachine/Connection.java +74 -0
  54. data/java/src/com/rubyeventmachine/ConnectionFactory.java +37 -0
  55. data/java/src/com/rubyeventmachine/DefaultConnectionFactory.java +46 -0
  56. data/java/src/com/rubyeventmachine/EmReactor.java +408 -0
  57. data/java/src/com/rubyeventmachine/EmReactorException.java +40 -0
  58. data/java/src/com/rubyeventmachine/EventableChannel.java +57 -0
  59. data/java/src/com/rubyeventmachine/EventableDatagramChannel.java +171 -0
  60. data/java/src/com/rubyeventmachine/EventableSocketChannel.java +244 -0
  61. data/java/src/com/rubyeventmachine/PeriodicTimer.java +38 -0
  62. data/java/src/com/rubyeventmachine/Timer.java +54 -0
  63. data/java/src/com/rubyeventmachine/tests/ApplicationTest.java +108 -0
  64. data/java/src/com/rubyeventmachine/tests/ConnectTest.java +124 -0
  65. data/java/src/com/rubyeventmachine/tests/EMTest.java +80 -0
  66. data/java/src/com/rubyeventmachine/tests/TestDatagrams.java +53 -0
  67. data/java/src/com/rubyeventmachine/tests/TestServers.java +74 -0
  68. data/java/src/com/rubyeventmachine/tests/TestTimers.java +89 -0
  69. data/lib/em/deferrable.rb +208 -0
  70. data/lib/em/eventable.rb +39 -0
  71. data/lib/em/future.rb +62 -0
  72. data/lib/em/messages.rb +66 -0
  73. data/lib/em/processes.rb +113 -0
  74. data/lib/em/spawnable.rb +88 -0
  75. data/lib/em/streamer.rb +112 -0
  76. data/lib/eventmachine.rb +1926 -0
  77. data/lib/eventmachine_version.rb +31 -0
  78. data/lib/evma.rb +32 -0
  79. data/lib/evma/callback.rb +32 -0
  80. data/lib/evma/container.rb +75 -0
  81. data/lib/evma/factory.rb +77 -0
  82. data/lib/evma/protocol.rb +87 -0
  83. data/lib/evma/reactor.rb +48 -0
  84. data/lib/jeventmachine.rb +137 -0
  85. data/lib/pr_eventmachine.rb +1011 -0
  86. data/lib/protocols/buftok.rb +127 -0
  87. data/lib/protocols/header_and_content.rb +129 -0
  88. data/lib/protocols/httpcli2.rb +803 -0
  89. data/lib/protocols/httpclient.rb +270 -0
  90. data/lib/protocols/line_and_text.rb +126 -0
  91. data/lib/protocols/linetext2.rb +161 -0
  92. data/lib/protocols/memcache.rb +293 -0
  93. data/lib/protocols/postgres.rb +261 -0
  94. data/lib/protocols/saslauth.rb +179 -0
  95. data/lib/protocols/smtpclient.rb +308 -0
  96. data/lib/protocols/smtpserver.rb +556 -0
  97. data/lib/protocols/stomp.rb +153 -0
  98. data/lib/protocols/tcptest.rb +57 -0
  99. data/setup.rb +1585 -0
  100. data/tasks/cpp.rake +77 -0
  101. data/tasks/project.rake +78 -0
  102. data/tasks/tests.rake +193 -0
  103. data/tests/test_attach.rb +83 -0
  104. data/tests/test_basic.rb +231 -0
  105. data/tests/test_connection_count.rb +45 -0
  106. data/tests/test_defer.rb +47 -0
  107. data/tests/test_epoll.rb +163 -0
  108. data/tests/test_error_handler.rb +35 -0
  109. data/tests/test_errors.rb +82 -0
  110. data/tests/test_eventables.rb +77 -0
  111. data/tests/test_exc.rb +58 -0
  112. data/tests/test_futures.rb +214 -0
  113. data/tests/test_handler_check.rb +37 -0
  114. data/tests/test_hc.rb +218 -0
  115. data/tests/test_httpclient.rb +215 -0
  116. data/tests/test_httpclient2.rb +155 -0
  117. data/tests/test_kb.rb +61 -0
  118. data/tests/test_ltp.rb +188 -0
  119. data/tests/test_ltp2.rb +320 -0
  120. data/tests/test_next_tick.rb +109 -0
  121. data/tests/test_processes.rb +95 -0
  122. data/tests/test_pure.rb +129 -0
  123. data/tests/test_running.rb +47 -0
  124. data/tests/test_sasl.rb +74 -0
  125. data/tests/test_send_file.rb +243 -0
  126. data/tests/test_servers.rb +80 -0
  127. data/tests/test_smtpclient.rb +83 -0
  128. data/tests/test_smtpserver.rb +93 -0
  129. data/tests/test_spawn.rb +329 -0
  130. data/tests/test_ssl_args.rb +68 -0
  131. data/tests/test_ssl_methods.rb +50 -0
  132. data/tests/test_timers.rb +148 -0
  133. data/tests/test_ud.rb +43 -0
  134. data/tests/testem.rb +31 -0
  135. data/web/whatis +7 -0
  136. metadata +214 -0
@@ -0,0 +1,320 @@
1
+ # $Id$
2
+ #
3
+ # Author:: Francis Cianfrocca (gmail: blackhedd)
4
+ # Homepage:: http://rubyeventmachine.com
5
+ # Date:: 8 April 2006
6
+ #
7
+ # See EventMachine and EventMachine::Connection for documentation and
8
+ # usage examples.
9
+ #
10
+ #----------------------------------------------------------------------------
11
+ #
12
+ # Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved.
13
+ # Gmail: blackhedd
14
+ #
15
+ # This program is free software; you can redistribute it and/or modify
16
+ # it under the terms of either: 1) the GNU General Public License
17
+ # as published by the Free Software Foundation; either version 2 of the
18
+ # License, or (at your option) any later version; or 2) Ruby's License.
19
+ #
20
+ # See the file COPYING for complete licensing information.
21
+ #
22
+ #---------------------------------------------------------------------------
23
+ #
24
+ #
25
+ #
26
+ #
27
+
28
+ $:.unshift "../lib"
29
+ require 'eventmachine'
30
+ require 'test/unit'
31
+
32
+ # TODO!!! Need tests for overlength headers and text bodies.
33
+
34
+ class TestLineText2 < Test::Unit::TestCase
35
+
36
+ # Run each of these tests two ways: passing in the whole test-dataset in one chunk,
37
+ # and passing it in one character at a time.
38
+
39
+ class Basic
40
+ include EM::Protocols::LineText2
41
+ attr_reader :lines
42
+ def receive_line line
43
+ (@lines ||= []) << line
44
+ end
45
+ end
46
+ def test_basic
47
+ testdata = "Line 1\nLine 2\r\nLine 3\n"
48
+
49
+ a = Basic.new
50
+ a.receive_data testdata
51
+ assert_equal( ["Line 1", "Line 2", "Line 3"], a.lines )
52
+
53
+ a = Basic.new
54
+ testdata.length.times {|i| a.receive_data( testdata[i...i+1] ) }
55
+ assert_equal( ["Line 1", "Line 2", "Line 3"], a.lines )
56
+ end
57
+
58
+
59
+ class ChangeDelimiter
60
+ include EM::Protocols::LineText2
61
+ attr_reader :lines
62
+ def initialize *args
63
+ super
64
+ @delim = "A"
65
+ set_delimiter @delim
66
+ end
67
+ def receive_line line
68
+ (@lines ||= []) << line
69
+ set_delimiter( @delim.succ! )
70
+ end
71
+ end
72
+
73
+ def test_change_delimiter
74
+ testdata = %Q(LineaALinebBLinecCLinedD)
75
+
76
+ a = ChangeDelimiter.new
77
+ a.receive_data testdata
78
+ assert_equal( ["Linea", "Lineb", "Linec", "Lined"], a.lines )
79
+
80
+ a = ChangeDelimiter.new
81
+ testdata.length.times {|i| a.receive_data( testdata[i...i+1] ) }
82
+ assert_equal( ["Linea", "Lineb", "Linec", "Lined"], a.lines )
83
+ end
84
+
85
+
86
+ #--
87
+ # Test two lines followed by an empty line, ten bytes of binary data, then
88
+ # two more lines.
89
+
90
+ class Binary
91
+ include EM::Protocols::LineText2
92
+ attr_reader :lines, :body
93
+ def initialize *args
94
+ super
95
+ @lines = []
96
+ @body = nil
97
+ end
98
+ def receive_line ln
99
+ if ln == ""
100
+ set_text_mode 10
101
+ else
102
+ @lines << ln
103
+ end
104
+ end
105
+ def receive_binary_data data
106
+ @body = data
107
+ end
108
+ end
109
+
110
+ def test_binary
111
+ testdata = %Q(Line 1
112
+ Line 2
113
+
114
+ 0000000000Line 3
115
+ Line 4
116
+ )
117
+
118
+ a = Binary.new
119
+ a.receive_data testdata
120
+ assert_equal( ["Line 1", "Line 2", "Line 3", "Line 4"], a.lines)
121
+ assert_equal( "0000000000", a.body )
122
+
123
+ a = Binary.new
124
+ testdata.length.times {|i| a.receive_data( testdata[i...i+1] ) }
125
+ assert_equal( ["Line 1", "Line 2", "Line 3", "Line 4"], a.lines)
126
+ assert_equal( "0000000000", a.body )
127
+ end
128
+
129
+
130
+ # Test unsized binary data. The expectation is that each chunk of it
131
+ # will be passed to us as it it received.
132
+ class UnsizedBinary
133
+ include EM::Protocols::LineText2
134
+ attr_reader :n_calls, :body
135
+ def initialize *args
136
+ super
137
+ set_text_mode
138
+ end
139
+ def receive_binary_data data
140
+ @n_calls ||= 0
141
+ @n_calls += 1
142
+ (@body ||= "") << data
143
+ end
144
+ end
145
+
146
+ def test_unsized_binary
147
+ testdata = "X\0" * 1000
148
+
149
+ a = UnsizedBinary.new
150
+ a.receive_data testdata
151
+ assert_equal( 1, a.n_calls )
152
+ assert_equal( testdata, a.body )
153
+
154
+ a = UnsizedBinary.new
155
+ testdata.length.times {|i| a.receive_data( testdata[i...i+1] ) }
156
+ assert_equal( 2000, a.n_calls )
157
+ assert_equal( testdata, a.body )
158
+ end
159
+
160
+
161
+ # Test binary data with a "throw back" into line-mode.
162
+ class ThrowBack
163
+ include EM::Protocols::LineText2
164
+ attr_reader :headers
165
+ def initialize *args
166
+ super
167
+ @headers = []
168
+ @n_bytes = 0
169
+ set_text_mode
170
+ end
171
+ def receive_binary_data data
172
+ wanted = 25 - @n_bytes
173
+ will_take = if data.length > wanted
174
+ data.length - wanted
175
+ else
176
+ data.length
177
+ end
178
+ @n_bytes += will_take
179
+
180
+ if @n_bytes == 25
181
+ set_line_mode( data[will_take..-1] )
182
+ end
183
+ end
184
+ def receive_line ln
185
+ @headers << ln
186
+ end
187
+ end
188
+ def test_throw_back
189
+ testdata = "Line\n" * 10
190
+
191
+ a = ThrowBack.new
192
+ a.receive_data testdata
193
+ assert_equal( ["Line"] * 5, a.headers )
194
+
195
+ a = ThrowBack.new
196
+ testdata.length.times {|i| a.receive_data( testdata[i...i+1] ) }
197
+ assert_equal( ["Line"] * 5, a.headers )
198
+ end
199
+
200
+ # Test multi-character line delimiters.
201
+ # Also note that the test data has a "tail" with no delimiter, that will be
202
+ # discarded, but cf. the BinaryTail test.
203
+ # TODO!!! This test doesn't work in the byte-by-byte case.
204
+ class Multichar
205
+ include EM::Protocols::LineText2
206
+ attr_reader :lines
207
+ def initialize *args
208
+ super
209
+ @lines = []
210
+ set_delimiter "012"
211
+ end
212
+ def receive_line ln
213
+ @lines << ln
214
+ end
215
+ end
216
+ def test_multichar
217
+ testdata = "Line012Line012Line012Line"
218
+
219
+ a = Multichar.new
220
+ a.receive_data testdata
221
+ assert_equal( ["Line"]*3, a.lines )
222
+
223
+ a = Multichar.new
224
+ testdata.length.times {|i| a.receive_data( testdata[i...i+1] ) }
225
+ # DOESN'T WORK in this case. Multi-character delimiters are broken.
226
+ #assert_equal( ["Line"]*3, a.lines )
227
+ end
228
+
229
+ # Test a binary "tail," when a sized binary transfer doesn't complete because
230
+ # of an unbind. We get a partial result.
231
+ class BinaryTail
232
+ include EM::Protocols::LineText2
233
+ attr_reader :data
234
+ def initialize *args
235
+ super
236
+ @data = ""
237
+ set_text_mode 1000
238
+ end
239
+ def receive_binary_data data
240
+ # we expect to get all the data in one chunk, even in the byte-by-byte case,
241
+ # because sized transfers by definition give us exactly one call to
242
+ # #receive_binary_data.
243
+ @data = data
244
+ end
245
+ end
246
+ def test_binary_tail
247
+ testdata = "0" * 500
248
+
249
+ a = BinaryTail.new
250
+ a.receive_data testdata
251
+ a.unbind
252
+ assert_equal( "0" * 500, a.data )
253
+
254
+ a = BinaryTail.new
255
+ testdata.length.times {|i| a.receive_data( testdata[i...i+1] ) }
256
+ a.unbind
257
+ assert_equal( "0" * 500, a.data )
258
+ end
259
+
260
+
261
+
262
+ # Test an end-of-binary call. Arrange to receive binary data but don't bother counting it
263
+ # as it comes. Rely on getting receive_end_of_binary_data to signal the transition back to
264
+ # line mode.
265
+ # At the present time, this isn't strictly necessary with sized binary chunks because by
266
+ # definition we accumulate them and make exactly one call to receive_binary_data, but
267
+ # we may want to support a mode in the future that would break up large chunks into multiple
268
+ # calls.
269
+ class LazyBinary
270
+ include EM::Protocols::LineText2
271
+ attr_reader :data, :end
272
+ def initialize *args
273
+ super
274
+ @data = ""
275
+ set_text_mode 1000
276
+ end
277
+ def receive_binary_data data
278
+ # we expect to get all the data in one chunk, even in the byte-by-byte case,
279
+ # because sized transfers by definition give us exactly one call to
280
+ # #receive_binary_data.
281
+ @data = data
282
+ end
283
+ def receive_end_of_binary_data
284
+ @end = true
285
+ end
286
+ end
287
+ def test_receive_end_of_binary_data
288
+ testdata = "_" * 1000
289
+ a = LazyBinary.new
290
+ testdata.length.times {|i| a.receive_data( testdata[i...i+1] ) }
291
+ assert_equal( "_" * 1000, a.data )
292
+ assert( a.end )
293
+ end
294
+
295
+
296
+ # This tests a bug fix in which calling set_text_mode failed when called
297
+ # inside receive_binary_data.
298
+ #
299
+ class BinaryPair
300
+ include EM::Protocols::LineText2
301
+ attr_reader :sizes
302
+ def initialize *args
303
+ super
304
+ set_text_mode 1
305
+ @sizes = []
306
+ end
307
+ def receive_binary_data dt
308
+ @sizes << dt.length
309
+ set_text_mode( (dt.length == 1) ? 2 : 1 )
310
+ end
311
+ end
312
+ def test_binary_pairs
313
+ test_data = "123" * 5
314
+ a = BinaryPair.new
315
+ a.receive_data test_data
316
+ assert_equal( [1,2,1,2,1,2,1,2,1,2], a.sizes )
317
+ end
318
+
319
+ end
320
+
@@ -0,0 +1,109 @@
1
+ # $Id$
2
+ #
3
+ # Author:: Francis Cianfrocca (gmail: blackhedd)
4
+ # Homepage:: http://rubyeventmachine.com
5
+ # Date:: 8 April 2006
6
+ #
7
+ # See EventMachine and EventMachine::Connection for documentation and
8
+ # usage examples.
9
+ #
10
+ #----------------------------------------------------------------------------
11
+ #
12
+ # Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved.
13
+ # Gmail: blackhedd
14
+ #
15
+ # This program is free software; you can redistribute it and/or modify
16
+ # it under the terms of either: 1) the GNU General Public License
17
+ # as published by the Free Software Foundation; either version 2 of the
18
+ # License, or (at your option) any later version; or 2) Ruby's License.
19
+ #
20
+ # See the file COPYING for complete licensing information.
21
+ #
22
+ #---------------------------------------------------------------------------
23
+ #
24
+ #
25
+ #
26
+ #
27
+
28
+ $:.unshift "../lib"
29
+ require 'eventmachine'
30
+ require 'test/unit'
31
+
32
+
33
+
34
+ class TestNextTick < Test::Unit::TestCase
35
+
36
+ def setup
37
+ end
38
+
39
+ def teardown
40
+ end
41
+
42
+ def test_tick_arg
43
+ pr = proc {EM.stop}
44
+ EM.epoll
45
+ EM.run {
46
+ EM.next_tick pr
47
+ }
48
+ assert true
49
+ end
50
+
51
+ def test_tick_block
52
+ EM.epoll
53
+ EM.run {
54
+ EM.next_tick {EM.stop}
55
+ }
56
+ assert true
57
+ end
58
+
59
+ # This illustrates the solution to a long-standing problem.
60
+ # It's now possible to correctly nest calls to EM#run.
61
+ # See the source code commentary for EM#run for more info.
62
+ #
63
+ def test_run_run
64
+ EM.run {
65
+ EM.run {
66
+ EM.next_tick {EM.stop}
67
+ }
68
+ }
69
+ end
70
+
71
+ def test_pre_run_queue
72
+ x = false
73
+ EM.next_tick { EM.stop; x = true }
74
+ EM.run { EM.add_timer(0.2) { EM.stop } }
75
+ assert x
76
+ end
77
+
78
+ # We now support an additional parameter for EM#run.
79
+ # You can pass two procs to EM#run now. The first is executed as the normal
80
+ # run block. The second (if given) is scheduled for execution after the
81
+ # reactor loop completes.
82
+ # The reason for supporting this is subtle. There has always been an expectation
83
+ # that EM#run doesn't return until after the reactor loop ends. But now it's
84
+ # possible to nest calls to EM#run, which means that a nested call WILL
85
+ # RETURN. In order to write code that will run correctly either way, it's
86
+ # recommended to put any code which must execute after the reactor completes
87
+ # in the second parameter.
88
+ #
89
+ def test_run_run_2
90
+ a = proc {EM.stop}
91
+ b = proc {assert true}
92
+ EM.run a, b
93
+ end
94
+
95
+
96
+ # This illustrates that EM#run returns when it's called nested.
97
+ # This isn't a feature, rather it's something to be wary of when writing code
98
+ # that must run correctly even if EM#run is called while a reactor is already
99
+ # running.
100
+ def test_run_run_3
101
+ a = []
102
+ EM.run {
103
+ EM.run proc {EM.stop}, proc {a << 2}
104
+ a << 1
105
+ }
106
+ assert_equal( [1,2], a )
107
+ end
108
+
109
+ end
@@ -0,0 +1,95 @@
1
+ # $Id$
2
+ #
3
+ # Author:: Francis Cianfrocca (gmail: blackhedd)
4
+ # Homepage:: http://rubyeventmachine.com
5
+ # Date:: 8 April 2006
6
+ #
7
+ # See EventMachine and EventMachine::Connection for documentation and
8
+ # usage examples.
9
+ #
10
+ #----------------------------------------------------------------------------
11
+ #
12
+ # Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved.
13
+ # Gmail: blackhedd
14
+ #
15
+ # This program is free software; you can redistribute it and/or modify
16
+ # it under the terms of either: 1) the GNU General Public License
17
+ # as published by the Free Software Foundation; either version 2 of the
18
+ # License, or (at your option) any later version; or 2) Ruby's License.
19
+ #
20
+ # See the file COPYING for complete licensing information.
21
+ #
22
+ #---------------------------------------------------------------------------
23
+ #
24
+ #
25
+ #
26
+
27
+ $:.unshift "../lib"
28
+ require 'eventmachine'
29
+ require 'test/unit'
30
+
31
+ class TestProcesses < Test::Unit::TestCase
32
+
33
+ # EM::DeferrableChildProcess is a sugaring of a common use-case
34
+ # involving EM::popen.
35
+ # Call the #open method on EM::DeferrableChildProcess, passing
36
+ # a command-string. #open immediately returns an EM::Deferrable
37
+ # object. It also schedules the forking of a child process, which
38
+ # will execute the command passed to #open.
39
+ # When the forked child terminates, the Deferrable will be signalled
40
+ # and execute its callbacks, passing the data that the child process
41
+ # wrote to stdout.
42
+ #
43
+ def test_deferrable_child_process
44
+ ls = ""
45
+ EM.run {
46
+ d = EM::DeferrableChildProcess.open( "ls -ltr" )
47
+ d.callback {|data_from_child|
48
+ ls = data_from_child
49
+ EM.stop
50
+ }
51
+ }
52
+ assert( ls.length > 0)
53
+ end
54
+
55
+ def setup
56
+ $out = nil
57
+ $status = nil
58
+ end
59
+
60
+ def test_em_system
61
+ EM.run{
62
+ EM.system('ls'){ |out,status| $out, $status = out, status; EM.stop }
63
+ }
64
+
65
+ assert( $out.length > 0 )
66
+ assert_equal($status.exitstatus, 0)
67
+ assert_equal($status.class, Process::Status)
68
+ end
69
+
70
+ def test_em_system_with_proc
71
+ EM.run{
72
+ EM.system('ls', proc{ |out,status| $out, $status = out, status; EM.stop })
73
+ }
74
+
75
+ assert( $out.length > 0 )
76
+ assert_equal($status.exitstatus, 0)
77
+ assert_equal($status.class, Process::Status)
78
+ end
79
+
80
+ def test_em_system_with_two_procs
81
+ EM.run{
82
+ EM.system('sh', proc{ |process|
83
+ process.send_data("echo hello\n")
84
+ process.send_data("exit\n")
85
+ }, proc{ |out,status|
86
+ $out = out
87
+ $status = status
88
+ EM.stop
89
+ })
90
+ }
91
+
92
+ assert_equal($out, "hello\n")
93
+ end
94
+ end
95
+