ffi-rzmq 0.9.3 → 0.9.6

Sign up to get free protection for your applications and to get access to all the features.
data/spec/poll_spec.rb CHANGED
@@ -51,31 +51,112 @@ module ZMQ
51
51
 
52
52
 
53
53
  context "#delete" do
54
- let(:poller) { Poller.new }
55
- let(:socket) { mock('socket') }
56
- let(:context) { Context.new }
54
+ before(:all) do
55
+ @context = Context.new
56
+ end
57
+
58
+ before(:each) do
59
+ @socket = @context.socket(XREQ)
60
+ @socket.setsockopt(LINGER, 0)
61
+ @poller = Poller.new
62
+ end
63
+
64
+ after(:each) do
65
+ @socket.close
66
+ end
67
+
68
+ after(:all) do
69
+ @context.terminate
70
+ end
57
71
 
58
72
  it "should return false for an unregistered socket (i.e. not found)" do
59
- poller.delete(socket).should be_false
73
+ @poller.delete(@socket).should be_false
60
74
  end
61
75
 
62
76
  it "returns true for a sucessfully deleted socket when only 1 is registered" do
63
- socket1 = context.socket ZMQ::REP
77
+ socket1 = @context.socket(REP)
78
+ socket1.setsockopt(LINGER, 0)
64
79
 
65
- poller.register socket1
66
- poller.delete(socket1).should be_true
80
+ @poller.register socket1
81
+ @poller.delete(socket1).should be_true
82
+ socket1.close
67
83
  end
68
84
 
69
85
  it "returns true for a sucessfully deleted socket when more than 1 is registered" do
70
- socket1 = context.socket ZMQ::REP
71
- socket2 = context.socket ZMQ::REP
86
+ socket1 = @context.socket(REP)
87
+ socket2 = @context.socket(REP)
88
+ socket1.setsockopt(LINGER, 0)
89
+ socket2.setsockopt(LINGER, 0)
72
90
 
73
- poller.register socket1
74
- poller.register socket2
75
- poller.delete(socket2).should be_true
91
+ @poller.register socket1
92
+ @poller.register socket2
93
+ @poller.delete(socket2).should be_true
94
+ socket1.close
95
+ socket2.close
76
96
  end
77
97
 
78
98
  end
99
+
100
+
101
+ context "poll" do
102
+ include APIHelper
103
+
104
+ before(:all) do
105
+ end
106
+
107
+ before(:each) do
108
+ # Must recreate context for each test otherwise some poll tests fail.
109
+ # This is likely due to a race condition in event handling when reusing
110
+ # the same inproc inside the same context over and over. Making a new
111
+ # context solves it.
112
+ @context = Context.new
113
+ endpoint = "inproc://poll_test"
114
+ @socket = @context.socket(DEALER)
115
+ @socket2 = @context.socket(ROUTER)
116
+ @socket.setsockopt(LINGER, 0)
117
+ @socket2.setsockopt(LINGER, 0)
118
+ @socket.bind(endpoint)
119
+ connect_to_inproc(@socket2, endpoint)
120
+
121
+ @poller = Poller.new
122
+ end
123
+
124
+ after(:each) do
125
+ @socket.close
126
+ @socket2.close
127
+ @context.terminate
128
+ end
129
+
130
+ it "returns 0 when there are no sockets to poll" do
131
+ rc = @poller.poll(100)
132
+ rc.should be_zero
133
+ end
134
+
135
+ it "returns 0 when there is a single socket to poll and no events" do
136
+ @poller.register(@socket, 0)
137
+ rc = @poller.poll(100)
138
+ rc.should be_zero
139
+ end
140
+
141
+ it "returns 1 when there is a read event on a socket" do
142
+ @poller.register_readable(@socket2)
143
+
144
+ @socket.send_string('test')
145
+ rc = @poller.poll(1000)
146
+ rc.should == 1
147
+ end
148
+
149
+ it "returns 1 when there is a read event on one socket and the second socket has been removed from polling" do
150
+ @poller.register_readable(@socket2)
151
+ @poller.register_writable(@socket)
152
+
153
+ @socket.send_string('test')
154
+ @poller.deregister_writable(@socket)
155
+
156
+ rc = @poller.poll(1000)
157
+ rc.should == 1
158
+ end
159
+ end # poll
79
160
 
80
161
 
81
162
  end # describe Poll
