grpc 1.6.7-universal-darwin → 1.7.0.pre1-universal-darwin

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 (33) hide show
  1. checksums.yaml +4 -4
  2. data/src/ruby/ext/grpc/rb_call_credentials.c +6 -2
  3. data/src/ruby/ext/grpc/rb_grpc.c +1 -1
  4. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +30 -20
  5. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +50 -35
  6. data/src/ruby/lib/grpc.rb +1 -0
  7. data/src/ruby/lib/grpc/2.0/grpc_c.bundle +0 -0
  8. data/src/ruby/lib/grpc/2.1/grpc_c.bundle +0 -0
  9. data/src/ruby/lib/grpc/2.2/grpc_c.bundle +0 -0
  10. data/src/ruby/lib/grpc/2.3/grpc_c.bundle +0 -0
  11. data/src/ruby/lib/grpc/2.4/grpc_c.bundle +0 -0
  12. data/src/ruby/lib/grpc/generic/active_call.rb +34 -9
  13. data/src/ruby/lib/grpc/generic/bidi_call.rb +19 -10
  14. data/src/ruby/lib/grpc/generic/client_stub.rb +95 -38
  15. data/src/ruby/lib/grpc/generic/interceptor_registry.rb +53 -0
  16. data/src/ruby/lib/grpc/generic/interceptors.rb +186 -0
  17. data/src/ruby/lib/grpc/generic/rpc_desc.rb +66 -20
  18. data/src/ruby/lib/grpc/generic/rpc_server.rb +15 -3
  19. data/src/ruby/lib/grpc/google_rpc_status_utils.rb +1 -2
  20. data/src/ruby/lib/grpc/version.rb +1 -1
  21. data/src/ruby/pb/grpc/testing/duplicate/echo_duplicate_services_pb.rb +1 -0
  22. data/src/ruby/spec/channel_connection_spec.rb +1 -34
  23. data/src/ruby/spec/client_server_spec.rb +188 -82
  24. data/src/ruby/spec/generic/active_call_spec.rb +65 -11
  25. data/src/ruby/spec/generic/client_interceptors_spec.rb +153 -0
  26. data/src/ruby/spec/generic/interceptor_registry_spec.rb +65 -0
  27. data/src/ruby/spec/generic/rpc_desc_spec.rb +38 -0
  28. data/src/ruby/spec/generic/rpc_server_spec.rb +1 -34
  29. data/src/ruby/spec/generic/server_interceptors_spec.rb +218 -0
  30. data/src/ruby/spec/spec_helper.rb +4 -0
  31. data/src/ruby/spec/support/helpers.rb +73 -0
  32. data/src/ruby/spec/support/services.rb +147 -0
  33. metadata +24 -12
@@ -12,7 +12,7 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- require 'grpc'
15
+ require 'spec_helper'
16
16
 
17
17
  include GRPC::Core::StatusCodes
18
18
 
@@ -22,6 +22,21 @@ describe GRPC::ActiveCall do
22
22
  CallOps = GRPC::Core::CallOps
23
23
  WriteFlags = GRPC::Core::WriteFlags
24
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
+
25
40
  before(:each) do
26
41
  @pass_through = proc { |x| x }
27
42
  host = '0.0.0.0:0'
@@ -67,16 +82,26 @@ describe GRPC::ActiveCall do
67
82
  end
68
83
  end
69
84
  end
85
+
86
+ describe '#interceptable' do
87
+ it 'exposes a fixed subset of the ActiveCall.methods' do
88
+ want = %w(deadline)
89
+ v = @client_call.interceptable
90
+ want.each do |w|
91
+ expect(v.methods.include?(w))
92
+ end
93
+ end
94
+ end
70
95
  end
71
96
 
72
97
  describe '#remote_send' do
73
- it 'allows a client to send a payload to the server' do
98
+ it 'allows a client to send a payload to the server', test: true do
74
99
  call = make_test_call
75
100
  ActiveCall.client_invoke(call)
76
- @client_call = ActiveCall.new(call, @pass_through,
77
- @pass_through, deadline)
101
+ client_call = ActiveCall.new(call, @pass_through,
102
+ @pass_through, deadline)
78
103
  msg = 'message is a string'
79
- @client_call.remote_send(msg)
104
+ client_call.remote_send(msg)
80
105
 
81
106
  # check that server rpc new was received
82
107
  recvd_rpc = @server.request_call
@@ -86,8 +111,13 @@ describe GRPC::ActiveCall do
86
111
  # Accept the call, and verify that the server reads the response ok.
