rbczmq 1.7.4 → 1.7.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (99) hide show
  1. checksums.yaml +5 -13
  2. data/.travis.yml +4 -1
  3. data/CHANGELOG.rdoc +13 -0
  4. data/Gemfile +8 -1
  5. data/Gemfile.lock +211 -2
  6. data/README.rdoc +7 -4
  7. data/ext/rbczmq/beacon.c +6 -3
  8. data/ext/rbczmq/context.c +117 -8
  9. data/ext/rbczmq/context.h +5 -0
  10. data/ext/rbczmq/message.c +6 -4
  11. data/ext/rbczmq/poller.c +12 -5
  12. data/ext/rbczmq/rbczmq_ext.c +2 -0
  13. data/ext/rbczmq/rbczmq_ext.h +1 -0
  14. data/ext/rbczmq/socket.c +135 -59
  15. data/ext/rbczmq/socket.h +2 -0
  16. data/ext/zeromq/CMakeLists.txt +3 -1
  17. data/ext/zeromq/NEWS +28 -3
  18. data/ext/zeromq/doc/zmq.txt +3 -3
  19. data/ext/zeromq/doc/zmq_getsockopt.txt +3 -3
  20. data/ext/zeromq/doc/zmq_msg_get.txt +2 -1
  21. data/ext/zeromq/doc/zmq_msg_more.txt +1 -1
  22. data/ext/zeromq/doc/zmq_setsockopt.txt +18 -19
  23. data/ext/zeromq/doc/zmq_socket.txt +4 -0
  24. data/ext/zeromq/include/zmq.h +14 -18
  25. data/ext/zeromq/src/clock.cpp +57 -2
  26. data/ext/zeromq/src/ctx.cpp +11 -5
  27. data/ext/zeromq/src/devpoll.cpp +5 -0
  28. data/ext/zeromq/src/devpoll.hpp +2 -0
  29. data/ext/zeromq/src/epoll.cpp +5 -0
  30. data/ext/zeromq/src/epoll.hpp +2 -0
  31. data/ext/zeromq/src/i_engine.hpp +2 -2
  32. data/ext/zeromq/src/kqueue.cpp +5 -0
  33. data/ext/zeromq/src/kqueue.hpp +2 -0
  34. data/ext/zeromq/src/pgm_receiver.cpp +2 -2
  35. data/ext/zeromq/src/pgm_receiver.hpp +2 -2
  36. data/ext/zeromq/src/pgm_sender.cpp +2 -2
  37. data/ext/zeromq/src/pgm_sender.hpp +2 -2
  38. data/ext/zeromq/src/poll.cpp +5 -0
  39. data/ext/zeromq/src/poll.hpp +2 -0
  40. data/ext/zeromq/src/router.cpp +2 -0
  41. data/ext/zeromq/src/select.cpp +5 -0
  42. data/ext/zeromq/src/select.hpp +2 -0
  43. data/ext/zeromq/src/session_base.cpp +2 -2
  44. data/ext/zeromq/src/signaler.cpp +73 -99
  45. data/ext/zeromq/src/signaler.hpp +2 -2
  46. data/ext/zeromq/src/socket_base.cpp +42 -40
  47. data/ext/zeromq/src/stream_engine.cpp +60 -58
  48. data/ext/zeromq/src/stream_engine.hpp +7 -8
  49. data/ext/zeromq/src/zmq_utils.cpp +6 -5
  50. data/ext/zeromq/tests/Makefile.am +6 -5
  51. data/ext/zeromq/tests/test_conflate.cpp +2 -5
  52. data/ext/zeromq/tests/test_ctx_destroy.cpp +1 -1
  53. data/ext/zeromq/tests/test_ctx_options.cpp +1 -1
  54. data/ext/zeromq/tests/test_immediate.cpp +1 -2
  55. data/ext/zeromq/tests/test_inproc_connect.cpp +1 -1
  56. data/ext/zeromq/tests/test_iov.cpp +1 -1
  57. data/ext/zeromq/tests/test_many_sockets.cpp +90 -0
  58. data/ext/zeromq/tests/test_monitor.cpp +3 -3
  59. data/ext/zeromq/tests/test_req_relaxed.cpp +1 -1
  60. data/ext/zeromq/tests/test_router_raw_empty.cpp +65 -0
  61. data/ext/zeromq/tests/test_spec_req.cpp +1 -1
  62. data/ext/zeromq/tests/test_stream.cpp +6 -7
  63. data/ext/zeromq/tests/test_sub_forward.cpp +1 -1
  64. data/ext/zeromq/tests/test_term_endpoint.cpp +2 -2
  65. data/ext/zeromq/tests/testutil.hpp +18 -1
  66. data/ext/zeromq/tools/Makefile.am +1 -1
  67. data/lib/zmq/socket.rb +1 -0
  68. data/lib/zmq/socket/stream.rb +44 -0
  69. data/lib/zmq/version.rb +1 -1
  70. data/test/socket/test_dealer_socket.rb +1 -1
  71. data/test/socket/test_pair_socket.rb +1 -1
  72. data/test/socket/test_pair_sockets.rb +1 -1
  73. data/test/socket/test_pub_socket.rb +1 -1
  74. data/test/socket/test_pub_sub_sockets.rb +1 -1
  75. data/test/socket/test_pull_socket.rb +1 -1
  76. data/test/socket/test_push_pull_sockets.rb +1 -1
  77. data/test/socket/test_push_socket.rb +1 -1
  78. data/test/socket/test_rep_socket.rb +1 -1
  79. data/test/socket/test_req_rep_sockets.rb +1 -1
  80. data/test/socket/test_req_socket.rb +1 -1
  81. data/test/socket/test_router_socket.rb +1 -1
  82. data/test/socket/test_routing.rb +1 -1
  83. data/test/socket/test_stream_socket.rb +74 -0
  84. data/test/socket/test_sub_socket.rb +1 -1
  85. data/test/test_beacon.rb +4 -2
  86. data/test/test_context.rb +2 -2
  87. data/test/test_frame.rb +2 -2
  88. data/test/test_handler.rb +2 -2
  89. data/test/test_logger.rb +1 -1
  90. data/test/test_loop.rb +2 -2
  91. data/test/test_message.rb +1 -1
  92. data/test/test_monitoring.rb +15 -3
  93. data/test/test_poller.rb +2 -2
  94. data/test/test_pollitem.rb +2 -2
  95. data/test/test_socket.rb +53 -6
  96. data/test/test_threading.rb +2 -2
  97. data/test/test_timer.rb +2 -2
  98. data/test/test_zmq.rb +2 -2
  99. metadata +109 -104
