grpc 1.42.0.pre1-arm64-darwin → 1.58.3-arm64-darwin

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/grpc_c.64-ucrt.ruby +0 -0
  3. data/src/ruby/bin/math_pb.rb +24 -18
  4. data/src/ruby/ext/grpc/ext-export-truffleruby-with-ruby-abi-version.clang +2 -0
  5. data/src/ruby/ext/grpc/ext-export-truffleruby-with-ruby-abi-version.gcc +7 -0
  6. data/src/ruby/ext/grpc/ext-export-with-ruby-abi-version.clang +2 -0
  7. data/src/ruby/ext/grpc/ext-export-with-ruby-abi-version.gcc +7 -0
  8. data/src/ruby/ext/grpc/ext-export.gcc +1 -1
  9. data/src/ruby/ext/grpc/extconf.rb +117 -32
  10. data/src/ruby/ext/grpc/rb_call.c +63 -39
  11. data/src/ruby/ext/grpc/rb_call_credentials.c +0 -1
  12. data/src/ruby/ext/grpc/rb_channel.c +113 -84
  13. data/src/ruby/ext/grpc/rb_channel.h +1 -0
  14. data/src/ruby/ext/grpc/rb_channel_args.c +17 -2
  15. data/src/ruby/ext/grpc/rb_channel_args.h +4 -0
  16. data/src/ruby/ext/grpc/rb_channel_credentials.c +0 -1
  17. data/src/ruby/ext/grpc/rb_compression_options.c +1 -2
  18. data/src/ruby/ext/grpc/rb_event_thread.c +22 -6
  19. data/src/ruby/ext/grpc/rb_event_thread.h +1 -0
  20. data/src/ruby/ext/grpc/rb_grpc.c +193 -30
  21. data/src/ruby/ext/grpc/rb_grpc.h +8 -2
  22. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +66 -72
  23. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +102 -111
  24. data/src/ruby/ext/grpc/rb_loader.c +6 -2
  25. data/src/ruby/ext/grpc/rb_server.c +69 -49
  26. data/src/ruby/ext/grpc/rb_server_credentials.c +0 -1
  27. data/src/ruby/ext/grpc/rb_xds_channel_credentials.c +0 -1
  28. data/src/ruby/ext/grpc/rb_xds_server_credentials.c +0 -1
  29. data/src/ruby/lib/grpc/2.6/grpc_c.bundle +0 -0
  30. data/src/ruby/lib/grpc/2.7/grpc_c.bundle +0 -0
  31. data/src/ruby/lib/grpc/3.0/grpc_c.bundle +0 -0
  32. data/src/ruby/lib/grpc/3.1/grpc_c.bundle +0 -0
  33. data/src/ruby/lib/grpc/3.2/grpc_c.bundle +0 -0
  34. data/src/ruby/lib/grpc/errors.rb +1 -1
  35. data/src/ruby/lib/grpc/generic/active_call.rb +16 -15
  36. data/src/ruby/lib/grpc/generic/bidi_call.rb +4 -0
  37. data/src/ruby/lib/grpc/grpc.rb +1 -1
  38. data/src/ruby/lib/grpc/version.rb +1 -1
  39. data/src/ruby/pb/generate_proto_ruby.sh +1 -6
  40. data/src/ruby/pb/grpc/health/v1/health_pb.rb +24 -13
  41. data/src/ruby/pb/src/proto/grpc/testing/empty_pb.rb +24 -3
  42. data/src/ruby/pb/src/proto/grpc/testing/messages_pb.rb +26 -108
  43. data/src/ruby/pb/src/proto/grpc/testing/test_pb.rb +27 -3
  44. data/src/ruby/pb/test/client.rb +16 -0
  45. data/src/ruby/spec/channel_spec.rb +5 -43
  46. data/src/ruby/spec/client_server_spec.rb +20 -8
  47. data/src/ruby/spec/generic/active_call_spec.rb +12 -3
  48. data/src/ruby/spec/generic/client_stub_spec.rb +23 -23
  49. data/src/ruby/spec/generic/rpc_server_spec.rb +3 -3
  50. data/src/ruby/spec/generic/server_interceptors_spec.rb +1 -1
  51. data/src/ruby/spec/user_agent_spec.rb +1 -1
  52. metadata +61 -59
  53. data/src/ruby/lib/grpc/2.4/grpc_c.bundle +0 -0
  54. data/src/ruby/lib/grpc/2.5/grpc_c.bundle +0 -0
  55. /data/{grpc_c.32.ruby → grpc_c.32-msvcrt.ruby} +0 -0
  56. /data/{grpc_c.64.ruby → grpc_c.64-msvcrt.ruby} +0 -0
@@ -139,7 +139,9 @@ module GRPC
139
139
  end
140
140
 
141
141
  # set_output_stream_done is relevant on client-side
142
+ # rubocop:disable Metrics/PerceivedComplexity
142
143
  def write_loop(requests, is_client: true, set_output_stream_done: nil)
144
+ GRPC::Core.fork_unsafe_begin
143
145
  GRPC.logger.debug('bidi-write-loop: starting')
144
146
  count = 0
145
147
  requests.each do |req|
@@ -180,8 +182,10 @@ module GRPC
180
182
  raise e
181
183
  end
182
184
  ensure
185
+ GRPC::Core.fork_unsafe_end
183
186
  set_output_stream_done.call if is_client
184
187
  end
188
+ # rubocop:enable Metrics/PerceivedComplexity
185
189
 
186
190
  # Provides an enumerator that yields results of remote reads
187
191
  def read_loop(set_input_stream_done, is_client: true)
@@ -16,7 +16,7 @@ begin
16
16
  ruby_version_dirname = /(\d+\.\d+)/.match(RUBY_VERSION).to_s
17
17
  distrib_lib_dir = File.expand_path(ruby_version_dirname,
18
18
  File.dirname(__FILE__))
