grpc 1.30.2-x64-mingw32

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

Potentially problematic release.


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

Files changed (121) hide show
  1. checksums.yaml +7 -0
  2. data/etc/roots.pem +4644 -0
  3. data/grpc_c.32.ruby +0 -0
  4. data/grpc_c.64.ruby +0 -0
  5. data/src/ruby/bin/math_client.rb +140 -0
  6. data/src/ruby/bin/math_pb.rb +34 -0
  7. data/src/ruby/bin/math_server.rb +191 -0
  8. data/src/ruby/bin/math_services_pb.rb +51 -0
  9. data/src/ruby/bin/noproto_client.rb +93 -0
  10. data/src/ruby/bin/noproto_server.rb +97 -0
  11. data/src/ruby/ext/grpc/ext-export.clang +1 -0
  12. data/src/ruby/ext/grpc/ext-export.gcc +6 -0
  13. data/src/ruby/ext/grpc/extconf.rb +107 -0
  14. data/src/ruby/ext/grpc/rb_byte_buffer.c +64 -0
  15. data/src/ruby/ext/grpc/rb_byte_buffer.h +35 -0
  16. data/src/ruby/ext/grpc/rb_call.c +1050 -0
  17. data/src/ruby/ext/grpc/rb_call.h +53 -0
  18. data/src/ruby/ext/grpc/rb_call_credentials.c +297 -0
  19. data/src/ruby/ext/grpc/rb_call_credentials.h +31 -0
  20. data/src/ruby/ext/grpc/rb_channel.c +835 -0
  21. data/src/ruby/ext/grpc/rb_channel.h +34 -0
  22. data/src/ruby/ext/grpc/rb_channel_args.c +155 -0
  23. data/src/ruby/ext/grpc/rb_channel_args.h +38 -0
  24. data/src/ruby/ext/grpc/rb_channel_credentials.c +267 -0
  25. data/src/ruby/ext/grpc/rb_channel_credentials.h +32 -0
  26. data/src/ruby/ext/grpc/rb_completion_queue.c +100 -0
  27. data/src/ruby/ext/grpc/rb_completion_queue.h +36 -0
  28. data/src/ruby/ext/grpc/rb_compression_options.c +470 -0
  29. data/src/ruby/ext/grpc/rb_compression_options.h +29 -0
  30. data/src/ruby/ext/grpc/rb_enable_cpp.cc +22 -0
  31. data/src/ruby/ext/grpc/rb_event_thread.c +143 -0
  32. data/src/ruby/ext/grpc/rb_event_thread.h +21 -0
  33. data/src/ruby/ext/grpc/rb_grpc.c +328 -0
  34. data/src/ruby/ext/grpc/rb_grpc.h +76 -0
  35. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +573 -0
  36. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +865 -0
  37. data/src/ruby/ext/grpc/rb_loader.c +57 -0
  38. data/src/ruby/ext/grpc/rb_loader.h +25 -0
  39. data/src/ruby/ext/grpc/rb_server.c +372 -0
  40. data/src/ruby/ext/grpc/rb_server.h +32 -0
  41. data/src/ruby/ext/grpc/rb_server_credentials.c +243 -0
  42. data/src/ruby/ext/grpc/rb_server_credentials.h +32 -0
  43. data/src/ruby/lib/grpc.rb +37 -0
  44. data/src/ruby/lib/grpc/2.3/grpc_c.so +0 -0
  45. data/src/ruby/lib/grpc/2.4/grpc_c.so +0 -0
  46. data/src/ruby/lib/grpc/2.5/grpc_c.so +0 -0
  47. data/src/ruby/lib/grpc/2.6/grpc_c.so +0 -0
  48. data/src/ruby/lib/grpc/2.7/grpc_c.so +0 -0
  49. data/src/ruby/lib/grpc/core/status_codes.rb +135 -0
  50. data/src/ruby/lib/grpc/core/time_consts.rb +56 -0
  51. data/src/ruby/lib/grpc/errors.rb +277 -0
  52. data/src/ruby/lib/grpc/generic/active_call.rb +669 -0
  53. data/src/ruby/lib/grpc/generic/bidi_call.rb +233 -0
  54. data/src/ruby/lib/grpc/generic/client_stub.rb +501 -0
  55. data/src/ruby/lib/grpc/generic/interceptor_registry.rb +53 -0
  56. data/src/ruby/lib/grpc/generic/interceptors.rb +186 -0
  57. data/src/ruby/lib/grpc/generic/rpc_desc.rb +204 -0
  58. data/src/ruby/lib/grpc/generic/rpc_server.rb +551 -0
  59. data/src/ruby/lib/grpc/generic/service.rb +211 -0
  60. data/src/ruby/lib/grpc/google_rpc_status_utils.rb +40 -0
  61. data/src/ruby/lib/grpc/grpc.rb +24 -0
  62. data/src/ruby/lib/grpc/logconfig.rb +44 -0
  63. data/src/ruby/lib/grpc/notifier.rb +45 -0
  64. data/src/ruby/lib/grpc/structs.rb +15 -0
  65. data/src/ruby/lib/grpc/version.rb +18 -0
  66. data/src/ruby/pb/README.md +42 -0
  67. data/src/ruby/pb/generate_proto_ruby.sh +51 -0
  68. data/src/ruby/pb/grpc/health/checker.rb +75 -0
  69. data/src/ruby/pb/grpc/health/v1/health_pb.rb +31 -0
  70. data/src/ruby/pb/grpc/health/v1/health_services_pb.rb +62 -0
  71. data/src/ruby/pb/grpc/testing/duplicate/echo_duplicate_services_pb.rb +44 -0
  72. data/src/ruby/pb/grpc/testing/metrics_pb.rb +28 -0
  73. data/src/ruby/pb/grpc/testing/metrics_services_pb.rb +49 -0
  74. data/src/ruby/pb/src/proto/grpc/testing/empty_pb.rb +17 -0
  75. data/src/ruby/pb/src/proto/grpc/testing/messages_pb.rb +105 -0
  76. data/src/ruby/pb/src/proto/grpc/testing/test_pb.rb +16 -0
  77. data/src/ruby/pb/src/proto/grpc/testing/test_services_pb.rb +118 -0
  78. data/src/ruby/pb/test/client.rb +769 -0
  79. data/src/ruby/pb/test/server.rb +252 -0
  80. data/src/ruby/pb/test/xds_client.rb +213 -0
  81. data/src/ruby/spec/call_credentials_spec.rb +42 -0
  82. data/src/ruby/spec/call_spec.rb +180 -0
  83. data/src/ruby/spec/channel_connection_spec.rb +126 -0
  84. data/src/ruby/spec/channel_credentials_spec.rb +82 -0
  85. data/src/ruby/spec/channel_spec.rb +234 -0
  86. data/src/ruby/spec/client_auth_spec.rb +126 -0
  87. data/src/ruby/spec/client_server_spec.rb +664 -0
  88. data/src/ruby/spec/compression_options_spec.rb +149 -0
  89. data/src/ruby/spec/debug_message_spec.rb +134 -0
  90. data/src/ruby/spec/error_sanity_spec.rb +49 -0
  91. data/src/ruby/spec/errors_spec.rb +142 -0
  92. data/src/ruby/spec/generic/active_call_spec.rb +672 -0
  93. data/src/ruby/spec/generic/client_interceptors_spec.rb +153 -0
  94. data/src/ruby/spec/generic/client_stub_spec.rb +1083 -0
  95. data/src/ruby/spec/generic/interceptor_registry_spec.rb +65 -0
  96. data/src/ruby/spec/generic/rpc_desc_spec.rb +374 -0
  97. data/src/ruby/spec/generic/rpc_server_pool_spec.rb +127 -0
  98. data/src/ruby/spec/generic/rpc_server_spec.rb +748 -0
  99. data/src/ruby/spec/generic/server_interceptors_spec.rb +218 -0
  100. data/src/ruby/spec/generic/service_spec.rb +263 -0
  101. data/src/ruby/spec/google_rpc_status_utils_spec.rb +282 -0
  102. data/src/ruby/spec/pb/codegen/grpc/testing/package_options.proto +28 -0
  103. data/src/ruby/spec/pb/codegen/grpc/testing/package_options_import.proto +22 -0
  104. data/src/ruby/spec/pb/codegen/grpc/testing/package_options_import2.proto +23 -0
  105. data/src/ruby/spec/pb/codegen/grpc/testing/package_options_ruby_style.proto +41 -0
  106. data/src/ruby/spec/pb/codegen/package_option_spec.rb +82 -0
  107. data/src/ruby/spec/pb/duplicate/codegen_spec.rb +57 -0
  108. data/src/ruby/spec/pb/health/checker_spec.rb +236 -0
  109. data/src/ruby/spec/server_credentials_spec.rb +79 -0
  110. data/src/ruby/spec/server_spec.rb +209 -0
  111. data/src/ruby/spec/spec_helper.rb +61 -0
  112. data/src/ruby/spec/support/helpers.rb +107 -0
  113. data/src/ruby/spec/support/services.rb +160 -0
  114. data/src/ruby/spec/testdata/README +1 -0
  115. data/src/ruby/spec/testdata/ca.pem +20 -0
  116. data/src/ruby/spec/testdata/client.key +28 -0
  117. data/src/ruby/spec/testdata/client.pem +20 -0
  118. data/src/ruby/spec/testdata/server1.key +28 -0
  119. data/src/ruby/spec/testdata/server1.pem +22 -0
  120. data/src/ruby/spec/time_consts_spec.rb +74 -0
  121. metadata +394 -0
