grpc 0.13.0.pre1.1-universal-darwin

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of grpc might be problematic. Click here for more details.

Files changed (95) hide show
  1. checksums.yaml +7 -0
  2. data/etc/roots.pem +5114 -0
  3. data/grpc_c.32.ruby +0 -0
  4. data/grpc_c.64.ruby +0 -0
  5. data/src/ruby/bin/apis/google/protobuf/empty.rb +44 -0
  6. data/src/ruby/bin/apis/pubsub_demo.rb +256 -0
  7. data/src/ruby/bin/apis/tech/pubsub/proto/pubsub.rb +174 -0
  8. data/src/ruby/bin/apis/tech/pubsub/proto/pubsub_services.rb +103 -0
  9. data/src/ruby/bin/grpc_ruby_interop_client +33 -0
  10. data/src/ruby/bin/grpc_ruby_interop_server +33 -0
  11. data/src/ruby/bin/interop/interop_client.rb +51 -0
  12. data/src/ruby/bin/interop/interop_server.rb +50 -0
  13. data/src/ruby/bin/math.rb +32 -0
  14. data/src/ruby/bin/math_client.rb +147 -0
  15. data/src/ruby/bin/math_server.rb +206 -0
  16. data/src/ruby/bin/math_services.rb +27 -0
  17. data/src/ruby/bin/noproto_client.rb +108 -0
  18. data/src/ruby/bin/noproto_server.rb +112 -0
  19. data/src/ruby/ext/grpc/extconf.rb +129 -0
  20. data/src/ruby/ext/grpc/rb_byte_buffer.c +70 -0
  21. data/src/ruby/ext/grpc/rb_byte_buffer.h +47 -0
  22. data/src/ruby/ext/grpc/rb_call.c +908 -0
  23. data/src/ruby/ext/grpc/rb_call.h +66 -0
  24. data/src/ruby/ext/grpc/rb_call_credentials.c +319 -0
  25. data/src/ruby/ext/grpc/rb_call_credentials.h +46 -0
  26. data/src/ruby/ext/grpc/rb_channel.c +432 -0
  27. data/src/ruby/ext/grpc/rb_channel.h +47 -0
  28. data/src/ruby/ext/grpc/rb_channel_args.c +169 -0
  29. data/src/ruby/ext/grpc/rb_channel_args.h +53 -0
  30. data/src/ruby/ext/grpc/rb_channel_credentials.c +268 -0
  31. data/src/ruby/ext/grpc/rb_channel_credentials.h +47 -0
  32. data/src/ruby/ext/grpc/rb_completion_queue.c +183 -0
  33. data/src/ruby/ext/grpc/rb_completion_queue.h +55 -0
  34. data/src/ruby/ext/grpc/rb_event_thread.c +158 -0
  35. data/src/ruby/ext/grpc/rb_event_thread.h +37 -0
  36. data/src/ruby/ext/grpc/rb_grpc.c +336 -0
  37. data/src/ruby/ext/grpc/rb_grpc.h +85 -0
  38. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +560 -0
  39. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +843 -0
  40. data/src/ruby/ext/grpc/rb_loader.c +72 -0
  41. data/src/ruby/ext/grpc/rb_loader.h +40 -0
  42. data/src/ruby/ext/grpc/rb_server.c +400 -0
  43. data/src/ruby/ext/grpc/rb_server.h +47 -0
  44. data/src/ruby/ext/grpc/rb_server_credentials.c +284 -0
  45. data/src/ruby/ext/grpc/rb_server_credentials.h +47 -0
  46. data/src/ruby/lib/grpc.rb +44 -0
  47. data/src/ruby/lib/grpc/2.0/grpc_c.bundle +0 -0
  48. data/src/ruby/lib/grpc/2.1/grpc_c.bundle +0 -0
  49. data/src/ruby/lib/grpc/2.2/grpc_c.bundle +0 -0
  50. data/src/ruby/lib/grpc/2.3/grpc_c.bundle +0 -0
  51. data/src/ruby/lib/grpc/core/time_consts.rb +71 -0
  52. data/src/ruby/lib/grpc/errors.rb +62 -0
  53. data/src/ruby/lib/grpc/generic/active_call.rb +488 -0
  54. data/src/ruby/lib/grpc/generic/bidi_call.rb +218 -0
  55. data/src/ruby/lib/grpc/generic/client_stub.rb +471 -0
  56. data/src/ruby/lib/grpc/generic/rpc_desc.rb +147 -0
  57. data/src/ruby/lib/grpc/generic/rpc_server.rb +504 -0
  58. data/src/ruby/lib/grpc/generic/service.rb +234 -0
  59. data/src/ruby/lib/grpc/grpc.rb +34 -0
  60. data/src/ruby/lib/grpc/logconfig.rb +59 -0
  61. data/src/ruby/lib/grpc/notifier.rb +60 -0
  62. data/src/ruby/lib/grpc/version.rb +33 -0
  63. data/src/ruby/pb/README.md +42 -0
  64. data/src/ruby/pb/generate_proto_ruby.sh +51 -0
  65. data/src/ruby/pb/grpc/health/checker.rb +75 -0
  66. data/src/ruby/pb/grpc/health/v1alpha/health.rb +29 -0
  67. data/src/ruby/pb/grpc/health/v1alpha/health_services.rb +28 -0
  68. data/src/ruby/pb/test/client.rb +469 -0
  69. data/src/ruby/pb/test/proto/empty.rb +15 -0
  70. data/src/ruby/pb/test/proto/messages.rb +80 -0
  71. data/src/ruby/pb/test/proto/test.rb +14 -0
  72. data/src/ruby/pb/test/proto/test_services.rb +64 -0
  73. data/src/ruby/pb/test/server.rb +253 -0
  74. data/src/ruby/spec/call_credentials_spec.rb +57 -0
  75. data/src/ruby/spec/call_spec.rb +163 -0
  76. data/src/ruby/spec/channel_credentials_spec.rb +97 -0
  77. data/src/ruby/spec/channel_spec.rb +177 -0
  78. data/src/ruby/spec/client_server_spec.rb +475 -0
  79. data/src/ruby/spec/completion_queue_spec.rb +42 -0
  80. data/src/ruby/spec/generic/active_call_spec.rb +373 -0
  81. data/src/ruby/spec/generic/client_stub_spec.rb +476 -0
  82. data/src/ruby/spec/generic/rpc_desc_spec.rb +331 -0
  83. data/src/ruby/spec/generic/rpc_server_pool_spec.rb +138 -0
  84. data/src/ruby/spec/generic/rpc_server_spec.rb +576 -0
  85. data/src/ruby/spec/generic/service_spec.rb +345 -0
  86. data/src/ruby/spec/pb/health/checker_spec.rb +232 -0
  87. data/src/ruby/spec/server_credentials_spec.rb +94 -0
  88. data/src/ruby/spec/server_spec.rb +209 -0
  89. data/src/ruby/spec/spec_helper.rb +69 -0
  90. data/src/ruby/spec/testdata/README +1 -0
  91. data/src/ruby/spec/testdata/ca.pem +15 -0
  92. data/src/ruby/spec/testdata/server1.key +16 -0
  93. data/src/ruby/spec/testdata/server1.pem +16 -0
  94. data/src/ruby/spec/time_consts_spec.rb +89 -0
  95. metadata +319 -0
