wj_eventmachine 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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +179 -0
- data/GNU +281 -0
- data/LICENSE +60 -0
- data/README.md +110 -0
- data/docs/DocumentationGuidesIndex.md +27 -0
- data/docs/GettingStarted.md +520 -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/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 +52 -0
- data/ext/cmain.cpp +1046 -0
- data/ext/ed.cpp +2238 -0
- data/ext/ed.h +460 -0
- data/ext/em.cpp +2378 -0
- data/ext/em.h +266 -0
- data/ext/eventmachine.h +152 -0
- data/ext/extconf.rb +285 -0
- data/ext/fastfilereader/extconf.rb +120 -0
- data/ext/fastfilereader/mapper.cpp +214 -0
- data/ext/fastfilereader/mapper.h +59 -0
- data/ext/fastfilereader/rubymain.cpp +126 -0
- data/ext/kb.cpp +79 -0
- data/ext/page.cpp +107 -0
- data/ext/page.h +51 -0
- data/ext/pipe.cpp +354 -0
- data/ext/project.h +174 -0
- data/ext/rubymain.cpp +1610 -0
- data/ext/ssl.cpp +627 -0
- data/ext/ssl.h +103 -0
- data/ext/wait_for_single_fd.h +36 -0
- data/java/.classpath +8 -0
- data/java/.project +17 -0
- data/java/src/com/rubyeventmachine/EmReactor.java +625 -0
- data/java/src/com/rubyeventmachine/EmReactorException.java +40 -0
- data/java/src/com/rubyeventmachine/EmReactorInterface.java +70 -0
- data/java/src/com/rubyeventmachine/EventableChannel.java +72 -0
- data/java/src/com/rubyeventmachine/EventableDatagramChannel.java +201 -0
- data/java/src/com/rubyeventmachine/EventableSocketChannel.java +415 -0
- data/java/src/com/rubyeventmachine/NullEmReactor.java +157 -0
- data/java/src/com/rubyeventmachine/NullEventableChannel.java +81 -0
- data/lib/em/buftok.rb +59 -0
- data/lib/em/callback.rb +58 -0
- data/lib/em/channel.rb +69 -0
- data/lib/em/completion.rb +307 -0
- data/lib/em/connection.rb +776 -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/io_streamer.rb +68 -0
- data/lib/em/iterator.rb +252 -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 +37 -0
- data/lib/em/protocols/header_and_content.rb +138 -0
- data/lib/em/protocols/httpclient.rb +303 -0
- data/lib/em/protocols/httpclient2.rb +602 -0
- data/lib/em/protocols/line_and_text.rb +125 -0
- data/lib/em/protocols/line_protocol.rb +33 -0
- data/lib/em/protocols/linetext2.rb +179 -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 +394 -0
- data/lib/em/protocols/smtpserver.rb +666 -0
- data/lib/em/protocols/socks4.rb +66 -0
- data/lib/em/protocols/stomp.rb +205 -0
- data/lib/em/protocols/tcptest.rb +54 -0
- data/lib/em/pure_ruby.rb +1299 -0
- data/lib/em/queue.rb +80 -0
- data/lib/em/resolver.rb +232 -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 +1602 -0
- data/lib/jeventmachine.rb +318 -0
- data/rakelib/package.rake +120 -0
- data/rakelib/test.rake +6 -0
- data/rakelib/test_pure.rake +11 -0
- data/tests/client.crt +31 -0
- data/tests/client.key +51 -0
- data/tests/dhparam.pem +13 -0
- data/tests/em_ssl_handlers.rb +153 -0
- data/tests/em_test_helper.rb +198 -0
- data/tests/jruby/test_jeventmachine.rb +38 -0
- data/tests/test_attach.rb +199 -0
- data/tests/test_basic.rb +321 -0
- data/tests/test_channel.rb +75 -0
- data/tests/test_completion.rb +178 -0
- data/tests/test_connection_count.rb +83 -0
- data/tests/test_connection_write.rb +35 -0
- data/tests/test_defer.rb +35 -0
- data/tests/test_deferrable.rb +35 -0
- data/tests/test_epoll.rb +141 -0
- data/tests/test_error_handler.rb +38 -0
- data/tests/test_exc.rb +37 -0
- data/tests/test_file_watch.rb +86 -0
- data/tests/test_fork.rb +75 -0
- data/tests/test_futures.rb +170 -0
- data/tests/test_handler_check.rb +35 -0
- data/tests/test_hc.rb +155 -0
- data/tests/test_httpclient.rb +238 -0
- data/tests/test_httpclient2.rb +132 -0
- data/tests/test_idle_connection.rb +31 -0
- data/tests/test_inactivity_timeout.rb +102 -0
- data/tests/test_io_streamer.rb +47 -0
- data/tests/test_ipv4.rb +96 -0
- data/tests/test_ipv6.rb +107 -0
- data/tests/test_iterator.rb +122 -0
- data/tests/test_kb.rb +28 -0
- data/tests/test_keepalive.rb +113 -0
- data/tests/test_line_protocol.rb +33 -0
- data/tests/test_ltp.rb +155 -0
- data/tests/test_ltp2.rb +332 -0
- data/tests/test_many_fds.rb +21 -0
- data/tests/test_next_tick.rb +104 -0
- data/tests/test_object_protocol.rb +36 -0
- data/tests/test_pause.rb +109 -0
- data/tests/test_pending_connect_timeout.rb +52 -0
- data/tests/test_pool.rb +196 -0
- data/tests/test_process_watch.rb +50 -0
- data/tests/test_processes.rb +128 -0
- data/tests/test_proxy_connection.rb +180 -0
- data/tests/test_pure.rb +156 -0
- data/tests/test_queue.rb +64 -0
- data/tests/test_resolver.rb +129 -0
- data/tests/test_running.rb +14 -0
- data/tests/test_sasl.rb +46 -0
- data/tests/test_send_file.rb +217 -0
- data/tests/test_servers.rb +32 -0
- data/tests/test_shutdown_hooks.rb +23 -0
- data/tests/test_smtpclient.rb +75 -0
- data/tests/test_smtpserver.rb +90 -0
- data/tests/test_sock_opt.rb +53 -0
- data/tests/test_spawn.rb +290 -0
- data/tests/test_ssl_args.rb +41 -0
- data/tests/test_ssl_dhparam.rb +57 -0
- data/tests/test_ssl_ecdh_curve.rb +57 -0
- data/tests/test_ssl_extensions.rb +24 -0
- data/tests/test_ssl_methods.rb +31 -0
- data/tests/test_ssl_protocols.rb +190 -0
- data/tests/test_ssl_verify.rb +52 -0
- data/tests/test_stomp.rb +38 -0
- data/tests/test_system.rb +46 -0
- data/tests/test_threaded_resource.rb +68 -0
- data/tests/test_tick_loop.rb +58 -0
- data/tests/test_timers.rb +150 -0
- data/tests/test_ud.rb +8 -0
- data/tests/test_unbind_reason.rb +40 -0
- metadata +384 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'em_test_helper'
|
|
4
|
+
require 'em/io_streamer'
|
|
5
|
+
|
|
6
|
+
# below to stop 'already initialized constant' warning
|
|
7
|
+
EM::IOStreamer.__send__ :remove_const, :CHUNK_SIZE
|
|
8
|
+
EM::IOStreamer.const_set :CHUNK_SIZE, 2
|
|
9
|
+
|
|
10
|
+
class TestIOStreamer < Test::Unit::TestCase
|
|
11
|
+
|
|
12
|
+
class StreamServer < EM::Connection
|
|
13
|
+
def initialize(sent)
|
|
14
|
+
@sent = sent
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def post_init
|
|
18
|
+
io = StringIO.new @sent
|
|
19
|
+
EM::IOStreamer.new(self, io).callback { close_connection_after_writing }
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
class StreamClient < EM::Connection
|
|
24
|
+
def initialize(received)
|
|
25
|
+
@received = received
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def receive_data data
|
|
29
|
+
@received << data
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def unbind
|
|
33
|
+
EM.stop
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def test_io_stream
|
|
38
|
+
sent = 'this is a test'
|
|
39
|
+
received = ''.dup
|
|
40
|
+
EM.run do
|
|
41
|
+
port = next_port
|
|
42
|
+
EM.start_server '127.0.0.1', port, StreamServer, sent
|
|
43
|
+
EM.connect '127.0.0.1', port, StreamClient, received
|
|
44
|
+
end
|
|
45
|
+
assert_equal sent, received
|
|
46
|
+
end
|
|
47
|
+
end
|
data/tests/test_ipv4.rb
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
require_relative 'em_test_helper'
|
|
2
|
+
|
|
3
|
+
class TestIPv4 < Test::Unit::TestCase
|
|
4
|
+
# Runs a TCP server in the local IPv4 address, connects to it and sends a specific data.
|
|
5
|
+
# Timeout in 2 seconds.
|
|
6
|
+
def test_ipv4_tcp_local_server
|
|
7
|
+
omit_if(!Test::Unit::TestCase.public_ipv4?)
|
|
8
|
+
|
|
9
|
+
@@received_data = nil
|
|
10
|
+
@local_port = next_port
|
|
11
|
+
setup_timeout(2)
|
|
12
|
+
|
|
13
|
+
EM.run do
|
|
14
|
+
EM::start_server(@@public_ipv4, @local_port) do |s|
|
|
15
|
+
def s.receive_data data
|
|
16
|
+
@@received_data = data
|
|
17
|
+
EM.stop
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
EM::connect(@@public_ipv4, @local_port) do |c|
|
|
22
|
+
c.send_data "ipv4/tcp"
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
assert_equal "ipv4/tcp", @@received_data
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Runs a UDP server in the local IPv4 address, connects to it and sends a specific data.
|
|
30
|
+
# Timeout in 2 seconds.
|
|
31
|
+
def test_ipv4_udp_local_server
|
|
32
|
+
omit_if(!Test::Unit::TestCase.public_ipv4?)
|
|
33
|
+
|
|
34
|
+
@@received_data = nil
|
|
35
|
+
@local_port = next_port
|
|
36
|
+
setup_timeout(darwin? ? 4 : 2)
|
|
37
|
+
|
|
38
|
+
EM.run do
|
|
39
|
+
EM::open_datagram_socket(@@public_ipv4, @local_port) do |s|
|
|
40
|
+
def s.receive_data data
|
|
41
|
+
@@received_data = data
|
|
42
|
+
EM.stop
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
EM::open_datagram_socket(@@public_ipv4, next_port) do |c|
|
|
47
|
+
c.send_datagram "ipv4/udp", @@public_ipv4, @local_port
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
assert_equal "ipv4/udp", @@received_data
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Try to connect via TCP to an invalid IPv4. EM.connect should raise
|
|
55
|
+
# EM::ConnectionError.
|
|
56
|
+
def test_tcp_connect_to_invalid_ipv4
|
|
57
|
+
omit_if(!Test::Unit::TestCase.public_ipv4?)
|
|
58
|
+
pend("\nFIXME: Windows as of 2018-06-23 on 32 bit >= 2.4 (#{RUBY_VERSION} #{RUBY_PLATFORM})") if RUBY_PLATFORM[/i386-mingw/] && RUBY_VERSION >= '2.4'
|
|
59
|
+
|
|
60
|
+
invalid_ipv4 = "9.9:9"
|
|
61
|
+
|
|
62
|
+
EM.run do
|
|
63
|
+
begin
|
|
64
|
+
error = nil
|
|
65
|
+
EM.connect(invalid_ipv4, 1234)
|
|
66
|
+
rescue => e
|
|
67
|
+
error = e
|
|
68
|
+
ensure
|
|
69
|
+
EM.stop
|
|
70
|
+
assert_equal EM::ConnectionError, (error && error.class)
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Try to send a UDP datagram to an invalid IPv4. EM.send_datagram should raise
|
|
76
|
+
# EM::ConnectionError.
|
|
77
|
+
def test_udp_send_datagram_to_invalid_ipv4
|
|
78
|
+
omit_if(!Test::Unit::TestCase.public_ipv4?)
|
|
79
|
+
|
|
80
|
+
invalid_ipv4 = "9.9:9"
|
|
81
|
+
|
|
82
|
+
EM.run do
|
|
83
|
+
begin
|
|
84
|
+
error = nil
|
|
85
|
+
EM.open_datagram_socket(@@public_ipv4, next_port) do |c|
|
|
86
|
+
c.send_datagram "hello", invalid_ipv4, 1234
|
|
87
|
+
end
|
|
88
|
+
rescue => e
|
|
89
|
+
error = e
|
|
90
|
+
ensure
|
|
91
|
+
EM.stop
|
|
92
|
+
assert_equal EM::ConnectionError, (error && error.class)
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
data/tests/test_ipv6.rb
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
require_relative 'em_test_helper'
|
|
2
|
+
|
|
3
|
+
class TestIPv6 < Test::Unit::TestCase
|
|
4
|
+
|
|
5
|
+
if Test::Unit::TestCase.public_ipv6?
|
|
6
|
+
|
|
7
|
+
# Runs a TCP server in the local IPv6 address, connects to it and sends a specific data.
|
|
8
|
+
# Timeout in 2 seconds.
|
|
9
|
+
def test_ipv6_tcp_local_server
|
|
10
|
+
@@received_data = nil
|
|
11
|
+
@local_port = next_port
|
|
12
|
+
setup_timeout(2)
|
|
13
|
+
|
|
14
|
+
EM.run do
|
|
15
|
+
EM.start_server(@@public_ipv6, @local_port) do |s|
|
|
16
|
+
def s.receive_data data
|
|
17
|
+
@@received_data = data
|
|
18
|
+
EM.stop
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
EM::connect(@@public_ipv6, @local_port) do |c|
|
|
23
|
+
def c.unbind(reason)
|
|
24
|
+
warn "unbind: #{reason.inspect}" if reason # XXX at least find out why it failed
|
|
25
|
+
end
|
|
26
|
+
c.send_data "ipv6/tcp"
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
assert_equal "ipv6/tcp", @@received_data
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Runs a UDP server in the local IPv6 address, connects to it and sends a specific data.
|
|
34
|
+
# Timeout in 2 seconds.
|
|
35
|
+
def test_ipv6_udp_local_server
|
|
36
|
+
@@received_data = nil
|
|
37
|
+
@local_port = next_port
|
|
38
|
+
@@remote_ip = nil
|
|
39
|
+
setup_timeout(2)
|
|
40
|
+
|
|
41
|
+
EM.run do
|
|
42
|
+
EM.open_datagram_socket(@@public_ipv6, @local_port) do |s|
|
|
43
|
+
def s.receive_data data
|
|
44
|
+
_port, @@remote_ip = Socket.unpack_sockaddr_in(get_peername)
|
|
45
|
+
@@received_data = data
|
|
46
|
+
EM.stop
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
EM.open_datagram_socket(@@public_ipv6, next_port) do |c|
|
|
51
|
+
c.send_datagram "ipv6/udp", @@public_ipv6, @local_port
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
assert_equal @@remote_ip, @@public_ipv6
|
|
55
|
+
assert_equal "ipv6/udp", @@received_data
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Try to connect via TCP to an invalid IPv6. EM.connect should raise
|
|
59
|
+
# EM::ConnectionError.
|
|
60
|
+
def test_tcp_connect_to_invalid_ipv6
|
|
61
|
+
invalid_ipv6 = "1:A"
|
|
62
|
+
|
|
63
|
+
EM.run do
|
|
64
|
+
begin
|
|
65
|
+
error = nil
|
|
66
|
+
EM.connect(invalid_ipv6, 1234)
|
|
67
|
+
rescue => e
|
|
68
|
+
error = e
|
|
69
|
+
ensure
|
|
70
|
+
EM.stop
|
|
71
|
+
assert_equal EM::ConnectionError, (error && error.class)
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Try to send a UDP datagram to an invalid IPv6. EM.send_datagram should raise
|
|
77
|
+
# EM::ConnectionError.
|
|
78
|
+
def test_udp_send_datagram_to_invalid_ipv6
|
|
79
|
+
invalid_ipv6 = "1:A"
|
|
80
|
+
|
|
81
|
+
EM.run do
|
|
82
|
+
begin
|
|
83
|
+
error = nil
|
|
84
|
+
EM.open_datagram_socket(@@public_ipv6, next_port) do |c|
|
|
85
|
+
c.send_datagram "hello", invalid_ipv6, 1234
|
|
86
|
+
end
|
|
87
|
+
rescue => e
|
|
88
|
+
error = e
|
|
89
|
+
ensure
|
|
90
|
+
EM.stop
|
|
91
|
+
assert_equal EM::ConnectionError, (error && error.class)
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
else
|
|
98
|
+
warn "no IPv6 in this host, skipping tests in #{__FILE__}"
|
|
99
|
+
|
|
100
|
+
# Because some rubies will complain if a TestCase class has no tests.
|
|
101
|
+
def test_ipv6_unavailable
|
|
102
|
+
assert true
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
end
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
require_relative 'em_test_helper'
|
|
2
|
+
|
|
3
|
+
class TestIterator < Test::Unit::TestCase
|
|
4
|
+
|
|
5
|
+
def setup
|
|
6
|
+
@time0 = nil
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
# By default, format the time with tenths-of-seconds.
|
|
10
|
+
# Some tests should ask for extra decimal places to ensure
|
|
11
|
+
# that delays between iterations will receive a changed time.
|
|
12
|
+
def get_time(n = 1)
|
|
13
|
+
@time0 = EM.current_time unless @time0
|
|
14
|
+
sprintf "%07.#{n}f", EM.current_time - @time0
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def test_default_concurrency
|
|
18
|
+
items = {}
|
|
19
|
+
list = 1..10
|
|
20
|
+
EM.run {
|
|
21
|
+
EM::Iterator.new(list).each( proc {|num,iter|
|
|
22
|
+
time = get_time(3)
|
|
23
|
+
items[time] ||= []
|
|
24
|
+
items[time] << num
|
|
25
|
+
EM::Timer.new(0.02) {iter.next}
|
|
26
|
+
}, proc {EM.stop})
|
|
27
|
+
}
|
|
28
|
+
assert_equal(10, items.keys.size)
|
|
29
|
+
assert_equal(list.to_a.sort, items.values.flatten.sort)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def test_default_concurrency_with_a_proc
|
|
33
|
+
items = {}
|
|
34
|
+
list = (1..10).to_a
|
|
35
|
+
original_list = list.dup
|
|
36
|
+
EM.run {
|
|
37
|
+
EM::Iterator.new(proc{list.pop || EM::Iterator::Stop}).each( proc {|num,iter|
|
|
38
|
+
time = get_time(3)
|
|
39
|
+
items[time] ||= []
|
|
40
|
+
items[time] << num
|
|
41
|
+
EM::Timer.new(0.02) {iter.next}
|
|
42
|
+
}, proc {EM.stop})
|
|
43
|
+
}
|
|
44
|
+
assert_equal(10, items.keys.size)
|
|
45
|
+
assert_equal(original_list.to_a.sort, items.values.flatten.sort)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def test_concurrency_bigger_than_list_size
|
|
49
|
+
items = {}
|
|
50
|
+
list = [1,2,3]
|
|
51
|
+
EM.run {
|
|
52
|
+
EM::Iterator.new(list,10).each(proc {|num,iter|
|
|
53
|
+
time = get_time
|
|
54
|
+
items[time] ||= []
|
|
55
|
+
items[time] << num
|
|
56
|
+
EM::Timer.new(1) {iter.next}
|
|
57
|
+
}, proc {EM.stop})
|
|
58
|
+
}
|
|
59
|
+
assert_equal(1, items.keys.size)
|
|
60
|
+
assert_equal(list.to_a.sort, items.values.flatten.sort)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def test_changing_concurrency_affects_active_iteration
|
|
64
|
+
items = {}
|
|
65
|
+
list = 1..25
|
|
66
|
+
seen = 0
|
|
67
|
+
EM.run {
|
|
68
|
+
i = EM::Iterator.new(list,1)
|
|
69
|
+
i.each(proc {|num,iter|
|
|
70
|
+
time = get_time
|
|
71
|
+
items[time] ||= []
|
|
72
|
+
items[time] << num
|
|
73
|
+
if (seen += 1) == 5
|
|
74
|
+
# The first 5 items will be distinct times
|
|
75
|
+
# The next 20 items will happen in 2 bursts
|
|
76
|
+
i.concurrency = 10
|
|
77
|
+
end
|
|
78
|
+
EM::Timer.new(0.2) {iter.next}
|
|
79
|
+
}, proc {EM.stop})
|
|
80
|
+
}
|
|
81
|
+
assert_in_delta(7, items.keys.size, 1)
|
|
82
|
+
assert_equal(list.to_a.sort, items.values.flatten.sort)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def test_map
|
|
86
|
+
list = 100..150
|
|
87
|
+
EM.run {
|
|
88
|
+
EM::Iterator.new(list).map(proc{ |num,iter|
|
|
89
|
+
EM.add_timer(0.01){ iter.return(num) }
|
|
90
|
+
}, proc{ |results|
|
|
91
|
+
assert_equal(list.to_a.size, results.size)
|
|
92
|
+
EM.stop
|
|
93
|
+
})
|
|
94
|
+
}
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def test_inject
|
|
98
|
+
omit_if(windows?)
|
|
99
|
+
|
|
100
|
+
list = %w[ pwd uptime uname date ]
|
|
101
|
+
EM.run {
|
|
102
|
+
EM::Iterator.new(list, 2).inject({}, proc{ |hash,cmd,iter|
|
|
103
|
+
EM.system(cmd){ |output,status|
|
|
104
|
+
hash[cmd] = status.exitstatus == 0 ? output.strip : nil
|
|
105
|
+
iter.return(hash)
|
|
106
|
+
}
|
|
107
|
+
}, proc{ |results|
|
|
108
|
+
assert_equal(results.keys.sort, list.sort)
|
|
109
|
+
EM.stop
|
|
110
|
+
})
|
|
111
|
+
}
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def test_concurrency_is_0
|
|
115
|
+
EM.run {
|
|
116
|
+
assert_raise ArgumentError do
|
|
117
|
+
EM::Iterator.new(1..5,0)
|
|
118
|
+
end
|
|
119
|
+
EM.stop
|
|
120
|
+
}
|
|
121
|
+
end
|
|
122
|
+
end
|
data/tests/test_kb.rb
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
require_relative 'em_test_helper'
|
|
2
|
+
|
|
3
|
+
class TestKeyboardEvents < Test::Unit::TestCase
|
|
4
|
+
|
|
5
|
+
module KbHandler
|
|
6
|
+
include EM::Protocols::LineText2
|
|
7
|
+
def receive_line d
|
|
8
|
+
EM::stop if d == "STOP"
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# This test doesn't actually do anything useful but is here to
|
|
13
|
+
# illustrate the usage. If you removed the timer and ran this test
|
|
14
|
+
# by itself on a console, and then typed into the console, it would
|
|
15
|
+
# work.
|
|
16
|
+
# I don't know how to get the test harness to simulate actual keystrokes.
|
|
17
|
+
# When someone figures that out, then we can make this a real test.
|
|
18
|
+
#
|
|
19
|
+
def test_kb
|
|
20
|
+
omit_if(jruby?)
|
|
21
|
+
omit_if(!$stdout.tty?) # don't run the test unless it stands a chance of validity.
|
|
22
|
+
EM.run do
|
|
23
|
+
EM.open_keyboard KbHandler
|
|
24
|
+
EM::Timer.new(1) { EM.stop }
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
end
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
require_relative 'em_test_helper'
|
|
2
|
+
|
|
3
|
+
class TestKeepalive < Test::Unit::TestCase
|
|
4
|
+
def setup
|
|
5
|
+
assert(!EM.reactor_running?)
|
|
6
|
+
@port = next_port
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def teardown
|
|
10
|
+
assert(!EM.reactor_running?)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def test_enable_keepalive
|
|
14
|
+
omit_if(!EM.respond_to?(:get_sock_opt))
|
|
15
|
+
|
|
16
|
+
# I don't know why "An operation was attempted on something that is not a socket."
|
|
17
|
+
pend('FIXME: this test is broken on Windows') if windows?
|
|
18
|
+
|
|
19
|
+
val = nil
|
|
20
|
+
test_module = Module.new do
|
|
21
|
+
define_method :post_init do
|
|
22
|
+
enable_keepalive
|
|
23
|
+
val = get_sock_opt Socket::SOL_SOCKET, Socket::SO_KEEPALIVE
|
|
24
|
+
EM.stop
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
EM.run do
|
|
29
|
+
EM.start_server '127.0.0.1', @port
|
|
30
|
+
EM.connect '127.0.0.1', @port, test_module
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Enabled isn't 1 on all platforms - Mac OS seems to be 8
|
|
34
|
+
# Docs say any non-zero value indicates keepalive is enabled
|
|
35
|
+
assert_not_equal 0, val.unpack('i').first
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def test_enable_keepalive_values
|
|
39
|
+
omit_if(!EM.respond_to?(:get_sock_opt))
|
|
40
|
+
|
|
41
|
+
# I don't know why "An operation was attempted on something that is not a socket."
|
|
42
|
+
pend('FIXME: this test is broken on Windows') if windows?
|
|
43
|
+
|
|
44
|
+
val, val_idle, val_intvl, val_cnt = nil
|
|
45
|
+
test_module = Module.new do
|
|
46
|
+
define_method :post_init do
|
|
47
|
+
enable_keepalive(5, 10, 15)
|
|
48
|
+
val = get_sock_opt Socket::SOL_SOCKET, Socket::SO_KEEPALIVE
|
|
49
|
+
|
|
50
|
+
if defined?(Socket::TCP_KEEPALIVE)
|
|
51
|
+
val_idle = get_sock_opt Socket::IPPROTO_TCP, Socket::TCP_KEEPALIVE
|
|
52
|
+
end
|
|
53
|
+
if defined?(Socket::TCP_KEEPIDLE)
|
|
54
|
+
val_idle = get_sock_opt Socket::IPPROTO_TCP, Socket::TCP_KEEPIDLE
|
|
55
|
+
end
|
|
56
|
+
if defined?(Socket::TCP_KEEPINTVL)
|
|
57
|
+
val_intvl = get_sock_opt Socket::IPPROTO_TCP, Socket::TCP_KEEPINTVL
|
|
58
|
+
end
|
|
59
|
+
if defined?(Socket::TCP_KEEPCNT)
|
|
60
|
+
val_cnt = get_sock_opt Socket::IPPROTO_TCP, Socket::TCP_KEEPCNT
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
EM.stop
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
EM.run do
|
|
68
|
+
EM.start_server '127.0.0.1', @port
|
|
69
|
+
EM.connect '127.0.0.1', @port, test_module
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Enabled isn't 1 on all platforms - Mac OS seems to be 8
|
|
73
|
+
# Docs say any non-zero value indicates keepalive is enabled
|
|
74
|
+
assert_not_equal 0, val.unpack('i').first
|
|
75
|
+
|
|
76
|
+
# Make sure each of the individual settings was set
|
|
77
|
+
if defined?(Socket::TCP_KEEPIDLE) || defined?(Socket::TCP_KEEPALIVE)
|
|
78
|
+
assert_equal 5, val_idle.unpack('i').first
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
if defined?(Socket::TCP_KEEPINTVL)
|
|
82
|
+
assert_equal 10, val_intvl.unpack('i').first
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
if defined?(Socket::TCP_KEEPCNT)
|
|
86
|
+
assert_equal 15, val_cnt.unpack('i').first
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def test_disable_keepalive
|
|
91
|
+
omit_if(!EM.respond_to?(:get_sock_opt))
|
|
92
|
+
|
|
93
|
+
# I don't know why "An operation was attempted on something that is not a socket."
|
|
94
|
+
pend('FIXME: this test is broken on Windows') if windows?
|
|
95
|
+
|
|
96
|
+
val = nil
|
|
97
|
+
test_module = Module.new do
|
|
98
|
+
define_method :post_init do
|
|
99
|
+
enable_keepalive
|
|
100
|
+
disable_keepalive
|
|
101
|
+
val = get_sock_opt Socket::SOL_SOCKET, Socket::SO_KEEPALIVE
|
|
102
|
+
EM.stop
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
EM.run do
|
|
107
|
+
EM.start_server '127.0.0.1', @port
|
|
108
|
+
EM.connect '127.0.0.1', @port, test_module
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
assert_equal 0, val.unpack('i').first
|
|
112
|
+
end
|
|
113
|
+
end
|