zmachine 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,178 @@
1
+ require 'zmachine/tcp_channel'
2
+ require 'zmachine/zmq_channel'
3
+
4
+ include ZMachine
5
+
6
+ shared_examples_for "a Channel" do
7
+
8
+ context '#bind' do
9
+
10
+ it 'binds a server socket' do
11
+ expect(@server).to be_bound
12
+ end
13
+
14
+ it 'accepts client connections' do
15
+ channel = @server.accept
16
+ expect(channel).to be_a(klass)
17
+ expect(channel).to be_connected
18
+ end
19
+
20
+ end
21
+
22
+ context '#connect' do
23
+
24
+ it 'connects to a pending server socket' do
25
+ expect(@client).to be_connection_pending
26
+ end
27
+
28
+ it 'connects to an accepted server socket' do
29
+ @server.accept
30
+ @client.finish_connecting
31
+ expect(@client).to be_connected
32
+ end
33
+
34
+ end
35
+
36
+ context '#send/recv' do
37
+
38
+ before(:each) do
39
+ @channel = @server.accept
40
+ @channel.raw = false
41
+ @client.finish_connecting
42
+ end
43
+
44
+ it 'writes outbound buffers to the socket' do
45
+ @client.send_data(data)
46
+ expect(@client.write_outbound_data).to eq(true)
47
+ end
48
+
49
+ it 'receives data sent from the client' do
50
+ @client.send_data(data)
51
+ @client.write_outbound_data
52
+ received = @channel.read_inbound_data
53
+ expect(received.to_s).to eq(data.to_s)
54
+ end
55
+
56
+ it 'receives data sent from the server' do
57
+ @client.send_data(data)
58
+ @client.write_outbound_data
59
+ received = @channel.read_inbound_data
60
+ @channel.send_data(data)
61
+ @channel.write_outbound_data
62
+ received = @client.read_inbound_data
63
+ expect(received.to_s).to eq(data.to_s)
64
+ end
65
+
66
+ end
67
+
68
+ context '#close' do
69
+
70
+ it 'closes the client connection' do
71
+ @client.close
72
+ expect(@client).to be_closed
73
+ end
74
+
75
+ it 'closes the server connection' do
76
+ @server.close
77
+ expect(@server).to be_closed
78
+ end
79
+
80
+ it 'closes the accepted connection' do
81
+ channel = @server.accept
82
+ channel.close
83
+ expect(channel).to be_closed
84
+ end
85
+
86
+ it 'closes the connection after writing' do
87
+ channel = @server.accept
88
+ @client.finish_connecting
89
+ @client.send_data(data)
90
+ @client.close(true)
91
+ expect(@client).to be_connected
92
+ @client.write_outbound_data
93
+ expect(@client).not_to be_connected
94
+ end
95
+
96
+ end
97
+
98
+ end
99
+
100
+ describe TCPChannel do
101
+
102
+ it_behaves_like "a Channel"
103
+
104
+ let(:klass) { TCPChannel }
105
+ let(:address) { "0.0.0.0" }
106
+ let(:port_or_type) { [51635, 51635] }
107
+
108
+ before(:each) do
109
+ @server = klass.new
110
+ @server.bind(address, port_or_type[0])
111
+ @client = klass.new
112
+ @client.connect(address, port_or_type[1])
113
+ end
114
+
115
+ after(:each) do
116
+ @client.close
117
+ @server.close
118
+ ZMachine.context.destroy
119
+ end
120
+
121
+ let(:data) { "foo".to_java_bytes }
122
+
123
+ it 'has the correct peer information' do
124
+ expect(@client.peer).to eq([port_or_type[0], address])
125
+ channel = @server.accept
126
+ @client.finish_connecting
127
+ socket = @client.socket.socket
128
+ expect(channel.peer).to eq([socket.local_port, socket.local_address.host_address])
129
+ end
130
+
131
+ context '#send/recv' do
132
+
133
+ it 'reads data after server has closed connection' do
134
+ channel = @server.accept
135
+ @client.finish_connecting
136
+ channel.send_data(data)
137
+ channel.close(true)
138
+ expect(channel).to be_connected
139
+ channel.write_outbound_data
140
+ expect(channel).not_to be_connected
141
+ expect(@client).to be_connected
142
+ @client.read_inbound_data
143
+ expect{@client.read_inbound_data}.to raise_error(IOException)
144
+ end
145
+
146
+ end
147
+
148
+ end
149
+
150
+ describe ZMQChannel do
151
+
152
+ it_behaves_like "a Channel"
153
+
154
+ let(:klass) { ZMQChannel }
155
+ let(:address) { "tcp://0.0.0.0:51634" }
156
+ let(:port_or_type) { [ZMQ::REP, ZMQ::REQ] }
157
+
158
+ before(:each) do
159
+ @server = klass.new
160
+ @server.bind(address, port_or_type[0])
161
+ @client = klass.new
162
+ @client.connect(address, port_or_type[1])
163
+ @client.raw = false
164
+ end
165
+
166
+ after(:each) do
167
+ @client.close
168
+ @server.close
169
+ ZMachine.context.destroy
170
+ end
171
+
172
+ let(:data) { "foo".to_java_bytes }
173
+
174
+ it 'has no concept of a peer' do
175
+ expect{@client.peer}.to raise_error(RuntimeError)
176
+ end
177
+
178
+ end
@@ -2,17 +2,19 @@ require 'zmachine/connection'
2
2
 