87
112
  server_call = ActiveCall.new(recvd_call, @pass_through,
88
113
  @pass_through, deadline,
89
- metadata_received: true)
114
+ metadata_received: true,
115
+ started: false)
90
116
  expect(server_call.remote_read).to eq(msg)
117
+ # finish the call
118
+ server_call.send_initial_metadata
119
+ call.run_batch(CallOps::RECV_INITIAL_METADATA => nil)
120
+ send_and_receive_close_and_status(call, recvd_call)
91
121
  end
92
122
 
93
123
  it 'marshals the payload using the marshal func' do
@@ -109,6 +139,9 @@ describe GRPC::ActiveCall do
109
139
  @pass_through, deadline,
110
140
  metadata_received: true)
111
141
  expect(server_call.remote_read).to eq('marshalled:' + msg)
142
+ # finish the call
143
+ call.run_batch(CallOps::RECV_INITIAL_METADATA => nil)
144
+ send_and_receive_close_and_status(call, recvd_call)
112
145
  end
113
146
 
114
147
  TEST_WRITE_FLAGS = [WriteFlags::BUFFER_HINT, WriteFlags::NO_COMPRESS]
@@ -136,6 +169,9 @@ describe GRPC::ActiveCall do
136
169
  @pass_through, deadline,
137
170
  metadata_received: true)
138
171
  expect(server_call.remote_read).to eq('marshalled:' + msg)
172
+ # finish the call
173
+ server_call.send_status(OK, '', true)
174
+ client_call.receive_and_check_status
139
175
  end
140
176
  end
141
177
  end
@@ -177,7 +213,6 @@ describe GRPC::ActiveCall do
177
213
  @pass_through,
178
214
  @pass_through,
179
215
  deadline)
180
-
181
216
  expect(@client_call.metadata_sent).to eql(true)
