grpc 1.33.0.pre1-x86-mingw32 → 1.37.0.pre1-x86-mingw32

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 (44) hide show
  1. checksums.yaml +4 -4
  2. data/etc/roots.pem +257 -573
  3. data/grpc_c.32.ruby +0 -0
  4. data/grpc_c.64.ruby +0 -0
  5. data/src/ruby/ext/grpc/extconf.rb +10 -2
  6. data/src/ruby/ext/grpc/rb_channel.c +10 -1
  7. data/src/ruby/ext/grpc/rb_channel_credentials.c +11 -1
  8. data/src/ruby/ext/grpc/rb_channel_credentials.h +4 -0
  9. data/src/ruby/ext/grpc/rb_compression_options.c +1 -1
  10. data/src/ruby/ext/grpc/rb_enable_cpp.cc +1 -1
  11. data/src/ruby/ext/grpc/rb_event_thread.c +2 -0
  12. data/src/ruby/ext/grpc/rb_grpc.c +4 -0
  13. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +36 -14
  14. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +70 -37
  15. data/src/ruby/ext/grpc/rb_server.c +13 -1
  16. data/src/ruby/ext/grpc/rb_server_credentials.c +19 -3
  17. data/src/ruby/ext/grpc/rb_server_credentials.h +4 -0
  18. data/src/ruby/ext/grpc/rb_xds_channel_credentials.c +215 -0
  19. data/src/ruby/ext/grpc/rb_xds_channel_credentials.h +35 -0
  20. data/src/ruby/ext/grpc/rb_xds_server_credentials.c +169 -0
  21. data/src/ruby/ext/grpc/rb_xds_server_credentials.h +35 -0
  22. data/src/ruby/lib/grpc/2.4/grpc_c.so +0 -0
  23. data/src/ruby/lib/grpc/2.5/grpc_c.so +0 -0
  24. data/src/ruby/lib/grpc/2.6/grpc_c.so +0 -0
  25. data/src/ruby/lib/grpc/2.7/grpc_c.so +0 -0
  26. data/src/ruby/lib/grpc/3.0/grpc_c.so +0 -0
  27. data/src/ruby/lib/grpc/generic/client_stub.rb +4 -2
  28. data/src/ruby/lib/grpc/version.rb +1 -1
  29. data/src/ruby/pb/src/proto/grpc/testing/messages_pb.rb +35 -0
  30. data/src/ruby/pb/src/proto/grpc/testing/test_services_pb.rb +18 -0
  31. data/src/ruby/pb/test/xds_client.rb +166 -25
  32. data/src/ruby/spec/call_spec.rb +1 -1
  33. data/src/ruby/spec/channel_credentials_spec.rb +32 -0
  34. data/src/ruby/spec/channel_spec.rb +17 -6
  35. data/src/ruby/spec/client_auth_spec.rb +27 -1
  36. data/src/ruby/spec/errors_spec.rb +1 -1
  37. data/src/ruby/spec/generic/active_call_spec.rb +2 -2
  38. data/src/ruby/spec/generic/client_stub_spec.rb +4 -4
  39. data/src/ruby/spec/generic/rpc_server_spec.rb +1 -1
  40. data/src/ruby/spec/pb/codegen/package_option_spec.rb +2 -6
  41. data/src/ruby/spec/server_credentials_spec.rb +25 -0
  42. data/src/ruby/spec/server_spec.rb +22 -0
  43. metadata +40 -36
  44. data/src/ruby/lib/grpc/2.3/grpc_c.so +0 -0
@@ -0,0 +1,35 @@
1
+ /*
2
+ *
3
+ * Copyright 2021 gRPC authors.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ *
17
+ */
18
+
19
+ #ifndef GRPC_RB_XDS_SERVER_CREDENTIALS_H_
20
+ #define GRPC_RB_XDS_SERVER_CREDENTIALS_H_
21
+
22
+ #include <grpc/grpc_security.h>
23
+ #include <ruby/ruby.h>
24
+ #include <stdbool.h>
25
+
26
+ /* Initializes the ruby XdsServerCredentials class. */
27
+ void Init_grpc_xds_server_credentials();
28
+
29
+ /* Gets the wrapped server_credentials from the ruby wrapper */
30
+ grpc_server_credentials* grpc_rb_get_wrapped_xds_server_credentials(VALUE v);
31
+
32
+ /* Check if v is kind of XdsServerCredentials */
33
+ bool grpc_rb_is_xds_server_credentials(VALUE v);
34
+
35
+ #endif /* GRPC_RB_XDS_SERVER_CREDENTIALS_H_ */
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -41,8 +41,10 @@ module GRPC
41
41
  channel_args['grpc.primary_user_agent'] += ' '
