protobuf 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +5 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +28 -0
- data/README.md +216 -0
- data/Rakefile +1 -0
- data/bin/rpc_server +117 -0
- data/bin/rprotoc +46 -0
- data/examples/addressbook.pb.rb +55 -0
- data/examples/addressbook.proto +24 -0
- data/examples/reading_a_message.rb +32 -0
- data/examples/writing_a_message.rb +46 -0
- data/lib/protobuf.rb +6 -0
- data/lib/protobuf/common/exceptions.rb +11 -0
- data/lib/protobuf/common/logger.rb +64 -0
- data/lib/protobuf/common/util.rb +59 -0
- data/lib/protobuf/common/wire_type.rb +10 -0
- data/lib/protobuf/compiler/compiler.rb +52 -0
- data/lib/protobuf/compiler/nodes.rb +323 -0
- data/lib/protobuf/compiler/proto.y +216 -0
- data/lib/protobuf/compiler/proto2.ebnf +79 -0
- data/lib/protobuf/compiler/proto_parser.rb +1425 -0
- data/lib/protobuf/compiler/template/rpc_bin.erb +4 -0
- data/lib/protobuf/compiler/template/rpc_client.erb +18 -0
- data/lib/protobuf/compiler/template/rpc_service.erb +25 -0
- data/lib/protobuf/compiler/template/rpc_service_implementation.erb +42 -0
- data/lib/protobuf/compiler/visitors.rb +302 -0
- data/lib/protobuf/descriptor/descriptor.proto +286 -0
- data/lib/protobuf/descriptor/descriptor.rb +55 -0
- data/lib/protobuf/descriptor/descriptor_builder.rb +143 -0
- data/lib/protobuf/descriptor/descriptor_proto.rb +138 -0
- data/lib/protobuf/descriptor/enum_descriptor.rb +33 -0
- data/lib/protobuf/descriptor/field_descriptor.rb +49 -0
- data/lib/protobuf/descriptor/file_descriptor.rb +37 -0
- data/lib/protobuf/message/decoder.rb +83 -0
- data/lib/protobuf/message/encoder.rb +46 -0
- data/lib/protobuf/message/enum.rb +62 -0
- data/lib/protobuf/message/extend.rb +8 -0
- data/lib/protobuf/message/field.rb +701 -0
- data/lib/protobuf/message/message.rb +402 -0
- data/lib/protobuf/message/protoable.rb +38 -0
- data/lib/protobuf/rpc/buffer.rb +74 -0
- data/lib/protobuf/rpc/client.rb +268 -0
- data/lib/protobuf/rpc/client_connection.rb +225 -0
- data/lib/protobuf/rpc/error.rb +34 -0
- data/lib/protobuf/rpc/error/client_error.rb +31 -0
- data/lib/protobuf/rpc/error/server_error.rb +43 -0
- data/lib/protobuf/rpc/rpc.pb.rb +107 -0
- data/lib/protobuf/rpc/server.rb +183 -0
- data/lib/protobuf/rpc/service.rb +244 -0
- data/lib/protobuf/rpc/stat.rb +70 -0
- data/lib/protobuf/version.rb +3 -0
- data/proto/rpc.proto +73 -0
- data/protobuf.gemspec +25 -0
- data/script/mk_parser +2 -0
- data/spec/functional/embedded_service_spec.rb +7 -0
- data/spec/proto/test.pb.rb +31 -0
- data/spec/proto/test.proto +31 -0
- data/spec/proto/test_service.rb +30 -0
- data/spec/proto/test_service_impl.rb +17 -0
- data/spec/spec_helper.rb +26 -0
- data/spec/unit/client_spec.rb +128 -0
- data/spec/unit/common/logger_spec.rb +121 -0
- data/spec/unit/enum_spec.rb +13 -0
- data/spec/unit/message_spec.rb +67 -0
- data/spec/unit/server_spec.rb +27 -0
- data/spec/unit/service_spec.rb +75 -0
- data/test/check_unbuild.rb +30 -0
- data/test/data/data.bin +3 -0
- data/test/data/data_source.py +14 -0
- data/test/data/types.bin +0 -0
- data/test/data/types_source.py +22 -0
- data/test/data/unk.png +0 -0
- data/test/proto/addressbook.pb.rb +66 -0
- data/test/proto/addressbook.proto +33 -0
- data/test/proto/addressbook_base.pb.rb +58 -0
- data/test/proto/addressbook_base.proto +26 -0
- data/test/proto/addressbook_ext.pb.rb +20 -0
- data/test/proto/addressbook_ext.proto +6 -0
- data/test/proto/collision.pb.rb +17 -0
- data/test/proto/collision.proto +5 -0
- data/test/proto/ext_collision.pb.rb +24 -0
- data/test/proto/ext_collision.proto +8 -0
- data/test/proto/ext_range.pb.rb +22 -0
- data/test/proto/ext_range.proto +7 -0
- data/test/proto/float_default.proto +10 -0
- data/test/proto/lowercase.pb.rb +30 -0
- data/test/proto/lowercase.proto +9 -0
- data/test/proto/merge.pb.rb +39 -0
- data/test/proto/merge.proto +15 -0
- data/test/proto/nested.pb.rb +30 -0
- data/test/proto/nested.proto +9 -0
- data/test/proto/optional_field.pb.rb +35 -0
- data/test/proto/optional_field.proto +12 -0
- data/test/proto/packed.pb.rb +22 -0
- data/test/proto/packed.proto +6 -0
- data/test/proto/rpc.proto +6 -0
- data/test/proto/types.pb.rb +84 -0
- data/test/proto/types.proto +37 -0
- data/test/test_addressbook.rb +56 -0
- data/test/test_compiler.rb +325 -0
- data/test/test_descriptor.rb +122 -0
- data/test/test_enum_value.rb +41 -0
- data/test/test_extension.rb +36 -0
- data/test/test_lowercase.rb +11 -0
- data/test/test_message.rb +128 -0
- data/test/test_optional_field.rb +103 -0
- data/test/test_packed_field.rb +40 -0
- data/test/test_parse.rb +15 -0
- data/test/test_repeated_types.rb +132 -0
- data/test/test_serialize.rb +61 -0
- data/test/test_standard_message.rb +96 -0
- data/test/test_types.rb +226 -0
- metadata +261 -0
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'date'
|
2
|
+
require 'protobuf/common/logger'
|
3
|
+
|
4
|
+
module Protobuf
|
5
|
+
module Rpc
|
6
|
+
class Stat
|
7
|
+
attr_accessor :type, :start_time, :end_time, :request_size, :response_size, :client, :server, :service, :method
|
8
|
+
|
9
|
+
TYPES = [:SERVER, :CLIENT]
|
10
|
+
|
11
|
+
def initialize type=:SERVER, do_start=true
|
12
|
+
@type = type
|
13
|
+
start if do_start
|
14
|
+
end
|
15
|
+
|
16
|
+
def client= peer
|
17
|
+
@client = {:port => peer[0], :ip => peer[1]}
|
18
|
+
end
|
19
|
+
|
20
|
+
def client
|
21
|
+
@client ? '%s:%d' % [@client[:ip], @client[:port]] : nil
|
22
|
+
end
|
23
|
+
|
24
|
+
def server= peer
|
25
|
+
@server = {:port => peer[0], :ip => peer[1]}
|
26
|
+
end
|
27
|
+
|
28
|
+
def server
|
29
|
+
@server ? '%s:%d' % [@server[:ip], @server[:port]] : nil
|
30
|
+
end
|
31
|
+
|
32
|
+
def sizes
|
33
|
+
'%dB/%dB' % [@request_size || 0, @response_size || 0]
|
34
|
+
end
|
35
|
+
|
36
|
+
def start
|
37
|
+
@start_time ||= Time.now
|
38
|
+
end
|
39
|
+
|
40
|
+
def end
|
41
|
+
start if !@start_time
|
42
|
+
@end_time ||= Time.now
|
43
|
+
end
|
44
|
+
|
45
|
+
def rpc
|
46
|
+
service && method ? '%s#%s' % [service, method] : nil
|
47
|
+
end
|
48
|
+
|
49
|
+
def elapsed_time
|
50
|
+
(start_time && end_time ? '%ss' % (end_time - start_time).round(4) : nil)
|
51
|
+
end
|
52
|
+
|
53
|
+
def log_stats
|
54
|
+
Protobuf::Logger.info to_s
|
55
|
+
end
|
56
|
+
|
57
|
+
def to_s
|
58
|
+
[
|
59
|
+
@type == :SERVER ? '[SRV]' : '[CLT]',
|
60
|
+
rpc,
|
61
|
+
elapsed_time,
|
62
|
+
sizes,
|
63
|
+
@type == :SERVER ? server : client
|
64
|
+
].delete_if{|v| v.nil? }.join(' - ')
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
data/proto/rpc.proto
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
// Copyright (c) 2009 Shardul Deo
|
2
|
+
//
|
3
|
+
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
// of this software and associated documentation files (the "Software"), to deal
|
5
|
+
// in the Software without restriction, including without limitation the rights
|
6
|
+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
// copies of the Software, and to permit persons to whom the Software is
|
8
|
+
// furnished to do so, subject to the following conditions:
|
9
|
+
//
|
10
|
+
// The above copyright notice and this permission notice shall be included in
|
11
|
+
// all copies or substantial portions of the Software.
|
12
|
+
//
|
13
|
+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
// THE SOFTWARE.
|
20
|
+
|
21
|
+
// Author: Shardul Deo
|
22
|
+
//
|
23
|
+
// Protobufs needed for socket rpcs.
|
24
|
+
|
25
|
+
package protobuf.socketrpc;
|
26
|
+
|
27
|
+
message Request {
|
28
|
+
|
29
|
+
// RPC service full name
|
30
|
+
required string service_name = 1;
|
31
|
+
|
32
|
+
// RPC method name
|
33
|
+
required string method_name = 2;
|
34
|
+
|
35
|
+
// RPC request proto
|
36
|
+
required bytes request_proto = 3;
|
37
|
+
}
|
38
|
+
|
39
|
+
message Response {
|
40
|
+
|
41
|
+
// RPC response proto
|
42
|
+
optional bytes response_proto = 1;
|
43
|
+
|
44
|
+
// Error, if any
|
45
|
+
optional string error = 2;
|
46
|
+
|
47
|
+
// Was callback invoked
|
48
|
+
optional bool callback = 3 [default = false];
|
49
|
+
|
50
|
+
// Error Reason
|
51
|
+
optional ErrorReason error_reason = 4;
|
52
|
+
}
|
53
|
+
|
54
|
+
// Possible error reasons
|
55
|
+
// The server-side errors are returned in the response from the server.
|
56
|
+
// The client-side errors are returned by the client-side code when it doesn't
|
57
|
+
// have a response from the server.
|
58
|
+
enum ErrorReason {
|
59
|
+
|
60
|
+
// Server-side errors
|
61
|
+
BAD_REQUEST_DATA = 0; // Server received bad request data
|
62
|
+
BAD_REQUEST_PROTO = 1; // Server received bad request proto
|
63
|
+
SERVICE_NOT_FOUND = 2; // Service not found on server
|
64
|
+
METHOD_NOT_FOUND = 3; // Method not found on server
|
65
|
+
RPC_ERROR = 4; // Rpc threw exception on server
|
66
|
+
RPC_FAILED = 5; // Rpc failed on server
|
67
|
+
|
68
|
+
// Client-side errors (these are returned by the client-side code)
|
69
|
+
INVALID_REQUEST_PROTO = 6; // Rpc was called with invalid request proto
|
70
|
+
BAD_RESPONSE_PROTO = 7; // Server returned a bad response proto
|
71
|
+
UNKNOWN_HOST = 8; // Could not find supplied host
|
72
|
+
IO_ERROR = 9; // I/O error while communicating with server
|
73
|
+
}
|
data/protobuf.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("./lib", File.dirname(__FILE__))
|
3
|
+
require "protobuf/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = 'protobuf'
|
7
|
+
s.version = Protobuf::VERSION
|
8
|
+
s.date = %q{2011-11-06}
|
9
|
+
|
10
|
+
s.authors = ['BJ Neilsen']
|
11
|
+
s.email = ["bj.neilsen@gmail.com"]
|
12
|
+
s.homepage = %q{https://github.com/localshred/protobuf}
|
13
|
+
s.summary = 'Ruby implementation for Protocol Buffers. Works with other protobuf rpc implementations (e.g. Java, Python, C++).'
|
14
|
+
s.description = s.summary + "\n\nThis gem has diverged from https://github.com/macks/ruby-protobuf. All credit for serialization and rprotoc work most certainly goes to the original authors. All RPC implementation code (client/server/service) was written and is maintained by this author. Attempts to reconcile the original codebase with the current RPC implementation went unsuccessful."
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
s.add_dependency 'eventmachine', '~> 0.12.10'
|
22
|
+
|
23
|
+
s.add_development_dependency 'rake', '~> 0.8.7'
|
24
|
+
s.add_development_dependency 'rspec', '~> 2.7.0'
|
25
|
+
end
|
data/script/mk_parser
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
### Generated by rprotoc. DO NOT EDIT!
|
2
|
+
require 'protobuf/message/message'
|
3
|
+
require 'protobuf/message/enum'
|
4
|
+
require 'protobuf/message/extend'
|
5
|
+
|
6
|
+
module Spec
|
7
|
+
module Proto
|
8
|
+
class StatusType < ::Protobuf::Enum
|
9
|
+
define :PENDING, 0
|
10
|
+
define :ENABLED, 1
|
11
|
+
define :DISABLED, 2
|
12
|
+
define :DELETED, 3
|
13
|
+
end
|
14
|
+
class ResourceFindRequest < ::Protobuf::Message
|
15
|
+
optional :string, :name, 1
|
16
|
+
optional :bool, :active, 2
|
17
|
+
end
|
18
|
+
class Resource < ::Protobuf::Message
|
19
|
+
optional :string, :name, 1
|
20
|
+
optional :int64, :date_created, 2
|
21
|
+
optional :StatusType, :status, 3
|
22
|
+
repeated :StatusType, :repeated_enum, 4
|
23
|
+
end
|
24
|
+
class Nested < ::Protobuf::Message
|
25
|
+
optional :string, :name, 1
|
26
|
+
optional :Resource, :resource, 2
|
27
|
+
repeated :Resource, :multiple_resources, 3
|
28
|
+
optional :StatusType, :status, 4
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
package spec.proto;
|
2
|
+
|
3
|
+
enum StatusType {
|
4
|
+
PENDING = 0;
|
5
|
+
ENABLED = 1;
|
6
|
+
DISABLED = 2;
|
7
|
+
DELETED = 3;
|
8
|
+
}
|
9
|
+
|
10
|
+
message ResourceFindRequest {
|
11
|
+
optional string name = 1;
|
12
|
+
optional bool active = 2;
|
13
|
+
}
|
14
|
+
|
15
|
+
message Resource {
|
16
|
+
optional string name = 1;
|
17
|
+
optional int64 date_created = 2;
|
18
|
+
optional StatusType status = 3;
|
19
|
+
repeated StatusType repeated_enum = 4;
|
20
|
+
}
|
21
|
+
|
22
|
+
message Nested {
|
23
|
+
optional string name = 1;
|
24
|
+
optional Resource resource = 2;
|
25
|
+
repeated Resource multiple_resources = 3;
|
26
|
+
optional StatusType status = 4;
|
27
|
+
}
|
28
|
+
|
29
|
+
service TestService {
|
30
|
+
rpc Find (ResourceFindRequest) returns (Resource);
|
31
|
+
}
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'protobuf/rpc/service'
|
2
|
+
require 'spec/proto/test.pb'
|
3
|
+
|
4
|
+
## !! DO NOT EDIT THIS FILE !!
|
5
|
+
##
|
6
|
+
## To implement this service as defined by the protobuf, simply
|
7
|
+
## reopen Spec::Proto::TestService and implement each service method:
|
8
|
+
##
|
9
|
+
## module Spec
|
10
|
+
## module Proto
|
11
|
+
## class TestService
|
12
|
+
##
|
13
|
+
## # request -> Spec::Proto::ResourceFindRequest
|
14
|
+
## # response -> Spec::Proto::Resource
|
15
|
+
## def find
|
16
|
+
## # TODO: implement find
|
17
|
+
## end
|
18
|
+
##
|
19
|
+
## end
|
20
|
+
## end
|
21
|
+
## end
|
22
|
+
##
|
23
|
+
|
24
|
+
module Spec
|
25
|
+
module Proto
|
26
|
+
class TestService < Protobuf::Rpc::Service
|
27
|
+
rpc :find, ResourceFindRequest, Resource
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'spec/proto/test_service'
|
2
|
+
|
3
|
+
module Spec
|
4
|
+
module Proto
|
5
|
+
class TestService
|
6
|
+
located_at "localhost:9191"
|
7
|
+
|
8
|
+
# request -> Spec::Proto::ResourceFindRequest
|
9
|
+
# response -> Spec::Proto::Resource
|
10
|
+
def find
|
11
|
+
response.name = request.name
|
12
|
+
response.status = request.active ? 1 : 0
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
Bundler.setup :default, :development, :test
|
4
|
+
|
5
|
+
RSpec.configure do |c|
|
6
|
+
c.mock_with :rspec
|
7
|
+
end
|
8
|
+
|
9
|
+
$:.push File.expand_path('..', File.dirname(__FILE__))
|
10
|
+
$:.push File.expand_path('../lib', File.dirname(__FILE__))
|
11
|
+
require 'protobuf'
|
12
|
+
|
13
|
+
require 'protobuf/rpc/client'
|
14
|
+
class ::Protobuf::Rpc::Client
|
15
|
+
def == other
|
16
|
+
options == other.options && \
|
17
|
+
error == other.error && \
|
18
|
+
do_block == other.do_block && \
|
19
|
+
@success_callback == other.instance_variable_get(:@success_callback) && \
|
20
|
+
@failure_callback == other.instance_variable_get(:@failure_callback)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def reset_service_location service
|
25
|
+
service.instance_variable_set :@locations, nil
|
26
|
+
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'spec/proto/test_service_impl'
|
3
|
+
|
4
|
+
describe Protobuf::Rpc::Client do
|
5
|
+
|
6
|
+
context 'when creating a client from a service' do
|
7
|
+
|
8
|
+
it 'should be able to get a client through the Service#client helper method' do
|
9
|
+
Spec::Proto::TestService.client(:port => 9191).should == Protobuf::Rpc::Client.new(:service => Spec::Proto::TestService, :port => 9191)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should be able to override a service location's host and port" do
|
13
|
+
Spec::Proto::TestService.located_at 'somewheregreat.com:12345'
|
14
|
+
clean_client = Spec::Proto::TestService.client
|
15
|
+
clean_client.options[:host].should == 'somewheregreat.com'
|
16
|
+
clean_client.options[:port].should == 12345
|
17
|
+
|
18
|
+
updated_client = Spec::Proto::TestService.client(:host => 'amazing.com', :port => 54321)
|
19
|
+
updated_client.options[:host].should == 'amazing.com'
|
20
|
+
updated_client.options[:port].should == 54321
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should be able to define the syncronicity of the client request' do
|
24
|
+
client = Spec::Proto::TestService.client(:async => false)
|
25
|
+
client.options[:async].should be_false
|
26
|
+
client.do_block.should be_true
|
27
|
+
|
28
|
+
client = Spec::Proto::TestService.client(:async => true)
|
29
|
+
client.options[:async].should be_true
|
30
|
+
client.do_block.should be_false
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'should be able to define which service to create itself for' do
|
34
|
+
client = Protobuf::Rpc::Client.new :service => Spec::Proto::TestService
|
35
|
+
client.options[:service].should == Spec::Proto::TestService
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'should have a hard default for host and port on a service that has not been configured' do
|
39
|
+
reset_service_location Spec::Proto::TestService
|
40
|
+
client = Spec::Proto::TestService.client
|
41
|
+
client.options[:host].should == Protobuf::Rpc::Service::DEFAULT_LOCATION[:host]
|
42
|
+
client.options[:port].should == Protobuf::Rpc::Service::DEFAULT_LOCATION[:port]
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'when calling methods on a service client' do
|
48
|
+
|
49
|
+
# NOTE: we are assuming the service methods are accurately
|
50
|
+
# defined inside spec/proto/test_service.rb,
|
51
|
+
# namely the :find method
|
52
|
+
|
53
|
+
it 'should respond to defined service methods' do
|
54
|
+
client = Spec::Proto::TestService.client
|
55
|
+
client.should_receive(:send_request).and_return(nil)
|
56
|
+
expect { client.find(nil) }.should_not raise_error
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'raises a NameError when accessing a var that does not exist' do
|
60
|
+
pending
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'should be able to set and get local variables within client response blocks' do
|
64
|
+
outer_value = 'OUTER'
|
65
|
+
inner_value = 'INNER'
|
66
|
+
client = Spec::Proto::TestService.client(:async => true)
|
67
|
+
|
68
|
+
EM.should_receive(:reactor_running?).and_return(true)
|
69
|
+
EM.stub!(:schedule) do
|
70
|
+
client.instance_variable_get(:@success_callback).call(inner_value)
|
71
|
+
end
|
72
|
+
|
73
|
+
client.find(nil) do |c|
|
74
|
+
c.on_success do |response|
|
75
|
+
outer_value.should == 'OUTER'
|
76
|
+
outer_value = response
|
77
|
+
end
|
78
|
+
end
|
79
|
+
outer_value.should == inner_value
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
context 'when receiving request objects' do
|
85
|
+
|
86
|
+
it 'should be able to create the correct request object if passed a hash' do
|
87
|
+
client = Spec::Proto::TestService.client
|
88
|
+
client.should_receive(:send_request)
|
89
|
+
client.find({:name => 'Test Name', :active => false})
|
90
|
+
client.options[:request].should be_a Spec::Proto::ResourceFindRequest
|
91
|
+
client.options[:request].name.should == 'Test Name'
|
92
|
+
client.options[:request].active.should == false
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
|
97
|
+
describe '#synchronize_or_return' do
|
98
|
+
|
99
|
+
context 'when a timeout error occurs' do
|
100
|
+
it 'returns a timeout error' do
|
101
|
+
client = Spec::Proto::TestService.client :timeout => 1
|
102
|
+
client.stub(:ensure_callback).and_return(proc {|err|
|
103
|
+
err.should be_a Protobuf::Rpc::ClientError
|
104
|
+
err.message.should == 'Client timeout of 1 seconds expired'
|
105
|
+
err.code.should == Protobuf::Socketrpc::ErrorReason::RPC_ERROR
|
106
|
+
})
|
107
|
+
Timeout.timeout(2) { client.synchronize_or_return }
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
context 'when any other error occurs' do
|
112
|
+
it 'returns the error' do
|
113
|
+
client = Spec::Proto::TestService.client
|
114
|
+
client.stub(:ensure_callback).and_return(proc {|err|
|
115
|
+
err.should be_a Protobuf::Rpc::ClientError
|
116
|
+
err.message.should == 'Client failed: This is another type of error'
|
117
|
+
err.code.should == Protobuf::Socketrpc::ErrorReason::RPC_ERROR
|
118
|
+
})
|
119
|
+
Timeout.timeout(2) {
|
120
|
+
Timeout.stub(:timeout).and_raise(RuntimeError.new('This is another type of error'))
|
121
|
+
client.synchronize_or_return
|
122
|
+
}
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
end
|
127
|
+
|
128
|
+
end
|