blob: d9df0b9ae246004f824bc4b7b2ac884d92c130cf [file] [log] [blame]
Craig Tiller6169d5f2016-03-31 07:46:18 -07001# Copyright 2015, Google Inc.
nnoble097ef9b2014-12-01 17:06:10 -08002# All rights reserved.
3#
4# Redistribution and use in source and binary forms, with or without
5# modification, are permitted provided that the following conditions are
6# met:
7#
8# * Redistributions of source code must retain the above copyright
9# notice, this list of conditions and the following disclaimer.
10# * Redistributions in binary form must reproduce the above
11# copyright notice, this list of conditions and the following disclaimer
12# in the documentation and/or other materials provided with the
13# distribution.
14# * Neither the name of Google Inc. nor the names of its
15# contributors may be used to endorse or promote products derived from
16# this software without specific prior written permission.
17#
18# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30require 'grpc'
nnoble097ef9b2014-12-01 17:06:10 -080031
nnoble0c475f02014-12-05 15:37:39 -080032include GRPC::Core
33
nnoble097ef9b2014-12-01 17:06:10 -080034shared_context 'setup: tags' do
Tim Emiola05e934f2015-03-28 15:19:34 -070035 let(:sent_message) { 'sent message' }
36 let(:reply_text) { 'the reply' }
nnoble097ef9b2014-12-01 17:06:10 -080037
38 def deadline
Tim Emiola391664a2015-08-31 15:38:43 -070039 Time.now + 5
nnoble097ef9b2014-12-01 17:06:10 -080040 end
41
yang-g2cecece2016-06-26 10:57:11 -070042 def server_allows_client_to_proceed(metadata = {})
murgatroid995ea4a992016-06-13 10:36:41 -070043 recvd_rpc = @server.request_call
Tim Emiola05e934f2015-03-28 15:19:34 -070044 expect(recvd_rpc).to_not eq nil
45 server_call = recvd_rpc.call
yang-g2cecece2016-06-26 10:57:11 -070046 ops = { CallOps::SEND_INITIAL_METADATA => metadata }
murgatroid995ea4a992016-06-13 10:36:41 -070047 svr_batch = server_call.run_batch(ops)
Tim Emiola05e934f2015-03-28 15:19:34 -070048 expect(svr_batch.send_metadata).to be true
Tim Emiola75d7f9a2015-01-26 16:57:33 -080049 server_call
50 end
51
nnoble097ef9b2014-12-01 17:06:10 -080052 def new_client_call
murgatroid995ea4a992016-06-13 10:36:41 -070053 @ch.create_call(nil, nil, '/method', nil, deadline)
nnoble097ef9b2014-12-01 17:06:10 -080054 end
nnoble097ef9b2014-12-01 17:06:10 -080055end
56
57shared_examples 'basic GRPC message delivery is OK' do
Tim Emiola05e934f2015-03-28 15:19:34 -070058 include GRPC::Core
nnoble097ef9b2014-12-01 17:06:10 -080059 include_context 'setup: tags'
60
Tim Emiola623a74d2015-08-11 09:24:20 -070061 context 'the test channel' do
62 it 'should have a target' do
63 expect(@ch.target).to be_a(String)
64 end
65 end
66
67 context 'a client call' do
68 it 'should have a peer' do
69 expect(new_client_call.peer).to be_a(String)
70 end
71 end
72
73 it 'calls have peer info' do
74 call = new_client_call
75 expect(call.peer).to be_a(String)
76 end
77
Tim Emiola05e934f2015-03-28 15:19:34 -070078 it 'servers receive requests from clients and can respond' do
nnoble097ef9b2014-12-01 17:06:10 -080079 call = new_client_call
Craig Tiller09600be2015-05-13 16:46:55 -070080 server_call = nil
81
82 server_thread = Thread.new do
83 server_call = server_allows_client_to_proceed
84 end
85
Tim Emiola05e934f2015-03-28 15:19:34 -070086 client_ops = {
87 CallOps::SEND_INITIAL_METADATA => {},
88 CallOps::SEND_MESSAGE => sent_message
89 }
murgatroid995ea4a992016-06-13 10:36:41 -070090 batch_result = call.run_batch(client_ops)
Tim Emiola05e934f2015-03-28 15:19:34 -070091 expect(batch_result.send_metadata).to be true
92 expect(batch_result.send_message).to be true
nnoble097ef9b2014-12-01 17:06:10 -080093
94 # confirm the server can read the inbound message
Craig Tiller09600be2015-05-13 16:46:55 -070095 server_thread.join
Tim Emiola05e934f2015-03-28 15:19:34 -070096 server_ops = {
97 CallOps::RECV_MESSAGE => nil
98 }
murgatroid995ea4a992016-06-13 10:36:41 -070099 svr_batch = server_call.run_batch(server_ops)
Tim Emiola05e934f2015-03-28 15:19:34 -0700100 expect(svr_batch.message).to eq(sent_message)
nnoble097ef9b2014-12-01 17:06:10 -0800101 end
102
103 it 'responses written by servers are received by the client' do
104 call = new_client_call
Craig Tiller09600be2015-05-13 16:46:55 -0700105 server_call = nil
106
107 server_thread = Thread.new do
108 server_call = server_allows_client_to_proceed
109 end
110
Tim Emiola05e934f2015-03-28 15:19:34 -0700111 client_ops = {
112 CallOps::SEND_INITIAL_METADATA => {},
113 CallOps::SEND_MESSAGE => sent_message
114 }
murgatroid995ea4a992016-06-13 10:36:41 -0700115 batch_result = call.run_batch(client_ops)
Tim Emiola05e934f2015-03-28 15:19:34 -0700116 expect(batch_result.send_metadata).to be true
117 expect(batch_result.send_message).to be true
nnoble097ef9b2014-12-01 17:06:10 -0800118
Tim Emiola05e934f2015-03-28 15:19:34 -0700119 # confirm the server can read the inbound message
Craig Tiller09600be2015-05-13 16:46:55 -0700120 server_thread.join
Tim Emiola05e934f2015-03-28 15:19:34 -0700121 server_ops = {
122 CallOps::RECV_MESSAGE => nil,
123 CallOps::SEND_MESSAGE => reply_text
124 }
murgatroid995ea4a992016-06-13 10:36:41 -0700125 svr_batch = server_call.run_batch(server_ops)
Tim Emiola05e934f2015-03-28 15:19:34 -0700126 expect(svr_batch.message).to eq(sent_message)
127 expect(svr_batch.send_message).to be true
nnoble097ef9b2014-12-01 17:06:10 -0800128 end
129
yang-g2cecece2016-06-26 10:57:11 -0700130 it 'compressed messages can be sent and received' do
131 call = new_client_call
132 server_call = nil
133 long_request_str = '0' * 2000
134 long_response_str = '1' * 2000
135 md = { 'grpc-internal-encoding-request' => 'gzip' }
136
137 server_thread = Thread.new do
138 server_call = server_allows_client_to_proceed(md)
139 end
140
141 client_ops = {
142 CallOps::SEND_INITIAL_METADATA => md,
143 CallOps::SEND_MESSAGE => long_request_str
144 }
murgatroid99d9d9ba92016-06-29 14:28:39 -0700145 batch_result = call.run_batch(client_ops)
yang-g2cecece2016-06-26 10:57:11 -0700146 expect(batch_result.send_metadata).to be true
147 expect(batch_result.send_message).to be true
148
149 # confirm the server can read the inbound message
150 server_thread.join
151 server_ops = {
152 CallOps::RECV_MESSAGE => nil,
153 CallOps::SEND_MESSAGE => long_response_str
154 }
murgatroid99d9d9ba92016-06-29 14:28:39 -0700155 svr_batch = server_call.run_batch(server_ops)
yang-g2cecece2016-06-26 10:57:11 -0700156 expect(svr_batch.message).to eq(long_request_str)
157 expect(svr_batch.send_message).to be true
158
159 client_ops = {
160 CallOps::SEND_CLOSE_FROM_CLIENT => nil,
161 CallOps::RECV_INITIAL_METADATA => nil,
162 CallOps::RECV_MESSAGE => nil
163 }
murgatroid99d9d9ba92016-06-29 14:28:39 -0700164 batch_result = call.run_batch(client_ops)
yang-g2cecece2016-06-26 10:57:11 -0700165 expect(batch_result.send_close).to be true
166 expect(batch_result.message).to eq long_response_str
167 end
168
nnoble097ef9b2014-12-01 17:06:10 -0800169 it 'servers can ignore a client write and send a status' do
nnoble097ef9b2014-12-01 17:06:10 -0800170 call = new_client_call
Craig Tiller09600be2015-05-13 16:46:55 -0700171 server_call = nil
172
173 server_thread = Thread.new do
174 server_call = server_allows_client_to_proceed
175 end
176
Tim Emiola05e934f2015-03-28 15:19:34 -0700177 client_ops = {
178 CallOps::SEND_INITIAL_METADATA => {},
179 CallOps::SEND_MESSAGE => sent_message
180 }
murgatroid995ea4a992016-06-13 10:36:41 -0700181 batch_result = call.run_batch(client_ops)
Tim Emiola05e934f2015-03-28 15:19:34 -0700182 expect(batch_result.send_metadata).to be true
183 expect(batch_result.send_message).to be true
nnoble097ef9b2014-12-01 17:06:10 -0800184
Tim Emiola05e934f2015-03-28 15:19:34 -0700185 # confirm the server can read the inbound message
186 the_status = Struct::Status.new(StatusCodes::OK, 'OK')
Craig Tiller09600be2015-05-13 16:46:55 -0700187 server_thread.join
Tim Emiola05e934f2015-03-28 15:19:34 -0700188 server_ops = {
189 CallOps::SEND_STATUS_FROM_SERVER => the_status
190 }
murgatroid995ea4a992016-06-13 10:36:41 -0700191 svr_batch = server_call.run_batch(server_ops)
Tim Emiola05e934f2015-03-28 15:19:34 -0700192 expect(svr_batch.message).to eq nil
193 expect(svr_batch.send_status).to be true
nnoble097ef9b2014-12-01 17:06:10 -0800194 end
195
196 it 'completes calls by sending status to client and server' do
197 call = new_client_call
Craig Tiller09600be2015-05-13 16:46:55 -0700198 server_call = nil
199
200 server_thread = Thread.new do
201 server_call = server_allows_client_to_proceed
202 end
203
Tim Emiola05e934f2015-03-28 15:19:34 -0700204 client_ops = {
205 CallOps::SEND_INITIAL_METADATA => {},
206 CallOps::SEND_MESSAGE => sent_message
207 }
murgatroid995ea4a992016-06-13 10:36:41 -0700208 batch_result = call.run_batch(client_ops)
Tim Emiola05e934f2015-03-28 15:19:34 -0700209 expect(batch_result.send_metadata).to be true
210 expect(batch_result.send_message).to be true
211
212 # confirm the server can read the inbound message and respond
213 the_status = Struct::Status.new(StatusCodes::OK, 'OK', {})
Craig Tiller09600be2015-05-13 16:46:55 -0700214 server_thread.join
Tim Emiola05e934f2015-03-28 15:19:34 -0700215 server_ops = {
216 CallOps::RECV_MESSAGE => nil,
217 CallOps::SEND_MESSAGE => reply_text,
218 CallOps::SEND_STATUS_FROM_SERVER => the_status
219 }
murgatroid995ea4a992016-06-13 10:36:41 -0700220 svr_batch = server_call.run_batch(server_ops)
Tim Emiola05e934f2015-03-28 15:19:34 -0700221 expect(svr_batch.message).to eq sent_message
222 expect(svr_batch.send_status).to be true
223 expect(svr_batch.send_message).to be true
nnoble097ef9b2014-12-01 17:06:10 -0800224
Tim Emiola05e934f2015-03-28 15:19:34 -0700225 # confirm the client can receive the server response and status.
226 client_ops = {
227 CallOps::SEND_CLOSE_FROM_CLIENT => nil,
murgatroid995738c502016-02-04 10:15:42 -0800228 CallOps::RECV_INITIAL_METADATA => nil,
Tim Emiola05e934f2015-03-28 15:19:34 -0700229 CallOps::RECV_MESSAGE => nil,
230 CallOps::RECV_STATUS_ON_CLIENT => nil
231 }
murgatroid995ea4a992016-06-13 10:36:41 -0700232 batch_result = call.run_batch(client_ops)
Tim Emiola05e934f2015-03-28 15:19:34 -0700233 expect(batch_result.send_close).to be true
234 expect(batch_result.message).to eq reply_text
235 expect(batch_result.status).to eq the_status
nnoble097ef9b2014-12-01 17:06:10 -0800236
Tim Emiola05e934f2015-03-28 15:19:34 -0700237 # confirm the server can receive the client close.
238 server_ops = {
239 CallOps::RECV_CLOSE_ON_SERVER => nil
240 }
murgatroid995ea4a992016-06-13 10:36:41 -0700241 svr_batch = server_call.run_batch(server_ops)
Tim Emiola05e934f2015-03-28 15:19:34 -0700242 expect(svr_batch.send_close).to be true
nnoble097ef9b2014-12-01 17:06:10 -0800243 end
nnoble097ef9b2014-12-01 17:06:10 -0800244end
245
nnoble097ef9b2014-12-01 17:06:10 -0800246shared_examples 'GRPC metadata delivery works OK' do
nnoble097ef9b2014-12-01 17:06:10 -0800247 include_context 'setup: tags'
248
249 describe 'from client => server' do
nnoble097ef9b2014-12-01 17:06:10 -0800250 before(:example) do
251 n = 7 # arbitrary number of metadata
Tim Emiola1e098122015-04-14 09:42:09 -0700252 diff_keys_fn = proc { |i| [format('k%d', i), format('v%d', i)] }
Tim Emiolae2860c52015-01-16 02:58:41 -0800253 diff_keys = Hash[n.times.collect { |x| diff_keys_fn.call x }]
Tim Emiola1e098122015-04-14 09:42:09 -0700254 null_vals_fn = proc { |i| [format('k%d', i), format('v\0%d', i)] }
Tim Emiolae2860c52015-01-16 02:58:41 -0800255 null_vals = Hash[n.times.collect { |x| null_vals_fn.call x }]
Tim Emiola1e098122015-04-14 09:42:09 -0700256 same_keys_fn = proc { |i| [format('k%d', i), [format('v%d', i)] * n] }
Tim Emiolae2860c52015-01-16 02:58:41 -0800257 same_keys = Hash[n.times.collect { |x| same_keys_fn.call x }]
258 symbol_key = { a_key: 'a val' }
nnoble097ef9b2014-12-01 17:06:10 -0800259 @valid_metadata = [diff_keys, same_keys, null_vals, symbol_key]
260 @bad_keys = []
261 @bad_keys << { Object.new => 'a value' }
262 @bad_keys << { 1 => 'a value' }
263 end
264
265 it 'raises an exception if a metadata key is invalid' do
266 @bad_keys.each do |md|
267 call = new_client_call
Tim Emiola05e934f2015-03-28 15:19:34 -0700268 client_ops = {
269 CallOps::SEND_INITIAL_METADATA => md
270 }
271 blk = proc do
murgatroid995ea4a992016-06-13 10:36:41 -0700272 call.run_batch(client_ops)
Tim Emiola05e934f2015-03-28 15:19:34 -0700273 end
274 expect(&blk).to raise_error
nnoble097ef9b2014-12-01 17:06:10 -0800275 end
276 end
277
nnoble097ef9b2014-12-01 17:06:10 -0800278 it 'sends all the metadata pairs when keys and values are valid' do
279 @valid_metadata.each do |md|
Craig Tiller09600be2015-05-13 16:46:55 -0700280 recvd_rpc = nil
281 rcv_thread = Thread.new do
murgatroid995ea4a992016-06-13 10:36:41 -0700282 recvd_rpc = @server.request_call
Craig Tiller09600be2015-05-13 16:46:55 -0700283 end
284
nnoble097ef9b2014-12-01 17:06:10 -0800285 call = new_client_call
Tim Emiola05e934f2015-03-28 15:19:34 -0700286 client_ops = {
287 CallOps::SEND_INITIAL_METADATA => md
288 }
murgatroid995ea4a992016-06-13 10:36:41 -0700289 batch_result = call.run_batch(client_ops)
Tim Emiola05e934f2015-03-28 15:19:34 -0700290 expect(batch_result.send_metadata).to be true
nnoble097ef9b2014-12-01 17:06:10 -0800291
Tim Emiola05e934f2015-03-28 15:19:34 -0700292 # confirm the server can receive the client metadata
Craig Tiller09600be2015-05-13 16:46:55 -0700293 rcv_thread.join
Tim Emiola05e934f2015-03-28 15:19:34 -0700294 expect(recvd_rpc).to_not eq nil
295 recvd_md = recvd_rpc.metadata
Tim Emiolae2860c52015-01-16 02:58:41 -0800296 replace_symbols = Hash[md.each_pair.collect { |x, y| [x.to_s, y] }]
Tim Emiola05e934f2015-03-28 15:19:34 -0700297 expect(recvd_md).to eq(recvd_md.merge(replace_symbols))
nnoble097ef9b2014-12-01 17:06:10 -0800298 end
299 end
nnoble097ef9b2014-12-01 17:06:10 -0800300 end
301
302 describe 'from server => client' do
nnoble097ef9b2014-12-01 17:06:10 -0800303 before(:example) do
304 n = 7 # arbitrary number of metadata
Tim Emiola1e098122015-04-14 09:42:09 -0700305 diff_keys_fn = proc { |i| [format('k%d', i), format('v%d', i)] }
Tim Emiolae2860c52015-01-16 02:58:41 -0800306 diff_keys = Hash[n.times.collect { |x| diff_keys_fn.call x }]
Tim Emiola1e098122015-04-14 09:42:09 -0700307 null_vals_fn = proc { |i| [format('k%d', i), format('v\0%d', i)] }
Tim Emiolae2860c52015-01-16 02:58:41 -0800308 null_vals = Hash[n.times.collect { |x| null_vals_fn.call x }]
Tim Emiola1e098122015-04-14 09:42:09 -0700309 same_keys_fn = proc { |i| [format('k%d', i), [format('v%d', i)] * n] }
Tim Emiolae2860c52015-01-16 02:58:41 -0800310 same_keys = Hash[n.times.collect { |x| same_keys_fn.call x }]
311 symbol_key = { a_key: 'a val' }
nnoble097ef9b2014-12-01 17:06:10 -0800312 @valid_metadata = [diff_keys, same_keys, null_vals, symbol_key]
313 @bad_keys = []
314 @bad_keys << { Object.new => 'a value' }
315 @bad_keys << { 1 => 'a value' }
316 end
317
318 it 'raises an exception if a metadata key is invalid' do
319 @bad_keys.each do |md|
Craig Tiller09600be2015-05-13 16:46:55 -0700320 recvd_rpc = nil
321 rcv_thread = Thread.new do
murgatroid995ea4a992016-06-13 10:36:41 -0700322 recvd_rpc = @server.request_call
Craig Tiller09600be2015-05-13 16:46:55 -0700323 end
324
nnoble097ef9b2014-12-01 17:06:10 -0800325 call = new_client_call
Tim Emiola05e934f2015-03-28 15:19:34 -0700326 # client signals that it's done sending metadata to allow server to
327 # respond
328 client_ops = {
329 CallOps::SEND_INITIAL_METADATA => nil
330 }
murgatroid995ea4a992016-06-13 10:36:41 -0700331 call.run_batch(client_ops)
nnoble097ef9b2014-12-01 17:06:10 -0800332
333 # server gets the invocation
Craig Tiller09600be2015-05-13 16:46:55 -0700334 rcv_thread.join
Tim Emiola05e934f2015-03-28 15:19:34 -0700335 expect(recvd_rpc).to_not eq nil
336 server_ops = {
337 CallOps::SEND_INITIAL_METADATA => md
338 }
339 blk = proc do
murgatroid995ea4a992016-06-13 10:36:41 -0700340 recvd_rpc.call.run_batch(server_ops)
Tim Emiola05e934f2015-03-28 15:19:34 -0700341 end
342 expect(&blk).to raise_error
nnoble097ef9b2014-12-01 17:06:10 -0800343 end
344 end
345
Tim Emiola05e934f2015-03-28 15:19:34 -0700346 it 'sends an empty hash if no metadata is added' do
Craig Tiller09600be2015-05-13 16:46:55 -0700347 recvd_rpc = nil
348 rcv_thread = Thread.new do
murgatroid995ea4a992016-06-13 10:36:41 -0700349 recvd_rpc = @server.request_call
Craig Tiller09600be2015-05-13 16:46:55 -0700350 end
351
nnoble097ef9b2014-12-01 17:06:10 -0800352 call = new_client_call
Tim Emiola05e934f2015-03-28 15:19:34 -0700353 # client signals that it's done sending metadata to allow server to
354 # respond
355 client_ops = {
356 CallOps::SEND_INITIAL_METADATA => nil
357 }
murgatroid995ea4a992016-06-13 10:36:41 -0700358 call.run_batch(client_ops)
nnoble097ef9b2014-12-01 17:06:10 -0800359
Tim Emiola05e934f2015-03-28 15:19:34 -0700360 # server gets the invocation but sends no metadata back
Craig Tiller09600be2015-05-13 16:46:55 -0700361 rcv_thread.join
Tim Emiola05e934f2015-03-28 15:19:34 -0700362 expect(recvd_rpc).to_not eq nil
363 server_call = recvd_rpc.call
364 server_ops = {
365 CallOps::SEND_INITIAL_METADATA => nil
366 }
murgatroid995ea4a992016-06-13 10:36:41 -0700367 server_call.run_batch(server_ops)
nnoble097ef9b2014-12-01 17:06:10 -0800368
Tim Emiola05e934f2015-03-28 15:19:34 -0700369 # client receives nothing as expected
370 client_ops = {
371 CallOps::RECV_INITIAL_METADATA => nil
372 }
murgatroid995ea4a992016-06-13 10:36:41 -0700373 batch_result = call.run_batch(client_ops)
Tim Emiola05e934f2015-03-28 15:19:34 -0700374 expect(batch_result.metadata).to eq({})
nnoble097ef9b2014-12-01 17:06:10 -0800375 end
376
Tim Emiola5d66df82015-02-09 12:35:10 -0800377 it 'sends all the pairs when keys and values are valid' do
nnoble097ef9b2014-12-01 17:06:10 -0800378 @valid_metadata.each do |md|
Craig Tiller09600be2015-05-13 16:46:55 -0700379 recvd_rpc = nil
380 rcv_thread = Thread.new do
murgatroid995ea4a992016-06-13 10:36:41 -0700381 recvd_rpc = @server.request_call
Craig Tiller09600be2015-05-13 16:46:55 -0700382 end
383
nnoble097ef9b2014-12-01 17:06:10 -0800384 call = new_client_call
Tim Emiola05e934f2015-03-28 15:19:34 -0700385 # client signals that it's done sending metadata to allow server to
386 # respond
387 client_ops = {
388 CallOps::SEND_INITIAL_METADATA => nil
389 }
murgatroid995ea4a992016-06-13 10:36:41 -0700390 call.run_batch(client_ops)
nnoble097ef9b2014-12-01 17:06:10 -0800391
Tim Emiola05e934f2015-03-28 15:19:34 -0700392 # server gets the invocation but sends no metadata back
Craig Tiller09600be2015-05-13 16:46:55 -0700393 rcv_thread.join
Tim Emiola05e934f2015-03-28 15:19:34 -0700394 expect(recvd_rpc).to_not eq nil
395 server_call = recvd_rpc.call
396 server_ops = {
397 CallOps::SEND_INITIAL_METADATA => md
398 }
murgatroid995ea4a992016-06-13 10:36:41 -0700399 server_call.run_batch(server_ops)
nnoble097ef9b2014-12-01 17:06:10 -0800400
Tim Emiola05e934f2015-03-28 15:19:34 -0700401 # client receives nothing as expected
402 client_ops = {
403 CallOps::RECV_INITIAL_METADATA => nil
404 }
murgatroid995ea4a992016-06-13 10:36:41 -0700405 batch_result = call.run_batch(client_ops)
Tim Emiolae2860c52015-01-16 02:58:41 -0800406 replace_symbols = Hash[md.each_pair.collect { |x, y| [x.to_s, y] }]
Tim Emiola05e934f2015-03-28 15:19:34 -0700407 expect(batch_result.metadata).to eq(replace_symbols)
nnoble097ef9b2014-12-01 17:06:10 -0800408 end
nnoble097ef9b2014-12-01 17:06:10 -0800409 end
nnoble097ef9b2014-12-01 17:06:10 -0800410 end
nnoble097ef9b2014-12-01 17:06:10 -0800411end
412
nnoble097ef9b2014-12-01 17:06:10 -0800413describe 'the http client/server' do
nnoble097ef9b2014-12-01 17:06:10 -0800414 before(:example) do
Tim Emiola75d7f9a2015-01-26 16:57:33 -0800415 server_host = '0.0.0.0:0'
murgatroid995ea4a992016-06-13 10:36:41 -0700416 @server = GRPC::Core::Server.new(nil)
Tim Emiola934ae9a2015-08-31 09:42:59 -0700417 server_port = @server.add_http2_port(server_host, :this_port_is_insecure)
nnoble097ef9b2014-12-01 17:06:10 -0800418 @server.start
murgatroid99afe39742015-12-16 13:04:37 -0800419 @ch = Channel.new("0.0.0.0:#{server_port}", nil, :this_channel_is_insecure)
nnoble097ef9b2014-12-01 17:06:10 -0800420 end
421
422 after(:example) do
Tim Emiola75d7f9a2015-01-26 16:57:33 -0800423 @ch.close
murgatroid995ea4a992016-06-13 10:36:41 -0700424 @server.close(deadline)
nnoble097ef9b2014-12-01 17:06:10 -0800425 end
426
nnoble0c475f02014-12-05 15:37:39 -0800427 it_behaves_like 'basic GRPC message delivery is OK' do
428 end
429
430 it_behaves_like 'GRPC metadata delivery works OK' do
431 end
nnoble0c475f02014-12-05 15:37:39 -0800432end
433
434describe 'the secure http client/server' do
murgatroid99cfa26e12015-12-04 14:36:52 -0800435 include_context 'setup: tags'
436
Tim Emiola73a540a2015-08-28 18:56:17 -0700437 def load_test_certs
438 test_root = File.join(File.dirname(__FILE__), 'testdata')
439 files = ['ca.pem', 'server1.key', 'server1.pem']
440 files.map { |f| File.open(File.join(test_root, f)).read }
441 end
442
nnoble0c475f02014-12-05 15:37:39 -0800443 before(:example) do
444 certs = load_test_certs
Tim Emiola0ce8edc2015-03-05 15:17:30 -0800445 server_host = '0.0.0.0:0'
Tim Emiola73a540a2015-08-28 18:56:17 -0700446 server_creds = GRPC::Core::ServerCredentials.new(
447 nil, [{ private_key: certs[1], cert_chain: certs[2] }], false)
murgatroid995ea4a992016-06-13 10:36:41 -0700448 @server = GRPC::Core::Server.new(nil)
Tim Emiola0ce8edc2015-03-05 15:17:30 -0800449 server_port = @server.add_http2_port(server_host, server_creds)
nnoble0c475f02014-12-05 15:37:39 -0800450 @server.start
Julien Boeuf597a4f22015-02-23 15:57:14 -0800451 args = { Channel::SSL_TARGET => 'foo.test.google.fr' }
Tim Emiola2b90e302015-01-26 17:37:15 -0800452 @ch = Channel.new("0.0.0.0:#{server_port}", args,
Tim Emiola43a7e4e2015-10-28 00:17:14 -0700453 GRPC::Core::ChannelCredentials.new(certs[0], nil, nil))
nnoble0c475f02014-12-05 15:37:39 -0800454 end
455
456 after(:example) do
murgatroid995ea4a992016-06-13 10:36:41 -0700457 @server.close(deadline)
nnoble0c475f02014-12-05 15:37:39 -0800458 end
nnoble097ef9b2014-12-01 17:06:10 -0800459
Tim Emiola0ce8edc2015-03-05 15:17:30 -0800460 it_behaves_like 'basic GRPC message delivery is OK' do
461 end
nnoble097ef9b2014-12-01 17:06:10 -0800462
Tim Emiola0ce8edc2015-03-05 15:17:30 -0800463 it_behaves_like 'GRPC metadata delivery works OK' do
464 end
murgatroid99cfa26e12015-12-04 14:36:52 -0800465
466 it 'modifies metadata with CallCredentials' do
467 auth_proc = proc { { 'k1' => 'updated-v1' } }
468 call_creds = GRPC::Core::CallCredentials.new(auth_proc)
469 md = { 'k2' => 'v2' }
470 expected_md = { 'k1' => 'updated-v1', 'k2' => 'v2' }
471 recvd_rpc = nil
472 rcv_thread = Thread.new do
murgatroid995ea4a992016-06-13 10:36:41 -0700473 recvd_rpc = @server.request_call
murgatroid99cfa26e12015-12-04 14:36:52 -0800474 end
475
476 call = new_client_call
477 call.set_credentials! call_creds
478 client_ops = {
479 CallOps::SEND_INITIAL_METADATA => md
480 }
murgatroid995ea4a992016-06-13 10:36:41 -0700481 batch_result = call.run_batch(client_ops)
murgatroid99cfa26e12015-12-04 14:36:52 -0800482 expect(batch_result.send_metadata).to be true
483
484 # confirm the server can receive the client metadata
485 rcv_thread.join
486 expect(recvd_rpc).to_not eq nil
487 recvd_md = recvd_rpc.metadata
488 replace_symbols = Hash[expected_md.each_pair.collect { |x, y| [x.to_s, y] }]
489 expect(recvd_md).to eq(recvd_md.merge(replace_symbols))
490 end
Craig Tiller190d3602015-02-18 09:23:38 -0800491end