42
42
  end
43
43
  channel_args['grpc.primary_user_agent'] += "grpc-ruby/#{VERSION}"
44
- unless creds.is_a?(Core::ChannelCredentials) || creds.is_a?(Symbol)
45
- fail(TypeError, '!ChannelCredentials or Symbol')
44
+ unless creds.is_a?(Core::ChannelCredentials) ||
45
+ creds.is_a?(Core::XdsChannelCredentials) ||
46
+ creds.is_a?(Symbol)
47
+ fail(TypeError, 'creds is not a ChannelCredentials, XdsChannelCredentials, or Symbol')
46
48
  end
47
49
  Core::Channel.new(host, channel_args, creds)
48
50
  end
@@ -14,5 +14,5 @@
14
14
 
15
15
  # GRPC contains the General RPC module.
16
16
  module GRPC
17
- VERSION = '1.33.0.pre1'
17
+ VERSION = '1.37.0.pre1'
18
18
  end
@@ -76,6 +76,34 @@ Google::Protobuf::DescriptorPool.generated_pool.build do
76
76
  add_message "grpc.testing.LoadBalancerStatsResponse.RpcsByPeer" do
77
77
  map :rpcs_by_peer, :string, :int32, 1
78
78
  end
79
+ add_message "grpc.testing.LoadBalancerAccumulatedStatsRequest" do
80
+ end
81
+ add_message "grpc.testing.LoadBalancerAccumulatedStatsResponse" do
82
+ map :num_rpcs_started_by_method, :string, :int32, 1
83
+ map :num_rpcs_succeeded_by_method, :string, :int32, 2
84
+ map :num_rpcs_failed_by_method, :string, :int32, 3
85
+ map :stats_per_method, :string, :message, 4, "grpc.testing.LoadBalancerAccumulatedStatsResponse.MethodStats"
86
+ end
87
+ add_message "grpc.testing.LoadBalancerAccumulatedStatsResponse.MethodStats" do
88
+ optional :rpcs_started, :int32, 1
89
+ map :result, :int32, :int32, 2
90
+ end
91
+ add_message "grpc.testing.ClientConfigureRequest" do
92
+ repeated :types, :enum, 1, "grpc.testing.ClientConfigureRequest.RpcType"
93
+ repeated :metadata, :message, 2, "grpc.testing.ClientConfigureRequest.Metadata"
94
+ optional :timeout_sec, :int32, 3
95
+ end
96
+ add_message "grpc.testing.ClientConfigureRequest.Metadata" do
97
+ optional :type, :enum, 1, "grpc.testing.ClientConfigureRequest.RpcType"
98
+ optional :key, :string, 2
99
+ optional :value, :string, 3
100
+ end
101
+ add_enum "grpc.testing.ClientConfigureRequest.RpcType" do
102
+ value :EMPTY_CALL, 0
103
+ value :UNARY_CALL, 1
104
+ end
105
+ add_message "grpc.testing.ClientConfigureResponse" do
106
+ end
79
107
  add_enum "grpc.testing.PayloadType" do
80
108
  value :COMPRESSABLE, 0
81
109
  end
@@ -104,6 +132,13 @@ module Grpc
104
132
  LoadBalancerStatsRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.LoadBalancerStatsRequest").msgclass
105
133
  LoadBalancerStatsResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.LoadBalancerStatsResponse").msgclass
106
134
  LoadBalancerStatsResponse::RpcsByPeer = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.LoadBalancerStatsResponse.RpcsByPeer").msgclass