19
- if File.directory?(distrib_lib_dir)
19
+ if !Dir.glob("#{distrib_lib_dir}/grpc_c*").empty?
20
20
  require "#{distrib_lib_dir}/grpc_c"
21
21
  else
22
22
  require 'grpc/grpc_c'
@@ -14,5 +14,5 @@
14
14
 
15
15
  # GRPC contains the General RPC module.
16
16
  module GRPC
17
- VERSION = '1.42.0.pre1'
17
+ VERSION = '1.58.3'
18
18
  end
@@ -34,12 +34,7 @@ $PROTOC -I . \
34
34
  --plugin=$PLUGIN
35
35
 
36
36
  $PROTOC -I . \
37
- src/proto/grpc/core/stats.proto \
38
- --grpc_out=src/ruby/qps \
39
- --ruby_out=src/ruby/qps \
40
- --plugin=$PLUGIN
41
-
42
- $PROTOC -I . \
37
+ -I third_party/protobuf/src \
43
38
  src/proto/grpc/testing/{messages,payloads,stats,benchmark_service,report_qps_scenario_service,worker_service,control}.proto \
44
39
  --grpc_out=src/ruby/qps \
45
40
  --ruby_out=src/ruby/qps \
@@ -1,23 +1,34 @@
1
+ # frozen_string_literal: true
1
2
  # Generated by the protocol buffer compiler. DO NOT EDIT!
2
3
  # source: grpc/health/v1/health.proto
3
4
 
4
5
  require 'google/protobuf'
5
6
 
6
- Google::Protobuf::DescriptorPool.generated_pool.build do
7
- add_file("grpc/health/v1/health.proto", :syntax => :proto3) do
8
- add_message "grpc.health.v1.HealthCheckRequest" do
9
- optional :service, :string, 1
10
- end
11
- add_message "grpc.health.v1.HealthCheckResponse" do
12
- optional :status, :enum, 1, "grpc.health.v1.HealthCheckResponse.ServingStatus"
13
- end
14
- add_enum "grpc.health.v1.HealthCheckResponse.ServingStatus" do
15
- value :UNKNOWN, 0
16
- value :SERVING, 1
17
- value :NOT_SERVING, 2
18
- value :SERVICE_UNKNOWN, 3
7
+
8
+ descriptor_data = "\n\x1bgrpc/health/v1/health.proto\x12\x0egrpc.health.v1\"%\n\x12HealthCheckRequest\x12\x0f\n\x07service\x18\x01 \x01(\t\"\xa9\x01\n\x13HealthCheckResponse\x12\x41\n\x06status\x18\x01 \x01(\x0e\x32\x31.grpc.health.v1.HealthCheckResponse.ServingStatus\"O\n\rServingStatus\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x0b\n\x07SERVING\x10\x01\x12\x0f\n\x0bNOT_SERVING\x10\x02\x12\x13\n\x0fSERVICE_UNKNOWN\x10\x03\x32\xae\x01\n\x06Health\x12P\n\x05\x43heck\x12\".grpc.health.v1.HealthCheckRequest\x1a#.grpc.health.v1.HealthCheckResponse\x12R\n\x05Watch\x12\".grpc.health.v1.HealthCheckRequest\x1a#.grpc.health.v1.HealthCheckResponse0\x01\x42\x61\n\x11io.grpc.health.v1B\x0bHealthProtoP\x01Z,google.golang.org/grpc/health/grpc_health_v1\xaa\x02\x0eGrpc.Health.V1b\x06proto3"
9
+
10
+ pool = Google::Protobuf::DescriptorPool.generated_pool
11
+
12
+ begin
13
+ pool.add_serialized_file(descriptor_data)
14
+ rescue TypeError => e
15
+ # Compatibility code: will be removed in the next major version.
16
+ require 'google/protobuf/descriptor_pb'
17
+ parsed = Google::Protobuf::FileDescriptorProto.decode(descriptor_data)
18
+ parsed.clear_dependency
19
+ serialized = parsed.class.encode(parsed)
20
+ file = pool.add_serialized_file(serialized)
21
+ warn "Warning: Protobuf detected an import path issue while loading generated file #{__FILE__}"
22
+ imports = [
23
+ ]
24
+ imports.each do |type_name, expected_filename|
25
+ import_file = pool.lookup(type_name).file_descriptor
26
+ if import_file.name != expected_filename
27
+ warn "- #{file.name} imports #{expected_filename}, but that import was loaded as #{import_file.name}"
19
28
  end
20
29
  end
30
+ warn "Each proto file must use a consistent fully-qualified name."
31
+ warn "This will become an error in the next major version."
21
32
  end
22
33
 
23
34
  module Grpc
@@ -1,13 +1,34 @@
1
+ # frozen_string_literal: true
1
2
  # Generated by the protocol buffer compiler. DO NOT EDIT!
2
3
  # source: src/proto/grpc/testing/empty.proto
3
4
 
4
5
  require 'google/protobuf'
5
6
 
6
- Google::Protobuf::DescriptorPool.generated_pool.build do
7
- add_file("src/proto/grpc/testing/empty.proto", :syntax => :proto3) do
8
- add_message "grpc.testing.Empty" do
7
+
8
+ descriptor_data = "\n\"src/proto/grpc/testing/empty.proto\x12\x0cgrpc.testing\"\x07\n\x05\x45mptyb\x06proto3"
9
+
10
+ pool = Google::Protobuf::DescriptorPool.generated_pool
11
+
12
+ begin
13
+ pool.add_serialized_file(descriptor_data)
14
+ rescue TypeError => e
15
+ # Compatibility code: will be removed in the next major version.
16
+ require 'google/protobuf/descriptor_pb'
17
+ parsed = Google::Protobuf::FileDescriptorProto.decode(descriptor_data)
18
+ parsed.clear_dependency
19
+ serialized = parsed.class.encode(parsed)
20
+ file = pool.add_serialized_file(serialized)
21
+ warn "Warning: Protobuf detected an import path issue while loading generated file #{__FILE__}"
22
+ imports = [
23
+ ]
24
+ imports.each do |type_name, expected_filename|
25
+ import_file = pool.lookup(type_name).file_descriptor
26
+ if import_file.name != expected_filename
27
+ warn "- #{file.name} imports #{expected_filename}, but that import was loaded as #{import_file.name}"
9
28
  end
