rjr 0.18.2 → 0.19.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Rakefile +2 -0
- data/bin/rjr-client +16 -9
- data/bin/rjr-server +2 -1
- data/examples/client.rb +21 -19
- data/examples/server.rb +1 -1
- data/examples/structured_server.rb +1 -0
- data/examples/tcp.rb +1 -0
- data/lib/rjr/common.rb +1 -226
- data/lib/rjr/core_ext.rb +63 -0
- data/lib/rjr/dispatcher.rb +75 -219
- data/lib/rjr/messages.rb +8 -0
- data/lib/rjr/messages/compressed.rb +264 -0
- data/lib/rjr/messages/notification.rb +95 -0
- data/lib/rjr/messages/request.rb +99 -0
- data/lib/rjr/messages/response.rb +128 -0
- data/lib/rjr/node.rb +100 -97
- data/lib/rjr/node_callback.rb +43 -0
- data/lib/rjr/nodes/amqp.rb +12 -11
- data/lib/rjr/nodes/easy.rb +4 -4
- data/lib/rjr/nodes/local.rb +13 -12
- data/lib/rjr/nodes/multi.rb +1 -1
- data/lib/rjr/nodes/tcp.rb +15 -13
- data/lib/rjr/nodes/template.rb +4 -4
- data/lib/rjr/nodes/unix.rb +15 -13
- data/lib/rjr/nodes/web.rb +15 -14
- data/lib/rjr/nodes/ws.rb +12 -11
- data/lib/rjr/request.rb +128 -0
- data/lib/rjr/result.rb +75 -0
- data/lib/rjr/util/args.rb +145 -0
- data/lib/rjr/{em_adapter.rb → util/em_adapter.rb} +0 -0
- data/lib/rjr/util/handles_methods.rb +115 -0
- data/lib/rjr/util/has_messages.rb +50 -0
- data/lib/rjr/{inspect.rb → util/inspect.rb} +1 -1
- data/lib/rjr/util/json_parser.rb +101 -0
- data/lib/rjr/util/logger.rb +128 -0
- data/lib/rjr/{thread_pool.rb → util/thread_pool.rb} +2 -0
- data/lib/rjr/version.rb +1 -1
- data/site/jrw.js +1 -1
- data/specs/args_spec.rb +144 -0
- data/specs/dispatcher_spec.rb +399 -211
- data/specs/em_adapter_spec.rb +31 -18
- data/specs/handles_methods_spec.rb +154 -0
- data/specs/has_messages_spec.rb +54 -0
- data/specs/inspect_spec.rb +1 -1
- data/specs/json_parser_spec.rb +169 -0
- data/specs/messages/notification_spec.rb +59 -0
- data/specs/messages/request_spec.rb +66 -0
- data/specs/messages/response_spec.rb +94 -0
- data/specs/node_callbacks_spec.rb +47 -0
- data/specs/node_spec.rb +465 -56
- data/specs/request_spec.rb +147 -0
- data/specs/result_spec.rb +144 -0
- data/specs/thread_pool_spec.rb +1 -1
- metadata +41 -11
- data/lib/rjr/errors.rb +0 -23
- data/lib/rjr/message.rb +0 -351
- data/lib/rjr/semaphore.rb +0 -58
- data/specs/message_spec.rb +0 -229
data/specs/em_adapter_spec.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'thread'
|
2
|
-
require 'rjr/em_adapter'
|
2
|
+
require 'rjr/util/em_adapter'
|
3
3
|
|
4
4
|
module RJR
|
5
5
|
describe EMAdapter do
|
@@ -11,30 +11,43 @@ module RJR
|
|
11
11
|
@em.halt.join
|
12
12
|
end
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
14
|
+
describe "#start" do
|
15
|
+
it "should start the reactor" do
|
16
|
+
@em.start
|
17
|
+
@em.reactor_running?.should be_true
|
18
|
+
['sleep', 'run'].should include(@em.reactor_thread.status)
|
19
|
+
end
|
19
20
|
|
20
|
-
|
21
|
-
|
21
|
+
it "should only start the reactor once" do
|
22
|
+
@em.start
|
22
23
|
|
23
|
-
|
24
|
-
|
25
|
-
|
24
|
+
ot = @em.reactor_thread
|
25
|
+
@em.start
|
26
|
+
@em.reactor_thread.should == ot
|
27
|
+
end
|
26
28
|
end
|
27
29
|
|
28
|
-
|
29
|
-
|
30
|
+
describe "#stop" do
|
31
|
+
it "should halt the reactor" do
|
32
|
+
@em.start
|
30
33
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
34
|
+
@em.halt
|
35
|
+
@em.join
|
36
|
+
@em.reactor_running?.should be_false
|
37
|
+
@em.reactor_thread.should be_nil
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "#join" do
|
42
|
+
it "joins reactor thread" do
|
43
|
+
th = Object.new
|
44
|
+
th.should_receive(:join).twice # XXX also called in after block above
|
45
|
+
@em.instance_variable_set(:@reactor_thread, th)
|
46
|
+
@em.join
|
47
|
+
end
|
35
48
|
end
|
36
49
|
|
37
|
-
it "should
|
50
|
+
it "should forward all messages to eventmachine" do
|
38
51
|
@em.start
|
39
52
|
|
40
53
|
invoked = false
|
@@ -0,0 +1,154 @@
|
|
1
|
+
require 'rjr/util/handles_methods'
|
2
|
+
require 'rjr/dispatcher'
|
3
|
+
|
4
|
+
module RJR
|
5
|
+
class HandlesMethodsTest
|
6
|
+
include HandlesMethods
|
7
|
+
|
8
|
+
jr_method :method1
|
9
|
+
jr_method :method2, :method3
|
10
|
+
|
11
|
+
jr_method :method4, :custom
|
12
|
+
jr_method :method5, :method6, :custom
|
13
|
+
|
14
|
+
def custom
|
15
|
+
@foo
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe HandlesMethods do
|
20
|
+
before(:each) do
|
21
|
+
@handlers = HandlesMethodsTest.jr_handlers
|
22
|
+
HandlesMethodsTest.jr_handlers = Hash[@handlers] if !!@handlers
|
23
|
+
end
|
24
|
+
|
25
|
+
after(:each) do
|
26
|
+
HandlesMethodsTest.jr_handlers = @handlers
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "#extract_handler_method" do
|
30
|
+
context "args.last is a class method" do
|
31
|
+
it "returns args.last" do
|
32
|
+
result = HandlesMethodsTest.extract_handler_method([:method1, :custom])
|
33
|
+
result[0].should == :custom
|
34
|
+
end
|
35
|
+
|
36
|
+
it "returns argument list with args.last removed" do
|
37
|
+
result = HandlesMethodsTest.extract_handler_method([:method1, :custom])
|
38
|
+
result[1].should == [:method1]
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context "args.last is not a class method" do
|
43
|
+
it "returns :handle" do
|
44
|
+
result = HandlesMethodsTest.extract_handler_method([:method1])
|
45
|
+
result[0].should == :handle
|
46
|
+
end
|
47
|
+
|
48
|
+
it "returns argument list" do
|
49
|
+
result = HandlesMethodsTest.extract_handler_method([:method1])
|
50
|
+
result[1].should == [:method1]
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "#has_handler_for?" do
|
56
|
+
before(:each) do
|
57
|
+
HandlesMethodsTest.jr_handlers = {:handle => proc{}}
|
58
|
+
end
|
59
|
+
|
60
|
+
context "handler exists" do
|
61
|
+
it "returns true" do
|
62
|
+
HandlesMethodsTest.has_handler_for?(:handle).should be_true
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
context "handler does not exist" do
|
67
|
+
it "returns false" do
|
68
|
+
HandlesMethodsTest.has_handler_for?(:foobar).should be_false
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe "#handler_for" do
|
74
|
+
before(:each) do
|
75
|
+
HandlesMethodsTest.jr_handlers = {:custom => 'foobar'}
|
76
|
+
end
|
77
|
+
|
78
|
+
it "returns handler" do
|
79
|
+
HandlesMethodsTest.handler_for(:custom).should == 'foobar'
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
describe "#create_handler_for" do
|
84
|
+
it "store handler proc in handler registry" do
|
85
|
+
HandlesMethodsTest.create_handler_for(:foobar)
|
86
|
+
HandlesMethodsTest.jr_handlers[:foobar].should be_an_instance_of(Proc)
|
87
|
+
end
|
88
|
+
|
89
|
+
it "returns handler proc" do
|
90
|
+
HandlesMethodsTest.create_handler_for(:foobar).should ==
|
91
|
+
HandlesMethodsTest.jr_handlers[:foobar]
|
92
|
+
end
|
93
|
+
|
94
|
+
describe "handler" do
|
95
|
+
it "instantiates handler class" do
|
96
|
+
HandlesMethodsTest.should_receive(:new).and_call_original
|
97
|
+
HandlesMethodsTest.create_handler_for(:custom).call
|
98
|
+
end
|
99
|
+
|
100
|
+
it "sets local instance_variables on instance" do
|
101
|
+
@foo = 'bar'
|
102
|
+
inst = HandlesMethodsTest.new
|
103
|
+
HandlesMethodsTest.should_receive(:new).and_return(inst)
|
104
|
+
instance_exec &HandlesMethodsTest.create_handler_for(:custom)
|
105
|
+
inst.instance_variable_get(:@foo).should == 'bar'
|
106
|
+
end
|
107
|
+
|
108
|
+
it "invokes handler method with args" do
|
109
|
+
inst = HandlesMethodsTest.new
|
110
|
+
HandlesMethodsTest.should_receive(:new).twice.and_return(inst)
|
111
|
+
inst.should_receive(:custom).twice.with(42)
|
112
|
+
HandlesMethodsTest.create_handler_for(:custom).call 42
|
113
|
+
HandlesMethodsTest.jr_handlers[:custom].call 42
|
114
|
+
end
|
115
|
+
|
116
|
+
it "returns handler return value" do
|
117
|
+
@foo = 'bar'
|
118
|
+
instance_exec(&HandlesMethodsTest.create_handler_for(:custom)).should == @foo
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
describe "#jr_method" do
|
124
|
+
it "registers json-rpc methods for later evaluation" do
|
125
|
+
args = HandlesMethodsTest.instance_variable_get(:@jr_method_args)
|
126
|
+
args.should == [[:method1], [:method2, :method3],
|
127
|
+
[:method4, :custom], [:method5, :method6, :custom]]
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
describe "#dispatch_to" do
|
132
|
+
it "registers json-rpc method with new handler" do
|
133
|
+
d = Dispatcher.new
|
134
|
+
HandlesMethodsTest.jr_handlers.should be_nil
|
135
|
+
HandlesMethodsTest.dispatch_to(d)
|
136
|
+
HandlesMethodsTest.jr_handlers.size.should == 2
|
137
|
+
HandlesMethodsTest.jr_handlers[:handle].should be_an_instance_of(Proc)
|
138
|
+
HandlesMethodsTest.jr_handlers[:custom].should be_an_instance_of(Proc)
|
139
|
+
end
|
140
|
+
|
141
|
+
it "registers local json rpc methods with dispatcher" do
|
142
|
+
d = Dispatcher.new
|
143
|
+
HandlesMethodsTest.dispatch_to(d)
|
144
|
+
|
145
|
+
d.handler_for('method1').should == HandlesMethodsTest.jr_handlers[:handle]
|
146
|
+
d.handler_for('method2').should == HandlesMethodsTest.jr_handlers[:handle]
|
147
|
+
d.handler_for('method3').should == HandlesMethodsTest.jr_handlers[:handle]
|
148
|
+
d.handler_for('method4').should == HandlesMethodsTest.jr_handlers[:custom]
|
149
|
+
d.handler_for('method5').should == HandlesMethodsTest.jr_handlers[:custom]
|
150
|
+
d.handler_for('method6').should == HandlesMethodsTest.jr_handlers[:custom]
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'rjr/util/has_messages'
|
2
|
+
|
3
|
+
module RJR
|
4
|
+
class HasMessagesTest
|
5
|
+
include HasMessages
|
6
|
+
end
|
7
|
+
|
8
|
+
describe HasMessages do
|
9
|
+
after(:each) do
|
10
|
+
HasMessagesTest.clear_messages
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "#define_message" do
|
14
|
+
it "defines new message" do
|
15
|
+
HasMessagesTest.new.define_message('foobar') { 'barfoo' }
|
16
|
+
HasMessagesTest.message('foobar').should == 'barfoo'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "::message" do
|
21
|
+
it "sets/gets message" do
|
22
|
+
HasMessagesTest.message('foobar', 'barfoo')
|
23
|
+
HasMessagesTest.message('foobar').should == 'barfoo'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "::clear_messages" do
|
28
|
+
it "clears messages" do
|
29
|
+
HasMessagesTest.message('foobar', 'barfoo')
|
30
|
+
HasMessagesTest.clear_messages
|
31
|
+
HasMessagesTest.message('foobar').should be_nil
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "#rand_message" do
|
36
|
+
it "returns random message" do
|
37
|
+
msg1 = {}
|
38
|
+
msg2 = {}
|
39
|
+
HasMessagesTest.message('foobar', msg1)
|
40
|
+
HasMessagesTest.message('barfoo', msg2)
|
41
|
+
HasMessagesTest.should_receive(:rand).and_return(1)
|
42
|
+
HasMessagesTest.rand_message.should == msg2
|
43
|
+
end
|
44
|
+
|
45
|
+
it "returns random message matching specified transport" do
|
46
|
+
tcpm = {:transports => ['tcp']}
|
47
|
+
amqpm = {:transports => ['amqp']}
|
48
|
+
HasMessagesTest.message('foobar', tcpm)
|
49
|
+
HasMessagesTest.message('barfoo', amqpm)
|
50
|
+
HasMessagesTest.rand_message('tcp').should == tcpm
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end # describe HasMessages
|
54
|
+
end # module RJR
|
data/specs/inspect_spec.rb
CHANGED
@@ -0,0 +1,169 @@
|
|
1
|
+
require 'rjr/util/json_parser'
|
2
|
+
|
3
|
+
module RJR
|
4
|
+
describe JSONParser do
|
5
|
+
describe "#extract_json_from" do
|
6
|
+
it "returns first json object from string" do
|
7
|
+
json = '{"foo":"bar"}'
|
8
|
+
JSONParser.extract_json_from(json).should == [json, '']
|
9
|
+
end
|
10
|
+
|
11
|
+
it "returns remaining portion of string" do
|
12
|
+
json = '{"foo":"bar"}'
|
13
|
+
complete = "#{json}remaining"
|
14
|
+
JSONParser.extract_json_from(complete).should == [json, 'remaining']
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "#invalid_json_class?" do
|
19
|
+
before(:each) do
|
20
|
+
@orig_whitelist = Class.whitelist_json_classes
|
21
|
+
end
|
22
|
+
|
23
|
+
after(:each) do
|
24
|
+
Class.whitelist_json_classes = @orig_whitelist
|
25
|
+
end
|
26
|
+
|
27
|
+
context "json class whitelisting enabled" do
|
28
|
+
before(:each) do
|
29
|
+
Class.whitelist_json_classes = true
|
30
|
+
end
|
31
|
+
|
32
|
+
context "class not on permitted classes list" do
|
33
|
+
it "returns true" do
|
34
|
+
Class.should_receive(:permitted_json_classes).and_return([])
|
35
|
+
JSONParser.invalid_json_class?('foobar').should be_true
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context "class on permitted classes list" do
|
40
|
+
it "returns false" do
|
41
|
+
Class.should_receive(:permitted_json_classes).and_return(['foobar'])
|
42
|
+
JSONParser.invalid_json_class?('foobar').should be_false
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context "json class whitelisting not enabled" do
|
48
|
+
before(:each) do
|
49
|
+
Class.whitelist_json_classes = false
|
50
|
+
end
|
51
|
+
|
52
|
+
context "class not on ruby heirarchy" do
|
53
|
+
it "returns true" do
|
54
|
+
JSONParser.invalid_json_class?('Foobar').should be_true
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context "class on ruby heirarchy" do
|
59
|
+
it "returns false" do
|
60
|
+
JSONParser.invalid_json_class?('Integer').should be_false
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe "#validate_json_hash" do
|
67
|
+
context "a hash key is the JSON.create_id and value is invalid class" do
|
68
|
+
it "raises argument error" do
|
69
|
+
hash = {JSON.create_id => 'foobar'}
|
70
|
+
JSONParser.should_receive(:invalid_json_class?).
|
71
|
+
with('foobar').and_return(true)
|
72
|
+
lambda{
|
73
|
+
JSONParser.validate_json_hash(hash)
|
74
|
+
}.should raise_error(ArgumentError)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
context "a value is an array" do
|
79
|
+
it "validates json array" do
|
80
|
+
arr = []
|
81
|
+
hash = {'foobar' => arr}
|
82
|
+
JSONParser.should_receive(:validate_json_array).with(arr)
|
83
|
+
JSONParser.validate_json_hash(hash)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
context "a value is a hash" do
|
88
|
+
it "validates json hash" do
|
89
|
+
inner = {}
|
90
|
+
hash = {'foobar' => inner}
|
91
|
+
JSONParser.should_receive(:validate_json_hash).with(hash).and_call_original
|
92
|
+
JSONParser.should_receive(:validate_json_hash).with(inner)
|
93
|
+
JSONParser.validate_json_hash(hash)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
describe "#validate_json_array" do
|
99
|
+
context "a value is an array" do
|
100
|
+
it "validates json array" do
|
101
|
+
inner = []
|
102
|
+
array = [inner]
|
103
|
+
JSONParser.should_receive(:validate_json_array).with(array).and_call_original
|
104
|
+
JSONParser.should_receive(:validate_json_array).with(inner)
|
105
|
+
JSONParser.validate_json_array(array)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
context "a value is a hash" do
|
110
|
+
it "validates json hash" do
|
111
|
+
inner = {}
|
112
|
+
array = [inner]
|
113
|
+
JSONParser.should_receive(:validate_json_hash).with(inner)
|
114
|
+
JSONParser.validate_json_array(array)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
describe "#parse" do
|
120
|
+
before(:each) do
|
121
|
+
@json = '{"foo":"bar"}'
|
122
|
+
end
|
123
|
+
|
124
|
+
it "safely parses json" do
|
125
|
+
JSON.should_receive(:parse).
|
126
|
+
with(@json, :create_additions => false).and_call_original
|
127
|
+
JSON.should_receive(:parse).once
|
128
|
+
JSONParser.parse(@json)
|
129
|
+
end
|
130
|
+
|
131
|
+
context "json is an array" do
|
132
|
+
it "validates json array" do
|
133
|
+
arr = []
|
134
|
+
JSON.should_receive(:parse).and_return(arr)
|
135
|
+
JSON.should_receive(:parse).once
|
136
|
+
JSONParser.should_receive(:validate_json_array).with(arr)
|
137
|
+
JSONParser.parse(@json)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
context "json is a hash" do
|
142
|
+
it "validates json hash" do
|
143
|
+
hash = {}
|
144
|
+
JSON.should_receive(:parse).and_return(hash)
|
145
|
+
JSON.should_receive(:parse).once
|
146
|
+
JSONParser.should_receive(:validate_json_hash).with(hash)
|
147
|
+
JSONParser.parse(@json)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
context "json is not a array/hash" do
|
152
|
+
it "returns value" do
|
153
|
+
JSON.should_receive(:parse).and_return(42)
|
154
|
+
JSONParser.parse(@json).should == 42
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
it "parses json, creating classes" do
|
159
|
+
njs = {}
|
160
|
+
JSON.should_receive(:parse).
|
161
|
+
with(@json, :create_additions => false).and_call_original
|
162
|
+
JSON.should_receive(:parse).
|
163
|
+
with(@json, :create_additions => true).
|
164
|
+
and_return(njs)
|
165
|
+
JSONParser.parse(@json).should == njs
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end # describe JSONParser
|
169
|
+
end # module RJR
|