protobuf 1.1.3 → 1.3.0

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.
Files changed (60) hide show
  1. data/.gitignore +3 -0
  2. data/Gemfile.lock +44 -25
  3. data/README.md +2 -2
  4. data/Rakefile +15 -0
  5. data/bin/rpc_server +52 -11
  6. data/lib/protobuf.rb +22 -10
  7. data/lib/protobuf/common/logger.rb +26 -25
  8. data/lib/protobuf/descriptor/file_descriptor.rb +1 -1
  9. data/lib/protobuf/message/field.rb +2 -2
  10. data/lib/protobuf/rpc/buffer.rb +30 -25
  11. data/lib/protobuf/rpc/client.rb +8 -8
  12. data/lib/protobuf/rpc/connector.rb +2 -0
  13. data/lib/protobuf/rpc/connectors/base.rb +0 -1
  14. data/lib/protobuf/rpc/connectors/common.rb +48 -48
  15. data/lib/protobuf/rpc/connectors/em_client.rb +53 -27
  16. data/lib/protobuf/rpc/connectors/eventmachine.rb +14 -17
  17. data/lib/protobuf/rpc/connectors/socket.rb +23 -16
  18. data/lib/protobuf/rpc/connectors/zmq.rb +73 -0
  19. data/lib/protobuf/rpc/error.rb +1 -2
  20. data/lib/protobuf/rpc/error/client_error.rb +4 -4
  21. data/lib/protobuf/rpc/server.rb +31 -43
  22. data/lib/protobuf/rpc/servers/evented/server.rb +43 -0
  23. data/lib/protobuf/rpc/servers/evented_runner.rb +1 -1
  24. data/lib/protobuf/rpc/servers/socket/server.rb +108 -0
  25. data/lib/protobuf/rpc/servers/socket/worker.rb +59 -0
  26. data/lib/protobuf/rpc/servers/socket_runner.rb +3 -3
  27. data/lib/protobuf/rpc/servers/zmq/broker.rb +85 -0
  28. data/lib/protobuf/rpc/servers/zmq/server.rb +50 -0
  29. data/lib/protobuf/rpc/servers/zmq/util.rb +27 -0
  30. data/lib/protobuf/rpc/servers/zmq/worker.rb +72 -0
  31. data/lib/protobuf/rpc/servers/zmq_runner.rb +26 -0
  32. data/lib/protobuf/rpc/service.rb +5 -5
  33. data/lib/protobuf/version.rb +1 -1
  34. data/protobuf.gemspec +12 -10
  35. data/spec/benchmark/tasks.rb +37 -5
  36. data/spec/functional/evented_server_spec.rb +64 -0
  37. data/spec/functional/socket_server_spec.rb +63 -0
  38. data/spec/functional/zmq_server_spec.rb +63 -0
  39. data/spec/helper/server.rb +32 -12
  40. data/spec/lib/protobuf/message/encoder_spec.rb +19 -0
  41. data/spec/proto/test.pb.rb +3 -3
  42. data/spec/proto/test.proto +3 -3
  43. data/spec/proto/test_service.rb +1 -0
  44. data/spec/spec_helper.rb +6 -0
  45. data/spec/unit/message_spec.rb +1 -1
  46. data/spec/unit/rpc/client_spec.rb +11 -3
  47. data/spec/unit/rpc/connectors/common_spec.rb +0 -1
  48. data/spec/unit/rpc/connectors/eventmachine_client_spec.rb +32 -0
  49. data/spec/unit/rpc/connectors/socket_spec.rb +2 -4
  50. data/spec/unit/rpc/connectors/zmq_spec.rb +27 -0
  51. data/spec/unit/rpc/servers/evented_server_spec.rb +3 -3
  52. data/spec/unit/rpc/servers/socket_server_spec.rb +14 -13
  53. data/spec/unit/rpc/servers/zmq/broker_spec.rb +27 -0
  54. data/spec/unit/rpc/servers/zmq/server_spec.rb +37 -0
  55. data/spec/unit/rpc/servers/zmq/util_spec.rb +41 -0
  56. data/spec/unit/rpc/servers/zmq/worker_spec.rb +36 -0
  57. data/spec/unit/rpc/service_spec.rb +22 -18
  58. metadata +87 -40
  59. data/lib/protobuf/rpc/servers/evented_server.rb +0 -28
  60. data/lib/protobuf/rpc/servers/socket_server.rb +0 -146
