protobuf-cucumber 3.10.4

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 (204) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +21 -0
  3. data/.rubocop.yml +70 -0
  4. data/.rubocop_todo.yml +145 -0
  5. data/.travis.yml +40 -0
  6. data/.yardopts +5 -0
  7. data/CHANGES.md +344 -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 +22 -0
  14. data/bin/rpc_server +5 -0
  15. data/install-protobuf.sh +28 -0
  16. data/lib/protobuf.rb +129 -0
  17. data/lib/protobuf/cli.rb +257 -0
  18. data/lib/protobuf/code_generator.rb +120 -0
  19. data/lib/protobuf/decoder.rb +28 -0
  20. data/lib/protobuf/deprecation.rb +117 -0
  21. data/lib/protobuf/descriptors.rb +3 -0
  22. data/lib/protobuf/descriptors/google/protobuf/compiler/plugin.pb.rb +62 -0
  23. data/lib/protobuf/descriptors/google/protobuf/descriptor.pb.rb +301 -0
  24. data/lib/protobuf/encoder.rb +11 -0
  25. data/lib/protobuf/enum.rb +365 -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 +380 -0
  29. data/lib/protobuf/field/base_field_object_definitions.rb +504 -0
  30. data/lib/protobuf/field/bool_field.rb +64 -0
  31. data/lib/protobuf/field/bytes_field.rb +78 -0
  32. data/lib/protobuf/field/double_field.rb +25 -0
  33. data/lib/protobuf/field/enum_field.rb +61 -0
  34. data/lib/protobuf/field/field_array.rb +104 -0
  35. data/lib/protobuf/field/field_hash.rb +122 -0
  36. data/lib/protobuf/field/fixed32_field.rb +25 -0
  37. data/lib/protobuf/field/fixed64_field.rb +28 -0
  38. data/lib/protobuf/field/float_field.rb +43 -0
  39. data/lib/protobuf/field/int32_field.rb +21 -0
  40. data/lib/protobuf/field/int64_field.rb +34 -0
  41. data/lib/protobuf/field/integer_field.rb +23 -0
  42. data/lib/protobuf/field/message_field.rb +51 -0
  43. data/lib/protobuf/field/sfixed32_field.rb +27 -0
  44. data/lib/protobuf/field/sfixed64_field.rb +28 -0
  45. data/lib/protobuf/field/signed_integer_field.rb +29 -0
  46. data/lib/protobuf/field/sint32_field.rb +21 -0
  47. data/lib/protobuf/field/sint64_field.rb +21 -0
  48. data/lib/protobuf/field/string_field.rb +51 -0
  49. data/lib/protobuf/field/uint32_field.rb +21 -0
  50. data/lib/protobuf/field/uint64_field.rb +21 -0
  51. data/lib/protobuf/field/varint_field.rb +77 -0
  52. data/lib/protobuf/generators/base.rb +85 -0
  53. data/lib/protobuf/generators/enum_generator.rb +39 -0
  54. data/lib/protobuf/generators/extension_generator.rb +27 -0
  55. data/lib/protobuf/generators/field_generator.rb +193 -0
  56. data/lib/protobuf/generators/file_generator.rb +262 -0
  57. data/lib/protobuf/generators/group_generator.rb +122 -0
  58. data/lib/protobuf/generators/message_generator.rb +104 -0
  59. data/lib/protobuf/generators/option_generator.rb +17 -0
  60. data/lib/protobuf/generators/printable.rb +160 -0
  61. data/lib/protobuf/generators/service_generator.rb +50 -0
  62. data/lib/protobuf/lifecycle.rb +33 -0
  63. data/lib/protobuf/logging.rb +39 -0
  64. data/lib/protobuf/message.rb +260 -0
  65. data/lib/protobuf/message/fields.rb +233 -0
  66. data/lib/protobuf/message/serialization.rb +85 -0
  67. data/lib/protobuf/optionable.rb +70 -0
  68. data/lib/protobuf/rpc/buffer.rb +78 -0
  69. data/lib/protobuf/rpc/client.rb +140 -0
  70. data/lib/protobuf/rpc/connectors/base.rb +221 -0
  71. data/lib/protobuf/rpc/connectors/ping.rb +89 -0
  72. data/lib/protobuf/rpc/connectors/socket.rb +78 -0
  73. data/lib/protobuf/rpc/connectors/zmq.rb +319 -0
  74. data/lib/protobuf/rpc/dynamic_discovery.pb.rb +50 -0
  75. data/lib/protobuf/rpc/env.rb +60 -0
  76. data/lib/protobuf/rpc/error.rb +28 -0
  77. data/lib/protobuf/rpc/error/client_error.rb +31 -0
  78. data/lib/protobuf/rpc/error/server_error.rb +43 -0
  79. data/lib/protobuf/rpc/middleware.rb +25 -0
  80. data/lib/protobuf/rpc/middleware/exception_handler.rb +40 -0
  81. data/lib/protobuf/rpc/middleware/logger.rb +95 -0
  82. data/lib/protobuf/rpc/middleware/request_decoder.rb +79 -0
  83. data/lib/protobuf/rpc/middleware/response_encoder.rb +83 -0
  84. data/lib/protobuf/rpc/middleware/runner.rb +18 -0
  85. data/lib/protobuf/rpc/rpc.pb.rb +64 -0
  86. data/lib/protobuf/rpc/rpc_method.rb +16 -0
  87. data/lib/protobuf/rpc/server.rb +39 -0
  88. data/lib/protobuf/rpc/servers/socket/server.rb +121 -0
  89. data/lib/protobuf/rpc/servers/socket/worker.rb +56 -0
  90. data/lib/protobuf/rpc/servers/socket_runner.rb +46 -0
  91. data/lib/protobuf/rpc/servers/zmq/broker.rb +194 -0
  92. data/lib/protobuf/rpc/servers/zmq/server.rb +321 -0
  93. data/lib/protobuf/rpc/servers/zmq/util.rb +48 -0
  94. data/lib/protobuf/rpc/servers/zmq/worker.rb +105 -0
  95. data/lib/protobuf/rpc/servers/zmq_runner.rb +70 -0
  96. data/lib/protobuf/rpc/service.rb +172 -0
  97. data/lib/protobuf/rpc/service_directory.rb +261 -0
  98. data/lib/protobuf/rpc/service_dispatcher.rb +45 -0
  99. data/lib/protobuf/rpc/service_filters.rb +250 -0
  100. data/lib/protobuf/rpc/stat.rb +119 -0
  101. data/lib/protobuf/socket.rb +21 -0
  102. data/lib/protobuf/tasks.rb +1 -0
  103. data/lib/protobuf/tasks/compile.rake +80 -0
  104. data/lib/protobuf/varint.rb +20 -0
  105. data/lib/protobuf/varint_pure.rb +31 -0
  106. data/lib/protobuf/version.rb +3 -0
  107. data/lib/protobuf/wire_type.rb +10 -0
  108. data/lib/protobuf/zmq.rb +21 -0
  109. data/profile.html +5103 -0
  110. data/proto/dynamic_discovery.proto +44 -0
  111. data/proto/google/protobuf/compiler/plugin.proto +147 -0
  112. data/proto/google/protobuf/descriptor.proto +779 -0
  113. data/proto/rpc.proto +69 -0
  114. data/protobuf-cucumber.gemspec +57 -0
  115. data/spec/benchmark/tasks.rb +143 -0
  116. data/spec/bin/protoc-gen-ruby_spec.rb +23 -0
  117. data/spec/encoding/all_types_spec.rb +103 -0
  118. data/spec/encoding/extreme_values_spec.rb +0 -0
  119. data/spec/functional/class_inheritance_spec.rb +52 -0
  120. data/spec/functional/code_generator_spec.rb +58 -0
  121. data/spec/functional/socket_server_spec.rb +59 -0
  122. data/spec/functional/zmq_server_spec.rb +105 -0
  123. data/spec/lib/protobuf/cli_spec.rb +317 -0
  124. data/spec/lib/protobuf/code_generator_spec.rb +87 -0
  125. data/spec/lib/protobuf/enum_spec.rb +307 -0
  126. data/spec/lib/protobuf/field/bool_field_spec.rb +91 -0
  127. data/spec/lib/protobuf/field/double_field_spec.rb +9 -0
  128. data/spec/lib/protobuf/field/enum_field_spec.rb +44 -0
  129. data/spec/lib/protobuf/field/field_array_spec.rb +105 -0
  130. data/spec/lib/protobuf/field/field_hash_spec.rb +168 -0
  131. data/spec/lib/protobuf/field/fixed32_field_spec.rb +7 -0
  132. data/spec/lib/protobuf/field/fixed64_field_spec.rb +7 -0
  133. data/spec/lib/protobuf/field/float_field_spec.rb +90 -0
  134. data/spec/lib/protobuf/field/int32_field_spec.rb +120 -0
  135. data/spec/lib/protobuf/field/int64_field_spec.rb +7 -0
  136. data/spec/lib/protobuf/field/message_field_spec.rb +132 -0
  137. data/spec/lib/protobuf/field/sfixed32_field_spec.rb +9 -0
  138. data/spec/lib/protobuf/field/sfixed64_field_spec.rb +9 -0
  139. data/spec/lib/protobuf/field/sint32_field_spec.rb +9 -0
  140. data/spec/lib/protobuf/field/sint64_field_spec.rb +9 -0
  141. data/spec/lib/protobuf/field/string_field_spec.rb +79 -0
  142. data/spec/lib/protobuf/field/uint32_field_spec.rb +7 -0
  143. data/spec/lib/protobuf/field/uint64_field_spec.rb +7 -0
  144. data/spec/lib/protobuf/field_spec.rb +192 -0
  145. data/spec/lib/protobuf/generators/base_spec.rb +154 -0
  146. data/spec/lib/protobuf/generators/enum_generator_spec.rb +82 -0
  147. data/spec/lib/protobuf/generators/extension_generator_spec.rb +42 -0
  148. data/spec/lib/protobuf/generators/field_generator_spec.rb +197 -0
  149. data/spec/lib/protobuf/generators/file_generator_spec.rb +119 -0
  150. data/spec/lib/protobuf/generators/message_generator_spec.rb +0 -0
  151. data/spec/lib/protobuf/generators/service_generator_spec.rb +99 -0
  152. data/spec/lib/protobuf/lifecycle_spec.rb +94 -0
  153. data/spec/lib/protobuf/message_spec.rb +944 -0
  154. data/spec/lib/protobuf/optionable_spec.rb +265 -0
  155. data/spec/lib/protobuf/rpc/client_spec.rb +66 -0
  156. data/spec/lib/protobuf/rpc/connectors/base_spec.rb +226 -0
  157. data/spec/lib/protobuf/rpc/connectors/ping_spec.rb +69 -0
  158. data/spec/lib/protobuf/rpc/connectors/socket_spec.rb +34 -0
  159. data/spec/lib/protobuf/rpc/connectors/zmq_spec.rb +110 -0
  160. data/spec/lib/protobuf/rpc/middleware/exception_handler_spec.rb +62 -0
  161. data/spec/lib/protobuf/rpc/middleware/logger_spec.rb +49 -0
  162. data/spec/lib/protobuf/rpc/middleware/request_decoder_spec.rb +115 -0
  163. data/spec/lib/protobuf/rpc/middleware/response_encoder_spec.rb +91 -0
  164. data/spec/lib/protobuf/rpc/servers/socket_server_spec.rb +38 -0
  165. data/spec/lib/protobuf/rpc/servers/zmq/server_spec.rb +43 -0
  166. data/spec/lib/protobuf/rpc/servers/zmq/util_spec.rb +55 -0
  167. data/spec/lib/protobuf/rpc/servers/zmq/worker_spec.rb +35 -0
  168. data/spec/lib/protobuf/rpc/service_directory_spec.rb +293 -0
  169. data/spec/lib/protobuf/rpc/service_dispatcher_spec.rb +35 -0
  170. data/spec/lib/protobuf/rpc/service_filters_spec.rb +517 -0
  171. data/spec/lib/protobuf/rpc/service_spec.rb +162 -0
  172. data/spec/lib/protobuf/rpc/stat_spec.rb +101 -0
  173. data/spec/lib/protobuf/varint_spec.rb +29 -0
  174. data/spec/lib/protobuf_spec.rb +105 -0
  175. data/spec/spec_helper.rb +42 -0
  176. data/spec/support/all.rb +6 -0
  177. data/spec/support/packed_field.rb +23 -0
  178. data/spec/support/protos/all_types.data.bin +0 -0
  179. data/spec/support/protos/all_types.data.txt +119 -0
  180. data/spec/support/protos/enum.pb.rb +63 -0
  181. data/spec/support/protos/enum.proto +37 -0
  182. data/spec/support/protos/extreme_values.data.bin +0 -0
  183. data/spec/support/protos/google_unittest.bin +0 -0
  184. data/spec/support/protos/google_unittest.pb.rb +798 -0
  185. data/spec/support/protos/google_unittest.proto +884 -0
  186. data/spec/support/protos/google_unittest_custom_options.bin +0 -0
  187. data/spec/support/protos/google_unittest_custom_options.pb.rb +361 -0
  188. data/spec/support/protos/google_unittest_custom_options.proto +424 -0
  189. data/spec/support/protos/google_unittest_import.pb.rb +55 -0
  190. data/spec/support/protos/google_unittest_import.proto +73 -0
  191. data/spec/support/protos/google_unittest_import_public.pb.rb +31 -0
  192. data/spec/support/protos/google_unittest_import_public.proto +41 -0
  193. data/spec/support/protos/map-test.bin +157 -0
  194. data/spec/support/protos/map-test.pb.rb +85 -0
  195. data/spec/support/protos/map-test.proto +68 -0
  196. data/spec/support/protos/multi_field_extensions.pb.rb +59 -0
  197. data/spec/support/protos/multi_field_extensions.proto +35 -0
  198. data/spec/support/protos/resource.pb.rb +172 -0
  199. data/spec/support/protos/resource.proto +137 -0
  200. data/spec/support/resource_service.rb +23 -0
  201. data/spec/support/server.rb +65 -0
  202. data/spec/support/test_app_file.rb +2 -0
  203. data/varint_prof.rb +82 -0
  204. metadata +579 -0
