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,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