@@ -0,0 +1,64 @@
1
+ require 'spec_helper'
2
+ require 'spec/proto/test_service_impl'
3
+
4
+ describe 'Functional EventMachine Client' do
5
+ before(:each) do
6
+ ::Spec::Proto::TestService.configure(::Spec::Proto::TestService::DEFAULT_LOCATION)
7
+ end
8
+
9
+ it 'runs fine when required fields are set' do
10
+ expect {
11
+ EventMachine.fiber_run do
12
+ StubServer.new do |server|
13
+ client = ::Spec::Proto::TestService.client(:async => false, :timeout => 5)
14
+
15
+ client.find(:name => 'Test Name', :active => true) do |c|
16
+ c.on_success do |succ|
17
+ succ.name.should eq("Test Name")
18
+ succ.status.should eq(::Spec::Proto::StatusType::ENABLED)
19
+ end
20
+
21
+ c.on_failure do |err|
22
+ raise err.inspect
23
+ end
24
+ end
25
+ end
26
+ EM.stop
27
+ end
28
+ }.to_not raise_error
29
+ end
30
+
31
+ it 'calls the on_failure callback when a message is malformed' do
32
+ error = nil
33
+ EventMachine.fiber_run do
34
+ StubServer.new do |server|
35
+ request = ::Spec::Proto::ResourceFindRequest.new(:active => true)
36
+ client = ::Spec::Proto::TestService.client(:async => false)
37
+
38
+ client.find(request) do |c|
39
+ c.on_success { raise "shouldn't pass"}
40
+ c.on_failure {|e| error = e}
41
+ end
42
+ end
43
+ EM.stop
44
+ end
45
+ error.message.should =~ /ResourceFindRequest.*fields.*improperly set.*"name"/
46
+ end
47
+
48
+ it 'calls the on_failure callback when the request type is wrong' do
49
+ error = nil
50
+ EventMachine.fiber_run do
51
+ StubServer.new do |server|
52
+ request = ::Spec::Proto::Resource.new(:name => 'Test Name')
53
+ client = ::Spec::Proto::TestService.client(:async => false)
54
+
55
+ client.find(request) do |c|
56
+ c.on_success { raise "shouldn't pass"}
57
+ c.on_failure {|e| error = e}
58
+ end
59
+ end
60
+ EM.stop
61
+ end
62
+ error.message.should =~ /expected request.*ResourceFindRequest.*Resource instead/i
63
+ end
64
+ end
@@ -0,0 +1,63 @@
1
+ require 'spec_helper'
2
+ require 'spec/proto/test_service_impl'
3
+
4
+ describe 'Functional Socket Client' do
5
+ before(:all) do
6
+ Thread.abort_on_exception = true
7
+ server = OpenStruct.new(:server => "127.0.0.1", :port => 9399, :backlog => 100, :threshold => 100)
8
+ @server_thread = Thread.new(server) { |s| Protobuf::Rpc::SocketRunner.run(s) }
9
+ Thread.pass until Protobuf::Rpc::Socket::Server.running?
10
+ end
11
+
12
+ after(:all) do
13
+ Protobuf::Rpc::SocketRunner.stop
14
+ @server_thread.join
15
+ end
16
+
17
+ it 'runs fine when required fields are set' do
18
+ expect {
19
+ with_constants "Protobuf::ClientType" => "Socket" do
20
+ client = ::Spec::Proto::TestService.client(:async => false)
21
+
22
+ client.find(:name => 'Test Name', :active => true) do |c|
23
+ c.on_success do |succ|
24
+ succ.name.should eq("Test Name")
25
+ succ.status.should eq(::Spec::Proto::StatusType::ENABLED)
26
+ end
27
+
28
+ c.on_failure do |err|
29
+ raise err.inspect
30
+ end
31
+ end
32
+ end
33
+ }.to_not raise_error
34
+ end
35
+
36
+ it 'calls the on_failure callback when a message is malformed' do
37
+ error = nil
38
+ with_constants "Protobuf::ClientType" => "Socket" do
39
+ request = ::Spec::Proto::ResourceFindRequest.new(:active => true)
40
+ client = ::Spec::Proto::TestService.client(:async => false)
41
+
42
+ client.find(request) do |c|
43
+ c.on_success { raise "shouldn't pass"}
44
+ c.on_failure {|e| error = e}
45
+ end
46
+ end
47
+ error.message.should =~ /ResourceFindRequest.*fields.*improperly set.*"name"/
48
+ end
49
+
50
+ it 'calls the on_failure callback when the request type is wrong' do
51
+ error = nil
52
+ with_constants "Protobuf::ClientType" => "Socket" do
53
+ request = ::Spec::Proto::Resource.new(:name => 'Test Name')
54
+ client = ::Spec::Proto::TestService.client(:async => false)
55
+
56
+ client.find(request) do |c|
57
+ c.on_success { raise "shouldn't pass"}
58
+ c.on_failure {|e| error = e}
59
+ end
60
+ end
61
+ error.message.should =~ /expected request.*ResourceFindRequest.*Resource instead/i
62
+ end
63
+ end
@@ -0,0 +1,63 @@
1
+ require 'spec_helper'
2
+ require 'spec/proto/test_service_impl'
3
+
4
+ describe 'Functional ZMQ Client' do
5
+ before(:all) do
6
+ Thread.abort_on_exception = true
7
+ server = OpenStruct.new(:server => "127.0.0.1", :port => 9399, :backlog => 100, :threshold => 100)
8
+ @server_thread = Thread.new(server) { |s| Protobuf::Rpc::ZmqRunner.run(s) }
9
+ Thread.pass until Protobuf::Rpc::Zmq::Server.running?
10
+ end
11
+
12
+ after(:all) do
13
+ ::Protobuf::Rpc::Zmq::Server.stop
14
+ @server_thread.join
15
+ end
16
+
17
+ it 'runs fine when required fields are set' do
18
+ expect {
19
+ with_constants "Protobuf::ClientType" => "Zmq" do
20
+ client = ::Spec::Proto::TestService.client(:async => false)
21
+
22
+ client.find(:name => 'Test Name', :active => true) do |c|
23
+ c.on_success do |succ|
24
+ succ.name.should eq("Test Name")
25
+ succ.status.should eq(::Spec::Proto::StatusType::ENABLED)
26
+ end
27
+
28
+ c.on_failure do |err|
29
+ raise err.inspect
30
+ end
31
+ end
32
+ end
33
+ }.to_not raise_error
34
+ end
35
+
36
+ it 'calls the on_failure callback when a message is malformed' do
37
+ error = nil
38
+ with_constants "Protobuf::ClientType" => "Zmq" do
39
+ request = ::Spec::Proto::ResourceFindRequest.new(:active => true)
40
+ client = ::Spec::Proto::TestService.client(:async => false)
41
+
42
+ client.find(request) do |c|
43
+ c.on_success { raise "shouldn't pass"}
44
+ c.on_failure {|e| error = e}
45
+ end
46
+ end
47
+ error.message.should =~ /ResourceFindRequest.*fields.*improperly set.*"name"/
48
+ end
49
+
50
+ it 'calls the on_failure callback when the request type is wrong' do
51
+ error = nil
52
+ with_constants "Protobuf::ClientType" => "Zmq" do
53
+ request = ::Spec::Proto::Resource.new(:name => 'Test Name')
54
+ client = ::Spec::Proto::TestService.client(:async => false)
55
+
56
+ client.find(request) do |c|
57
+ c.on_success { raise "shouldn't pass"}
58
+ c.on_failure {|e| error = e}
59
+ end
60
+ end
61
+ error.message.should =~ /expected request.*ResourceFindRequest.*Resource instead/i
62
+ end
63
+ end
@@ -1,13 +1,18 @@
1
1
  require 'ostruct'
