grpc 1.60.0.pre1-aarch64-linux

Sign up to get free protection for your applications and to get access to all the features.
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