@@ -2,23 +2,26 @@
2
2
  require File.join(File.dirname(__FILE__), %w[spec_helper])
3
3
 
4
4
  module ZMQ
5
- describe Context do
5
+ describe Socket do
6
6
  context "when running basic push pull" do
7
7
  include APIHelper
8
8
 
9
9
  let(:string) { "booga-booga" }
10
-
10
+
11
11
  before(:each) do
12
- $stdout.flush
13
- @context = ZMQ::Context.new
12
+ # Use new context for each iteration to avoid inproc race. See
13
+ # poll_spec.rb for more details.
14
+ @context = Context.new
15
+ poller_setup
16
+
14
17
  @push = @context.socket ZMQ::PUSH
15
18
  @pull = @context.socket ZMQ::PULL
16
19
  @push.setsockopt ZMQ::LINGER, 0
17
20
  @pull.setsockopt ZMQ::LINGER, 0
18
- port = connect_to_random_tcp_port(@pull)
19
- @link = "tcp://127.0.0.1:#{port}"
20
- #@link = "inproc://push_pull_test" # can't connect to inproc *before* bind
21
- @push.bind @link
21
+
22
+ @link = "inproc://push_pull_test"
23
+ @push.bind @link
24
+ connect_to_inproc(@pull, @link)
22
25
  end
23
26
 
24
27
  after(:each) do
@@ -35,126 +38,77 @@ module ZMQ
35
38
  received.should == string
36
39
  end
37
40
 
38
- if version2?
39
- it "should receive an exact string copy of the message sent when receiving in non-blocking mode and using Message objects directly" do
40
- sent_message = Message.new string
41
- received_message = Message.new
42
-
43
- rc = @push.send sent_message
44
- rc.should == 0
45
- sleep 0.1 # give it time for delivery
46
- rc = @pull.recv received_message, ZMQ::NOBLOCK
47
- received_message.copy_out_string.should == string
48
- end
49
-
50
- else
51
-
52
- it "should receive an exact string copy of the message sent when receiving in non-blocking mode and using Message objects directly" do
53
- sent_message = Message.new string
54
- received_message = Message.new
41
+ it "should receive an exact string copy of the message sent when receiving in non-blocking mode and using Message objects directly" do
42
+ sent_message = Message.new string
43
+ received_message = Message.new
55
44
 
45
+ poll_it_for_read(@pull) do
56
46
  rc = @push.sendmsg sent_message
57
- rc.should == string.size
58
- sleep 0.1 # give it time for delivery
59
- rc = @pull.recvmsg received_message, ZMQ::DONTWAIT
60
- rc.should == string.size
61
- received_message.copy_out_string.should == string
47
+ LibZMQ.version2? ? rc.should == 0 : rc.should == string.size
62
48
  end
49
+
50
+ rc = @pull.recvmsg received_message, ZMQ::NonBlocking
51
+ LibZMQ.version2? ? rc.should == 0 : rc.should == string.size
52
+ received_message.copy_out_string.should == string
63
53
  end
64
54
 
65
55
 
66
- if version2?
67
-
68
- it "should receive a single message for each message sent on each socket listening, when an equal number pulls to messages and a unique socket per thread" do
69
- received = []
70
- threads = []
71
- count = 4
72
- @pull.close # close this one since we aren't going to use it below and we don't want it to receive a message
73
- mutex = Mutex.new
74
-
75
- count.times do |i|
76
- threads << Thread.new do
77
- pull = @context.socket ZMQ::PULL
78
- rc = pull.setsockopt ZMQ::LINGER, 0
79
- rc = pull.connect @link
80
- rc.should == 0
81
- buffer = ''
82
- rc = pull.recv_string buffer
83
- rc.should == 0
84
- mutex.synchronize { received << buffer }
85
- pull.close
86
- end
87
- sleep 0.01 # give each thread time to spin up
88
- end
89
-
90
- count.times { @push.send_string(string) }
91
-
92
- threads.each {|t| t.join}
93
56
 
94
- received.find_all {|r| r == string}.length.should == count
57
+ it "should receive a single message for each message sent on each socket listening, when an equal number of sockets pulls messages and where each socket is unique per thread" do
58
+ received = []
59
+ threads = []
60
+ sockets = []
61
+ count = 4
62
+ mutex = Mutex.new
63
+
64
+ # make sure all sockets are connected before we do our load-balancing test
65
+ (count - 1).times do
66
+ socket = @context.socket ZMQ::PULL
67
+ socket.setsockopt ZMQ::LINGER, 0
68
+ connect_to_inproc(socket, @link)
69
+ sockets << socket
95
70
  end