2
2
  require 'protobuf/common/logger'
3
3
  require 'protobuf/rpc/server'
4
- require 'protobuf/rpc/servers/socket_server'
4
+ require 'protobuf/rpc/servers/socket/server'
5
5
  require 'protobuf/rpc/servers/socket_runner'
6
+ require 'protobuf/rpc/servers/zmq/server'
7
+ require 'protobuf/rpc/servers/zmq_runner'
6
8
  require 'spec/proto/test_service_impl'
7
9
 
10
+ # Want to abort if server dies?
11
+ Thread.abort_on_exception = true
12
+
8
13
  module StubProtobufServerFactory
9
14
  def self.build(delay)
10
- new_server = Class.new(Protobuf::Rpc::EventedServer) do
15
+ new_server = Class.new(Protobuf::Rpc::Evented::Server) do
11
16
  def self.sleep_interval
12
17
  @sleep_interval
13
18
  end
@@ -38,7 +43,7 @@ class StubServer
38
43
  :host => "127.0.0.1",
39
44
  :port => 9399,
40
45
  :delay => 0,
41
- :server => Protobuf::Rpc::EventedServer
46
+ :server => Protobuf::Rpc::Evented::Server
42
47
  }.merge(opts))
43
48
 
44
49
  start
@@ -48,14 +53,13 @@ class StubServer
48
53
  end
