ffi-rzmq 0.9.3 → 0.9.6

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.
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