135
+ LoadBalancerAccumulatedStatsRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.LoadBalancerAccumulatedStatsRequest").msgclass
136
+ LoadBalancerAccumulatedStatsResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.LoadBalancerAccumulatedStatsResponse").msgclass
137
+ LoadBalancerAccumulatedStatsResponse::MethodStats = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.LoadBalancerAccumulatedStatsResponse.MethodStats").msgclass
138
+ ClientConfigureRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ClientConfigureRequest").msgclass
139
+ ClientConfigureRequest::Metadata = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ClientConfigureRequest.Metadata").msgclass
140
+ ClientConfigureRequest::RpcType = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ClientConfigureRequest.RpcType").enummodule
141
+ ClientConfigureResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ClientConfigureResponse").msgclass
107
142
  PayloadType = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.PayloadType").enummodule
108
143
  GrpclbRouteType = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.GrpclbRouteType").enummodule
109
144
  end
@@ -110,6 +110,8 @@ module Grpc
110
110
 
111
111
  # Gets the backend distribution for RPCs sent by a test client.
112
112
  rpc :GetClientStats, ::Grpc::Testing::LoadBalancerStatsRequest, ::Grpc::Testing::LoadBalancerStatsResponse
113
+ # Gets the accumulated stats for RPCs sent by a test client.
114
+ rpc :GetClientAccumulatedStats, ::Grpc::Testing::LoadBalancerAccumulatedStatsRequest, ::Grpc::Testing::LoadBalancerAccumulatedStatsResponse
113
115
  end
114
116
 
115
117
  Stub = Service.rpc_stub_class
@@ -128,6 +130,22 @@ module Grpc
128
130
  rpc :SetNotServing, ::Grpc::Testing::Empty, ::Grpc::Testing::Empty
129
131
  end
130
132
 
133
+ Stub = Service.rpc_stub_class
134
+ end
135
+ module XdsUpdateClientConfigureService
136
+ # A service to dynamically update the configuration of an xDS test client.
137
+ class Service
138
+
139
+ include GRPC::GenericService
140
+
141
+ self.marshal_class_method = :encode
142
+ self.unmarshal_class_method = :decode
143
+ self.service_name = 'grpc.testing.XdsUpdateClientConfigureService'
144
+
145
+ # Update the tes client's configuration.
146
+ rpc :Configure, ::Grpc::Testing::ClientConfigureRequest, ::Grpc::Testing::ClientConfigureResponse
147
+ end
148
+
131
149
  Stub = Service.rpc_stub_class
132
150
  end
133
151
  end
@@ -39,11 +39,35 @@ require_relative '../src/proto/grpc/testing/empty_pb'
39
39
  require_relative '../src/proto/grpc/testing/messages_pb'
40
40
  require_relative '../src/proto/grpc/testing/test_services_pb'
41
41
 
42
+ class RpcConfig
43
+ attr_reader :rpcs_to_send, :metadata_to_send, :timeout_sec
44
+ def init(rpcs_to_send, metadata_to_send, timeout_sec = 0)
45
+ @rpcs_to_send = rpcs_to_send
46
+ @metadata_to_send = metadata_to_send
47
+ @timeout_sec = timeout_sec
48
+ end
49
+ end
50
+
51
+ # Some global constant mappings
52
+ $RPC_MAP = {
53
+ 'UnaryCall' => :UNARY_CALL,
54
+ 'EmptyCall' => :EMPTY_CALL,
55
+ }
56
+
42
57
  # Some global variables to be shared by server and client
43
58
  $watchers = Array.new
44
59
  $watchers_mutex = Mutex.new
45
60
  $watchers_cv = ConditionVariable.new
46
61
  $shutdown = false
62
+ # These can be configured by the test runner dynamically
63
+ $rpc_config = RpcConfig.new
64
+ $rpc_config.init([:UNARY_CALL], {})
65
+ # These stats are shared across threads
66
+ $accumulated_stats_mu = Mutex.new
67
+ $num_rpcs_started_by_method = {}
68
+ $num_rpcs_succeeded_by_method = {}
69
+ $num_rpcs_failed_by_method = {}
70
+ $accumulated_method_stats = {}
47
71
 
48
72
  # RubyLogger defines a logger for gRPC based on the standard ruby logger.
49
73
  module RubyLogger
@@ -71,6 +95,41 @@ def create_stub(opts)
71
95
  )
72
96
  end
73
97
 