@@ -0,0 +1,69 @@
1
+ require "spec_helper"
2
+ require "protobuf/zmq"
3
+
4
+ ::RSpec.describe ::Protobuf::Rpc::Connectors::Ping do
5
+ subject { described_class.new("google.com", 80) }
6
+
7
+ let(:host) { "google.com" }
8
+ let(:port) { 80 }
9
+
10
+ describe ".new" do
11
+ it "assigns host" do
12
+ expect(subject.host).to eq(host)
13
+ end
14
+
15
+ it "assigns port" do
16
+ expect(subject.port).to eq(port)
17
+ end
18
+ end
19
+
20
+ describe "#online?" do
21
+ it "closes the socket" do
22
+ socket = double(:close => nil, :setsockopt => nil)
23
+ allow(subject).to receive(:tcp_socket).and_return(socket)
24
+ expect(socket).to receive(:close)
25
+ expect(subject).to be_online
26
+ end
27
+
28
+ context "when a socket can connect" do
29
+ let(:socket) { double(:close => nil, :setsockopt => nil) }
30
+ before { allow(subject).to receive(:tcp_socket).and_return(socket) }
31
+
32
+ it "returns true" do
33
+ expect(subject).to be_online
34
+ end
35
+ end
36
+
37
+ context "when a socket error is raised" do
38
+ before { allow(subject).to receive(:tcp_socket).and_raise(::Errno::ECONNREFUSED) }
39
+
40
+ it "returns false" do
41
+ expect(subject).to_not be_online
42
+ end
43
+ end
44
+
45
+ context "when a select timeout is fired" do
46
+ let(:wait_writable_class) { ::Class.new(StandardError) { include ::IO::WaitWritable } }
47
+ before { expect_any_instance_of(::Socket).to receive(:connect_nonblock).and_raise(wait_writable_class) }
48
+
49
+ it "returns false" do
50
+ expect(::IO).to receive(:select).and_return(false)
51
+ expect(subject).to_not be_online
52
+ end
53
+ end
54
+ end
55
+
56
+ describe "#timeout" do
57
+ it "uses the default value" do
58
+ expect(subject.timeout).to eq(0.2)
59
+ end
60
+
61
+ context "when environment variable is set" do
62
+ before { ::ENV["PB_RPC_PING_PORT_TIMEOUT"] = "100" }
63
+
64
+ it "uses the environmet variable" do
65
+ expect(subject.timeout).to eq(0.1)
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,34 @@
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
+ context "#read_response" do
22
+ let(:data) { "New data" }
23
+
24
+ it "fills the buffer with data from the socket" do
25
+ socket = StringIO.new("#{data.bytesize}-#{data}")
26
+ subject.instance_variable_set(:@socket, socket)
27
+ subject.instance_variable_set(:@stats, OpenStruct.new)
28
+ expect(subject).to receive(:parse_response).and_return(true)
29
+
30
+ subject.__send__(:read_response)
31
+ expect(subject.instance_variable_get(:@response_data)).to eq(data)
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,110 @@
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(RuntimeError)
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
+ allow_any_instance_of(::Protobuf::Rpc::Connectors::Ping).to receive(:online?).and_return(true)
101
+ expect(subject.send(:host_alive?, "huzzah1.com")).to eq(true)
102
+ end
103
+
104
+ it "returns false when the connection fails" do
105
+ allow_any_instance_of(::Protobuf::Rpc::Connectors::Ping).to receive(:online?).and_return(false)
106
+ expect(subject.send(:host_alive?, "huzzah2.com")).to eq(false)
107
+ end
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,62 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Protobuf::Rpc::Middleware::ExceptionHandler do
4
+ let(:app) { proc { |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
+ expect(app).to receive(:call).with(env)
12
+ subject.call(env)
13
+ end
14
+
15
+ it "returns the env" do
16
+ expect(subject.call(env)).to 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 { allow(app).to receive(: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
+ expect(stack_env.response.class).to eq error.class
36
+ end
37
+
38
+ it "encodes the response" do
39
+ stack_env = subject.call(env)
40
+ expect(stack_env.encoded_response).to 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 { allow(app).to receive(:call).and_raise(RuntimeError, 'Boom!') }
49
+
50
+ it "wraps the exception in a generic Protobuf error" do
51
+ stack_env = subject.call(env)
52
+ expect(stack_env.response).to eq error
53
+ end
54
+
55
+ it "encodes the wrapped exception" do
56
+ stack_env = subject.call(env)
57
+ expect(stack_env.encoded_response).to eq encoded_error
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,49 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Protobuf::Rpc::Middleware::Logger do
4
+ let(:app) { proc { |inner_env| inner_env } }
5
+ let(:env) do
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
+ end
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) do
24
+ ::Protobuf::Socketrpc::Request.new(
25
+ :service_name => service_name,
26
+ :method_name => method_name.to_s,
27
+ :request_proto => request,
28
+ )
29
+ end
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
+ expect(app).to receive(:call).with(env).and_return(env)
42
+ subject.call(env)
43
+ end
44
+
45
+ it "returns the env" do
46
+ expect(subject.call(env)).to eq env
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,115 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Protobuf::Rpc::Middleware::RequestDecoder do
4
+ let(:app) { proc { |env| env } }
5
+ let(:client_host) { 'client_host.test.co' }
6
+ let(:env) do
7
+ Protobuf::Rpc::Env.new(
8
+ 'encoded_request' => encoded_request,
9
+ 'log_signature' => 'log_signature',
10
+ )
11
+ end
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) do
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
+ end
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
+ expect(stack_env.request).to eq request
35
+ end
36
+
37
+ it "calls the stack" do
38
+ expect(app).to 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
+ expect(stack_env.client_host).to eq client_host
45
+ end
46
+
47
+ it "sets Env#service_name" do
48
+ stack_env = subject.call(env)
49
+ expect(stack_env.service_name).to eq service_name
50
+ end
51
+
52
+ it "sets Env#method_name" do
53
+ stack_env = subject.call(env)
54
+ expect(stack_env.method_name).to eq method_name.to_sym
55
+ end
56
+
57
+ it "sets Env#request_type" do
58
+ stack_env = subject.call(env)
59
+ expect(stack_env.request_type).to eq request_type
60
+ end
61
+
62
+ it "sets Env#response_type" do
63
+ stack_env = subject.call(env)
64
+ expect(stack_env.response_type).to eq response_type
65
+ end
66
+
67
+ it "sets Env#rpc_method" do
68
+ stack_env = subject.call(env)
69
+ expect(stack_env.rpc_method).to eq rpc_method
70
+ end
71
+
72
+ it "sets Env#rpc_service" do
73
+ stack_env = subject.call(env)
74
+ expect(stack_env.rpc_service).to eq rpc_service
75
+ end
76
+
77
+ context "when decoding fails" do
78
+ before { allow(::Protobuf::Socketrpc::Request).to receive(: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) do
87
+ ::Protobuf::Socketrpc::Request.new(
88
+ :caller => client_host,
89
+ :service_name => 'NonexistantService',
90
+ :method_name => method_name.to_s,
91
+ :request_proto => request,
92
+ )
93
+ end
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) do
102
+ ::Protobuf::Socketrpc::Request.new(
103
+ :caller => client_host,
104
+ :service_name => service_name,
105
+ :method_name => 'foo',
106
+ :request_proto => request,
107
+ )
108
+ end
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,91 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Protobuf::Rpc::Middleware::ResponseEncoder do
4
+ let(:app) { proc { |env| env.response = response; env } }
5
+ let(:env) do
6
+ Protobuf::Rpc::Env.new(
7
+ 'response_type' => Test::Resource,
8
+ 'log_signature' => 'log_signature',
9
+ )
10
+ end
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
+ expect(stack_env.encoded_response).to eq encoded_response
21
+ end
22
+
23
+ it "calls the stack" do
24
+ stack_env = subject.call(env)
25
+ expect(stack_env.response).to 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
+ expect(stack_env.response).to 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
+ expect(stack_env.response).to 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
+ expect(stack_env.encoded_response).to eq encoded_response
64
+ end
65
+ end
66
+
67
+ context "when encoding fails" do
68
+ before { allow_any_instance_of(::Protobuf::Socketrpc::Response).to receive(: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
+
75
+ context "when server exists in the env" do
76
+ let(:env) do
77
+ Protobuf::Rpc::Env.new(
78
+ 'response_type' => Test::Resource,
79
+ 'log_signature' => 'log_signature',
80
+ 'server' => 'itsaserver',
81
+ )
82
+ end
83
+
84
+ it "adds the servers to the response" do
85
+ expected_response = ::Protobuf::Socketrpc::Response.new(:response_proto => response, :server => 'itsaserver').encode
86
+ subject.call(env)
87
+ expect(env.encoded_response).to eq(expected_response)
88
+ end
89
+ end
90
+ end
91
+ end