182
217
  expect(call).to(
183
218
  receive(:run_batch).with(hash_including(
@@ -291,6 +326,10 @@ describe GRPC::ActiveCall do
291
326
  expect(recvd_rpc.metadata).to_not be_nil
292
327
  expect(recvd_rpc.metadata['k1']).to eq('v1')
293
328
  expect(recvd_rpc.metadata['k2']).to eq('v2')
329
+ # finish the call
330
+ recvd_call.run_batch(CallOps::SEND_INITIAL_METADATA => {})
331
+ call.run_batch(CallOps::RECV_INITIAL_METADATA => nil)
332
+ send_and_receive_close_and_status(call, recvd_call)
294
333
  end
295
334
  end
296
335
 
@@ -324,6 +363,8 @@ describe GRPC::ActiveCall do
324
363
  server_call = expect_server_to_receive(msg)
325
364
  server_call.remote_send('server_response')
326
365
  expect(client_call.remote_read).to eq('server_response')
366
+ send_and_receive_close_and_status(
367
+ call, inner_call_of_active_call(server_call))
327
368
  end
328
369
 
329
370
  it 'saves no metadata when the server adds no metadata' do
@@ -338,6 +379,8 @@ describe GRPC::ActiveCall do
338
379
  expect(client_call.metadata).to be_nil
339
380
  client_call.remote_read
340
381
  expect(client_call.metadata).to eq({})
382
+ send_and_receive_close_and_status(
383
+ call, inner_call_of_active_call(server_call))
341
384
  end
342
385
 
343
386
  it 'saves metadata add by the server' do
@@ -353,6 +396,8 @@ describe GRPC::ActiveCall do
353
396
  client_call.remote_read
354
397
  expected = { 'k1' => 'v1', 'k2' => 'v2' }
355
398
  expect(client_call.metadata).to eq(expected)
399
+ send_and_receive_close_and_status(
400
+ call, inner_call_of_active_call(server_call))
356
401
  end
357
402
 
358
403
  it 'get a status from server when nothing else sent from server' do
@@ -409,6 +454,8 @@ describe GRPC::ActiveCall do
409
454
  server_call = expect_server_to_receive(msg)
410
455
  server_call.remote_send('server_response')
411
456
  expect(client_call.remote_read).to eq('unmarshalled:server_response')
457
+ send_and_receive_close_and_status(
458
+ call, inner_call_of_active_call(server_call))
412
459
  end
413
460
  end
414
461
 
@@ -418,9 +465,11 @@ describe GRPC::ActiveCall do
418
465
  client_call = ActiveCall.new(call, @pass_through,
419
466
  @pass_through, deadline)
420
467
  expect(client_call.each_remote_read).to be_a(Enumerator)
468
+ # finish the call
469
+ client_call.cancel
421
470
  end
422
471
 
423
- it 'the returns an enumerator that can read n responses' do
472
+ it 'the returned enumerator can read n responses' do
424
473
  call = make_test_call
425
474
  ActiveCall.client_invoke(call)
426
475
  client_call = ActiveCall.new(call, @pass_through,
@@ -435,6 +484,8 @@ describe GRPC::ActiveCall do
435
484
  server_call.remote_send(reply)
436
485
  expect(e.next).to eq(reply)
437
486
  end
487
+ send_and_receive_close_and_status(
488
+ call, inner_call_of_active_call(server_call))
438
489
  end
439
490
 
440
491
  it 'the returns an enumerator that stops after an OK Status' do
@@ -453,7 +504,7 @@ describe GRPC::ActiveCall do
453
504
  server_call.remote_send(reply)
454
505
  expect(e.next).to eq(reply)
455
506
  end
456
- server_call.send_status(OK, 'OK')
507
+ server_call.send_status(OK, 'OK', true)
457
508
  expect { e.next }.to raise_error(StopIteration)
458
509
  end
459
510
  end
@@ -568,9 +619,11 @@ describe GRPC::ActiveCall do
568
619
  msgs
569
620
  end
570
621
 
622
+ int_ctx = GRPC::InterceptionContext.new
623
+
571
624
  @server_thread = Thread.new do
572
625
  @server_call.run_server_bidi(
573
- fake_gen_each_reply_with_no_call_param)
626
+ fake_gen_each_reply_with_no_call_param, int_ctx)
574
627
  @server_call.send_status(@server_status)
575
628
  end
576
629
  end
@@ -583,10 +636,11 @@ describe GRPC::ActiveCall do
583
636
  call_param.send_initial_metadata
584
637
  msgs
585
638
  end
639
+ int_ctx = GRPC::InterceptionContext.new
586
640
 
587
641
  @server_thread = Thread.new do
588
642
  @server_call.run_server_bidi(
589
- fake_gen_each_reply_with_call_param)
643
+ fake_gen_each_reply_with_call_param, int_ctx)
590
644
  @server_call.send_status(@server_status)
591
645
  end
592
646
  end
@@ -0,0 +1,153 @@
1
+ # Copyright 2017 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
+ require 'spec_helper'
15
+
16
+ describe 'Client Interceptors' do
17
+ let(:interceptor) { TestClientInterceptor.new }
18
+ let(:interceptors_opts) { { interceptors: [interceptor] } }
19
+ let(:request) { EchoMsg.new }
20
+ let(:service) { EchoService }
21
+
22
+ before(:each) do
23
+ build_rpc_server
24
+ end
25
+
26
+ context 'when a client interceptor is added' do
27
+ context 'with a request/response call' do
28
+ it 'should be called', server: true do
29
+ expect(interceptor).to receive(:request_response)
30
+ .once.and_call_original
31
+
32
+ run_services_on_server(@server, services: [service]) do
33
+ stub = build_insecure_stub(EchoStub, opts: interceptors_opts)
34
+ expect_any_instance_of(GRPC::ActiveCall).to receive(:request_response)
35
+ .once.and_call_original
36
+ expect(stub.an_rpc(request)).to be_a(EchoMsg)
37
+ end
38
+ end
39
+
40
+ it 'can modify outgoing metadata', server: true do
41
+ expect(interceptor).to receive(:request_response)
42
+ .once.and_call_original
43
+
44
+ run_services_on_server(@server, services: [service]) do
45
+ stub = build_insecure_stub(EchoStub, opts: interceptors_opts)
46
+ expect_any_instance_of(GRPC::ActiveCall).to receive(:request_response)
47
+ .with(request, metadata: { 'foo' => 'bar_from_request_response' })
48
+ .once.and_call_original
49
+ expect(stub.an_rpc(request)).to be_a(EchoMsg)
50
+ end
51
+ end
52
+ end
53
+
54
+ context 'with a client streaming call' do
55
+ it 'should be called', server: true do
56
+ expect(interceptor).to receive(:client_streamer)
57
+ .once.and_call_original
58
+
59
+ run_services_on_server(@server, services: [service]) do
60
+ stub = build_insecure_stub(EchoStub, opts: interceptors_opts)
61
+ expect_any_instance_of(GRPC::ActiveCall).to receive(:client_streamer)
62
+ .once.and_call_original
63
+ requests = [EchoMsg.new, EchoMsg.new]
64
+ expect(stub.a_client_streaming_rpc(requests)).to be_a(EchoMsg)
65
+ end
66
+ end
67
+
68
+ it 'can modify outgoing metadata', server: true do
69
+ expect(interceptor).to receive(:client_streamer)
70
+ .once.and_call_original
71
+
72
+ run_services_on_server(@server, services: [service]) do
73
+ stub = build_insecure_stub(EchoStub, opts: interceptors_opts)
74
+ requests = [EchoMsg.new, EchoMsg.new]
75
+ expect_any_instance_of(GRPC::ActiveCall).to receive(:client_streamer)
76
+ .with(requests, metadata: { 'foo' => 'bar_from_client_streamer' })
77
+ .once.and_call_original
78
+ expect(stub.a_client_streaming_rpc(requests)).to be_a(EchoMsg)
79
+ end
80
+ end
81
+ end
82
+
83
+ context 'with a server streaming call' do
84
+ it 'should be called', server: true do
85
+ expect(interceptor).to receive(:server_streamer)
86
+ .once.and_call_original
87
+
88
+ run_services_on_server(@server, services: [service]) do
89
+ stub = build_insecure_stub(EchoStub, opts: interceptors_opts)
90
+ request = EchoMsg.new
91
+ expect_any_instance_of(GRPC::ActiveCall).to receive(:server_streamer)
92
+ .once.and_call_original
93
+ responses = stub.a_server_streaming_rpc(request)
94
+ responses.each do |r|
95
+ expect(r).to be_a(EchoMsg)
96
+ end
97
+ end
98
+ end
99
+
100
+ it 'can modify outgoing metadata', server: true do
101
+ expect(interceptor).to receive(:server_streamer)
102
+ .once.and_call_original
103
+
104
+ run_services_on_server(@server, services: [service]) do
105
+ stub = build_insecure_stub(EchoStub, opts: interceptors_opts)
106
+ request = EchoMsg.new
107
+ expect_any_instance_of(GRPC::ActiveCall).to receive(:server_streamer)
108
+ .with(request, metadata: { 'foo' => 'bar_from_server_streamer' })
109
+ .once.and_call_original
110
+ responses = stub.a_server_streaming_rpc(request)
111
+ responses.each do |r|
112
+ expect(r).to be_a(EchoMsg)
113
+ end
114
+ end
115
+ end
116
+ end
117
+
118
+ context 'with a bidi call' do
119
+ it 'should be called', server: true do
120
+ expect(interceptor).to receive(:bidi_streamer)
121
+ .once.and_call_original
122
+
123
+ run_services_on_server(@server, services: [service]) do
124
+ stub = build_insecure_stub(EchoStub, opts: interceptors_opts)
125
+ expect_any_instance_of(GRPC::ActiveCall).to receive(:bidi_streamer)
126
+ .once.and_call_original
127
+ requests = [EchoMsg.new, EchoMsg.new]
128
+ responses = stub.a_bidi_rpc(requests)
129
+ responses.each do |r|
130
+ expect(r).to be_a(EchoMsg)
131
+ end
132
+ end
133
+ end
134
+
135
+ it 'can modify outgoing metadata', server: true do
136
+ expect(interceptor).to receive(:bidi_streamer)
137
+ .once.and_call_original
138
+
139
+ run_services_on_server(@server, services: [service]) do
140
+ stub = build_insecure_stub(EchoStub, opts: interceptors_opts)
141
+ requests = [EchoMsg.new, EchoMsg.new]
142
+ expect_any_instance_of(GRPC::ActiveCall).to receive(:bidi_streamer)
143
+ .with(requests, metadata: { 'foo' => 'bar_from_bidi_streamer' })
144
+ .once.and_call_original
145
+ responses = stub.a_bidi_rpc(requests)
146
+ responses.each do |r|
147
+ expect(r).to be_a(EchoMsg)
148
+ end
149
+ end
150
+ end
151
+ end
152
+ end
153
+ end
@@ -0,0 +1,65 @@
1
+ # Copyright 2017 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
+ require 'spec_helper'
15
+
16
+ describe GRPC::InterceptorRegistry do
17
+ let(:server) { RpcServer.new }
18
+ let(:interceptor) { TestServerInterceptor.new }
19
+ let(:interceptors) { [interceptor] }
20
+ let(:registry) { described_class.new(interceptors) }
21
+
22
+ describe 'initialization' do
23
+ subject { registry }
24
+
25
+ context 'with an interceptor extending GRPC::ServerInterceptor' do
26
+ it 'should add the interceptor to the registry' do
27
+ subject
28
+ is = registry.instance_variable_get('@interceptors')
29
+ expect(is.count).to eq 1
30
+ expect(is.first).to eq interceptor
31
+ end
32
+ end
33
+
34
+ context 'with multiple interceptors' do
35
+ let(:interceptor2) { TestServerInterceptor.new }
36
+ let(:interceptor3) { TestServerInterceptor.new }
37
+ let(:interceptors) { [interceptor, interceptor2, interceptor3] }
38
+
39
+ it 'should maintain order of insertion when iterated against' do
40
+ subject
41
+ is = registry.instance_variable_get('@interceptors')
42
+ expect(is.count).to eq 3
43
+ is.each_with_index do |i, idx|
44
+ case idx
45
+ when 0
46
+ expect(i).to eq interceptor
47
+ when 1
48
+ expect(i).to eq interceptor2
49
+ when 2
50
+ expect(i).to eq interceptor3
51
+ end
52
+ end
53
+ end
54
+ end
55
+
56
+ context 'with an interceptor not extending GRPC::ServerInterceptor' do
57
+ let(:interceptor) { Class }
58
+ let(:err) { GRPC::InterceptorRegistry::DescendantError }
59
+
60
+ it 'should raise an InvalidArgument exception' do
61
+ expect { subject }.to raise_error(err)
62
+ end
63
+ end
64
+ end
65
+ end
@@ -52,6 +52,13 @@ describe GRPC::RpcDesc do
52
52
  this_desc.run_server_method(@call, method(:other_error))
53
53
  end
54
54
 
55
+ it 'sends status UNKNOWN if NotImplementedErrors are raised' do
56
+ expect(@call).to receive(:read_unary_request).once.and_return(Object.new)
57
+ expect(@call).to receive(:send_status).once.with(
58
+ UNKNOWN, not_implemented_error_msg, false, metadata: {})
59
+ this_desc.run_server_method(@call, method(:not_implemented))
60
+ end
61
+
55
62
  it 'absorbs CallError with no further action' do
56
63
  expect(@call).to receive(:read_unary_request).once.and_raise(CallError)
57
64
  blk = proc do
@@ -102,6 +109,12 @@ describe GRPC::RpcDesc do
102
109
  @client_streamer.run_server_method(@call, method(:other_error_alt))
103
110
  end
104
111
 
112
+ it 'sends status UNKNOWN if NotImplementedErrors are raised' do
113
+ expect(@call).to receive(:send_status).once.with(
114
+ UNKNOWN, not_implemented_error_msg, false, metadata: {})
115
+ @client_streamer.run_server_method(@call, method(:not_implemented_alt))
116
+ end
117
+
105
118
  it 'absorbs CallError with no further action' do
106
119
  expect(@call).to receive(:server_unary_response).once.and_raise(
107
120
  CallError)
@@ -166,6 +179,14 @@ describe GRPC::RpcDesc do
166
179
  @bidi_streamer.run_server_method(@call, method(:other_error_alt))
167
180
  end
168
181
 
182
+ it 'sends status UNKNOWN if NotImplementedErrors are raised' do
183
+ expect(@call).to receive(:run_server_bidi).and_raise(
184
+ not_implemented_error)
185
+ expect(@call).to receive(:send_status).once.with(
186
+ UNKNOWN, not_implemented_error_msg, false, metadata: {})
187
+ @bidi_streamer.run_server_method(@call, method(:not_implemented_alt))
188
+ end
189
+
169
190
  it 'closes the stream if there no errors' do
170
191
  expect(@call).to receive(:run_server_bidi)
171
192
  expect(@call).to receive(:output_metadata).and_return(fake_md)
@@ -329,8 +350,25 @@ describe GRPC::RpcDesc do
329
350
  fail(ArgumentError, 'other error')
330
351
  end
331
352
 
353
+ def not_implemented(_req, _call)
354
+ fail not_implemented_error
355
+ end
356
+
357
+ def not_implemented_alt(_call)
358
+ fail not_implemented_error
359
+ end
360
+
332
361
  def arg_error_msg(error = nil)
333
362
  error ||= ArgumentError.new('other error')
334
363
  "#{error.class}: #{error.message}"
335
364
  end
365
+
366
+ def not_implemented_error
367
+ NotImplementedError.new('some OS feature not implemented')
368
+ end
369
+
370
+ def not_implemented_error_msg(error = nil)
371
+ error ||= not_implemented_error
372
+ "#{error.class}: #{error.message}"
373
+ end
336
374
  end