@@ -45,7 +45,6 @@ int main (int argc, char *argv [])
45
45
  assert (rc == 0);
46
46
 
47
47
  int message_count = 20;
48
-
49
48
  for (int j = 0; j < message_count; ++j) {
50
49
  rc = zmq_send(s_out, (void*)&j, sizeof(int), 0);
51
50
  if (rc < 0) {
@@ -53,15 +52,13 @@ int main (int argc, char *argv [])
53
52
  return -1;
54
53
  }
55
54
  }
56
-
57
- zmq_sleep (1);
55
+ msleep (SETTLE_TIME);
58
56
 
59
57
  int payload_recved = 0;
60
- rc = zmq_recv(s_in, (void*)&payload_recved, sizeof(int), 0);
58
+ rc = zmq_recv (s_in, (void*)&payload_recved, sizeof(int), 0);
61
59
  assert (rc > 0);
62
60
  assert (payload_recved == message_count - 1);
63
61
 
64
-
65
62
  rc = zmq_close (s_in);
66
63
  assert (rc == 0);
67
64
 
@@ -61,7 +61,7 @@ void test_ctx_shutdown()
61
61
  void *receiver_thread = zmq_threadstart (&receiver, socket);
62
62
 
63
63
  // Wait for thread to start up and block
64
- zmq_sleep (1);
64
+ msleep (SETTLE_TIME);
65
65
 
66
66
  // Shutdown context, if we used destroy here we would deadlock.
67
67
  rc = zmq_ctx_shutdown (ctx);
@@ -33,7 +33,7 @@ int main (void)
33
33
  assert (zmq_ctx_get (ctx, ZMQ_IPV6) == 0);
34
34
 
