rbczmq 0.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.
Files changed (101) hide show
  1. data/.gitignore +23 -0
  2. data/.travis.yml +19 -0
  3. data/Gemfile +5 -0
  4. data/Gemfile.lock +19 -0
  5. data/MIT-LICENSE +20 -0
  6. data/README.rdoc +247 -0
  7. data/Rakefile +67 -0
  8. data/examples/loop.rb +109 -0
  9. data/examples/poller.rb +37 -0
  10. data/examples/pub_sub.rb +101 -0
  11. data/examples/push_pull.rb +104 -0
  12. data/examples/req_rep.rb +100 -0
  13. data/ext/czmq.tar.gz +0 -0
  14. data/ext/rbczmq/context.c +280 -0
  15. data/ext/rbczmq/context.h +26 -0
  16. data/ext/rbczmq/extconf.rb +138 -0
  17. data/ext/rbczmq/frame.c +401 -0
  18. data/ext/rbczmq/frame.h +24 -0
  19. data/ext/rbczmq/jruby.h +22 -0
  20. data/ext/rbczmq/loop.c +413 -0
  21. data/ext/rbczmq/loop.h +24 -0
  22. data/ext/rbczmq/message.c +620 -0
  23. data/ext/rbczmq/message.h +24 -0
  24. data/ext/rbczmq/poller.c +308 -0
  25. data/ext/rbczmq/poller.h +29 -0
  26. data/ext/rbczmq/pollitem.c +251 -0
  27. data/ext/rbczmq/pollitem.h +25 -0
  28. data/ext/rbczmq/rbczmq_ext.c +198 -0
  29. data/ext/rbczmq/rbczmq_ext.h +94 -0
  30. data/ext/rbczmq/rbczmq_prelude.h +22 -0
  31. data/ext/rbczmq/rubinius.h +24 -0
  32. data/ext/rbczmq/ruby18.h +43 -0
  33. data/ext/rbczmq/ruby19.h +15 -0
  34. data/ext/rbczmq/socket.c +1570 -0
  35. data/ext/rbczmq/socket.h +136 -0
  36. data/ext/rbczmq/timer.c +110 -0
  37. data/ext/rbczmq/timer.h +23 -0
  38. data/ext/zeromq.tar.gz +0 -0
  39. data/lib/rbczmq.rb +3 -0
  40. data/lib/zmq.rb +77 -0
  41. data/lib/zmq/context.rb +50 -0
  42. data/lib/zmq/default_handler.rb +16 -0
  43. data/lib/zmq/frame.rb +11 -0
  44. data/lib/zmq/handler.rb +76 -0
  45. data/lib/zmq/loop.rb +131 -0
  46. data/lib/zmq/message.rb +9 -0
  47. data/lib/zmq/poller.rb +22 -0
  48. data/lib/zmq/pollitem.rb +31 -0
  49. data/lib/zmq/socket.rb +125 -0
  50. data/lib/zmq/socket/dealer.rb +33 -0
  51. data/lib/zmq/socket/pair.rb +39 -0
  52. data/lib/zmq/socket/pub.rb +30 -0
  53. data/lib/zmq/socket/pull.rb +29 -0
  54. data/lib/zmq/socket/push.rb +32 -0
  55. data/lib/zmq/socket/rep.rb +37 -0
  56. data/lib/zmq/socket/req.rb +37 -0
  57. data/lib/zmq/socket/router.rb +38 -0
  58. data/lib/zmq/socket/sub.rb +27 -0
  59. data/lib/zmq/timer.rb +12 -0
  60. data/lib/zmq/version.rb +5 -0
  61. data/perf/pair.rb +7 -0
  62. data/perf/pair/local.rb +22 -0
  63. data/perf/pair/remote.rb +25 -0
  64. data/perf/pub_sub.rb +7 -0
  65. data/perf/pub_sub/local.rb +22 -0
  66. data/perf/pub_sub/remote.rb +25 -0
  67. data/perf/push_pull.rb +7 -0
  68. data/perf/push_pull/local.rb +21 -0
  69. data/perf/push_pull/remote.rb +25 -0
  70. data/perf/req_rep.rb +7 -0
  71. data/perf/req_rep/local.rb +35 -0
  72. data/perf/req_rep/remote.rb +28 -0
  73. data/perf/runner.rb +142 -0
  74. data/rbczmq.gemspec +22 -0
  75. data/test/helper.rb +21 -0
  76. data/test/socket/test_dealer_socket.rb +14 -0
  77. data/test/socket/test_pair_socket.rb +24 -0
  78. data/test/socket/test_pair_sockets.rb +74 -0
  79. data/test/socket/test_pub_socket.rb +17 -0
  80. data/test/socket/test_pub_sub_sockets.rb +87 -0
  81. data/test/socket/test_pull_socket.rb +17 -0
  82. data/test/socket/test_push_pull_sockets.rb +81 -0
  83. data/test/socket/test_push_socket.rb +17 -0
  84. data/test/socket/test_rep_socket.rb +25 -0
  85. data/test/socket/test_req_rep_sockets.rb +42 -0
  86. data/test/socket/test_req_socket.rb +27 -0
  87. data/test/socket/test_router_socket.rb +14 -0
  88. data/test/socket/test_routing.rb +66 -0
  89. data/test/socket/test_sub_socket.rb +17 -0
  90. data/test/test_context.rb +86 -0
  91. data/test/test_frame.rb +78 -0
  92. data/test/test_handler.rb +28 -0
  93. data/test/test_loop.rb +252 -0
  94. data/test/test_message.rb +201 -0
  95. data/test/test_poller.rb +154 -0
  96. data/test/test_pollitem.rb +78 -0
  97. data/test/test_socket.rb +403 -0
  98. data/test/test_threading.rb +34 -0
  99. data/test/test_timer.rb +37 -0
  100. data/test/test_zmq.rb +62 -0
  101. metadata +208 -0