96
-
97
- it "should receive a single message for each message sent on each socket listening, when an equal number pulls to messages and a single shared socket protected by a mutex" do
98
- received = []
99
- threads = []
100
- count = 4
101
- @pull.close # close this one since we aren't going to use it below and we don't want it to receive a message
102
- pull = @context.socket ZMQ::PULL
103
- rc = pull.setsockopt ZMQ::LINGER, 0
104
- rc = pull.connect @link
105
- rc.should == 0
106
- mutex = Mutex.new
107
-
108
- count.times do |i|
109
- threads << Thread.new do
110
- buffer = ''
111
- rc = 0
112
- mutex.synchronize { rc = pull.recv_string buffer }
113
- rc.should == 0
114
- mutex.synchronize { received << buffer }
115
- end
116
- sleep 0.01 # give each thread time to spin up
71
+ sockets << @pull
72
+
73
+ sockets.each do |socket|
74
+ threads << Thread.new do
75
+ buffer = ''
76
+ rc = socket.recv_string buffer
77
+ version2? ? (rc.should == 0) : (rc.should == buffer.size)
78
+ mutex.synchronize { received << buffer }
79
+ socket.close
117
80
  end
81
+ end
118
82
 
119
- count.times { @push.send_string(string) }
83
+ count.times { @push.send_string(string) }
120
84
 
121
- threads.each {|t| t.join}
122
- pull.close
85
+ threads.each {|t| t.join}
123
86
 
124
- received.find_all {|r| r == string}.length.should == count
125
- end
87
+ received.find_all {|r| r == string}.length.should == count
88
+ end
126
89
 
127
- else # version3 or 4
128
-
129
- it "should receive a single message for each message sent on each socket listening, when an equal number pulls to messages" do
130
- received = []
131
- threads = []
132
- count = 4
133
- @pull.close # close this one since we aren't going to use it below and we don't want it to receive a message
134
-
135
- count.times do |i|
136
- threads << Thread.new do
137
- pull = @context.socket ZMQ::PULL
138
- rc = pull.setsockopt ZMQ::LINGER, 0
139
- rc = pull.connect @link
140
- rc.should == 0
141
- buffer = ''
142
- rc = pull.recv_string buffer
143
- rc.should == string.size
144
- received << buffer
145
- pull.close
146
- end
147
- sleep 0.01 # give each thread time to spin up
90
+ it "should receive a single message for each message sent when using a single shared socket protected by a mutex" do
91
+ received = []
92
+ threads = []
93
+ count = 4
94
+ mutex = Mutex.new
95
+
96
+ count.times do |i|
97
+ threads << Thread.new do
98
+ buffer = ''
99
+ rc = 0
100
+ mutex.synchronize { rc = @pull.recv_string buffer }
101
+ version2? ? (rc.should == 0) : (rc.should == buffer.size)
102
+ mutex.synchronize { received << buffer }
148
103
  end
104
+ end
149
105
 
150
- count.times { @push.send_string(string) }
151
-
152
- threads.each {|t| t.join}
106
+ count.times { @push.send_string(string) }
153
107
 
154
- received.find_all {|r| r == string}.length.should == count
155
- end
108
+ threads.each {|t| t.join}
156
109
 
157
- end # if version...
110
+ received.find_all {|r| r == string}.length.should == count
111
+ end
158
112
 
159
113
  end # @context ping-pong
160
114
  end # describe
data/spec/reqrep_spec.rb CHANGED
@@ -4,88 +4,77 @@ require File.join(File.dirname(__FILE__), %w[spec_helper])
4
4
  module ZMQ
5
5
 
6
6
 
7
- describe Context do
7
+ describe Socket do
8
8
 
9
9
  context "when running ping pong" do
10
10
  include APIHelper
11
11
 
12
12
  let(:string) { "booga-booga" }
13
13
 
14
+ # reset sockets each time because we only send 1 message which leaves
15
+ # the REQ socket in a bad state. It cannot send again unless we were to
16
+ # send a reply with the REP and read it.
14
17
  before(:each) do