49
54
 
50
55
  def start
51
- if @options.server == Protobuf::Rpc::EventedServer
52
- start_em_server
56
+ case
57
+ when @options.server == Protobuf::Rpc::Evented::Server then start_em_server
58
+ when @options.server == Protobuf::Rpc::Zmq::Server then start_zmq_server
53
59
  else
54
- @sock_server = Thread.new(@options) { |opt| Protobuf::Rpc::SocketRunner.run(opt) }
55
- @sock_server.abort_on_exception = true # Set for testing purposes
56
- Thread.pass until Protobuf::Rpc::SocketServer.running?
60
+ start_socket_server
57
61
  end
58
- log_debug "[stub-server] Server started #{@options.host}:#{@options.port}"
62
+ log_debug { "[stub-server] Server started #{@options.host}:#{@options.port}" }
59
63
  rescue => ex
60
64
  if ex =~ /no acceptor/ # Means EM didn't shutdown in the next_tick yet
61
65
  stop
@@ -64,16 +68,32 @@ class StubServer
64
68
  end
65
69
 
66
70
  def start_em_server
67
- @server_handle = EventMachine::start_server(@options.host, @options.port, StubProtobufServerFactory.build(@options.delay))
71
+ @server_handle = EventMachine.start_server(@options.host, @options.port, StubProtobufServerFactory.build(@options.delay))
72
+ end
73
+
74
+ def start_socket_server
75
+ @sock_server = Thread.new(@options) { |opt| Protobuf::Rpc::SocketRunner.run(opt) }
76
+ @sock_server.abort_on_exception = true # Set for testing purposes
77
+ Thread.pass until Protobuf::Rpc::Socket::Server.running?
78
+ end
79
+
80
+ def start_zmq_server
81
+ @zmq_server = Thread.new(@options) { |opt| Protobuf::Rpc::ZmqRunner.run(opt) }
82
+ Thread.pass until Protobuf::Rpc::Zmq::Server.running?
68
83
  end
69
84
 
70
85
  def stop
71
- if @options.server == Protobuf::Rpc::EventedServer
86
+ case
87
+ when @options.server == Protobuf::Rpc::Evented::Server then
72
88
  EventMachine.stop_server(@server_handle) if @server_handle