98
+ class StatsPerMethod
99
+ attr_reader :rpcs_started, :result
100
+ def initialize()
101
+ @rpcs_started = 0
102
+ @result = Hash.new(0)
103
+ end
104
+ def increment_rpcs_started()
105
+ @rpcs_started += 1
106
+ end
107
+ def add_result(status_code)
108
+ @result[status_code] += 1
109
+ end
110
+ end
111
+
112
+ class ConfigureTarget < Grpc::Testing::XdsUpdateClientConfigureService::Service
113
+ include Grpc::Testing
114
+
115
+ def configure(req, _call)
116
+ metadata_to_send = {}
117
+ req.metadata.each do |m|
118
+ rpc = m.type
119
+ if !metadata_to_send.key?(rpc)
120
+ metadata_to_send[rpc] = {}
121
+ end
122
+ metadata_key = m.key
123
+ metadata_value = m.value
124
+ metadata_to_send[rpc][metadata_key] = metadata_value
125
+ end
126
+ new_rpc_config = RpcConfig.new
127
+ new_rpc_config.init(req['types'], metadata_to_send, req['timeout_sec'])
128
+ $rpc_config = new_rpc_config
129
+ ClientConfigureResponse.new()
130
+ end
131
+ end
132
+
74
133
  # This implements LoadBalancerStatsService required by the test runner
75
134
  class TestTarget < Grpc::Testing::LoadBalancerStatsService::Service
76
135
  include Grpc::Testing
@@ -107,73 +166,139 @@ class TestTarget < Grpc::Testing::LoadBalancerStatsService::Service
107
166
  rpcs_by_method: rpcs_by_method,
108
167
  rpcs_by_peer: watcher['rpcs_by_peer'],
109
168
  num_failures: watcher['no_remote_peer'] + watcher['rpcs_needed']
110
- );
169
+ )
170
+ end
171
+
172
+ def get_client_accumulated_stats(req, _call)
173
+ $accumulated_stats_mu.synchronize do
174
+ all_stats_per_method = $accumulated_method_stats.map { |rpc, stats_per_method|
175
+ [rpc,
176
+ LoadBalancerAccumulatedStatsResponse::MethodStats.new(
177
+ rpcs_started: stats_per_method.rpcs_started,
178
+ result: stats_per_method.result
179
+ )]
180
+ }.to_h
181
+ LoadBalancerAccumulatedStatsResponse.new(
182
+ num_rpcs_started_by_method: $num_rpcs_started_by_method,
183
+ num_rpcs_succeeded_by_method: $num_rpcs_succeeded_by_method,
184
+ num_rpcs_failed_by_method: $num_rpcs_failed_by_method,
185
+ stats_per_method: all_stats_per_method,
186
+ )
187
+ end
111
188
  end
112
189
  end
113
190
 
114
191
  # execute 1 RPC and return remote hostname
115
- def execute_rpc(op, fail_on_failed_rpcs)
192
+ def execute_rpc(op, fail_on_failed_rpcs, rpc_stats_key)
116
193
  remote_peer = ""
194
+ status_code = 0
117
195
  begin
118
196
  op.execute
119
197
  if op.metadata.key?('hostname')
120
198
  remote_peer = op.metadata['hostname']
121
199
  end
122
200
  rescue GRPC::BadStatus => e
123
- GRPC.logger.info("ruby xds: rpc failed:|#{e.message}|, " \
124
- "this may or may not be expected")
125
201
  if fail_on_failed_rpcs
126
202
  raise e
127
203
  end
204
+ status_code = e.code
205
+ end
206
+ $accumulated_stats_mu.synchronize do
207
+ $accumulated_method_stats[rpc_stats_key].add_result(status_code)
208
+ if remote_peer.empty?
209
+ $num_rpcs_failed_by_method[rpc_stats_key] += 1
210
+ else
211
+ $num_rpcs_succeeded_by_method[rpc_stats_key] += 1
212
+ end
128
213
  end
129
214
  remote_peer
130
215
  end
131
216
 
