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.
- checksums.yaml +7 -0
- data/.gitignore +21 -0
- data/.rubocop.yml +51 -0
- data/.rubocop_todo.yml +89 -0
- data/.travis.yml +25 -0
- data/.yardopts +5 -0
- data/CHANGES.md +256 -0
- data/CONTRIBUTING.md +16 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +22 -0
- data/README.md +33 -0
- data/Rakefile +64 -0
- data/bin/protoc-gen-ruby +16 -0
- data/bin/rpc_server +5 -0
- data/install-protobuf.sh +28 -0
- data/lib/protobuf.rb +100 -0
- data/lib/protobuf/cli.rb +242 -0
- data/lib/protobuf/code_generator.rb +44 -0
- data/lib/protobuf/decoder.rb +73 -0
- data/lib/protobuf/deprecation.rb +112 -0
- data/lib/protobuf/descriptors.rb +3 -0
- data/lib/protobuf/descriptors/google/protobuf/compiler/plugin.pb.rb +48 -0
- data/lib/protobuf/descriptors/google/protobuf/descriptor.pb.rb +251 -0
- data/lib/protobuf/encoder.rb +67 -0
- data/lib/protobuf/enum.rb +303 -0
- data/lib/protobuf/exceptions.rb +9 -0
- data/lib/protobuf/field.rb +74 -0
- data/lib/protobuf/field/base_field.rb +267 -0
- data/lib/protobuf/field/bool_field.rb +59 -0
- data/lib/protobuf/field/bytes_field.rb +82 -0
- data/lib/protobuf/field/double_field.rb +25 -0
- data/lib/protobuf/field/enum_field.rb +68 -0
- data/lib/protobuf/field/field_array.rb +87 -0
- data/lib/protobuf/field/fixed32_field.rb +25 -0
- data/lib/protobuf/field/fixed64_field.rb +28 -0
- data/lib/protobuf/field/float_field.rb +41 -0
- data/lib/protobuf/field/int32_field.rb +21 -0
- data/lib/protobuf/field/int64_field.rb +21 -0
- data/lib/protobuf/field/integer_field.rb +23 -0
- data/lib/protobuf/field/message_field.rb +65 -0
- data/lib/protobuf/field/sfixed32_field.rb +27 -0
- data/lib/protobuf/field/sfixed64_field.rb +28 -0
- data/lib/protobuf/field/signed_integer_field.rb +29 -0
- data/lib/protobuf/field/sint32_field.rb +21 -0
- data/lib/protobuf/field/sint64_field.rb +21 -0
- data/lib/protobuf/field/string_field.rb +34 -0
- data/lib/protobuf/field/uint32_field.rb +21 -0
- data/lib/protobuf/field/uint64_field.rb +21 -0
- data/lib/protobuf/field/varint_field.rb +73 -0
- data/lib/protobuf/generators/base.rb +70 -0
- data/lib/protobuf/generators/enum_generator.rb +41 -0
- data/lib/protobuf/generators/extension_generator.rb +27 -0
- data/lib/protobuf/generators/field_generator.rb +131 -0
- data/lib/protobuf/generators/file_generator.rb +135 -0
- data/lib/protobuf/generators/group_generator.rb +112 -0
- data/lib/protobuf/generators/message_generator.rb +98 -0
- data/lib/protobuf/generators/printable.rb +160 -0
- data/lib/protobuf/generators/service_generator.rb +26 -0
- data/lib/protobuf/lifecycle.rb +33 -0
- data/lib/protobuf/logging.rb +39 -0
- data/lib/protobuf/message.rb +193 -0
- data/lib/protobuf/message/fields.rb +133 -0
- data/lib/protobuf/message/serialization.rb +89 -0
- data/lib/protobuf/optionable.rb +23 -0
- data/lib/protobuf/rpc/buffer.rb +77 -0
- data/lib/protobuf/rpc/client.rb +168 -0
- data/lib/protobuf/rpc/connector.rb +19 -0
- data/lib/protobuf/rpc/connectors/base.rb +55 -0
- data/lib/protobuf/rpc/connectors/common.rb +176 -0
- data/lib/protobuf/rpc/connectors/socket.rb +73 -0
- data/lib/protobuf/rpc/connectors/zmq.rb +322 -0
- data/lib/protobuf/rpc/dynamic_discovery.pb.rb +49 -0
- data/lib/protobuf/rpc/env.rb +58 -0
- data/lib/protobuf/rpc/error.rb +28 -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/middleware.rb +25 -0
- data/lib/protobuf/rpc/middleware/exception_handler.rb +36 -0
- data/lib/protobuf/rpc/middleware/logger.rb +91 -0
- data/lib/protobuf/rpc/middleware/request_decoder.rb +83 -0
- data/lib/protobuf/rpc/middleware/response_encoder.rb +88 -0
- data/lib/protobuf/rpc/middleware/runner.rb +18 -0
- data/lib/protobuf/rpc/rpc.pb.rb +55 -0
- data/lib/protobuf/rpc/server.rb +39 -0
- data/lib/protobuf/rpc/servers/socket/server.rb +123 -0
- data/lib/protobuf/rpc/servers/socket/worker.rb +56 -0
- data/lib/protobuf/rpc/servers/socket_runner.rb +40 -0
- data/lib/protobuf/rpc/servers/zmq/broker.rb +193 -0
- data/lib/protobuf/rpc/servers/zmq/server.rb +320 -0
- data/lib/protobuf/rpc/servers/zmq/util.rb +48 -0
- data/lib/protobuf/rpc/servers/zmq/worker.rb +104 -0
- data/lib/protobuf/rpc/servers/zmq_runner.rb +62 -0
- data/lib/protobuf/rpc/service.rb +179 -0
- data/lib/protobuf/rpc/service_directory.rb +253 -0
- data/lib/protobuf/rpc/service_dispatcher.rb +46 -0
- data/lib/protobuf/rpc/service_filters.rb +272 -0
- data/lib/protobuf/rpc/stat.rb +97 -0
- data/lib/protobuf/socket.rb +21 -0
- data/lib/protobuf/tasks.rb +1 -0
- data/lib/protobuf/tasks/compile.rake +61 -0
- data/lib/protobuf/version.rb +3 -0
- data/lib/protobuf/wire_type.rb +10 -0
- data/lib/protobuf/zmq.rb +21 -0
- data/proto/dynamic_discovery.proto +44 -0
- data/proto/google/protobuf/compiler/plugin.proto +147 -0
- data/proto/google/protobuf/descriptor.proto +620 -0
- data/proto/rpc.proto +62 -0
- data/protobuf.gemspec +51 -0
- data/spec/benchmark/tasks.rb +139 -0
- data/spec/bin/protoc-gen-ruby_spec.rb +23 -0
- data/spec/data/data.bin +3 -0
- data/spec/data/types.bin +0 -0
- data/spec/encoding/all_types_spec.rb +105 -0
- data/spec/encoding/extreme_values_spec.rb +0 -0
- data/spec/functional/class_inheritance_spec.rb +52 -0
- data/spec/functional/socket_server_spec.rb +59 -0
- data/spec/functional/zmq_server_spec.rb +105 -0
- data/spec/lib/protobuf/cli_spec.rb +273 -0
- data/spec/lib/protobuf/code_generator_spec.rb +60 -0
- data/spec/lib/protobuf/enum_spec.rb +265 -0
- data/spec/lib/protobuf/field/bool_field_spec.rb +51 -0
- data/spec/lib/protobuf/field/field_array_spec.rb +69 -0
- data/spec/lib/protobuf/field/float_field_spec.rb +55 -0
- data/spec/lib/protobuf/field/int32_field_spec.rb +89 -0
- data/spec/lib/protobuf/field/string_field_spec.rb +45 -0
- data/spec/lib/protobuf/field_spec.rb +191 -0
- data/spec/lib/protobuf/generators/base_spec.rb +84 -0
- data/spec/lib/protobuf/generators/enum_generator_spec.rb +73 -0
- data/spec/lib/protobuf/generators/extension_generator_spec.rb +42 -0
- data/spec/lib/protobuf/generators/field_generator_spec.rb +102 -0
- data/spec/lib/protobuf/generators/file_generator_spec.rb +32 -0
- data/spec/lib/protobuf/generators/message_generator_spec.rb +0 -0
- data/spec/lib/protobuf/generators/service_generator_spec.rb +46 -0
- data/spec/lib/protobuf/lifecycle_spec.rb +94 -0
- data/spec/lib/protobuf/message_spec.rb +526 -0
- data/spec/lib/protobuf/optionable_spec.rb +46 -0
- data/spec/lib/protobuf/rpc/client_spec.rb +66 -0
- data/spec/lib/protobuf/rpc/connector_spec.rb +26 -0
- data/spec/lib/protobuf/rpc/connectors/base_spec.rb +50 -0
- data/spec/lib/protobuf/rpc/connectors/common_spec.rb +170 -0
- data/spec/lib/protobuf/rpc/connectors/socket_spec.rb +36 -0
- data/spec/lib/protobuf/rpc/connectors/zmq_spec.rb +117 -0
- data/spec/lib/protobuf/rpc/middleware/exception_handler_spec.rb +62 -0
- data/spec/lib/protobuf/rpc/middleware/logger_spec.rb +49 -0
- data/spec/lib/protobuf/rpc/middleware/request_decoder_spec.rb +115 -0
- data/spec/lib/protobuf/rpc/middleware/response_encoder_spec.rb +75 -0
- data/spec/lib/protobuf/rpc/servers/socket_server_spec.rb +38 -0
- data/spec/lib/protobuf/rpc/servers/zmq/server_spec.rb +43 -0
- data/spec/lib/protobuf/rpc/servers/zmq/util_spec.rb +55 -0
- data/spec/lib/protobuf/rpc/servers/zmq/worker_spec.rb +35 -0
- data/spec/lib/protobuf/rpc/service_directory_spec.rb +293 -0
- data/spec/lib/protobuf/rpc/service_dispatcher_spec.rb +52 -0
- data/spec/lib/protobuf/rpc/service_filters_spec.rb +517 -0
- data/spec/lib/protobuf/rpc/service_spec.rb +162 -0
- data/spec/lib/protobuf/rpc/stat_spec.rb +68 -0
- data/spec/lib/protobuf_spec.rb +98 -0
- data/spec/spec_helper.rb +44 -0
- data/spec/support/all.rb +6 -0
- data/spec/support/packed_field.rb +22 -0
- data/spec/support/server.rb +64 -0
- data/spec/support/test/all_types.data.bin +0 -0
- data/spec/support/test/all_types.data.txt +119 -0
- data/spec/support/test/defaults.pb.rb +27 -0
- data/spec/support/test/defaults.proto +9 -0
- data/spec/support/test/enum.pb.rb +55 -0
- data/spec/support/test/enum.proto +34 -0
- data/spec/support/test/extended.pb.rb +18 -0
- data/spec/support/test/extended.proto +10 -0
- data/spec/support/test/extreme_values.data.bin +0 -0
- data/spec/support/test/google_unittest.pb.rb +537 -0
- data/spec/support/test/google_unittest.proto +713 -0
- data/spec/support/test/google_unittest_import.pb.rb +39 -0
- data/spec/support/test/google_unittest_import.proto +64 -0
- data/spec/support/test/google_unittest_import_public.pb.rb +10 -0
- data/spec/support/test/google_unittest_import_public.proto +38 -0
- data/spec/support/test/multi_field_extensions.pb.rb +58 -0
- data/spec/support/test/multi_field_extensions.proto +33 -0
- data/spec/support/test/resource.pb.rb +119 -0
- data/spec/support/test/resource.proto +94 -0
- data/spec/support/test/resource_service.rb +23 -0
- data/spec/support/test_app_file.rb +2 -0
- metadata +502 -0
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
require 'spec/support/test/resource_service'
|
|
4
|
+
require 'protobuf/rpc/service_directory'
|
|
5
|
+
|
|
6
|
+
RSpec.describe 'Functional ZMQ Client' do
|
|
7
|
+
before(:all) do
|
|
8
|
+
load "protobuf/zmq.rb"
|
|
9
|
+
@runner = ::Protobuf::Rpc::ZmqRunner.new(
|
|
10
|
+
:host => "127.0.0.1",
|
|
11
|
+
:port => 9399,
|
|
12
|
+
:worker_port => 9408,
|
|
13
|
+
:backlog => 100,
|
|
14
|
+
:threshold => 100,
|
|
15
|
+
:threads => 5,
|
|
16
|
+
)
|
|
17
|
+
@server_thread = Thread.new(@runner) { |runner| runner.run }
|
|
18
|
+
Thread.pass until @runner.running?
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
after(:all) do
|
|
22
|
+
@runner.stop
|
|
23
|
+
@server_thread.join
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it 'runs fine when required fields are set' do
|
|
27
|
+
expect do
|
|
28
|
+
client = ::Test::ResourceService.client
|
|
29
|
+
|
|
30
|
+
client.find(:name => 'Test Name', :active => true) do |c|
|
|
31
|
+
c.on_success do |succ|
|
|
32
|
+
expect(succ.name).to eq("Test Name")
|
|
33
|
+
expect(succ.status).to eq(::Test::StatusType::ENABLED)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
c.on_failure do |err|
|
|
37
|
+
fail err.inspect
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end.to_not raise_error
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it 'runs under heavy load' do
|
|
44
|
+
10.times do
|
|
45
|
+
5.times.map do
|
|
46
|
+
Thread.new do
|
|
47
|
+
client = ::Test::ResourceService.client
|
|
48
|
+
|
|
49
|
+
client.find(:name => 'Test Name', :active => true) do |c|
|
|
50
|
+
c.on_success do |succ|
|
|
51
|
+
expect(succ.name).to eq("Test Name")
|
|
52
|
+
expect(succ.status).to eq(::Test::StatusType::ENABLED)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
c.on_failure do |err|
|
|
56
|
+
fail err.inspect
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end.each(&:join)
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
context 'when a message is malformed' do
|
|
65
|
+
it 'calls the on_failure callback' do
|
|
66
|
+
error = nil
|
|
67
|
+
request = ::Test::ResourceFindRequest.new(:active => true)
|
|
68
|
+
client = ::Test::ResourceService.client
|
|
69
|
+
|
|
70
|
+
client.find(request) do |c|
|
|
71
|
+
c.on_success { fail "shouldn't pass" }
|
|
72
|
+
c.on_failure { |e| error = e }
|
|
73
|
+
end
|
|
74
|
+
expect(error.message).to match(/Required field.*does not have a value/)
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
context 'when the request type is wrong' do
|
|
79
|
+
it 'calls the on_failure callback' do
|
|
80
|
+
error = nil
|
|
81
|
+
request = ::Test::Resource.new(:name => 'Test Name')
|
|
82
|
+
client = ::Test::ResourceService.client
|
|
83
|
+
|
|
84
|
+
client.find(request) do |c|
|
|
85
|
+
c.on_success { fail "shouldn't pass" }
|
|
86
|
+
c.on_failure { |e| error = e }
|
|
87
|
+
end
|
|
88
|
+
expect(error.message).to match(/expected request.*ResourceFindRequest.*Resource instead/i)
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
context 'when the server takes too long to respond' do
|
|
93
|
+
it 'responds with a timeout error' do
|
|
94
|
+
error = nil
|
|
95
|
+
client = ::Test::ResourceService.client(:timeout => 1)
|
|
96
|
+
|
|
97
|
+
client.find_with_sleep(:sleep => 2) do |c|
|
|
98
|
+
c.on_success { fail "shouldn't pass" }
|
|
99
|
+
c.on_failure { |e| error = e }
|
|
100
|
+
end
|
|
101
|
+
expect(error.message).to match(/The server repeatedly failed to respond/)
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
end
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'protobuf/cli'
|
|
3
|
+
|
|
4
|
+
RSpec.describe ::Protobuf::CLI do
|
|
5
|
+
|
|
6
|
+
let(:app_file) do
|
|
7
|
+
File.expand_path('../../../support/test_app_file.rb', __FILE__)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
let(:sock_runner) do
|
|
11
|
+
runner = double("SocketRunner", :register_signals => nil)
|
|
12
|
+
allow(runner).to receive(:run).and_return(::ActiveSupport::Notifications.publish("after_server_bind"))
|
|
13
|
+
runner
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
let(:zmq_runner) do
|
|
17
|
+
runner = double("ZmqRunner", :register_signals => nil)
|
|
18
|
+
allow(runner).to receive(:run).and_return(::ActiveSupport::Notifications.publish("after_server_bind"))
|
|
19
|
+
runner
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
around(:each) do |example|
|
|
23
|
+
logger = ::Protobuf::Logging.logger
|
|
24
|
+
example.run
|
|
25
|
+
::Protobuf::Logging.logger = logger
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
before(:each) do
|
|
29
|
+
allow(::Protobuf::Rpc::SocketRunner).to receive(:new).and_return(sock_runner)
|
|
30
|
+
allow(::Protobuf::Rpc::ZmqRunner).to receive(:new).and_return(zmq_runner)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
describe '#start' do
|
|
34
|
+
let(:base_args) { ['start', app_file] }
|
|
35
|
+
let(:test_args) { [] }
|
|
36
|
+
let(:args) { base_args + test_args }
|
|
37
|
+
|
|
38
|
+
context 'host option' do
|
|
39
|
+
let(:test_args) { ['--host=123.123.123.123'] }
|
|
40
|
+
|
|
41
|
+
it 'sends the host option to the runner' do
|
|
42
|
+
expect(::Protobuf::Rpc::SocketRunner).to receive(:new) do |options|
|
|
43
|
+
expect(options[:host]).to eq '123.123.123.123'
|
|
44
|
+
end.and_return(sock_runner)
|
|
45
|
+
described_class.start(args)
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
context 'port option' do
|
|
50
|
+
let(:test_args) { ['--port=12345'] }
|
|
51
|
+
|
|
52
|
+
it 'sends the port option to the runner' do
|
|
53
|
+
expect(::Protobuf::Rpc::SocketRunner).to receive(:new) do |options|
|
|
54
|
+
expect(options[:port]).to eq 12345
|
|
55
|
+
end.and_return(sock_runner)
|
|
56
|
+
described_class.start(args)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
context 'threads option' do
|
|
61
|
+
let(:test_args) { ['--threads=500'] }
|
|
62
|
+
|
|
63
|
+
it 'sends the threads option to the runner' do
|
|
64
|
+
expect(::Protobuf::Rpc::SocketRunner).to receive(:new) do |options|
|
|
65
|
+
expect(options[:threads]).to eq 500
|
|
66
|
+
end.and_return(sock_runner)
|
|
67
|
+
described_class.start(args)
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
context 'backlog option' do
|
|
72
|
+
let(:test_args) { ['--backlog=500'] }
|
|
73
|
+
|
|
74
|
+
it 'sends the backlog option to the runner' do
|
|
75
|
+
expect(::Protobuf::Rpc::SocketRunner).to receive(:new) do |options|
|
|
76
|
+
expect(options[:backlog]).to eq 500
|
|
77
|
+
end.and_return(sock_runner)
|
|
78
|
+
described_class.start(args)
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
context 'threshold option' do
|
|
83
|
+
let(:test_args) { ['--threshold=500'] }
|
|
84
|
+
|
|
85
|
+
it 'sends the backlog option to the runner' do
|
|
86
|
+
expect(::Protobuf::Rpc::SocketRunner).to receive(:new) do |options|
|
|
87
|
+
expect(options[:threshold]).to eq 500
|
|
88
|
+
end.and_return(sock_runner)
|
|
89
|
+
described_class.start(args)
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
context 'log options' do
|
|
94
|
+
let(:test_args) { ['--log=mylog.log', '--level=0'] }
|
|
95
|
+
|
|
96
|
+
it 'sends the log file and level options to the runner' do
|
|
97
|
+
expect(::Protobuf::Logging).to receive(:initialize_logger) do |file, level|
|
|
98
|
+
expect(file).to eq 'mylog.log'
|
|
99
|
+
expect(level).to eq 0
|
|
100
|
+
end
|
|
101
|
+
described_class.start(args)
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
context 'gc options' do
|
|
106
|
+
|
|
107
|
+
context 'when gc options are not present' do
|
|
108
|
+
let(:test_args) { [] }
|
|
109
|
+
|
|
110
|
+
it 'sets both request and serialization pausing to false' do
|
|
111
|
+
described_class.start(args)
|
|
112
|
+
expect(::Protobuf).to_not be_gc_pause_server_request
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
unless defined?(JRUBY_VERSION)
|
|
117
|
+
context 'request pausing' do
|
|
118
|
+
let(:test_args) { ['--gc_pause_request'] }
|
|
119
|
+
|
|
120
|
+
it 'sets the configuration option to GC pause server request' do
|
|
121
|
+
described_class.start(args)
|
|
122
|
+
expect(::Protobuf).to be_gc_pause_server_request
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
context 'deprecation options' do
|
|
129
|
+
context 'when not given' do
|
|
130
|
+
let(:test_args) { [] }
|
|
131
|
+
|
|
132
|
+
context 'when no ENV is present and no command line option' do
|
|
133
|
+
before { ENV.delete("PB_IGNORE_DEPRECATIONS") }
|
|
134
|
+
|
|
135
|
+
it 'sets the deprecation warning flag to true' do
|
|
136
|
+
described_class.start(args)
|
|
137
|
+
expect(::Protobuf.print_deprecation_warnings?).to be true
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
context 'if ENV["PB_IGNORE_DEPRECATIONS"] is present' do
|
|
142
|
+
before { ENV["PB_IGNORE_DEPRECATIONS"] = "1" }
|
|
143
|
+
after { ENV.delete("PB_IGNORE_DEPRECATIONS") }
|
|
144
|
+
|
|
145
|
+
it 'sets the deprecation warning flag to false ' do
|
|
146
|
+
described_class.start(args)
|
|
147
|
+
expect(::Protobuf.print_deprecation_warnings?).to be false
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
context 'when enabled' do
|
|
153
|
+
let(:test_args) { ['--print_deprecation_warnings'] }
|
|
154
|
+
|
|
155
|
+
it 'sets the deprecation warning flag to true' do
|
|
156
|
+
described_class.start(args)
|
|
157
|
+
expect(::Protobuf.print_deprecation_warnings?).to be true
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
context 'when disabled' do
|
|
162
|
+
let(:test_args) { ['--no-print_deprecation_warnings'] }
|
|
163
|
+
|
|
164
|
+
it 'sets the deprecation warning flag to false' do
|
|
165
|
+
described_class.start(args)
|
|
166
|
+
expect(::Protobuf.print_deprecation_warnings?).to be false
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
context 'run modes' do
|
|
172
|
+
|
|
173
|
+
context 'socket' do
|
|
174
|
+
let(:test_args) { ['--socket'] }
|
|
175
|
+
let(:runner) { ::Protobuf::Rpc::SocketRunner }
|
|
176
|
+
|
|
177
|
+
before do
|
|
178
|
+
expect(::Protobuf::Rpc::ZmqRunner).not_to receive(:new)
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
it 'is activated by the --socket switch' do
|
|
182
|
+
expect(runner).to receive(:new)
|
|
183
|
+
described_class.start(args)
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
it 'is activated by PB_SERVER_TYPE=Socket ENV variable' do
|
|
187
|
+
ENV['PB_SERVER_TYPE'] = "Socket"
|
|
188
|
+
expect(runner).to receive(:new).and_return(sock_runner)
|
|
189
|
+
described_class.start(args)
|
|
190
|
+
ENV.delete('PB_SERVER_TYPE')
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
it 'configures the connector type to be socket' do
|
|
194
|
+
load "protobuf/socket.rb"
|
|
195
|
+
expect(::Protobuf.connector_type).to eq(:socket)
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
context 'zmq workers only' do
|
|
200
|
+
let(:test_args) { ['--workers_only', '--zmq'] }
|
|
201
|
+
let(:runner) { ::Protobuf::Rpc::ZmqRunner }
|
|
202
|
+
|
|
203
|
+
before do
|
|
204
|
+
expect(::Protobuf::Rpc::SocketRunner).not_to receive(:new)
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
it 'is activated by the --workers_only switch' do
|
|
208
|
+
expect(runner).to receive(:new) do |options|
|
|
209
|
+
expect(options[:workers_only]).to be true
|
|
210
|
+
end.and_return(zmq_runner)
|
|
211
|
+
|
|
212
|
+
described_class.start(args)
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
it 'is activated by PB_WORKERS_ONLY=1 ENV variable' do
|
|
216
|
+
ENV['PB_WORKERS_ONLY'] = "1"
|
|
217
|
+
expect(runner).to receive(:new) do |options|
|
|
218
|
+
expect(options[:workers_only]).to be true
|
|
219
|
+
end.and_return(zmq_runner)
|
|
220
|
+
|
|
221
|
+
described_class.start(args)
|
|
222
|
+
ENV.delete('PB_WORKERS_ONLY')
|
|
223
|
+
end
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
context 'zmq worker port' do
|
|
227
|
+
let(:test_args) { ['--worker_port=1234', '--zmq'] }
|
|
228
|
+
let(:runner) { ::Protobuf::Rpc::ZmqRunner }
|
|
229
|
+
|
|
230
|
+
before do
|
|
231
|
+
expect(::Protobuf::Rpc::SocketRunner).not_to receive(:new)
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
it 'is activated by the --worker_port switch' do
|
|
235
|
+
expect(runner).to receive(:new) do |options|
|
|
236
|
+
expect(options[:worker_port]).to eq(1234)
|
|
237
|
+
end.and_return(zmq_runner)
|
|
238
|
+
|
|
239
|
+
described_class.start(args)
|
|
240
|
+
end
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
context 'zmq' do
|
|
244
|
+
let(:test_args) { ['--zmq'] }
|
|
245
|
+
let(:runner) { ::Protobuf::Rpc::ZmqRunner }
|
|
246
|
+
|
|
247
|
+
before do
|
|
248
|
+
expect(::Protobuf::Rpc::SocketRunner).not_to receive(:new)
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
it 'is activated by the --zmq switch' do
|
|
252
|
+
expect(runner).to receive(:new)
|
|
253
|
+
described_class.start(args)
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
it 'is activated by PB_SERVER_TYPE=Zmq ENV variable' do
|
|
257
|
+
ENV['PB_SERVER_TYPE'] = "Zmq"
|
|
258
|
+
expect(runner).to receive(:new)
|
|
259
|
+
described_class.start(args)
|
|
260
|
+
ENV.delete('PB_SERVER_TYPE')
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
it 'configures the connector type to be zmq' do
|
|
264
|
+
load "protobuf/zmq.rb"
|
|
265
|
+
expect(::Protobuf.connector_type).to eq(:zmq)
|
|
266
|
+
end
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
require 'protobuf/code_generator'
|
|
4
|
+
|
|
5
|
+
RSpec.describe ::Protobuf::CodeGenerator do
|
|
6
|
+
|
|
7
|
+
# Some constants to shorten things up
|
|
8
|
+
DESCRIPTOR = ::Google::Protobuf
|
|
9
|
+
COMPILER = ::Google::Protobuf::Compiler
|
|
10
|
+
|
|
11
|
+
describe '#response_bytes' do
|
|
12
|
+
let(:input_file1) { DESCRIPTOR::FileDescriptorProto.new(:name => 'test/foo.proto') }
|
|
13
|
+
let(:input_file2) { DESCRIPTOR::FileDescriptorProto.new(:name => 'test/bar.proto') }
|
|
14
|
+
|
|
15
|
+
let(:output_file1) { COMPILER::CodeGeneratorResponse::File.new(:name => 'test/foo.pb.rb') }
|
|
16
|
+
let(:output_file2) { COMPILER::CodeGeneratorResponse::File.new(:name => 'test/bar.pb.rb') }
|
|
17
|
+
|
|
18
|
+
let(:file_generator1) { double('file generator 1', :generate_output_file => output_file1) }
|
|
19
|
+
let(:file_generator2) { double('file generator 2', :generate_output_file => output_file2) }
|
|
20
|
+
|
|
21
|
+
let(:request_bytes) do
|
|
22
|
+
COMPILER::CodeGeneratorRequest.encode(:proto_file => [input_file1, input_file2])
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
let(:expected_response_bytes) do
|
|
26
|
+
COMPILER::CodeGeneratorResponse.encode(:file => [output_file1, output_file2])
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
before do
|
|
30
|
+
expect(::Protobuf::Generators::FileGenerator).to receive(:new).with(input_file1).and_return(file_generator1)
|
|
31
|
+
expect(::Protobuf::Generators::FileGenerator).to receive(:new).with(input_file2).and_return(file_generator2)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it 'returns the serialized CodeGeneratorResponse which contains the generated file contents' do
|
|
35
|
+
generator = described_class.new(request_bytes)
|
|
36
|
+
expect(generator.response_bytes).to eq expected_response_bytes
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
context 'class-level printing methods' do
|
|
41
|
+
describe '.fatal' do
|
|
42
|
+
it 'raises a CodeGeneratorFatalError error' do
|
|
43
|
+
expect do
|
|
44
|
+
described_class.fatal("something is wrong")
|
|
45
|
+
end.to raise_error(
|
|
46
|
+
::Protobuf::CodeGenerator::CodeGeneratorFatalError,
|
|
47
|
+
"something is wrong",
|
|
48
|
+
)
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
describe '.warn' do
|
|
53
|
+
it 'prints a warning to stderr' do
|
|
54
|
+
expect(STDERR).to receive(:puts).with("[WARN] a warning")
|
|
55
|
+
described_class.warn("a warning")
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
end
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
RSpec.describe Protobuf::Enum do
|
|
4
|
+
|
|
5
|
+
describe 'class dsl' do
|
|
6
|
+
let(:name) { :THREE }
|
|
7
|
+
let(:tag) { 3 }
|
|
8
|
+
|
|
9
|
+
before(:all) do
|
|
10
|
+
Test::EnumTestType.define(:MINUS_ONE, -1)
|
|
11
|
+
Test::EnumTestType.define(:THREE, 3)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
before(:all) do
|
|
15
|
+
EnumAliasTest = ::Class.new(::Protobuf::Enum) do
|
|
16
|
+
set_option :allow_alias
|
|
17
|
+
define :FOO, 1
|
|
18
|
+
define :BAR, 1
|
|
19
|
+
define :BAZ, 2
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
describe '.aliases_allowed?' do
|
|
24
|
+
it 'is nil when the option is not set' do
|
|
25
|
+
expect(Test::EnumTestType.aliases_allowed?).to be nil
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
describe '.define' do
|
|
30
|
+
it 'defines a constant enum on the parent class' do
|
|
31
|
+
expect(Test::EnumTestType.constants).to include(name)
|
|
32
|
+
expect(Test::EnumTestType::THREE).to be_a(Protobuf::Enum)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
context 'when enum allows aliases' do
|
|
36
|
+
before(:all) do
|
|
37
|
+
DefineEnumAlias = ::Class.new(::Protobuf::Enum) do
|
|
38
|
+
set_option :allow_alias
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it 'allows defining enums with the same tag number' do
|
|
43
|
+
expect do
|
|
44
|
+
DefineEnumAlias.define(:FOO, 1)
|
|
45
|
+
DefineEnumAlias.define(:BAR, 1)
|
|
46
|
+
end.not_to raise_error
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
describe '.enums' do
|
|
52
|
+
it 'provides an array of defined Enums' do
|
|
53
|
+
expect(Test::EnumTestType.enums).to eq(
|
|
54
|
+
[
|
|
55
|
+
Test::EnumTestType::ONE,
|
|
56
|
+
Test::EnumTestType::TWO,
|
|
57
|
+
Test::EnumTestType::MINUS_ONE,
|
|
58
|
+
Test::EnumTestType::THREE,
|
|
59
|
+
],
|
|
60
|
+
)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
context 'when enum allows aliases' do
|
|
64
|
+
it 'treats aliased enums as valid' do
|
|
65
|
+
expect(EnumAliasTest.enums).to eq(
|
|
66
|
+
[
|
|
67
|
+
EnumAliasTest::FOO,
|
|
68
|
+
EnumAliasTest::BAR,
|
|
69
|
+
EnumAliasTest::BAZ,
|
|
70
|
+
],
|
|
71
|
+
)
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
describe '.enums_for_tag' do
|
|
77
|
+
it 'returns an array of Enums for the given tag, if any' do
|
|
78
|
+
expect(EnumAliasTest.enums_for_tag(1)).to eq([EnumAliasTest::FOO, EnumAliasTest::BAR])
|
|
79
|
+
expect(EnumAliasTest.enums_for_tag(2)).to eq([EnumAliasTest::BAZ])
|
|
80
|
+
expect(EnumAliasTest.enums_for_tag(3)).to eq([])
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
describe '.fetch' do
|
|
85
|
+
context 'when candidate is an Enum' do
|
|
86
|
+
it 'responds with the Enum' do
|
|
87
|
+
expect(Test::EnumTestType.fetch(Test::EnumTestType::THREE)).to eq(Test::EnumTestType::THREE)
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
context 'when candidate can be coerced to a symbol' do
|
|
92
|
+
it 'fetches based on the symbol name' do
|
|
93
|
+
expect(Test::EnumTestType.fetch("ONE")).to eq(Test::EnumTestType::ONE)
|
|
94
|
+
expect(Test::EnumTestType.fetch(:ONE)).to eq(Test::EnumTestType::ONE)
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
context 'when candidate can be coerced to an integer' do
|
|
99
|
+
it 'fetches based on the integer tag' do
|
|
100
|
+
expect(Test::EnumTestType.fetch(3.0)).to eq(Test::EnumTestType::THREE)
|
|
101
|
+
expect(Test::EnumTestType.fetch(3)).to eq(Test::EnumTestType::THREE)
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
context 'when enum allows aliases' do
|
|
105
|
+
it 'fetches the first defined Enum' do
|
|
106
|
+
expect(EnumAliasTest.fetch(1)).to eq(EnumAliasTest::FOO)
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
context 'when candidate is not an applicable type' do
|
|
112
|
+
it 'returns a nil' do
|
|
113
|
+
expect(Test::EnumTestType.fetch(EnumAliasTest::FOO)).to be_nil
|
|
114
|
+
expect(Test::EnumTestType.fetch(Test::Resource.new)).to be_nil
|
|
115
|
+
expect(Test::EnumTestType.fetch(nil)).to be_nil
|
|
116
|
+
expect(Test::EnumTestType.fetch(false)).to be_nil
|
|
117
|
+
expect(Test::EnumTestType.fetch(-10)).to be_nil
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
describe '.enum_for_tag' do
|
|
123
|
+
it 'gets the Enum corresponding to the given tag' do
|
|
124
|
+
expect(Test::EnumTestType.enum_for_tag(tag)).to eq(Test::EnumTestType.const_get(name))
|
|
125
|
+
expect(Test::EnumTestType.enum_for_tag(-5)).to be_nil
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
describe '.name_for_tag' do
|
|
130
|
+
it 'get the name of the enum given the enum' do
|
|
131
|
+
expect(Test::EnumTestType.name_for_tag(::Test::EnumTestType::THREE)).to eq(name)
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
it 'gets the name of the enum corresponding to the given tag' do
|
|
135
|
+
expect(Test::EnumTestType.name_for_tag(tag)).to eq(name)
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
it 'gets the name when the tag is coercable to an int' do
|
|
139
|
+
expect(Test::EnumTestType.name_for_tag("3")).to eq(name)
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
it 'returns nil when tag does not correspond to a name' do
|
|
143
|
+
expect(Test::EnumTestType.name_for_tag(12345)).to be_nil
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
context 'when given name is nil' do
|
|
147
|
+
it 'returns a nil' do
|
|
148
|
+
expect(Test::EnumTestType.name_for_tag(nil)).to be_nil
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
context 'when enum allows aliases' do
|
|
153
|
+
it 'returns the first defined name for the given tag' do
|
|
154
|
+
expect(EnumAliasTest.name_for_tag(1)).to eq(:FOO)
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
describe '.valid_tag?' do
|
|
160
|
+
context 'when tag is defined' do
|
|
161
|
+
specify { expect(Test::EnumTestType.valid_tag?(tag)).to be true }
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
context 'when tag is not defined' do
|
|
165
|
+
specify { expect(Test::EnumTestType.valid_tag?(300)).to be false }
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
context 'is true for aliased enums' do
|
|
169
|
+
specify { expect(EnumAliasTest.valid_tag?(1)).to be true }
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
describe '.enum_for_name' do
|
|
174
|
+
it 'gets the Enum corresponding to the given name' do
|
|
175
|
+
expect(Test::EnumTestType.enum_for_name(name)).to eq(Test::EnumTestType::THREE)
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
describe '.values' do
|
|
180
|
+
around do |example|
|
|
181
|
+
# this method is deprecated
|
|
182
|
+
::Protobuf.deprecator.silence(&example)
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
it 'provides a hash of defined Enums' do
|
|
186
|
+
expect(Test::EnumTestType.values).to eq(
|
|
187
|
+
:MINUS_ONE => Test::EnumTestType::MINUS_ONE,
|
|
188
|
+
:ONE => Test::EnumTestType::ONE,
|
|
189
|
+
:TWO => Test::EnumTestType::TWO,
|
|
190
|
+
:THREE => Test::EnumTestType::THREE,
|
|
191
|
+
)
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
it 'contains aliased Enums' do
|
|
195
|
+
expect(EnumAliasTest.values).to eq(
|
|
196
|
+
:FOO => EnumAliasTest::FOO,
|
|
197
|
+
:BAR => EnumAliasTest::BAR,
|
|
198
|
+
:BAZ => EnumAliasTest::BAZ,
|
|
199
|
+
)
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
describe '.all_tags' do
|
|
204
|
+
it 'provides a unique array of defined tags' do
|
|
205
|
+
expect(Test::EnumTestType.all_tags).to include(1, 2, -1, 3)
|
|
206
|
+
expect(EnumAliasTest.all_tags).to include(1, 2)
|
|
207
|
+
end
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
subject { Test::EnumTestType::ONE }
|
|
212
|
+
specify { expect(subject.class).to eq(Fixnum) }
|
|
213
|
+
specify { expect(subject.parent_class).to eq(Test::EnumTestType) }
|
|
214
|
+
specify { expect(subject.name).to eq(:ONE) }
|
|
215
|
+
specify { expect(subject.tag).to eq(1) }
|
|
216
|
+
|
|
217
|
+
context 'deprecated' do
|
|
218
|
+
around do |example|
|
|
219
|
+
# this method is deprecated
|
|
220
|
+
::Protobuf.deprecator.silence(&example)
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
specify { expect(subject.value).to eq(1) }
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
specify { expect(subject.to_hash_value).to eq(1) }
|
|
227
|
+
specify { expect(subject.to_s).to eq("1") }
|
|
228
|
+
specify { expect(subject.inspect).to eq('#<Protobuf::Enum(Test::EnumTestType)::ONE=1>') }
|
|
229
|
+
specify { expect(subject.to_s(:tag)).to eq("1") }
|
|
230
|
+
specify { expect(subject.to_s(:name)).to eq("ONE") }
|
|
231
|
+
|
|
232
|
+
it "can be used as the index to an array" do
|
|
233
|
+
array = [0, 1, 2, 3]
|
|
234
|
+
expect(array[::Test::EnumTestType::ONE]).to eq(1)
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
describe '#try' do
|
|
238
|
+
specify { expect(subject.try(:parent_class)).to eq(subject.parent_class) }
|
|
239
|
+
specify { expect(subject.try(:class)).to eq(subject.class) }
|
|
240
|
+
specify { expect(subject.try(:name)).to eq(subject.name) }
|
|
241
|
+
specify { expect(subject.try(:tag)).to eq(subject.tag) }
|
|
242
|
+
|
|
243
|
+
context 'deprecated' do
|
|
244
|
+
around do |example|
|
|
245
|
+
# this method is deprecated
|
|
246
|
+
::Protobuf.deprecator.silence(&example)
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
specify { expect(subject.try(:value)).to eq(subject.value) }
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
specify { expect(subject.try(:to_i)).to eq(subject.to_i) }
|
|
253
|
+
specify { expect(subject.try(:to_int)).to eq(subject.to_int) }
|
|
254
|
+
specify { subject.try { |yielded| expect(yielded).to eq(subject) } }
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
context 'when coercing from enum' do
|
|
258
|
+
subject { Test::StatusType::PENDING }
|
|
259
|
+
it { is_expected.to eq(0) }
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
context 'when coercing from integer' do
|
|
263
|
+
specify { expect(0).to eq(Test::StatusType::PENDING) }
|
|
264
|
+
end
|
|
265
|
+
end
|