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,196 @@
1
+ require_relative 'em_test_helper'
2
+
3
+ class TestPool < Test::Unit::TestCase
4
+ def pool
5
+ @pool ||= EM::Pool.new
6
+ end
7
+
8
+ def go
9
+ EM.run { yield }
10
+ end
11
+
12
+ def stop
13
+ EM.stop
14
+ end
15
+
16
+ def deferrable
17
+ @deferrable ||= EM::DefaultDeferrable.new
18
+ end
19
+
20
+ def test_supports_more_work_than_resources
21
+ ran = false
22
+ go do
23
+ pool.perform do
24
+ ran = true
25
+ deferrable
26
+ end
27
+ stop
28
+ end
29
+ assert_equal false, ran
30
+ go do
31
+ pool.add :resource
32
+ stop
33
+ end
34
+ assert_equal true, ran
35
+ end
36
+
37
+ def test_reques_resources_on_error
38
+ pooled_res, pooled_res2 = nil
39
+ pool.add :res
40
+ go do
41
+ pool.perform do |res|
42
+ pooled_res = res
43
+ deferrable
44
+ end
45
+ stop
46
+ end
47
+ deferrable.fail
48
+ go do
49
+ pool.perform do |res|
50
+ pooled_res2 = res
51
+ deferrable
52
+ end
53
+ stop
54
+ end
55
+ assert_equal :res, pooled_res
56
+ assert_equal pooled_res, pooled_res2
57
+ end
58
+
59
+ def test_supports_custom_on_error
60
+ eres = nil
61
+ pool.on_error do |res|
62
+ eres = res
63
+ end
64
+ performs = []
65
+ pool.add :res
66
+ go do
67
+ pool.perform do |res|
68
+ performs << res
69
+ deferrable
70
+ end
71
+ pool.perform do |res|
72
+ performs << res
73
+ deferrable
74
+ end
75
+ deferrable.fail
76
+ stop
77
+ end
78
+ assert_equal :res, eres
79
+ # manual requeues required when error handler is installed:
80
+ assert_equal 1, performs.size
81
+ assert_equal :res, performs.first
82
+ end
83
+
84
+ def test_catches_successful_deferrables
85
+ performs = []
86
+ pool.add :res
87
+ go do
88
+ pool.perform { |res| performs << res; deferrable }
89
+ pool.perform { |res| performs << res; deferrable }
90
+ stop
91
+ end
92
+ assert_equal [:res], performs
93
+ deferrable.succeed
94
+ go { stop }
95
+ assert_equal [:res, :res], performs
96
+ end
97
+
98
+ def test_prunes_locked_and_removed_resources
99
+ performs = []
100
+ pool.add :res
101
+ deferrable.succeed
102
+ go do
103
+ pool.perform { |res| performs << res; pool.remove res; deferrable }
104
+ pool.perform { |res| performs << res; pool.remove res; deferrable }
105
+ stop
106
+ end
107
+ assert_equal [:res], performs
108
+ end
109
+
110
+ # Contents is only to be used for inspection of the pool!
111
+ def test_contents
112
+ pool.add :res
113
+ assert_equal [:res], pool.contents
114
+ # Assert that modifying the contents list does not affect the pools
115
+ # contents.
116
+ pool.contents.delete(:res)
117
+ assert_equal [:res], pool.contents
118
+ end
119
+
120
+ def test_contents_when_perform_errors_and_on_error_is_not_set
121
+ pool.add :res
122
+ assert_equal [:res], pool.contents
123
+
124
+ pool.perform do |r|
125
+ d = EM::DefaultDeferrable.new
126
+ d.fail
127
+ d
128
+ end
129
+
130
+ EM.run { EM.next_tick { EM.stop } }
131
+
132
+ assert_equal [:res], pool.contents
133
+ end
134
+
135
+ def test_contents_when_perform_errors_and_on_error_is_set
136
+ pool.add :res
137
+ res = nil
138
+ pool.on_error do |r|
139
+ res = r
140
+ end
141
+ assert_equal [:res], pool.contents
142
+
143
+ pool.perform do |r|
144
+ d = EM::DefaultDeferrable.new
145
+ d.fail 'foo'
146
+ d
147
+ end
148
+
149
+ EM.run { EM.next_tick { EM.stop } }
150
+
151
+ assert_equal :res, res
152
+ assert_equal [], pool.contents
153
+ end
154
+
155
+ def test_num_waiting
156
+ pool.add :res
157
+ assert_equal 0, pool.num_waiting
158
+ pool.perform { |r| EM::DefaultDeferrable.new }
159
+ assert_equal 0, pool.num_waiting
160
+ 10.times { pool.perform { |r| EM::DefaultDeferrable.new } }
161
+ EM.run { EM.next_tick { EM.stop } }
162
+ assert_equal 10, pool.num_waiting
163
+ end
164
+
165
+ def test_exceptions_in_the_work_block_bubble_up_raise_and_fail_the_resource
166
+ pool.add :res
167
+
168
+ res = nil
169
+ pool.on_error { |r| res = r }
170
+ pool.perform { raise 'boom' }
171
+
172
+ assert_raises(RuntimeError) do
173
+ EM.run { EM.next_tick { EM.stop } }
174
+ end
175
+
176
+ assert_equal [], pool.contents
177
+ assert_equal :res, res
178
+ end
179
+
180
+ def test_removed_list_does_not_leak_on_errors
181
+ pool.add :res
182
+
183
+ pool.on_error do |r|
184
+ # This is actually the wrong thing to do, and not required, but some users
185
+ # might do it. When they do, they would find that @removed would cause a
186
+ # slow leak.
187
+ pool.remove r
188
+ end
189
+
190
+ pool.perform { d = EM::DefaultDeferrable.new; d.fail; d }
191
+
192
+ EM.run { EM.next_tick { EM.stop } }
193
+ assert_equal [], pool.instance_variable_get(:@removed)
194
+ end
195
+
196
+ end
@@ -0,0 +1,50 @@
1
+ require_relative 'em_test_helper'
2
+
3
+ if EM.kqueue?
4
+ class TestProcessWatch < Test::Unit::TestCase
5
+ module ParentProcessWatcher
6
+ def process_forked
7
+ $forked = true
8
+ end
9
+ end
10
+
11
+ module ChildProcessWatcher
12
+ def process_exited
13
+ $exited = true
14
+ end
15
+ def unbind
16
+ $unbind = true
17
+ EM.stop
18
+ end
19
+ end
20
+
21
+ def setup
22
+ EM.kqueue = true
23
+ end
24
+
25
+ def teardown
26
+ EM.kqueue = false
27
+ end
28
+
29
+ def test_events
30
+ omit_if(rbx?)
31
+ omit_if(jruby?)
32
+ EM.run{
33
+ # watch ourselves for a fork notification
34
+ EM.watch_process(Process.pid, ParentProcessWatcher)
35
+ $fork_pid = fork{ sleep }
36
+ child = EM.watch_process($fork_pid, ChildProcessWatcher)
37
+ $pid = child.pid
38
+
39
+ EM.add_timer(0.2){
40
+ Process.kill('TERM', $fork_pid)
41
+ }
42
+ }
43
+
44
+ assert_equal($pid, $fork_pid)
45
+ assert($forked)
46
+ assert($exited)
47
+ assert($unbind)
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,147 @@
1
+ require_relative 'em_test_helper'
2
+
3
+ class TestProcesses < Test::Unit::TestCase
4
+
5
+ if !windows? && !jruby?
6
+
7
+ # EM::DeferrableChildProcess is a sugaring of a common use-case
8
+ # involving EM::popen.
9
+ # Call the #open method on EM::DeferrableChildProcess, passing
10
+ # a command-string. #open immediately returns an EM::Deferrable
11
+ # object. It also schedules the forking of a child process, which
12
+ # will execute the command passed to #open.
13
+ # When the forked child terminates, the Deferrable will be signalled
14
+ # and execute its callbacks, passing the data that the child process
15
+ # wrote to stdout.
16
+ #
17
+ def test_deferrable_child_process
18
+ ls = ""
19
+ EM.run {
20
+ d = EM::DeferrableChildProcess.open( "ls -ltr" )
21
+ d.callback {|data_from_child|
22
+ ls = data_from_child
23
+ EM.stop
24
+ }
25
+ }
26
+ assert( ls.length > 0)
27
+ end
28
+
29
+ def setup
30
+ $out = nil
31
+ $status = nil
32
+ end
33
+
34
+ def test_em_system
35
+ out, status = nil, nil
36
+
37
+ EM.run{
38
+ EM.system('ls'){ |_out,_status| out, status = _out, _status; EM.stop }
39
+ }
40
+
41
+ assert(out.length > 0 )
42
+ assert_kind_of(Process::Status, status)
43
+ assert_equal(0, status.exitstatus)
44
+ end
45
+
46
+ def test_em_system_bad_exitstatus
47
+ status = nil
48
+ sys_pid = nil
49
+
50
+ EM.run{
51
+ sys_pid = EM.system('exit 1'){ |_out,_status| status = _status; EM.stop }
52
+ }
53
+
54
+ assert_kind_of(Process::Status, status)
55
+ refute_equal(0, status.exitstatus)
56
+ assert_equal sys_pid, status.pid
57
+ end
58
+
59
+ def test_em_system_pid
60
+ status = nil
61
+ sys_pid = nil
62
+
63
+ EM.run{
64
+ sys_pid = EM.system('echo hi', proc{ |_out,_status| status = _status; EM.stop })
65
+ }
66
+
67
+ refute_equal(0, sys_pid)
68
+ assert_kind_of(Process::Status, status)
69
+ refute_equal(0, status.pid)
70
+ assert_equal sys_pid, status.pid
71
+ end
72
+
73
+ def test_em_system_with_proc
74
+ EM.run{
75
+ EM.system('ls', proc{ |out,status| $out, $status = out, status; EM.stop })
76
+ }
77
+
78
+ assert( $out.length > 0 )
79
+ assert_kind_of(Process::Status, $status)
80
+ assert_equal(0, $status.exitstatus)
81
+ end
82
+
83
+ def test_em_system_with_two_procs
84
+ EM.run{
85
+ EM.system('sh', proc{ |process|
86
+ process.send_data("echo hello\n")
87
+ process.send_data("exit\n")
88
+ }, proc{ |out,status|
89
+ $out = out
90
+ $status = status
91
+ EM.stop
92
+ })
93
+ }
94
+
95
+ assert_equal("hello\n", $out)
96
+ end
97
+
98
+ def test_em_system_cmd_arguments
99
+ EM.run{
100
+ EM.system('echo', '1', '2', 'version', proc{ |process|
101
+ }, proc{ |out,status|
102
+ $out = out
103
+ $status = status
104
+ EM.stop
105
+ })
106
+ }
107
+
108
+ assert_match(/1 2 version/i, $out)
109
+ end
110
+
111
+ def test_em_system_spaced_arguments
112
+ EM.run{
113
+ EM.system('ruby', '-e', 'puts "hello"', proc{ |out,status|
114
+ $out = out
115
+ EM.stop
116
+ })
117
+ }
118
+
119
+ assert_equal("hello\n", $out)
120
+ end
121
+
122
+ def test_em_popen_pause_resume
123
+ c_rx = 0
124
+
125
+ test_client = Module.new do
126
+ define_method :receive_data do |data|
127
+ c_rx += 1
128
+ pause
129
+ EM.add_timer(0.5) { EM.stop }
130
+ end
131
+ end
132
+
133
+ EM.run do
134
+ EM.popen('echo 1', test_client)
135
+ end
136
+
137
+ assert_equal 1, c_rx
138
+ end
139
+ else
140
+ warn "EM.popen not implemented, skipping tests in #{__FILE__}"
141
+
142
+ # Because some rubies will complain if a TestCase class has no tests
143
+ def test_em_popen_unsupported
144
+ assert true
145
+ end
146
+ end
147
+ end
@@ -0,0 +1,180 @@
1
+ require_relative 'em_test_helper'
2
+
3
+ class TestProxyConnection < Test::Unit::TestCase
4
+
5
+ if EM.respond_to?(:start_proxy)
6
+ module ProxyConnection
7
+ def initialize(client, request)
8
+ @client, @request = client, request
9
+ end
10
+
11
+ def post_init
12
+ EM::enable_proxy(self, @client)
13
+ end
14
+
15
+ def connection_completed
16
+ EM.next_tick {
17
+ send_data @request
18
+ }
19
+ end
20
+
21
+ def proxy_target_unbound
22
+ $unbound_early = true
23
+ EM.stop
24
+ end
25
+
26
+ def unbind
27
+ $proxied_bytes = self.get_proxied_bytes
28
+ @client.close_connection_after_writing
29
+ end
30
+ end
31
+
32
+ module PartialProxyConnection
33
+ def initialize(client, request, length)
34
+ @client, @request, @length = client, request, length
35
+ end
36
+
37
+ def post_init
38
+ EM::enable_proxy(self, @client, 0, @length)
39
+ end
40
+
41
+ def receive_data(data)
42
+ $unproxied_data = data
43
+ @client.send_data(data)
44
+ end
45
+
46
+ def connection_completed
47
+ EM.next_tick {
48
+ send_data @request
49
+ }
50
+ end
51
+
52
+ def proxy_target_unbound
53
+ $unbound_early = true
54
+ EM.stop
55
+ end
56
+
57
+ def proxy_completed
58
+ $proxy_completed = true
59
+ end
60
+
61
+ def unbind
62
+ @client.close_connection_after_writing
63
+ end
64
+ end
65
+
66
+ module Client
67
+ def connection_completed
68
+ send_data "EM rocks!"
69
+ end
70
+
71
+ def receive_data(data)
72
+ $client_data = data
73
+ end
74
+
75
+ def unbind
76
+ EM.stop
77
+ end
78
+ end
79
+
80
+ module Client2
81
+ include Client
82
+ def unbind; end
83
+ end
84
+
85
+ module Server
86
+ def receive_data(data)
87
+ send_data "I know!" if data == "EM rocks!"
88
+ close_connection_after_writing
89
+ end
90
+ end
91
+
92
+ module ProxyServer
93
+ def initialize port
94
+ @port = port
95
+ end
96
+
97
+ def receive_data(data)
98
+ @proxy = EM.connect("127.0.0.1", @port, ProxyConnection, self, data)
99
+ end
100
+ end
101
+
102
+ module PartialProxyServer
103
+ def initialize port
104
+ @port = port
105
+ end
106
+
107
+ def receive_data(data)
108
+ EM.connect("127.0.0.1", @port, PartialProxyConnection, self, data, 1)
109
+ end
110
+ end
111
+
112
+ module EarlyClosingProxy
113
+ def initialize port
114
+ @port = port
115
+ end
116
+
117
+ def receive_data(data)
118
+ EM.connect("127.0.0.1", @port, ProxyConnection, self, data)
119
+ close_connection
120
+ end
121
+ end
122
+
123
+ def setup
124
+ @port = next_port
125
+ @proxy_port = next_port
126
+ end
127
+
128
+ def test_proxy_connection
129
+ EM.run {
130
+ EM.start_server("127.0.0.1", @port, Server)
131
+ EM.start_server("127.0.0.1", @proxy_port, ProxyServer, @port)
132
+ EM.connect("127.0.0.1", @proxy_port, Client)
133
+ }
134
+
135
+ assert_equal("I know!", $client_data)
136
+ end
137
+
138
+ def test_proxied_bytes
139
+ EM.run {
140
+ EM.start_server("127.0.0.1", @port, Server)
141
+ EM.start_server("127.0.0.1", @proxy_port, ProxyServer, @port)
142
+ EM.connect("127.0.0.1", @proxy_port, Client)
143
+ }
144
+
145
+ assert_equal("I know!", $client_data)
146
+ assert_equal("I know!".bytesize, $proxied_bytes)
147
+ end
148
+
149
+ def test_partial_proxy_connection
150
+ EM.run {
151
+ EM.start_server("127.0.0.1", @port, Server)
152
+ EM.start_server("127.0.0.1", @proxy_port, PartialProxyServer, @port)
153
+ EM.connect("127.0.0.1", @proxy_port, Client)
154
+ }
155
+
156
+ assert_equal("I know!", $client_data)
157
+ assert_equal(" know!", $unproxied_data)
158
+ assert($proxy_completed)
159
+ end
160
+
161
+ def test_early_close
162
+ $client_data = nil
163
+ EM.run {
164
+ EM.start_server("127.0.0.1", @port, Server)
165
+ EM.start_server("127.0.0.1", @proxy_port, EarlyClosingProxy, @port)
166
+ EM.connect("127.0.0.1", @proxy_port, Client2)
167
+ }
168
+
169
+ assert($unbound_early)
170
+ end
171
+ else
172
+ warn "EM.start_proxy not implemented, skipping tests in #{__FILE__}"
173
+
174
+ # Because some rubies will complain if a TestCase class has no tests
175
+ def test_em_start_proxy_not_implemented
176
+ assert !EM.respond_to?(:start_proxy)
177
+ end
178
+ end
179
+
180
+ end
@@ -0,0 +1,156 @@
1
+ require_relative 'em_test_helper'
2
+
3
+ class TestPure < Test::Unit::TestCase
4
+
5
+ def setup
6
+ @port = next_port
7
+ end
8
+
9
+ # These tests are intended to exercise problems that come up in the
10
+ # pure-Ruby implementation. However, we DON'T constrain them such that
11
+ # they only run in pure-Ruby. These tests need to work identically in
12
+ # any implementation.
13
+
14
+ #-------------------------------------
15
+
16
+ # The EM reactor needs to run down open connections and release other resources
17
+ # when it stops running. Make sure this happens even if user code throws a Ruby
18
+ # exception.
19
+ # If exception handling is incorrect, the second test will fail with a no-bind error
20
+ # because the TCP server opened in the first test will not have been closed.
21
+
22
+ def test_exception_handling_releases_resources
23
+ exception = Class.new(StandardError)
24
+
25
+ 2.times do
26
+ assert_raises(exception) do
27
+ EM.run do
28
+ EM.start_server "127.0.0.1", @port
29
+ raise exception
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ # Under some circumstances, the pure Ruby library would emit an Errno::ECONNREFUSED
36
+ # exception on certain kinds of TCP connect-errors.
37
+ # It's always been something of an open question whether EM should throw an exception
38
+ # in these cases but the defined answer has always been to catch it the unbind method.
39
+ # With a connect failure, the latter will always fire, but connection_completed will
40
+ # never fire. So even though the point is arguable, it's incorrect for the pure Ruby
41
+ # version to throw an exception.
42
+ module TestConnrefused
43
+ def unbind
44
+ EM.stop
45
+ end
46
+ def connection_completed
47
+ raise "should never get here"
48
+ end
49
+ end
50
+
51
+ def test_connrefused
52
+ assert_nothing_raised do
53
+ EM.run {
54
+ setup_timeout(2)
55
+ EM.connect "127.0.0.1", @port, TestConnrefused
56
+ }
57
+ end
58
+ end
59
+
60
+ # Make sure connection_completed gets called as expected with TCP clients. This is the
61
+ # opposite of test_connrefused.
62
+ # If the test fails, it will hang because EM.stop never gets called.
63
+ #
64
+ module TestConnaccepted
65
+ def connection_completed
66
+ EM.stop
67
+ end
68
+ end
69
+ def test_connaccepted
70
+ assert_nothing_raised do
71
+ EM.run {
72
+ EM.start_server "127.0.0.1", @port
73
+ EM.connect "127.0.0.1", @port, TestConnaccepted
74
+ setup_timeout(1)
75
+ }
76
+ end
77
+ end
78
+
79
+ def test_reactor_running
80
+ a = false
81
+ EM.run {
82
+ a = EM.reactor_running?
83
+ EM.next_tick {EM.stop}
84
+ }
85
+ assert a
86
+ end
87
+
88
+ module TLSServer
89
+ def post_init
90
+ start_tls
91
+ end
92
+
93
+ def ssl_handshake_completed
94
+ $server_handshake_completed = true
95
+ end
96
+
97
+ def receive_data(data)
98
+ $server_received_data = data
99
+ send_data(data)
100
+ end
101
+ end
102
+
103
+ module TLSClient
104
+ def post_init
105
+ start_tls
106
+ end
107
+
108
+ def ssl_handshake_completed
109
+ $client_handshake_completed = true
110
+ end
111
+
112
+ def connection_completed
113
+ send_data('Hello World!')
114
+ end
115
+
116
+ def receive_data(data)
117
+ $client_received_data = data
118
+ close_connection
119
+ end
120
+
121
+ def unbind
122
+ EM.stop_event_loop
123
+ end
124
+ end
125
+
126
+ def test_start_tls
127
+ omit("No SSL") unless EM.ssl?
128
+ $client_handshake_completed, $server_handshake_completed = false, false
129
+ $client_received_data, $server_received_data = nil, nil
130
+ EM.run do
131
+ EM.start_server("127.0.0.1", 16789, TLSServer)
132
+ EM.connect("127.0.0.1", 16789, TLSClient)
133
+ end
134
+
135
+ assert($client_handshake_completed)
136
+ assert($server_handshake_completed)
137
+ assert($client_received_data == "Hello World!")
138
+ assert($server_received_data == "Hello World!")
139
+ end
140
+
141
+ def test_periodic_timer
142
+ x = 0
143
+ start, finish = nil
144
+
145
+ EM.run {
146
+ start = Time.now.to_f
147
+ EM::PeriodicTimer.new(0.2) do
148
+ x += 1
149
+ finish = Time.now.to_f
150
+ EM.stop if x == 4
151
+ end
152
+ }
153
+ assert_in_delta 0.8, (finish - start), (darwin? ? 0.6 : 0.2)
154
+ assert_equal 4, x
155
+ end
156
+ end