35
35
  rc = zmq_ctx_set (ctx, ZMQ_IPV6, true);
36
- assert (zmq_ctx_get (ctx, ZMQ_IPV6) == true);
36
+ assert (zmq_ctx_get (ctx, ZMQ_IPV6) == 1);
37
37
 
38
38
  void *router = zmq_socket (ctx, ZMQ_ROUTER);
39
39
  int ipv6;
@@ -193,8 +193,7 @@ int main (void)
193
193
  assert (rc == 0);
194
194
 
195
195
  // Give time to process disconnect
196
- // There's no way to do this except with a sleep
197
- zmq_sleep(1);
196
+ msleep (SETTLE_TIME);
198
197
 
199
198
  // Send a message, should fail
200
199
  rc = zmq_send (frontend, "Hello", 5, ZMQ_DONTWAIT);
@@ -142,7 +142,7 @@ void test_connect_before_bind_pub_sub()
142
142
  assert (rc == 0);
143
143
 
144
144
  // Wait for pub-sub connection to happen
145
- zmq_sleep (1);
145
+ msleep (SETTLE_TIME);
146
146
 
147
147
  // Queue up some data, this not will be dropped
148
148
  rc = zmq_send_const (connectSocket, "after", 6, 0);
@@ -80,7 +80,7 @@ int main (void)
80
80
  rc = zmq_bind (sb, "inproc://a");
81
81
  assert (rc == 0);
82
82
 
83
- zmq_sleep(1);
83
+ msleep (SETTLE_TIME);
84
84
  void *sc = zmq_socket (ctx, ZMQ_PUSH);
85
85
 
86
86
  rc = zmq_connect (sc, "inproc://a");
@@ -0,0 +1,90 @@
1
+ /*
2
+ Copyright (c) 2007-2013 Contributors as noted in the AUTHORS file
3
+
4
+ This file is part of 0MQ.
5
+
6
+ 0MQ is free software; you can redistribute it and/or modify it under
7
+ the terms of the GNU Lesser General Public License as published by
8
+ the Free Software Foundation; either version 3 of the License, or
9
+ (at your option) any later version.
10
+
11
+ 0MQ is distributed in the hope that it will be useful,
12
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ GNU Lesser General Public License for more details.
15
+
16
+ You should have received a copy of the GNU Lesser General Public License
17
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
18
+ */
19
+
20
+ #include "testutil.hpp"
21
+ #include <zmq.h>
22
+ #include <stdio.h>
23
+ #include <stdlib.h>
24
+ #include <vector>
25
+
26
+ void test_system_max ()
27
+ {
28
+ // Keep allocating sockets until we run out of system resources
29
+ const int no_of_sockets = 2 * 65536;
30
+ void *ctx = zmq_ctx_new ();
31
+ zmq_ctx_set (ctx, ZMQ_MAX_SOCKETS, no_of_sockets);
32
+ std::vector <void*> sockets;
33
+
34
+ while (true) {
35
+ void *socket = zmq_socket (ctx, ZMQ_PAIR);
36
+ if (!socket)
37
+ break;
38
+ sockets.push_back (socket);
39
+ }
40
+ assert ((int) sockets.size () < no_of_sockets);
41
+
42
+ // System is out of resources, further calls to zmq_socket should return NULL
43
+ for (unsigned int i = 0; i < 10; ++i) {
44
+ void *socket = zmq_socket (ctx, ZMQ_PAIR);
45
+ assert (socket == NULL);
46
+ }
47
+ // Clean up.
48
+ for (unsigned int i = 0; i < sockets.size (); ++i)
49
+ zmq_close (sockets [i]);
50
+
51
+ zmq_ctx_destroy (ctx);
52
+ }
53
+
54
+ void test_zmq_default_max ()
55
+ {
56
+ // Keep allocating sockets until we hit the default limit
57
+ void *ctx = zmq_ctx_new ();
58
+ std::vector<void*> sockets;
59
+
60
+ while (true) {
61
+ void *socket = zmq_socket (ctx, ZMQ_PAIR);
62
+ if (!socket)
63
+ break;
64
+ sockets.push_back (socket);
65
+ }
66
+ // We may stop sooner if system has fewer available sockets
67
+ assert (sockets.size () <= ZMQ_MAX_SOCKETS_DFLT);
68
+
69
+ // Further calls to zmq_socket should return NULL
70
+ for (unsigned int i = 0; i < 10; ++i) {
71
+ void *socket = zmq_socket (ctx, ZMQ_PAIR);
72
+ assert (socket == NULL);
73
+ }
74
+
75
+ // Clean up
76
+ for (unsigned int i = 0; i < sockets.size (); ++i)
77
+ zmq_close (sockets [i]);
78
+
79
+ zmq_ctx_destroy (ctx);
80
+ }
81
+
82
+ int main (void)
83
+ {
84
+ setup_test_environment ();
85
+
86
+ test_system_max ();
87
+ test_zmq_default_max ();
88
+
89
+ return 0;
90
+ }
@@ -211,7 +211,7 @@ int main (void)
211
211
  rc = zmq_socket_monitor (req, "inproc://monitor.req", ZMQ_EVENT_ALL);
