toq 0.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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +1 -0
- data/LICENSE.md +29 -0
- data/README.md +68 -0
- data/Rakefile +53 -0
- data/lib/toq/client/handler.rb +165 -0
- data/lib/toq/client.rb +249 -0
- data/lib/toq/exceptions.rb +152 -0
- data/lib/toq/message.rb +63 -0
- data/lib/toq/protocol.rb +101 -0
- data/lib/toq/proxy.rb +84 -0
- data/lib/toq/request.rb +59 -0
- data/lib/toq/response.rb +63 -0
- data/lib/toq/server/handler.rb +144 -0
- data/lib/toq/server.rb +276 -0
- data/lib/toq/version.rb +13 -0
- data/lib/toq.rb +13 -0
- data/spec/pems/cacert.pem +37 -0
- data/spec/pems/client/cert.pem +37 -0
- data/spec/pems/client/foo-cert.pem +39 -0
- data/spec/pems/client/foo-key.pem +51 -0
- data/spec/pems/client/key.pem +51 -0
- data/spec/pems/server/cert.pem +37 -0
- data/spec/pems/server/key.pem +51 -0
- data/spec/servers/basic.rb +3 -0
- data/spec/servers/server.rb +83 -0
- data/spec/servers/unix_socket.rb +8 -0
- data/spec/servers/with_ssl_primitives.rb +11 -0
- data/spec/spec_helper.rb +39 -0
- data/spec/toq/client_spec.rb +397 -0
- data/spec/toq/exceptions_spec.rb +77 -0
- data/spec/toq/message_spec.rb +47 -0
- data/spec/toq/proxy_spec.rb +99 -0
- data/spec/toq/request_spec.rb +53 -0
- data/spec/toq/response_spec.rb +49 -0
- data/spec/toq/server_spec.rb +129 -0
- metadata +116 -0
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'ap'
|
2
|
+
require_relative '../../lib/toq'
|
3
|
+
|
4
|
+
def pems_path
|
5
|
+
File.expand_path( File.dirname( __FILE__ ) + '/../' )
|
6
|
+
end
|
7
|
+
|
8
|
+
def rpc_opts
|
9
|
+
{
|
10
|
+
host: '127.0.0.1',
|
11
|
+
port: 7331,
|
12
|
+
token: 'superdupersecret',
|
13
|
+
serializer: Marshal,
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
def rpc_opts_with_socket
|
18
|
+
opts = rpc_opts
|
19
|
+
opts.delete( :host )
|
20
|
+
opts.delete( :port )
|
21
|
+
|
22
|
+
opts.merge( socket: '/tmp/arachni-rpc-test' )
|
23
|
+
end
|
24
|
+
|
25
|
+
def rpc_opts_with_ssl_primitives
|
26
|
+
rpc_opts.merge(
|
27
|
+
port: 7332,
|
28
|
+
ssl_ca: pems_path + '/pems/cacert.pem',
|
29
|
+
ssl_pkey: pems_path + '/pems/client/key.pem',
|
30
|
+
ssl_cert: pems_path + '/pems/client/cert.pem'
|
31
|
+
)
|
32
|
+
end
|
33
|
+
|
34
|
+
def rpc_opts_with_invalid_ssl_primitives
|
35
|
+
rpc_opts_with_ssl_primitives.merge(
|
36
|
+
ssl_pkey: pems_path + '/pems/client/foo-key.pem',
|
37
|
+
ssl_cert: pems_path + '/pems/client/foo-cert.pem'
|
38
|
+
)
|
39
|
+
end
|
40
|
+
|
41
|
+
def rpc_opts_with_mixed_ssl_primitives
|
42
|
+
rpc_opts_with_ssl_primitives.merge(
|
43
|
+
ssl_pkey: pems_path + '/pems/client/key.pem',
|
44
|
+
ssl_cert: pems_path + '/pems/client/foo-cert.pem'
|
45
|
+
)
|
46
|
+
end
|
47
|
+
|
48
|
+
class Parent
|
49
|
+
def foo( arg )
|
50
|
+
arg
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
class Test < Parent
|
55
|
+
|
56
|
+
# In order to make inherited methods accessible you've got to explicitly
|
57
|
+
# make them public.
|
58
|
+
private :foo
|
59
|
+
public :foo
|
60
|
+
|
61
|
+
def delay( arg, &block )
|
62
|
+
Raktr.global.delay( 1 ) { block.call( arg ) }
|
63
|
+
end
|
64
|
+
|
65
|
+
def exception
|
66
|
+
fail
|
67
|
+
end
|
68
|
+
|
69
|
+
def defer( arg, &block )
|
70
|
+
Thread.new do
|
71
|
+
block.call( arg )
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
def start_server( opts, do_not_start = false )
|
78
|
+
server = Toq::Server.new( opts )
|
79
|
+
server.add_async_check { |method| method.parameters.flatten.include? :block }
|
80
|
+
server.add_handler( 'test', Test.new )
|
81
|
+
server.run if !do_not_start
|
82
|
+
server
|
83
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require_relative 'server'
|
2
|
+
|
3
|
+
cwd = File.expand_path( File.dirname( __FILE__ ) )
|
4
|
+
opts = rpc_opts.merge(
|
5
|
+
port: 7332,
|
6
|
+
ssl_ca: cwd + '/../pems/cacert.pem',
|
7
|
+
ssl_pkey: cwd + '/../pems/server/key.pem',
|
8
|
+
ssl_cert: cwd + '/../pems/server/cert.pem'
|
9
|
+
)
|
10
|
+
|
11
|
+
start_server( opts )
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'ap'
|
2
|
+
require 'timeout'
|
3
|
+
require_relative '../lib/toq'
|
4
|
+
require_relative 'servers/server'
|
5
|
+
|
6
|
+
def cwd
|
7
|
+
File.expand_path( File.dirname( __FILE__ ) )
|
8
|
+
end
|
9
|
+
|
10
|
+
def start_client( opts )
|
11
|
+
Toq::Client.new( opts )
|
12
|
+
end
|
13
|
+
|
14
|
+
def quiet_spawn( file )
|
15
|
+
path = File.join( File.expand_path( File.dirname( __FILE__ ) ), 'servers', "#{file}.rb" )
|
16
|
+
Process.spawn RbConfig.ruby, path#, out: '/dev/null'
|
17
|
+
end
|
18
|
+
|
19
|
+
server_pids = []
|
20
|
+
RSpec.configure do |config|
|
21
|
+
config.color = true
|
22
|
+
config.add_formatter :documentation
|
23
|
+
|
24
|
+
config.before( :suite ) do
|
25
|
+
File.delete( '/tmp/arachni-rpc-test' ) rescue nil
|
26
|
+
|
27
|
+
files = %w(basic with_ssl_primitives)
|
28
|
+
files << 'unix_socket' if Raktr.supports_unix_sockets?
|
29
|
+
|
30
|
+
files.each do |name|
|
31
|
+
server_pids << quiet_spawn( name ).tap { |pid| Process.detach( pid ) }
|
32
|
+
end
|
33
|
+
sleep 5
|
34
|
+
end
|
35
|
+
|
36
|
+
config.after( :suite ) do
|
37
|
+
server_pids.each { |pid| Process.kill( 'KILL', pid ) }
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,397 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Toq::Client do
|
4
|
+
|
5
|
+
def wait
|
6
|
+
Raktr.global.wait rescue Raktr::Error::NotRunning
|
7
|
+
end
|
8
|
+
|
9
|
+
before(:each) do
|
10
|
+
if Raktr.global.running?
|
11
|
+
Raktr.stop
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
let(:arguments) do
|
16
|
+
[
|
17
|
+
'one',
|
18
|
+
2,
|
19
|
+
{ three: 3 },
|
20
|
+
[ 4 ]
|
21
|
+
]
|
22
|
+
end
|
23
|
+
let(:reactor) { Raktr.global }
|
24
|
+
let(:handler) { 'test' }
|
25
|
+
let(:remote_method) { 'foo' }
|
26
|
+
let(:options) { rpc_opts }
|
27
|
+
subject do
|
28
|
+
start_client( options )
|
29
|
+
end
|
30
|
+
|
31
|
+
def call( &block )
|
32
|
+
subject.call( "#{handler}.#{remote_method}", arguments, &block )
|
33
|
+
end
|
34
|
+
|
35
|
+
describe '#initialize' do
|
36
|
+
let(:options) { rpc_opts.merge( role: :client ) }
|
37
|
+
|
38
|
+
it 'assigns instance options (including :role)' do
|
39
|
+
subject.opts.should == options
|
40
|
+
end
|
41
|
+
|
42
|
+
context 'when passed no connection information' do
|
43
|
+
it 'raises ArgumentError' do
|
44
|
+
begin
|
45
|
+
described_class.new({})
|
46
|
+
rescue => e
|
47
|
+
e.should be_kind_of ArgumentError
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe 'option' do
|
53
|
+
describe :socket, if: Raktr.supports_unix_sockets? do
|
54
|
+
let(:options) { rpc_opts_with_socket }
|
55
|
+
|
56
|
+
it 'connects to it' do
|
57
|
+
call.should == arguments
|
58
|
+
end
|
59
|
+
|
60
|
+
context 'when under heavy load' do
|
61
|
+
it 'retains stability and consistency' do
|
62
|
+
n = 10_000
|
63
|
+
cnt = 0
|
64
|
+
|
65
|
+
mismatches = []
|
66
|
+
|
67
|
+
n.times do |i|
|
68
|
+
arg = 'a' * i
|
69
|
+
subject.call( "#{handler}.#{remote_method}", arg ) do |res|
|
70
|
+
cnt += 1
|
71
|
+
mismatches << [i, arg, res] if arg != res
|
72
|
+
Raktr.stop if cnt == n || mismatches.any?
|
73
|
+
end
|
74
|
+
end
|
75
|
+
wait
|
76
|
+
|
77
|
+
cnt.should > 0
|
78
|
+
mismatches.should be_empty
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
context 'and connecting to a non-existent server' do
|
83
|
+
let(:options) { rpc_opts_with_socket.merge( socket: '/' ) }
|
84
|
+
|
85
|
+
it "returns #{Toq::Exceptions::ConnectionError}" do
|
86
|
+
response = nil
|
87
|
+
call do |res|
|
88
|
+
response = res
|
89
|
+
Raktr.stop
|
90
|
+
end
|
91
|
+
wait
|
92
|
+
|
93
|
+
response.should be_rpc_connection_error
|
94
|
+
response.should be_kind_of Toq::Exceptions::ConnectionError
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
context 'when passed an invalid socket path' do
|
99
|
+
it 'raises ArgumentError' do
|
100
|
+
begin
|
101
|
+
described_class.new( socket: 'blah' )
|
102
|
+
rescue => e
|
103
|
+
e.should be_kind_of ArgumentError
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
context 'when passed a host but not a port' do
|
111
|
+
it 'raises ArgumentError' do
|
112
|
+
begin
|
113
|
+
described_class.new( host: 'test' )
|
114
|
+
rescue => e
|
115
|
+
e.should be_kind_of ArgumentError
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
context 'when passed a port but not a host' do
|
121
|
+
it 'raises ArgumentError' do
|
122
|
+
begin
|
123
|
+
described_class.new( port: 9999 )
|
124
|
+
rescue => e
|
125
|
+
e.should be_kind_of ArgumentError
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
context 'when passed an invalid port' do
|
131
|
+
it 'raises ArgumentError' do
|
132
|
+
begin
|
133
|
+
described_class.new( host: 'tt', port: 'blah' )
|
134
|
+
rescue => e
|
135
|
+
e.should be_kind_of ArgumentError
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
describe '#call' do
|
142
|
+
context 'when calling a remote method that delays its results' do
|
143
|
+
let(:remote_method) { 'delay' }
|
144
|
+
|
145
|
+
it 'it supports it' do
|
146
|
+
call.should == arguments
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
context 'when calling a remote method that defers its results' do
|
151
|
+
let(:remote_method) { 'defer' }
|
152
|
+
|
153
|
+
it 'it supports it' do
|
154
|
+
call.should == arguments
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
context 'when under heavy load' do
|
159
|
+
it 'retains stability and consistency' do
|
160
|
+
n = 10_000
|
161
|
+
cnt = 0
|
162
|
+
|
163
|
+
mismatches = []
|
164
|
+
|
165
|
+
n.times do |i|
|
166
|
+
arg = 'a' * i
|
167
|
+
subject.call( "#{handler}.#{remote_method}", arg ) do |res|
|
168
|
+
cnt += 1
|
169
|
+
mismatches << [i, arg, res] if arg != res
|
170
|
+
Raktr.stop if cnt == n || mismatches.any?
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
wait
|
175
|
+
|
176
|
+
cnt.should > 0
|
177
|
+
mismatches.should be_empty
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
context 'when using Threads' do
|
182
|
+
it 'should be able to perform synchronous calls' do
|
183
|
+
arguments.should == call
|
184
|
+
end
|
185
|
+
|
186
|
+
it 'should be able to perform asynchronous calls' do
|
187
|
+
response = nil
|
188
|
+
call do |res|
|
189
|
+
response = res
|
190
|
+
Raktr.stop
|
191
|
+
end
|
192
|
+
wait
|
193
|
+
|
194
|
+
response.should == arguments
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
context 'when run inside the Reactor loop' do
|
199
|
+
it 'should be able to perform asynchronous calls' do
|
200
|
+
response = nil
|
201
|
+
|
202
|
+
Raktr.stop
|
203
|
+
reactor.run do
|
204
|
+
call do |res|
|
205
|
+
response = res
|
206
|
+
Raktr.stop
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
response.should == arguments
|
211
|
+
end
|
212
|
+
|
213
|
+
it 'should not be able to perform synchronous calls' do
|
214
|
+
exception = nil
|
215
|
+
|
216
|
+
Raktr.stop
|
217
|
+
reactor.run do
|
218
|
+
begin
|
219
|
+
call
|
220
|
+
rescue => e
|
221
|
+
exception = e
|
222
|
+
Raktr.stop
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
exception.should be_kind_of RuntimeError
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
context 'when performing an asynchronous call' do
|
231
|
+
context 'and connecting to a non-existent server' do
|
232
|
+
let(:options) { rpc_opts.merge( host: 'dddd', port: 999339 ) }
|
233
|
+
|
234
|
+
it "returns #{Toq::Exceptions::ConnectionError}" do
|
235
|
+
response = nil
|
236
|
+
call do |res|
|
237
|
+
response = res
|
238
|
+
Raktr.stop
|
239
|
+
end
|
240
|
+
wait
|
241
|
+
|
242
|
+
response.should be_rpc_connection_error
|
243
|
+
response.should be_kind_of Toq::Exceptions::ConnectionError
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
context 'and requesting a non-existent object' do
|
248
|
+
let(:handler) { 'bar' }
|
249
|
+
|
250
|
+
it "returns #{Toq::Exceptions::InvalidObject}" do
|
251
|
+
response = nil
|
252
|
+
|
253
|
+
call do |res|
|
254
|
+
response = res
|
255
|
+
Raktr.stop
|
256
|
+
end
|
257
|
+
wait
|
258
|
+
|
259
|
+
response.should be_rpc_invalid_object_error
|
260
|
+
response.should be_kind_of Toq::Exceptions::InvalidObject
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
context 'and requesting a non-public method' do
|
265
|
+
let(:remote_method) { 'bar' }
|
266
|
+
|
267
|
+
it "returns #{Toq::Exceptions::InvalidMethod}" do
|
268
|
+
response = nil
|
269
|
+
|
270
|
+
call do |res|
|
271
|
+
response = res
|
272
|
+
Raktr.stop
|
273
|
+
end
|
274
|
+
wait
|
275
|
+
|
276
|
+
response.should be_rpc_invalid_method_error
|
277
|
+
response.should be_kind_of Toq::Exceptions::InvalidMethod
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
context 'and there is a remote exception' do
|
282
|
+
let(:remote_method) { :exception }
|
283
|
+
|
284
|
+
it "returns #{Toq::Exceptions::RemoteException}" do
|
285
|
+
response = nil
|
286
|
+
call do |res|
|
287
|
+
response = res
|
288
|
+
Raktr.stop
|
289
|
+
end
|
290
|
+
wait
|
291
|
+
|
292
|
+
response.should be_rpc_remote_exception
|
293
|
+
response.should be_kind_of Toq::Exceptions::RemoteException
|
294
|
+
end
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
298
|
+
context 'when performing a synchronous call' do
|
299
|
+
context 'and connecting to a non-existent server' do
|
300
|
+
let(:options) { rpc_opts.merge( host: 'dddd', port: 999339 ) }
|
301
|
+
|
302
|
+
it "raises #{Toq::Exceptions::ConnectionError}" do
|
303
|
+
begin
|
304
|
+
call
|
305
|
+
rescue => e
|
306
|
+
e.rpc_connection_error?.should be_true
|
307
|
+
e.should be_kind_of Toq::Exceptions::ConnectionError
|
308
|
+
end
|
309
|
+
end
|
310
|
+
end
|
311
|
+
|
312
|
+
context 'and requesting a non-existent object' do
|
313
|
+
let(:handler) { 'bar' }
|
314
|
+
|
315
|
+
it "raises #{Toq::Exceptions::InvalidObject}" do
|
316
|
+
begin
|
317
|
+
call
|
318
|
+
rescue => e
|
319
|
+
e.rpc_invalid_object_error?.should be_true
|
320
|
+
e.should be_kind_of Toq::Exceptions::InvalidObject
|
321
|
+
end
|
322
|
+
end
|
323
|
+
end
|
324
|
+
|
325
|
+
context 'and requesting a non-public method' do
|
326
|
+
let(:remote_method) { 'bar' }
|
327
|
+
|
328
|
+
it "raises #{Toq::Exceptions::InvalidMethod}" do
|
329
|
+
begin
|
330
|
+
call
|
331
|
+
rescue => e
|
332
|
+
e.rpc_invalid_method_error?.should be_true
|
333
|
+
e.should be_kind_of Toq::Exceptions::InvalidMethod
|
334
|
+
end
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
338
|
+
context 'and there is a remote exception' do
|
339
|
+
let(:remote_method) { :exception }
|
340
|
+
|
341
|
+
it "raises #{Toq::Exceptions::RemoteException}" do
|
342
|
+
begin
|
343
|
+
call
|
344
|
+
rescue => e
|
345
|
+
e.rpc_remote_exception?.should be_true
|
346
|
+
e.should be_kind_of Toq::Exceptions::RemoteException
|
347
|
+
end
|
348
|
+
end
|
349
|
+
end
|
350
|
+
end
|
351
|
+
|
352
|
+
context 'when using valid SSL configuration' do
|
353
|
+
let(:options) { rpc_opts_with_ssl_primitives }
|
354
|
+
|
355
|
+
it 'should be able to establish a connection' do
|
356
|
+
call.should == arguments
|
357
|
+
end
|
358
|
+
end
|
359
|
+
|
360
|
+
context 'when using invalid SSL configuration' do
|
361
|
+
let(:options) { rpc_opts_with_invalid_ssl_primitives }
|
362
|
+
|
363
|
+
it 'should not be able to establish a connection' do
|
364
|
+
response = nil
|
365
|
+
|
366
|
+
Raktr.stop
|
367
|
+
reactor.run do
|
368
|
+
call do |res|
|
369
|
+
response = res
|
370
|
+
Raktr.stop
|
371
|
+
end
|
372
|
+
end
|
373
|
+
|
374
|
+
response.should be_rpc_connection_error
|
375
|
+
end
|
376
|
+
end
|
377
|
+
|
378
|
+
context 'when using mixed SSL configuration' do
|
379
|
+
let(:options) { rpc_opts_with_mixed_ssl_primitives }
|
380
|
+
|
381
|
+
it 'should not be able to establish a connection' do
|
382
|
+
response = nil
|
383
|
+
|
384
|
+
Raktr.stop
|
385
|
+
reactor.run do
|
386
|
+
call do |res|
|
387
|
+
response = res
|
388
|
+
Raktr.stop
|
389
|
+
end
|
390
|
+
end
|
391
|
+
|
392
|
+
response.should be_rpc_connection_error
|
393
|
+
end
|
394
|
+
end
|
395
|
+
end
|
396
|
+
|
397
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Toq::Exceptions do
|
4
|
+
|
5
|
+
describe '#rpc_exception?' do
|
6
|
+
context 'for RPC exceptions' do
|
7
|
+
subject { described_class::InvalidMethod.new.rpc_exception? }
|
8
|
+
it { should be_true }
|
9
|
+
end
|
10
|
+
|
11
|
+
context 'for other exceptions' do
|
12
|
+
subject { ::Exception.new.rpc_connection_error? }
|
13
|
+
it { should be_false }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe '#rpc_connection_error?' do
|
18
|
+
context 'for ConnectionError' do
|
19
|
+
subject { described_class::ConnectionError.new.rpc_connection_error? }
|
20
|
+
it { should be_true }
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'for other exceptions' do
|
24
|
+
subject { described_class::InvalidMethod.new.rpc_connection_error? }
|
25
|
+
it { should be_false }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe '#rpc_remote_exception?' do
|
30
|
+
context 'for RemoteException' do
|
31
|
+
subject { described_class::RemoteException.new.rpc_remote_exception? }
|
32
|
+
it { should be_true }
|
33
|
+
end
|
34
|
+
|
35
|
+
context 'for other exceptions' do
|
36
|
+
subject { described_class::InvalidMethod.new.rpc_remote_exception? }
|
37
|
+
it { should be_false }
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe '#rpc_invalid_object_error?' do
|
42
|
+
context 'for invalid object RPC exceptions' do
|
43
|
+
subject { described_class::InvalidObject.new.rpc_invalid_object_error? }
|
44
|
+
it { should be_true }
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'for other exceptions' do
|
48
|
+
subject { ::Exception.new.rpc_invalid_object_error? }
|
49
|
+
it { should be_false }
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe '#rpc_invalid_method_error?' do
|
54
|
+
context 'for invalid method RPC exceptions' do
|
55
|
+
subject { described_class::InvalidMethod.new.rpc_invalid_method_error? }
|
56
|
+
it { should be_true }
|
57
|
+
end
|
58
|
+
|
59
|
+
context 'for other exceptions' do
|
60
|
+
subject { ::Exception.new.rpc_invalid_method_error? }
|
61
|
+
it { should be_false }
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe '#rpc_invalid_token_error?' do
|
66
|
+
context 'for RPC exceptions' do
|
67
|
+
subject { described_class::InvalidToken.new.rpc_invalid_token_error? }
|
68
|
+
it { should be_true }
|
69
|
+
end
|
70
|
+
|
71
|
+
context 'for other exceptions' do
|
72
|
+
subject { ::Exception.new.rpc_invalid_token_error? }
|
73
|
+
it { should be_false }
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class MyMessage < Toq::Message
|
4
|
+
attr_accessor :foo
|
5
|
+
attr_accessor :boo
|
6
|
+
|
7
|
+
def transmit?( attr )
|
8
|
+
attr == :@boo
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe Toq::Message do
|
13
|
+
let(:options) { { foo: 'foo val', boo: 'boo val' }}
|
14
|
+
subject { MyMessage.new( options ) }
|
15
|
+
|
16
|
+
describe '#initialize' do
|
17
|
+
it 'sets attributes' do
|
18
|
+
subject.foo == options[:foo]
|
19
|
+
subject.boo == options[:boo]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe '#merge!' do
|
24
|
+
it 'assigns the attribute values of the provided object to self' do
|
25
|
+
opts = { foo: 'my foo' }
|
26
|
+
my_msg = MyMessage.new( opts )
|
27
|
+
|
28
|
+
subject.merge!( my_msg )
|
29
|
+
|
30
|
+
subject.foo == opts[:foo]
|
31
|
+
subject.boo == options[:boo]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe '#prepare_for_tx' do
|
36
|
+
it 'converts self into a hash' do
|
37
|
+
subject.prepare_for_tx.class.should == Hash
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'skips attributes based on #transmit?' do
|
41
|
+
subject.prepare_for_tx.should include 'boo'
|
42
|
+
subject.prepare_for_tx.should_not include 'callback_id'
|
43
|
+
subject.prepare_for_tx.should_not include 'foo'
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|