@@ -0,0 +1,201 @@
1
+ # encoding: utf-8
2
+
3
+ require File.join(File.dirname(__FILE__), 'helper')
4
+
5
+ class TestZmqMessage < ZmqTestCase
6
+ def test_message
7
+ msg = ZMQ::Message.new
8
+ assert_instance_of ZMQ::Message, msg
9
+ assert_nil msg.destroy
10
+ end
11
+
12
+ def test_destroyed
13
+ msg = ZMQ::Message("one", "two")
14
+ msg.destroy
15
+ assert_raises ZMQ::Error do
16
+ msg.encode
17
+ end
18
+ end
19
+
20
+ def test_message_sugar
21
+ msg = ZMQ::Message("one", "two", "three")
22
+ assert_equal "one", msg.popstr
23
+ assert_equal "two", msg.popstr
24
+ assert_equal "three", msg.popstr
25
+ end
26
+
27
+ def test_size
28
+ msg = ZMQ::Message.new
29
+ assert_equal 0, msg.size
30
+ msg.pushstr "test"
31
+ assert_equal 1, msg.size
32
+ end
33
+
34
+ def test_content_size
35
+ msg = ZMQ::Message.new
36
+ assert_equal 0, msg.content_size
37
+ msg.pushstr "test"
38
+ assert_equal 4, msg.content_size
39
+ end
40
+
41
+ def test_push_pop
42
+ msg = ZMQ::Message.new
43
+ assert msg.push ZMQ::Frame("body")
44
+ assert_equal 1, msg.size
45
+ assert_equal 4, msg.content_size
46
+ assert msg.push ZMQ::Frame("header")
47
+ assert_equal 2, msg.size
48
+ assert_equal 10, msg.content_size
49
+
50
+ assert_equal ZMQ::Frame("header"), msg.pop
51
+ assert_equal 1, msg.size
52
+ assert_equal 4, msg.content_size
53
+
54
+ assert_equal ZMQ::Frame("body"), msg.pop
55
+ assert_equal 0, msg.size
56
+ assert_equal 0, msg.content_size
57
+ end
58
+
59
+ def test_add
60
+ msg = ZMQ::Message.new
61
+ msg.push ZMQ::Frame("header")
62
+ assert msg.add ZMQ::Frame("body")
63
+ assert_equal 2, msg.size
64
+ assert_equal ZMQ::Frame("header"), msg.pop
65
+ assert_equal ZMQ::Frame("body"), msg.pop
66
+ end
67
+
68
+ def test_print
69
+ msg = ZMQ::Message.new
70
+ msg.push ZMQ::Frame("header")
71
+ msg.add ZMQ::Frame("body")
72
+ assert_nil msg.print
73
+ end
74
+
75
+ def test_first
76
+ msg = ZMQ::Message.new
77
+ assert_nil msg.first
78
+ msg.push ZMQ::Frame("header")
79
+ msg.add ZMQ::Frame("body")
80
+ assert_equal ZMQ::Frame("header"), msg.first
81
+ end
82
+
83
+ def test_next
84
+ msg = ZMQ::Message.new
85
+ assert_nil msg.next
86
+ msg.push ZMQ::Frame("header")
87
+ msg.add ZMQ::Frame("body")
88
+ assert_equal ZMQ::Frame("header"), msg.next
89
+ assert_equal ZMQ::Frame("body"), msg.next
90
+ end
91
+
92
+ def test_last
93
+ msg = ZMQ::Message.new
94
+ assert_nil msg.last
95
+ msg.push ZMQ::Frame("header")
96
+ msg.add ZMQ::Frame("body")
97
+ assert_equal ZMQ::Frame("body"), msg.last
98
+ end
99
+
100
+ def test_to_a
101
+ assert_equal [], ZMQ::Message.new.to_a
102
+ msg = ZMQ::Message("header", "body")
103
+ assert_equal [ZMQ::Frame("header"), ZMQ::Frame("body")], msg.to_a
104
+ end
105
+
106
+ def test_remove
107
+ msg = ZMQ::Message.new
108
+ header = ZMQ::Frame("header")
109
+ body = ZMQ::Frame("body")
110
+ msg.push header
111
+ msg.add body
112
+ msg.remove(body)
113
+ assert_equal 1, msg.size
114
+ assert_equal header, msg.pop
115
+ end
116
+
117
+ def test_pushstr_popstr
118
+ msg = ZMQ::Message.new
119
+ assert msg.pushstr "body"
120
+ assert_equal 1, msg.size
121
+ assert_equal 4, msg.content_size
122
+ assert msg.pushstr "header"
123
+ assert_equal 2, msg.size
124
+ assert_equal 10, msg.content_size
125
+
126
+ assert_equal "header", msg.popstr
127
+ assert_equal 1, msg.size
128
+ assert_equal 4, msg.content_size
129
+
130
+ assert_equal "body", msg.popstr
131
+ assert_equal 0, msg.size
132
+ assert_equal 0, msg.content_size
133
+ end
134
+
135
+ def test_addstr
136
+ msg = ZMQ::Message.new
137
+ msg.pushstr "header"
138
+ assert msg.addstr "body"
139
+ assert_equal 2, msg.size
140
+ assert_equal "header", msg.popstr
141
+ assert_equal "body", msg.popstr
142
+ end
143
+
144
+ def test_wrap_unwrap
145
+ msg = ZMQ::Message.new
146
+ body = ZMQ::Frame("body")
147
+ assert_nil msg.wrap(body)
148
+ assert_equal 2, msg.size
149
+ assert_equal 4, msg.content_size
150
+ assert_equal body, msg.pop
151
+ assert_equal ZMQ::Frame(""), msg.pop
152
+
153
+ assert_equal 0, msg.size
154
+ assert_nil msg.wrap(body)
155
+ assert_equal 2, msg.size
156
+ assert_equal body, msg.unwrap
157
+ assert_equal 0, msg.size
158
+ end
159
+
160
+ def test_dup
161
+ msg = ZMQ::Message.new
162
+ msg.pushstr "header"
163
+ dup_msg = msg.dup
164
+ assert_not_equal dup_msg.object_id, msg.object_id
165
+ assert_equal msg.size, dup_msg.size
166
+ assert_equal "header", msg.popstr
167
+ end
168
+
169
+ def test_encode_decode
170
+ msg = ZMQ::Message.new
171
+ msg.pushstr "body"
172
+ msg.pushstr "header"
173
+
174
+ expected = "\006header\004body"
175
+ assert_equal expected, msg.encode
176
+
177
+ decoded = ZMQ::Message.decode(expected)
178
+ assert_equal "header", decoded.popstr
179
+ assert_equal "body", decoded.popstr
180
+
181
+ assert_nil ZMQ::Message.decode("tainted")
182
+ end
183
+
184
+ def test_equals
185
+ msg = ZMQ::Message.new
186
+ msg.pushstr "body"
187
+ msg.pushstr "header"
188
+
189
+ dup = msg.dup
190
+ assert_equal msg, msg
191
+ assert msg.eql?(dup)
192
+
193
+ other = ZMQ::Message.new
194
+ other.pushstr "header"
195
+ other.pushstr "body"
196
+
197
+ assert_not_equal msg, other
198
+ assert !msg.eql?(other)
199
+ assert other.eql?(other)
200
+ end
201
+ end
@@ -0,0 +1,154 @@
1
+ # encoding: utf-8
2
+
3
+ require File.join(File.dirname(__FILE__), 'helper')
4
+
5
+ class TestZmqPoller < ZmqTestCase
6
+
7
+ def test_alloc
8
+ assert_instance_of ZMQ::Poller, ZMQ::Poller.new
9
+ end
10
+
11
+ def test_verbose
12
+ poller = ZMQ::Poller.new
13
+ poller.verbose = true
14
+ end
15
+
16
+ def test_poll_sockets
17
+ ctx = ZMQ::Context.new
18
+ poller = ZMQ::Poller.new
19
+ poller.verbose = true
20
+ assert_equal 0, poller.poll
21
+ rep = ctx.socket(:REP)
22
+ rep.linger = 0
23
+ rep.bind("inproc://test.poll")
24
+ req = ctx.socket(:REQ)
25
+ req.linger = 0
26
+ req.connect("inproc://test.poll")
27
+
28
+ assert_raises TypeError do
29
+ poller.poll :invalid
30
+ end
31
+
32
+ assert_equal 0, poller.poll_nonblock
33
+
34
+ assert poller.register_readable(rep)
35
+ assert req.send("request")
36
+ sleep 0.1
37
+
38
+ assert_equal 1, poller.poll(1)
39
+ assert_equal [rep], poller.readables
40
+ assert_equal [], poller.writables
41
+ rep.recv
42
+
43
+ assert poller.register(req)
44
+ assert rep.send("reply")
45
+ sleep 0.1
46
+
47
+ assert_equal 1, poller.poll(1)
48
+ assert_equal [req], poller.readables
49
+ assert_equal [], poller.writables
50
+ ensure
51
+ ctx.destroy
52
+ end
53
+
54
+ def test_poll_ios
55
+ poller = ZMQ::Poller.new
56
+ r, w = IO.pipe
57
+
58
+ poller.register(ZMQ::Pollitem(r, ZMQ::POLLIN))
59
+ poller.register(ZMQ::Pollitem(w, ZMQ::POLLOUT))
60
+
61
+ w.write("message")
62
+ sleep 0.2
63
+
64
+ assert_equal 2, poller.poll(1)
65
+ assert_equal [r], poller.readables
66
+ assert_equal [w], poller.writables
67
+
68
+ assert_equal "message", r.read(7)
69
+ end
70
+
71
+ def test_poll_ruby_sockets
72
+ poller = ZMQ::Poller.new
73
+ server = TCPServer.new("127.0.0.1", 0)
74
+ f, port, host, addr = server.addr
75
+ client = TCPSocket.new("127.0.0.1", port)
76
+ s = server.accept
77
+
78
+ poller.register(ZMQ::Pollitem(s, ZMQ::POLLIN))
79
+ poller.register(ZMQ::Pollitem(client, ZMQ::POLLOUT))
80
+
81
+ client.send("message", 0)
82
+ sleep 0.2
83
+
84
+ assert_equal 2, poller.poll(1)
85
+ assert_equal [s], poller.readables
86
+ assert_equal [client], poller.writables
87
+
88
+ assert_equal "message", s.recv_nonblock(7)
89
+ end
90
+
91
+ def test_register
92
+ ctx = ZMQ::Context.new
93
+ rep = ctx.bind(:REP, 'inproc://test.poller-register')
94
+ req = ctx.connect(:REQ, 'inproc://test.poller-register')
95
+ poller = ZMQ::Poller.new
96
+ assert poller.register(rep)
97
+ assert_raises ZMQ::Error do
98
+ poller.register(ZMQ::Pollitem.new(req, 0))
99
+ end
100
+ unbound = ctx.socket(:REP)
101
+ assert_raises ZMQ::Error do
102
+ poller.register(unbound)
103
+ end
104
+ ensure
105
+ ctx.destroy
106
+ end
107
+
108
+ def test_register_readable
109
+ ctx = ZMQ::Context.new
110
+ rep = ctx.bind(:REP, 'inproc://test.poller-register_readable')
111
+ poller = ZMQ::Poller.new
112
+ assert poller.register_readable(rep)
113
+ ensure
114
+ ctx.destroy
115
+ end
116
+
117
+ def test_register_writable
118
+ ctx = ZMQ::Context.new
119
+ rep = ctx.bind(:REP, 'inproc://test.poller-register_writable')
120
+ poller = ZMQ::Poller.new
121
+ assert poller.register_writable(rep)
122
+ ensure
123
+ ctx.destroy
124
+ end
125
+
126
+ def test_remove
127
+ ctx = ZMQ::Context.new
128
+ rep = ctx.bind(:REP, 'inproc://test.poller-remove')
129
+ req = ctx.connect(:REQ, 'inproc://test.poller-remove')
130
+ poller = ZMQ::Poller.new
131
+ assert poller.register(req)
132
+ assert poller.remove(req)
133
+ assert !poller.remove(rep)
134
+
135
+ io_poll_item = ZMQ::Pollitem.new(STDIN, ZMQ::POLLIN)
136
+ poller.register(io_poll_item)
137
+ assert poller.remove(io_poll_item)
138
+
139
+ poller.register(io_poll_item)
140
+ assert poller.remove(STDIN)
141
+ ensure
142
+ ctx.destroy
143
+ end
144
+
145
+ def test_readables
146
+ poller = ZMQ::Poller.new
147
+ assert_equal [], poller.readables
148
+ end
149
+
150
+ def test_writables
151
+ poller = ZMQ::Poller.new
152
+ assert_equal [], poller.writables
153
+ end
154
+ end
@@ -0,0 +1,78 @@
1
+ # encoding: utf-8
2
+
3
+ require File.join(File.dirname(__FILE__), 'helper')
4
+
5
+ class TestZmqPollitem < ZmqTestCase
6
+ def test_alloc_io
7
+ pollitem = ZMQ::Pollitem.new(STDIN, ZMQ::POLLIN)
8
+ assert_equal STDIN, pollitem.pollable
9
+ assert_equal ZMQ::POLLIN, pollitem.events
10
+ end
11
+
12
+ def test_alloc_without_events
13
+ pollitem = ZMQ::Pollitem.new(STDIN)
14
+ assert pollitem.events & ZMQ::POLLIN
15
+ assert pollitem.events & ZMQ::POLLOUT
16
+ end
17
+
18
+ def test_alloc_socket
19
+ ctx = ZMQ::Context.new
20
+ rep = ctx.bind(:REP, 'inproc://test.pollitem-alloc_socket')
21
+ pollitem = ZMQ::Pollitem.new(rep, ZMQ::POLLIN)
22
+ assert_equal rep, pollitem.pollable
23
+ assert_equal ZMQ::POLLIN, pollitem.events
24
+ ensure
25
+ ctx.destroy
26
+ end
27
+
28
+ def test_alloc_ruby_socket
29
+ srv = TCPServer.new("127.0.0.1", 0)
30
+ pollitem = ZMQ::Pollitem.new(srv, ZMQ::POLLIN)
31
+ assert_equal srv, pollitem.pollable
32
+ assert_equal ZMQ::POLLIN, pollitem.events
33
+ ensure
34
+ srv.close if srv
35
+ end
36
+
37
+ def test_verbose
38
+ ctx = ZMQ::Context.new
39
+ rep = ctx.bind(:REP, 'inproc://test.pollitem-verbose')
40
+ pollitem = ZMQ::Pollitem.new(rep, ZMQ::POLLIN)
41
+ pollitem.verbose = true
42
+ ensure
43
+ ctx.destroy
44
+ end
45
+
46
+ def test_handler
47
+ pollitem = ZMQ::Pollitem.new(STDIN, ZMQ::POLLIN)
48
+ assert_nil pollitem.handler
49
+ handler = Module.new
50
+ pollitem.handler = handler
51
+ assert_equal handler, pollitem.handler
52
+ end
53
+
54
+ def test_coerce
55
+ pollitem = ZMQ::Pollitem.new(STDIN)
56
+ assert_equal pollitem, ZMQ::Pollitem.coerce(pollitem)
57
+ coerced = ZMQ::Pollitem.coerce(STDIN)
58
+ assert_instance_of ZMQ::Pollitem, coerced
59
+ assert_equal STDIN, coerced.pollable
60
+ end
61
+
62
+ def test_alloc_failures
63
+ ctx = ZMQ::Context.new
64
+ rep = ctx.socket(:REP)
65
+ assert_raises ZMQ::Error do
66
+ ZMQ::Pollitem.new(rep, ZMQ::POLLIN)
67
+ end
68
+ rep.bind('inproc://test.pollitem-alloc_failures')
69
+ assert_raises ZMQ::Error do
70
+ ZMQ::Pollitem.new(rep, 200)
71
+ end
72
+ assert_raises TypeError do
73
+ ZMQ::Pollitem.new(:invalid, ZMQ::POLLIN)
74
+ end
75
+ ensure
76
+ ctx.destroy
77
+ end
78
+ end
@@ -0,0 +1,403 @@
1
+ # encoding: utf-8
2
+
3
+ require File.join(File.dirname(__FILE__), 'helper')
4
+
5
+ class TestZmqSocket < ZmqTestCase
6
+ def test_fd
7
+ ctx = ZMQ::Context.new
8
+ sock = ctx.socket(:REP)
9
+ assert Fixnum === sock.fd
10
+ assert_equal(-1, sock.fd)
11
+ assert_equal sock.fd, sock.to_i
12
+ ensure
13
+ ctx.destroy
14
+ end
15
+
16
+ def test_type
17
+ ctx = ZMQ::Context.new
18
+ sock = ctx.socket(:REP)
19
+ assert_equal ZMQ::REP, sock.type
20
+ ensure
21
+ ctx.destroy
22
+ end
23
+
24
+ def test_readable_p
25
+ ctx = ZMQ::Context.new
26
+ rep = ctx.socket(:REP)
27
+ rep.bind("inproc://test.socket-readable_p")
28
+ req = ctx.connect(:REQ, "inproc://test.socket-readable_p")
29
+ assert req.writable?
30
+ req.send("m")
31
+ sleep 0.1
32
+ assert rep.readable?
33
+ ensure
34
+ ctx.destroy
35
+ end
36
+
37
+ def test_send_socket
38
+ ctx = ZMQ::Context.new
39
+ push = ctx.socket(:PUSH)
40
+ assert_raises ZMQ::Error do
41
+ push.recv
42
+ end
43
+ ensure
44
+ ctx.destroy
45
+ end
46
+
47
+ def test_receive_socket
48
+ ctx = ZMQ::Context.new
49
+ pull = ctx.socket(:PULL)
50
+ assert_raises ZMQ::Error do
51
+ pull.send("message")
52
+ end
53
+ ensure
54
+ ctx.destroy
55
+ end
56
+
57
+ def test_recv_timeout
58
+ ctx = ZMQ::Context.new
59
+ sock = ctx.socket(:REP)
60
+ assert_nil sock.recv_timeout
61
+ sock.recv_timeout = 10
62
+ assert_equal 10, sock.recv_timeout
63
+ assert_raises TypeError do
64
+ sock.recv_timeout = :x
65
+ end
66
+ ensure
67
+ ctx.destroy
68
+ end
69
+
70
+ def test_send_timeout
71
+ ctx = ZMQ::Context.new
72
+ sock = ctx.socket(:REP)
73
+ assert_nil sock.send_timeout
74
+ sock.send_timeout = 10
75
+ assert_equal 10, sock.send_timeout
76
+ assert_raises TypeError do
77
+ sock.send_timeout = :x
78
+ end
79
+ ensure
80
+ ctx.destroy
81
+ end
82
+
83
+ def test_gc_context_reaped
84
+ pub = ZMQ::Context.new.socket(:PUB)
85
+ GC.start
86
+ pub.bind("inproc://test.socket-gc_context_reaped")
87
+ GC.start
88
+ pub.send("test")
89
+ GC.start
90
+ pub.close
91
+ ensure
92
+ ZMQ.context.destroy
93
+ end
94
+
95
+ def test_bind
96
+ ctx = ZMQ::Context.new
97
+ sock = ctx.socket(:REP)
98
+ assert(sock.state & ZMQ::Socket::PENDING)
99
+ port = sock.bind("tcp://127.0.0.1:*")
100
+ assert sock.fd != -1
101
+ assert(sock.state & ZMQ::Socket::BOUND)
102
+ tcp_sock = nil
103
+ assert_nothing_raised do
104
+ tcp_sock = TCPSocket.new("127.0.0.1", port)
105
+ end
106
+ ensure
107
+ ctx.destroy
108
+ tcp_sock.close if tcp_sock
109
+ end
110
+
111
+ def test_connect
112
+ ctx = ZMQ::Context.new
113
+ rep = ctx.socket(:PAIR)
114
+ port = rep.bind("inproc://test.socket-connect")
115
+ req = ctx.socket(:PAIR)
116
+ assert(req.state & ZMQ::Socket::PENDING)
117
+ req.connect("inproc://test.socket-connect")
118
+ assert req.fd != -1
119
+ assert(req.state & ZMQ::Socket::CONNECTED)
120
+ ensure
121
+ ctx.destroy
122
+ end
123
+
124
+ def test_to_s
125
+ ctx = ZMQ::Context.new
126
+ sock = ctx.socket(:PAIR)
127
+ rep = ctx.socket(:REP)
128
+ port = rep.bind("tcp://127.0.0.1:*")
129
+ req = ctx.socket(:REQ)
130
+ assert(req.state & ZMQ::Socket::PENDING)
131
+ req.connect("tcp://127.0.0.1:#{port}")
132
+ assert_equal "PAIR socket", sock.to_s
133
+ assert_equal "REP socket bound to tcp://127.0.0.1:*", rep.to_s
134
+ assert_equal "REQ socket connected to tcp://127.0.0.1:#{port}", req.to_s
135
+ ensure
136
+ ctx.destroy
137
+ end
138
+
139
+ def test_endpoint
140
+ ctx = ZMQ::Context.new
141
+ rep = ctx.socket(:REP)
142
+ port = rep.bind("tcp://127.0.0.1:*")
143
+ req = ctx.socket(:REQ)
144
+ req.connect("tcp://127.0.0.1:#{port}")
145
+ assert_equal "tcp://127.0.0.1:*", rep.endpoint
146
+ assert_equal "tcp://127.0.0.1:#{port}", req.endpoint
147
+ ensure
148
+ ctx.destroy
149
+ end
150
+
151
+ def test_close
152
+ ctx = ZMQ::Context.new
153
+ sock = ctx.socket(:REP)
154
+ port = sock.bind("tcp://127.0.0.1:*")
155
+ assert sock.fd != -1
156
+ other = ctx.socket(:REQ)
157
+ other.connect("tcp://127.0.0.1:#{port}")
158
+ other.send("test")
159
+ assert_equal "test", sock.recv
160
+ sock.close
161
+ other.close
162
+ # zsocket_destroy in libczmq recycles the socket instance. libzmq don't support / expose underlying
163
+ # connection state or teardown through public API, thus we can't assert a PENDING socket state on close
164
+ # through the Ruby API as the socket instance has already been recycled.
165
+ begin
166
+ assert_equal ZMQ::Socket::PENDING, sock.state
167
+ rescue => e
168
+ assert_instance_of ZMQ::Error, e
169
+ assert_match(/ZMQ::Socket instance \w* has been destroyed by the ZMQ framework/, e.message)
170
+ end
171
+ sleep 0.2
172
+ assert_raises Errno::ECONNREFUSED do
173
+ TCPSocket.new("127.0.0.1", port)
174
+ end
175
+ ensure
176
+ ctx.destroy
177
+ end
178
+
179
+ def test_send_receive
180
+ ctx = ZMQ::Context.new
181
+ rep = ctx.socket(:PAIR)
182
+ rep.bind("inproc://test.socket-send_receive")
183
+ req = ctx.socket(:PAIR)
184
+ req.connect("inproc://test.socket-send_receive")
185
+ assert req.send("ping")
186
+ assert_equal "ping", rep.recv
187
+ ensure
188
+ ctx.destroy
189
+ end
190
+
191
+ def test_verbose
192
+ ctx = ZMQ::Context.new
193
+ rep = ctx.socket(:PAIR)
194
+ rep.verbose = true
195
+ rep.bind("inproc://test.socket-verbose")
196
+ req = ctx.socket(:PAIR)
197
+ req.verbose = true
198
+ req.connect("inproc://test.socket-verbose")
199
+ assert req.send("ping")
200
+ assert_equal "ping", rep.recv
201
+ req.send_frame(ZMQ::Frame("frame"))
202
+ assert_equal ZMQ::Frame("frame"), rep.recv_frame
203
+ ensure
204
+ ctx.destroy
205
+ end
206
+
207
+ def test_receive_nonblock
208
+ ctx = ZMQ::Context.new
209
+ rep = ctx.socket(:REP)
210
+ port = rep.bind("tcp://127.0.0.1:*")
211
+ req = ctx.socket(:REQ)
212
+ req.connect("tcp://127.0.0.1:#{port}")
213
+ assert req.send("ping")
214
+ assert_equal nil, rep.recv_nonblock
215
+ sleep 0.2
216
+ assert_equal "ping", rep.recv_nonblock
217
+ ensure
218
+ ctx.destroy
219
+ end
220
+
221
+ def test_send_multi
222
+ ctx = ZMQ::Context.new
223
+ rep = ctx.socket(:PAIR)
224
+ rep.bind("inproc://test.socket-send_multi")
225
+ req = ctx.socket(:PAIR)
226
+ req.connect("inproc://test.socket-send_multi")
227
+ assert req.sendm("batch")
228
+ req.sendm("of")
229
+ req.send("messages")
230
+ assert_equal "batch", rep.recv
231
+ assert_equal "of", rep.recv
232
+ assert_equal "messages", rep.recv
233
+ ensure
234
+ ctx.destroy
235
+ end
236
+
237
+ def test_send_receive_frame
238
+ ctx = ZMQ::Context.new
239
+ rep = ctx.socket(:REP)
240
+ port = rep.bind("tcp://127.0.0.1:*")
241
+ req = ctx.socket(:REQ)
242
+ req.connect("tcp://127.0.0.1:#{port}")
243
+ ping = ZMQ::Frame("ping")
244
+ assert req.send_frame(ping)
245
+ assert_equal ZMQ::Frame("ping"), rep.recv_frame
246
+ assert rep.send_frame(ZMQ::Frame("pong"))
247
+ assert_equal ZMQ::Frame("pong"), req.recv_frame
248
+ assert req.send_frame(ZMQ::Frame("pong"))
249
+ frame = rep.recv_frame_nonblock
250
+ if frame
251
+ assert_equal ZMQ::Frame("pong"), frame
252
+ else
253
+ sleep 0.3
254
+ assert_equal ZMQ::Frame("pong"), rep.recv_frame_nonblock
255
+ end
256
+ ensure
257
+ ctx.destroy
258
+ end
259
+
260
+ def test_send_frame_more
261
+ ctx = ZMQ::Context.new
262
+ rep = ctx.socket(:PAIR)
263
+ rep.bind("inproc://test.socket-send_frame_more")
264
+ req = ctx.socket(:PAIR)
265
+ req.connect("inproc://test.socket-send_frame_more")
266
+ 5.times do |i|
267
+ frame = ZMQ::Frame("m#{i}")
268
+ req.send_frame(frame, ZMQ::Frame::MORE)
269
+ end
270
+ req.send_frame(ZMQ::Frame("m6"))
271
+ expected, frames = %w(m0 m1 m2 m3 m4), []
272
+ 5.times do
273
+ frames << rep.recv_frame.data
274
+ end
275
+ assert_equal expected, frames
276
+ ensure
277
+ ctx.destroy
278
+ end
279
+
280
+ def test_send_frame_reuse
281
+ ctx = ZMQ::Context.new
282
+ rep = ctx.socket(:PAIR)
283
+ rep.bind("inproc://test.socket-send_frame_reuse")
284
+ req = ctx.socket(:PAIR)
285
+ req.connect("inproc://test.socket-send_frame_reuse")
286
+ frame = ZMQ::Frame("reused_frame")
287
+ 5.times do |i|
288
+ req.send_frame(frame, :REUSE)
289
+ end
290
+ expected, frames = ( %w(reused_frame) * 5), []
291
+ 5.times do
292
+ frames << rep.recv_frame.data
293
+ end
294
+ assert_equal expected, frames
295
+ ensure
296
+ ctx.destroy
297
+ end
298
+
299
+ def test_send_receive_message
300
+ ctx = ZMQ::Context.new
301
+ rep = ctx.socket(:PAIR)
302
+ rep.verbose = true
303
+ rep.bind("inproc://test.socket-send_receive_message")
304
+ req = ctx.socket(:PAIR)
305
+ req.verbose = true
306
+ req.connect("inproc://test.socket-send_receive_message")
307
+
308
+ msg = ZMQ::Message.new
309
+ msg.push ZMQ::Frame("header")
310
+
311
+ assert_nil req.send_message(msg)
312
+
313
+ recvd_msg = rep.recv_message
314
+ assert_instance_of ZMQ::Message, recvd_msg
315
+ assert_equal ZMQ::Frame("header"), recvd_msg.pop
316
+ ensure
317
+ ctx.destroy
318
+ end
319
+
320
+ def test_type_str
321
+ ctx = ZMQ::Context.new
322
+ sock = ctx.socket(:PAIR)
323
+ assert_equal "PAIR", sock.type_str
324
+ ensure
325
+ ctx.destroy
326
+ end
327
+
328
+ def test_sock_options
329
+ ctx = ZMQ::Context.new
330
+ sock = ctx.socket(:PAIR)
331
+ sock.verbose = true
332
+ assert_equal 0, sock.hwm
333
+ sock.hwm = 1000
334
+ assert_equal 1000, sock.hwm
335
+
336
+ assert_equal 0, sock.swap
337
+ sock.swap = 1000
338
+ assert_equal 1000, sock.swap
339
+
340
+ assert_equal 0, sock.affinity
341
+ sock.affinity = 1
342
+ assert_equal 1, sock.affinity
343
+
344
+ assert_equal 40000, sock.rate
345
+ sock.rate = 50000
346
+ assert_equal 50000, sock.rate
347
+
348
+ assert_equal 10, sock.recovery_ivl
349
+ sock.recovery_ivl = 20
350
+ assert_equal 20, sock.recovery_ivl
351
+
352
+ assert_equal(-1, sock.recovery_ivl_msec)
353
+ sock.recovery_ivl_msec = 20
354
+ assert_equal 20, sock.recovery_ivl_msec
355
+
356
+ assert_equal true, sock.mcast_loop?
357
+ sock.mcast_loop = false
358
+ assert !sock.mcast_loop?
359
+
360
+ assert_equal 0, sock.sndbuf
361
+ sock.sndbuf = 1000
362
+ assert_equal 1000, sock.sndbuf
363
+
364
+ assert_equal 0, sock.rcvbuf
365
+ sock.rcvbuf = 1000
366
+ assert_equal 1000, sock.rcvbuf
367
+
368
+ assert_equal(-1, sock.linger)
369
+ sock.linger = 10
370
+ assert_equal 10, sock.linger
371
+
372
+ assert_equal 100, sock.backlog
373
+ sock.backlog = 200
374
+ assert_equal 200, sock.backlog
375
+
376
+ assert_equal 100, sock.reconnect_ivl
377
+ sock.reconnect_ivl = 200
378
+ assert_equal 200, sock.reconnect_ivl
379
+
380
+ assert_equal 0, sock.reconnect_ivl_max
381
+ sock.reconnect_ivl_max = 5
382
+ assert_equal 5, sock.reconnect_ivl_max
383
+
384
+ sock.identity = "anonymous"
385
+ assert_raises ZMQ::Error do
386
+ sock.identity = ""
387
+ end
388
+ assert_raises ZMQ::Error do
389
+ sock.identity = ("*" * 256)
390
+ end
391
+
392
+ assert !sock.rcvmore?
393
+
394
+ assert_equal 0, sock.events
395
+
396
+ sub_sock = ctx.socket(:SUB)
397
+ sub_sock.verbose = true
398
+ sub_sock.subscribe("ruby")
399
+ sub_sock.unsubscribe("ruby")
400
+ ensure
401
+ ctx.destroy
402
+ end
403
+ end