212
212
  assert (rc == 0);
213
213
  threads [1] = zmq_threadstart(&req_socket_monitor, ctx);
214
- zmq_sleep(1);
214
+ msleep (SETTLE_TIME);
215
215
 
216
216
  // Bind REQ and REP
217
217
  rc = zmq_bind (rep, addr.c_str());
@@ -238,8 +238,8 @@ int main (void)
238
238
  rc = zmq_close (rep);
239
239
  assert (rc == 0);
240
240
 
241
- // Allow some time for detecting error states
242
- zmq_sleep(1);
241
+ // Allow enough time for detecting error states
242
+ msleep (250);
243
243
 
244
244
  // Close the REQ socket
245
245
  rc = zmq_close (req);
@@ -54,7 +54,7 @@ int main (void)
54
54
  // We have to give the connects time to finish otherwise the requests
55
55
  // will not properly round-robin. We could alternatively connect the
56
56
  // REQ sockets to the REP sockets.
57
- zmq_sleep(1);
57
+ msleep (SETTLE_TIME);
58
58
 
59
59
  // Case 1: Second send() before a reply arrives in a pipe.
60
60
 
@@ -0,0 +1,65 @@
1
+ /*
2
+ Copyright (c) 2007-2013 Contributors as noted in the AUTHORS file
3
+
4
+ This file is part of 0MQ.
5
+
6
+ 0MQ is free software; you can redistribute it and/or modify it under
7
+ the terms of the GNU Lesser General Public License as published by
8
+ the Free Software Foundation; either version 3 of the License, or
9
+ (at your option) any later version.
10
+
11
+ 0MQ is distributed in the hope that it will be useful,
12
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ GNU Lesser General Public License for more details.
15
+
16
+ You should have received a copy of the GNU Lesser General Public License
17
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
18
+ */
19
+
20
+ #include "testutil.hpp"
21
+
22
+ int main (void) {
23
+ setup_test_environment();
24
+ void *ctx = zmq_ctx_new();
25
+ assert(ctx);
26
+
27
+ void *router = zmq_socket(ctx, ZMQ_ROUTER);
28
+ assert(router);
29
+ void *dealer = zmq_socket(ctx, ZMQ_DEALER);
30
+ assert(dealer);
31
+
32
+ int one=1;
33
+ int rc = zmq_setsockopt(router, ZMQ_ROUTER_RAW, &one, sizeof(int));
34
+ assert(rc >= 0);
35
+ rc = zmq_setsockopt(router, ZMQ_ROUTER_MANDATORY, &one, sizeof(int));
36
+ assert(rc >= 0);
37
+
38
+ rc = zmq_bind(router, "tcp://127.0.0.1:5555");
39
+ rc = zmq_connect(dealer, "tcp://127.0.0.1:5555");
40
+ zmq_send(dealer, "", 0, 0);
41
+
42
+
43
+ zmq_msg_t ident, empty;
44
+ zmq_msg_init(&ident);
45
+ rc = zmq_msg_recv(&ident, router, 0);
46
+ assert(rc >= 0);
47
+ rc = zmq_msg_init_data(&empty, (void*)"", 0, NULL, NULL);
48
+ assert(rc >= 0);
49
+
50
+ rc = zmq_msg_send(&ident, router, ZMQ_SNDMORE);
51
+ assert(rc >= 0);
52
+ rc = zmq_msg_close(&ident);
53
+ assert(rc >= 0);
54
+
55
+ rc = zmq_msg_send(&empty, router, 0);
56
+ assert(rc >= 0);
57
+
58
+ // This close used to fail with Bad Address
59
+ rc = zmq_msg_close(&empty);
60
+ assert(rc >= 0);
61
+
62
+ close_zero_linger(dealer);
63
+ close_zero_linger(router);
64
+ zmq_ctx_term(ctx);
65
+ }
@@ -46,7 +46,7 @@ void test_round_robin_out (void *ctx)
46
46
  // We have to give the connects time to finish otherwise the requests
