eventmachine-le 1.1.0.beta.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 (129) hide show
  1. data/.gitignore +21 -0
  2. data/.yardopts +7 -0
  3. data/GNU +281 -0
  4. data/LICENSE +60 -0
  5. data/README.md +80 -0
  6. data/Rakefile +19 -0
  7. data/eventmachine-le.gemspec +42 -0
  8. data/ext/binder.cpp +124 -0
  9. data/ext/binder.h +46 -0
  10. data/ext/cmain.cpp +841 -0
  11. data/ext/ed.cpp +1995 -0
  12. data/ext/ed.h +424 -0
  13. data/ext/em.cpp +2377 -0
  14. data/ext/em.h +243 -0
  15. data/ext/eventmachine.h +126 -0
  16. data/ext/extconf.rb +166 -0
  17. data/ext/fastfilereader/extconf.rb +94 -0
  18. data/ext/fastfilereader/mapper.cpp +214 -0
  19. data/ext/fastfilereader/mapper.h +59 -0
  20. data/ext/fastfilereader/rubymain.cpp +127 -0
  21. data/ext/kb.cpp +79 -0
  22. data/ext/page.cpp +107 -0
  23. data/ext/page.h +51 -0
  24. data/ext/pipe.cpp +347 -0
  25. data/ext/project.h +155 -0
  26. data/ext/rubymain.cpp +1269 -0
  27. data/ext/ssl.cpp +468 -0
  28. data/ext/ssl.h +94 -0
  29. data/lib/em/buftok.rb +110 -0
  30. data/lib/em/callback.rb +58 -0
  31. data/lib/em/channel.rb +64 -0
  32. data/lib/em/completion.rb +304 -0
  33. data/lib/em/connection.rb +728 -0
  34. data/lib/em/deferrable.rb +210 -0
  35. data/lib/em/deferrable/pool.rb +2 -0
  36. data/lib/em/file_watch.rb +73 -0
  37. data/lib/em/future.rb +61 -0
  38. data/lib/em/iterator.rb +313 -0
  39. data/lib/em/messages.rb +66 -0
  40. data/lib/em/pool.rb +151 -0
  41. data/lib/em/process_watch.rb +45 -0
  42. data/lib/em/processes.rb +123 -0
  43. data/lib/em/protocols.rb +37 -0
  44. data/lib/em/protocols/header_and_content.rb +138 -0
  45. data/lib/em/protocols/httpclient.rb +279 -0
  46. data/lib/em/protocols/httpclient2.rb +600 -0
  47. data/lib/em/protocols/line_and_text.rb +125 -0
  48. data/lib/em/protocols/line_protocol.rb +29 -0
  49. data/lib/em/protocols/linetext2.rb +161 -0
  50. data/lib/em/protocols/memcache.rb +331 -0
  51. data/lib/em/protocols/object_protocol.rb +46 -0
  52. data/lib/em/protocols/postgres3.rb +246 -0
  53. data/lib/em/protocols/saslauth.rb +175 -0
  54. data/lib/em/protocols/smtpclient.rb +365 -0
  55. data/lib/em/protocols/smtpserver.rb +663 -0
  56. data/lib/em/protocols/socks4.rb +66 -0
  57. data/lib/em/protocols/stomp.rb +202 -0
  58. data/lib/em/protocols/tcptest.rb +54 -0
  59. data/lib/em/queue.rb +71 -0
  60. data/lib/em/resolver.rb +195 -0
  61. data/lib/em/spawnable.rb +84 -0
  62. data/lib/em/streamer.rb +118 -0
  63. data/lib/em/threaded_resource.rb +90 -0
  64. data/lib/em/tick_loop.rb +85 -0
  65. data/lib/em/timers.rb +106 -0
  66. data/lib/em/version.rb +3 -0
  67. data/lib/eventmachine-le.rb +10 -0
  68. data/lib/eventmachine.rb +1548 -0
  69. data/rakelib/cpp.rake_example +77 -0
  70. data/rakelib/package.rake +98 -0
  71. data/rakelib/test.rake +8 -0
  72. data/tests/client.crt +31 -0
  73. data/tests/client.key +51 -0
  74. data/tests/em_test_helper.rb +143 -0
  75. data/tests/test_attach.rb +148 -0
  76. data/tests/test_basic.rb +294 -0
  77. data/tests/test_channel.rb +62 -0
  78. data/tests/test_completion.rb +177 -0
  79. data/tests/test_connection_count.rb +33 -0
  80. data/tests/test_defer.rb +18 -0
  81. data/tests/test_deferrable.rb +35 -0
  82. data/tests/test_epoll.rb +134 -0
  83. data/tests/test_error_handler.rb +38 -0
  84. data/tests/test_exc.rb +28 -0
  85. data/tests/test_file_watch.rb +65 -0
  86. data/tests/test_futures.rb +170 -0
  87. data/tests/test_get_sock_opt.rb +37 -0
  88. data/tests/test_handler_check.rb +35 -0
  89. data/tests/test_hc.rb +155 -0
  90. data/tests/test_httpclient.rb +190 -0
  91. data/tests/test_httpclient2.rb +128 -0
  92. data/tests/test_inactivity_timeout.rb +54 -0
  93. data/tests/test_ipv4.rb +125 -0
  94. data/tests/test_ipv6.rb +131 -0
  95. data/tests/test_iterator.rb +110 -0
  96. data/tests/test_kb.rb +34 -0
  97. data/tests/test_line_protocol.rb +33 -0
  98. data/tests/test_ltp.rb +138 -0
  99. data/tests/test_ltp2.rb +288 -0
  100. data/tests/test_next_tick.rb +104 -0
  101. data/tests/test_object_protocol.rb +36 -0
  102. data/tests/test_pause.rb +78 -0
  103. data/tests/test_pending_connect_timeout.rb +52 -0
  104. data/tests/test_pool.rb +196 -0
  105. data/tests/test_process_watch.rb +48 -0
  106. data/tests/test_processes.rb +133 -0
  107. data/tests/test_proxy_connection.rb +168 -0
  108. data/tests/test_pure.rb +88 -0
  109. data/tests/test_queue.rb +50 -0
  110. data/tests/test_resolver.rb +55 -0
  111. data/tests/test_running.rb +14 -0
  112. data/tests/test_sasl.rb +47 -0
  113. data/tests/test_send_file.rb +217 -0
  114. data/tests/test_servers.rb +33 -0
  115. data/tests/test_set_sock_opt.rb +41 -0
  116. data/tests/test_shutdown_hooks.rb +23 -0
  117. data/tests/test_smtpclient.rb +55 -0
  118. data/tests/test_smtpserver.rb +120 -0
  119. data/tests/test_spawn.rb +293 -0
  120. data/tests/test_ssl_args.rb +78 -0
  121. data/tests/test_ssl_methods.rb +48 -0
  122. data/tests/test_ssl_verify.rb +82 -0
  123. data/tests/test_threaded_resource.rb +55 -0
  124. data/tests/test_tick_loop.rb +59 -0
  125. data/tests/test_timers.rb +180 -0
  126. data/tests/test_ud.rb +8 -0
  127. data/tests/test_udp46.rb +53 -0
  128. data/tests/test_unbind_reason.rb +48 -0
  129. metadata +390 -0