89
+ when @options.server == Protobuf::Rpc::Zmq::Server then
90
+ Protobuf::Rpc::ZmqRunner.stop
91
+ @zmq_server.join if(@zmq_server)
73
92
  else
74
93
  Protobuf::Rpc::SocketRunner.stop
75
- Thread.kill(@sock_server) if @sock_server
94
+ @sock_server.join if(@sock_server)
76
95
  end
96
+
77
97
  @running = false
78
98
  end
79
99
  end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ class EncoderTest
4
+ extend ::Protobuf::Encoder
5
+ end
6
+
7
+ describe Protobuf::Encoder do
8
+ describe '#encode' do
9
+ context "when there's no value for a required field" do
10
+ let(:message) { ::Spec::Proto::Resource.new }
11
+ let(:stream) { StringIO.new }
12
+ it "raises a 'message not initialized' error" do
13
+ expect {
14
+ EncoderTest.__send__(:encode, stream, message)
15
+ }.to raise_error(Protobuf::NotInitializedError, /message.*not initialized/i)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -12,11 +12,11 @@ module Spec
12
12
  define :DELETED, 3
13
13
  end
14
14
  class ResourceFindRequest < ::Protobuf::Message
15
- optional :string, :name, 1
15
+ required :string, :name, 1
16
16
  optional :bool, :active, 2
17
17
  end
18
18
  class Resource < ::Protobuf::Message
19
- optional :string, :name, 1
19
+ required :string, :name, 1
20
20
  optional :int64, :date_created, 2
21
21
  optional :StatusType, :status, 3
22
22
  repeated :StatusType, :repeated_enum, 4
@@ -28,4 +28,4 @@ module Spec
28
28
  optional :StatusType, :status, 4
29
29
  end
30
30
  end
31
- end
31
+ end
@@ -8,12 +8,12 @@ enum StatusType {
8
8
  }
9
9
 
10
10
  message ResourceFindRequest {
11
- optional string name = 1;
11
+ required string name = 1;
12
12
  optional bool active = 2;
13
13
  }
14
14
 
