protobuf 2.8.13 → 3.0.0.rc1
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 +4 -4
- data/CHANGES.md +84 -5
- data/CONTRIBUTING.md +3 -3
- data/Rakefile +46 -7
- data/lib/protobuf/cli.rb +2 -20
- data/lib/protobuf/decoder.rb +74 -0
- data/lib/protobuf/deprecator.rb +42 -0
- data/lib/protobuf/descriptors/google/protobuf/compiler/plugin.pb.rb +17 -16
- data/lib/protobuf/descriptors/google/protobuf/descriptor.pb.rb +86 -85
- data/lib/protobuf/encoder.rb +62 -0
- data/lib/protobuf/enum.rb +298 -37
- data/lib/protobuf/field/base_field.rb +41 -27
- data/lib/protobuf/field/bool_field.rb +22 -4
- data/lib/protobuf/field/bytes_field.rb +36 -15
- data/lib/protobuf/field/double_field.rb +10 -3
- data/lib/protobuf/field/enum_field.rb +21 -18
- data/lib/protobuf/field/field_array.rb +26 -16
- data/lib/protobuf/field/fixed32_field.rb +10 -4
- data/lib/protobuf/field/fixed64_field.rb +10 -3
- data/lib/protobuf/field/float_field.rb +18 -5
- data/lib/protobuf/field/int32_field.rb +14 -4
- data/lib/protobuf/field/int64_field.rb +14 -4
- data/lib/protobuf/field/integer_field.rb +9 -4
- data/lib/protobuf/field/message_field.rb +16 -7
- data/lib/protobuf/field/sfixed32_field.rb +10 -3
- data/lib/protobuf/field/sfixed64_field.rb +12 -7
- data/lib/protobuf/field/signed_integer_field.rb +7 -0
- data/lib/protobuf/field/sint32_field.rb +14 -4
- data/lib/protobuf/field/sint64_field.rb +14 -4
- data/lib/protobuf/field/string_field.rb +11 -1
- data/lib/protobuf/field/uint32_field.rb +14 -4
- data/lib/protobuf/field/uint64_field.rb +14 -4
- data/lib/protobuf/field/varint_field.rb +11 -9
- data/lib/protobuf/field.rb +42 -25
- data/lib/protobuf/generators/enum_generator.rb +12 -1
- data/lib/protobuf/generators/field_generator.rb +1 -1
- data/lib/protobuf/lifecycle.rb +3 -4
- data/lib/protobuf/message/fields.rb +122 -0
- data/lib/protobuf/message/serialization.rb +84 -0
- data/lib/protobuf/message.rb +21 -221
- data/lib/protobuf/optionable.rb +23 -0
- data/lib/protobuf/rpc/client.rb +2 -4
- data/lib/protobuf/rpc/connector.rb +0 -2
- data/lib/protobuf/rpc/connectors/common.rb +2 -2
- data/lib/protobuf/rpc/dynamic_discovery.pb.rb +14 -16
- data/lib/protobuf/rpc/env.rb +58 -0
- data/lib/protobuf/rpc/error.rb +8 -5
- data/lib/protobuf/rpc/middleware/exception_handler.rb +36 -0
- data/lib/protobuf/rpc/middleware/logger.rb +91 -0
- data/lib/protobuf/rpc/middleware/request_decoder.rb +83 -0
- data/lib/protobuf/rpc/middleware/response_encoder.rb +88 -0
- data/lib/protobuf/rpc/middleware/runner.rb +18 -0
- data/lib/protobuf/rpc/middleware.rb +25 -0
- data/lib/protobuf/rpc/rpc.pb.rb +15 -16
- data/lib/protobuf/rpc/server.rb +14 -64
- data/lib/protobuf/rpc/servers/socket/server.rb +0 -2
- data/lib/protobuf/rpc/servers/socket/worker.rb +11 -15
- data/lib/protobuf/rpc/servers/zmq/util.rb +4 -1
- data/lib/protobuf/rpc/servers/zmq/worker.rb +5 -13
- data/lib/protobuf/rpc/servers/zmq_runner.rb +1 -1
- data/lib/protobuf/rpc/service.rb +38 -72
- data/lib/protobuf/rpc/service_dispatcher.rb +20 -108
- data/lib/protobuf/version.rb +1 -2
- data/lib/protobuf.rb +5 -13
- data/protobuf.gemspec +5 -5
- data/spec/benchmark/tasks.rb +2 -77
- data/spec/functional/zmq_server_spec.rb +13 -21
- data/spec/lib/protobuf/cli_spec.rb +5 -43
- data/spec/lib/protobuf/enum_spec.rb +194 -61
- data/spec/lib/protobuf/field_spec.rb +194 -0
- data/spec/lib/protobuf/generators/enum_generator_spec.rb +24 -1
- data/spec/lib/protobuf/generators/field_generator_spec.rb +6 -6
- data/spec/lib/protobuf/message_spec.rb +52 -70
- data/spec/lib/protobuf/optionable_spec.rb +46 -0
- data/spec/lib/protobuf/rpc/client_spec.rb +1 -93
- data/spec/lib/protobuf/rpc/connector_spec.rb +1 -7
- data/spec/lib/protobuf/rpc/connectors/zmq_spec.rb +8 -0
- data/spec/lib/protobuf/rpc/middleware/exception_handler_spec.rb +62 -0
- data/spec/lib/protobuf/rpc/middleware/logger_spec.rb +49 -0
- data/spec/lib/protobuf/rpc/middleware/request_decoder_spec.rb +115 -0
- data/spec/lib/protobuf/rpc/middleware/response_encoder_spec.rb +75 -0
- data/spec/lib/protobuf/rpc/servers/socket_server_spec.rb +0 -6
- data/spec/lib/protobuf/rpc/servers/zmq/util_spec.rb +10 -0
- data/spec/lib/protobuf/rpc/service_dispatcher_spec.rb +30 -105
- data/spec/lib/protobuf/rpc/service_filters_spec.rb +4 -4
- data/spec/lib/protobuf/rpc/service_spec.rb +20 -24
- data/spec/lib/protobuf_spec.rb +3 -3
- data/spec/spec_helper.rb +5 -4
- data/spec/support/packed_field.rb +15 -14
- data/spec/support/server.rb +4 -21
- data/spec/support/test/defaults.pb.rb +4 -4
- data/spec/support/test/enum.pb.rb +13 -1
- data/spec/support/test/enum.proto +15 -0
- data/spec/support/test/extended.pb.rb +1 -1
- data/spec/support/test/google_unittest.pb.rb +239 -241
- data/spec/support/test/google_unittest_import.pb.rb +2 -2
- data/spec/support/test/multi_field_extensions.pb.rb +2 -2
- data/spec/support/test/resource.pb.rb +19 -18
- data/spec/support/test/resource.proto +1 -0
- data/spec/support/test/resource_service.rb +5 -0
- metadata +78 -57
- data/bin/rprotoc +0 -8
- data/lib/protobuf/enum_value.rb +0 -85
- data/lib/protobuf/evented.rb +0 -37
- data/lib/protobuf/ext/eventmachine.rb +0 -14
- data/lib/protobuf/field/extension_fields.rb +0 -32
- data/lib/protobuf/message/decoder.rb +0 -72
- data/lib/protobuf/message/message.rb +0 -1
- data/lib/protobuf/rpc/connectors/em_client.rb +0 -84
- data/lib/protobuf/rpc/connectors/eventmachine.rb +0 -87
- data/lib/protobuf/rpc/servers/evented/server.rb +0 -36
- data/lib/protobuf/rpc/servers/evented_runner.rb +0 -31
- data/spec/functional/embedded_service_spec.rb +0 -7
- data/spec/functional/evented_server_spec.rb +0 -64
- data/spec/lib/protobuf/enum_value_spec.rb +0 -29
- data/spec/lib/protobuf/rpc/servers/evented_server_spec.rb +0 -19
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Protobuf::Rpc::Middleware::ExceptionHandler do
|
4
|
+
let(:app) { Proc.new { |env| env } }
|
5
|
+
let(:env) { Protobuf::Rpc::Env.new }
|
6
|
+
|
7
|
+
subject { described_class.new(app) }
|
8
|
+
|
9
|
+
describe "#call" do
|
10
|
+
it "calls the stack" do
|
11
|
+
app.should_receive(:call).with(env)
|
12
|
+
subject.call(env)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "returns the env" do
|
16
|
+
subject.call(env).should eq env
|
17
|
+
end
|
18
|
+
|
19
|
+
context "when exceptions occur" do
|
20
|
+
let(:encoded_error) { error.encode }
|
21
|
+
let(:error) { Protobuf::Rpc::MethodNotFound.new('Boom!') }
|
22
|
+
|
23
|
+
before { app.stub(:call).and_raise(error, 'Boom!') }
|
24
|
+
|
25
|
+
it "rescues exceptions" do
|
26
|
+
expect { subject.call(env) }.not_to raise_exception
|
27
|
+
end
|
28
|
+
|
29
|
+
context "when exception is a Protobuf error" do
|
30
|
+
it "does not wrap the exception in a generic Protobuf error" do
|
31
|
+
stack_env = subject.call(env)
|
32
|
+
|
33
|
+
# Can't compare the error instances because the response has been
|
34
|
+
# raised and thus has a backtrace while the error does not.
|
35
|
+
stack_env.response.class.should eq error.class
|
36
|
+
end
|
37
|
+
|
38
|
+
it "encodes the response" do
|
39
|
+
stack_env = subject.call(env)
|
40
|
+
stack_env.encoded_response.should eq encoded_error
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context "when exception is not a Protobuf error" do
|
45
|
+
let(:encoded_error) { error.encode }
|
46
|
+
let(:error) { Protobuf::Rpc::RpcFailed.new('Boom!') }
|
47
|
+
|
48
|
+
before { app.stub(:call).and_raise(RuntimeError, 'Boom!') }
|
49
|
+
|
50
|
+
it "wraps the exception in a generic Protobuf error" do
|
51
|
+
stack_env = subject.call(env)
|
52
|
+
stack_env.response.should eq error
|
53
|
+
end
|
54
|
+
|
55
|
+
it "encodes the wrapped exception" do
|
56
|
+
stack_env = subject.call(env)
|
57
|
+
stack_env.encoded_response.should eq encoded_error
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Protobuf::Rpc::Middleware::Logger do
|
4
|
+
let(:app) { Proc.new { |env| env } }
|
5
|
+
let(:env) {
|
6
|
+
Protobuf::Rpc::Env.new(
|
7
|
+
'client_host' => 'client_host.test.co',
|
8
|
+
'encoded_request' => request_wrapper.encode,
|
9
|
+
'encoded_response' => response_wrapper.encode,
|
10
|
+
'method_name' => method_name,
|
11
|
+
'request' => request,
|
12
|
+
'request_type' => rpc_method.request_type,
|
13
|
+
'response' => response,
|
14
|
+
'response_type' => rpc_method.response_type,
|
15
|
+
'rpc_method' => rpc_method,
|
16
|
+
'rpc_service' => service_class,
|
17
|
+
'service_name' => service_name,
|
18
|
+
)
|
19
|
+
}
|
20
|
+
let(:method_name) { :find }
|
21
|
+
let(:request) { request_type.new(:name => 'required') }
|
22
|
+
let(:request_type) { rpc_method.request_type }
|
23
|
+
let(:request_wrapper) {
|
24
|
+
Protobuf::Socketrpc::Request.new(
|
25
|
+
:service_name => service_name,
|
26
|
+
:method_name => method_name.to_s,
|
27
|
+
:request_proto => request
|
28
|
+
)
|
29
|
+
}
|
30
|
+
let(:response_wrapper) { Protobuf::Socketrpc::Response.new(:response_proto => response) }
|
31
|
+
let(:response) { rpc_method.response_type.new(:name => 'required') }
|
32
|
+
let(:rpc_method) { service_class.rpcs[method_name] }
|
33
|
+
let(:rpc_service) { service_class.new(env) }
|
34
|
+
let(:service_class) { Test::ResourceService }
|
35
|
+
let(:service_name) { service_class.to_s }
|
36
|
+
|
37
|
+
subject { described_class.new(app) }
|
38
|
+
|
39
|
+
describe "#call" do
|
40
|
+
it "calls the stack" do
|
41
|
+
app.should_receive(:call).with(env)
|
42
|
+
subject.call(env)
|
43
|
+
end
|
44
|
+
|
45
|
+
it "returns the env" do
|
46
|
+
subject.call(env).should eq env
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Protobuf::Rpc::Middleware::RequestDecoder do
|
4
|
+
let(:app) { Proc.new { |env| env } }
|
5
|
+
let(:client_host) { 'client_host.test.co' }
|
6
|
+
let(:env) {
|
7
|
+
Protobuf::Rpc::Env.new(
|
8
|
+
'encoded_request' => encoded_request,
|
9
|
+
'log_signature' => 'log_signature'
|
10
|
+
)
|
11
|
+
}
|
12
|
+
let(:encoded_request) { request_wrapper.encode }
|
13
|
+
let(:method_name) { :find }
|
14
|
+
let(:request) { request_type.new(:name => 'required') }
|
15
|
+
let(:request_type) { rpc_method.request_type }
|
16
|
+
let(:request_wrapper) {
|
17
|
+
Protobuf::Socketrpc::Request.new(
|
18
|
+
:caller => client_host,
|
19
|
+
:service_name => service_name,
|
20
|
+
:method_name => method_name.to_s,
|
21
|
+
:request_proto => request
|
22
|
+
)
|
23
|
+
}
|
24
|
+
let(:response_type) { rpc_method.response_type }
|
25
|
+
let(:rpc_method) { rpc_service.rpcs[method_name] }
|
26
|
+
let(:rpc_service) { Test::ResourceService }
|
27
|
+
let(:service_name) { rpc_service.to_s }
|
28
|
+
|
29
|
+
subject { described_class.new(app) }
|
30
|
+
|
31
|
+
describe "#call" do
|
32
|
+
it "decodes the request" do
|
33
|
+
stack_env = subject.call(env)
|
34
|
+
stack_env.request.should eq request
|
35
|
+
end
|
36
|
+
|
37
|
+
it "calls the stack" do
|
38
|
+
app.should_receive(:call).with(env)
|
39
|
+
subject.call(env)
|
40
|
+
end
|
41
|
+
|
42
|
+
it "sets Env#client_host" do
|
43
|
+
stack_env = subject.call(env)
|
44
|
+
stack_env.client_host.should eq client_host
|
45
|
+
end
|
46
|
+
|
47
|
+
it "sets Env#service_name" do
|
48
|
+
stack_env = subject.call(env)
|
49
|
+
stack_env.service_name.should eq service_name
|
50
|
+
end
|
51
|
+
|
52
|
+
it "sets Env#method_name" do
|
53
|
+
stack_env = subject.call(env)
|
54
|
+
stack_env.method_name.should eq method_name.to_sym
|
55
|
+
end
|
56
|
+
|
57
|
+
it "sets Env#request_type" do
|
58
|
+
stack_env = subject.call(env)
|
59
|
+
stack_env.request_type.should eq request_type
|
60
|
+
end
|
61
|
+
|
62
|
+
it "sets Env#response_type" do
|
63
|
+
stack_env = subject.call(env)
|
64
|
+
stack_env.response_type.should eq response_type
|
65
|
+
end
|
66
|
+
|
67
|
+
it "sets Env#rpc_method" do
|
68
|
+
stack_env = subject.call(env)
|
69
|
+
stack_env.rpc_method.should eq rpc_method
|
70
|
+
end
|
71
|
+
|
72
|
+
it "sets Env#rpc_service" do
|
73
|
+
stack_env = subject.call(env)
|
74
|
+
stack_env.rpc_service.should eq rpc_service
|
75
|
+
end
|
76
|
+
|
77
|
+
context "when decoding fails" do
|
78
|
+
before { Protobuf::Socketrpc::Request.stub(:decode).and_raise(RuntimeError) }
|
79
|
+
|
80
|
+
it "raises a bad request data exception" do
|
81
|
+
expect { subject.call(env) }.to raise_exception(Protobuf::Rpc::BadRequestData)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
context "when the RPC service is not defined" do
|
86
|
+
let(:request_wrapper) {
|
87
|
+
Protobuf::Socketrpc::Request.new(
|
88
|
+
:caller => client_host,
|
89
|
+
:service_name => 'Foo',
|
90
|
+
:method_name => method_name.to_s,
|
91
|
+
:request_proto => request
|
92
|
+
)
|
93
|
+
}
|
94
|
+
|
95
|
+
it "raises a bad request data exception" do
|
96
|
+
expect { subject.call(env) }.to raise_exception(Protobuf::Rpc::ServiceNotFound)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
context "when RPC method is not defined" do
|
101
|
+
let(:request_wrapper) {
|
102
|
+
Protobuf::Socketrpc::Request.new(
|
103
|
+
:caller => client_host,
|
104
|
+
:service_name => service_name,
|
105
|
+
:method_name => 'foo',
|
106
|
+
:request_proto => request
|
107
|
+
)
|
108
|
+
}
|
109
|
+
|
110
|
+
it "raises a bad request data exception" do
|
111
|
+
expect { subject.call(env) }.to raise_exception(Protobuf::Rpc::MethodNotFound)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Protobuf::Rpc::Middleware::ResponseEncoder do
|
4
|
+
let(:app) { Proc.new { |env| env.response = response; env } }
|
5
|
+
let(:env) {
|
6
|
+
Protobuf::Rpc::Env.new(
|
7
|
+
'response_type' => Test::Resource,
|
8
|
+
'log_signature' => 'log_signature'
|
9
|
+
)
|
10
|
+
}
|
11
|
+
let(:encoded_response) { response_wrapper.encode }
|
12
|
+
let(:response) { Test::Resource.new(:name => 'required') }
|
13
|
+
let(:response_wrapper) { Protobuf::Socketrpc::Response.new(:response_proto => response) }
|
14
|
+
|
15
|
+
subject { described_class.new(app) }
|
16
|
+
|
17
|
+
describe "#call" do
|
18
|
+
it "encodes the response" do
|
19
|
+
stack_env = subject.call(env)
|
20
|
+
stack_env.encoded_response.should eq encoded_response
|
21
|
+
end
|
22
|
+
|
23
|
+
it "calls the stack" do
|
24
|
+
stack_env = subject.call(env)
|
25
|
+
stack_env.response.should eq response
|
26
|
+
end
|
27
|
+
|
28
|
+
context "when response is responds to :to_hash" do
|
29
|
+
let(:app) { proc { |env| env.response = hashable; env } }
|
30
|
+
let(:hashable) { double('hashable', :to_hash => response.to_hash) }
|
31
|
+
|
32
|
+
it "sets Env#response" do
|
33
|
+
stack_env = subject.call(env)
|
34
|
+
stack_env.response.should eq response
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context "when response is responds to :to_proto" do
|
39
|
+
let(:app) { proc { |env| env.response = protoable; env } }
|
40
|
+
let(:protoable) { double('protoable', :to_proto => response) }
|
41
|
+
|
42
|
+
it "sets Env#response" do
|
43
|
+
stack_env = subject.call(env)
|
44
|
+
stack_env.response.should eq response
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context "when response is not a valid response type" do
|
49
|
+
let(:app) { proc { |env| env.response = "I'm not a valid response"; env } }
|
50
|
+
|
51
|
+
it "raises a bad response proto exception" do
|
52
|
+
expect { subject.call(env) }.to raise_exception(Protobuf::Rpc::BadResponseProto)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context "when response is a Protobuf error" do
|
57
|
+
let(:app) { proc { |env| env.response = error; env } }
|
58
|
+
let(:error) { Protobuf::Rpc::RpcError.new }
|
59
|
+
let(:response_wrapper) { error.to_response }
|
60
|
+
|
61
|
+
it "wraps and encodes the response" do
|
62
|
+
stack_env = subject.call(env)
|
63
|
+
stack_env.encoded_response.should eq encoded_response
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
context "when encoding fails" do
|
68
|
+
before { Protobuf::Socketrpc::Response.any_instance.stub(:encode).and_raise(RuntimeError) }
|
69
|
+
|
70
|
+
it "raises a bad request data exception" do
|
71
|
+
expect { subject.call(env) }.to raise_exception(Protobuf::Rpc::PbError)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'spec/support/test/resource_service'
|
3
3
|
require 'protobuf/rpc/servers/socket_runner'
|
4
|
-
require 'protobuf/evented'
|
5
4
|
require 'protobuf/socket'
|
6
5
|
|
7
6
|
describe Protobuf::Rpc::Socket::Server do
|
@@ -32,11 +31,6 @@ describe Protobuf::Rpc::Socket::Server do
|
|
32
31
|
@server.should respond_to(:stop)
|
33
32
|
end
|
34
33
|
|
35
|
-
it "provides a Runner class" do
|
36
|
-
runner_class = described_class.to_s.gsub(/Evented::Server/, "EventedRunner")
|
37
|
-
expect { runner_class.constantize }.to_not raise_error
|
38
|
-
end
|
39
|
-
|
40
34
|
it "signals the Server is running" do
|
41
35
|
@server.should be_running
|
42
36
|
end
|
@@ -42,4 +42,14 @@ describe ::Protobuf::Rpc::Zmq::Util do
|
|
42
42
|
subject.log_signature.should include('server', 'UtilTest')
|
43
43
|
end
|
44
44
|
end
|
45
|
+
|
46
|
+
describe '.resolve_ip' do
|
47
|
+
it 'resolves ips' do
|
48
|
+
expect(subject.resolve_ip('127.0.0.1')).to eq('127.0.0.1')
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'resolves non ips' do
|
52
|
+
expect(subject.resolve_ip('localhost')).to eq('127.0.0.1')
|
53
|
+
end
|
54
|
+
end
|
45
55
|
end
|
@@ -2,115 +2,40 @@ require 'spec_helper'
|
|
2
2
|
require 'protobuf/rpc/service_dispatcher'
|
3
3
|
|
4
4
|
describe Protobuf::Rpc::ServiceDispatcher do
|
5
|
-
let(:
|
6
|
-
let(:
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
5
|
+
let(:app) { proc { |env| env } }
|
6
|
+
let(:env) {
|
7
|
+
Protobuf::Rpc::Env.new(
|
8
|
+
'method_name' => method_name,
|
9
|
+
'rpc_service' => service_class,
|
10
|
+
'service_name' => service_name,
|
11
|
+
)
|
12
|
+
}
|
13
|
+
let(:method_name) { :find }
|
14
|
+
let(:response) { response_type.new(:name => 'required') }
|
15
|
+
let(:response_type) { service_class.rpcs[method_name].response_type }
|
16
|
+
let(:rpc_service) { service_class.new(env) }
|
17
|
+
let(:service_class) { Test::ResourceService }
|
18
|
+
let(:service_name) { service_class.to_s }
|
19
|
+
|
20
|
+
subject { described_class.new(app) }
|
21
|
+
|
22
|
+
before { subject.stub(:rpc_service).and_return(rpc_service) }
|
23
|
+
|
24
|
+
describe '#call' do
|
25
|
+
before { rpc_service.stub(:callable_rpc_method).and_return(lambda {}) }
|
26
|
+
before { rpc_service.stub(:response).and_return(response) }
|
27
|
+
|
28
|
+
it "dispatches the request" do
|
29
|
+
stack_env = subject.call(env)
|
30
|
+
stack_env.response.should eq response
|
29
31
|
end
|
30
32
|
|
31
|
-
context
|
32
|
-
|
33
|
-
its(:success?) { should be_false }
|
34
|
-
its(:error) { should be_instance_of(Protobuf::Rpc::MethodNotFound) }
|
35
|
-
end
|
33
|
+
context "when the given RPC method is not implemented" do
|
34
|
+
before { rpc_service.stub(:callable_rpc_method).and_return(lambda { rpc_service.__send__(:foo) }) }
|
36
35
|
|
37
|
-
|
38
|
-
|
39
|
-
class Test::Resource
|
40
|
-
def non_rpc_method; end
|
41
|
-
end
|
36
|
+
it "raises a method not found exception" do
|
37
|
+
expect { subject.call(env) }.to raise_exception(Protobuf::Rpc::MethodNotFound)
|
42
38
|
end
|
43
|
-
|
44
|
-
let(:method_name) { 'non_rpc_method' }
|
45
|
-
its(:success?) { should be_false }
|
46
|
-
its(:error) { should be_instance_of(Protobuf::Rpc::MethodNotFound) }
|
47
39
|
end
|
48
40
|
end
|
49
|
-
|
50
|
-
describe '#invoke!' do
|
51
|
-
context 'regular invocation' do
|
52
|
-
before { subject.callable_method.should_receive(:call) }
|
53
|
-
before { subject.service.stub(:response).and_return(response) }
|
54
|
-
before { subject.invoke! }
|
55
|
-
its(:response) { should be_instance_of Test::Resource }
|
56
|
-
its(:success?) { should be_true }
|
57
|
-
end
|
58
|
-
|
59
|
-
context 'when service responds with' do
|
60
|
-
context 'a hash object' do
|
61
|
-
before { subject.callable_method.should_receive(:call) }
|
62
|
-
before { subject.service.stub(:response).and_return({ :name => 'returned' }) }
|
63
|
-
before { subject.invoke! }
|
64
|
-
its(:success?) { should be_true }
|
65
|
-
its(:response) { should eq Test::Resource.new(:name => 'returned') }
|
66
|
-
end
|
67
|
-
|
68
|
-
context 'an object that responds to to_hash but is not a hash' do
|
69
|
-
let(:hashable) do
|
70
|
-
double('hashable', :to_hash => { :name => 'hashable' })
|
71
|
-
end
|
72
|
-
before { subject.callable_method.should_receive(:call) }
|
73
|
-
before { subject.service.stub(:response).and_return(hashable) }
|
74
|
-
before { subject.invoke! }
|
75
|
-
its(:success?) { should be_true }
|
76
|
-
its(:response) { should eq Test::Resource.new(:name => 'hashable') }
|
77
|
-
end
|
78
|
-
|
79
|
-
context 'an object that responds to to_proto' do
|
80
|
-
let(:protoable) do
|
81
|
-
double('protoable', :to_proto => Test::Resource.new(:name => 'protoable'))
|
82
|
-
end
|
83
|
-
before { subject.callable_method.should_receive(:call) }
|
84
|
-
before { subject.service.stub(:response).and_return(protoable) }
|
85
|
-
before { subject.invoke! }
|
86
|
-
its(:success?) { should be_true }
|
87
|
-
its(:response) { should eq Test::Resource.new(:name => 'protoable') }
|
88
|
-
end
|
89
|
-
|
90
|
-
context 'a type not identified by the rpc definition' do
|
91
|
-
before { subject.callable_method.should_receive(:call) }
|
92
|
-
before { subject.service.stub(:response).and_return("I'm not a valid response") }
|
93
|
-
before { subject.invoke! }
|
94
|
-
its(:error) { should be_instance_of(Protobuf::Rpc::BadResponseProto) }
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
context 'when service invokes rpc failed callback' do
|
99
|
-
before(:all) do
|
100
|
-
class Test::ResourceService
|
101
|
-
rpc :find_with_rpc_failed, Test::ResourceFindRequest, Test::Resource
|
102
|
-
def find_with_rpc_failed
|
103
|
-
rpc_failed('Find failed')
|
104
|
-
end
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
let(:method_name) { 'find_with_rpc_failed' }
|
109
|
-
before { subject.service.find_with_rpc_failed }
|
110
|
-
|
111
|
-
its(:success?) { should be_false }
|
112
|
-
its(:error) { should be_instance_of(Protobuf::Rpc::RpcFailed) }
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
41
|
end
|
@@ -416,7 +416,7 @@ describe Protobuf::Rpc::ServiceFilters do
|
|
416
416
|
subject.__send__(:run_filters, :endpoint)
|
417
417
|
subject.called.should eq([ :filter_with_error3, :custom_error_occurred ])
|
418
418
|
subject.ex_class.should eq CustomError3
|
419
|
-
}.
|
419
|
+
}.not_to raise_error
|
420
420
|
end
|
421
421
|
end
|
422
422
|
|
@@ -437,7 +437,7 @@ describe Protobuf::Rpc::ServiceFilters do
|
|
437
437
|
subject.__send__(:run_filters, :endpoint)
|
438
438
|
subject.called.should eq([ :filter_with_error1, :custom_error_occurred ])
|
439
439
|
subject.ex_class.should eq CustomError1
|
440
|
-
}.
|
440
|
+
}.not_to raise_error
|
441
441
|
end
|
442
442
|
end
|
443
443
|
end
|
@@ -457,7 +457,7 @@ describe Protobuf::Rpc::ServiceFilters do
|
|
457
457
|
subject.__send__(:run_filters, :endpoint)
|
458
458
|
subject.called.should eq([ :filter_with_error1, :block_rescue_handler ])
|
459
459
|
subject.ex_class.should eq CustomError1
|
460
|
-
}.
|
460
|
+
}.not_to raise_error
|
461
461
|
end
|
462
462
|
end
|
463
463
|
|
@@ -476,7 +476,7 @@ describe Protobuf::Rpc::ServiceFilters do
|
|
476
476
|
subject.__send__(:run_filters, :endpoint)
|
477
477
|
subject.called.should eq([ :filter_with_runtime_error, :standard_error_rescue_handler ])
|
478
478
|
subject.ex_class.should eq RuntimeError
|
479
|
-
}.
|
479
|
+
}.not_to raise_error
|
480
480
|
end
|
481
481
|
end
|
482
482
|
end
|
@@ -120,18 +120,21 @@ describe Protobuf::Rpc::Service do
|
|
120
120
|
end
|
121
121
|
end
|
122
122
|
|
123
|
-
|
124
|
-
let(:
|
125
|
-
Test::ResourceFindRequest.new(:name => 'resource')
|
126
|
-
end
|
127
|
-
|
128
|
-
let(:response) do
|
129
|
-
Test::Resource.new
|
130
|
-
end
|
123
|
+
let(:request) { Test::ResourceFindRequest.new(:name => 'resource') }
|
124
|
+
let(:response) { Test::Resource.new }
|
131
125
|
|
132
126
|
context 'when calling the rpc method' do
|
133
127
|
context 'when response is implied' do
|
134
|
-
|
128
|
+
let(:env) {
|
129
|
+
Protobuf::Rpc::Env.new(
|
130
|
+
'request' => request,
|
131
|
+
'response_type' => response_type
|
132
|
+
)
|
133
|
+
}
|
134
|
+
let(:response_type) { service.rpcs[:find_with_implied_response].response_type }
|
135
|
+
let(:service) { NewTestService }
|
136
|
+
|
137
|
+
subject { NewTestService.new(env) }
|
135
138
|
|
136
139
|
before { subject.find_with_implied_response }
|
137
140
|
its(:response) { should be_a(Test::Resource) }
|
@@ -139,27 +142,20 @@ describe Protobuf::Rpc::Service do
|
|
139
142
|
end
|
140
143
|
|
141
144
|
context 'when using respond_with paradigm' do
|
142
|
-
|
145
|
+
let(:env) {
|
146
|
+
Protobuf::Rpc::Env.new(
|
147
|
+
'method_name' => :find_with_respond_with,
|
148
|
+
'request' => request
|
149
|
+
)
|
150
|
+
}
|
151
|
+
|
152
|
+
subject { NewTestService.new(env) }
|
143
153
|
|
144
154
|
before { subject.find_with_respond_with }
|
145
155
|
its(:response) { should be_a(Test::Resource) }
|
146
156
|
specify { subject.response.name.should eq 'Custom response' }
|
147
157
|
end
|
148
158
|
end
|
149
|
-
|
150
|
-
context 'when calling rpc_failed in the method' do
|
151
|
-
subject { NewTestService.new(:find_with_rpc_failed, request.encode) }
|
152
|
-
|
153
|
-
it 'invokes the rpc_failed callback with the error' do
|
154
|
-
error = nil
|
155
|
-
subject.on_rpc_failed(lambda { |err| error = err })
|
156
|
-
subject.find_with_rpc_failed
|
157
|
-
error.should eq 'This is a failed endpoint'
|
158
|
-
subject.response.name.should eq 'Name will still be set'
|
159
|
-
end
|
160
|
-
end
|
161
159
|
end
|
162
|
-
|
163
160
|
end
|
164
|
-
|
165
161
|
end
|
data/spec/lib/protobuf_spec.rb
CHANGED
@@ -26,15 +26,15 @@ describe ::Protobuf do
|
|
26
26
|
described_class.connector_type.should eq :socket
|
27
27
|
end
|
28
28
|
|
29
|
-
it 'accepts socket
|
30
|
-
[:socket, :
|
29
|
+
it 'accepts socket or zmq' do
|
30
|
+
[:socket, :zmq].each do |type|
|
31
31
|
described_class.connector_type = type
|
32
32
|
described_class.connector_type.should eq type
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
36
|
it 'does not accept other types' do
|
37
|
-
[:hello, :world].each do |type|
|
37
|
+
[:hello, :world, :evented].each do |type|
|
38
38
|
expect {
|
39
39
|
described_class.connector_type = type
|
40
40
|
}.to raise_error(ArgumentError)
|
data/spec/spec_helper.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'simplecov'
|
2
2
|
SimpleCov.start
|
3
3
|
|
4
|
+
require 'timeout'
|
4
5
|
require 'rubygems'
|
5
6
|
require 'bundler'
|
6
7
|
Bundler.setup :default, :development, :test
|
@@ -10,6 +11,7 @@ $: << ::File.expand_path('../..', __FILE__)
|
|
10
11
|
$: << ::File.expand_path('../support', __FILE__)
|
11
12
|
|
12
13
|
require 'protobuf'
|
14
|
+
require 'protobuf/rpc/server'
|
13
15
|
require ::File.expand_path('../support/all', __FILE__)
|
14
16
|
|
15
17
|
$: << ::File.expand_path("../../lib/protobuf/descriptors", __FILE__)
|
@@ -30,11 +32,10 @@ ENV.delete("PB_IGNORE_DEPRECATIONS")
|
|
30
32
|
|
31
33
|
c.before(:suite) do
|
32
34
|
unless ENV['NO_COMPILE_TEST_PROTOS']
|
35
|
+
require 'rake'
|
36
|
+
load ::File.expand_path('../../Rakefile', __FILE__)
|
33
37
|
$stdout.puts 'Compiling test protos (use NO_COMPILE_TEST_PROTOS=1 to skip)'
|
34
|
-
|
35
|
-
cmd = %Q{protoc --plugin=./bin/protoc-gen-ruby --ruby_out=#{proto_path} -I #{proto_path} #{File.join(proto_path, '**', '*.proto')}}
|
36
|
-
puts cmd
|
37
|
-
%x{#{cmd}}
|
38
|
+
::Rake::Task['compile:spec']
|
38
39
|
end
|
39
40
|
end
|
40
41
|
end
|
@@ -1,21 +1,22 @@
|
|
1
|
-
|
1
|
+
if defined?(RSpec)
|
2
|
+
shared_examples_for :packable_field do |field_klass|
|
2
3
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
before(:all) do
|
5
|
+
unless defined?(PackableFieldTest)
|
6
|
+
class PackableFieldTest < ::Protobuf::Message; end
|
7
|
+
end
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
end
|
9
|
+
field_name = "#{field_klass.name.split('::').last.underscore}_packed_field".to_sym
|
10
|
+
tag_num = PackableFieldTest.fields.size + 1
|
11
|
+
PackableFieldTest.repeated(field_klass, field_name, tag_num, :packed => true)
|
12
|
+
end
|
13
13
|
|
14
|
-
|
15
|
-
|
14
|
+
let(:field_name) { "#{field_klass.name.split('::').last.underscore}_packed_field".to_sym }
|
15
|
+
let(:message_instance) { PackableFieldTest.new(field_name => [100, 200, 300]) }
|
16
16
|
|
17
|
-
|
17
|
+
subject { PackableFieldTest.get_field(field_name) }
|
18
18
|
|
19
|
-
|
19
|
+
it { should be_packed }
|
20
20
|
|
21
|
+
end
|
21
22
|
end
|