47
47
  // will not properly round-robin. We could alternatively connect the
48
48
  // REQ sockets to the REP sockets.
49
- zmq_sleep(1);
49
+ msleep (SETTLE_TIME);
50
50
 
51
51
  // Send our peer-replies, and expect every REP it used once in order
52
52
  for (size_t peer = 0; peer < services; peer++) {
@@ -89,15 +89,14 @@ test_stream_to_dealer (void)
89
89
  assert (rc == sizeof (greeting));
90
90
 
91
91
  // Now we expect the data from the DEALER socket
92
- // First frame is, again, the identity of the connection
93
- rc = zmq_msg_recv (&identity, stream, 0);
94
- assert (rc > 0);
95
- assert (zmq_msg_more (&identity));
96
-
97
- // Second frame contains the rest of greeting along with
98
- // the Ready command
92
+ // We want the rest of greeting along with the Ready command
99
93
  int bytes_read = 0;
100
94
  while (bytes_read < 97) {
95
+ // First frame is the identity of the connection (each time)
96
+ rc = zmq_msg_recv (&identity, stream, 0);
97
+ assert (rc > 0);
98
+ assert (zmq_msg_more (&identity));
99
+ // Second frame contains the next chunk of data
101
100
  rc = zmq_recv (stream, buffer + bytes_read, 255 - bytes_read, 0);
102
101
  assert (rc >= 0);
103
102
  bytes_read += rc;
@@ -59,7 +59,7 @@ int main (void)
59
59
  assert (rc >= 0);
60
60
 
61
61
  // Wait a bit till the subscription gets to the publisher
62
- zmq_sleep(1);
62
+ msleep (SETTLE_TIME);
63
63
 
64
64
  // Send an empty message
65
65
  rc = zmq_send (pub, NULL, 0, 0);
@@ -49,7 +49,7 @@ int main (void)
49
49
  assert (rc == 0);
50
50
 
51
51
  // Allow unbind to settle
52
- zmq_sleep(1);
52
+ msleep (SETTLE_TIME);
53
53
 
54
54
  // Check that sending would block (there's no outbound connection)
55
55
  rc = zmq_send (push, "ABC", 3, ZMQ_DONTWAIT);
@@ -86,7 +86,7 @@ int main (void)
86
86
  assert (rc == 0);
87
87
 
88
88
  // Allow disconnect to settle
89
- zmq_sleep(1);
89
+ msleep (SETTLE_TIME);
90
90
 
91
91
  // Check that sending would block (there's no inbound connections).
92
92
  rc = zmq_send (push, "ABC", 3, ZMQ_DONTWAIT);
@@ -22,7 +22,12 @@
22
22
 
23
23
  #include "../include/zmq.h"
24
24
  #include "../include/zmq_utils.h"
25
- #include "platform.hpp"
25
+ #include "../src/platform.hpp"
26
+
27
+ // This defines the settle time used in tests; raise this if we
28
+ // get test failures on slower systems due to binds/connects not
29
+ // settled. Tested to work reliably at 1 msec on a fast PC.
30
+ #define SETTLE_TIME 10 // In msec
26
31
 
27
32
  #undef NDEBUG
28
33
  #include <time.h>
@@ -259,4 +264,16 @@ void setup_test_environment()
259
264
  #endif
260
265
  }
261
266
 
267
+ // Provide portable millisecond sleep
268
+ // http://www.cplusplus.com/forum/unices/60161/ http://en.cppreference.com/w/cpp/thread/sleep_for
269
+ void msleep (int milliseconds)
270
+ {
271
+ #ifdef ZMQ_HAVE_WINDOWS
272
+ Sleep (milliseconds);
273
+ #else
274
+ usleep (static_cast <useconds_t> (milliseconds) * 1000);
275
+ #endif
276
+ }
277
+
278
+
262
279
  #endif
@@ -4,6 +4,6 @@ INCLUDES = -I$(top_srcdir)/include
4
4
 
5
5
  bin_PROGRAMS = curve_keygen
6
6
 
7
- curve_keygen_LDADD = $(top_srcdir)/src/libzmq.la
7
+ curve_keygen_LDADD = $(top_builddir)/src/libzmq.la
8
8
  curve_keygen_SOURCES = curve_keygen.c
9
9
 
@@ -213,3 +213,4 @@ require "zmq/socket/req"
213
213
  require "zmq/socket/rep"
214
214
  require "zmq/socket/router"
215
215
  require "zmq/socket/dealer"
216
+ require "zmq/socket/stream"
@@ -0,0 +1,44 @@
1
+ # encoding: utf-8
2
+
3
+ class ZMQ::Socket::Stream
4
+
5
+ # == ZMQ::Socket::Stream
6
+ # A socket of type ZMQ::Socket::Stream is used to send and receive TCP data from a non-ØMQ peer,
7
+ # when using the tcp:// transport. A ZMQ::Socket::Stream socket can act as client and/or server,
8
+ # sending and/or receiving TCP data asynchronously.
9
+ #
10
+ # When receiving TCP data, a ZMQ::Socket::Stream socket shall prepend a message part containing
11
+ # the identity of the originating peer to the message before passing it to the application.
12
+ # Messages received are fair-queued from among all connected peers.
13
+ #
14
+ # When sending TCP data, a ZMQ::Socket::Stream socket shall remove the first part of the message
15
+ # and use it to determine the identity of the peer the message shall be routed to, and unroutable
16
+ # messages shall cause an EHOSTUNREACH or EAGAIN error.
17
+ #
18
+ # To open a connection to a server, use the zmq_connect call, and then fetch the socket identity
19
+ # using the ZMQ_IDENTITY zmq_getsockopt call.
20
+ #
21
+ # To close a specific client connection, as a server, send the identity frame followed by a zero-
22
+ # length message (see EXAMPLE section).
23
+ #
24
+ # The ZMQ_MSGMORE flag is ignored on data frames. You must send one identity frame followed by
25
+ # one data frame.
26
+ #
27
+ # Also, please note that omitting the ZMQ_MSGMORE flag will prevent sending further data (from
28
+ # any client) on the same socket.
29
+ #
30
+ # === Summary of ZMQ_STREAM characteristics
31
+ #
32
+ # [Compatible peer sockets] none.
33
+ # [Direction] Bidirectional
34
+ # [Send/receive pattern] Unrestricted
35
+ # [Outgoing routing strategy] See text
36
+ # [Incoming routing strategy] Fair-queued
37
+ # [ZMQ::Socket#hwm option action] EAGAIN
38
+
39
+ TYPE_STR = "STREAM"
40
+
41
+ def type
42
+ ZMQ::STREAM
43
+ end
44
+ end
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module ZMQ
4
- VERSION = "1.7.4"
4
+ VERSION = "1.7.5"
5
5
  end
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
2
 
3
- require File.join(File.dirname(__FILE__), '..', 'helper')
3
+ require File.expand_path("../../helper.rb", __FILE__)
4
4
 
5
5
  class TestDealerSocket < ZmqTestCase
6
6
  def test_behavior
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
2
 
3
- require File.join(File.dirname(__FILE__), '..', 'helper')
3
+ require File.expand_path("../../helper.rb", __FILE__)
4
4
 
5
5
  class TestPairSocket < ZmqTestCase
6
6
  def test_behavior
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
2
 
3
- require File.join(File.dirname(__FILE__), '..', 'helper')
3
+ require File.expand_path("../../helper.rb", __FILE__)
4
4
 
5
5
  class TestPairSockets < ZmqTestCase
6
6
  def test_flow