eventmachine 1.0.3-x86-mingw32 → 1.2.0.dev.2-x86-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +84 -1
- data/README.md +6 -7
- data/ext/binder.cpp +10 -10
- data/ext/binder.h +5 -5
- data/ext/cmain.cpp +173 -61
- data/ext/ed.cpp +262 -127
- data/ext/ed.h +50 -30
- data/ext/em.cpp +491 -445
- data/ext/em.h +101 -36
- data/ext/eventmachine.h +67 -51
- data/ext/extconf.rb +124 -31
- data/ext/fastfilereader/extconf.rb +9 -2
- data/ext/fastfilereader/mapper.cpp +3 -1
- data/ext/fastfilereader/rubymain.cpp +7 -7
- data/ext/kb.cpp +1 -1
- data/ext/pipe.cpp +11 -4
- data/ext/project.h +26 -6
- data/ext/rubymain.cpp +408 -201
- data/ext/ssl.cpp +167 -20
- data/ext/ssl.h +11 -2
- data/java/src/com/rubyeventmachine/EmReactor.java +16 -0
- data/java/src/com/rubyeventmachine/EventableChannel.java +2 -0
- data/java/src/com/rubyeventmachine/EventableDatagramChannel.java +6 -0
- data/java/src/com/rubyeventmachine/EventableSocketChannel.java +55 -10
- data/lib/1.9/fastfilereaderext.so +0 -0
- data/lib/1.9/rubyeventmachine.so +0 -0
- data/lib/2.0/fastfilereaderext.so +0 -0
- data/lib/2.0/rubyeventmachine.so +0 -0
- data/lib/2.1/fastfilereaderext.so +0 -0
- data/lib/2.1/rubyeventmachine.so +0 -0
- data/lib/2.2/fastfilereaderext.so +0 -0
- data/lib/2.2/rubyeventmachine.so +0 -0
- data/lib/2.3/fastfilereaderext.so +0 -0
- data/lib/2.3/rubyeventmachine.so +0 -0
- data/lib/em/buftok.rb +34 -85
- data/lib/em/channel.rb +5 -0
- data/lib/em/completion.rb +2 -2
- data/lib/em/connection.rb +62 -4
- data/lib/em/iterator.rb +30 -48
- data/lib/em/pool.rb +1 -1
- data/lib/em/protocols/httpclient.rb +31 -11
- data/lib/em/protocols/line_and_text.rb +4 -4
- data/lib/em/protocols/linetext2.rb +44 -39
- data/lib/em/protocols/smtpclient.rb +60 -31
- data/lib/em/protocols/smtpserver.rb +32 -9
- data/lib/em/pure_ruby.rb +8 -3
- data/lib/em/queue.rb +16 -7
- data/lib/em/resolver.rb +64 -24
- data/lib/em/threaded_resource.rb +2 -2
- data/lib/em/tick_loop.rb +19 -19
- data/lib/em/version.rb +1 -1
- data/lib/eventmachine.rb +96 -49
- data/lib/jeventmachine.rb +17 -0
- data/rakelib/package.rake +31 -4
- data/tests/dhparam.pem +13 -0
- data/tests/em_test_helper.rb +87 -0
- data/tests/test_attach.rb +25 -0
- data/tests/test_basic.rb +27 -38
- data/tests/test_channel.rb +14 -1
- data/tests/test_completion.rb +1 -0
- data/tests/test_connection_count.rb +22 -1
- data/tests/test_connection_write.rb +35 -0
- data/tests/test_defer.rb +17 -0
- data/tests/test_epoll.rb +26 -14
- data/tests/test_file_watch.rb +1 -0
- data/tests/test_fork.rb +75 -0
- data/tests/test_httpclient.rb +43 -0
- data/tests/test_idle_connection.rb +6 -4
- data/tests/test_ipv4.rb +125 -0
- data/tests/test_ipv6.rb +131 -0
- data/tests/test_iterator.rb +115 -0
- data/tests/test_kb.rb +19 -25
- data/tests/test_ltp2.rb +20 -0
- data/tests/test_many_fds.rb +22 -0
- data/tests/test_pause.rb +29 -0
- data/tests/test_pool.rb +2 -0
- data/tests/test_process_watch.rb +2 -0
- data/tests/test_processes.rb +7 -7
- data/tests/test_queue.rb +14 -0
- data/tests/test_resolver.rb +56 -7
- data/tests/test_set_sock_opt.rb +2 -0
- data/tests/test_smtpclient.rb +20 -0
- data/tests/test_ssl_args.rb +2 -2
- data/tests/test_ssl_dhparam.rb +83 -0
- data/tests/test_ssl_ecdh_curve.rb +79 -0
- data/tests/test_ssl_extensions.rb +49 -0
- data/tests/test_ssl_methods.rb +22 -5
- data/tests/test_ssl_protocols.rb +246 -0
- data/tests/test_ssl_verify.rb +103 -59
- data/tests/test_system.rb +4 -0
- data/tests/test_threaded_resource.rb +8 -0
- data/tests/test_unbind_reason.rb +5 -1
- metadata +173 -107
- data/.gitignore +0 -21
- data/.travis.yml +0 -12
- data/.yardopts +0 -7
- data/Gemfile +0 -2
- data/Rakefile +0 -20
- data/eventmachine.gemspec +0 -36
- data/rakelib/cpp.rake_example +0 -77
@@ -0,0 +1,115 @@
|
|
1
|
+
require 'em_test_helper'
|
2
|
+
|
3
|
+
class TestIterator < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def get_time
|
6
|
+
EM.current_time.strftime('%H:%M:%S')
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_default_concurrency
|
10
|
+
items = {}
|
11
|
+
list = 1..10
|
12
|
+
EM.run {
|
13
|
+
EM::Iterator.new(list).each( proc {|num,iter|
|
14
|
+
time = get_time
|
15
|
+
items[time] ||= []
|
16
|
+
items[time] << num
|
17
|
+
EM::Timer.new(1) {iter.next}
|
18
|
+
}, proc {EM.stop})
|
19
|
+
}
|
20
|
+
assert_equal(10, items.keys.size)
|
21
|
+
assert_equal(list.to_a.sort, items.values.flatten.sort)
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_default_concurrency_with_a_proc
|
25
|
+
items = {}
|
26
|
+
list = (1..10).to_a
|
27
|
+
original_list = list.dup
|
28
|
+
EM.run {
|
29
|
+
EM::Iterator.new(proc{list.pop || EM::Iterator::Stop}).each( proc {|num,iter|
|
30
|
+
time = get_time
|
31
|
+
items[time] ||= []
|
32
|
+
items[time] << num
|
33
|
+
EM::Timer.new(1) {iter.next}
|
34
|
+
}, proc {EM.stop})
|
35
|
+
}
|
36
|
+
assert_equal(10, items.keys.size)
|
37
|
+
assert_equal(original_list.to_a.sort, items.values.flatten.sort)
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_concurrency_bigger_than_list_size
|
41
|
+
items = {}
|
42
|
+
list = [1,2,3]
|
43
|
+
EM.run {
|
44
|
+
EM::Iterator.new(list,10).each(proc {|num,iter|
|
45
|
+
time = get_time
|
46
|
+
items[time] ||= []
|
47
|
+
items[time] << num
|
48
|
+
EM::Timer.new(1) {iter.next}
|
49
|
+
}, proc {EM.stop})
|
50
|
+
}
|
51
|
+
assert_equal(1, items.keys.size)
|
52
|
+
assert_equal(list.to_a.sort, items.values.flatten.sort)
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
def test_changing_concurrency_affects_active_iteration
|
57
|
+
items = {}
|
58
|
+
list = 1..25
|
59
|
+
EM.run {
|
60
|
+
i = EM::Iterator.new(list,5)
|
61
|
+
i.each(proc {|num,iter|
|
62
|
+
time = get_time
|
63
|
+
items[time] ||= []
|
64
|
+
items[time] << num
|
65
|
+
EM::Timer.new(1) {iter.next}
|
66
|
+
}, proc {EM.stop})
|
67
|
+
EM.add_timer(1){
|
68
|
+
i.concurrency = 1
|
69
|
+
}
|
70
|
+
EM.add_timer(3){
|
71
|
+
i.concurrency = 3
|
72
|
+
}
|
73
|
+
}
|
74
|
+
assert_equal(9, items.keys.size)
|
75
|
+
assert_equal(list.to_a.sort, items.values.flatten.sort)
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_map
|
79
|
+
list = 100..150
|
80
|
+
EM.run {
|
81
|
+
EM::Iterator.new(list).map(proc{ |num,iter|
|
82
|
+
EM.add_timer(0.01){ iter.return(num) }
|
83
|
+
}, proc{ |results|
|
84
|
+
assert_equal(list.to_a.size, results.size)
|
85
|
+
EM.stop
|
86
|
+
})
|
87
|
+
}
|
88
|
+
end
|
89
|
+
|
90
|
+
def test_inject
|
91
|
+
omit_if(windows?)
|
92
|
+
|
93
|
+
list = %w[ pwd uptime uname date ]
|
94
|
+
EM.run {
|
95
|
+
EM::Iterator.new(list, 2).inject({}, proc{ |hash,cmd,iter|
|
96
|
+
EM.system(cmd){ |output,status|
|
97
|
+
hash[cmd] = status.exitstatus == 0 ? output.strip : nil
|
98
|
+
iter.return(hash)
|
99
|
+
}
|
100
|
+
}, proc{ |results|
|
101
|
+
assert_equal(results.keys.sort, list.sort)
|
102
|
+
EM.stop
|
103
|
+
})
|
104
|
+
}
|
105
|
+
end
|
106
|
+
|
107
|
+
def test_concurrency_is_0
|
108
|
+
EM.run {
|
109
|
+
assert_raise ArgumentError do
|
110
|
+
EM::Iterator.new(1..5,0)
|
111
|
+
end
|
112
|
+
EM.stop
|
113
|
+
}
|
114
|
+
end
|
115
|
+
end
|
data/tests/test_kb.rb
CHANGED
@@ -2,33 +2,27 @@ require 'em_test_helper'
|
|
2
2
|
|
3
3
|
class TestKeyboardEvents < Test::Unit::TestCase
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
EM::stop if d == "STOP"
|
10
|
-
end
|
5
|
+
module KbHandler
|
6
|
+
include EM::Protocols::LineText2
|
7
|
+
def receive_line d
|
8
|
+
EM::stop if d == "STOP"
|
11
9
|
end
|
10
|
+
end
|
12
11
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
else
|
27
|
-
warn "EM.open_keyboard not implemented, skipping tests in #{__FILE__}"
|
28
|
-
|
29
|
-
# Because some rubies will complain if a TestCase class has no tests
|
30
|
-
def test_em_open_keyboard_unsupported
|
31
|
-
assert true
|
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 }
|
32
25
|
end
|
33
26
|
end
|
27
|
+
|
34
28
|
end
|
data/tests/test_ltp2.rb
CHANGED
@@ -26,6 +26,26 @@ class TestLineText2 < Test::Unit::TestCase
|
|
26
26
|
assert_equal( ["Line 1", "Line 2", "Line 3"], a.lines )
|
27
27
|
end
|
28
28
|
|
29
|
+
# The basic test above shows that extra newlines are chomped
|
30
|
+
# This test shows that newlines are preserved if the delimiter isn't \n
|
31
|
+
class PreserveNewlines
|
32
|
+
include EM::Protocols::LineText2
|
33
|
+
attr_reader :lines
|
34
|
+
def initialize *args
|
35
|
+
super
|
36
|
+
@delim = "|"
|
37
|
+
set_delimiter @delim
|
38
|
+
end
|
39
|
+
def receive_line line
|
40
|
+
(@lines ||= []) << line
|
41
|
+
end
|
42
|
+
end
|
43
|
+
def test_preserve_newlines
|
44
|
+
a = PreserveNewlines.new
|
45
|
+
a.receive_data "aaa|bbb|ccc|\n|\r\n| \t ||"
|
46
|
+
assert_equal( ["aaa", "bbb", "ccc", "\n", "\r\n", " \t ", ""], a.lines )
|
47
|
+
end
|
48
|
+
|
29
49
|
class ChangeDelimiter
|
30
50
|
include EM::Protocols::LineText2
|
31
51
|
attr_reader :lines
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'em_test_helper'
|
2
|
+
require 'socket'
|
3
|
+
|
4
|
+
class TestManyFDs < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
@port = next_port
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_connection_class_cache
|
10
|
+
mod = Module.new
|
11
|
+
a = nil
|
12
|
+
Process.setrlimit(Process::RLIMIT_NOFILE, 4096) rescue nil
|
13
|
+
EM.run {
|
14
|
+
EM.start_server '127.0.0.1', @port, mod
|
15
|
+
1100.times do
|
16
|
+
a = EM.connect '127.0.0.1', @port, mod
|
17
|
+
assert_kind_of EM::Connection, a
|
18
|
+
end
|
19
|
+
EM.stop
|
20
|
+
}
|
21
|
+
end
|
22
|
+
end
|
data/tests/test_pause.rb
CHANGED
@@ -67,6 +67,35 @@ class TestPause < Test::Unit::TestCase
|
|
67
67
|
end
|
68
68
|
end
|
69
69
|
end
|
70
|
+
|
71
|
+
def test_pause_in_receive_data
|
72
|
+
incoming = []
|
73
|
+
|
74
|
+
test_server = Module.new do
|
75
|
+
define_method(:receive_data) do |data|
|
76
|
+
incoming << data
|
77
|
+
pause
|
78
|
+
EM.add_timer(0.5){ close_connection }
|
79
|
+
end
|
80
|
+
define_method(:unbind) do
|
81
|
+
EM.stop
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
buf = 'a' * 1024
|
86
|
+
|
87
|
+
EM.run do
|
88
|
+
EM.start_server "127.0.0.1", @port, test_server
|
89
|
+
cli = EM.connect "127.0.0.1", @port
|
90
|
+
128.times do
|
91
|
+
cli.send_data buf
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
assert_equal 1, incoming.size
|
96
|
+
assert incoming[0].bytesize > buf.bytesize
|
97
|
+
assert incoming[0].bytesize < buf.bytesize * 128
|
98
|
+
end
|
70
99
|
else
|
71
100
|
warn "EM.pause_connection not implemented, skipping tests in #{__FILE__}"
|
72
101
|
|
data/tests/test_pool.rb
CHANGED
data/tests/test_process_watch.rb
CHANGED
data/tests/test_processes.rb
CHANGED
@@ -37,8 +37,8 @@ class TestProcesses < Test::Unit::TestCase
|
|
37
37
|
}
|
38
38
|
|
39
39
|
assert( $out.length > 0 )
|
40
|
-
assert_equal($status.exitstatus
|
41
|
-
|
40
|
+
assert_equal(0, $status.exitstatus)
|
41
|
+
assert_kind_of(Process::Status, $status)
|
42
42
|
end
|
43
43
|
|
44
44
|
def test_em_system_pid
|
@@ -57,8 +57,8 @@ class TestProcesses < Test::Unit::TestCase
|
|
57
57
|
}
|
58
58
|
|
59
59
|
assert( $out.length > 0 )
|
60
|
-
assert_equal($status.exitstatus
|
61
|
-
|
60
|
+
assert_equal(0, $status.exitstatus)
|
61
|
+
assert_kind_of(Process::Status, $status)
|
62
62
|
end
|
63
63
|
|
64
64
|
def test_em_system_with_two_procs
|
@@ -111,9 +111,9 @@ class TestProcesses < Test::Unit::TestCase
|
|
111
111
|
end
|
112
112
|
end
|
113
113
|
|
114
|
-
EM.run
|
115
|
-
EM.popen('
|
116
|
-
|
114
|
+
EM.run do
|
115
|
+
EM.popen('echo 1', test_client)
|
116
|
+
end
|
117
117
|
|
118
118
|
assert_equal 1, c_rx
|
119
119
|
end
|
data/tests/test_queue.rb
CHANGED
@@ -47,4 +47,18 @@ class TestEMQueue < Test::Unit::TestCase
|
|
47
47
|
EM.run { EM.next_tick { EM.stop } }
|
48
48
|
assert_equal many, q.num_waiting
|
49
49
|
end
|
50
|
+
|
51
|
+
def test_big_queue
|
52
|
+
EM.run do
|
53
|
+
q = EM::Queue.new
|
54
|
+
2000.times do |i|
|
55
|
+
q.push(*0..1000)
|
56
|
+
q.pop { |v| assert_equal v, i % 1001 }
|
57
|
+
end
|
58
|
+
q.pop do
|
59
|
+
assert_equal 1_999_999, q.size
|
60
|
+
EM.stop
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
50
64
|
end
|
data/tests/test_resolver.rb
CHANGED
@@ -1,7 +1,24 @@
|
|
1
1
|
require 'em_test_helper'
|
2
2
|
|
3
3
|
class TestResolver < Test::Unit::TestCase
|
4
|
+
def test_nameserver
|
5
|
+
assert_kind_of(String, EM::DNS::Resolver.nameserver)
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_nameservers
|
9
|
+
assert_kind_of(Array, EM::DNS::Resolver.nameservers)
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_hosts
|
13
|
+
assert_kind_of(Hash, EM::DNS::Resolver.hosts)
|
14
|
+
|
15
|
+
# Make sure that blank or comment lines are skipped
|
16
|
+
refute(EM::DNS::Resolver.hosts.include? nil)
|
17
|
+
end
|
18
|
+
|
4
19
|
def test_a
|
20
|
+
pend('FIXME: this test is broken on Windows') if windows?
|
21
|
+
|
5
22
|
EM.run {
|
6
23
|
d = EM::DNS::Resolver.resolve "google.com"
|
7
24
|
d.errback { assert false }
|
@@ -29,27 +46,59 @@ class TestResolver < Test::Unit::TestCase
|
|
29
46
|
end
|
30
47
|
|
31
48
|
def test_a_pair
|
49
|
+
pend('FIXME: this test is broken on Windows') if windows?
|
50
|
+
|
32
51
|
EM.run {
|
33
|
-
d = EM::DNS::Resolver.resolve "
|
34
|
-
d.errback { assert false }
|
52
|
+
d = EM::DNS::Resolver.resolve "yahoo.com"
|
53
|
+
d.errback { |err| assert false, "failed to resolve yahoo.com: #{err}" }
|
35
54
|
d.callback { |r|
|
36
|
-
|
37
|
-
assert r.size > 1
|
55
|
+
assert_kind_of(Array, r)
|
56
|
+
assert r.size > 1, "returned #{r.size} results: #{r.inspect}"
|
38
57
|
EM.stop
|
39
58
|
}
|
40
59
|
}
|
41
60
|
end
|
42
61
|
|
43
62
|
def test_localhost
|
63
|
+
pend('FIXME: this test is broken on Windows') if windows?
|
64
|
+
|
44
65
|
EM.run {
|
45
66
|
d = EM::DNS::Resolver.resolve "localhost"
|
46
67
|
d.errback { assert false }
|
47
68
|
d.callback { |r|
|
48
|
-
|
49
|
-
|
69
|
+
assert_include(["127.0.0.1", "::1"], r.first)
|
70
|
+
assert_kind_of(Array, r)
|
71
|
+
|
72
|
+
EM.stop
|
73
|
+
}
|
74
|
+
}
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_timer_cleanup
|
78
|
+
pend('FIXME: this test is broken on Windows') if windows?
|
79
|
+
|
80
|
+
EM.run {
|
81
|
+
d = EM::DNS::Resolver.resolve "google.com"
|
82
|
+
d.errback { |err| assert false, "failed to resolve google.com: #{err}" }
|
83
|
+
d.callback { |r|
|
84
|
+
# This isn't a great test, but it's hard to get more canonical
|
85
|
+
# confirmation that the timer is cancelled
|
86
|
+
assert_nil(EM::DNS::Resolver.socket.instance_variable_get(:@timer))
|
87
|
+
|
88
|
+
EM.stop
|
89
|
+
}
|
90
|
+
}
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_failure_timer_cleanup
|
94
|
+
EM.run {
|
95
|
+
d = EM::DNS::Resolver.resolve "asdfasdf"
|
96
|
+
d.callback { assert false }
|
97
|
+
d.errback {
|
98
|
+
assert_nil(EM::DNS::Resolver.socket.instance_variable_get(:@timer))
|
50
99
|
|
51
100
|
EM.stop
|
52
101
|
}
|
53
102
|
}
|
54
103
|
end
|
55
|
-
end
|
104
|
+
end
|
data/tests/test_set_sock_opt.rb
CHANGED
data/tests/test_smtpclient.rb
CHANGED
@@ -52,4 +52,24 @@ class TestSmtpClient < Test::Unit::TestCase
|
|
52
52
|
assert(err)
|
53
53
|
end
|
54
54
|
|
55
|
+
|
56
|
+
EM::Protocols::SmtpClient.__send__(:public, :escape_leading_dots)
|
57
|
+
|
58
|
+
def test_escaping
|
59
|
+
smtp = EM::Protocols::SmtpClient.new :domain => "example.com"
|
60
|
+
|
61
|
+
expectations = {
|
62
|
+
"Hello\r\n" => "Hello\r\n",
|
63
|
+
"\r\n.whatever\r\n" => "\r\n..whatever\r\n",
|
64
|
+
"\r\n.\r\n" => "\r\n..\r\n",
|
65
|
+
"\r\n.\r\n." => "\r\n..\r\n..",
|
66
|
+
".\r\n.\r\n" => "..\r\n..\r\n",
|
67
|
+
"..\r\n" => "...\r\n"
|
68
|
+
}
|
69
|
+
|
70
|
+
expectations.each do |input, output|
|
71
|
+
assert_equal output, smtp.escape_leading_dots(input)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
55
75
|
end
|