10
29
  end
30
+ warn "Each proto file must use a consistent fully-qualified name."
31
+ warn "This will become an error in the next major version."
11
32
  end
12
33
 
13
34
  module Grpc
@@ -1,118 +1,34 @@
1
+ # frozen_string_literal: true
1
2
  # Generated by the protocol buffer compiler. DO NOT EDIT!
2
3
  # source: src/proto/grpc/testing/messages.proto
3
4
 
4
5
  require 'google/protobuf'
5
6
 
6
- Google::Protobuf::DescriptorPool.generated_pool.build do
7
- add_file("src/proto/grpc/testing/messages.proto", :syntax => :proto3) do
8
- add_message "grpc.testing.BoolValue" do
9
- optional :value, :bool, 1
10
- end
11
- add_message "grpc.testing.Payload" do
12
- optional :type, :enum, 1, "grpc.testing.PayloadType"
13
- optional :body, :bytes, 2
14
- end
15
- add_message "grpc.testing.EchoStatus" do
16
- optional :code, :int32, 1
17
- optional :message, :string, 2
18
- end
19
- add_message "grpc.testing.SimpleRequest" do
20
- optional :response_type, :enum, 1, "grpc.testing.PayloadType"
21
- optional :response_size, :int32, 2
22
- optional :payload, :message, 3, "grpc.testing.Payload"
23
- optional :fill_username, :bool, 4
24
- optional :fill_oauth_scope, :bool, 5
25
- optional :response_compressed, :message, 6, "grpc.testing.BoolValue"
26
- optional :response_status, :message, 7, "grpc.testing.EchoStatus"
27
- optional :expect_compressed, :message, 8, "grpc.testing.BoolValue"
28
- optional :fill_server_id, :bool, 9
29
- optional :fill_grpclb_route_type, :bool, 10
30
- end
31
- add_message "grpc.testing.SimpleResponse" do
32
- optional :payload, :message, 1, "grpc.testing.Payload"
33
- optional :username, :string, 2
34
- optional :oauth_scope, :string, 3
35
- optional :server_id, :string, 4
36
- optional :grpclb_route_type, :enum, 5, "grpc.testing.GrpclbRouteType"
37
- optional :hostname, :string, 6
38
- end
39
- add_message "grpc.testing.StreamingInputCallRequest" do
40
- optional :payload, :message, 1, "grpc.testing.Payload"
41
- optional :expect_compressed, :message, 2, "grpc.testing.BoolValue"
42
- end
43
- add_message "grpc.testing.StreamingInputCallResponse" do
44
- optional :aggregated_payload_size, :int32, 1
45
- end
46
- add_message "grpc.testing.ResponseParameters" do
47
- optional :size, :int32, 1
48
- optional :interval_us, :int32, 2
49
- optional :compressed, :message, 3, "grpc.testing.BoolValue"
50
- end
51
- add_message "grpc.testing.StreamingOutputCallRequest" do
52
- optional :response_type, :enum, 1, "grpc.testing.PayloadType"
53
- repeated :response_parameters, :message, 2, "grpc.testing.ResponseParameters"
54
- optional :payload, :message, 3, "grpc.testing.Payload"
55
- optional :response_status, :message, 7, "grpc.testing.EchoStatus"
56
- end
57
- add_message "grpc.testing.StreamingOutputCallResponse" do
58
- optional :payload, :message, 1, "grpc.testing.Payload"
59
- end
60
- add_message "grpc.testing.ReconnectParams" do
61
- optional :max_reconnect_backoff_ms, :int32, 1
62
- end
63
- add_message "grpc.testing.ReconnectInfo" do
64
- optional :passed, :bool, 1
65
- repeated :backoff_ms, :int32, 2
66
- end
67
- add_message "grpc.testing.LoadBalancerStatsRequest" do
68
- optional :num_rpcs, :int32, 1
69
- optional :timeout_sec, :int32, 2
70
- end
71
- add_message "grpc.testing.LoadBalancerStatsResponse" do
72
- map :rpcs_by_peer, :string, :int32, 1
73
- optional :num_failures, :int32, 2
74
- map :rpcs_by_method, :string, :message, 3, "grpc.testing.LoadBalancerStatsResponse.RpcsByPeer"
75
- end
76
- add_message "grpc.testing.LoadBalancerStatsResponse.RpcsByPeer" do
77
- map :rpcs_by_peer, :string, :int32, 1
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
107
- add_enum "grpc.testing.PayloadType" do
108
- value :COMPRESSABLE, 0
109
- end
110
- add_enum "grpc.testing.GrpclbRouteType" do
111
- value :GRPCLB_ROUTE_TYPE_UNKNOWN, 0
112
- value :GRPCLB_ROUTE_TYPE_FALLBACK, 1
113
- value :GRPCLB_ROUTE_TYPE_BACKEND, 2
7
+
8
+ descriptor_data = "\n%src/proto/grpc/testing/messages.proto\x12\x0cgrpc.testing\"\x1a\n\tBoolValue\x12\r\n\x05value\x18\x01 \x01(\x08\"@\n\x07Payload\x12\'\n\x04type\x18\x01 \x01(\x0e\x32\x19.grpc.testing.PayloadType\x12\x0c\n\x04\x62ody\x18\x02 \x01(\x0c\"+\n\nEchoStatus\x12\x0c\n\x04\x63ode\x18\x01 \x01(\x05\x12\x0f\n\x07message\x18\x02 \x01(\t\"\xfa\x03\n\rSimpleRequest\x12\x30\n\rresponse_type\x18\x01 \x01(\x0e\x32\x19.grpc.testing.PayloadType\x12\x15\n\rresponse_size\x18\x02 \x01(\x05\x12&\n\x07payload\x18\x03 \x01(\x0b\x32\x15.grpc.testing.Payload\x12\x15\n\rfill_username\x18\x04 \x01(\x08\x12\x18\n\x10\x66ill_oauth_scope\x18\x05 \x01(\x08\x12\x34\n\x13response_compressed\x18\x06 \x01(\x0b\x32\x17.grpc.testing.BoolValue\x12\x31\n\x0fresponse_status\x18\x07 \x01(\x0b\x32\x18.grpc.testing.EchoStatus\x12\x32\n\x11\x65xpect_compressed\x18\x08 \x01(\x0b\x32\x17.grpc.testing.BoolValue\x12\x16\n\x0e\x66ill_server_id\x18\t \x01(\x08\x12\x1e\n\x16\x66ill_grpclb_route_type\x18\n \x01(\x08\x12;\n\x15orca_per_query_report\x18\x0b \x01(\x0b\x32\x1c.grpc.testing.TestOrcaReport\x12\x35\n\x0forca_oob_report\x18\x0c \x01(\x0b\x32\x1c.grpc.testing.TestOrcaReport\"\xbe\x01\n\x0eSimpleResponse\x12&\n\x07payload\x18\x01 \x01(\x0b\x32\x15.grpc.testing.Payload\x12\x10\n\x08username\x18\x02 \x01(\t\x12\x13\n\x0boauth_scope\x18\x03 \x01(\t\x12\x11\n\tserver_id\x18\x04 \x01(\t\x12\x38\n\x11grpclb_route_type\x18\x05 \x01(\x0e\x32\x1d.grpc.testing.GrpclbRouteType\x12\x10\n\x08hostname\x18\x06 \x01(\t\"w\n\x19StreamingInputCallRequest\x12&\n\x07payload\x18\x01 \x01(\x0b\x32\x15.grpc.testing.Payload\x12\x32\n\x11\x65xpect_compressed\x18\x02 \x01(\x0b\x32\x17.grpc.testing.BoolValue\"=\n\x1aStreamingInputCallResponse\x12\x1f\n\x17\x61ggregated_payload_size\x18\x01 \x01(\x05\"d\n\x12ResponseParameters\x12\x0c\n\x04size\x18\x01 \x01(\x05\x12\x13\n\x0binterval_us\x18\x02 \x01(\x05\x12+\n\ncompressed\x18\x03 \x01(\x0b\x32\x17.grpc.testing.BoolValue\"\x9f\x02\n\x1aStreamingOutputCallRequest\x12\x30\n\rresponse_type\x18\x01 \x01(\x0e\x32\x19.grpc.testing.PayloadType\x12=\n\x13response_parameters\x18\x02 \x03(\x0b\x32 .grpc.testing.ResponseParameters\x12&\n\x07payload\x18\x03 \x01(\x0b\x32\x15.grpc.testing.Payload\x12\x31\n\x0fresponse_status\x18\x07 \x01(\x0b\x32\x18.grpc.testing.EchoStatus\x12\x35\n\x0forca_oob_report\x18\x08 \x01(\x0b\x32\x1c.grpc.testing.TestOrcaReport\"E\n\x1bStreamingOutputCallResponse\x12&\n\x07payload\x18\x01 \x01(\x0b\x32\x15.grpc.testing.Payload\"3\n\x0fReconnectParams\x12 \n\x18max_reconnect_backoff_ms\x18\x01 \x01(\x05\"3\n\rReconnectInfo\x12\x0e\n\x06passed\x18\x01 \x01(\x08\x12\x12\n\nbackoff_ms\x18\x02 \x03(\x05\"A\n\x18LoadBalancerStatsRequest\x12\x10\n\x08num_rpcs\x18\x01 \x01(\x05\x12\x13\n\x0btimeout_sec\x18\x02 \x01(\x05\"\x8b\x04\n\x19LoadBalancerStatsResponse\x12M\n\x0crpcs_by_peer\x18\x01 \x03(\x0b\x32\x37.grpc.testing.LoadBalancerStatsResponse.RpcsByPeerEntry\x12\x14\n\x0cnum_failures\x18\x02 \x01(\x05\x12Q\n\x0erpcs_by_method\x18\x03 \x03(\x0b\x32\x39.grpc.testing.LoadBalancerStatsResponse.RpcsByMethodEntry\x1a\x99\x01\n\nRpcsByPeer\x12X\n\x0crpcs_by_peer\x18\x01 \x03(\x0b\x32\x42.grpc.testing.LoadBalancerStatsResponse.RpcsByPeer.RpcsByPeerEntry\x1a\x31\n\x0fRpcsByPeerEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\x1a\x31\n\x0fRpcsByPeerEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\x1ag\n\x11RpcsByMethodEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x41\n\x05value\x18\x02 \x01(\x0b\x32\x32.grpc.testing.LoadBalancerStatsResponse.RpcsByPeer:\x02\x38\x01\"%\n#LoadBalancerAccumulatedStatsRequest\"\xd8\x07\n$LoadBalancerAccumulatedStatsResponse\x12v\n\x1anum_rpcs_started_by_method\x18\x01 \x03(\x0b\x32N.grpc.testing.LoadBalancerAccumulatedStatsResponse.NumRpcsStartedByMethodEntryB\x02\x18\x01\x12z\n\x1cnum_rpcs_succeeded_by_method\x18\x02 \x03(\x0b\x32P.grpc.testing.LoadBalancerAccumulatedStatsResponse.NumRpcsSucceededByMethodEntryB\x02\x18\x01\x12t\n\x19num_rpcs_failed_by_method\x18\x03 \x03(\x0b\x32M.grpc.testing.LoadBalancerAccumulatedStatsResponse.NumRpcsFailedByMethodEntryB\x02\x18\x01\x12`\n\x10stats_per_method\x18\x04 \x03(\x0b\x32\x46.grpc.testing.LoadBalancerAccumulatedStatsResponse.StatsPerMethodEntry\x1a=\n\x1bNumRpcsStartedByMethodEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\x1a?\n\x1dNumRpcsSucceededByMethodEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\x1a<\n\x1aNumRpcsFailedByMethodEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\x1a\xae\x01\n\x0bMethodStats\x12\x14\n\x0crpcs_started\x18\x01 \x01(\x05\x12Z\n\x06result\x18\x02 \x03(\x0b\x32J.grpc.testing.LoadBalancerAccumulatedStatsResponse.MethodStats.ResultEntry\x1a-\n\x0bResultEntry\x12\x0b\n\x03key\x18\x01 \x01(\x05\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\x1au\n\x13StatsPerMethodEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12M\n\x05value\x18\x02 \x01(\x0b\x32>.grpc.testing.LoadBalancerAccumulatedStatsResponse.MethodStats:\x02\x38\x01\"\xba\x02\n\x16\x43lientConfigureRequest\x12;\n\x05types\x18\x01 \x03(\x0e\x32,.grpc.testing.ClientConfigureRequest.RpcType\x12?\n\x08metadata\x18\x02 \x03(\x0b\x32-.grpc.testing.ClientConfigureRequest.Metadata\x12\x13\n\x0btimeout_sec\x18\x03 \x01(\x05\x1a\x62\n\x08Metadata\x12:\n\x04type\x18\x01 \x01(\x0e\x32,.grpc.testing.ClientConfigureRequest.RpcType\x12\x0b\n\x03key\x18\x02 \x01(\t\x12\r\n\x05value\x18\x03 \x01(\t\")\n\x07RpcType\x12\x0e\n\nEMPTY_CALL\x10\x00\x12\x0e\n\nUNARY_CALL\x10\x01\"\x19\n\x17\x43lientConfigureResponse\"\x19\n\nMemorySize\x12\x0b\n\x03rss\x18\x01 \x01(\x03\"\xb6\x02\n\x0eTestOrcaReport\x12\x17\n\x0f\x63pu_utilization\x18\x01 \x01(\x01\x12\x1a\n\x12memory_utilization\x18\x02 \x01(\x01\x12\x43\n\x0crequest_cost\x18\x03 \x03(\x0b\x32-.grpc.testing.TestOrcaReport.RequestCostEntry\x12\x42\n\x0butilization\x18\x04 \x03(\x0b\x32-.grpc.testing.TestOrcaReport.UtilizationEntry\x1a\x32\n\x10RequestCostEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x01:\x02\x38\x01\x1a\x32\n\x10UtilizationEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x01:\x02\x38\x01*\x1f\n\x0bPayloadType\x12\x10\n\x0c\x43OMPRESSABLE\x10\x00*o\n\x0fGrpclbRouteType\x12\x1d\n\x19GRPCLB_ROUTE_TYPE_UNKNOWN\x10\x00\x12\x1e\n\x1aGRPCLB_ROUTE_TYPE_FALLBACK\x10\x01\x12\x1d\n\x19GRPCLB_ROUTE_TYPE_BACKEND\x10\x02\x42\x1d\n\x1bio.grpc.testing.integrationb\x06proto3"
9
+
10
+ pool = Google::Protobuf::DescriptorPool.generated_pool
11
+
12
+ begin
13
+ pool.add_serialized_file(descriptor_data)
14
+ rescue TypeError => e
15
+ # Compatibility code: will be removed in the next major version.
16
+ require 'google/protobuf/descriptor_pb'
17
+ parsed = Google::Protobuf::FileDescriptorProto.decode(descriptor_data)
18
+ parsed.clear_dependency
19
+ serialized = parsed.class.encode(parsed)
20
+ file = pool.add_serialized_file(serialized)
21
+ warn "Warning: Protobuf detected an import path issue while loading generated file #{__FILE__}"
22
+ imports = [
23
+ ]
24
+ imports.each do |type_name, expected_filename|
25
+ import_file = pool.lookup(type_name).file_descriptor
26
+ if import_file.name != expected_filename
27
+ warn "- #{file.name} imports #{expected_filename}, but that import was loaded as #{import_file.name}"
114
28
  end