3
3
  include ZMachine
4
4
 
5
- describe Connection do
5
+ shared_examples_for "a Connection" do
6
6
 
7
7
  before(:each) do
8
- @server = Connection.new.bind("0.0.0.0", 0)
9
- @port = @server.channel.socket.socket.local_port
10
- @client = Connection.new.connect("0.0.0.0", @port)
8
+ @server = Connection.new.bind(address, port_or_type[0]) { |c| @accepted = c }
9
+ @server.channel.raw = false
10
+ @client = Connection.new.connect(address, port_or_type[1]) { |c| @connection = c }
11
+ @client.channel.raw = false
11
12
  end
12
13
 
13
14
  after(:each) do
14
15
  @client.close
15
16
  @server.close
17
+ ZMachine.context.destroy
16
18
  end
17
19
 
18
20
  let(:data) { "foo" }
@@ -20,16 +22,17 @@ describe Connection do
20
22
  context 'triggers' do
21
23
 
22
24
  it 'triggers acceptable' do
23
- @server.channel.should_receive(:accept).once.and_call_original
24
- @server.should_receive(:connection_accepted).once
25
+ @server.channel.should_receive(:accept).and_call_original
25
26
  connection = @server.acceptable!
26
27
  expect(connection).to be_connected
28
+ expect(@accepted).to eq(connection)
29
+ expect(@connection).to be_a(Connection)
27
30
  end
28
31
 
29
32
  it 'triggers connectable' do
30
33
  @server.acceptable!
31
- @client.channel.should_receive(:finish_connecting).once.and_call_original
32
- @client.should_receive(:connection_completed).once
34
+ @client.channel.should_receive(:finish_connecting).and_call_original
35
+ @client.should_receive(:connection_completed)
33
36
  @client.connectable!
34
37
  expect(@client).to be_connected
35
38
  end
@@ -37,7 +40,7 @@ describe Connection do
37
40
  it 'triggers writable' do
38
41
  @server.acceptable!
39
42
  @client.connectable!
40
- @client.send_data(data.to_java_bytes)
43
+ @client.send_data(data)
41
44
  @client.channel.should_receive(:write_outbound_data).and_call_original
42
45
  @client.writable!
43
46
  end
@@ -45,12 +48,34 @@ describe Connection do
45
48
  it 'triggers readable' do
46
49
  connection = @server.acceptable!
47
50
  @client.connectable!
48
- @client.send_data(data.to_java_bytes)
51
+ @client.send_data(data)
49
52
  @client.writable!
50
53
  connection.channel.should_receive(:read_inbound_data).and_call_original
51
- connection.should_receive(:receive_data).once
54
+ connection.should_receive(:receive_data).with(data)
52
55
  connection.readable!
53
56
  end
54
57
 
55
58
  end
59
+
60
+ end
61
+
62
+ describe Connection do
63
+
64
+ context 'TCP' do
65
+
66
+ it_behaves_like "a Connection"
67
+
68
+ let(:address) { "0.0.0.0" }
69
+ let(:port_or_type) { [51635, 51635] }
70
+
71
+ end
72
+
73
+ context 'ZMQ' do
74
+
75
+ it_behaves_like "a Connection"
76
+
77
+ let(:address) { "tcp://0.0.0.0:51634" }
78
+ let(:port_or_type) { [ZMQ::REP, ZMQ::REQ] }
79
+
80
+ end
56
81
  end
@@ -1,7 +1,7 @@
1
1
  require 'zmachine/hashed_wheel'
2
2
 
3
3
  describe ZMachine::HashedWheel do
