arachni-rpc 0.1.3 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,77 @@
1
+ require 'spec_helper'
2
+
3
+ describe Arachni::RPC::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 < Arachni::RPC::Message
4
+ attr_accessor :foo
5
+ attr_accessor :boo
6
+
7
+ def transmit?( attr )
8
+ attr == :@boo
9
+ end
10
+ end
11
+
12
+ describe Arachni::RPC::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
@@ -0,0 +1,99 @@
1
+ require 'spec_helper'
2
+
3
+ class Translator < Arachni::RPC::Proxy
4
+
5
+ translate :foo do |response|
6
+ response.map(&:to_s)
7
+ end
8
+
9
+ translate :delay do |response, arguments|
10
+ [arguments, response.map(&:to_s)]
11
+ end
12
+
13
+ end
14
+
15
+ describe Arachni::RPC::Proxy do
16
+
17
+ def wait
18
+ Arachni::Reactor.global.wait rescue Arachni::Reactor::Error::NotRunning
19
+ end
20
+
21
+ before(:each) do
22
+ if Arachni::Reactor.global.running?
23
+ Arachni::Reactor.stop
24
+ end
25
+
26
+ Arachni::Reactor.global.run_in_thread
27
+ end
28
+
29
+ let(:translated_arguments) do
30
+ arguments.map(&:to_s)
31
+ end
32
+ let(:arguments) do
33
+ [
34
+ 'one',
35
+ 2,
36
+ { three: 3 },
37
+ [ 4 ]
38
+ ]
39
+ end
40
+ let(:reactor) { Arachni::Reactor.global }
41
+ let(:client) { start_client( rpc_opts ) }
42
+ let(:handler) { 'test' }
43
+ let(:translator) { Translator.new( client, handler ) }
44
+ subject do
45
+ Arachni::RPC::Proxy.new( client, handler )
46
+ end
47
+
48
+ it 'forwards synchronous calls' do
49
+ subject.foo( arguments ).should == arguments
50
+ end
51
+
52
+ it 'forwards synchronous calls' do
53
+ response = nil
54
+ subject.foo( arguments ) do |res|
55
+ response = res
56
+ Arachni::Reactor.stop
57
+ end
58
+ wait
59
+
60
+ response.should == arguments
61
+ end
62
+
63
+ describe '.translate' do
64
+ context 'when a synchronous call' do
65
+ context 'does not return an exception' do
66
+ it 'returns the translated result' do
67
+ translator.foo( arguments ).should == translated_arguments
68
+ end
69
+ end
70
+
71
+ context 'returns an exception' do
72
+ it 'returns the exception'
73
+ end
74
+ end
75
+
76
+ context 'when an asynchronous call' do
77
+ context 'does not result in an exception' do
78
+ it 'calls the block with the translated result' do
79
+ response = nil
80
+ translator.foo( arguments ) do |res|
81
+ response = res
82
+ Arachni::Reactor.stop
83
+ end
84
+ wait
85
+
86
+ response.should == translated_arguments
87
+ end
88
+ end
89
+
90
+ context 'results in an exception' do
91
+ it 'calls the block with the exception'
92
+ end
93
+ end
94
+
95
+ it 'passes the method arguments to the translator' do
96
+ translator.delay( arguments ).should == [arguments, translated_arguments]
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,53 @@
1
+ require 'spec_helper'
2
+
3
+ describe Arachni::RPC::Request do
4
+ subject { described_class.new }
5
+
6
+ describe '#message' do
7
+ it 'should be an accessor' do
8
+ subject.message = 'test'
9
+ subject.message.should == 'test'
10
+ end
11
+ end
12
+
13
+ describe '#args' do
14
+ it 'should be an accessor' do
15
+ subject.args = %w(test)
16
+ subject.args.should == %w(test)
17
+ end
18
+ end
19
+
20
+ describe '#token' do
21
+ it 'should be an accessor' do
22
+ subject.token = 'blah'
23
+ subject.token.should == 'blah'
24
+ end
25
+ end
26
+
27
+ describe '#callback' do
28
+ it 'should be an accessor' do
29
+ called = false
30
+ subject.callback = proc { called = true }
31
+ subject.callback.call
32
+ called.should be_true
33
+ end
34
+ end
35
+
36
+ describe '#prepare_for_tx' do
37
+ it 'should convert the request to a hash ready for transmission' do
38
+ subject.prepare_for_tx.should be_empty
39
+
40
+ described_class.new(
41
+ message: 'obj.method',
42
+ args: %w(test),
43
+ token: 'mytoken',
44
+ callback: proc{}
45
+ ).prepare_for_tx.should =={
46
+ 'args' => %w(test),
47
+ 'message' => 'obj.method',
48
+ 'token' => 'mytoken'
49
+ }
50
+ end
51
+ end
52
+
53
+ end
@@ -0,0 +1,49 @@
1
+ require 'spec_helper'
2
+
3
+ describe Arachni::RPC::Response do
4
+ subject { described_class.new }
5
+
6
+ describe '#obj' do
7
+ it 'should be an accessor' do
8
+ subject.obj = 'test'
9
+ subject.obj.should == 'test'
10
+ end
11
+ end
12
+
13
+ describe '#exception' do
14
+ it 'should be an accessor' do
15
+ subject.exception = 'test'
16
+ subject.exception.should == 'test'
17
+ end
18
+ end
19
+
20
+ describe '#exception?' do
21
+ context 'when #exception is not set' do
22
+ it 'returns false' do
23
+ subject.exception?.should be_false
24
+ end
25
+ end
26
+
27
+ context 'when #exception is set' do
28
+ it 'returns true' do
29
+ subject.exception = 'stuff'
30
+ subject.exception?.should be_true
31
+ end
32
+ end
33
+ end
34
+
35
+ describe '#async?' do
36
+ context 'by default' do
37
+ it 'should return false' do
38
+ subject.async?.should be_false
39
+ end
40
+ end
41
+
42
+ context 'after #async!' do
43
+ it 'should return false' do
44
+ subject.async!
45
+ subject.async?.should be_true
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,129 @@
1
+ require 'spec_helper'
2
+
3
+ class Arachni::RPC::Server
4
+ public :async?, :async_check, :object_exist?, :public_method?
5
+ attr_accessor :proxy
6
+ end
7
+
8
+ describe Arachni::RPC::Server do
9
+ let(:options) { rpc_opts.merge( port: 7333 ) }
10
+ subject { start_server( options, true ) }
11
+
12
+ describe '#initialize' do
13
+ it 'should be able to properly setup class options' do
14
+ subject.opts.should == options
15
+ end
16
+
17
+ context 'when passed no connection information' do
18
+ it 'raises ArgumentError' do
19
+ begin
20
+ described_class.new({})
21
+ rescue => e
22
+ e.should be_kind_of ArgumentError
23
+ end
24
+ end
25
+ end
26
+
27
+ context 'when passed a host but not a port' do
28
+ it 'raises ArgumentError' do
29
+ begin
30
+ described_class.new( host: 'test' )
31
+ rescue => e
32
+ e.should be_kind_of ArgumentError
33
+ end
34
+ end
35
+ end
36
+
37
+ context 'when passed a port but not a host' do
38
+ it 'raises ArgumentError' do
39
+ begin
40
+ described_class.new( port: 9999 )
41
+ rescue => e
42
+ e.should be_kind_of ArgumentError
43
+ end
44
+ end
45
+ end
46
+
47
+ context 'when passed an invalid port' do
48
+ it 'raises ArgumentError' do
49
+ begin
50
+ described_class.new( host: 'tt', port: 'blah' )
51
+ rescue => e
52
+ e.should be_kind_of ArgumentError
53
+ end
54
+ end
55
+ end
56
+ end
57
+
58
+ it 'retains the supplied token' do
59
+ subject.token.should == options[:token]
60
+ end
61
+
62
+ it 'has a Logger' do
63
+ subject.logger.class.should == ::Logger
64
+ end
65
+
66
+ describe '#alive?' do
67
+ it 'returns true' do
68
+ subject.should be_alive
69
+ end
70
+ end
71
+
72
+ describe '#async?' do
73
+ context 'when a method is async' do
74
+ it 'returns true' do
75
+ subject.async?( 'test', 'delay' ).should be_true
76
+ end
77
+ end
78
+
79
+ context 'when a method is sync' do
80
+ it 'returns false' do
81
+ subject.async?( 'test', 'foo' ).should be_false
82
+ end
83
+ end
84
+ end
85
+
86
+ describe '#async_check' do
87
+ context 'when a method is async' do
88
+ it 'returns true' do
89
+ subject.async_check( Test.new.method( :delay ) ).should be_true
90
+ end
91
+ end
92
+
93
+ context 'when a method is sync' do
94
+ it 'returns false' do
95
+ subject.async_check( Test.new.method( :foo ) ).should be_false
96
+ end
97
+ end
98
+ end
99
+
100
+ describe '#object_exist?' do
101
+ context 'when an object exists' do
102
+ it 'returns true' do
103
+ subject.object_exist?( 'test' ).should be_true
104
+ end
105
+ end
106
+
107
+ context 'when an object does not exist' do
108
+ it 'returns false' do
109
+ subject.object_exist?( 'foo' ).should be_false
110
+ end
111
+ end
112
+ end
113
+
114
+ describe '#public_method?' do
115
+ context 'when a method is public' do
116
+ it 'returns true' do
117
+ subject.public_method?( 'test', 'foo' ).should be_true
118
+ end
119
+ end
120
+
121
+ context 'when a method is non-existent or not public' do
122
+ it 'returns false' do
123
+ subject.public_method?( 'test', 'bar' ).should be_false
124
+ end
125
+ end
126
+ end
127
+
128
+ end
129
+