115
29
  end
30
+ warn "Each proto file must use a consistent fully-qualified name."
31
+ warn "This will become an error in the next major version."
116
32
  end
117
33
 
118
34
  module Grpc
@@ -139,6 +55,8 @@ module Grpc
139
55
  ClientConfigureRequest::Metadata = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ClientConfigureRequest.Metadata").msgclass
140
56
  ClientConfigureRequest::RpcType = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ClientConfigureRequest.RpcType").enummodule
141
57
  ClientConfigureResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ClientConfigureResponse").msgclass
58
+ MemorySize = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.MemorySize").msgclass
59
+ TestOrcaReport = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.TestOrcaReport").msgclass
142
60
  PayloadType = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.PayloadType").enummodule
143
61
  GrpclbRouteType = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.GrpclbRouteType").enummodule
144
62
  end
@@ -1,13 +1,37 @@
1
+ # frozen_string_literal: true
1
2
  # Generated by the protocol buffer compiler. DO NOT EDIT!
2
3
  # source: src/proto/grpc/testing/test.proto
3
4
 
5
+ require 'google/protobuf'
6
+
4
7
  require 'src/proto/grpc/testing/empty_pb'
5
8
  require 'src/proto/grpc/testing/messages_pb'
6
- require 'google/protobuf'
7
9
 