15
- context = ZMQ::Context.new 1
16
- @ping = context.socket ZMQ::REQ
17
- @pong = context.socket ZMQ::REP
18
- port = bind_to_random_tcp_port(@pong)
19
- @ping.connect "tcp://127.0.0.1:#{port}"
18
+ @context = ZMQ::Context.new
19
+ poller_setup
20
+
21
+ endpoint = "inproc://reqrep_test"
22
+ @ping = @context.socket ZMQ::REQ
23
+ @pong = @context.socket ZMQ::REP
24
+ @pong.bind(endpoint)
25
+ connect_to_inproc(@ping, endpoint)
20
26
  end
21
27
 
22
28
  after(:each) do
23
29
  @ping.close
24
30
  @pong.close
31
+ @context.terminate
25
32
  end
26
-
27
- it "should receive an exact string copy of the string message sent" do
33
+
34
+ def send_ping(string)
28
35
  @ping.send_string string
29
36
  received_message = ''
30
37
  rc = @pong.recv_string received_message
38
+ [rc, received_message]
39
+ end
31
40
 
41
+ it "should receive an exact string copy of the string message sent" do
42
+ rc, received_message = send_ping(string)
32
43
  received_message.should == string
33
44
  end
45
+
46
+ it "should generate a EFSM error when sending via the REQ socket twice in a row without an intervening receive operation" do
47
+ send_ping(string)
48
+ rc = @ping.send_string(string)
49
+ rc.should == -1
50
+ Util.errno.should == ZMQ::EFSM
51
+ end
34
52
 
35
- if version2?
36
- it "should receive an exact copy of the sent message using Message objects directly" do
37
- sent_message = Message.new string
38
- received_message = Message.new
39
-
40
- rc = @ping.send sent_message
41
- rc.should == 0
42
- rc = @pong.recv received_message
43
- rc.should == 0
44
-
45
- received_message.copy_out_string.should == string
46
- end
47
-
48
- it "should receive an exact copy of the sent message using Message objects directly in non-blocking mode" do
49
- sent_message = Message.new string
50
- received_message = Message.new
51
-
52
- rc = @ping.send sent_message, ZMQ::NOBLOCK
53
- rc.should == 0
54
- sleep 0.1 # give it time for delivery
55
- rc = @pong.recv received_message, ZMQ::NOBLOCK
56
- rc.should == 0
57
-
58
- received_message.copy_out_string.should == string
59
- end
60
-
61
- else # version3 or 4
62
-
63
- it "should receive an exact copy of the sent message using Message objects directly" do
64
- sent_message = Message.new string
65
- received_message = Message.new
66
-
67
- rc = @ping.sendmsg sent_message
68
- rc.should == string.size
69
- rc = @pong.recvmsg received_message
70
- rc.should == string.size
53
+ it "should receive an exact copy of the sent message using Message objects directly" do
54
+ received_message = Message.new
71
55
 
72
- received_message.copy_out_string.should == string
73
- end
56
+ rc = @ping.sendmsg(Message.new(string))
57
+ LibZMQ.version2? ? rc.should == 0 : rc.should == string.size
58
+ rc = @pong.recvmsg received_message
59
+ LibZMQ.version2? ? rc.should == 0 : rc.should == string.size
74
60
 
75
- it "should receive an exact copy of the sent message using Message objects directly in non-blocking mode" do
76
- sent_message = Message.new string
77
- received_message = Message.new
61
+ received_message.copy_out_string.should == string
62
+ end
78
63
 
79
- rc = @ping.sendmsg sent_message, ZMQ::DONTWAIT
80
- rc.should == string.size
81
- sleep 0.001 # give it time for delivery
82
- rc = @pong.recvmsg received_message, ZMQ::DONTWAIT
83
- rc.should == string.size
64
+ it "should receive an exact copy of the sent message using Message objects directly in non-blocking mode" do
65
+ sent_message = Message.new string
66
+ received_message = Message.new
84
67
 
85
- received_message.copy_out_string.should == string
68
+ poll_it_for_read(@pong) do
69
+ rc = @ping.sendmsg(Message.new(string), ZMQ::NonBlocking)
70
+ LibZMQ.version2? ? rc.should == 0 : rc.should == string.size
86
71
  end
72
+
73
+ rc = @pong.recvmsg received_message, ZMQ::NonBlocking
74
+ LibZMQ.version2? ? rc.should == 0 : rc.should == string.size
87
75
 
88
- end # if version...
76
+ received_message.copy_out_string.should == string
77
+ end
89
78
 
90
79
  end # context ping-pong
91
80