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.
Files changed (162) hide show
  1. data/.gitignore +22 -0
  2. data/.yardopts +7 -0
  3. data/GNU +281 -0
  4. data/Gemfile +3 -0
  5. data/LICENSE +60 -0
  6. data/README.md +109 -0
  7. data/Rakefile +20 -0
  8. data/docs/DocumentationGuidesIndex.md +27 -0
  9. data/docs/GettingStarted.md +521 -0
  10. data/docs/old/ChangeLog +211 -0
  11. data/docs/old/DEFERRABLES +246 -0
  12. data/docs/old/EPOLL +141 -0
  13. data/docs/old/INSTALL +13 -0
  14. data/docs/old/KEYBOARD +42 -0
  15. data/docs/old/LEGAL +25 -0
  16. data/docs/old/LIGHTWEIGHT_CONCURRENCY +130 -0
  17. data/docs/old/PURE_RUBY +75 -0
  18. data/docs/old/RELEASE_NOTES +94 -0
  19. data/docs/old/SMTP +4 -0
  20. data/docs/old/SPAWNED_PROCESSES +148 -0
  21. data/docs/old/TODO +8 -0
  22. data/eventmachine.gemspec +34 -0
  23. data/examples/guides/getting_started/01_eventmachine_echo_server.rb +18 -0
  24. data/examples/guides/getting_started/02_eventmachine_echo_server_that_recognizes_exit_command.rb +22 -0
  25. data/examples/guides/getting_started/03_simple_chat_server.rb +149 -0
  26. data/examples/guides/getting_started/04_simple_chat_server_step_one.rb +27 -0
  27. data/examples/guides/getting_started/05_simple_chat_server_step_two.rb +43 -0
  28. data/examples/guides/getting_started/06_simple_chat_server_step_three.rb +98 -0
  29. data/examples/guides/getting_started/07_simple_chat_server_step_four.rb +121 -0
  30. data/examples/guides/getting_started/08_simple_chat_server_step_five.rb +141 -0
  31. data/examples/old/ex_channel.rb +43 -0
  32. data/examples/old/ex_queue.rb +2 -0
  33. data/examples/old/ex_tick_loop_array.rb +15 -0
  34. data/examples/old/ex_tick_loop_counter.rb +32 -0
  35. data/examples/old/helper.rb +2 -0
  36. data/ext/binder.cpp +124 -0
  37. data/ext/binder.h +46 -0
  38. data/ext/cmain.cpp +876 -0
  39. data/ext/ed.cpp +1973 -0
  40. data/ext/ed.h +422 -0
  41. data/ext/em.cpp +2353 -0
  42. data/ext/em.h +239 -0
  43. data/ext/eventmachine.h +127 -0
  44. data/ext/extconf.rb +176 -0
  45. data/ext/fastfilereader/extconf.rb +103 -0
  46. data/ext/fastfilereader/mapper.cpp +214 -0
  47. data/ext/fastfilereader/mapper.h +59 -0
  48. data/ext/fastfilereader/rubymain.cpp +127 -0
  49. data/ext/kb.cpp +79 -0
  50. data/ext/page.cpp +107 -0
  51. data/ext/page.h +51 -0
  52. data/ext/pipe.cpp +347 -0
  53. data/ext/project.h +156 -0
  54. data/ext/rubymain.cpp +1297 -0
  55. data/ext/ssl.cpp +468 -0
  56. data/ext/ssl.h +94 -0
  57. data/java/.classpath +8 -0
  58. data/java/.project +17 -0
  59. data/java/src/com/rubyeventmachine/EmReactor.java +588 -0
  60. data/java/src/com/rubyeventmachine/EmReactorException.java +40 -0
  61. data/java/src/com/rubyeventmachine/EventableChannel.java +70 -0
  62. data/java/src/com/rubyeventmachine/EventableDatagramChannel.java +195 -0
  63. data/java/src/com/rubyeventmachine/EventableSocketChannel.java +364 -0
  64. data/lib/em/buftok.rb +110 -0
  65. data/lib/em/callback.rb +58 -0
  66. data/lib/em/channel.rb +64 -0
  67. data/lib/em/completion.rb +304 -0
  68. data/lib/em/connection.rb +712 -0
  69. data/lib/em/deferrable.rb +210 -0
  70. data/lib/em/deferrable/pool.rb +2 -0
  71. data/lib/em/file_watch.rb +73 -0
  72. data/lib/em/future.rb +61 -0
  73. data/lib/em/iterator.rb +270 -0
  74. data/lib/em/messages.rb +66 -0
  75. data/lib/em/pool.rb +151 -0
  76. data/lib/em/process_watch.rb +45 -0
  77. data/lib/em/processes.rb +123 -0
  78. data/lib/em/protocols.rb +36 -0
  79. data/lib/em/protocols/header_and_content.rb +138 -0
  80. data/lib/em/protocols/httpclient.rb +279 -0
  81. data/lib/em/protocols/httpclient2.rb +600 -0
  82. data/lib/em/protocols/line_and_text.rb +125 -0
  83. data/lib/em/protocols/line_protocol.rb +29 -0
  84. data/lib/em/protocols/linetext2.rb +161 -0
  85. data/lib/em/protocols/memcache.rb +331 -0
  86. data/lib/em/protocols/object_protocol.rb +46 -0
  87. data/lib/em/protocols/postgres3.rb +246 -0
  88. data/lib/em/protocols/saslauth.rb +175 -0
  89. data/lib/em/protocols/smtpclient.rb +365 -0
  90. data/lib/em/protocols/smtpserver.rb +640 -0
  91. data/lib/em/protocols/socks4.rb +66 -0
  92. data/lib/em/protocols/stomp.rb +202 -0
  93. data/lib/em/protocols/tcptest.rb +54 -0
  94. data/lib/em/pure_ruby.rb +1017 -0
  95. data/lib/em/queue.rb +71 -0
  96. data/lib/em/resolver.rb +192 -0
  97. data/lib/em/spawnable.rb +84 -0
  98. data/lib/em/streamer.rb +118 -0
  99. data/lib/em/threaded_resource.rb +90 -0
  100. data/lib/em/tick_loop.rb +85 -0
  101. data/lib/em/timers.rb +61 -0
  102. data/lib/em/version.rb +3 -0
  103. data/lib/eventmachine.rb +1532 -0
  104. data/lib/jeventmachine.rb +284 -0
  105. data/lib/sonixlabs-eventmachine-java.rb +1 -0
  106. data/rakelib/cpp.rake_example +77 -0
  107. data/rakelib/package.rake +98 -0
  108. data/rakelib/test.rake +8 -0
  109. data/tests/client.crt +31 -0
  110. data/tests/client.key +51 -0
  111. data/tests/em_test_helper.rb +64 -0
  112. data/tests/test_attach.rb +126 -0
  113. data/tests/test_basic.rb +294 -0
  114. data/tests/test_channel.rb +62 -0
  115. data/tests/test_completion.rb +177 -0
  116. data/tests/test_connection_count.rb +33 -0
  117. data/tests/test_defer.rb +18 -0
  118. data/tests/test_deferrable.rb +35 -0
  119. data/tests/test_epoll.rb +130 -0
  120. data/tests/test_error_handler.rb +38 -0
  121. data/tests/test_exc.rb +28 -0
  122. data/tests/test_file_watch.rb +65 -0
  123. data/tests/test_futures.rb +170 -0
  124. data/tests/test_get_sock_opt.rb +37 -0
  125. data/tests/test_handler_check.rb +35 -0
  126. data/tests/test_hc.rb +155 -0
  127. data/tests/test_httpclient.rb +190 -0
  128. data/tests/test_httpclient2.rb +128 -0
  129. data/tests/test_idle_connection.rb +23 -0
  130. data/tests/test_inactivity_timeout.rb +54 -0
  131. data/tests/test_kb.rb +34 -0
  132. data/tests/test_ltp.rb +138 -0
  133. data/tests/test_ltp2.rb +288 -0
  134. data/tests/test_next_tick.rb +104 -0
  135. data/tests/test_object_protocol.rb +36 -0
  136. data/tests/test_pause.rb +78 -0
  137. data/tests/test_pending_connect_timeout.rb +52 -0
  138. data/tests/test_pool.rb +194 -0
  139. data/tests/test_process_watch.rb +48 -0
  140. data/tests/test_processes.rb +128 -0
  141. data/tests/test_proxy_connection.rb +180 -0
  142. data/tests/test_pure.rb +88 -0
  143. data/tests/test_queue.rb +50 -0
  144. data/tests/test_resolver.rb +55 -0
  145. data/tests/test_running.rb +14 -0
  146. data/tests/test_sasl.rb +47 -0
  147. data/tests/test_send_file.rb +217 -0
  148. data/tests/test_servers.rb +33 -0
  149. data/tests/test_set_sock_opt.rb +37 -0
  150. data/tests/test_shutdown_hooks.rb +23 -0
  151. data/tests/test_smtpclient.rb +55 -0
  152. data/tests/test_smtpserver.rb +57 -0
  153. data/tests/test_spawn.rb +293 -0
  154. data/tests/test_ssl_args.rb +78 -0
  155. data/tests/test_ssl_methods.rb +48 -0
  156. data/tests/test_ssl_verify.rb +82 -0
  157. data/tests/test_threaded_resource.rb +53 -0
  158. data/tests/test_tick_loop.rb +59 -0
  159. data/tests/test_timers.rb +123 -0
  160. data/tests/test_ud.rb +8 -0
  161. data/tests/test_unbind_reason.rb +48 -0
  162. metadata +301 -0
