prepor-protobuf 3.5.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 (182) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +21 -0
  3. data/.rubocop.yml +51 -0
  4. data/.rubocop_todo.yml +89 -0
  5. data/.travis.yml +25 -0
  6. data/.yardopts +5 -0
  7. data/CHANGES.md +256 -0
  8. data/CONTRIBUTING.md +16 -0
  9. data/Gemfile +3 -0
  10. data/LICENSE.txt +22 -0
  11. data/README.md +33 -0
  12. data/Rakefile +64 -0
  13. data/bin/protoc-gen-ruby +16 -0
  14. data/bin/rpc_server +5 -0
  15. data/install-protobuf.sh +28 -0
  16. data/lib/protobuf.rb +100 -0
  17. data/lib/protobuf/cli.rb +242 -0
  18. data/lib/protobuf/code_generator.rb +44 -0
  19. data/lib/protobuf/decoder.rb +73 -0
  20. data/lib/protobuf/deprecation.rb +112 -0
  21. data/lib/protobuf/descriptors.rb +3 -0
  22. data/lib/protobuf/descriptors/google/protobuf/compiler/plugin.pb.rb +48 -0
  23. data/lib/protobuf/descriptors/google/protobuf/descriptor.pb.rb +251 -0
  24. data/lib/protobuf/encoder.rb +67 -0
  25. data/lib/protobuf/enum.rb +303 -0
  26. data/lib/protobuf/exceptions.rb +9 -0
  27. data/lib/protobuf/field.rb +74 -0
  28. data/lib/protobuf/field/base_field.rb +267 -0
  29. data/lib/protobuf/field/bool_field.rb +59 -0
  30. data/lib/protobuf/field/bytes_field.rb +82 -0
  31. data/lib/protobuf/field/double_field.rb +25 -0
  32. data/lib/protobuf/field/enum_field.rb +68 -0
  33. data/lib/protobuf/field/field_array.rb +87 -0
  34. data/lib/protobuf/field/fixed32_field.rb +25 -0
  35. data/lib/protobuf/field/fixed64_field.rb +28 -0
  36. data/lib/protobuf/field/float_field.rb +41 -0
  37. data/lib/protobuf/field/int32_field.rb +21 -0
  38. data/lib/protobuf/field/int64_field.rb +21 -0
  39. data/lib/protobuf/field/integer_field.rb +23 -0
  40. data/lib/protobuf/field/message_field.rb +65 -0
  41. data/lib/protobuf/field/sfixed32_field.rb +27 -0
  42. data/lib/protobuf/field/sfixed64_field.rb +28 -0
  43. data/lib/protobuf/field/signed_integer_field.rb +29 -0
  44. data/lib/protobuf/field/sint32_field.rb +21 -0
  45. data/lib/protobuf/field/sint64_field.rb +21 -0
  46. data/lib/protobuf/field/string_field.rb +34 -0
  47. data/lib/protobuf/field/uint32_field.rb +21 -0
  48. data/lib/protobuf/field/uint64_field.rb +21 -0
  49. data/lib/protobuf/field/varint_field.rb +73 -0
  50. data/lib/protobuf/generators/base.rb +70 -0
  51. data/lib/protobuf/generators/enum_generator.rb +41 -0
  52. data/lib/protobuf/generators/extension_generator.rb +27 -0
  53. data/lib/protobuf/generators/field_generator.rb +131 -0
  54. data/lib/protobuf/generators/file_generator.rb +135 -0
  55. data/lib/protobuf/generators/group_generator.rb +112 -0
  56. data/lib/protobuf/generators/message_generator.rb +98 -0
  57. data/lib/protobuf/generators/printable.rb +160 -0
  58. data/lib/protobuf/generators/service_generator.rb +26 -0
  59. data/lib/protobuf/lifecycle.rb +33 -0
  60. data/lib/protobuf/logging.rb +39 -0
  61. data/lib/protobuf/message.rb +193 -0
  62. data/lib/protobuf/message/fields.rb +133 -0
  63. data/lib/protobuf/message/serialization.rb +89 -0
  64. data/lib/protobuf/optionable.rb +23 -0
  65. data/lib/protobuf/rpc/buffer.rb +77 -0
  66. data/lib/protobuf/rpc/client.rb +168 -0
  67. data/lib/protobuf/rpc/connector.rb +19 -0
  68. data/lib/protobuf/rpc/connectors/base.rb +55 -0
  69. data/lib/protobuf/rpc/connectors/common.rb +176 -0
  70. data/lib/protobuf/rpc/connectors/socket.rb +73 -0
  71. data/lib/protobuf/rpc/connectors/zmq.rb +322 -0
  72. data/lib/protobuf/rpc/dynamic_discovery.pb.rb +49 -0
  73. data/lib/protobuf/rpc/env.rb +58 -0
  74. data/lib/protobuf/rpc/error.rb +28 -0
  75. data/lib/protobuf/rpc/error/client_error.rb +31 -0
  76. data/lib/protobuf/rpc/error/server_error.rb +43 -0
  77. data/lib/protobuf/rpc/middleware.rb +25 -0
  78. data/lib/protobuf/rpc/middleware/exception_handler.rb +36 -0
  79. data/lib/protobuf/rpc/middleware/logger.rb +91 -0
  80. data/lib/protobuf/rpc/middleware/request_decoder.rb +83 -0
  81. data/lib/protobuf/rpc/middleware/response_encoder.rb +88 -0
  82. data/lib/protobuf/rpc/middleware/runner.rb +18 -0
  83. data/lib/protobuf/rpc/rpc.pb.rb +55 -0
  84. data/lib/protobuf/rpc/server.rb +39 -0
  85. data/lib/protobuf/rpc/servers/socket/server.rb +123 -0
  86. data/lib/protobuf/rpc/servers/socket/worker.rb +56 -0
  87. data/lib/protobuf/rpc/servers/socket_runner.rb +40 -0
  88. data/lib/protobuf/rpc/servers/zmq/broker.rb +193 -0
  89. data/lib/protobuf/rpc/servers/zmq/server.rb +320 -0
  90. data/lib/protobuf/rpc/servers/zmq/util.rb +48 -0
  91. data/lib/protobuf/rpc/servers/zmq/worker.rb +104 -0
  92. data/lib/protobuf/rpc/servers/zmq_runner.rb +62 -0
  93. data/lib/protobuf/rpc/service.rb +179 -0
  94. data/lib/protobuf/rpc/service_directory.rb +253 -0
  95. data/lib/protobuf/rpc/service_dispatcher.rb +46 -0
  96. data/lib/protobuf/rpc/service_filters.rb +272 -0
  97. data/lib/protobuf/rpc/stat.rb +97 -0
  98. data/lib/protobuf/socket.rb +21 -0
  99. data/lib/protobuf/tasks.rb +1 -0
  100. data/lib/protobuf/tasks/compile.rake +61 -0
  101. data/lib/protobuf/version.rb +3 -0
  102. data/lib/protobuf/wire_type.rb +10 -0
  103. data/lib/protobuf/zmq.rb +21 -0
  104. data/proto/dynamic_discovery.proto +44 -0
  105. data/proto/google/protobuf/compiler/plugin.proto +147 -0
  106. data/proto/google/protobuf/descriptor.proto +620 -0
  107. data/proto/rpc.proto +62 -0
  108. data/protobuf.gemspec +51 -0
  109. data/spec/benchmark/tasks.rb +139 -0
  110. data/spec/bin/protoc-gen-ruby_spec.rb +23 -0
  111. data/spec/data/data.bin +3 -0
  112. data/spec/data/types.bin +0 -0
  113. data/spec/encoding/all_types_spec.rb +105 -0
  114. data/spec/encoding/extreme_values_spec.rb +0 -0
  115. data/spec/functional/class_inheritance_spec.rb +52 -0
  116. data/spec/functional/socket_server_spec.rb +59 -0
  117. data/spec/functional/zmq_server_spec.rb +105 -0
  118. data/spec/lib/protobuf/cli_spec.rb +273 -0
  119. data/spec/lib/protobuf/code_generator_spec.rb +60 -0
  120. data/spec/lib/protobuf/enum_spec.rb +265 -0
  121. data/spec/lib/protobuf/field/bool_field_spec.rb +51 -0
  122. data/spec/lib/protobuf/field/field_array_spec.rb +69 -0
  123. data/spec/lib/protobuf/field/float_field_spec.rb +55 -0
  124. data/spec/lib/protobuf/field/int32_field_spec.rb +89 -0
  125. data/spec/lib/protobuf/field/string_field_spec.rb +45 -0
  126. data/spec/lib/protobuf/field_spec.rb +191 -0
  127. data/spec/lib/protobuf/generators/base_spec.rb +84 -0
  128. data/spec/lib/protobuf/generators/enum_generator_spec.rb +73 -0
  129. data/spec/lib/protobuf/generators/extension_generator_spec.rb +42 -0
  130. data/spec/lib/protobuf/generators/field_generator_spec.rb +102 -0
  131. data/spec/lib/protobuf/generators/file_generator_spec.rb +32 -0
  132. data/spec/lib/protobuf/generators/message_generator_spec.rb +0 -0
  133. data/spec/lib/protobuf/generators/service_generator_spec.rb +46 -0
  134. data/spec/lib/protobuf/lifecycle_spec.rb +94 -0
  135. data/spec/lib/protobuf/message_spec.rb +526 -0
  136. data/spec/lib/protobuf/optionable_spec.rb +46 -0
  137. data/spec/lib/protobuf/rpc/client_spec.rb +66 -0
  138. data/spec/lib/protobuf/rpc/connector_spec.rb +26 -0
  139. data/spec/lib/protobuf/rpc/connectors/base_spec.rb +50 -0
  140. data/spec/lib/protobuf/rpc/connectors/common_spec.rb +170 -0
  141. data/spec/lib/protobuf/rpc/connectors/socket_spec.rb +36 -0
  142. data/spec/lib/protobuf/rpc/connectors/zmq_spec.rb +117 -0
  143. data/spec/lib/protobuf/rpc/middleware/exception_handler_spec.rb +62 -0
  144. data/spec/lib/protobuf/rpc/middleware/logger_spec.rb +49 -0
  145. data/spec/lib/protobuf/rpc/middleware/request_decoder_spec.rb +115 -0
  146. data/spec/lib/protobuf/rpc/middleware/response_encoder_spec.rb +75 -0
  147. data/spec/lib/protobuf/rpc/servers/socket_server_spec.rb +38 -0
  148. data/spec/lib/protobuf/rpc/servers/zmq/server_spec.rb +43 -0
  149. data/spec/lib/protobuf/rpc/servers/zmq/util_spec.rb +55 -0
  150. data/spec/lib/protobuf/rpc/servers/zmq/worker_spec.rb +35 -0
  151. data/spec/lib/protobuf/rpc/service_directory_spec.rb +293 -0
  152. data/spec/lib/protobuf/rpc/service_dispatcher_spec.rb +52 -0
  153. data/spec/lib/protobuf/rpc/service_filters_spec.rb +517 -0
  154. data/spec/lib/protobuf/rpc/service_spec.rb +162 -0
  155. data/spec/lib/protobuf/rpc/stat_spec.rb +68 -0
  156. data/spec/lib/protobuf_spec.rb +98 -0
  157. data/spec/spec_helper.rb +44 -0
  158. data/spec/support/all.rb +6 -0
  159. data/spec/support/packed_field.rb +22 -0
  160. data/spec/support/server.rb +64 -0
  161. data/spec/support/test/all_types.data.bin +0 -0
  162. data/spec/support/test/all_types.data.txt +119 -0
  163. data/spec/support/test/defaults.pb.rb +27 -0
  164. data/spec/support/test/defaults.proto +9 -0
  165. data/spec/support/test/enum.pb.rb +55 -0
  166. data/spec/support/test/enum.proto +34 -0
  167. data/spec/support/test/extended.pb.rb +18 -0
  168. data/spec/support/test/extended.proto +10 -0
  169. data/spec/support/test/extreme_values.data.bin +0 -0
  170. data/spec/support/test/google_unittest.pb.rb +537 -0
  171. data/spec/support/test/google_unittest.proto +713 -0
  172. data/spec/support/test/google_unittest_import.pb.rb +39 -0
  173. data/spec/support/test/google_unittest_import.proto +64 -0
  174. data/spec/support/test/google_unittest_import_public.pb.rb +10 -0
  175. data/spec/support/test/google_unittest_import_public.proto +38 -0
  176. data/spec/support/test/multi_field_extensions.pb.rb +58 -0
  177. data/spec/support/test/multi_field_extensions.proto +33 -0
  178. data/spec/support/test/resource.pb.rb +119 -0
  179. data/spec/support/test/resource.proto +94 -0
  180. data/spec/support/test/resource_service.rb +23 -0
  181. data/spec/support/test_app_file.rb +2 -0
  182. metadata +502 -0