8
- Google::Protobuf::DescriptorPool.generated_pool.build do
9
- add_file("src/proto/grpc/testing/test.proto", :syntax => :proto3) do
10
+
11
+ descriptor_data = "\n!src/proto/grpc/testing/test.proto\x12\x0cgrpc.testing\x1a\"src/proto/grpc/testing/empty.proto\x1a%src/proto/grpc/testing/messages.proto2\xcb\x05\n\x0bTestService\x12\x35\n\tEmptyCall\x12\x13.grpc.testing.Empty\x1a\x13.grpc.testing.Empty\x12\x46\n\tUnaryCall\x12\x1b.grpc.testing.SimpleRequest\x1a\x1c.grpc.testing.SimpleResponse\x12O\n\x12\x43\x61\x63heableUnaryCall\x12\x1b.grpc.testing.SimpleRequest\x1a\x1c.grpc.testing.SimpleResponse\x12l\n\x13StreamingOutputCall\x12(.grpc.testing.StreamingOutputCallRequest\x1a).grpc.testing.StreamingOutputCallResponse0\x01\x12i\n\x12StreamingInputCall\x12\'.grpc.testing.StreamingInputCallRequest\x1a(.grpc.testing.StreamingInputCallResponse(\x01\x12i\n\x0e\x46ullDuplexCall\x12(.grpc.testing.StreamingOutputCallRequest\x1a).grpc.testing.StreamingOutputCallResponse(\x01\x30\x01\x12i\n\x0eHalfDuplexCall\x12(.grpc.testing.StreamingOutputCallRequest\x1a).grpc.testing.StreamingOutputCallResponse(\x01\x30\x01\x12=\n\x11UnimplementedCall\x12\x13.grpc.testing.Empty\x1a\x13.grpc.testing.Empty2U\n\x14UnimplementedService\x12=\n\x11UnimplementedCall\x12\x13.grpc.testing.Empty\x1a\x13.grpc.testing.Empty2\x89\x01\n\x10ReconnectService\x12;\n\x05Start\x12\x1d.grpc.testing.ReconnectParams\x1a\x13.grpc.testing.Empty\x12\x38\n\x04Stop\x12\x13.grpc.testing.Empty\x1a\x1b.grpc.testing.ReconnectInfo2\x86\x02\n\x18LoadBalancerStatsService\x12\x63\n\x0eGetClientStats\x12&.grpc.testing.LoadBalancerStatsRequest\x1a\'.grpc.testing.LoadBalancerStatsResponse\"\x00\x12\x84\x01\n\x19GetClientAccumulatedStats\x12\x31.grpc.testing.LoadBalancerAccumulatedStatsRequest\x1a\x32.grpc.testing.LoadBalancerAccumulatedStatsResponse\"\x00\x32\x8b\x01\n\x16XdsUpdateHealthService\x12\x36\n\nSetServing\x12\x13.grpc.testing.Empty\x1a\x13.grpc.testing.Empty\x12\x39\n\rSetNotServing\x12\x13.grpc.testing.Empty\x1a\x13.grpc.testing.Empty2{\n\x1fXdsUpdateClientConfigureService\x12X\n\tConfigure\x12$.grpc.testing.ClientConfigureRequest\x1a%.grpc.testing.ClientConfigureResponseb\x06proto3"
12
+
13
+ pool = Google::Protobuf::DescriptorPool.generated_pool
14
+
15
+ begin
16
+ pool.add_serialized_file(descriptor_data)
17
+ rescue TypeError => e
18
+ # Compatibility code: will be removed in the next major version.
19
+ require 'google/protobuf/descriptor_pb'
20
+ parsed = Google::Protobuf::FileDescriptorProto.decode(descriptor_data)
21
+ parsed.clear_dependency
22
+ serialized = parsed.class.encode(parsed)
23
+ file = pool.add_serialized_file(serialized)
24
+ warn "Warning: Protobuf detected an import path issue while loading generated file #{__FILE__}"
25
+ imports = [
26
+ ]
27
+ imports.each do |type_name, expected_filename|
28
+ import_file = pool.lookup(type_name).file_descriptor
29
+ if import_file.name != expected_filename
30
+ warn "- #{file.name} imports #{expected_filename}, but that import was loaded as #{import_file.name}"
31
+ end
10
32
  end