@@ -0,0 +1,52 @@
1
+ require 'em_test_helper'
2
+
3
+ class TestPendingConnectTimeout < Test::Unit::TestCase
4
+
5
+ if EM.respond_to? :get_pending_connect_timeout
6
+ def test_default
7
+ EM.run {
8
+ c = EM.connect("127.0.0.1", 54321)
9
+ assert_equal 20.0, c.pending_connect_timeout
10
+ EM.stop
11
+ }
12
+ end
13
+
14
+ def test_set_and_get
15
+ EM.run {
16
+ c = EM.connect("127.0.0.1", 54321)
17
+ c.pending_connect_timeout = 2.5
18
+ assert_equal 2.5, c.pending_connect_timeout
19
+ EM.stop
20
+ }
21
+ end
22
+
23
+ def test_for_real
24
+ start, finish = nil
25
+
26
+ timeout_handler = Module.new do
27
+ define_method :unbind do
28
+ finish = Time.now
29
+ EM.stop
30
+ end
31
+ end
32
+
33
+ EM.run {
34
+ setup_timeout
35
+ EM.heartbeat_interval = 0.1
36
+ start = Time.now
37
+ c = EM.connect("1.2.3.4", 54321, timeout_handler)
38
+ c.pending_connect_timeout = 0.2
39
+ }
40
+
41
+ assert_in_delta(0.2, (finish - start), 0.1)
42
+ end
43
+ else
44
+ warn "EM.pending_connect_timeout not implemented, skipping tests in #{__FILE__}"
45
+
46
+ # Because some rubies will complain if a TestCase class has no tests
47
+ def test_em_pending_connect_timeout_not_implemented
48
+ assert true
49
+ end
50
+ end
51
+
52
+ end
@@ -0,0 +1,194 @@
1
+ class TestPool < Test::Unit::TestCase
2
+ def pool
3
+ @pool ||= EM::Pool.new
4
+ end
5
+
6
+ def go
7
+ EM.run { yield }
8
+ end
9
+
10
+ def stop
11
+ EM.stop
12
+ end
13
+
14
+ def deferrable
15
+ @deferrable ||= EM::DefaultDeferrable.new
16
+ end
17
+
18
+ def test_supports_more_work_than_resources
19
+ ran = false
20
+ go do
21
+ pool.perform do
22
+ ran = true
23
+ deferrable
24
+ end
25
+ stop
26
+ end
27
+ assert_equal false, ran
28
+ go do
29
+ pool.add :resource
30
+ stop
31
+ end
32
+ assert_equal true, ran
33
+ end
34
+
35
+ def test_reques_resources_on_error
36
+ pooled_res, pooled_res2 = nil
37
+ pool.add :res
38
+ go do
39
+ pool.perform do |res|
40
+ pooled_res = res
41
+ deferrable
42
+ end
43
+ stop
44
+ end
45
+ deferrable.fail
46
+ go do
47
+ pool.perform do |res|
48
+ pooled_res2 = res
49
+ deferrable
50
+ end
51
+ stop
52
+ end
53
+ assert_equal :res, pooled_res
54
+ assert_equal pooled_res, pooled_res2
55
+ end
56
+
57
+ def test_supports_custom_error_handler
58
+ eres = nil
59
+ pool.on_error do |res|
60
+ eres = res
61
+ end
62
+ performs = []
63
+ pool.add :res
64
+ go do
65
+ pool.perform do |res|
66
+ performs << res
67
+ deferrable
68
+ end
69
+ pool.perform do |res|
70
+ performs << res
71
+ deferrable
72
+ end
73
+ deferrable.fail
74
+ stop
75
+ end
76
+ assert_equal :res, eres
77
+ # manual requeues required when error handler is installed:
78
+ assert_equal 1, performs.size
79
+ assert_equal :res, performs.first
80
+ end
81
+
82
+ def test_catches_successful_deferrables
83
+ performs = []
84
+ pool.add :res
85
+ go do
86
+ pool.perform { |res| performs << res; deferrable }
87
+ pool.perform { |res| performs << res; deferrable }
88
+ stop
89
+ end
90
+ assert_equal [:res], performs
91
+ deferrable.succeed
92
+ go { stop }
93
+ assert_equal [:res, :res], performs
94
+ end
95
+
96
+ def test_prunes_locked_and_removed_resources
97
+ performs = []
98
+ pool.add :res
99
+ deferrable.succeed
100
+ go do
101
+ pool.perform { |res| performs << res; pool.remove res; deferrable }
102
+ pool.perform { |res| performs << res; pool.remove res; deferrable }
103
+ stop
104
+ end
105
+ assert_equal [:res], performs
106
+ end
107
+
108
+ # Contents is only to be used for inspection of the pool!
109
+ def test_contents
110
+ pool.add :res
111
+ assert_equal [:res], pool.contents
112
+ # Assert that modifying the contents list does not affect the pools
113
+ # contents.
114
+ pool.contents.delete(:res)
115
+ assert_equal [:res], pool.contents
116
+ end
117
+
118
+ def test_contents_when_perform_errors_and_on_error_is_not_set
119
+ pool.add :res
120
+ assert_equal [:res], pool.contents
121
+
122
+ pool.perform do |r|
123
+ d = EM::DefaultDeferrable.new
124
+ d.fail
125
+ d
126
+ end
127
+
128
+ EM.run { EM.next_tick { EM.stop } }
129
+
130
+ assert_equal [:res], pool.contents
131
+ end
132
+
133
+ def test_contents_when_perform_errors_and_on_error_is_set
134
+ pool.add :res
135
+ res = nil
136
+ pool.on_error do |r|
137
+ res = r
138
+ end
139
+ assert_equal [:res], pool.contents
140
+
141
+ pool.perform do |r|
142
+ d = EM::DefaultDeferrable.new
143
+ d.fail 'foo'
144
+ d
145
+ end
146
+
147
+ EM.run { EM.next_tick { EM.stop } }
148
+
149
+ assert_equal :res, res
150
+ assert_equal [], pool.contents
151
+ end
152
+
153
+ def test_num_waiting
154
+ pool.add :res
155
+ assert_equal 0, pool.num_waiting
156
+ pool.perform { |r| EM::DefaultDeferrable.new }
157
+ assert_equal 0, pool.num_waiting
158
+ 10.times { pool.perform { |r| EM::DefaultDeferrable.new } }
159
+ EM.run { EM.next_tick { EM.stop } }
160
+ assert_equal 10, pool.num_waiting
161
+ end
162
+
163
+ def test_exceptions_in_the_work_block_bubble_up_raise_and_fail_the_resource
164
+ pool.add :res
165
+
166
+ res = nil
167
+ pool.on_error { |r| res = r }
168
+ pool.perform { raise 'boom' }
169
+
170
+ assert_raises(RuntimeError) do
171
+ EM.run { EM.next_tick { EM.stop } }
172
+ end
173
+
174
+ assert_equal [], pool.contents
175
+ assert_equal :res, res
176
+ end
177
+
178
+ def test_removed_list_does_not_leak_on_errors
179
+ pool.add :res
180
+
181
+ pool.on_error do |r|
182
+ # This is actually the wrong thing to do, and not required, but some users
183
+ # might do it. When they do, they would find that @removed would cause a
184
+ # slow leak.
185
+ pool.remove r
186
+ end
187
+
188
+ pool.perform { d = EM::DefaultDeferrable.new; d.fail; d }
189
+
190
+ EM.run { EM.next_tick { EM.stop } }
191
+ assert_equal [], pool.instance_variable_get(:@removed)
192
+ end
193
+
194
+ end
@@ -0,0 +1,48 @@
1
+ require '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
+ EM.run{
31
+ # watch ourselves for a fork notification
32
+ EM.watch_process(Process.pid, ParentProcessWatcher)
33
+ $fork_pid = fork{ sleep }
34
+ child = EM.watch_process($fork_pid, ChildProcessWatcher)
35
+ $pid = child.pid
36
+
37
+ EM.add_timer(0.2){
38
+ Process.kill('TERM', $fork_pid)
39
+ }
40
+ }
41
+
42
+ assert_equal($pid, $fork_pid)
43
+ assert($forked)
44
+ assert($exited)
45
+ assert($unbind)
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,128 @@
1
+ require '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
+ EM.run{
36
+ EM.system('ls'){ |out,status| $out, $status = out, status; EM.stop }
37
+ }
38
+
39
+ assert( $out.length > 0 )
40
+ assert_equal($status.exitstatus, 0)
41
+ assert_equal($status.class, Process::Status)
42
+ end
43
+
44
+ def test_em_system_pid
45
+ $pids = []
46
+
47
+ EM.run{
48
+ $pids << EM.system('echo hi', proc{ |out,status|$pids << status.pid; EM.stop })
49
+ }
50
+
51
+ assert_equal $pids[0], $pids[1]
52
+ end
53
+
54
+ def test_em_system_with_proc
55
+ EM.run{
56
+ EM.system('ls', proc{ |out,status| $out, $status = out, status; EM.stop })
57
+ }
58
+
59
+ assert( $out.length > 0 )
60
+ assert_equal($status.exitstatus, 0)
61
+ assert_equal($status.class, Process::Status)
62
+ end
63
+
64
+ def test_em_system_with_two_procs
65
+ EM.run{
66
+ EM.system('sh', proc{ |process|
67
+ process.send_data("echo hello\n")
68
+ process.send_data("exit\n")
69
+ }, proc{ |out,status|
70
+ $out = out
71
+ $status = status
72
+ EM.stop
73
+ })
74
+ }
75
+
76
+ assert_equal("hello\n", $out)
77
+ end
78
+
79
+ def test_em_system_cmd_arguments
80
+ EM.run{
81
+ EM.system('echo', '1', '2', 'version', proc{ |process|
82
+ }, proc{ |out,status|
83
+ $out = out
84
+ $status = status
85
+ EM.stop
86
+ })
87
+ }
88
+
89
+ assert_match(/1 2 version/i, $out)
90
+ end
91
+
92
+ def test_em_system_spaced_arguments
93
+ EM.run{
94
+ EM.system('ruby', '-e', 'puts "hello"', proc{ |out,status|
95
+ $out = out
96
+ EM.stop
97
+ })
98
+ }
99
+
100
+ assert_equal("hello\n", $out)
101
+ end
102
+
103
+ def test_em_popen_pause_resume
104
+ c_rx = 0
105
+
106
+ test_client = Module.new do
107
+ define_method :receive_data do |data|
108
+ c_rx += 1
109
+ pause
110
+ EM.add_timer(0.5) { EM.stop }
111
+ end
112
+ end
113
+
114
+ EM.run{
115
+ EM.popen('cat /dev/random', test_client)
116
+ }
117
+
118
+ assert_equal 1, c_rx
119
+ end
120
+ else
121
+ warn "EM.popen not implemented, skipping tests in #{__FILE__}"
122
+
123
+ # Because some rubies will complain if a TestCase class has no tests
124
+ def test_em_popen_unsupported
125
+ assert true
126
+ end
127
+ end
128
+ end
@@ -0,0 +1,180 @@
1
+ require '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