em-zeromq 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,65 +1,62 @@
1
1
  # em-zeromq #
2
2
 
3
- Low level event machine support for ZeroMQ
4
-
5
3
  ## Description: ##
6
4
 
7
- This seems to work fine, no memory leaks, and it runs fast.
8
- It may not be perfect though, and the API is extremely minimal, just the bare minumum
9
- to make ZeroMQ work with EventMachine.
5
+ EventMachine support for ZeroMQ
10
6
 
11
- ## Using: ##
7
+ ## Usage: ##
12
8
 
13
- You must use either rubinius, jruby, or 1.9.x. 1.8.7 does not work with libzmq.
9
+ Tested and functional with Rubinius, jRuby, and 1.9.2.
14
10
 
15
- This only works with ZeroMQ 2.1.x which is still unreleased
16
- Build+Install ZeroMQ 2.1 from HEAD ( https://github.com/zeromq/zeromq2 )
11
+ If using 1.9.2 you must `gem install ffi` before using.
17
12
 
18
- Run the specs, see specs for examples
13
+ MRI 1.8.7 does not work with libzmq.
19
14
 
20
15
  Want to help out? Ask!
21
16
 
22
17
  ## Example ##
23
- require 'rubygems'
24
- require 'em-zeromq'
25
-
26
- Thread.abort_on_exception = true
27
-
28
- class EMTestPullHandler
29
- attr_reader :received
30
- def on_readable(socket, messages)
31
- messages.each do |m|
32
- puts m.copy_out_string
33
- end
34
- end
35
- end
36
-
37
- EM.run do
38
- ctx = EM::ZeroMQ::Context.new(1)
39
-
40
- # setup push sockets
41
- push_socket1 = ctx.bind( ZMQ::PUSH, 'tcp://127.0.0.1:2091')
42
- push_socket2 = ctx.bind( ZMQ::PUSH, 'ipc:///tmp/a')
43
- push_socket3 = ctx.bind( ZMQ::PUSH, 'inproc://simple_test')
44
-
45
- # setup one pull sockets listening to both push sockets
46
- pull_socket = ctx.connect( ZMQ::PULL, 'tcp://127.0.0.1:2091', EMTestPullHandler.new)
47
- pull_socket.connect('ipc:///tmp/a')
48
- pull_socket.connect('inproc://simple_test')
49
-
50
- n = 0
51
-
52
- # push_socket.hwm = 40
53
- # puts push_socket.hwm
54
- # puts pull_socket.hwm
55
-
56
- EM::PeriodicTimer.new(0.1) do
57
- puts '.'
58
- push_socket1.send_msg("t#{n += 1}_")
59
- push_socket2.send_msg("i#{n += 1}_")
60
- push_socket3.send_msg("p#{n += 1}_")
61
- end
18
+ ```ruby
19
+ require 'rubygems'
20
+ require 'em-zeromq'
21
+
22
+ Thread.abort_on_exception = true
23
+
24
+ class EMTestPullHandler
25
+ attr_reader :received
26
+ def on_readable(socket, messages)
27
+ messages.each do |m|
28
+ puts m.copy_out_string
62
29
  end
30
+ end
31
+ end
32
+
33
+ EM.run do
34
+ ctx = EM::ZeroMQ::Context.new(1)
35
+
36
+ # setup push sockets
37
+ push_socket1 = ctx.bind( ZMQ::PUSH, 'tcp://127.0.0.1:2091')
38
+ push_socket2 = ctx.bind( ZMQ::PUSH, 'ipc:///tmp/a')
39
+ push_socket3 = ctx.bind( ZMQ::PUSH, 'inproc://simple_test')
40
+
41
+ # setup one pull sockets listening to both push sockets
42
+ pull_socket = ctx.connect( ZMQ::PULL, 'tcp://127.0.0.1:2091', EMTestPullHandler.new)
43
+ pull_socket.connect('ipc:///tmp/a')
44
+ pull_socket.connect('inproc://simple_test')
45
+
46
+ n = 0
47
+
48
+ # push_socket.hwm = 40
49
+ # puts push_socket.hwm
50
+ # puts pull_socket.hwm
51
+
52
+ EM::PeriodicTimer.new(0.1) do
53
+ puts '.'
54
+ push_socket1.send_msg("t#{n += 1}_")
55
+ push_socket2.send_msg("i#{n += 1}_")
56
+ push_socket3.send_msg("p#{n += 1}_")
57
+ end
58
+ end
59
+ ```
63
60
 
64
61
  ## License: ##
65
62
 
data/em-zeromq.gemspec CHANGED
@@ -15,10 +15,12 @@ Gem::Specification.new do |s|
15
15
 
16
16
  s.rubyforge_project = "em-zeromq"
17
17
 
18
- s.add_dependency 'eventmachine', '>= 1.0.0.beta.3'
19
- s.add_dependency 'ffi-rzmq', '>= 0.7.2'
18
+ s.add_dependency 'eventmachine', '>= 1.0.0.beta.4'
19
+ s.add_dependency 'ffi', '>= 1.0.0'
20
+ s.add_dependency 'ffi-rzmq', '~> 0.9.0'
20
21
 
21
22
  s.add_development_dependency 'rspec', '>= 2.5.0'
23
+ s.add_development_dependency 'rake'
22
24
 
23
25
  s.files = `git ls-files`.split("\n")
24
26
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
data/example/simple.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  require 'rubygems'
2
- $LOAD_PATH << File.expand_path('../../lib', __FILE__)
2
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
3
3
  require 'em-zeromq'
4
4
 
5
5
  Thread.abort_on_exception = true
@@ -13,6 +13,12 @@ class EMTestPullHandler
13
13
  end
14
14
  end
15
15
 
16
+ trap('INT') do
17
+ EM::stop()
18
+ end
19
+
20
+ puts "Started (with zmq #{ZMQ::Util.version.join('.')})."
21
+
16
22
  EM.run do
17
23
  ctx = EM::ZeroMQ::Context.new(1)
18
24
 
@@ -21,16 +27,15 @@ EM.run do
21
27
  push_socket2 = ctx.bind( ZMQ::PUSH, 'ipc:///tmp/a')
22
28
  push_socket3 = ctx.bind( ZMQ::PUSH, 'inproc://simple_test')
23
29
 
24
- # setup one pull sockets listening to both push sockets
30
+ # setup one pull sockets listening to all push sockets
25
31
  pull_socket = ctx.connect( ZMQ::PULL, 'tcp://127.0.0.1:2091', EMTestPullHandler.new)
26
32
  pull_socket.connect('ipc:///tmp/a')
27
33
  pull_socket.connect('inproc://simple_test')
28
34
 
29
35
  n = 0
30
36
 
31
- # push_socket.hwm = 40
32
- # puts push_socket.hwm
33
- # puts pull_socket.hwm
37
+ push_socket1.hwm = 40
38
+ puts "HWM: #{push_socket1.hwm}"
34
39
 
35
40
  EM::PeriodicTimer.new(0.1) do
36
41
  puts '.'
@@ -39,3 +44,5 @@ EM.run do
39
44
  push_socket3.send_msg("p#{n += 1}_")
40
45
  end
41
46
  end
47
+
48
+ puts "Completed."
@@ -69,7 +69,6 @@ module EventMachine
69
69
  # all the previous parts were queued, send
70
70
  # the last one
71
71
  @socket.send_string(parts[-1], ZMQ::NOBLOCK)
72
- true
73
72
  else
74
73
  # error while sending the previous parts
75
74
  # register the socket for writability
@@ -143,8 +142,6 @@ module EventMachine
143
142
  @handler.on_writable(self)
144
143
  end
145
144
  end
146
- private
147
- # internal methods
148
145
  def readable?
149
146
  (@socket.getsockopt(ZMQ::EVENTS) & ZMQ::POLLIN) == ZMQ::POLLIN
150
147
  end
@@ -154,6 +151,10 @@ module EventMachine
154
151
  # ZMQ::EVENTS has issues in ZMQ HEAD, we'll ignore this till they're fixed
155
152
  # (@socket.getsockopt(ZMQ::EVENTS) & ZMQ::POLLOUT) == ZMQ::POLLOUT
156
153
  end
154
+
155
+ private
156
+
157
+ # internal methods
157
158
 
158
159
  def get_message
159
160
  msg = ZMQ::Message.new
@@ -7,8 +7,8 @@
7
7
  module EventMachine
8
8
  module ZeroMQ
9
9
  class Context
10
- READABLES = [ ZMQ::SUB, ZMQ::PULL, ZMQ::XREQ, ZMQ::XREP, ZMQ::REP, ZMQ::REQ ]
11
- WRITABLES = [ ZMQ::PUB, ZMQ::PUSH, ZMQ::XREQ, ZMQ::XREP, ZMQ::REP, ZMQ::REQ ]
10
+ READABLES = [ ZMQ::SUB, ZMQ::PULL, ZMQ::ROUTER, ZMQ::DEALER, ZMQ::REP, ZMQ::REQ ]
11
+ WRITABLES = [ ZMQ::PUB, ZMQ::PUSH, ZMQ::ROUTER, ZMQ::DEALER, ZMQ::REP, ZMQ::REQ ]
12
12
 
13
13
  def initialize(threads_or_context)
14
14
  if threads_or_context.is_a?(ZMQ::Context)
@@ -44,8 +44,9 @@ module EventMachine
44
44
  else
45
45
  socket.connect(address)
46
46
  end
47
-
48
- conn = EM.watch(socket.getsockopt(ZMQ::FD), EventMachine::ZeroMQ::Connection, socket, socket_type, address, handler)
47
+
48
+ fd = socket.getsockopt(ZMQ::FD)
49
+ conn = EM.watch(fd, EventMachine::ZeroMQ::Connection, socket, socket_type, address, handler)
49
50
 
50
51
  if READABLES.include?(socket_type)
51
52
  conn.register_readable
@@ -0,0 +1,52 @@
1
+ module RZMQCompat
2
+ class ZMQError < RuntimeError; end
3
+ class ZMQOperationFailed < ZMQError; end
4
+
5
+ def self.included(klass)
6
+ klass.instance_eval do
7
+ %w(getsockopt recv).each do |m|
8
+ alias_method :"#{m}_without_raise", m.to_sym
9
+ alias_method m.to_sym, :"#{m}_with_raise"
10
+ end
11
+ end
12
+ end
13
+
14
+ def getsockopt_with_raise(opt, *args)
15
+ arity = method(:getsockopt_without_raise).arity
16
+ if args.empty?
17
+ case arity
18
+ when 1
19
+ getsockopt_without_raise(opt)
20
+
21
+ when 2
22
+ ret = []
23
+ rc = getsockopt_without_raise(opt, ret)
24
+ unless ZMQ::Util.resultcode_ok?(rc)
25
+ raise ZMQOperationFailed, "getsockopt: #{ZMQ.errno}"
26
+ end
27
+
28
+ (ret.size == 1) ? ret[0] : ret
29
+
30
+ else
31
+ raise "Unsupported version of ffi-rzmq, getsockopt takes #{arity} arguments"
32
+ end
33
+
34
+ else
35
+ # just pass the call to the original method
36
+ getsockopt_without_raise(opt, *args)
37
+ end
38
+ end
39
+
40
+ def recv_with_raise(msg, flags = 0)
41
+ ret = recv_without_raise(msg, flags)
42
+ if (ret == true) || (ret == 0)
43
+ true
44
+ else
45
+ false
46
+ end
47
+ end
48
+
49
+
50
+ end
51
+
52
+ ZMQ::Socket.send(:include, RZMQCompat)
@@ -1,4 +1,4 @@
1
1
  # encoding: utf-8
2
2
  module EmZeromq
3
- VERSION = "0.2.1"
3
+ VERSION = "0.2.2"
4
4
  end
data/spec/context_spec.rb CHANGED
@@ -13,11 +13,11 @@ describe 'Context' do
13
13
 
14
14
  it 'can create socket' do
15
15
  EM::run do
16
- s1 = @ctx.bind(:xreq, 'tcp://127.0.0.1:5555')
17
- s2 = @ctx.bind('xreq', 'tcp://127.0.0.1:5556')
18
- s3 = @ctx.bind(ZMQ::XREQ, 'tcp://127.0.0.1:5557')
16
+ s1 = @ctx.bind(:router, 'tcp://127.0.0.1:5555')
17
+ s2 = @ctx.bind('router', 'tcp://127.0.0.1:5556')
18
+ s3 = @ctx.bind(ZMQ::ROUTER, 'tcp://127.0.0.1:5557')
19
19
 
20
- s1.instance_variable_get('@socket').name.should == 'XREQ'
20
+ s1.instance_variable_get('@socket').name.should == 'ROUTER'
21
21
  EM::stop_event_loop
22
22
  end
23
23
  end
@@ -0,0 +1,80 @@
1
+ require File.join(File.dirname(__FILE__), %w[spec_helper])
2
+
3
+ describe EventMachine::ZeroMQ do
4
+ class EMTestRouterHandler
5
+ attr_reader :received
6
+ def initialize
7
+ @received = []
8
+ end
9
+ def on_writable(socket)
10
+ end
11
+ def on_readable(socket, messages)
12
+ @received += messages
13
+ end
14
+ end
15
+
16
+ class EMTestDealerHandler
17
+ attr_reader :received
18
+ def initialize(&block)
19
+ @received = []
20
+ @on_writable_callback = block
21
+ end
22
+ def on_writable(socket)
23
+ @on_writable_callback.call(socket) if @on_writable_callback
24
+ end
25
+ def on_readable(socket, messages)
26
+ ident, delim, message = messages.map(&:copy_out_string)
27
+ ident.should == "dealer1"
28
+ @received += [ident, delim, message].map {|s| ZMQ::Message.new(s)}
29
+
30
+ socket.send_msg(ident, delim, "re:#{message}")
31
+ end
32
+ end
33
+
34
+ it "Should instantiate a connection given valid opts for Router/Dealer" do
35
+ router_conn = nil
36
+ run_reactor(1) do
37
+ router_conn = SPEC_CTX.bind(ZMQ::ROUTER, rand_addr, EMTestRouterHandler.new)
38
+ end
39
+ router_conn.should be_a(EventMachine::ZeroMQ::Connection)
40
+ end
41
+
42
+ describe "sending/receiving a single message via Router/Dealer" do
43
+ before(:all) do
44
+ results = {}
45
+ @test_message = test_message = "M#{rand(999)}"
46
+
47
+ run_reactor(0.5) do
48
+ results[:dealer_hndlr] = dealer_hndlr = EMTestDealerHandler.new
49
+ results[:router_hndlr] = router_hndlr = EMTestRouterHandler.new
50
+
51
+ addr = rand_addr
52
+ dealer_conn = SPEC_CTX.bind(ZMQ::DEALER, addr, dealer_hndlr, :identity => "dealer1")
53
+ router_conn = SPEC_CTX.connect(ZMQ::ROUTER, addr, router_hndlr, :identity => "router1")
54
+ router_conn.send_msg('x', test_message)
55
+
56
+ EM::Timer.new(0.1) do
57
+ results[:specs_ran] = true
58
+ end
59
+ end
60
+
61
+ @results = results
62
+ end
63
+
64
+ it "should run completely" do
65
+ @results[:specs_ran].should be_true
66
+ end
67
+
68
+ it "should receive the message intact on the dealer" do
69
+ @results[:dealer_hndlr].received.should_not be_empty
70
+ @results[:dealer_hndlr].received.last.should be_a(ZMQ::Message)
71
+ @results[:dealer_hndlr].received.last.copy_out_string.should == @test_message
72
+ end
73
+
74
+ it "the router should be echoed its original message" do
75
+ @results[:router_hndlr].received.should_not be_empty
76
+ @results[:router_hndlr].received.last.should be_a(ZMQ::Message)
77
+ @results[:router_hndlr].received.last.copy_out_string.should == "re:#{@test_message}"
78
+ end
79
+ end
80
+ end
metadata CHANGED
@@ -1,61 +1,78 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: em-zeromq
3
- version: !ruby/object:Gem::Version
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.2
4
5
  prerelease:
5
- version: 0.2.1
6
6
  platform: ruby
7
- authors:
7
+ authors:
8
8
  - Andrew Cholakian
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
-
13
- date: 2011-03-03 00:00:00 -08:00
14
- default_executable:
15
- dependencies:
16
- - !ruby/object:Gem::Dependency
12
+ date: 2011-11-27 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
17
15
  name: eventmachine
16
+ requirement: &7728660 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 1.0.0.beta.4
22
+ type: :runtime
18
23
  prerelease: false
19
- requirement: &id001 !ruby/object:Gem::Requirement
24
+ version_requirements: *7728660
25
+ - !ruby/object:Gem::Dependency
26
+ name: ffi
27
+ requirement: &7728080 !ruby/object:Gem::Requirement
20
28
  none: false
21
- requirements:
22
- - - ">="
23
- - !ruby/object:Gem::Version
24
- version: 1.0.0.beta.3
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: 1.0.0
25
33
  type: :runtime
26
- version_requirements: *id001
27
- - !ruby/object:Gem::Dependency
28
- name: ffi-rzmq
29
34
  prerelease: false
30
- requirement: &id002 !ruby/object:Gem::Requirement
35
+ version_requirements: *7728080
36
+ - !ruby/object:Gem::Dependency
37
+ name: ffi-rzmq
38
+ requirement: &7727520 !ruby/object:Gem::Requirement
31
39
  none: false
32
- requirements:
33
- - - ">="
34
- - !ruby/object:Gem::Version
35
- version: 0.7.2
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ version: 0.9.0
36
44
  type: :runtime
37
- version_requirements: *id002
38
- - !ruby/object:Gem::Dependency
39
- name: rspec
40
45
  prerelease: false
41
- requirement: &id003 !ruby/object:Gem::Requirement
46
+ version_requirements: *7727520
47
+ - !ruby/object:Gem::Dependency
48
+ name: rspec
49
+ requirement: &7726580 !ruby/object:Gem::Requirement
42
50
  none: false
43
- requirements:
44
- - - ">="
45
- - !ruby/object:Gem::Version
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
46
54
  version: 2.5.0
47
55
  type: :development
48
- version_requirements: *id003
56
+ prerelease: false
57
+ version_requirements: *7726580
58
+ - !ruby/object:Gem::Dependency
59
+ name: rake
60
+ requirement: &7725760 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *7725760
49
69
  description: Low level event machine support for ZeroMQ
50
- email:
70
+ email:
51
71
  - andrew@andrewvc.com
52
72
  executables: []
53
-
54
73
  extensions: []
55
-
56
74
  extra_rdoc_files: []
57
-
58
- files:
75
+ files:
59
76
  - .bnsignore
60
77
  - .gitignore
61
78
  - Gemfile
@@ -67,40 +84,37 @@ files:
67
84
  - lib/em-zeromq.rb
68
85
  - lib/em-zeromq/connection.rb
69
86
  - lib/em-zeromq/context.rb
87
+ - lib/em-zeromq/rzmq_compat.rb
70
88
  - lib/em-zeromq/version.rb
71
89
  - spec/context_spec.rb
72
90
  - spec/pub_sub_spec.rb
73
91
  - spec/push_pull_spec.rb
92
+ - spec/router_dealer_spec.rb
74
93
  - spec/spec_helper.rb
75
- - spec/xreq_xrep_spec.rb
76
- has_rdoc: true
77
94
  homepage: https://github.com/andrewvc/em-zeromq
78
95
  licenses: []
79
-
80
96
  post_install_message:
81
- rdoc_options:
97
+ rdoc_options:
82
98
  - --main
83
99
  - README.md
84
- require_paths:
100
+ require_paths:
85
101
  - lib
86
- required_ruby_version: !ruby/object:Gem::Requirement
102
+ required_ruby_version: !ruby/object:Gem::Requirement
87
103
  none: false
88
- requirements:
89
- - - ">="
90
- - !ruby/object:Gem::Version
91
- version: "0"
92
- required_rubygems_version: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - ! '>='
106
+ - !ruby/object:Gem::Version
107
+ version: '0'
108
+ required_rubygems_version: !ruby/object:Gem::Requirement
93
109
  none: false
94
- requirements:
95
- - - ">="
96
- - !ruby/object:Gem::Version
97
- version: "0"
110
+ requirements:
111
+ - - ! '>='
112
+ - !ruby/object:Gem::Version
113
+ version: '0'
98
114
  requirements: []
99
-
100
115
  rubyforge_project: em-zeromq
101
- rubygems_version: 1.6.0
116
+ rubygems_version: 1.8.10
102
117
  signing_key:
103
118
  specification_version: 3
104
119
  summary: Low level event machine support for ZeroMQ
105
120
  test_files: []
106
-
@@ -1,77 +0,0 @@
1
- require File.join(File.dirname(__FILE__), %w[spec_helper])
2
-
3
- describe EventMachine::ZeroMQ do
4
- class EMTestXREQHandler
5
- attr_reader :received
6
- def initialize
7
- @received = []
8
- end
9
- def on_readable(socket, messages)
10
- @received += messages
11
- end
12
- end
13
-
14
- class EMTestXREPHandler
15
- attr_reader :received
16
- def initialize(&block)
17
- @received = []
18
- @on_writable_callback = block
19
- end
20
- def on_writable(socket)
21
- @on_writable_callback.call(socket) if @on_writable_callback
22
- end
23
- def on_readable(socket, messages)
24
- ident, delim, message = messages.map(&:copy_out_string)
25
- ident.should == "req1"
26
- @received += [ident, delim, message].map {|s| ZMQ::Message.new(s)}
27
-
28
- socket.send_msg(ident, delim, "re:#{message}")
29
- end
30
- end
31
-
32
- it "Should instantiate a connection given valid opts" do
33
- xreq_conn = nil
34
- run_reactor(1) do
35
- xreq_conn = SPEC_CTX.bind(ZMQ::XREQ, rand_addr, EMTestXREQHandler.new)
36
- end
37
- xreq_conn.should be_a(EventMachine::ZeroMQ::Connection)
38
- end
39
-
40
- describe "sending/receiving a single message via Xreq/Xrep" do
41
- before(:all) do
42
- results = {}
43
- @test_message = test_message = "M#{rand(999)}"
44
-
45
- run_reactor(0.5) do
46
- results[:xrep_hndlr] = xrep_hndlr = EMTestXREPHandler.new
47
- results[:xreq_hndlr] = xreq_hndlr = EMTestXREQHandler.new
48
- xreq_conn = SPEC_CTX.connect(ZMQ::XREQ, rand_addr, xreq_hndlr, :identity => "req1")
49
- xreq_conn.send_msg('', test_message)
50
-
51
- xrep_conn = SPEC_CTX.bind(ZMQ::XREP, xreq_conn.address, xrep_hndlr, :identity => "rep1")
52
-
53
- EM::Timer.new(0.1) do
54
- results[:specs_ran] = true
55
- end
56
- end
57
-
58
- @results = results
59
- end
60
-
61
- it "should run completely" do
62
- @results[:specs_ran].should be_true
63
- end
64
-
65
- it "should receive the message intact on the xrep" do
66
- @results[:xrep_hndlr].received.should_not be_empty
67
- @results[:xrep_hndlr].received.last.should be_a(ZMQ::Message)
68
- @results[:xrep_hndlr].received.last.copy_out_string.should == @test_message
69
- end
70
-
71
- it "the xreq should be echoed its original message" do
72
- @results[:xreq_hndlr].received.should_not be_empty
73
- @results[:xreq_hndlr].received.last.should be_a(ZMQ::Message)
74
- @results[:xreq_hndlr].received.last.copy_out_string.should == "re:#{@test_message}"
75
- end
76
- end
77
- end