217
+ def execute_rpc_in_thread(op, rpc_stats_key)
218
+ Thread.new {
219
+ begin
220
+ op.execute
221
+ # The following should _not_ happen with the current spec
222
+ # because we are only executing RPCs in a thread if we expect it
223
+ # to be kept open, or deadline_exceeded, or dropped by the load
224
+ # balancing policy. These RPCs should not complete successfully.
225
+ # Doing this for consistency
226
+ $accumulated_stats_mu.synchronize do
227
+ $num_rpcs_succeeded_by_method[rpc_stats_key] += 1
228
+ $accumulated_method_stats[rpc_stats_key].add_result(0)
229
+ end
230
+ rescue GRPC::BadStatus => e
231
+ # Normal execution arrives here,
232
+ # either because of deadline_exceeded or "call dropped by load
233
+ # balancing policy"
234
+ $accumulated_stats_mu.synchronize do
235
+ $num_rpcs_failed_by_method[rpc_stats_key] += 1
236
+ $accumulated_method_stats[rpc_stats_key].add_result(e.code)
237
+ end
238
+ end
239
+ }
240
+ end
241
+
132
242
  # send 1 rpc every 1/qps second
133
- def run_test_loop(stub, target_seconds_between_rpcs, fail_on_failed_rpcs,
134
- rpcs_to_send, metadata_to_send)
243
+ def run_test_loop(stub, target_seconds_between_rpcs, fail_on_failed_rpcs)
135
244
  include Grpc::Testing
136
245
  simple_req = SimpleRequest.new()
137
246
  empty_req = Empty.new()
138
247
  target_next_start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
248
+ # Some RPCs are meant to be "kept open". Since Ruby does not have an
249
+ # async API, we are executing those RPCs in a thread so that they don't
250
+ # block.
251
+ keep_open_threads = Array.new
139
252
  while !$shutdown
140
253
  now = Process.clock_gettime(Process::CLOCK_MONOTONIC)
141
254
  sleep_seconds = target_next_start - now
142
255
  if sleep_seconds < 0
143
256
  target_next_start = now + target_seconds_between_rpcs
144
- GRPC.logger.info(
145
- "ruby xds: warning, rpc takes too long to finish. " \
146
- "Deficit = %.1fms. " \
147
- "If you consistently see this, the qps is too high." \
148
- % [(sleep_seconds * 1000).abs().round(1)])
149
257
  else
150
258
  target_next_start += target_seconds_between_rpcs
151
259
  sleep(sleep_seconds)
152
260
  end
153
- deadline = GRPC::Core::TimeConsts::from_relative_time(30) # 30 seconds
261
+ deadline_sec = $rpc_config.timeout_sec > 0 ? $rpc_config.timeout_sec : 30
262
+ deadline = GRPC::Core::TimeConsts::from_relative_time(deadline_sec)
154
263
  results = {}
155
- rpcs_to_send.each do |rpc|
156
- metadata = metadata_to_send.key?(rpc) ? metadata_to_send[rpc] : {}
157
- if rpc == 'UnaryCall'
264
+ $rpc_config.rpcs_to_send.each do |rpc|
265
+ # rpc is in the form of :UNARY_CALL or :EMPTY_CALL here
266
+ metadata = $rpc_config.metadata_to_send.key?(rpc) ?
267
+ $rpc_config.metadata_to_send[rpc] : {}
268
+ $accumulated_stats_mu.synchronize do
269
+ $num_rpcs_started_by_method[rpc.to_s] += 1
270
+ $accumulated_method_stats[rpc.to_s].increment_rpcs_started()
271
+ end
272
+ if rpc == :UNARY_CALL
158
273
  op = stub.unary_call(simple_req,
159
274
  metadata: metadata,
160
275
  deadline: deadline,
161
276
  return_op: true)
162
- elsif rpc == 'EmptyCall'
277
+ elsif rpc == :EMPTY_CALL
163
278
  op = stub.empty_call(empty_req,
164
279
  metadata: metadata,
165
280
  deadline: deadline,
166
281
  return_op: true)
167
282
  else
168
- raise "Unsupported rpc %s" % [rpc]
283
+ raise "Unsupported rpc #{rpc}"
284
+ end
285
+ rpc_stats_key = rpc.to_s
286
+ if metadata.key?('rpc-behavior') and
287
+ ((metadata['rpc-behavior'] == 'keep-open') or
288
+ (metadata['rpc-behavior'].start_with?('sleep')))
289
+ keep_open_threads << execute_rpc_in_thread(op, rpc_stats_key)
290
+ else
291
+ results[rpc] = execute_rpc(op, fail_on_failed_rpcs, rpc_stats_key)
169
292
  end