33
+ warn "Each proto file must use a consistent fully-qualified name."
34
+ warn "This will become an error in the next major version."
11
35
  end
12
36
 
13
37
  module Grpc
@@ -649,6 +649,22 @@ class NamedTests
649
649
 
650
650
  end
651
651
 
652
+ def special_status_message
653
+ code = GRPC::Core::StatusCodes::UNKNOWN
654
+ message = "\t\ntest with whitespace\r\nand Unicode BMP ☺ and non-BMP 😈\t\n"
655
+ req = SimpleRequest.new(
656
+ response_status: EchoStatus.new(code: code, message: message))
657
+ begin
658
+ resp = @stub.unary_call(req)
659
+ fail AssertionError, "GRPC::Unknown should have been raised."
660
+ rescue GRPC::Unknown => e
661
+ if e.details.force_encoding("UTF-8") != message
662
+ fail AssertionError,
663
+ "Expected message #{message}. Received: #{e.details}"
664
+ end
665
+ end
666
+ end
667
+
652
668
  def all
653
669
  all_methods = NamedTests.instance_methods(false).map(&:to_s)
654
670
  all_methods.each do |m|
@@ -28,28 +28,6 @@ describe GRPC::Core::Channel do
28
28
  GRPC::Core::ChannelCredentials.new(load_test_certs[0])
29
29
  end
30
30
 
31
- def fork_with_propagated_error_message
32
- pipe_read, pipe_write = IO.pipe
33
- pid = fork do
34
- pipe_read.close
35
- begin
36
- yield
37
- rescue => exc
38
- pipe_write.syswrite(exc.message)
39
- end
40
- pipe_write.close
41
- end
42
- pipe_write.close
43
-
44
- exc_message = pipe_read.read
45
- Process.wait(pid)
46
-
47
- unless $CHILD_STATUS.success?
48
- raise "forked process failed with #{$CHILD_STATUS}"
49
- end
50
- raise exc_message unless exc_message.empty?
51
- end
52
-
53
31
  shared_examples '#new' do
54
32
  it 'take a host name without channel args' do
55
33
  blk = proc do
@@ -102,14 +80,6 @@ describe GRPC::Core::Channel do
102
80
  blk = construct_with_args(args)