@@ -0,0 +1,672 @@
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::StatusCodes
18
+
19
+ describe GRPC::ActiveCall do
20
+ ActiveCall = GRPC::ActiveCall
21
+ Call = GRPC::Core::Call
22
+ CallOps = GRPC::Core::CallOps
23
+ WriteFlags = GRPC::Core::WriteFlags
24
+
25
+ def ok_status
26
+ Struct::Status.new(OK, 'OK')
27
+ end
28
+
29
+ def send_and_receive_close_and_status(client_call, server_call)
30
+ client_call.run_batch(CallOps::SEND_CLOSE_FROM_CLIENT => nil)
31
+ server_call.run_batch(CallOps::RECV_CLOSE_ON_SERVER => nil,
32
+ CallOps::SEND_STATUS_FROM_SERVER => ok_status)
33
+ client_call.run_batch(CallOps::RECV_STATUS_ON_CLIENT => nil)
34
+ end
35
+
36
+ def inner_call_of_active_call(active_call)
37
+ active_call.instance_variable_get(:@call)
38
+ end
39
+
40
+ before(:each) do
41
+ @pass_through = proc { |x| x }
42
+ host = '0.0.0.0:0'
43
+ @server = new_core_server_for_testing(nil)
44
+ server_port = @server.add_http2_port(host, :this_port_is_insecure)
45
+ @server.start
46
+ @ch = GRPC::Core::Channel.new("0.0.0.0:#{server_port}", nil,
47
+ :this_channel_is_insecure)
48
+ end
49
+
50
+ after(:each) do
51
+ @server.shutdown_and_notify(deadline)
52
+ @server.close
53
+ end
54
+
55
+ describe 'restricted view methods' do
56
+ before(:each) do
57
+ call = make_test_call
58
+ ActiveCall.client_invoke(call)
59
+ @client_call = ActiveCall.new(call, @pass_through,
60
+ @pass_through, deadline)
61
+ end
62
+
63
+ describe '#multi_req_view' do
64
+ it 'exposes a fixed subset of the ActiveCall.methods' do
65
+ want = %w(cancelled?, deadline, each_remote_read, metadata, \
66
+ shutdown, peer, peer_cert, send_initial_metadata, \
67
+ initial_metadata_sent)
68
+ v = @client_call.multi_req_view
69
+ want.each do |w|
70
+ expect(v.methods.include?(w))
71
+ end
72
+ end
73
+ end
74
+
75
+ describe '#single_req_view' do
76
+ it 'exposes a fixed subset of the ActiveCall.methods' do
77
+ want = %w(cancelled?, deadline, metadata, shutdown, \
78
+ send_initial_metadata, metadata_to_send, \
79
+ merge_metadata_to_send, initial_metadata_sent)
80
+ v = @client_call.single_req_view
81
+ want.each do |w|
82
+ expect(v.methods.include?(w))
83
+ end
84
+ end
85
+ end
86
+
87
+ describe '#interceptable' do
88
+ it 'exposes a fixed subset of the ActiveCall.methods' do
89
+ want = %w(deadline)
90
+ v = @client_call.interceptable
91
+ want.each do |w|
92
+ expect(v.methods.include?(w))
93
+ end
94
+ end
95
+ end
96
+ end
97
+
98
+ describe '#remote_send' do
99
+ it 'allows a client to send a payload to the server', test: true do
100
+ call = make_test_call
101
+ ActiveCall.client_invoke(call)
102
+ client_call = ActiveCall.new(call, @pass_through,
103
+ @pass_through, deadline)
104
+ msg = 'message is a string'
105
+ client_call.remote_send(msg)
106
+
107
+ # check that server rpc new was received
108
+ recvd_rpc = @server.request_call
109
+ expect(recvd_rpc).to_not eq nil
110
+ recvd_call = recvd_rpc.call
111
+
112
+ # Accept the call, and verify that the server reads the response ok.
113
+ server_call = ActiveCall.new(recvd_call, @pass_through,
114
+ @pass_through, deadline,
115
+ metadata_received: true,
116
+ started: false)
117
+ expect(server_call.remote_read).to eq(msg)
118
+ # finish the call
119
+ server_call.send_initial_metadata
120
+ call.run_batch(CallOps::RECV_INITIAL_METADATA => nil)
121
+ send_and_receive_close_and_status(call, recvd_call)
122
+ end
123
+
124
+ it 'marshals the payload using the marshal func' do
125
+ call = make_test_call
126
+ ActiveCall.client_invoke(call)
127
+ marshal = proc { |x| 'marshalled:' + x }
128
+ client_call = ActiveCall.new(call, marshal, @pass_through, deadline)
129
+ msg = 'message is a string'
130
+ client_call.remote_send(msg)
131
+
132
+ # confirm that the message was marshalled
133
+ recvd_rpc = @server.request_call
134
+ recvd_call = recvd_rpc.call
135
+ server_ops = {
136
+ CallOps::SEND_INITIAL_METADATA => nil
137
+ }
138
+ recvd_call.run_batch(server_ops)
139
+ server_call = ActiveCall.new(recvd_call, @pass_through,
140
+ @pass_through, deadline,
141
+ metadata_received: true)
142
+ expect(server_call.remote_read).to eq('marshalled:' + msg)
143
+ # finish the call
144
+ call.run_batch(CallOps::RECV_INITIAL_METADATA => nil)
145
+ send_and_receive_close_and_status(call, recvd_call)
146
+ end
147
+
148
+ TEST_WRITE_FLAGS = [WriteFlags::BUFFER_HINT, WriteFlags::NO_COMPRESS]
149
+ TEST_WRITE_FLAGS.each do |f|
150
+ it "successfully makes calls with write_flag set to #{f}" do
151
+ call = make_test_call
152
+ ActiveCall.client_invoke(call)
153
+ marshal = proc { |x| 'marshalled:' + x }
154
+ client_call = ActiveCall.new(call, marshal,
155
+ @pass_through, deadline)
156
+ msg = 'message is a string'
157
+ client_call.write_flag = f
158
+ client_call.remote_send(msg)
159
+ # flush the message in case writes are set to buffered
160
+ call.run_batch(CallOps::SEND_CLOSE_FROM_CLIENT => nil) if f == 1
161
+
162
+ # confirm that the message was marshalled
163
+ recvd_rpc = @server.request_call
164
+ recvd_call = recvd_rpc.call
165
+ server_ops = {
166
+ CallOps::SEND_INITIAL_METADATA => nil
167
+ }
168
+ recvd_call.run_batch(server_ops)
169
+ server_call = ActiveCall.new(recvd_call, @pass_through,
170
+ @pass_through, deadline,
171
+ metadata_received: true)
172
+ expect(server_call.remote_read).to eq('marshalled:' + msg)
173
+ # finish the call
174
+ server_call.send_status(OK, '', true)
175
+ client_call.receive_and_check_status
176
+ end
177
+ end
178
+ end
179
+
180
+ describe 'sending initial metadata', send_initial_metadata: true do
181
+ it 'sends metadata before sending a message if it hasnt been sent yet' do
182
+ call = make_test_call
183
+ @client_call = ActiveCall.new(
184
+ call,
185
+ @pass_through,
186
+ @pass_through,
187
+ deadline,
188
+ started: false)
189
+
190
+ metadata = { key: 'dummy_val', other: 'other_val' }
191
+ expect(@client_call.metadata_sent).to eq(false)
192
+ @client_call.merge_metadata_to_send(metadata)
193
+
194
+ message = 'dummy message'
195
+
196
+ expect(call).to(
197
+ receive(:run_batch)
198
+ .with(
199
+ hash_including(
200
+ CallOps::SEND_INITIAL_METADATA => metadata)).once)
201
+
202
+ expect(call).to(
203
+ receive(:run_batch).with(hash_including(
204
+ CallOps::SEND_MESSAGE => message)).once)
205
+ @client_call.remote_send(message)
206
+
207
+ expect(@client_call.metadata_sent).to eq(true)
208
+ end
209
+
210
+ it 'doesnt send metadata if it thinks its already been sent' do
211
+ call = make_test_call
212
+
213
+ @client_call = ActiveCall.new(call,
214
+ @pass_through,
215
+ @pass_through,
216
+ deadline)
217
+ expect(@client_call.metadata_sent).to eql(true)
218
+ expect(call).to(
219
+ receive(:run_batch).with(hash_including(
220
+ CallOps::SEND_INITIAL_METADATA)).never)
221
+
222
+ @client_call.remote_send('test message')
223
+ end
224
+
225
+ it 'sends metadata if it is explicitly sent and ok to do so' do
226
+ call = make_test_call
227
+
228
+ @client_call = ActiveCall.new(call,
229
+ @pass_through,
230
+ @pass_through,
231
+ deadline,
232
+ started: false)
233
+
234
+ expect(@client_call.metadata_sent).to eql(false)
235
+
236
+ metadata = { test_key: 'val' }
237
+ @client_call.merge_metadata_to_send(metadata)
238
+ expect(@client_call.metadata_to_send).to eq(metadata)
239
+
240
+ expect(call).to(
241
+ receive(:run_batch).with(hash_including(
242
+ CallOps::SEND_INITIAL_METADATA =>
243
+ metadata)).once)
244
+ @client_call.send_initial_metadata
245
+ end
246
+
247
+ it 'explicit sending does nothing if metadata has already been sent' do
248
+ call = make_test_call
249
+
250
+ @client_call = ActiveCall.new(call,
251
+ @pass_through,
252
+ @pass_through,
253
+ deadline)
254
+
255
+ expect(@client_call.metadata_sent).to eql(true)
256
+
257
+ blk = proc do
258
+ @client_call.send_initial_metadata
259
+ end
260
+
261
+ expect { blk.call }.to_not raise_error
262
+ end
263
+ end
264
+
265
+ describe '#merge_metadata_to_send', merge_metadata_to_send: true do
266
+ it 'adds to existing metadata when there is existing metadata to send' do
267
+ call = make_test_call
268
+ starting_metadata = {
269
+ k1: 'key1_val',
270
+ k2: 'key2_val',
271
+ k3: 'key3_val'
272
+ }
273
+
274
+ @client_call = ActiveCall.new(
275
+ call,
276
+ @pass_through, @pass_through,
277
+ deadline,
278
+ started: false,
279
+ metadata_to_send: starting_metadata)
280
+
281
+ expect(@client_call.metadata_to_send).to eq(starting_metadata)
282
+
283
+ @client_call.merge_metadata_to_send(
284
+ k3: 'key3_new_val',
285
+ k4: 'key4_val')
286
+
287
+ expected_md_to_send = {
288
+ k1: 'key1_val',
289
+ k2: 'key2_val',
290
+ k3: 'key3_new_val',
291
+ k4: 'key4_val' }
292
+
293
+ expect(@client_call.metadata_to_send).to eq(expected_md_to_send)
294
+
295
+ @client_call.merge_metadata_to_send(k5: 'key5_val')
296
+ expected_md_to_send.merge!(k5: 'key5_val')
297
+ expect(@client_call.metadata_to_send).to eq(expected_md_to_send)
298
+ end
299
+
300
+ it 'fails when initial metadata has already been sent' do
301
+ call = make_test_call
302
+ @client_call = ActiveCall.new(
303
+ call,
304
+ @pass_through,
305
+ @pass_through,
306
+ deadline,
307
+ started: true)
308
+
309
+ expect(@client_call.metadata_sent).to eq(true)
310
+
311
+ blk = proc do
312
+ @client_call.merge_metadata_to_send(k1: 'key1_val')
313
+ end
314
+
315
+ expect { blk.call }.to raise_error
316
+ end
317
+ end
318
+
319
+ describe '#client_invoke' do
320
+ it 'sends metadata to the server when present' do
321
+ call = make_test_call
322
+ metadata = { k1: 'v1', k2: 'v2' }
323
+ ActiveCall.client_invoke(call, metadata)
324
+ recvd_rpc = @server.request_call
325
+ recvd_call = recvd_rpc.call
326
+ expect(recvd_call).to_not be_nil
327
+ expect(recvd_rpc.metadata).to_not be_nil
328
+ expect(recvd_rpc.metadata['k1']).to eq('v1')
329
+ expect(recvd_rpc.metadata['k2']).to eq('v2')
330
+ # finish the call
331
+ recvd_call.run_batch(CallOps::SEND_INITIAL_METADATA => {})
332
+ call.run_batch(CallOps::RECV_INITIAL_METADATA => nil)
333
+ send_and_receive_close_and_status(call, recvd_call)
334
+ end
335
+ end
336
+
337
+ describe '#send_status', send_status: true do
338
+ it 'works when no metadata or messages have been sent yet' do
339
+ call = make_test_call
340
+ ActiveCall.client_invoke(call)
341
+
342
+ recvd_rpc = @server.request_call
343
+ server_call = ActiveCall.new(
344
+ recvd_rpc.call,
345
+ @pass_through,
346
+ @pass_through,
347
+ deadline,
348
+ started: false)
349
+
350
+ expect(server_call.metadata_sent).to eq(false)
351
+ blk = proc { server_call.send_status(OK) }
352
+ expect { blk.call }.to_not raise_error
353
+ end
354
+ end
355
+
356
+ describe '#remote_read', remote_read: true do
357
+ it 'reads the response sent by a server' do
358
+ call = make_test_call
359
+ ActiveCall.client_invoke(call)
360
+ client_call = ActiveCall.new(call, @pass_through,
361
+ @pass_through, deadline)
362
+ msg = 'message is a string'
363
+ client_call.remote_send(msg)
364
+ server_call = expect_server_to_receive(msg)
365
+ server_call.remote_send('server_response')
366
+ expect(client_call.remote_read).to eq('server_response')
367
+ send_and_receive_close_and_status(
368
+ call, inner_call_of_active_call(server_call))
369
+ end
370
+
371
+ it 'saves no metadata when the server adds no metadata' do
372
+ call = make_test_call
373
+ ActiveCall.client_invoke(call)
374
+ client_call = ActiveCall.new(call, @pass_through,
375
+ @pass_through, deadline)
376
+ msg = 'message is a string'
377
+ client_call.remote_send(msg)
378
+ server_call = expect_server_to_receive(msg)
379
+ server_call.remote_send('ignore me')
380
+ expect(client_call.metadata).to be_nil
381
+ client_call.remote_read
382
+ expect(client_call.metadata).to eq({})
383
+ send_and_receive_close_and_status(
384
+ call, inner_call_of_active_call(server_call))
385
+ end
386
+
387
+ it 'saves metadata add by the server' do
388
+ call = make_test_call
389
+ ActiveCall.client_invoke(call)
390
+ client_call = ActiveCall.new(call, @pass_through,
391
+ @pass_through, deadline)
392
+ msg = 'message is a string'
393
+ client_call.remote_send(msg)
394
+ server_call = expect_server_to_receive(msg, k1: 'v1', k2: 'v2')
395
+ server_call.remote_send('ignore me')
396
+ expect(client_call.metadata).to be_nil
397
+ client_call.remote_read
398
+ expected = { 'k1' => 'v1', 'k2' => 'v2' }
399
+ expect(client_call.metadata).to eq(expected)
400
+ send_and_receive_close_and_status(
401
+ call, inner_call_of_active_call(server_call))
402
+ end
403
+
404
+ it 'get a status from server when nothing else sent from server' do
405
+ client_call = make_test_call
406
+ ActiveCall.client_invoke(client_call)
407
+
408
+ recvd_rpc = @server.request_call
409
+ recvd_call = recvd_rpc.call
410
+
411
+ server_call = ActiveCall.new(
412
+ recvd_call,
413
+ @pass_through,
414
+ @pass_through,
415
+ deadline,
416
+ started: false)
417
+
418
+ server_call.send_status(OK, 'OK')
419
+
420
+ # Check that we can receive initial metadata and a status
421
+ client_call.run_batch(
422
+ CallOps::RECV_INITIAL_METADATA => nil)
423
+ batch_result = client_call.run_batch(
424
+ CallOps::RECV_STATUS_ON_CLIENT => nil)
425
+
426
+ expect(batch_result.status.code).to eq(OK)
427
+ end
428
+
429
+ it 'get a nil msg before a status when an OK status is sent' do
430
+ call = make_test_call
431
+ ActiveCall.client_invoke(call)
432
+ client_call = ActiveCall.new(call, @pass_through,
433
+ @pass_through, deadline)
434
+ msg = 'message is a string'
435
+ client_call.remote_send(msg)
436
+ call.run_batch(CallOps::SEND_CLOSE_FROM_CLIENT => nil)
437
+ server_call = expect_server_to_receive(msg)
438
+ server_call.remote_send('server_response')
439
+ server_call.send_status(OK, 'OK')
440
+ expect(client_call.remote_read).to eq('server_response')
441
+ res = client_call.remote_read
442
+ expect(res).to be_nil
443
+ end
444
+
445
+ it 'unmarshals the response using the unmarshal func' do
446
+ call = make_test_call
447
+ ActiveCall.client_invoke(call)
448
+ unmarshal = proc { |x| 'unmarshalled:' + x }
449
+ client_call = ActiveCall.new(call, @pass_through,
450
+ unmarshal, deadline)
451
+
452
+ # confirm the client receives the unmarshalled message
453
+ msg = 'message is a string'
454
+ client_call.remote_send(msg)
455
+ server_call = expect_server_to_receive(msg)
456
+ server_call.remote_send('server_response')
457
+ expect(client_call.remote_read).to eq('unmarshalled:server_response')
458
+ send_and_receive_close_and_status(
459
+ call, inner_call_of_active_call(server_call))
460
+ end
461
+ end
462
+
463
+ describe '#each_remote_read' do
464
+ it 'creates an Enumerator' do
465
+ call = make_test_call
466
+ client_call = ActiveCall.new(call, @pass_through,
467
+ @pass_through, deadline)
468
+ expect(client_call.each_remote_read).to be_a(Enumerator)
469
+ # finish the call
470
+ client_call.cancel
471
+ end
472
+
473
+ it 'the returned enumerator can read n responses' do
474
+ call = make_test_call
475
+ ActiveCall.client_invoke(call)
476
+ client_call = ActiveCall.new(call, @pass_through,
477
+ @pass_through, deadline)
478
+ msg = 'message is a string'
479
+ reply = 'server_response'
480
+ client_call.remote_send(msg)
481
+ server_call = expect_server_to_receive(msg)
482
+ e = client_call.each_remote_read
483
+ n = 3 # arbitrary value > 1
484
+ n.times do
485
+ server_call.remote_send(reply)
486
+ expect(e.next).to eq(reply)
487
+ end
488
+ send_and_receive_close_and_status(
489
+ call, inner_call_of_active_call(server_call))
490
+ end
491
+
492
+ it 'the returns an enumerator that stops after an OK Status' do
493
+ call = make_test_call
494
+ ActiveCall.client_invoke(call)
495
+ client_call = ActiveCall.new(call, @pass_through,
496
+ @pass_through, deadline)
497
+ msg = 'message is a string'
498
+ reply = 'server_response'
499
+ client_call.remote_send(msg)
500
+ call.run_batch(CallOps::SEND_CLOSE_FROM_CLIENT => nil)
501
+ server_call = expect_server_to_receive(msg)
502
+ e = client_call.each_remote_read
503
+ n = 3 # arbitrary value > 1
504
+ n.times do
505
+ server_call.remote_send(reply)
506
+ expect(e.next).to eq(reply)
507
+ end
508
+ server_call.send_status(OK, 'OK', true)
509
+ expect { e.next }.to raise_error(StopIteration)
510
+ end
511
+ end
512
+
513
+ describe '#closing the call from the client' do
514
+ it 'finishes ok if the server sends a status response' do
515
+ call = make_test_call
516
+ ActiveCall.client_invoke(call)
517
+ client_call = ActiveCall.new(call, @pass_through,
518
+ @pass_through, deadline)
519
+ msg = 'message is a string'
520
+ client_call.remote_send(msg)
521
+ expect do
522
+ call.run_batch(CallOps::SEND_CLOSE_FROM_CLIENT => nil)
523
+ end.to_not raise_error
524
+ server_call = expect_server_to_receive(msg)
525
+ server_call.remote_send('server_response')
526
+ expect(client_call.remote_read).to eq('server_response')
527
+ server_call.send_status(OK, 'status code is OK')
528
+ expect { client_call.receive_and_check_status }.to_not raise_error
529
+ end
530
+
531
+ it 'finishes ok if the server sends an early status response' do
532
+ call = make_test_call
533
+ ActiveCall.client_invoke(call)
534
+ client_call = ActiveCall.new(call, @pass_through,
535
+ @pass_through, deadline)
536
+ msg = 'message is a string'
537
+ client_call.remote_send(msg)
538
+ server_call = expect_server_to_receive(msg)
539
+ server_call.remote_send('server_response')
540
+ server_call.send_status(OK, 'status code is OK')
541
+ expect(client_call.remote_read).to eq('server_response')
542
+ expect do
543
+ call.run_batch(CallOps::SEND_CLOSE_FROM_CLIENT => nil)
544
+ end.to_not raise_error
545
+ expect { client_call.receive_and_check_status }.to_not raise_error
546
+ end
547
+
548
+ it 'finishes ok if SEND_CLOSE and RECV_STATUS has been sent' do
549
+ call = make_test_call
550
+ ActiveCall.client_invoke(call)
551
+ client_call = ActiveCall.new(call, @pass_through,
552
+ @pass_through, deadline)
553
+ msg = 'message is a string'
554
+ client_call.remote_send(msg)
555
+ server_call = expect_server_to_receive(msg)
556
+ server_call.remote_send('server_response')
557
+ server_call.send_status(OK, 'status code is OK')
558
+ expect(client_call.remote_read).to eq('server_response')
559
+ expect do
560
+ call.run_batch(
561
+ CallOps::SEND_CLOSE_FROM_CLIENT => nil,
562
+ CallOps::RECV_STATUS_ON_CLIENT => nil)
563
+ end.to_not raise_error
564
+ end
565
+ end
566
+
567
+ # Test sending of the initial metadata in #run_server_bidi
568
+ # from the server handler both implicitly and explicitly.
569
+ describe '#run_server_bidi metadata sending tests', run_server_bidi: true do
570
+ before(:each) do
571
+ @requests = ['first message', 'second message']
572
+ @server_to_client_metadata = { 'test_key' => 'test_val' }
573
+ @server_status = OK
574
+
575
+ @client_call = make_test_call
576
+ @client_call.run_batch(CallOps::SEND_INITIAL_METADATA => {})
577
+
578
+ recvd_rpc = @server.request_call
579
+ recvd_call = recvd_rpc.call
580
+ @server_call = ActiveCall.new(
581
+ recvd_call,
582
+ @pass_through,
583
+ @pass_through,
584
+ deadline,
585
+ metadata_received: true,
586
+ started: false,
587
+ metadata_to_send: @server_to_client_metadata)
588
+ end
589
+
590
+ after(:each) do
591
+ # Send the requests and send a close so the server can send a status
592
+ @requests.each do |message|
593
+ @client_call.run_batch(CallOps::SEND_MESSAGE => message)
594
+ end
595
+ @client_call.run_batch(CallOps::SEND_CLOSE_FROM_CLIENT => nil)
596
+
597
+ @server_thread.join
598
+
599
+ # Expect that initial metadata was sent,
600
+ # the requests were echoed, and a status was sent
601
+ batch_result = @client_call.run_batch(
602
+ CallOps::RECV_INITIAL_METADATA => nil)
603
+ expect(batch_result.metadata).to eq(@server_to_client_metadata)
604
+
605
+ @requests.each do |message|
606
+ batch_result = @client_call.run_batch(
607
+ CallOps::RECV_MESSAGE => nil)
608
+ expect(batch_result.message).to eq(message)
609
+ end
610
+
611
+ batch_result = @client_call.run_batch(
612
+ CallOps::RECV_STATUS_ON_CLIENT => nil)
613
+ expect(batch_result.status.code).to eq(@server_status)
614
+ end
615
+
616
+ it 'sends the initial metadata implicitly if not already sent' do
617
+ # Server handler that doesn't have access to a "call"
618
+ # It echoes the requests
619
+ fake_gen_each_reply_with_no_call_param = proc do |msgs|
620
+ msgs
621
+ end
622
+
623
+ int_ctx = GRPC::InterceptionContext.new
624
+
625
+ @server_thread = Thread.new do
626
+ @server_call.run_server_bidi(
627
+ fake_gen_each_reply_with_no_call_param, int_ctx)
628
+ @server_call.send_status(@server_status)
629
+ end
630
+ end
631
+
632
+ it 'sends the metadata when sent explicitly and not already sent' do
633
+ # Fake server handler that has access to a "call" object and
634
+ # uses it to explicitly update and send the initial metadata
635
+ fake_gen_each_reply_with_call_param = proc do |msgs, call_param|
636
+ call_param.merge_metadata_to_send(@server_to_client_metadata)
637
+ call_param.send_initial_metadata
638
+ msgs
639
+ end
640
+ int_ctx = GRPC::InterceptionContext.new
641
+
642
+ @server_thread = Thread.new do
643
+ @server_call.run_server_bidi(
644
+ fake_gen_each_reply_with_call_param, int_ctx)
645
+ @server_call.send_status(@server_status)
646
+ end
647
+ end
648
+ end
649
+
650
+ def expect_server_to_receive(sent_text, **kw)
651
+ c = expect_server_to_be_invoked(**kw)
652
+ expect(c.remote_read).to eq(sent_text)
653
+ c
654
+ end
655
+
656
+ def expect_server_to_be_invoked(**kw)
657
+ recvd_rpc = @server.request_call
658
+ expect(recvd_rpc).to_not eq nil
659
+ recvd_call = recvd_rpc.call
660
+ recvd_call.run_batch(CallOps::SEND_INITIAL_METADATA => kw)
661
+ ActiveCall.new(recvd_call, @pass_through, @pass_through, deadline,
662
+ metadata_received: true, started: true)
663
+ end
664
+
665
+ def make_test_call
666
+ @ch.create_call(nil, nil, '/method', nil, deadline)
667
+ end
668
+
669
+ def deadline
670
+ Time.now + 2 # in 2 seconds; arbitrary
671
+ end
672
+ end