15
15
  message Resource {
16
- optional string name = 1;
16
+ required string name = 1;
17
17
  optional int64 date_created = 2;
18
18
  optional StatusType status = 3;
19
19
  repeated StatusType repeated_enum = 4;
@@ -28,4 +28,4 @@ message Nested {
28
28
 
29
29
  service TestService {
30
30
  rpc Find (ResourceFindRequest) returns (Resource);
31
- }
31
+ }
@@ -1,4 +1,5 @@
1
1
  require 'protobuf/rpc/service'
2
+ require 'spec/proto/test.pb'
2
3
 
3
4
  ## !! DO NOT EDIT THIS FILE !!
4
5
  ##
@@ -11,6 +11,12 @@ $:.push File.expand_path('../lib', File.dirname(__FILE__))
11
11
  require 'protobuf'
12
12
  require 'protobuf/rpc/client'
13
13
  require File.dirname(__FILE__) + '/helper/all'
14
+ require 'pry'
15
+
16
+ # these aren't explicitly required in lib/protobuf.rb. We require them here for
17
+ # testing purposes
18
+ require 'ffi-rzmq'
19
+ require 'protobuf/rpc/connectors/zmq'
14
20
 
15
21
  # Including a way to turn on debug logger for spec runs
16
22
  if ENV["DEBUG"]
@@ -64,4 +64,4 @@ describe Protobuf::Message do
64
64
 
65
65
  end
66
66
 
67
- end
67
+ end
@@ -2,6 +2,9 @@ require 'spec_helper'
2
2
  require 'spec/proto/test_service_impl'
3
3
 
4
4
  describe Protobuf::Rpc::Client do
5
+ before(:each) do
6
+ ::Spec::Proto::TestService.configure(::Spec::Proto::TestService::DEFAULT_LOCATION)
7
+ end
5
8
 
6
9
  context "when using fiber based calls" do
7
10
  it "waits for response when running synchronously" do
@@ -55,17 +58,22 @@ describe Protobuf::Rpc::Client do
55
58
  end
56
59
 
57
60
  it "throws a timeout when client timeout is exceeded" do
58
- subject = Proc.new do
61
+ error = nil
62
+ test_proc = Proc.new do
59
63
  EventMachine.fiber_run do
60
64
  StubServer.new(:delay => 2) do |server|
61
65
  client = Spec::Proto::TestService.client(:async => false, :timeout => 1)
62
- client.find(:name => "Test Name", :active => true)
66
+ client.find(:name => "Test Name", :active => true) do |cl|
67
+ cl.on_success {}
68
+ cl.on_failure {|f| error = f}
69
+ end
63
70
  end
64
71
  EM.stop
65
72
  end
66
73
  end
67
74
 
68
- subject.should raise_error(RuntimeError, /timeout/i)
75
+ test_proc.call
76
+ error.message.should =~ /timeout/i
69
77
  end
70
78
 
71
79
  context "without reactor_running?" do
@@ -19,7 +19,6 @@ describe Protobuf::Rpc::Connectors::Common do
19
19
  specify{ subject.respond_to?(:fail).should be_true }
20
20
  specify{ subject.respond_to?(:complete).should be_true }
21
21
  specify{ subject.respond_to?(:parse_response).should be_true }
22
- specify{ subject.respond_to?(:_send_request).should be_true }
23
22
  specify{ subject.respond_to?(:verify_options).should be_true }
24
23
  specify{ subject.respond_to?(:verify_callbacks).should be_true }
25
24
  end
@@ -0,0 +1,32 @@
1
+ require 'spec_helper'
2
+
3
+ describe ::Protobuf::Rpc::Connectors::EMClient do
4
+ describe '#send_data' do
5
+ context 'when sending data errs' do
6
+ let(:buffer_double) do
7
+ bd = double(Protobuf::Rpc::Buffer)
8
+ bd.should_receive(:set_data)
9
+ bd
10
+ end
11
+
12
+ it 'sets the error instance' do
13
+ buffer_double.should_receive(:write).and_raise(RuntimeError.new('Failure for testing'))
14
+ Protobuf::Rpc::Buffer.stub(:new).with(:read).and_return(Protobuf::Rpc::Buffer.new(:read))
15
+ Protobuf::Rpc::Buffer.stub(:new).with(:write).and_return(buffer_double)
16
+ error = nil
17
+ test_proc = Proc.new do
18
+ StubServer.new do |server|
19
+ client = ::Spec::Proto::TestService.client
20
+ client.find(:name => 'Test Name', :active => true) do |c|
21
+ c.on_failure do |f|
22
+ error = f
23
+ end
24
+ end
25
+ end
26
+ end
27
+ test_proc.call
28
+ error.should_not be_nil
29
+ end
30
+ end
31
+ end
32
+ end
@@ -24,13 +24,12 @@ describe Protobuf::Rpc::Connectors::Socket do
24
24
 
25
25
  it "fills the buffer with data from the socket" do
26
26
  socket = StringIO.new("#{data.bytesize}-#{data}")
27
- subject.instance_variable_set(:@buffer, Protobuf::Rpc::Buffer.new(:read))
28
27
  subject.instance_variable_set(:@socket, socket)
28
+ subject.instance_variable_set(:@stats, OpenStruct.new)
29
29
  subject.should_receive(:parse_response).and_return(true)
30
30
 
31
31
  subject.__send__(:read_response)
32
- subject.instance_variable_get(:@buffer).flushed?.should be_true
33
- subject.instance_variable_get(:@buffer).data.should eq(data)
32
+ subject.instance_variable_get(:@response_data).should eq(data)
34
33
  end
35
34
  end
36
35
 
@@ -45,5 +44,4 @@ describe Protobuf::Rpc::Connectors::Socket do
45
44
  expect{ conn.__send__(:check_async) }.to_not raise_error
46
45
  end
47
46
  end
48
-
49
47
  end