grpc 1.60.0-aarch64-linux

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 (132) hide show
  1. checksums.yaml +7 -0
  2. data/etc/roots.pem +4337 -0
  3. data/grpc_c.32-msvcrt.ruby +0 -0
  4. data/grpc_c.64-msvcrt.ruby +0 -0
  5. data/grpc_c.64-ucrt.ruby +0 -0
  6. data/src/ruby/bin/math_client.rb +140 -0
  7. data/src/ruby/bin/math_pb.rb +40 -0
  8. data/src/ruby/bin/math_server.rb +191 -0
  9. data/src/ruby/bin/math_services_pb.rb +51 -0
  10. data/src/ruby/bin/noproto_client.rb +93 -0
  11. data/src/ruby/bin/noproto_server.rb +97 -0
  12. data/src/ruby/ext/grpc/ext-export-truffleruby-with-ruby-abi-version.clang +2 -0
  13. data/src/ruby/ext/grpc/ext-export-truffleruby-with-ruby-abi-version.gcc +7 -0
  14. data/src/ruby/ext/grpc/ext-export-with-ruby-abi-version.clang +2 -0
  15. data/src/ruby/ext/grpc/ext-export-with-ruby-abi-version.gcc +7 -0
  16. data/src/ruby/ext/grpc/ext-export.clang +1 -0
  17. data/src/ruby/ext/grpc/ext-export.gcc +6 -0
  18. data/src/ruby/ext/grpc/extconf.rb +270 -0
  19. data/src/ruby/ext/grpc/rb_byte_buffer.c +65 -0
  20. data/src/ruby/ext/grpc/rb_byte_buffer.h +35 -0
  21. data/src/ruby/ext/grpc/rb_call.c +1075 -0
  22. data/src/ruby/ext/grpc/rb_call.h +57 -0
  23. data/src/ruby/ext/grpc/rb_call_credentials.c +340 -0
  24. data/src/ruby/ext/grpc/rb_call_credentials.h +31 -0
  25. data/src/ruby/ext/grpc/rb_channel.c +875 -0
  26. data/src/ruby/ext/grpc/rb_channel.h +35 -0
  27. data/src/ruby/ext/grpc/rb_channel_args.c +172 -0
  28. data/src/ruby/ext/grpc/rb_channel_args.h +42 -0
  29. data/src/ruby/ext/grpc/rb_channel_credentials.c +285 -0
  30. data/src/ruby/ext/grpc/rb_channel_credentials.h +37 -0
  31. data/src/ruby/ext/grpc/rb_completion_queue.c +101 -0
  32. data/src/ruby/ext/grpc/rb_completion_queue.h +36 -0
  33. data/src/ruby/ext/grpc/rb_compression_options.c +470 -0
  34. data/src/ruby/ext/grpc/rb_compression_options.h +29 -0
  35. data/src/ruby/ext/grpc/rb_enable_cpp.cc +22 -0
  36. data/src/ruby/ext/grpc/rb_event_thread.c +161 -0
  37. data/src/ruby/ext/grpc/rb_event_thread.h +22 -0
  38. data/src/ruby/ext/grpc/rb_grpc.c +496 -0
  39. data/src/ruby/ext/grpc/rb_grpc.h +83 -0
  40. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +603 -0
  41. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +910 -0
  42. data/src/ruby/ext/grpc/rb_loader.c +61 -0
  43. data/src/ruby/ext/grpc/rb_loader.h +25 -0
  44. data/src/ruby/ext/grpc/rb_server.c +405 -0
  45. data/src/ruby/ext/grpc/rb_server.h +32 -0
  46. data/src/ruby/ext/grpc/rb_server_credentials.c +258 -0
  47. data/src/ruby/ext/grpc/rb_server_credentials.h +37 -0
  48. data/src/ruby/ext/grpc/rb_xds_channel_credentials.c +217 -0
  49. data/src/ruby/ext/grpc/rb_xds_channel_credentials.h +37 -0
  50. data/src/ruby/ext/grpc/rb_xds_server_credentials.c +169 -0
  51. data/src/ruby/ext/grpc/rb_xds_server_credentials.h +37 -0
  52. data/src/ruby/lib/grpc/2.7/grpc_c.so +0 -0
  53. data/src/ruby/lib/grpc/3.0/grpc_c.so +0 -0
  54. data/src/ruby/lib/grpc/3.1/grpc_c.so +0 -0
  55. data/src/ruby/lib/grpc/3.2/grpc_c.so +0 -0
  56. data/src/ruby/lib/grpc/core/status_codes.rb +135 -0
  57. data/src/ruby/lib/grpc/core/time_consts.rb +56 -0
  58. data/src/ruby/lib/grpc/errors.rb +277 -0
  59. data/src/ruby/lib/grpc/generic/active_call.rb +670 -0
  60. data/src/ruby/lib/grpc/generic/bidi_call.rb +237 -0
  61. data/src/ruby/lib/grpc/generic/client_stub.rb +503 -0
  62. data/src/ruby/lib/grpc/generic/interceptor_registry.rb +53 -0
  63. data/src/ruby/lib/grpc/generic/interceptors.rb +186 -0
  64. data/src/ruby/lib/grpc/generic/rpc_desc.rb +204 -0
  65. data/src/ruby/lib/grpc/generic/rpc_server.rb +551 -0
  66. data/src/ruby/lib/grpc/generic/service.rb +211 -0
  67. data/src/ruby/lib/grpc/google_rpc_status_utils.rb +40 -0
  68. data/src/ruby/lib/grpc/grpc.rb +24 -0
  69. data/src/ruby/lib/grpc/logconfig.rb +44 -0
  70. data/src/ruby/lib/grpc/notifier.rb +45 -0
  71. data/src/ruby/lib/grpc/structs.rb +15 -0
  72. data/src/ruby/lib/grpc/version.rb +18 -0
  73. data/src/ruby/lib/grpc.rb +37 -0
  74. data/src/ruby/pb/README.md +42 -0
  75. data/src/ruby/pb/generate_proto_ruby.sh +46 -0
  76. data/src/ruby/pb/grpc/health/checker.rb +75 -0
  77. data/src/ruby/pb/grpc/health/v1/health_pb.rb +42 -0
  78. data/src/ruby/pb/grpc/health/v1/health_services_pb.rb +62 -0
  79. data/src/ruby/pb/grpc/testing/duplicate/echo_duplicate_services_pb.rb +44 -0
  80. data/src/ruby/pb/grpc/testing/metrics_pb.rb +28 -0
  81. data/src/ruby/pb/grpc/testing/metrics_services_pb.rb +49 -0
  82. data/src/ruby/pb/src/proto/grpc/testing/empty_pb.rb +38 -0
  83. data/src/ruby/pb/src/proto/grpc/testing/messages_pb.rb +71 -0
  84. data/src/ruby/pb/src/proto/grpc/testing/test_pb.rb +40 -0
  85. data/src/ruby/pb/src/proto/grpc/testing/test_services_pb.rb +174 -0
  86. data/src/ruby/pb/test/client.rb +785 -0
  87. data/src/ruby/pb/test/server.rb +252 -0
  88. data/src/ruby/pb/test/xds_client.rb +415 -0
  89. data/src/ruby/spec/call_credentials_spec.rb +42 -0
  90. data/src/ruby/spec/call_spec.rb +180 -0
  91. data/src/ruby/spec/channel_connection_spec.rb +126 -0
  92. data/src/ruby/spec/channel_credentials_spec.rb +124 -0
  93. data/src/ruby/spec/channel_spec.rb +207 -0
  94. data/src/ruby/spec/client_auth_spec.rb +152 -0
  95. data/src/ruby/spec/client_server_spec.rb +676 -0
  96. data/src/ruby/spec/compression_options_spec.rb +149 -0
  97. data/src/ruby/spec/debug_message_spec.rb +134 -0
  98. data/src/ruby/spec/error_sanity_spec.rb +49 -0
  99. data/src/ruby/spec/errors_spec.rb +142 -0
  100. data/src/ruby/spec/generic/active_call_spec.rb +692 -0
  101. data/src/ruby/spec/generic/client_interceptors_spec.rb +153 -0
  102. data/src/ruby/spec/generic/client_stub_spec.rb +1083 -0
  103. data/src/ruby/spec/generic/interceptor_registry_spec.rb +65 -0
  104. data/src/ruby/spec/generic/rpc_desc_spec.rb +374 -0
  105. data/src/ruby/spec/generic/rpc_server_pool_spec.rb +127 -0
  106. data/src/ruby/spec/generic/rpc_server_spec.rb +748 -0
  107. data/src/ruby/spec/generic/server_interceptors_spec.rb +218 -0
  108. data/src/ruby/spec/generic/service_spec.rb +263 -0
  109. data/src/ruby/spec/google_rpc_status_utils_spec.rb +282 -0
  110. data/src/ruby/spec/pb/codegen/grpc/testing/package_options.proto +28 -0
  111. data/src/ruby/spec/pb/codegen/grpc/testing/package_options_import.proto +22 -0
  112. data/src/ruby/spec/pb/codegen/grpc/testing/package_options_import2.proto +23 -0
  113. data/src/ruby/spec/pb/codegen/grpc/testing/package_options_ruby_style.proto +41 -0
  114. data/src/ruby/spec/pb/codegen/grpc/testing/same_package_service_name.proto +27 -0
  115. data/src/ruby/spec/pb/codegen/grpc/testing/same_ruby_package_service_name.proto +29 -0
  116. data/src/ruby/spec/pb/codegen/package_option_spec.rb +98 -0
  117. data/src/ruby/spec/pb/duplicate/codegen_spec.rb +57 -0
  118. data/src/ruby/spec/pb/health/checker_spec.rb +236 -0
  119. data/src/ruby/spec/server_credentials_spec.rb +104 -0
  120. data/src/ruby/spec/server_spec.rb +231 -0
  121. data/src/ruby/spec/spec_helper.rb +61 -0
  122. data/src/ruby/spec/support/helpers.rb +107 -0
  123. data/src/ruby/spec/support/services.rb +160 -0
  124. data/src/ruby/spec/testdata/README +1 -0
  125. data/src/ruby/spec/testdata/ca.pem +20 -0
  126. data/src/ruby/spec/testdata/client.key +28 -0
  127. data/src/ruby/spec/testdata/client.pem +20 -0
  128. data/src/ruby/spec/testdata/server1.key +28 -0
  129. data/src/ruby/spec/testdata/server1.pem +22 -0
  130. data/src/ruby/spec/time_consts_spec.rb +74 -0
  131. data/src/ruby/spec/user_agent_spec.rb +74 -0
  132. metadata +405 -0