4
- let(:wheel) { ZMachine::HashedWheel.new(16, 100) }
4
+ let(:wheel) { ZMachine::HashedWheel.new(16, 0.1) }
5
5
 
6
6
  it 'returns a timeout on add' do
7
7
  expect(wheel.add(0)).to be_instance_of(ZMachine::HashedWheelTimeout)
@@ -9,11 +9,11 @@ describe ZMachine::HashedWheel do
9
9
 
10
10
  it 'adds timeouts to the correct slot' do
11
11
  wheel.add 0
12
- wheel.add 90
13
- wheel.add 110
14
- wheel.add 1000
15
- wheel.add 1600
16
- wheel.add 3200
12
+ wheel.add 0.090
13
+ wheel.add 0.110
14
+ wheel.add 1.000
15
+ wheel.add 1.600
16
+ wheel.add 3.200
17
17
  expect(wheel.slots[0].length).to eq(4)
18
18
  expect(wheel.slots[1].length).to eq(1)
19
19
  expect(wheel.slots[10].length).to eq(1)
@@ -21,19 +21,19 @@ describe ZMachine::HashedWheel do
21
21
 
22
22
  it 'times out same slot timeouts correctly' do
23
23
  now = wheel.reset
24
- wheel.add 10
25
- wheel.add 50
24
+ wheel.add 0.01
25
+ wheel.add 0.05
26
26
  timedout = wheel.advance(now + 30 * 1_000_000)
27
27
  expect(timedout.length).to eq(1)
28
28
  end
29
29
 
30
30
  it 'calculates the timeout set correctly' do
31
31
  now = wheel.reset
32
- wheel.add 10
33
- wheel.add 40
34
- wheel.add 1900
35
- wheel.add 3300
36
- wheel.add 4000
32
+ wheel.add 0.010
33
+ wheel.add 0.040
34
+ wheel.add 1.900
35
+ wheel.add 3.300
36
+ wheel.add 4.000
37
37
  timedout = wheel.advance(now + 3900 * 1_000_000)
38
38
  expect(timedout).to be
39
39
  expect(timedout.length).to eq(4)
@@ -41,8 +41,8 @@ describe ZMachine::HashedWheel do
41
41
 
42
42
  it 'cancels timers correctly' do
43
43
  now = wheel.reset
44
- t1 = wheel.add 90
45
- t2 = wheel.add 110
44
+ t1 = wheel.add 0.090
45
+ t2 = wheel.add 0.110
46
46
  t1.cancel
47
47
  timedout = wheel.advance(now + 200 * 1_000_000)
48
48
  expect(timedout).to eq([t2])
@@ -0,0 +1,32 @@
1
+ require "socket"
2
+
3
+ module EchoMock
4
+ def self.start(port = 6380)
5
+ server = TCPServer.new("127.0.0.1", port)
6
+ loop do
7
+ session = server.accept
8
+ while line = session.gets
9
+ session.write(line)
10
+ session.write("\r\n")
11
+ end
12
+ end
13
+ end
14
+
15
+ module Helper
16
+ def echo_mock
17
+ begin
18
+ pid = fork do
19
+ trap("TERM") { exit }
20
+ EchoMock.start
21
+ end
22
+ sleep 1 # Give time for the socket to start listening.
23
+ yield
24
+ ensure
25
+ if pid
26
+ Process.kill("TERM", pid)
27
+ Process.wait(pid)
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
data/zmachine.gemspec CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |spec|
4
4
  spec.name = "zmachine"
5
- spec.version = "0.2.1"
5
+ spec.version = "0.3.0"
6
6
  spec.authors = ["LiquidM, Inc."]
7
7
  spec.email = ["opensource@liquidm.com"]
8
8
  spec.description = %q{pure JRuby multi-threaded mostly EventMachine compatible event loop}
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zmachine
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - LiquidM, Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-11-25 00:00:00.000000000 Z
11
+ date: 2013-12-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: liquid-ext
@@ -42,8 +42,8 @@ files:
42
42
  - benchmarks/benchmark.sh
43
43
  - benchmarks/tcp_channel.rb
44
44
  - benchmarks/zmq_channel.rb
45
- - echo_client.rb
46
- - echo_server.rb
45
+ - examples/echo_client.rb
46
+ - examples/echo_server.rb
47
47
  - lib/zmachine.rb
48
48
  - lib/zmachine/acceptor.rb
49
49
  - lib/zmachine/channel.rb
@@ -51,17 +51,17 @@ files:
51
51
  - lib/zmachine/connection_manager.rb
52
52
  - lib/zmachine/deferrable.rb