170
- results[rpc] = execute_rpc(op, fail_on_failed_rpcs)
171
293
  end
172
294
  $watchers_mutex.synchronize do
173
295
  $watchers.each do |watcher|
174
296
  # this is counted once when each group of all rpcs_to_send were done
175
297
  watcher['rpcs_needed'] -= 1
176
298
  results.each do |rpc_name, remote_peer|
299
+ # These stats expect rpc_name to be in the form of
300
+ # UnaryCall or EmptyCall, not the underscore-case all-caps form
301
+ rpc_name = $RPC_MAP.invert()[rpc_name]
177
302
  if remote_peer.strip.empty?
178
303
  # error is counted per individual RPC
179
304
  watcher['no_remote_peer'] += 1
@@ -191,6 +316,7 @@ def run_test_loop(stub, target_seconds_between_rpcs, fail_on_failed_rpcs,
191
316
  $watchers_cv.broadcast
192
317
  end
193
318
  end
319
+ keep_open_threads.each { |thd| thd.join }
194
320
  end
195
321
 
196
322
  # Args is used to hold the command line info.
@@ -242,18 +368,23 @@ def main
242
368
  s = GRPC::RpcServer.new
243
369
  s.add_http2_port(host, :this_port_is_insecure)
244
370
  s.handle(TestTarget)
371
+ s.handle(ConfigureTarget)
245
372
  server_thread = Thread.new {
246
373
  # run the server until the main test runner terminates this process
247
374
  s.run_till_terminated_or_interrupted(['TERM'])
248
375
  }
249
376
 
250
- # The client just sends unary rpcs continuously in a regular interval
377
+ # Initialize stats
378
+ $RPC_MAP.values.each do |rpc|
379
+ $num_rpcs_started_by_method[rpc.to_s] = 0
380
+ $num_rpcs_succeeded_by_method[rpc.to_s] = 0
381
+ $num_rpcs_failed_by_method[rpc.to_s] = 0
382
+ $accumulated_method_stats[rpc.to_s] = StatsPerMethod.new
383
+ end
384
+
385
+ # The client just sends rpcs continuously in a regular interval
251
386
  stub = create_stub(opts)
252
387
  target_seconds_between_rpcs = (1.0 / opts['qps'].to_f)
253
- rpcs_to_send = []
254
- if opts['rpc']
255
- rpcs_to_send = opts['rpc'].split(',')
256
- end
257
388
  # Convert 'metadata' input in the form of
258
389
  # rpc1:k1:v1,rpc2:k2:v2,rpc1:k3:v3
259
390
  # into
@@ -266,11 +397,13 @@ def main
266
397
  # 'k2' => 'v2'
267
398
  # },
268
399
  # }
400
+ rpcs_to_send = []
269
401
  metadata_to_send = {}
270
402
  if opts['metadata']
271
403
  metadata_entries = opts['metadata'].split(',')
272
404
  metadata_entries.each do |e|
273
405
  (rpc_name, metadata_key, metadata_value) = e.split(':')
406
+ rpc_name = $RPC_MAP[rpc_name]
274
407
  # initialize if we haven't seen this rpc_name yet
275
408
  if !metadata_to_send.key?(rpc_name)
276
409
  metadata_to_send[rpc_name] = {}
@@ -278,12 +411,20 @@ def main
278
411
  metadata_to_send[rpc_name][metadata_key] = metadata_value
279
412
  end
280
413
  end
414
+ if opts['rpc']
415
+ rpcs_to_send = opts['rpc'].split(',')
416
+ end
417
+ if rpcs_to_send.size > 0
418
+ rpcs_to_send.map! { |rpc| $RPC_MAP[rpc] }
419
+ new_rpc_config = RpcConfig.new
420
+ new_rpc_config.init(rpcs_to_send, metadata_to_send)
421
+ $rpc_config = new_rpc_config
422
+ end
281
423
  client_threads = Array.new
282
424
  opts['num_channels'].times {
283
425
  client_threads << Thread.new {
284
426
  run_test_loop(stub, target_seconds_between_rpcs,
285
- opts['fail_on_failed_rpcs'],
286
- rpcs_to_send, metadata_to_send)
427
+ opts['fail_on_failed_rpcs'])
287
428
  }
288
429
  }
289
430