@@ -0,0 +1,33 @@
1
+ require 'em_test_helper'
2
+
3
+ class TestConnectionCount < Test::Unit::TestCase
4
+ def test_idle_connection_count
5
+ EM.run {
6
+ $count = EM.connection_count
7
+ EM.stop_event_loop
8
+ }
9
+
10
+ assert_equal(0, $count)
11
+ end
12
+
13
+ module Client
14
+ def connection_completed
15
+ $client_conns += 1
16
+ EM.stop if $client_conns == 3
17
+ end
18
+ end
19
+
20
+ def test_with_some_connections
21
+ EM.run {
22
+ $client_conns = 0
23
+ $initial_conns = EM.connection_count
24
+ EM.start_server("127.0.0.1", 9999)
25
+ $server_conns = EM.connection_count
26
+ 3.times { EM.connect("127.0.0.1", 9999, Client) }
27
+ }
28
+
29
+ assert_equal(0, $initial_conns)
30
+ assert_equal(1, $server_conns)
31
+ assert_equal(4, $client_conns + $server_conns)
32
+ end
33
+ end
@@ -0,0 +1,18 @@
1
+ require 'em_test_helper'
2
+
3
+ class TestDefer < Test::Unit::TestCase
4
+
5
+ def test_defers
6
+ n = 0
7
+ n_times = 20
8
+ EM.run {
9
+ n_times.times {
10
+ work_proc = proc { n += 1 }
11
+ callback = proc { EM.stop if n == n_times }
12
+ EM.defer work_proc, callback
13
+ }
14
+ }
15
+ assert_equal( n, n_times )
16
+ end
17
+
18
+ end
@@ -0,0 +1,35 @@
1
+ require 'em_test_helper'
2
+
3
+ class TestDeferrable < Test::Unit::TestCase
4
+ class Later
5
+ include EM::Deferrable
6
+ end
7
+
8
+ def test_timeout_without_args
9
+ assert_nothing_raised do
10
+ EM.run {
11
+ df = Later.new
12
+ df.timeout(0)
13
+ df.errback { EM.stop }
14
+ EM.add_timer(0.01) { flunk "Deferrable was not timed out." }
15
+ }
16
+ end
17
+ end
18
+
19
+ def test_timeout_with_args
20
+ args = nil
21
+
22
+ EM.run {
23
+ df = Later.new
24
+ df.timeout(0, :timeout, :foo)
25
+ df.errback do |type, name|
26
+ args = [type, name]
27
+ EM.stop
28
+ end
29
+
30
+ EM.add_timer(0.01) { flunk "Deferrable was not timed out." }
31
+ }
32
+
33
+ assert_equal [:timeout, :foo], args
34
+ end
35
+ end
@@ -0,0 +1,134 @@
1
+ require 'em_test_helper'
2
+
3
+
4
+ class TestEpoll < Test::Unit::TestCase
5
+
6
+ module TestEchoServer
7
+ def receive_data data
8
+ send_data data
9
+ close_connection_after_writing
10
+ end
11
+ end
12
+
13
+ module TestEchoClient
14
+ def connection_completed
15
+ send_data "ABCDE"
16
+ $max += 1
17
+ end
18
+ def receive_data data
19
+ raise "bad response" unless data == "ABCDE"
20
+ end
21
+ def unbind
22
+ $n -= 1
23
+ EM.stop if $n == 0
24
+ end
25
+ end
26
+
27
+
28
+ if windows? || jruby?
29
+ warn "EM.set_descriptor_table_size not implemented, skipping test in #{__FILE__}"
30
+ else
31
+ # We can set the rlimit/nofile of a process but we can only set it
32
+ # higher if we're running as root.
33
+ # On most systems, the default value is 1024.
34
+ def test_rlimit
35
+ unless RUBY_PLATFORM =~ /java/ or EM.set_descriptor_table_size >= 1024
36
+ a = EM.set_descriptor_table_size
37
+ assert( a <= 1024 )
38
+ a = EM.set_descriptor_table_size( 1024 )
39
+ assert( a == 1024 )
40
+ end
41
+ end
42
+ end
43
+
44
+ # Run a high-volume version of this test by kicking the number of connections
45
+ # up past 512. (Each connection uses two sockets, a client and a server.)
46
+ # (Will require running the test as root)
47
+ # This test exercises TCP clients and servers.
48
+ #
49
+ # XXX this test causes all sort of weird issues on OSX (when run as part of the suite)
50
+ def _test_descriptors
51
+ EM.epoll
52
+ EM.set_descriptor_table_size 60000
53
+ EM.run {
54
+ EM.start_server "127.0.0.1", 9800, TestEchoServer
55
+ $n = 0
56
+ $max = 0
57
+ 100.times {
58
+ EM.connect("127.0.0.1", 9800, TestEchoClient) {$n += 1}
59
+ }
60
+ }
61
+ assert_equal(0, $n)
62
+ assert_equal(100, $max)
63
+ end
64
+
65
+ def setup
66
+ @port = next_port
67
+ end
68
+
69
+ module TestDatagramServer
70
+ def receive_data dgm
71
+ $in = dgm
72
+ send_data "abcdefghij"
73
+ end
74
+ end
75
+ module TestDatagramClient
76
+ def initialize port
77
+ @port = port
78
+ end
79
+
80
+ def post_init
81
+ send_datagram "1234567890", $testing_localhost, @port
82
+ end
83
+
84
+ def receive_data dgm
85
+ $out = dgm
86
+ EM.stop
87
+ end
88
+ end
89
+
90
+ def test_datagrams
91
+ local_ips.each { |localhost|
92
+ $testing_localhost = localhost
93
+ $in = $out = ""
94
+ EM.run {
95
+ setup_timeout(2)
96
+ EM.open_datagram_socket $testing_localhost, @port, TestDatagramServer
97
+ EM.open_datagram_socket $testing_localhost, 0, TestDatagramClient, @port
98
+ }
99
+ assert_equal( "1234567890", $in )
100
+ assert_equal( "abcdefghij", $out )
101
+ }
102
+ end
103
+
104
+ # XXX this test fails randomly..
105
+ def _test_unix_domain
106
+ fn = "/tmp/xxx.chain"
107
+ EM.epoll
108
+ EM.set_descriptor_table_size 60000
109
+ EM.run {
110
+ # The pure-Ruby version won't let us open the socket if the node already exists.
111
+ # Not sure, that actually may be correct and the compiled version is wrong.
112
+ # Pure Ruby also oddly won't let us make that many connections. This test used
113
+ # to run 100 times. Not sure where that lower connection-limit is coming from in
114
+ # pure Ruby.
115
+ # Let's not sweat the Unix-ness of the filename, since this test can't possibly
116
+ # work on Windows anyway.
117
+ #
118
+ File.unlink(fn) if File.exist?(fn)
119
+ EM.start_unix_domain_server fn, TestEchoServer
120
+ $n = 0
121
+ $max = 0
122
+ 50.times {
123
+ EM.connect_unix_domain(fn, TestEchoClient) {$n += 1}
124
+ }
125
+ EM::add_timer(1) { $stderr.puts("test_unix_domain timed out!"); EM::stop }
126
+ }
127
+ assert_equal(0, $n)
128
+ assert_equal(50, $max)
129
+ ensure
130
+ File.unlink(fn) if File.exist?(fn)
131
+ end
132
+
133
+ end
134
+
@@ -0,0 +1,38 @@
1
+ require 'em_test_helper'
2
+
3
+ class TestErrorHandler < Test::Unit::TestCase
4
+ def setup
5
+ @exception = Class.new(StandardError)
6
+ end
7
+
8
+ def test_error_handler
9
+ error = nil
10
+
11
+ EM.error_handler{ |e|
12
+ error = e
13
+ EM.error_handler(nil)
14
+ EM.stop
15
+ }
16
+
17
+ assert_nothing_raised do
18
+ EM.run{
19
+ EM.add_timer(0){
20
+ raise @exception, 'test'
21
+ }
22
+ }
23
+ end
24
+
25
+ assert_equal error.class, @exception
26
+ assert_equal error.message, 'test'
27
+ end
28
+
29
+ def test_without_error_handler
30
+ assert_raise @exception do
31
+ EM.run{
32
+ EM.add_timer(0){
33
+ raise @exception, 'test'
34
+ }
35
+ }
36
+ end
37
+ end
38
+ end
data/tests/test_exc.rb ADDED
@@ -0,0 +1,28 @@
1
+ require 'em_test_helper'
2
+
3
+ class TestSomeExceptions < Test::Unit::TestCase
4
+
5
+ # Read the commentary in EM#run.
6
+ # This test exercises the ensure block in #run that makes sure
7
+ # EM#release_machine gets called even if an exception is
8
+ # thrown within the user code. Without the ensured call to release_machine,
9
+ # the second call to EM#run will fail with a C++ exception
10
+ # because the machine wasn't cleaned up properly.
11
+
12
+ def test_a
13
+ assert_raises(RuntimeError) {
14
+ EM.run {
15
+ raise "some exception"
16
+ }
17
+ }
18
+ end
19
+
20
+ def test_b
21
+ assert_raises(RuntimeError) {
22
+ EM.run {
23
+ raise "some exception"
24
+ }
25
+ }
26
+ end
27
+
28
+ end
@@ -0,0 +1,65 @@
1
+ require 'em_test_helper'
2
+ require 'tempfile'
3
+
4
+ class TestFileWatch < Test::Unit::TestCase
5
+ if windows?
6
+ def test_watch_file_raises_unsupported_error
7
+ assert_raises(EM::Unsupported) do
8
+ EM.run do
9
+ file = Tempfile.new("fake_file")
10
+ EM.watch_file(file.path)
11
+ end
12
+ end
13
+ end
14
+ elsif EM.respond_to? :watch_filename
15
+ module FileWatcher
16
+ def file_modified
17
+ $modified = true
18
+ end
19
+ def file_deleted
20
+ $deleted = true
21
+ end
22
+ def unbind
23
+ $unbind = true
24
+ EM.stop
25
+ end
26
+ end
27
+
28
+ def setup
29
+ EM.kqueue = true if EM.kqueue?
30
+ end
31
+
32
+ def teardown
33
+ EM.kqueue = false if EM.kqueue?
34
+ end
35
+
36
+ def test_events
37
+ EM.run{
38
+ file = Tempfile.new('em-watch')
39
+ $tmp_path = file.path
40
+
41
+ # watch it
42
+ watch = EM.watch_file(file.path, FileWatcher)
43
+ $path = watch.path
44
+
45
+ # modify it
46
+ File.open(file.path, 'w'){ |f| f.puts 'hi' }
47
+
48
+ # delete it
49
+ EM.add_timer(0.01){ file.close; file.delete }
50
+ }
51
+
52
+ assert_equal($path, $tmp_path)
53
+ assert($modified)
54
+ assert($deleted)
55
+ assert($unbind)
56
+ end
57
+ else
58
+ warn "EM.watch_file not implemented, skipping tests in #{__FILE__}"
59
+
60
+ # Because some rubies will complain if a TestCase class has no tests
61
+ def test_em_watch_file_unsupported
62
+ assert true
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,170 @@
1
+ require 'em_test_helper'
2
+
3
+ class TestFutures < Test::Unit::TestCase
4
+
5
+ def setup
6
+ end
7
+
8
+ def teardown
9
+ end
10
+
11
+ def test_future
12
+ assert_equal(100, EM::Deferrable.future(100) )
13
+
14
+ p1 = proc { 100 + 1 }
15
+ assert_equal(101, EM::Deferrable.future(p1) )
16
+ end
17
+
18
+ class MyFuture
19
+ include EM::Deferrable
20
+ def initialize *args
21
+ super
22
+ set_deferred_status :succeeded, 40
23
+ end
24
+ end
25
+
26
+ class MyErrorFuture
27
+ include EM::Deferrable
28
+ def initialize *args
29
+ super
30
+ set_deferred_status :failed, 41
31
+ end
32
+ end
33
+
34
+
35
+ def test_future_1
36
+ # Call future with one additional argument and it will be treated as a callback.
37
+ def my_future
38
+ MyFuture.new
39
+ end
40
+
41
+ value = nil
42
+ EM::Deferrable.future my_future, proc {|v| value=v}
43
+ assert_equal( 40, value )
44
+ end
45
+
46
+
47
+ def test_future_2
48
+ # Call future with two additional arguments and they will be treated as a callback
49
+ # and an errback.
50
+ value = nil
51
+ EM::Deferrable.future MyErrorFuture.new, nil, proc {|v| value=v}
52
+ assert_equal( 41, value )
53
+ end
54
+
55
+
56
+ def test_future_3
57
+ # Call future with no additional arguments but with a block, and the block will be
58
+ # treated as a callback.
59
+ value = nil
60
+ EM::Deferrable.future MyFuture.new do |v|
61
+ value=v
62
+ end
63
+ assert_equal( 40, value )
64
+ end
65
+
66
+
67
+ class RecursiveCallback
68
+ include EM::Deferrable
69
+ end
70
+
71
+ # A Deferrable callback can call #set_deferred_status to change the values
72
+ # passed to subsequent callbacks.
73
+ #
74
+ def test_recursive_callbacks
75
+ n = 0 # counter assures that all the tests actually run.
76
+ rc = RecursiveCallback.new
77
+ rc.callback {|a|
78
+ assert_equal(100, a)
79
+ n += 1
80
+ rc.set_deferred_status :succeeded, 101, 101
81
+ }
82
+ rc.callback {|a,b|
83
+ assert_equal(101, a)
84
+ assert_equal(101, b)
85
+ n += 1
86
+ rc.set_deferred_status :succeeded, 102, 102, 102
87
+ }
88
+ rc.callback {|a,b,c|
89
+ assert_equal(102, a)
90
+ assert_equal(102, b)
91
+ assert_equal(102, c)
92
+ n += 1
93
+ }
94
+ rc.set_deferred_status :succeeded, 100
95
+ assert_equal(3, n)
96
+ end
97
+
98
+ def test_syntactic_sugar
99
+ rc = RecursiveCallback.new
100
+ rc.set_deferred_success 100
101
+ rc.set_deferred_failure 200
102
+ end
103
+
104
+ # It doesn't raise an error to set deferred status more than once.
105
+ # In fact, this is a desired and useful idiom when it happens INSIDE
106
+ # a callback or errback.
107
+ # However, it's less useful otherwise, and in fact would generally be
108
+ # indicative of a programming error. However, we would like to be resistant
109
+ # to such errors. So whenever we set deferred status, we also clear BOTH
110
+ # stacks of handlers.
111
+ #
112
+ def test_double_calls
113
+ s = 0
114
+ e = 0
115
+
116
+ d = EM::DefaultDeferrable.new
117
+ d.callback {s += 1}
118
+ d.errback {e += 1}
119
+
120
+ d.succeed # We expect the callback to be called, and the errback to be DISCARDED.
121
+ d.fail # Presumably an error. We expect the errback NOT to be called.
122
+ d.succeed # We expect the callback to have been discarded and NOT to be called again.
123
+
124
+ assert_equal(1, s)
125
+ assert_equal(0, e)
126
+ end
127
+
128
+ # Adding a callback to a Deferrable that is already in a success state executes the callback
129
+ # immediately. The same applies to a an errback added to an already-failed Deferrable.
130
+ # HOWEVER, we expect NOT to be able to add errbacks to succeeded Deferrables, or callbacks
131
+ # to failed ones.
132
+ #
133
+ # We illustrate this with a rather contrived test. The test calls #fail after #succeed,
134
+ # which ordinarily would not happen in a real program.
135
+ #
136
+ # What we're NOT attempting to specify is what happens if a Deferrable is succeeded and then
137
+ # failed (or vice-versa). Should we then be able to add callbacks/errbacks of the appropriate
138
+ # type for immediate execution? For now at least, the official answer is "don't do that."
139
+ #
140
+ def test_delayed_callbacks
141
+ s1 = 0
142
+ s2 = 0
143
+ e = 0
144
+
145
+ d = EM::DefaultDeferrable.new
146
+ d.callback {s1 += 1}
147
+
148
+ d.succeed # Triggers and discards the callback.
149
+
150
+ d.callback {s2 += 1} # This callback is executed immediately and discarded.
151
+
152
+ d.errback {e += 1} # This errback should be DISCARDED and never execute.
153
+ d.fail # To prove it, fail and assert e is 0
154
+
155
+ assert_equal( [1,1], [s1,s2] )
156
+ assert_equal( 0, e )
157
+ end
158
+
159
+ def test_timeout
160
+ n = 0
161
+ EM.run {
162
+ d = EM::DefaultDeferrable.new
163
+ d.callback {n = 1; EM.stop}
164
+ d.errback {n = 2; EM.stop}
165
+ d.timeout(0.01)
166
+ }
167
+ assert_equal( 2, n )
168
+ end
169
+
170
+ end