53
53
  - lib/zmachine/hashed_wheel.rb
54
- - lib/zmachine/jeromq-0.3.0-SNAPSHOT.jar
54
+ - lib/zmachine/jeromq-0.3.2-SNAPSHOT.jar
55
55
  - lib/zmachine/reactor.rb
56
56
  - lib/zmachine/tcp_channel.rb
57
57
  - lib/zmachine/timers.rb
58
58
  - lib/zmachine/zmq_channel.rb
59
+ - spec/channel_spec.rb
59
60
  - spec/connection_manager_spec.rb
60
61
  - spec/connection_spec.rb
61
62
  - spec/hashed_wheel_spec.rb
62
63
  - spec/spec_helper.rb
63
- - spec/tcp_channel_spec.rb
64
- - spec/zmq_channel_spec.rb
64
+ - spec/support/echo_mock.rb
65
65
  - zmachine.gemspec
66
66
  homepage: https://github.com/liquidm/zmachine
67
67
  licenses:
@@ -88,10 +88,10 @@ signing_key:
88
88
  specification_version: 4
89
89
  summary: pure JRuby multi-threaded mostly EventMachine compatible event loop
90
90
  test_files:
91
+ - spec/channel_spec.rb
91
92
  - spec/connection_manager_spec.rb
92
93
  - spec/connection_spec.rb
93
94
  - spec/hashed_wheel_spec.rb
94
95
  - spec/spec_helper.rb
95
- - spec/tcp_channel_spec.rb
96
- - spec/zmq_channel_spec.rb
96
+ - spec/support/echo_mock.rb
97
97
  has_rdoc:
Binary file
@@ -1,109 +0,0 @@
1
- require 'zmachine/tcp_channel'
2
-
3
- include ZMachine
4
-
5
- describe ZMachine::TCPChannel do
6
-
7
- before(:each) do
8
- @server = TCPChannel.new
9
- @server.bind("0.0.0.0", 0)
10
- @port = @server.socket.socket.local_port
11
- @client = TCPChannel.new
12
- @client.connect("0.0.0.0", @port)
13
- end
14
-
15
- after(:each) do
16
- @client.close
17
- @server.close
18
- end
19
-
20
- let(:data) { "foo" }
21
-
22
- context '#bind' do
23
-
24
- it 'binds a server socket' do
25
- expect(@server).to be_bound
26
- end
27
-
28
- it 'accepts client connections' do
29
- channel = @server.accept
30
- expect(channel).to be_a(TCPChannel)
31
- expect(channel).to be_connected
32
- end
33
-
34
- end
35
-
36
- context '#connect' do
37
-
38
- it 'connects to a pending server socket' do
39
- expect(@client).to be_connection_pending
40
- end
41
-
42
- it 'connects to an accepted server socket' do
43
- @server.accept
44
- @client.finish_connecting
45
- expect(@client).to be_connected
46
- end
47
-
48
- end
49
-
50
- context '#send/recv' do
51
-
52
- before(:each) do
53
- @channel = @server.accept
54
- @client.finish_connecting
55
- @client.send_data(data.to_java_bytes)
56
- end
57
-
58
- it 'writes outbound buffers to the socket' do
59
- expect(@client.write_outbound_data).to eq(true)
60
- end
61
-
62
- it 'receives data sent from the client' do
63
- @client.write_outbound_data
64
- received = @channel.read_inbound_data
65
- expect(received).to eq(data)
66
- end
67
-
68
- it 'receives data sent from the server' do
69
- @client.write_outbound_data
70
- received = @channel.read_inbound_data
71
- @channel.send_data(data.to_java_bytes)
72
- @channel.write_outbound_data
73
- received = @client.read_inbound_data
74
- expect(received).to eq(data)
75
- end
76
-
77
- end
78
-
79
- context '#close' do
80
-
81
- it 'closes the client connection' do
82
- @client.close
83
- expect(@client).to be_closed
84
- end
85
-
86
- it 'closes the server connection' do
87
- @server.close
88
- expect(@server).to be_closed
89
- end
90
-
91
- it 'closes the accepted connection' do
92
- channel = @server.accept
93
- channel.close
94
- expect(channel).to be_closed
95
- end
96
-
97
- it 'closes the connection after writing' do
98
- channel = @server.accept
99
- @client.finish_connecting
100
- @client.send_data(data.to_java_bytes)
101
- @client.close_after_writing
102
- expect(@client).to be_connected
103
- @client.write_outbound_data
104
- expect(@client).not_to be_connected
105
- end
106
-
107
- end
108
-
109
- end