@@ -0,0 +1,676 @@
1
+ # Copyright 2015 gRPC authors.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require 'spec_helper'
16
+
17
+ include GRPC::Core
18
+
19
+ shared_context 'setup: tags' do
20
+ let(:sent_message) { 'sent message' }
21
+ let(:reply_text) { 'the reply' }
22
+
23
+ def deadline
24
+ Time.now + 5
25
+ end
26
+
27
+ def server_allows_client_to_proceed(metadata = {})
28
+ recvd_rpc = @server.request_call
29
+ expect(recvd_rpc).to_not eq nil
30
+ server_call = recvd_rpc.call
31
+ ops = { CallOps::SEND_INITIAL_METADATA => metadata }
32
+ server_batch = server_call.run_batch(ops)
33
+ expect(server_batch.send_metadata).to be true
34
+ server_call
35
+ end
36
+
37
+ def new_client_call
38
+ @ch.create_call(nil, nil, '/method', nil, deadline)
39
+ end
40
+
41
+ def ok_status
42
+ Struct::Status.new(StatusCodes::OK, 'OK')
43
+ end
44
+ end
45
+
46
+ shared_examples 'basic GRPC message delivery is OK' do
47
+ include GRPC::Core
48
+ include_context 'setup: tags'
49
+
50
+ context 'the test channel' do
51
+ it 'should have a target' do
52
+ expect(@ch.target).to be_a(String)
53
+ end
54
+ end
55
+
56
+ context 'a client call' do
57
+ it 'should have a peer' do
58
+ expect(new_client_call.peer).to be_a(String)
59
+ end
60
+ end
61
+
62
+ it 'calls have peer info' do
63
+ call = new_client_call
64
+ expect(call.peer).to be_a(String)
65
+ end
66
+
67
+ it 'servers receive requests from clients and can respond' do
68
+ call = new_client_call
69
+ server_call = nil
70
+
71
+ server_thread = Thread.new do
72
+ server_call = server_allows_client_to_proceed
73
+ end
74
+
75
+ client_ops = {
76
+ CallOps::SEND_INITIAL_METADATA => {},
77
+ CallOps::SEND_MESSAGE => sent_message,
78
+ CallOps::SEND_CLOSE_FROM_CLIENT => nil
79
+ }
80
+ client_batch = call.run_batch(client_ops)
81
+ expect(client_batch.send_metadata).to be true
82
+ expect(client_batch.send_message).to be true
83
+ expect(client_batch.send_close).to be true
84
+
85
+ # confirm the server can read the inbound message
86
+ server_thread.join
87
+ server_ops = {
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 = {
93
+ CallOps::RECV_CLOSE_ON_SERVER => nil,
94
+ CallOps::SEND_STATUS_FROM_SERVER => ok_status
95
+ }
96
+ server_batch = server_call.run_batch(server_ops)
97
+ expect(server_batch.send_close).to be true
98
+ expect(server_batch.send_status).to be true
99
+
100
+ # finish the call
101
+ final_client_batch = call.run_batch(
102
+ CallOps::RECV_INITIAL_METADATA => nil,
103
+ CallOps::RECV_STATUS_ON_CLIENT => nil)
104
+ expect(final_client_batch.metadata).to eq({})
105
+ expect(final_client_batch.status.code).to eq(0)
106
+ end
107
+
108
+ it 'responses written by servers are received by the client' do
109
+ call = new_client_call
110
+ server_call = nil
111
+
112
+ server_thread = Thread.new do
113
+ server_call = server_allows_client_to_proceed
114
+ end
115
+
116
+ client_ops = {
117
+ CallOps::SEND_INITIAL_METADATA => {},
118
+ CallOps::SEND_MESSAGE => sent_message,
119
+ CallOps::SEND_CLOSE_FROM_CLIENT => nil
120
+ }
121
+ client_batch = call.run_batch(client_ops)
122
+ expect(client_batch.send_metadata).to be true
123
+ expect(client_batch.send_message).to be true
124
+ expect(client_batch.send_close).to be true
125
+
126
+ # confirm the server can read the inbound message
127
+ server_thread.join
128
+ server_ops = {
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 = {
134
+ CallOps::RECV_CLOSE_ON_SERVER => nil,
135
+ CallOps::SEND_MESSAGE => reply_text,
136
+ CallOps::SEND_STATUS_FROM_SERVER => ok_status
137
+ }
138
+ server_batch = server_call.run_batch(server_ops)
139
+ expect(server_batch.send_close).to be true
140
+ expect(server_batch.send_message).to be true
141
+ expect(server_batch.send_status).to be true
142
+
143
+ # finish the call
144
+ final_client_batch = call.run_batch(
145
+ CallOps::RECV_INITIAL_METADATA => nil,
146
+ CallOps::RECV_MESSAGE => nil,
147
+ CallOps::RECV_STATUS_ON_CLIENT => nil)
148
+ expect(final_client_batch.metadata).to eq({})
149
+ expect(final_client_batch.message).to eq(reply_text)
150
+ expect(final_client_batch.status.code).to eq(0)
151
+ end
152
+
153
+ it 'compressed messages can be sent and received' do
154
+ call = new_client_call
155
+ server_call = nil
156
+ long_request_str = '0' * 2000
157
+ long_response_str = '1' * 2000
158
+ md = { 'grpc-internal-encoding-request' => 'gzip' }
159
+
160
+ server_thread = Thread.new do
161
+ server_call = server_allows_client_to_proceed(md)
162
+ end
163
+
164
+ client_ops = {
165
+ CallOps::SEND_INITIAL_METADATA => md,
166
+ CallOps::SEND_MESSAGE => long_request_str,
167
+ CallOps::SEND_CLOSE_FROM_CLIENT => nil
168
+ }
169
+ client_batch = call.run_batch(client_ops)
170
+ expect(client_batch.send_metadata).to be true
171
+ expect(client_batch.send_message).to be true
172
+ expect(client_batch.send_close).to be true
173
+
174
+ # confirm the server can read the inbound message
175
+ server_thread.join
176
+ server_ops = {
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 = {
182
+ CallOps::RECV_CLOSE_ON_SERVER => nil,
183
+ CallOps::SEND_MESSAGE => long_response_str,
184
+ CallOps::SEND_STATUS_FROM_SERVER => ok_status
185
+ }
186
+ server_batch = server_call.run_batch(server_ops)
187
+ expect(server_batch.send_close).to be true
188
+ expect(server_batch.send_message).to be true
189
+ expect(server_batch.send_status).to be true
190
+
191
+ client_ops = {
192
+ CallOps::RECV_INITIAL_METADATA => nil,
193
+ CallOps::RECV_MESSAGE => nil,
194
+ CallOps::RECV_STATUS_ON_CLIENT => nil
195
+ }
196
+ final_client_batch = call.run_batch(client_ops)
197
+ expect(final_client_batch.metadata).to eq({})
198
+ expect(final_client_batch.message).to eq long_response_str
199
+ expect(final_client_batch.status.code).to eq(0)
200
+ end
201
+
202
+ it 'servers can ignore a client write and send a status' do
203
+ call = new_client_call
204
+ server_call = nil
205
+
206
+ server_thread = Thread.new do
207
+ server_call = server_allows_client_to_proceed
208
+ end
209
+
210
+ client_ops = {
211
+ CallOps::SEND_INITIAL_METADATA => {},
212
+ CallOps::SEND_MESSAGE => sent_message,
213
+ CallOps::SEND_CLOSE_FROM_CLIENT => nil
214
+ }
215
+ client_batch = call.run_batch(client_ops)
216
+ expect(client_batch.send_metadata).to be true
217
+ expect(client_batch.send_message).to be true
218
+ expect(client_batch.send_close).to be true
219
+
220
+ # confirm the server can read the inbound message
221
+ the_status = Struct::Status.new(StatusCodes::OK, 'OK')
222
+ server_thread.join
223
+ server_ops = {
224
+ CallOps::SEND_STATUS_FROM_SERVER => the_status
225
+ }
226
+ server_batch = server_call.run_batch(server_ops)
227
+ expect(server_batch.message).to eq nil
228
+ expect(server_batch.send_status).to be true
229
+
230
+ final_client_batch = call.run_batch(
231
+ CallOps::RECV_INITIAL_METADATA => nil,
232
+ CallOps::RECV_STATUS_ON_CLIENT => nil)
233
+ expect(final_client_batch.metadata).to eq({})
234
+ expect(final_client_batch.status.code).to eq(0)
235
+ end
236
+
237
+ it 'completes calls by sending status to client and server' do
238
+ call = new_client_call
239
+ server_call = nil
240
+
241
+ server_thread = Thread.new do
242
+ server_call = server_allows_client_to_proceed
243
+ end
244
+
245
+ client_ops = {
246
+ CallOps::SEND_INITIAL_METADATA => {},
247
+ CallOps::SEND_MESSAGE => sent_message
248
+ }
249
+ client_batch = call.run_batch(client_ops)
250
+ expect(client_batch.send_metadata).to be true
251
+ expect(client_batch.send_message).to be true
252
+
253
+ # confirm the server can read the inbound message and respond
254
+ the_status = Struct::Status.new(StatusCodes::OK, 'OK', {})
255
+ server_thread.join
256
+ server_ops = {
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 = {
262
+ CallOps::SEND_MESSAGE => reply_text,
263
+ CallOps::SEND_STATUS_FROM_SERVER => the_status
264
+ }
265
+ server_batch = server_call.run_batch(server_ops)
266
+ expect(server_batch.send_status).to be true
267
+ expect(server_batch.send_message).to be true
268
+
269
+ # confirm the client can receive the server response and status.
270
+ client_ops = {
271
+ CallOps::SEND_CLOSE_FROM_CLIENT => nil,
272
+ CallOps::RECV_INITIAL_METADATA => nil,
273
+ CallOps::RECV_MESSAGE => nil,
274
+ CallOps::RECV_STATUS_ON_CLIENT => nil
275
+ }
276
+ final_client_batch = call.run_batch(client_ops)
277
+ expect(final_client_batch.send_close).to be true
278
+ expect(final_client_batch.message).to eq reply_text
279
+ expect(final_client_batch.status).to eq the_status
280
+
281
+ # confirm the server can receive the client close.
282
+ server_ops = {
283
+ CallOps::RECV_CLOSE_ON_SERVER => nil
284
+ }
285
+ final_server_batch = server_call.run_batch(server_ops)
286
+ expect(final_server_batch.send_close).to be true
287
+ end
288
+
289
+ def client_cancel_test(cancel_proc, expected_code,
290
+ expected_details)
291
+ call = new_client_call
292
+ server_call = nil
293
+
294
+ server_thread = Thread.new do
295
+ server_call = server_allows_client_to_proceed
296
+ end
297
+
298
+ client_ops = {
299
+ CallOps::SEND_INITIAL_METADATA => {},
300
+ CallOps::RECV_INITIAL_METADATA => nil
301
+ }
302
+ client_batch = call.run_batch(client_ops)
303
+ expect(client_batch.send_metadata).to be true
304
+ expect(client_batch.metadata).to eq({})
305
+
306
+ cancel_proc.call(call)
307
+
308
+ server_thread.join
309
+ server_ops = {
310
+ CallOps::RECV_CLOSE_ON_SERVER => nil
311
+ }
312
+ server_batch = server_call.run_batch(server_ops)
313
+ expect(server_batch.send_close).to be true
314
+
315
+ client_ops = {
316
+ CallOps::RECV_STATUS_ON_CLIENT => {}
317
+ }
318
+ client_batch = call.run_batch(client_ops)
319
+
320
+ expect(client_batch.status.code).to be expected_code
321
+ expect(client_batch.status.details).to eq expected_details
322
+ end
323
+
324
+ it 'clients can cancel a call on the server' do
325
+ expected_code = StatusCodes::CANCELLED
326
+ expected_details = 'CANCELLED'
327
+ cancel_proc = proc { |call| call.cancel }
328
+ client_cancel_test(cancel_proc, expected_code, expected_details)
329
+ end
330
+
331
+ it 'cancel_with_status unknown status' do
332
+ code = StatusCodes::UNKNOWN
333
+ details = 'test unknown reason'
334
+ cancel_proc = proc { |call| call.cancel_with_status(code, details) }
335
+ client_cancel_test(cancel_proc, code, details)
336
+ end
337
+
338
+ it 'cancel_with_status unknown status' do
339
+ code = StatusCodes::FAILED_PRECONDITION
340
+ details = 'test failed precondition reason'
341
+ cancel_proc = proc { |call| call.cancel_with_status(code, details) }
342
+ client_cancel_test(cancel_proc, code, details)
343
+ end
344
+ end
345
+
346
+ shared_examples 'GRPC metadata delivery works OK' do
347
+ include_context 'setup: tags'
348
+
349
+ describe 'from client => server' do
350
+ before(:example) do
351
+ n = 7 # arbitrary number of metadata
352
+ diff_keys_fn = proc { |i| [format('k%d', i), format('v%d', i)] }
353
+ diff_keys = Hash[n.times.collect { |x| diff_keys_fn.call x }]
354
+ null_vals_fn = proc { |i| [format('k%d', i), format('v\0%d', i)] }
355
+ null_vals = Hash[n.times.collect { |x| null_vals_fn.call x }]
356
+ same_keys_fn = proc { |i| [format('k%d', i), [format('v%d', i)] * n] }
357
+ same_keys = Hash[n.times.collect { |x| same_keys_fn.call x }]
358
+ symbol_key = { a_key: 'a val' }
359
+ @valid_metadata = [diff_keys, same_keys, null_vals, symbol_key]
360
+ @bad_keys = []
361
+ @bad_keys << { Object.new => 'a value' }
362
+ @bad_keys << { 1 => 'a value' }
363
+ end
364
+
365
+ it 'raises an exception if a metadata key is invalid' do
366
+ @bad_keys.each do |md|
367
+ call = new_client_call
368
+ client_ops = {
369
+ CallOps::SEND_INITIAL_METADATA => md
370
+ }
371
+ blk = proc do
372
+ call.run_batch(client_ops)
373
+ end
374
+ expect(&blk).to raise_error
375
+ end
376
+ end
377
+
378
+ it 'sends all the metadata pairs when keys and values are valid' do
379
+ @valid_metadata.each do |md|
380
+ recvd_rpc = nil
381
+ rcv_thread = Thread.new do
382
+ recvd_rpc = @server.request_call
383
+ end
384
+
385
+ call = new_client_call
386
+ client_ops = {
387
+ CallOps::SEND_INITIAL_METADATA => md,
388
+ CallOps::SEND_CLOSE_FROM_CLIENT => nil
389
+ }
390
+ client_batch = call.run_batch(client_ops)
391
+ expect(client_batch.send_metadata).to be true
392
+
393
+ # confirm the server can receive the client metadata
394
+ rcv_thread.join
395
+ expect(recvd_rpc).to_not eq nil
396
+ recvd_md = recvd_rpc.metadata
397
+ replace_symbols = Hash[md.each_pair.collect { |x, y| [x.to_s, y] }]
398
+ expect(recvd_md).to eq(recvd_md.merge(replace_symbols))
399
+
400
+ # finish the call
401
+ final_server_batch = recvd_rpc.call.run_batch(
402
+ CallOps::RECV_CLOSE_ON_SERVER => nil,
403
+ CallOps::SEND_INITIAL_METADATA => nil,
404
+ CallOps::SEND_STATUS_FROM_SERVER => ok_status)
405
+ expect(final_server_batch.send_close).to be(true)
406
+ expect(final_server_batch.send_metadata).to be(true)
407
+ expect(final_server_batch.send_status).to be(true)
408
+
409
+ final_client_batch = call.run_batch(
410
+ CallOps::RECV_INITIAL_METADATA => nil,
411
+ CallOps::RECV_STATUS_ON_CLIENT => nil)
412
+ expect(final_client_batch.metadata).to eq({})
413
+ expect(final_client_batch.status.code).to eq(0)
414
+ end
415
+ end
416
+ end
417
+
418
+ describe 'from server => client' do
419
+ before(:example) do
420
+ n = 7 # arbitrary number of metadata
421
+ diff_keys_fn = proc { |i| [format('k%d', i), format('v%d', i)] }
422
+ diff_keys = Hash[n.times.collect { |x| diff_keys_fn.call x }]
423
+ null_vals_fn = proc { |i| [format('k%d', i), format('v\0%d', i)] }
424
+ null_vals = Hash[n.times.collect { |x| null_vals_fn.call x }]
425
+ same_keys_fn = proc { |i| [format('k%d', i), [format('v%d', i)] * n] }
426
+ same_keys = Hash[n.times.collect { |x| same_keys_fn.call x }]
427
+ symbol_key = { a_key: 'a val' }
428
+ @valid_metadata = [diff_keys, same_keys, null_vals, symbol_key]
429
+ @bad_keys = []
430
+ @bad_keys << { Object.new => 'a value' }
431
+ @bad_keys << { 1 => 'a value' }
432
+ end
433
+
434
+ it 'raises an exception if a metadata key is invalid' do
435
+ @bad_keys.each do |md|
436
+ recvd_rpc = nil
437
+ rcv_thread = Thread.new do
438
+ recvd_rpc = @server.request_call
439
+ end
440
+
441
+ call = new_client_call
442
+ # client signals that it's done sending metadata to allow server to
443
+ # respond
444
+ client_ops = {
445
+ CallOps::SEND_INITIAL_METADATA => nil
446
+ }
447
+ call.run_batch(client_ops)
448
+
449
+ # server gets the invocation
450
+ rcv_thread.join
451
+ expect(recvd_rpc).to_not eq nil
452
+ server_ops = {
453
+ CallOps::SEND_INITIAL_METADATA => md
454
+ }
455
+ blk = proc do
456
+ recvd_rpc.call.run_batch(server_ops)
457
+ end
458
+ expect(&blk).to raise_error
459
+
460
+ # cancel the call so the server can shut down immediately
461
+ call.cancel
462
+ end
463
+ end
464
+
465
+ it 'sends an empty hash if no metadata is added' do
466
+ recvd_rpc = nil
467
+ rcv_thread = Thread.new do
468
+ recvd_rpc = @server.request_call
469
+ end
470
+
471
+ call = new_client_call
472
+ # client signals that it's done sending metadata to allow server to
473
+ # respond
474
+ client_ops = {
475
+ CallOps::SEND_INITIAL_METADATA => nil,
476
+ CallOps::SEND_CLOSE_FROM_CLIENT => nil
477
+ }
478
+ client_batch = call.run_batch(client_ops)
479
+ expect(client_batch.send_metadata).to be true
480
+ expect(client_batch.send_close).to be true
481
+
482
+ # server gets the invocation but sends no metadata back
483
+ rcv_thread.join
484
+ expect(recvd_rpc).to_not eq nil
485
+ server_call = recvd_rpc.call
486
+ server_ops = {
487
+ # receive close and send status to finish the call
488
+ CallOps::RECV_CLOSE_ON_SERVER => nil,
489
+ CallOps::SEND_INITIAL_METADATA => nil,
490
+ CallOps::SEND_STATUS_FROM_SERVER => ok_status
491
+ }
492
+ srv_batch = server_call.run_batch(server_ops)
493
+ expect(srv_batch.send_close).to be true
494
+ expect(srv_batch.send_metadata).to be true
495
+ expect(srv_batch.send_status).to be true
496
+
497
+ # client receives nothing as expected
498
+ client_ops = {
499
+ CallOps::RECV_INITIAL_METADATA => nil,
500
+ # receive status to finish the call
501
+ CallOps::RECV_STATUS_ON_CLIENT => nil
502
+ }
503
+ final_client_batch = call.run_batch(client_ops)
504
+ expect(final_client_batch.metadata).to eq({})
505
+ expect(final_client_batch.status.code).to eq(0)
506
+ end
507
+
508
+ it 'sends all the pairs when keys and values are valid' do
509
+ @valid_metadata.each do |md|
510
+ recvd_rpc = nil
511
+ rcv_thread = Thread.new do
512
+ recvd_rpc = @server.request_call
513
+ end
514
+
515
+ call = new_client_call
516
+ # client signals that it's done sending metadata to allow server to
517
+ # respond
518
+ client_ops = {
519
+ CallOps::SEND_INITIAL_METADATA => nil,
520
+ CallOps::SEND_CLOSE_FROM_CLIENT => nil
521
+ }
522
+ client_batch = call.run_batch(client_ops)
523
+ expect(client_batch.send_metadata).to be true
524
+ expect(client_batch.send_close).to be true
525
+
526
+ # server gets the invocation but sends no metadata back
527
+ rcv_thread.join
528
+ expect(recvd_rpc).to_not eq nil
529
+ server_call = recvd_rpc.call
530
+ server_ops = {
531
+ CallOps::RECV_CLOSE_ON_SERVER => nil,
532
+ CallOps::SEND_INITIAL_METADATA => md,
533
+ CallOps::SEND_STATUS_FROM_SERVER => ok_status
534
+ }
535
+ srv_batch = server_call.run_batch(server_ops)
536
+ expect(srv_batch.send_close).to be true
537
+ expect(srv_batch.send_metadata).to be true
538
+ expect(srv_batch.send_status).to be true
539
+
540
+ # client receives nothing as expected
541
+ client_ops = {
542
+ CallOps::RECV_INITIAL_METADATA => nil,
543
+ CallOps::RECV_STATUS_ON_CLIENT => nil
544
+ }
545
+ final_client_batch = call.run_batch(client_ops)
546
+ replace_symbols = Hash[md.each_pair.collect { |x, y| [x.to_s, y] }]
547
+ expect(final_client_batch.metadata).to eq(replace_symbols)
548
+ expect(final_client_batch.status.code).to eq(0)
549
+ end
550
+ end
551
+ end
552
+ end
553
+
554
+ describe 'the http client/server' do
555
+ before(:example) do
556
+ server_host = '0.0.0.0:0'
557
+ @server = new_core_server_for_testing(nil)
558
+ server_port = @server.add_http2_port(server_host, :this_port_is_insecure)
559
+ @server.start
560
+ @ch = Channel.new("0.0.0.0:#{server_port}", nil, :this_channel_is_insecure)
561
+ end
562
+
563
+ after(:example) do
564
+ @ch.close
565
+ @server.shutdown_and_notify(deadline)
566
+ @server.close
567
+ end
568
+
569
+ it_behaves_like 'basic GRPC message delivery is OK' do
570
+ end
571
+
572
+ it_behaves_like 'GRPC metadata delivery works OK' do
573
+ end
574
+ end
575
+
576
+ describe 'the secure http client/server' do
577
+ include_context 'setup: tags'
578
+
579
+ def load_test_certs
580
+ test_root = File.join(File.dirname(__FILE__), 'testdata')
581
+ files = ['ca.pem', 'server1.key', 'server1.pem']
582
+ files.map { |f| File.open(File.join(test_root, f)).read }
583
+ end
584
+
585
+ before(:example) do
586
+ certs = load_test_certs
587
+ server_host = '0.0.0.0:0'
588
+ server_creds = GRPC::Core::ServerCredentials.new(
589
+ nil, [{ private_key: certs[1], cert_chain: certs[2] }], false)
590
+ @server = new_core_server_for_testing(nil)
591
+ server_port = @server.add_http2_port(server_host, server_creds)
592
+ @server.start
593
+ args = { Channel::SSL_TARGET => 'foo.test.google.fr' }
594
+ @ch = Channel.new("0.0.0.0:#{server_port}", args,
595
+ GRPC::Core::ChannelCredentials.new(certs[0], nil, nil))
596
+ end
597
+
598
+ after(:example) do
599
+ @server.shutdown_and_notify(deadline)
600
+ @server.close
601
+ end
602
+
603
+ it_behaves_like 'basic GRPC message delivery is OK' do
604
+ end
605
+
606
+ it_behaves_like 'GRPC metadata delivery works OK' do
607
+ end
608
+
609
+ def credentials_update_test(creds_update_md)
610
+ auth_proc = proc { creds_update_md }
611
+ call_creds = GRPC::Core::CallCredentials.new(auth_proc)
612
+
613
+ initial_md_key = 'k2'
614
+ initial_md_val = 'v2'
615
+ initial_md = { initial_md_key => initial_md_val }
616
+ expected_md = creds_update_md.clone
617
+ fail 'bad test param' unless expected_md[initial_md_key].nil?
618
+ expected_md[initial_md_key] = initial_md_val
619
+
620
+ recvd_rpc = nil
621
+ rcv_thread = Thread.new do
622
+ recvd_rpc = @server.request_call
623
+ end
624
+
625
+ call = new_client_call
626
+ call.set_credentials! call_creds
627
+
628
+ client_batch = call.run_batch(
629
+ CallOps::SEND_INITIAL_METADATA => initial_md,
630
+ CallOps::SEND_CLOSE_FROM_CLIENT => nil)
631
+ expect(client_batch.send_metadata).to be true
632
+ expect(client_batch.send_close).to be true
633
+
634
+ # confirm the server can receive the client metadata
635
+ rcv_thread.join
636
+ expect(recvd_rpc).to_not eq nil
637
+ recvd_md = recvd_rpc.metadata
638
+ replace_symbols = Hash[expected_md.each_pair.collect { |x, y| [x.to_s, y] }]
639
+ expect(recvd_md).to eq(recvd_md.merge(replace_symbols))
640
+
641
+ credentials_update_test_finish_call(call, recvd_rpc.call)
642
+ end
643
+
644
+ def credentials_update_test_finish_call(client_call, server_call)
645
+ final_server_batch = server_call.run_batch(
646
+ CallOps::RECV_CLOSE_ON_SERVER => nil,
647
+ CallOps::SEND_INITIAL_METADATA => nil,
648
+ CallOps::SEND_STATUS_FROM_SERVER => ok_status)
649
+ expect(final_server_batch.send_close).to be(true)
650
+ expect(final_server_batch.send_metadata).to be(true)
651
+ expect(final_server_batch.send_status).to be(true)
652
+
653
+ final_client_batch = client_call.run_batch(
654
+ CallOps::RECV_INITIAL_METADATA => nil,
655
+ CallOps::RECV_STATUS_ON_CLIENT => nil)
656
+ expect(final_client_batch.metadata).to eq({})
657
+ expect(final_client_batch.status.code).to eq(0)
658
+ end
659
+
660
+ it 'modifies metadata with CallCredentials' do
661
+ credentials_update_test('k1' => 'updated-v1')
662
+ end
663
+
664
+ it 'modifies large metadata with CallCredentials' do
665
+ val_array = %w(
666
+ '00000000000000000000000000000000000000000000000000000000000000',
667
+ '11111111111111111111111111111111111111111111111111111111111111',
668
+ )
669
+ md = {
670
+ k3: val_array,
671
+ k4: '0000000000000000000000000000000000000000000000000000000000',
672
+ keeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeey5: 'v1'
673
+ }
674
+ credentials_update_test(md)
675
+ end
676
+ end