@@ -0,0 +1,46 @@
1
+ require 'spec_helper'
2
+ require 'protobuf/optionable'
3
+
4
+ RSpec.describe 'Optionable' do
5
+
6
+ describe '.set_option' do
7
+ before(:all) do
8
+ OptionableSetOptionTest = ::Class.new do
9
+ include ::Protobuf::Optionable
10
+ end
11
+ end
12
+
13
+ it 'stores the given option and value' do
14
+ expect(OptionableSetOptionTest).to respond_to(:set_option)
15
+ expect(OptionableSetOptionTest.method(:set_option).arity).to eq(-2)
16
+ expect do
17
+ OptionableSetOptionTest.set_option(:foo, :bar)
18
+ end.to_not raise_error
19
+ end
20
+
21
+ it 'defaults the value to true' do
22
+ OptionableSetOptionTest.set_option(:baz_enabled)
23
+ expect(OptionableSetOptionTest.get_option(:baz_enabled)).to be true
24
+ end
25
+ end
26
+
27
+ describe '.get_option' do
28
+ before(:all) do
29
+ OptionableGetOptionTest = ::Class.new do
30
+ include ::Protobuf::Optionable
31
+ set_option :foo, :bar
32
+ end
33
+ end
34
+
35
+ it 'retrieves the option for the given name, if any' do
36
+ expect(OptionableGetOptionTest.get_option(:foo)).to eq(:bar)
37
+ expect(OptionableGetOptionTest.get_option(:baz)).to be_nil
38
+ end
39
+
40
+ it 'retrieves the option in the context of an instance' do
41
+ expect(OptionableGetOptionTest.new.get_option(:foo)).to eq(:bar)
42
+ expect(OptionableGetOptionTest.new.get_option(:baz)).to be_nil
43
+ end
44
+ end
45
+
46
+ end
@@ -0,0 +1,66 @@
1
+ require 'spec_helper'
2
+ require 'spec/support/test/resource_service'
3
+
4
+ RSpec.describe Protobuf::Rpc::Client do
5
+ before(:each) do
6
+ load 'protobuf/socket.rb'
7
+ end
8
+
9
+ context 'when creating a client from a service' do
10
+ before { reset_service_location(Test::ResourceService) }
11
+
12
+ it 'should be able to get a client through the Service#client helper method' do
13
+ expect(::Test::ResourceService.client(:port => 9191)).to eq(Protobuf::Rpc::Client.new(:service => Test::ResourceService, :port => 9191))
14
+ end
15
+
16
+ it "should be able to override a service location's host and port" do
17
+ Test::ResourceService.located_at 'somewheregreat.com:12345'
18
+ clean_client = Test::ResourceService.client
19
+ expect(clean_client.options[:host]).to eq('somewheregreat.com')
20
+ expect(clean_client.options[:port]).to eq(12345)
21
+
22
+ updated_client = Test::ResourceService.client(:host => 'amazing.com', :port => 54321)
23
+ expect(updated_client.options[:host]).to eq('amazing.com')
24
+ expect(updated_client.options[:port]).to eq(54321)
25
+ end
26
+
27
+ it 'should be able to define which service to create itself for' do
28
+ client = Protobuf::Rpc::Client.new :service => Test::ResourceService
29
+ expect(client.options[:service]).to eq(Test::ResourceService)
30
+ end
31
+
32
+ it 'should have a hard default for host and port on a service that has not been configured' do
33
+ client = Test::ResourceService.client
34
+ expect(client.options[:host]).to eq(Protobuf::Rpc::Service::DEFAULT_HOST)
35
+ expect(client.options[:port]).to eq(Protobuf::Rpc::Service::DEFAULT_PORT)
36
+ end
37
+
38
+ end
39
+
40
+ context 'when calling methods on a service client' do
41
+
42
+ # NOTE: we are assuming the service methods are accurately
43
+ # defined inside spec/proto/test_service.rb,
44
+ # namely the :find method
45
+
46
+ it 'should respond to defined service methods' do
47
+ client = Test::ResourceService.client
48
+ expect(client).to receive(:send_request).and_return(nil)
49
+ expect { client.find(nil) }.to_not raise_error
50
+ end
51
+ end
52
+
53
+ context 'when receiving request objects' do
54
+
55
+ it 'should be able to create the correct request object if passed a hash' do
56
+ client = Test::ResourceService.client
57
+ expect(client).to receive(:send_request)
58
+ client.find(:name => 'Test Name', :active => false)
59
+ expect(client.options[:request]).to be_a(Test::ResourceFindRequest)
60
+ expect(client.options[:request].name).to eq('Test Name')
61
+ expect(client.options[:request].active).to eq(false)
62
+ end
63
+
64
+ end
65
+
66
+ end
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+ require 'protobuf/socket'
3
+ require 'protobuf/zmq'
4
+
5
+ RSpec.describe ::Protobuf::Rpc::Connector do
6
+
7
+ describe '.connector_for_client(true)' do
8
+ subject { described_class.connector_for_client }
9
+
10
+ context 'Protobuf.connector_type is socket' do
11
+ before { ::Protobuf.connector_type = :socket }
12
+ specify { expect(subject).to eq ::Protobuf::Rpc::Connectors::Socket }
13
+ end
14
+
15
+ context 'Protobuf.connector_type is not a known value' do
16
+ before { allow(::Protobuf).to receive(:connector_type).and_return(:foo) }
17
+ specify { expect(subject).to eq(::Protobuf::Rpc::Connectors::Socket) }
18
+ end
19
+
20
+ context 'Protobuf.connector_type is zmq' do
21
+ before { ::Protobuf.connector_type = :zmq }
22
+ specify { expect(subject).to eq(::Protobuf::Rpc::Connectors::Zmq) }
23
+ end
24
+ end
25
+
26
+ end
@@ -0,0 +1,50 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Protobuf::Rpc::Connectors::Base do
4
+
5
+ let(:options) do
6
+ { :timeout => 60 }
7
+ end
8
+
9
+ subject { Protobuf::Rpc::Connectors::Base.new(options) }
10
+
11
+ describe "#send_request" do
12
+ it "raising an error when 'send_request' is not overridden" do
13
+ expect { subject.send_request }.to raise_error(RuntimeError, /inherit a Connector/)
14
+ end
15
+
16
+ it "does not raise error when 'send_request' is overridden" do
17
+ new_sub = Class.new(subject.class) { def send_request; end }.new(options)
18
+ expect { new_sub.send_request }.to_not raise_error
19
+ end
20
+ end
21
+
22
+ describe '.new' do
23
+ it 'assigns passed options and initializes success/failure callbacks' do
24
+ expect(subject.options).to eq(Protobuf::Rpc::Connectors::DEFAULT_OPTIONS.merge(options))
25
+ expect(subject.success_cb).to be_nil
26
+ expect(subject.failure_cb).to be_nil
27
+ end
28
+ end
29
+
30
+ describe '#success_cb' do
31
+ it 'allows setting the success callback and calling it' do
32
+ expect(subject.success_cb).to be_nil
33
+ cb = proc { |res| fail res }
34
+ subject.success_cb = cb
35
+ expect(subject.success_cb).to eq(cb)
36
+ expect { subject.success_cb.call('an error from cb') }.to raise_error 'an error from cb'
37
+ end
38
+ end
39
+
40
+ describe '#failure_cb' do
41
+ it 'allows setting the failure callback and calling it' do
42
+ expect(subject.failure_cb).to be_nil
43
+ cb = proc { |res| fail res }
44
+ subject.failure_cb = cb
45
+ expect(subject.failure_cb).to eq(cb)
46
+ expect { subject.failure_cb.call('an error from cb') }.to raise_error 'an error from cb'
47
+ end
48
+ end
49
+
50
+ end
@@ -0,0 +1,170 @@
1
+ require 'spec_helper'
2
+ require 'protobuf/rpc/service'
3
+
4
+ RSpec.describe Protobuf::Rpc::Connectors::Common do
5
+ let(:common_class) do
6
+ Class.new(Protobuf::Rpc::Connectors::Base) do
7
+ include Protobuf::Rpc::Connectors::Common
8
+ attr_accessor :options
9
+ attr_accessor :stats
10
+ end
11
+ end
12
+
13
+ let(:subject_options) { {} }
14
+
15
+ subject { @subject ||= common_class.new(subject_options) }
16
+
17
+ context "API" do
18
+ specify { expect(subject.respond_to?(:any_callbacks?)).to be true }
19
+ specify { expect(subject.respond_to?(:request_caller)).to be true }
20
+ specify { expect(subject.respond_to?(:data_callback)).to be true }
21
+ specify { expect(subject.respond_to?(:error)).to be true }
22
+ specify { expect(subject.respond_to?(:failure)).to be true }
23
+ specify { expect(subject.respond_to?(:complete)).to be true }
24
+ specify { expect(subject.respond_to?(:parse_response)).to be true }
25
+ specify { expect(subject.respond_to?(:verify_options!)).to be true }
26
+ specify { expect(subject.respond_to?(:verify_callbacks)).to be true }
27
+ end
28
+
29
+ describe "#any_callbacks?" do
30
+
31
+ [:@complete_cb, :@success_cb, :@failure_cb].each do |cb|
32
+ it "returns true if #{cb} is provided" do
33
+ subject.instance_variable_set(cb, "something")
34
+ expect(subject.any_callbacks?).to be true
35
+ end
36
+ end
37
+
38
+ it "returns false when all callbacks are not provided" do
39
+ subject.instance_variable_set(:@complete_cb, nil)
40
+ subject.instance_variable_set(:@success_cb, nil)
41
+ subject.instance_variable_set(:@failure_cb, nil)
42
+
43
+ expect(subject.any_callbacks?).to be false
44
+ end
45
+
46
+ end
47
+
48
+ describe '#request_caller' do
49
+ specify { expect(subject.request_caller).to eq ::Protobuf.client_host }
50
+
51
+ context 'when "client_host" option is given to initializer' do
52
+ let(:hostname) { 'myhost.myserver.com' }
53
+ let(:subject_options) { { :client_host => hostname } }
54
+
55
+ specify { expect(subject.request_caller).to_not eq ::Protobuf.client_host }
56
+ specify { expect(subject.request_caller).to eq hostname }
57
+ end
58
+ end
59
+
60
+ describe "#data_callback" do
61
+ it "changes state to use the data callback" do
62
+ subject.data_callback("data")
63
+ expect(subject.instance_variable_get(:@used_data_callback)).to be true
64
+ end
65
+
66
+ it "sets the data var when using the data_callback" do
67
+ subject.data_callback("data")
68
+ expect(subject.instance_variable_get(:@data)).to eq("data")
69
+ end
70
+ end
71
+
72
+ describe '#request_bytes' do
73
+ let(:service) { Test::ResourceService }
74
+ let(:method) { :find }
75
+ let(:request) { '' }
76
+ let(:client_host) { 'myhost.myservice.com' }
77
+ let(:subject_options) do
78
+ {
79
+ :service => service,
80
+ :method => method,
81
+ :request => request,
82
+ :client_host => client_host,
83
+ }
84
+ end
85
+
86
+ let(:expected) do
87
+ ::Protobuf::Socketrpc::Request.new(
88
+ :service_name => service.name,
89
+ :method_name => 'find',
90
+ :request_proto => '',
91
+ :caller => client_host,
92
+ )
93
+ end
94
+
95
+ before { allow(subject).to receive(:validate_request_type!).and_return(true) }
96
+ before { expect(subject).not_to receive(:failure) }
97
+
98
+ specify { expect(subject.request_bytes).to eq expected.encode }
99
+ end
100
+
101
+ describe "#verify_callbacks" do
102
+
103
+ it "sets @failure_cb to #data_callback when no callbacks are defined" do
104
+ subject.verify_callbacks
105
+ expect(subject.instance_variable_get(:@failure_cb)).to eq(subject.method(:data_callback))
106
+ end
107
+
108
+ it "sets @success_cb to #data_callback when no callbacks are defined" do
109
+ subject.verify_callbacks
110
+ expect(subject.instance_variable_get(:@success_cb)).to eq(subject.method(:data_callback))
111
+ end
112
+
113
+ it "doesn't set @failure_cb when already defined" do
114
+ set_cb = -> { true }
115
+ subject.instance_variable_set(:@failure_cb, set_cb)
116
+ subject.verify_callbacks
117
+ expect(subject.instance_variable_get(:@failure_cb)).to eq(set_cb)
118
+ expect(subject.instance_variable_get(:@failure_cb)).to_not eq(subject.method(:data_callback))
119
+ end
120
+
121
+ it "doesn't set @success_cb when already defined" do
122
+ set_cb = -> { true }
123
+ subject.instance_variable_set(:@success_cb, set_cb)
124
+ subject.verify_callbacks
125
+ expect(subject.instance_variable_get(:@success_cb)).to eq(set_cb)
126
+ expect(subject.instance_variable_get(:@success_cb)).to_not eq(subject.method(:data_callback))
127
+ end
128
+
129
+ end
130
+
131
+ shared_examples "a ConnectorDisposition" do |meth, cb, *args|
132
+
133
+ it "calls #complete before exit" do
134
+ subject.stats = double("Object", :stop => true)
135
+
136
+ expect(subject).to receive(:complete)
137
+ subject.method(meth).call(*args)
138
+ end
139
+
140
+ it "calls the #{cb} callback when provided" do
141
+ stats = double("Object")
142
+ allow(stats).to receive(:stop).and_return(true)
143
+ subject.stats = stats
144
+ some_cb = double("Object")
145
+
146
+ subject.instance_variable_set("@#{cb}", some_cb)
147
+ expect(some_cb).to receive(:call).and_return(true)
148
+ subject.method(meth).call(*args)
149
+ end
150
+
151
+ it "calls the complete callback when provided" do
152
+ stats = double("Object")
153
+ allow(stats).to receive(:stop).and_return(true)
154
+ subject.stats = stats
155
+ comp_cb = double("Object")
156
+
157
+ subject.instance_variable_set(:@complete_cb, comp_cb)
158
+ expect(comp_cb).to receive(:call).and_return(true)
159
+ subject.method(meth).call(*args)
160
+ end
161
+
162
+ end
163
+
164
+ it_behaves_like("a ConnectorDisposition", :failure, "failure_cb", "code", "message")
165
+ it_behaves_like("a ConnectorDisposition", :failure, "complete_cb", "code", "message")
166
+ it_behaves_like("a ConnectorDisposition", :succeed, "complete_cb", "response")
167
+ it_behaves_like("a ConnectorDisposition", :succeed, "success_cb", "response")
168
+ it_behaves_like("a ConnectorDisposition", :complete, "complete_cb")
169
+
170
+ end
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+ require 'protobuf/socket'
3
+
4
+ RSpec.shared_examples "a Protobuf Connector" do
5
+ subject { described_class.new({}) }
6
+
7
+ context "API" do
8
+ # Check the API
9
+ specify { expect(subject.respond_to?(:send_request, true)).to be true }
10
+ specify { expect(subject.respond_to?(:post_init, true)).to be true }
11
+ specify { expect(subject.respond_to?(:close_connection, true)).to be true }
12
+ specify { expect(subject.respond_to?(:error?, true)).to be true }
13
+ end
14
+ end
15
+
16
+ RSpec.describe Protobuf::Rpc::Connectors::Socket do
17
+ subject { described_class.new({}) }
18
+
19
+ it_behaves_like "a Protobuf Connector"
20
+
21
+ specify { expect(described_class.include?(Protobuf::Rpc::Connectors::Common)).to be true }
22
+
23
+ context "#read_response" do
24
+ let(:data) { "New data" }
25
+
26
+ it "fills the buffer with data from the socket" do
27
+ socket = StringIO.new("#{data.bytesize}-#{data}")
28
+ subject.instance_variable_set(:@socket, socket)
29
+ subject.instance_variable_set(:@stats, OpenStruct.new)
30
+ expect(subject).to receive(:parse_response).and_return(true)
31
+
32
+ subject.__send__(:read_response)
33
+ expect(subject.instance_variable_get(:@response_data)).to eq(data)
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,117 @@
1
+ require 'spec_helper'
2
+ require 'protobuf/zmq'
3
+
4
+ RSpec.describe ::Protobuf::Rpc::Connectors::Zmq do
5
+ subject { described_class.new(options) }
6
+
7
+ let(:options) do
8
+ {
9
+ :service => "Test::Service",
10
+ :method => "find",
11
+ :timeout => 3,
12
+ :host => "127.0.0.1",
13
+ :port => "9400",
14
+ }
15
+ end
16
+
17
+ let(:socket_double) { double(::ZMQ::Socket, :connect => 0) }
18
+ let(:zmq_context_double) { double(::ZMQ::Context, :socket => socket_double) }
19
+
20
+ before do
21
+ allow(::ZMQ::Context).to receive(:new).and_return(zmq_context_double)
22
+ allow(socket_double).to receive(:setsockopt)
23
+ end
24
+
25
+ before(:all) do
26
+ @ping_port_before = ENV['PB_RPC_PING_PORT']
27
+ end
28
+
29
+ after(:all) do
30
+ ENV['PB_RPC_PING_PORT'] = @ping_port_before
31
+ end
32
+
33
+ describe "#lookup_server_uri" do
34
+ let(:service_directory) { double('ServiceDirectory', :running? => running?) }
35
+ let(:listing) { double('Listing', :address => '127.0.0.2', :port => 9399) }
36
+ let(:listings) { [listing] }
37
+ let(:running?) { true }
38
+
39
+ before { allow(subject).to receive(:service_directory).and_return(service_directory) }
40
+
41
+ context "when the service directory is running" do
42
+ it "searches the service directory" do
43
+ allow(service_directory).to receive(:all_listings_for).and_return(listings)
44
+ expect(subject.send(:lookup_server_uri)).to eq "tcp://127.0.0.2:9399"
45
+ end
46
+
47
+ it "defaults to the options" do
48
+ allow(service_directory).to receive(:all_listings_for).and_return([])
49
+ expect(subject.send(:lookup_server_uri)).to eq "tcp://127.0.0.1:9400"
50
+ end
51
+ end
52
+
53
+ context "when the service directory is not running" do
54
+ let(:running?) { false }
55
+
56
+ it "defaults to the options" do
57
+ allow(service_directory).to receive(:all_listings_for).and_return([])
58
+ expect(subject.send(:lookup_server_uri)).to eq "tcp://127.0.0.1:9400"
59
+ end
60
+ end
61
+
62
+ it "checks if the server is alive" do
63
+ allow(service_directory).to receive(:all_listings_for).and_return([])
64
+ expect(subject).to receive(:host_alive?).with("127.0.0.1") { true }
65
+ expect(subject.send(:lookup_server_uri)).to eq "tcp://127.0.0.1:9400"
66
+ end
67
+
68
+ context "when no host is alive" do
69
+ it "raises an error" do
70
+ allow(service_directory).to receive(:all_listings_for).and_return(listings)
71
+ allow(subject).to receive(:host_alive?).and_return(false)
72
+ expect { subject.send(:lookup_server_uri) }.to raise_error
73
+ end
74
+ end
75
+
76
+ end
77
+
78
+ describe "#host_alive?" do
79
+ context "when the PB_RPC_PING_PORT is not set" do
80
+ before do
81
+ ENV.delete("PB_RPC_PING_PORT")
82
+ end
83
+
84
+ it "returns true" do
85
+ expect(subject.send(:host_alive?, "yip.yip")).to be true
86
+ end
87
+
88
+ it "does not attempt a connection" do
89
+ expect(TCPSocket).not_to receive(:new)
90
+ subject.send(:host_alive?, "blargh.com")
91
+ end
92
+ end
93
+
94
+ context "when the PB_RPC_PING_PORT is set" do
95
+ before do
96
+ ENV["PB_RPC_PING_PORT"] = "3307"
97
+ end
98
+
99
+ it "returns true when the connection succeeds" do
100
+ expect(TCPSocket).to receive(:new).with("huzzah.com", 3307).and_return(double(:close => nil, :setsockopt => nil))
101
+ expect(subject.send(:host_alive?, "huzzah.com")).to be true
102
+ end
103
+
104
+ it "returns false when the connection fails" do
105
+ expect(TCPSocket).to receive(:new).with("hayoob.com", 3307).and_raise(Errno::ECONNREFUSED)
106
+ expect(subject.send(:host_alive?, "hayoob.com")).to be false
107
+ end
108
+
109
+ it "closes the socket" do
110
+ socket = double("TCPSocket", :setsockopt => nil)
111
+ expect(socket).to receive(:close)
112
+ expect(TCPSocket).to receive(:new).with("absorbalof.com", 3307).and_return(socket)
113
+ expect(subject.send(:host_alive?, "absorbalof.com")).to be true
114
+ end
115
+ end
116
+ end
117
+ end