103
81
  expect(&blk).to_not raise_error
104
82
  end
105
-
106
- it 'raises if grpc was initialized in another process' do
107
- blk = construct_with_args({})
108
- expect(&blk).not_to raise_error
109
- expect do
110
- fork_with_propagated_error_message(&blk)
111
- end.to raise_error(RuntimeError, 'grpc cannot be used before and after forking')
112
- end
113
83
  end
114
84
 
115
85
  describe '#new for secure channels' do
@@ -154,27 +124,19 @@ describe GRPC::Core::Channel do
154
124
  end
155
125
 
156
126
  it 'raises an error if called on a closed channel' do
127
+ STDERR.puts "#{Time.now}: begin: raises an error if called on a closed channel"
157
128
  ch = GRPC::Core::Channel.new(fake_host, nil, :this_channel_is_insecure)
129
+ STDERR.puts "#{Time.now}: created channel"
158
130
  ch.close
131
+ STDERR.puts "#{Time.now}: closed channel"
159
132
 
160
133
  deadline = Time.now + 5
161
134
  blk = proc do
162
135
  ch.create_call(nil, nil, 'phony_method', nil, deadline)
136
+ STDERR.puts "#{Time.now}: created call"
163
137
  end
164
138
  expect(&blk).to raise_error(RuntimeError)
165
- end
166
-
167
- it 'raises if grpc was initialized in another process' do
168
- ch = GRPC::Core::Channel.new(fake_host, nil, :this_channel_is_insecure)
169
-
170
- deadline = Time.now + 5
171
-
172
- blk = proc do
173
- fork_with_propagated_error_message do
174
- ch.create_call(nil, nil, 'phony_method', nil, deadline)
175
- end
176
- end
177
- expect(&blk).to raise_error(RuntimeError, 'grpc cannot be used before and after forking')
139
+ STDERR.puts "#{Time.now}: finished: raises an error if called on a closed channel"
178
140
  end
179
141
  end
180
142
 
@@ -85,12 +85,15 @@ shared_examples 'basic GRPC message delivery is OK' do
85
85
  # confirm the server can read the inbound message
86
86
  server_thread.join
87
87
  server_ops = {
88
- CallOps::RECV_MESSAGE => nil,
88
+ CallOps::RECV_MESSAGE => nil
89
+ }
90
+ server_batch = server_call.run_batch(server_ops)
91
+ expect(server_batch.message).to eq(sent_message)
92
+ server_ops = {
89
93
  CallOps::RECV_CLOSE_ON_SERVER => nil,
90
94
  CallOps::SEND_STATUS_FROM_SERVER => ok_status
91
95
  }
92
96
  server_batch = server_call.run_batch(server_ops)
93
- expect(server_batch.message).to eq(sent_message)
94
97
  expect(server_batch.send_close).to be true
95
98
  expect(server_batch.send_status).to be true
96
99
 
@@ -123,13 +126,16 @@ shared_examples 'basic GRPC message delivery is OK' do
123
126
  # confirm the server can read the inbound message
124
127
  server_thread.join
125
128
  server_ops = {
126
- CallOps::RECV_MESSAGE => nil,
129
+ CallOps::RECV_MESSAGE => nil
130
+ }
131
+ server_batch = server_call.run_batch(server_ops)
132
+ expect(server_batch.message).to eq(sent_message)
133
+ server_ops = {
127
134
  CallOps::RECV_CLOSE_ON_SERVER => nil,
128
135
  CallOps::SEND_MESSAGE => reply_text,
129
136
  CallOps::SEND_STATUS_FROM_SERVER => ok_status
130
137
  }
131
138
  server_batch = server_call.run_batch(server_ops)
132
- expect(server_batch.message).to eq(sent_message)
133
139
  expect(server_batch.send_close).to be true
134
140
  expect(server_batch.send_message).to be true
135
141
  expect(server_batch.send_status).to be true
@@ -168,13 +174,16 @@ shared_examples 'basic GRPC message delivery is OK' do
168
174
  # confirm the server can read the inbound message
169
175
  server_thread.join
170
176
  server_ops = {
171
- CallOps::RECV_MESSAGE => nil,
177
+ CallOps::RECV_MESSAGE => nil
178
+ }
179
+ server_batch = server_call.run_batch(server_ops)
180
+ expect(server_batch.message).to eq(long_request_str)
181
+ server_ops = {
172
182
  CallOps::RECV_CLOSE_ON_SERVER => nil,
173
183
  CallOps::SEND_MESSAGE => long_response_str,
174
184
  CallOps::SEND_STATUS_FROM_SERVER => ok_status
175
185
  }
176
186
  server_batch = server_call.run_batch(server_ops)
177
- expect(server_batch.message).to eq(long_request_str)
178
187
  expect(server_batch.send_close).to be true
179
188
  expect(server_batch.send_message).to be true
180
189
  expect(server_batch.send_status).to be true
@@ -245,12 +254,15 @@ shared_examples 'basic GRPC message delivery is OK' do
245
254
  the_status = Struct::Status.new(StatusCodes::OK, 'OK', {})
246
255
  server_thread.join
247
256
  server_ops = {
248
- CallOps::RECV_MESSAGE => nil,
257
+ CallOps::RECV_MESSAGE => nil
258
+ }
259
+ server_batch = server_call.run_batch(server_ops)
260
+ expect(server_batch.message).to eq sent_message
261
+ server_ops = {
249
262
  CallOps::SEND_MESSAGE => reply_text,
250
263
  CallOps::SEND_STATUS_FROM_SERVER => the_status
251
264
  }
252
265
  server_batch = server_call.run_batch(server_ops)
253
- expect(server_batch.message).to eq sent_message
254
266
  expect(server_batch.send_status).to be true
255
267
  expect(server_batch.send_message).to be true
256
268
 
@@ -65,12 +65,21 @@ describe GRPC::ActiveCall do
65
65
 
66
66
  describe 'restricted view methods' do