@@ -0,0 +1,51 @@
1
+ #!/bin/sh
2
+ # Copyright 2015, Google Inc.
3
+ # All rights reserved.
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without
6
+ # modification, are permitted provided that the following conditions are
7
+ # met:
8
+ #
9
+ # * Redistributions of source code must retain the above copyright
10
+ # notice, this list of conditions and the following disclaimer.
11
+ # * Redistributions in binary form must reproduce the above
12
+ # copyright notice, this list of conditions and the following disclaimer
13
+ # in the documentation and/or other materials provided with the
14
+ # distribution.
15
+ # * Neither the name of Google Inc. nor the names of its
16
+ # contributors may be used to endorse or promote products derived from
17
+ # this software without specific prior written permission.
18
+ #
19
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
+ # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
+ # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22
+ # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23
+ # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24
+ # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25
+ # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26
+ # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27
+ # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
+ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
+
31
+ # Regenerates gRPC service stubs from proto files.
32
+ set +e
33
+ cd $(dirname $0)/../../..
34
+
35
+ PROTOC=bins/opt/protobuf/protoc
36
+ PLUGIN=protoc-gen-grpc=bins/opt/grpc_ruby_plugin
37
+
38
+ $PROTOC -I src/proto src/proto/grpc/health/v1alpha/health.proto \
39
+ --grpc_out=src/ruby/pb \
40
+ --ruby_out=src/ruby/pb \
41
+ --plugin=$PLUGIN
42
+
43
+ $PROTOC -I . test/proto/{messages,test,empty}.proto \
44
+ --grpc_out=src/ruby/pb \
45
+ --ruby_out=src/ruby/pb \
46
+ --plugin=$PLUGIN
47
+
48
+ $PROTOC -I src/proto/math src/proto/math/math.proto \
49
+ --grpc_out=src/ruby/bin \
50
+ --ruby_out=src/ruby/bin \
51
+ --plugin=$PLUGIN
@@ -0,0 +1,75 @@
1
+ # Copyright 2015, Google Inc.
2
+ # All rights reserved.
3
+ #
4
+ # Redistribution and use in source and binary forms, with or without
5
+ # modification, are permitted provided that the following conditions are
6
+ # met:
7
+ #
8
+ # * Redistributions of source code must retain the above copyright
9
+ # notice, this list of conditions and the following disclaimer.
10
+ # * Redistributions in binary form must reproduce the above
11
+ # copyright notice, this list of conditions and the following disclaimer
12
+ # in the documentation and/or other materials provided with the
13
+ # distribution.
14
+ # * Neither the name of Google Inc. nor the names of its
15
+ # contributors may be used to endorse or promote products derived from
16
+ # this software without specific prior written permission.
17
+ #
18
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19
+ # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20
+ # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21
+ # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22
+ # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23
+ # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24
+ # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
+ # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26
+ # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27
+ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
+
30
+ require 'grpc'
31
+ require 'grpc/health/v1alpha/health_services'
32
+ require 'thread'
33
+
34
+ module Grpc
35
+ # Health contains classes and modules that support providing a health check
36
+ # service.
37
+ module Health
38
+ # Checker is implementation of the schema-specified health checking service.
39
+ class Checker < V1alpha::Health::Service
40
+ StatusCodes = GRPC::Core::StatusCodes
41
+ HealthCheckResponse = V1alpha::HealthCheckResponse
42
+
43
+ # Initializes the statuses of participating services
44
+ def initialize
45
+ @statuses = {}
46
+ @status_mutex = Mutex.new # guards access to @statuses
47
+ end
48
+
49
+ # Implements the rpc IDL API method
50
+ def check(req, _call)
51
+ status = nil
52
+ @status_mutex.synchronize do
53
+ status = @statuses["#{req.host}/#{req.service}"]
54
+ end
55
+ fail GRPC::BadStatus, StatusCodes::NOT_FOUND if status.nil?
56
+ HealthCheckResponse.new(status: status)
57
+ end
58
+
59
+ # Adds the health status for a given host and service.
60
+ def add_status(host, service, status)
61
+ @status_mutex.synchronize { @statuses["#{host}/#{service}"] = status }
62
+ end
63
+
64
+ # Clears the status for the given host or service.
65
+ def clear_status(host, service)
66
+ @status_mutex.synchronize { @statuses.delete("#{host}/#{service}") }
67
+ end
68
+
69
+ # Clears alls the statuses.
70
+ def clear_all
71
+ @status_mutex.synchronize { @statuses = {} }
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,29 @@
1
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
2
+ # source: grpc/health/v1alpha/health.proto
3
+
4
+ require 'google/protobuf'
5
+
6
+ Google::Protobuf::DescriptorPool.generated_pool.build do
7
+ add_message "grpc.health.v1alpha.HealthCheckRequest" do
8
+ optional :host, :string, 1
9
+ optional :service, :string, 2
10
+ end
11
+ add_message "grpc.health.v1alpha.HealthCheckResponse" do
12
+ optional :status, :enum, 1, "grpc.health.v1alpha.HealthCheckResponse.ServingStatus"
13
+ end
14
+ add_enum "grpc.health.v1alpha.HealthCheckResponse.ServingStatus" do
15
+ value :UNKNOWN, 0
16
+ value :SERVING, 1
17
+ value :NOT_SERVING, 2
18
+ end
19
+ end
20
+
21
+ module Grpc
22
+ module Health
23
+ module V1alpha
24
+ HealthCheckRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.health.v1alpha.HealthCheckRequest").msgclass
25
+ HealthCheckResponse = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.health.v1alpha.HealthCheckResponse").msgclass
26
+ HealthCheckResponse::ServingStatus = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.health.v1alpha.HealthCheckResponse.ServingStatus").enummodule
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,28 @@
1
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
2
+ # Source: grpc/health/v1alpha/health.proto for package 'grpc.health.v1alpha'
3
+
4
+ require 'grpc'
5
+ require 'grpc/health/v1alpha/health'
6
+
7
+ module Grpc
8
+ module Health
9
+ module V1alpha
10
+ module Health
11
+
12
+ # TODO: add proto service documentation here
13
+ class Service
14
+
15
+ include GRPC::GenericService
16
+
17
+ self.marshal_class_method = :encode
18
+ self.unmarshal_class_method = :decode
19
+ self.service_name = 'grpc.health.v1alpha.Health'
20
+
21
+ rpc :Check, HealthCheckRequest, HealthCheckResponse
22
+ end
23
+
24
+ Stub = Service.rpc_stub_class
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,469 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Copyright 2015-2016, Google Inc.
4
+ # All rights reserved.
5
+ #
6
+ # Redistribution and use in source and binary forms, with or without
7
+ # modification, are permitted provided that the following conditions are
8
+ # met:
9
+ #
10
+ # * Redistributions of source code must retain the above copyright
11
+ # notice, this list of conditions and the following disclaimer.
12
+ # * Redistributions in binary form must reproduce the above
13
+ # copyright notice, this list of conditions and the following disclaimer
14
+ # in the documentation and/or other materials provided with the
15
+ # distribution.
16
+ # * Neither the name of Google Inc. nor the names of its
17
+ # contributors may be used to endorse or promote products derived from
18
+ # this software without specific prior written permission.
19
+ #
20
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21
+ # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22
+ # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23
+ # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24
+ # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25
+ # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26
+ # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27
+ # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28
+ # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29
+ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+
32
+ # client is a testing tool that accesses a gRPC interop testing server and runs
33
+ # a test on it.
34
+ #
35
+ # Helps validate interoperation b/w different gRPC implementations.
36
+ #
37
+ # Usage: $ path/to/client.rb --server_host=<hostname> \
38
+ # --server_port=<port> \
39
+ # --test_case=<testcase_name>
40
+
41
+ this_dir = File.expand_path(File.dirname(__FILE__))
42
+ lib_dir = File.join(File.dirname(File.dirname(this_dir)), 'lib')
43
+ pb_dir = File.dirname(File.dirname(this_dir))
44
+ $LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir)
45
+ $LOAD_PATH.unshift(pb_dir) unless $LOAD_PATH.include?(pb_dir)
46
+ $LOAD_PATH.unshift(this_dir) unless $LOAD_PATH.include?(this_dir)
47
+
48
+ require 'optparse'
49
+ require 'logger'
50
+
51
+ require 'grpc'
52
+ require 'googleauth'
53
+ require 'google/protobuf'
54
+
55
+ require 'test/proto/empty'
56
+ require 'test/proto/messages'
57
+ require 'test/proto/test_services'
58
+
59
+ AUTH_ENV = Google::Auth::CredentialsLoader::ENV_VAR
60
+
61
+ # RubyLogger defines a logger for gRPC based on the standard ruby logger.
62
+ module RubyLogger
63
+ def logger
64
+ LOGGER
65
+ end
66
+
67
+ LOGGER = Logger.new(STDOUT)
68
+ LOGGER.level = Logger::INFO
69
+ end
70
+
71
+ # GRPC is the general RPC module
72
+ module GRPC
73
+ # Inject the noop #logger if no module-level logger method has been injected.
74
+ extend RubyLogger
75
+ end
76
+
77
+ # AssertionError is use to indicate interop test failures.
78
+ class AssertionError < RuntimeError; end
79
+
80
+ # Fails with AssertionError if the block does evaluate to true
81
+ def assert(msg = 'unknown cause')
82
+ fail 'No assertion block provided' unless block_given?
83
+ fail AssertionError, msg unless yield
84
+ end
85
+
86
+ # loads the certificates used to access the test server securely.
87
+ def load_test_certs
88
+ this_dir = File.expand_path(File.dirname(__FILE__))
89
+ data_dir = File.join(File.dirname(File.dirname(this_dir)), 'spec/testdata')
90
+ files = ['ca.pem', 'server1.key', 'server1.pem']
91
+ files.map { |f| File.open(File.join(data_dir, f)).read }
92
+ end
93
+
94
+ # creates SSL Credentials from the test certificates.
95
+ def test_creds
96
+ certs = load_test_certs
97
+ GRPC::Core::ChannelCredentials.new(certs[0])
98
+ end
99
+
100
+ # creates SSL Credentials from the production certificates.
101
+ def prod_creds
102
+ GRPC::Core::ChannelCredentials.new()
103
+ end
104
+
105
+ # creates the SSL Credentials.
106
+ def ssl_creds(use_test_ca)
107
+ return test_creds if use_test_ca
108
+ prod_creds
109
+ end
110
+
111
+ # creates a test stub that accesses host:port securely.
112
+ def create_stub(opts)
113
+ address = "#{opts.host}:#{opts.port}"
114
+ if opts.secure
115
+ creds = ssl_creds(opts.use_test_ca)
116
+ stub_opts = {
117
+ GRPC::Core::Channel::SSL_TARGET => opts.host_override
118
+ }
119
+
120
+ # Add service account creds if specified
121
+ wants_creds = %w(all compute_engine_creds service_account_creds)
122
+ if wants_creds.include?(opts.test_case)
123
+ unless opts.oauth_scope.nil?
124
+ auth_creds = Google::Auth.get_application_default(opts.oauth_scope)
125
+ call_creds = GRPC::Core::CallCredentials.new(auth_creds.updater_proc)
126
+ creds = creds.compose call_creds
127
+ end
128
+ end
129
+
130
+ if opts.test_case == 'oauth2_auth_token'
131
+ auth_creds = Google::Auth.get_application_default(opts.oauth_scope)
132
+ kw = auth_creds.updater_proc.call({}) # gives as an auth token
133
+
134
+ # use a metadata update proc that just adds the auth token.
135
+ call_creds = GRPC::Core::CallCredentials.new(proc { |md| md.merge(kw) })
136
+ creds = creds.compose call_creds
137
+ end
138
+
139
+ if opts.test_case == 'jwt_token_creds' # don't use a scope
140
+ auth_creds = Google::Auth.get_application_default
141
+ call_creds = GRPC::Core::CallCredentials.new(auth_creds.updater_proc)
142
+ creds = creds.compose call_creds
143
+ end
144
+
145
+ GRPC.logger.info("... connecting securely to #{address}")
146
+ Grpc::Testing::TestService::Stub.new(address, creds, **stub_opts)
147
+ else
148
+ GRPC.logger.info("... connecting insecurely to #{address}")
149
+ Grpc::Testing::TestService::Stub.new(address, :this_channel_is_insecure)
150
+ end
151
+ end
152
+
153
+ # produces a string of null chars (\0) of length l.
154
+ def nulls(l)
155
+ fail 'requires #{l} to be +ve' if l < 0
156
+ [].pack('x' * l).force_encoding('ascii-8bit')
157
+ end
158
+
159
+ # a PingPongPlayer implements the ping pong bidi test.
160
+ class PingPongPlayer
161
+ include Grpc::Testing
162
+ include Grpc::Testing::PayloadType
163
+ attr_accessor :queue
164
+ attr_accessor :canceller_op
165
+
166
+ # reqs is the enumerator over the requests
167
+ def initialize(msg_sizes)
168
+ @queue = Queue.new
169
+ @msg_sizes = msg_sizes
170
+ @canceller_op = nil # used to cancel after the first response
171
+ end
172
+
173
+ def each_item
174
+ return enum_for(:each_item) unless block_given?
175
+ req_cls, p_cls = StreamingOutputCallRequest, ResponseParameters # short
176
+ count = 0
177
+ @msg_sizes.each do |m|
178
+ req_size, resp_size = m
179
+ req = req_cls.new(payload: Payload.new(body: nulls(req_size)),
180
+ response_type: :COMPRESSABLE,
181
+ response_parameters: [p_cls.new(size: resp_size)])
182
+ yield req
183
+ resp = @queue.pop
184
+ assert('payload type is wrong') { :COMPRESSABLE == resp.payload.type }
185
+ assert("payload body #{count} has the wrong length") do
186
+ resp_size == resp.payload.body.length
187
+ end
188
+ p "OK: ping_pong #{count}"
189
+ count += 1
190
+ unless @canceller_op.nil?
191
+ canceller_op.cancel
192
+ break
193
+ end
194
+ end
195
+ end
196
+ end
197
+
198
+ # defines methods corresponding to each interop test case.
199
+ class NamedTests
200
+ include Grpc::Testing
201
+ include Grpc::Testing::PayloadType
202
+
203
+ def initialize(stub, args)
204
+ @stub = stub
205
+ @args = args
206
+ end
207
+
208
+ def empty_unary
209
+ resp = @stub.empty_call(Empty.new)
210
+ assert('empty_unary: invalid response') { resp.is_a?(Empty) }
211
+ p 'OK: empty_unary'
212
+ end
213
+
214
+ def large_unary
215
+ perform_large_unary
216
+ p 'OK: large_unary'
217
+ end
218
+
219
+ def service_account_creds
220
+ # ignore this test if the oauth options are not set
221
+ if @args.oauth_scope.nil?
222
+ p 'NOT RUN: service_account_creds; no service_account settings'
223
+ return
224
+ end
225
+ json_key = File.read(ENV[AUTH_ENV])
226
+ wanted_email = MultiJson.load(json_key)['client_email']
227
+ resp = perform_large_unary(fill_username: true,
228
+ fill_oauth_scope: true)
229
+ assert("#{__callee__}: bad username") { wanted_email == resp.username }
230
+ assert("#{__callee__}: bad oauth scope") do
231
+ @args.oauth_scope.include?(resp.oauth_scope)
232
+ end
233
+ p "OK: #{__callee__}"
234
+ end
235
+
236
+ def jwt_token_creds
237
+ json_key = File.read(ENV[AUTH_ENV])
238
+ wanted_email = MultiJson.load(json_key)['client_email']
239
+ resp = perform_large_unary(fill_username: true)
240
+ assert("#{__callee__}: bad username") { wanted_email == resp.username }
241
+ p "OK: #{__callee__}"
242
+ end
243
+
244
+ def compute_engine_creds
245
+ resp = perform_large_unary(fill_username: true,
246
+ fill_oauth_scope: true)
247
+ assert("#{__callee__}: bad username") do
248
+ @args.default_service_account == resp.username
249
+ end
250
+ p "OK: #{__callee__}"
251
+ end
252
+
253
+ def oauth2_auth_token
254
+ resp = perform_large_unary(fill_username: true,
255
+ fill_oauth_scope: true)
256
+ json_key = File.read(ENV[AUTH_ENV])
257
+ wanted_email = MultiJson.load(json_key)['client_email']
258
+ assert("#{__callee__}: bad username") { wanted_email == resp.username }
259
+ assert("#{__callee__}: bad oauth scope") do
260
+ @args.oauth_scope.include?(resp.oauth_scope)
261
+ end
262
+ p "OK: #{__callee__}"
263
+ end
264
+
265
+ def per_rpc_creds
266
+ auth_creds = Google::Auth.get_application_default(@args.oauth_scope)
267
+ update_metadata = proc do |md|
268
+ kw = auth_creds.updater_proc.call({})
269
+ end
270
+
271
+ call_creds = GRPC::Core::CallCredentials.new(update_metadata)
272
+
273
+ resp = perform_large_unary(fill_username: true,
274
+ fill_oauth_scope: true,
275
+ credentials: call_creds)
276
+ json_key = File.read(ENV[AUTH_ENV])
277
+ wanted_email = MultiJson.load(json_key)['client_email']
278
+ assert("#{__callee__}: bad username") { wanted_email == resp.username }
279
+ assert("#{__callee__}: bad oauth scope") do
280
+ @args.oauth_scope.include?(resp.oauth_scope)
281
+ end
282
+ p "OK: #{__callee__}"
283
+ end
284
+
285
+ def client_streaming
286
+ msg_sizes = [27_182, 8, 1828, 45_904]
287
+ wanted_aggregate_size = 74_922
288
+ reqs = msg_sizes.map do |x|
289
+ req = Payload.new(body: nulls(x))
290
+ StreamingInputCallRequest.new(payload: req)
291
+ end
292
+ resp = @stub.streaming_input_call(reqs)
293
+ assert("#{__callee__}: aggregate payload size is incorrect") do
294
+ wanted_aggregate_size == resp.aggregated_payload_size
295
+ end
296
+ p "OK: #{__callee__}"
297
+ end
298
+
299
+ def server_streaming
300
+ msg_sizes = [31_415, 9, 2653, 58_979]
301
+ response_spec = msg_sizes.map { |s| ResponseParameters.new(size: s) }
302
+ req = StreamingOutputCallRequest.new(response_type: :COMPRESSABLE,
303
+ response_parameters: response_spec)
304
+ resps = @stub.streaming_output_call(req)
305
+ resps.each_with_index do |r, i|
306
+ assert("#{__callee__}: too many responses") { i < msg_sizes.length }
307
+ assert("#{__callee__}: payload body #{i} has the wrong length") do
308
+ msg_sizes[i] == r.payload.body.length
309
+ end
310
+ assert("#{__callee__}: payload type is wrong") do
311
+ :COMPRESSABLE == r.payload.type
312
+ end
313
+ end
314
+ p "OK: #{__callee__}"
315
+ end
316
+
317
+ def ping_pong
318
+ msg_sizes = [[27_182, 31_415], [8, 9], [1828, 2653], [45_904, 58_979]]
319
+ ppp = PingPongPlayer.new(msg_sizes)
320
+ resps = @stub.full_duplex_call(ppp.each_item)
321
+ resps.each { |r| ppp.queue.push(r) }
322
+ p "OK: #{__callee__}"
323
+ end
324
+
325
+ def timeout_on_sleeping_server
326
+ msg_sizes = [[27_182, 31_415]]
327
+ ppp = PingPongPlayer.new(msg_sizes)
328
+ resps = @stub.full_duplex_call(ppp.each_item, timeout: 0.001)
329
+ resps.each { |r| ppp.queue.push(r) }
330
+ fail 'Should have raised GRPC::BadStatus(DEADLINE_EXCEEDED)'
331
+ rescue GRPC::BadStatus => e
332
+ assert("#{__callee__}: status was wrong") do
333
+ e.code == GRPC::Core::StatusCodes::DEADLINE_EXCEEDED
334
+ end
335
+ p "OK: #{__callee__}"
336
+ end
337
+
338
+ def empty_stream
339
+ ppp = PingPongPlayer.new([])
340
+ resps = @stub.full_duplex_call(ppp.each_item)
341
+ count = 0
342
+ resps.each do |r|
343
+ ppp.queue.push(r)
344
+ count += 1
345
+ end
346
+ assert("#{__callee__}: too many responses expected 0") do
347
+ count == 0
348
+ end
349
+ p "OK: #{__callee__}"
350
+ end
351
+
352
+ def cancel_after_begin
353
+ msg_sizes = [27_182, 8, 1828, 45_904]
354
+ reqs = msg_sizes.map do |x|
355
+ req = Payload.new(body: nulls(x))
356
+ StreamingInputCallRequest.new(payload: req)
357
+ end
358
+ op = @stub.streaming_input_call(reqs, return_op: true)
359
+ op.cancel
360
+ op.execute
361
+ fail 'Should have raised GRPC:Cancelled'
362
+ rescue GRPC::Cancelled
363
+ assert("#{__callee__}: call operation should be CANCELLED") { op.cancelled }
364
+ p "OK: #{__callee__}"
365
+ end
366
+
367
+ def cancel_after_first_response
368
+ msg_sizes = [[27_182, 31_415], [8, 9], [1828, 2653], [45_904, 58_979]]
369
+ ppp = PingPongPlayer.new(msg_sizes)
370
+ op = @stub.full_duplex_call(ppp.each_item, return_op: true)
371
+ ppp.canceller_op = op # causes ppp to cancel after the 1st message
372
+ op.execute.each { |r| ppp.queue.push(r) }
373
+ fail 'Should have raised GRPC:Cancelled'
374
+ rescue GRPC::Cancelled
375
+ assert("#{__callee__}: call operation should be CANCELLED") { op.cancelled }
376
+ op.wait
377
+ p "OK: #{__callee__}"
378
+ end
379
+
380
+ def all
381
+ all_methods = NamedTests.instance_methods(false).map(&:to_s)
382
+ all_methods.each do |m|
383
+ next if m == 'all' || m.start_with?('assert')
384
+ p "TESTCASE: #{m}"
385
+ method(m).call
386
+ end
387
+ end
388
+
389
+ private
390
+
391
+ def perform_large_unary(fill_username: false, fill_oauth_scope: false, **kw)
392
+ req_size, wanted_response_size = 271_828, 314_159
393
+ payload = Payload.new(type: :COMPRESSABLE, body: nulls(req_size))
394
+ req = SimpleRequest.new(response_type: :COMPRESSABLE,
395
+ response_size: wanted_response_size,
396
+ payload: payload)
397
+ req.fill_username = fill_username
398
+ req.fill_oauth_scope = fill_oauth_scope
399
+ resp = @stub.unary_call(req, **kw)
400
+ assert('payload type is wrong') do
401
+ :COMPRESSABLE == resp.payload.type
402
+ end
403
+ assert('payload body has the wrong length') do
404
+ wanted_response_size == resp.payload.body.length
405
+ end
406
+ assert('payload body is invalid') do
407
+ nulls(wanted_response_size) == resp.payload.body
408
+ end
409
+ resp
410
+ end
411
+ end
412
+
413
+ # Args is used to hold the command line info.
414
+ Args = Struct.new(:default_service_account, :host, :host_override,
415
+ :oauth_scope, :port, :secure, :test_case,
416
+ :use_test_ca)
417
+
418
+ # validates the the command line options, returning them as a Hash.
419
+ def parse_args
420
+ args = Args.new
421
+ args.host_override = 'foo.test.google.fr'
422
+ OptionParser.new do |opts|
423
+ opts.on('--oauth_scope scope',
424
+ 'Scope for OAuth tokens') { |v| args['oauth_scope'] = v }
425
+ opts.on('--server_host SERVER_HOST', 'server hostname') do |v|
426
+ args['host'] = v
427
+ end
428
+ opts.on('--default_service_account email_address',
429
+ 'email address of the default service account') do |v|
430
+ args['default_service_account'] = v
431
+ end
432
+ opts.on('--server_host_override HOST_OVERRIDE',
433
+ 'override host via a HTTP header') do |v|
434
+ args['host_override'] = v
435
+ end
436
+ opts.on('--server_port SERVER_PORT', 'server port') { |v| args['port'] = v }
437
+ # instance_methods(false) gives only the methods defined in that class
438
+ test_cases = NamedTests.instance_methods(false).map(&:to_s)
439
+ test_case_list = test_cases.join(',')
440
+ opts.on('--test_case CODE', test_cases, {}, 'select a test_case',
441
+ " (#{test_case_list})") { |v| args['test_case'] = v }
442
+ opts.on('--use_tls USE_TLS', ['false', 'true'],
443
+ 'require a secure connection?') do |v|
444
+ args['secure'] = v == 'true'
445
+ end
446
+ opts.on('--use_test_ca USE_TEST_CA', ['false', 'true'],
447
+ 'if secure, use the test certificate?') do |v|
448
+ args['use_test_ca'] = v == 'true'
449
+ end
450
+ end.parse!
451
+ _check_args(args)
452
+ end
453
+
454
+ def _check_args(args)
455
+ %w(host port test_case).each do |a|
456
+ if args[a].nil?
457
+ fail(OptionParser::MissingArgument, "please specify --#{a}")
458
+ end
459
+ end
460
+ args
461
+ end
462
+
463
+ def main
464
+ opts = parse_args
465
+ stub = create_stub(opts)
466
+ NamedTests.new(stub, opts).method(opts['test_case']).call
467
+ end
468
+
469
+ main