67
67
  before(:each) do
68
- call = make_test_call
69
- ActiveCall.client_invoke(call)
70
- @client_call = ActiveCall.new(call, @pass_through,
68
+ @call = make_test_call
69
+ ActiveCall.client_invoke(@call)
70
+ @client_call = ActiveCall.new(@call, @pass_through,
71
71
  @pass_through, deadline)
72
72
  end
73
73
 
74
+ after(:each) do
75
+ # terminate the RPC that was started in before(:each)
76
+ recvd_rpc = @received_rpcs_queue.pop
77
+ recvd_call = recvd_rpc.call
78
+ recvd_call.run_batch(CallOps::SEND_INITIAL_METADATA => nil)
79
+ @call.run_batch(CallOps::RECV_INITIAL_METADATA => nil)
80
+ send_and_receive_close_and_status(@call, recvd_call)
81
+ end
82
+
74
83
  describe '#multi_req_view' do
75
84
  it 'exposes a fixed subset of the ActiveCall.methods' do
76
85
  want = %w(cancelled?, deadline, each_remote_read, metadata, \
@@ -498,31 +498,10 @@ describe 'ClientStub' do # rubocop:disable Metrics/BlockLength
498
498
  /Header values must be of type string or array/)
499
499
  end
500
500
 
501
- def run_server_streamer_against_client_with_unmarshal_error(
502
- expected_input, replys)
503
- wakey_thread do |notifier|
504
- c = expect_server_to_be_invoked(notifier)
505
- expect(c.remote_read).to eq(expected_input)
506
- begin
507
- replys.each { |r| c.remote_send(r) }
508
- rescue GRPC::Core::CallError
509
- # An attempt to write to the client might fail. This is ok
510
- # because the client call is expected to fail when
511
- # unmarshalling the first response, and to cancel the call,
512
- # and there is a race as for when the server-side call will
513
- # start to fail.
514
- p 'remote_send failed (allowed because call expected to cancel)'
515
- ensure
516
- c.send_status(OK, 'OK', true)
517
- close_active_server_call(c)
518
- end
519
- end
520
- end
521
-
522
501
  it 'the call terminates when there is an unmarshalling error' do
523
502
  server_port = create_test_server
524
503
  host = "localhost:#{server_port}"
525
- th = run_server_streamer_against_client_with_unmarshal_error(
504
+ th = run_server_streamer_handle_client_cancellation(
526
505
  @sent_msg, @replys)
527
506
  stub = GRPC::ClientStub.new(host, :this_channel_is_insecure)
528
507
 
@@ -597,7 +576,8 @@ describe 'ClientStub' do # rubocop:disable Metrics/BlockLength
597
576
  it 'raises GRPC::Cancelled after the call has been cancelled' do
598
577
  server_port = create_test_server
599
578
  host = "localhost:#{server_port}"
600
- th = run_server_streamer(@sent_msg, @replys, @pass)
579
+ th = run_server_streamer_handle_client_cancellation(
580
+ @sent_msg, @replys)
601
581
  stub = GRPC::ClientStub.new(host, :this_channel_is_insecure)
602
582
  resp = get_responses(stub, run_start_call_first: false)
603
583
  expect(resp.next).to eq('reply_1')
@@ -1037,6 +1017,26 @@ describe 'ClientStub' do # rubocop:disable Metrics/BlockLength
1037
1017
  end
1038
1018
  end
1039
1019
 
1020
+ def run_server_streamer_handle_client_cancellation(
1021
+ expected_input, replys)
1022
+ wakey_thread do |notifier|
1023
+ c = expect_server_to_be_invoked(notifier)
1024
+ expect(c.remote_read).to eq(expected_input)
1025
+ begin
1026
+ replys.each { |r| c.remote_send(r) }
1027
+ rescue GRPC::Core::CallError
1028
+ # An attempt to write to the client might fail. This is ok
1029
+ # because the client call is expected to cancel the call,
1030
+ # and there is a race as for when the server-side call will
1031
+ # start to fail.
1032
+ p 'remote_send failed (allowed because call expected to cancel)'
1033
+ ensure
1034
+ c.send_status(OK, 'OK', true)
1035
+ close_active_server_call(c)
1036
+ end
1037
+ end
1038
+ end
1039
+
1040
1040
  def run_request_response(expected_input, resp, status,
1041
1041
  expected_metadata: {},
1042
1042
  server_initial_md: {},
@@ -668,9 +668,9 @@ describe GRPC::RpcServer do
668
668
  def check_multi_req_view_of_finished_call(call)
669
669
  common_check_of_finished_server_call(call)
670
670
 
671
- expect do
672
- call.each_remote_read.each { |r| p r }
673
- end.to raise_error(GRPC::Core::CallError)
671
+ l = []
672
+ call.each_remote_read.each { |r| l << r }
673
+ expect(l.size).to eq(0)
674
674
  end
675
675
 
676
676
  def common_check_of_finished_server_call(call)
@@ -17,7 +17,7 @@ describe 'Server Interceptors' do
17
17
  let(:interceptor) { TestServerInterceptor.new }
18
18
  let(:request) { EchoMsg.new }
19
19
  let(:trailing_metadata) { {} }
20
- let(:service) { EchoService.new(trailing_metadata) }
20
+ let(:service) { EchoService.new(**trailing_metadata) }
21
21
  let(:interceptors) { [] }
22
22
 
23
23
  before(:each) do
@@ -49,7 +49,7 @@ describe 'user agent' do
49
49
  it 'client sends expected user agent' do
50
50
  stub = UserAgentEchoServiceStub.new("localhost:#{@port}",
51
51
  :this_channel_is_insecure,
52
- {})
52
+ channel_args: {})
53
53
  response = stub.an_rpc(EchoMsg.new)
54
54
  expected_user_agent_prefix = "grpc-ruby/#{GRPC::VERSION}"
55
55
  expect(response.msg.start_with?(expected_user_agent_prefix)).to be true