grpc 0.13.0.pre1.1-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 (95) hide show
  1. checksums.yaml +7 -0
  2. data/etc/roots.pem +5114 -0
  3. data/grpc_c.32.ruby +0 -0
  4. data/grpc_c.64.ruby +0 -0
  5. data/src/ruby/bin/apis/google/protobuf/empty.rb +44 -0
  6. data/src/ruby/bin/apis/pubsub_demo.rb +256 -0
  7. data/src/ruby/bin/apis/tech/pubsub/proto/pubsub.rb +174 -0
  8. data/src/ruby/bin/apis/tech/pubsub/proto/pubsub_services.rb +103 -0
  9. data/src/ruby/bin/grpc_ruby_interop_client +33 -0
  10. data/src/ruby/bin/grpc_ruby_interop_server +33 -0
  11. data/src/ruby/bin/interop/interop_client.rb +51 -0
  12. data/src/ruby/bin/interop/interop_server.rb +50 -0
  13. data/src/ruby/bin/math.rb +32 -0
  14. data/src/ruby/bin/math_client.rb +147 -0
  15. data/src/ruby/bin/math_server.rb +206 -0
  16. data/src/ruby/bin/math_services.rb +27 -0
  17. data/src/ruby/bin/noproto_client.rb +108 -0
  18. data/src/ruby/bin/noproto_server.rb +112 -0
  19. data/src/ruby/ext/grpc/extconf.rb +129 -0
  20. data/src/ruby/ext/grpc/rb_byte_buffer.c +70 -0
  21. data/src/ruby/ext/grpc/rb_byte_buffer.h +47 -0
  22. data/src/ruby/ext/grpc/rb_call.c +908 -0
  23. data/src/ruby/ext/grpc/rb_call.h +66 -0
  24. data/src/ruby/ext/grpc/rb_call_credentials.c +319 -0
  25. data/src/ruby/ext/grpc/rb_call_credentials.h +46 -0
  26. data/src/ruby/ext/grpc/rb_channel.c +432 -0
  27. data/src/ruby/ext/grpc/rb_channel.h +47 -0
  28. data/src/ruby/ext/grpc/rb_channel_args.c +169 -0
  29. data/src/ruby/ext/grpc/rb_channel_args.h +53 -0
  30. data/src/ruby/ext/grpc/rb_channel_credentials.c +268 -0
  31. data/src/ruby/ext/grpc/rb_channel_credentials.h +47 -0
  32. data/src/ruby/ext/grpc/rb_completion_queue.c +183 -0
  33. data/src/ruby/ext/grpc/rb_completion_queue.h +55 -0
  34. data/src/ruby/ext/grpc/rb_event_thread.c +158 -0
  35. data/src/ruby/ext/grpc/rb_event_thread.h +37 -0
  36. data/src/ruby/ext/grpc/rb_grpc.c +336 -0
  37. data/src/ruby/ext/grpc/rb_grpc.h +85 -0
  38. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +560 -0
  39. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +843 -0
  40. data/src/ruby/ext/grpc/rb_loader.c +72 -0
  41. data/src/ruby/ext/grpc/rb_loader.h +40 -0
  42. data/src/ruby/ext/grpc/rb_server.c +400 -0
  43. data/src/ruby/ext/grpc/rb_server.h +47 -0
  44. data/src/ruby/ext/grpc/rb_server_credentials.c +284 -0
  45. data/src/ruby/ext/grpc/rb_server_credentials.h +47 -0
  46. data/src/ruby/lib/grpc.rb +44 -0
  47. data/src/ruby/lib/grpc/2.0/grpc_c.bundle +0 -0
  48. data/src/ruby/lib/grpc/2.1/grpc_c.bundle +0 -0
  49. data/src/ruby/lib/grpc/2.2/grpc_c.bundle +0 -0
  50. data/src/ruby/lib/grpc/2.3/grpc_c.bundle +0 -0
  51. data/src/ruby/lib/grpc/core/time_consts.rb +71 -0
  52. data/src/ruby/lib/grpc/errors.rb +62 -0
  53. data/src/ruby/lib/grpc/generic/active_call.rb +488 -0
  54. data/src/ruby/lib/grpc/generic/bidi_call.rb +218 -0
  55. data/src/ruby/lib/grpc/generic/client_stub.rb +471 -0
  56. data/src/ruby/lib/grpc/generic/rpc_desc.rb +147 -0
  57. data/src/ruby/lib/grpc/generic/rpc_server.rb +504 -0
  58. data/src/ruby/lib/grpc/generic/service.rb +234 -0
  59. data/src/ruby/lib/grpc/grpc.rb +34 -0
  60. data/src/ruby/lib/grpc/logconfig.rb +59 -0
  61. data/src/ruby/lib/grpc/notifier.rb +60 -0
  62. data/src/ruby/lib/grpc/version.rb +33 -0
  63. data/src/ruby/pb/README.md +42 -0
  64. data/src/ruby/pb/generate_proto_ruby.sh +51 -0
  65. data/src/ruby/pb/grpc/health/checker.rb +75 -0
  66. data/src/ruby/pb/grpc/health/v1alpha/health.rb +29 -0
  67. data/src/ruby/pb/grpc/health/v1alpha/health_services.rb +28 -0
  68. data/src/ruby/pb/test/client.rb +469 -0
  69. data/src/ruby/pb/test/proto/empty.rb +15 -0
  70. data/src/ruby/pb/test/proto/messages.rb +80 -0
  71. data/src/ruby/pb/test/proto/test.rb +14 -0
  72. data/src/ruby/pb/test/proto/test_services.rb +64 -0
  73. data/src/ruby/pb/test/server.rb +253 -0
  74. data/src/ruby/spec/call_credentials_spec.rb +57 -0
  75. data/src/ruby/spec/call_spec.rb +163 -0
  76. data/src/ruby/spec/channel_credentials_spec.rb +97 -0
  77. data/src/ruby/spec/channel_spec.rb +177 -0
  78. data/src/ruby/spec/client_server_spec.rb +475 -0
  79. data/src/ruby/spec/completion_queue_spec.rb +42 -0
  80. data/src/ruby/spec/generic/active_call_spec.rb +373 -0
  81. data/src/ruby/spec/generic/client_stub_spec.rb +476 -0
  82. data/src/ruby/spec/generic/rpc_desc_spec.rb +331 -0
  83. data/src/ruby/spec/generic/rpc_server_pool_spec.rb +138 -0
  84. data/src/ruby/spec/generic/rpc_server_spec.rb +576 -0
  85. data/src/ruby/spec/generic/service_spec.rb +345 -0
  86. data/src/ruby/spec/pb/health/checker_spec.rb +232 -0
  87. data/src/ruby/spec/server_credentials_spec.rb +94 -0
  88. data/src/ruby/spec/server_spec.rb +209 -0
  89. data/src/ruby/spec/spec_helper.rb +69 -0
  90. data/src/ruby/spec/testdata/README +1 -0
  91. data/src/ruby/spec/testdata/ca.pem +15 -0
  92. data/src/ruby/spec/testdata/server1.key +16 -0
  93. data/src/ruby/spec/testdata/server1.pem +16 -0
  94. data/src/ruby/spec/time_consts_spec.rb +89 -0
  95. metadata +319 -0
@@ -0,0 +1,163 @@
1
+ # Copyright 2015, Google Inc.
2
+ # 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
+
30
+ require 'grpc'
31
+
32
+ include GRPC::Core::StatusCodes
33
+
34
+ describe GRPC::Core::WriteFlags do
35
+ it 'should define the known write flag values' do
36
+ m = GRPC::Core::WriteFlags
37
+ expect(m.const_get(:BUFFER_HINT)).to_not be_nil
38
+ expect(m.const_get(:NO_COMPRESS)).to_not be_nil
39
+ end
40
+ end
41
+
42
+ describe GRPC::Core::RpcErrors do
43
+ before(:each) do
44
+ @known_types = {
45
+ OK: 0,
46
+ ERROR: 1,
47
+ NOT_ON_SERVER: 2,
48
+ NOT_ON_CLIENT: 3,
49
+ ALREADY_ACCEPTED: 4,
50
+ ALREADY_INVOKED: 5,
51
+ NOT_INVOKED: 6,
52
+ ALREADY_FINISHED: 7,
53
+ TOO_MANY_OPERATIONS: 8,
54
+ INVALID_FLAGS: 9,
55
+ ErrorMessages: {
56
+ 0 => 'ok',
57
+ 1 => 'unknown error',
58
+ 2 => 'not available on a server',
59
+ 3 => 'not available on a client',
60
+ 4 => 'call is already accepted',
61
+ 5 => 'call is already invoked',
62
+ 6 => 'call is not yet invoked',
63
+ 7 => 'call is already finished',
64
+ 8 => 'outstanding read or write present',
65
+ 9 => 'a bad flag was given'
66
+ }
67
+ }
68
+ end
69
+
70
+ it 'should have symbols for all the known error codes' do
71
+ m = GRPC::Core::RpcErrors
72
+ syms_and_codes = m.constants.collect { |c| [c, m.const_get(c)] }
73
+ expect(Hash[syms_and_codes]).to eq(@known_types)
74
+ end
75
+ end
76
+
77
+ describe GRPC::Core::CallOps do
78
+ before(:each) do
79
+ @known_types = {
80
+ SEND_INITIAL_METADATA: 0,
81
+ SEND_MESSAGE: 1,
82
+ SEND_CLOSE_FROM_CLIENT: 2,
83
+ SEND_STATUS_FROM_SERVER: 3,
84
+ RECV_INITIAL_METADATA: 4,
85
+ RECV_MESSAGE: 5,
86
+ RECV_STATUS_ON_CLIENT: 6,
87
+ RECV_CLOSE_ON_SERVER: 7
88
+ }
89
+ end
90
+
91
+ it 'should have symbols for all the known operation types' do
92
+ m = GRPC::Core::CallOps
93
+ syms_and_codes = m.constants.collect { |c| [c, m.const_get(c)] }
94
+ expect(Hash[syms_and_codes]).to eq(@known_types)
95
+ end
96
+ end
97
+
98
+ describe GRPC::Core::Call do
99
+ let(:client_queue) { GRPC::Core::CompletionQueue.new }
100
+ let(:test_tag) { Object.new }
101
+ let(:fake_host) { 'localhost:10101' }
102
+
103
+ before(:each) do
104
+ @ch = GRPC::Core::Channel.new(fake_host, nil, :this_channel_is_insecure)
105
+ end
106
+
107
+ describe '#status' do
108
+ it 'can save the status and read it back' do
109
+ call = make_test_call
110
+ sts = Struct::Status.new(OK, 'OK')
111
+ expect { call.status = sts }.not_to raise_error
112
+ expect(call.status).to eq(sts)
113
+ end
114
+
115
+ it 'must be set to a status' do
116
+ call = make_test_call
117
+ bad_sts = Object.new
118
+ expect { call.status = bad_sts }.to raise_error(TypeError)
119
+ end
120
+
121
+ it 'can be set to nil' do
122
+ call = make_test_call
123
+ expect { call.status = nil }.not_to raise_error
124
+ end
125
+ end
126
+
127
+ describe '#metadata' do
128
+ it 'can save the metadata hash and read it back' do
129
+ call = make_test_call
130
+ md = { 'k1' => 'v1', 'k2' => 'v2' }
131
+ expect { call.metadata = md }.not_to raise_error
132
+ expect(call.metadata).to be(md)
133
+ end
134
+
135
+ it 'must be set with a hash' do
136
+ call = make_test_call
137
+ bad_md = Object.new
138
+ expect { call.metadata = bad_md }.to raise_error(TypeError)
139
+ end
140
+
141
+ it 'can be set to nil' do
142
+ call = make_test_call
143
+ expect { call.metadata = nil }.not_to raise_error
144
+ end
145
+ end
146
+
147
+ describe '#set_credentials!' do
148
+ it 'can set a valid CallCredentials object' do
149
+ call = make_test_call
150
+ auth_proc = proc { { 'plugin_key' => 'plugin_value' } }
151
+ creds = GRPC::Core::CallCredentials.new auth_proc
152
+ expect { call.set_credentials! creds }.not_to raise_error
153
+ end
154
+ end
155
+
156
+ def make_test_call
157
+ @ch.create_call(client_queue, nil, nil, 'dummy_method', nil, deadline)
158
+ end
159
+
160
+ def deadline
161
+ Time.now + 2 # in 2 seconds; arbitrary
162
+ end
163
+ end
@@ -0,0 +1,97 @@
1
+ # Copyright 2015, Google Inc.
2
+ # 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
+
30
+ require 'grpc'
31
+
32
+ describe GRPC::Core::ChannelCredentials do
33
+ ChannelCredentials = GRPC::Core::ChannelCredentials
34
+ CallCredentials = GRPC::Core::CallCredentials
35
+
36
+ def load_test_certs
37
+ test_root = File.join(File.dirname(__FILE__), 'testdata')
38
+ files = ['ca.pem', 'server1.pem', 'server1.key']
39
+ files.map { |f| File.open(File.join(test_root, f)).read }
40
+ end
41
+
42
+ describe '#new' do
43
+ it 'can be constructed with fake inputs' do
44
+ blk = proc { ChannelCredentials.new('root_certs', 'key', 'cert') }
45
+ expect(&blk).not_to raise_error
46
+ end
47
+
48
+ it 'it can be constructed using specific test certificates' do
49
+ certs = load_test_certs
50
+ expect { ChannelCredentials.new(*certs) }.not_to raise_error
51
+ end
52
+
53
+ it 'can be constructed with server roots certs only' do
54
+ root_cert, _, _ = load_test_certs
55
+ expect { ChannelCredentials.new(root_cert) }.not_to raise_error
56
+ end
57
+
58
+ it 'can be constructed with a nil server roots' do
59
+ _, client_key, client_chain = load_test_certs
60
+ blk = proc { ChannelCredentials.new(nil, client_key, client_chain) }
61
+ expect(&blk).not_to raise_error
62
+ end
63
+
64
+ it 'can be constructed with no params' do
65
+ blk = proc { ChannelCredentials.new(nil) }
66
+ expect(&blk).not_to raise_error
67
+ end
68
+ end
69
+
70
+ describe '#compose' do
71
+ it 'can compose with a CallCredentials' do
72
+ certs = load_test_certs
73
+ channel_creds = ChannelCredentials.new(*certs)
74
+ auth_proc = proc { { 'plugin_key' => 'plugin_value' } }
75
+ call_creds = CallCredentials.new auth_proc
76
+ expect { channel_creds.compose call_creds }.not_to raise_error
77
+ end
78
+
79
+ it 'can compose with multiple CallCredentials' do
80
+ certs = load_test_certs
81
+ channel_creds = ChannelCredentials.new(*certs)
82
+ auth_proc = proc { { 'plugin_key' => 'plugin_value' } }
83
+ call_creds1 = CallCredentials.new auth_proc
84
+ call_creds2 = CallCredentials.new auth_proc
85
+ expect do
86
+ channel_creds.compose(call_creds1, call_creds2)
87
+ end.not_to raise_error
88
+ end
89
+
90
+ it 'cannot compose with ChannelCredentials' do
91
+ certs = load_test_certs
92
+ channel_creds1 = ChannelCredentials.new(*certs)
93
+ channel_creds2 = ChannelCredentials.new(*certs)
94
+ expect { channel_creds1.compose channel_creds2 }.to raise_error(TypeError)
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,177 @@
1
+ # Copyright 2015, Google Inc.
2
+ # 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
+
30
+ require 'grpc'
31
+
32
+ def load_test_certs
33
+ test_root = File.join(File.dirname(__FILE__), 'testdata')
34
+ files = ['ca.pem', 'server1.key', 'server1.pem']
35
+ files.map { |f| File.open(File.join(test_root, f)).read }
36
+ end
37
+
38
+ describe GRPC::Core::Channel do
39
+ let(:fake_host) { 'localhost:0' }
40
+ let(:cq) { GRPC::Core::CompletionQueue.new }
41
+
42
+ def create_test_cert
43
+ GRPC::Core::ChannelCredentials.new(load_test_certs[0])
44
+ end
45
+
46
+ shared_examples '#new' do
47
+ it 'take a host name without channel args' do
48
+ blk = proc do
49
+ GRPC::Core::Channel.new('dummy_host', nil, :this_channel_is_insecure)
50
+ end
51
+ expect(&blk).not_to raise_error
52
+ end
53
+
54
+ it 'does not take a hash with bad keys as channel args' do
55
+ blk = construct_with_args(Object.new => 1)
56
+ expect(&blk).to raise_error TypeError
57
+ blk = construct_with_args(1 => 1)
58
+ expect(&blk).to raise_error TypeError
59
+ end
60
+
61
+ it 'does not take a hash with bad values as channel args' do
62
+ blk = construct_with_args(symbol: Object.new)
63
+ expect(&blk).to raise_error TypeError
64
+ blk = construct_with_args('1' => {})
65
+ expect(&blk).to raise_error TypeError
66
+ end
67
+
68
+ it 'can take a hash with a symbol key as channel args' do
69
+ blk = construct_with_args(a_symbol: 1)
70
+ expect(&blk).to_not raise_error
71
+ end
72
+
73
+ it 'can take a hash with a string key as channel args' do
74
+ blk = construct_with_args('a_symbol' => 1)
75
+ expect(&blk).to_not raise_error
76
+ end
77
+
78
+ it 'can take a hash with a string value as channel args' do
79
+ blk = construct_with_args(a_symbol: '1')
80
+ expect(&blk).to_not raise_error
81
+ end
82
+
83
+ it 'can take a hash with a symbol value as channel args' do
84
+ blk = construct_with_args(a_symbol: :another_symbol)
85
+ expect(&blk).to_not raise_error
86
+ end
87
+
88
+ it 'can take a hash with a numeric value as channel args' do
89
+ blk = construct_with_args(a_symbol: 1)
90
+ expect(&blk).to_not raise_error
91
+ end
92
+
93
+ it 'can take a hash with many args as channel args' do
94
+ args = Hash[127.times.collect { |x| [x.to_s, x] }]
95
+ blk = construct_with_args(args)
96
+ expect(&blk).to_not raise_error
97
+ end
98
+ end
99
+
100
+ describe '#new for secure channels' do
101
+ def construct_with_args(a)
102
+ proc { GRPC::Core::Channel.new('dummy_host', a, create_test_cert) }
103
+ end
104
+
105
+ it_behaves_like '#new'
106
+ end
107
+
108
+ describe '#new for insecure channels' do
109
+ it_behaves_like '#new'
110
+
111
+ def construct_with_args(a)
112
+ proc do
113
+ GRPC::Core::Channel.new('dummy_host', a, :this_channel_is_insecure)
114
+ end
115
+ end
116
+ end
117
+
118
+ describe '#create_call' do
119
+ it 'creates a call OK' do
120
+ ch = GRPC::Core::Channel.new(fake_host, nil, :this_channel_is_insecure)
121
+
122
+ deadline = Time.now + 5
123
+
124
+ blk = proc do
125
+ ch.create_call(cq, nil, nil, 'dummy_method', nil, deadline)
126
+ end
127
+ expect(&blk).to_not raise_error
128
+ end
129
+
130
+ it 'raises an error if called on a closed channel' do
131
+ ch = GRPC::Core::Channel.new(fake_host, nil, :this_channel_is_insecure)
132
+ ch.close
133
+
134
+ deadline = Time.now + 5
135
+ blk = proc do
136
+ ch.create_call(cq, nil, nil, 'dummy_method', nil, deadline)
137
+ end
138
+ expect(&blk).to raise_error(RuntimeError)
139
+ end
140
+ end
141
+
142
+ describe '#destroy' do
143
+ it 'destroys a channel ok' do
144
+ ch = GRPC::Core::Channel.new(fake_host, nil, :this_channel_is_insecure)
145
+ blk = proc { ch.destroy }
146
+ expect(&blk).to_not raise_error
147
+ end
148
+
149
+ it 'can be called more than once without error' do
150
+ ch = GRPC::Core::Channel.new(fake_host, nil, :this_channel_is_insecure)
151
+ blk = proc { ch.destroy }
152
+ blk.call
153
+ expect(&blk).to_not raise_error
154
+ end
155
+ end
156
+
157
+ describe '::SSL_TARGET' do
158
+ it 'is a symbol' do
159
+ expect(GRPC::Core::Channel::SSL_TARGET).to be_a(Symbol)
160
+ end
161
+ end
162
+
163
+ describe '#close' do
164
+ it 'closes a channel ok' do
165
+ ch = GRPC::Core::Channel.new(fake_host, nil, :this_channel_is_insecure)
166
+ blk = proc { ch.close }
167
+ expect(&blk).to_not raise_error
168
+ end
169
+
170
+ it 'can be called more than once without error' do
171
+ ch = GRPC::Core::Channel.new(fake_host, nil, :this_channel_is_insecure)
172
+ blk = proc { ch.close }
173
+ blk.call
174
+ expect(&blk).to_not raise_error
175
+ end
176
+ end
177
+ end
@@ -0,0 +1,475 @@
1
+ # Copyright 2015, Google Inc.
2
+ # 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
+
30
+ require 'grpc'
31
+
32
+ include GRPC::Core
33
+
34
+ shared_context 'setup: tags' do
35
+ let(:sent_message) { 'sent message' }
36
+ let(:reply_text) { 'the reply' }
37
+ before(:example) do
38
+ @client_tag = Object.new
39
+ @server_tag = Object.new
40
+ end
41
+
42
+ def deadline
43
+ Time.now + 5
44
+ end
45
+
46
+ def server_allows_client_to_proceed
47
+ recvd_rpc = @server.request_call(@server_queue, @server_tag, deadline)
48
+ expect(recvd_rpc).to_not eq nil
49
+ server_call = recvd_rpc.call
50
+ ops = { CallOps::SEND_INITIAL_METADATA => {} }
51
+ svr_batch = server_call.run_batch(@server_queue, @server_tag, deadline, ops)
52
+ expect(svr_batch.send_metadata).to be true
53
+ server_call
54
+ end
55
+
56
+ def new_client_call
57
+ @ch.create_call(@client_queue, nil, nil, '/method', nil, deadline)
58
+ end
59
+ end
60
+
61
+ shared_examples 'basic GRPC message delivery is OK' do
62
+ include GRPC::Core
63
+ include_context 'setup: tags'
64
+
65
+ context 'the test channel' do
66
+ it 'should have a target' do
67
+ expect(@ch.target).to be_a(String)
68
+ end
69
+ end
70
+
71
+ context 'a client call' do
72
+ it 'should have a peer' do
73
+ expect(new_client_call.peer).to be_a(String)
74
+ end
75
+ end
76
+
77
+ it 'calls have peer info' do
78
+ call = new_client_call
79
+ expect(call.peer).to be_a(String)
80
+ end
81
+
82
+ it 'servers receive requests from clients and can respond' do
83
+ call = new_client_call
84
+ server_call = nil
85
+
86
+ server_thread = Thread.new do
87
+ server_call = server_allows_client_to_proceed
88
+ end
89
+
90
+ client_ops = {
91
+ CallOps::SEND_INITIAL_METADATA => {},
92
+ CallOps::SEND_MESSAGE => sent_message
93
+ }
94
+ batch_result = call.run_batch(@client_queue, @client_tag, deadline,
95
+ client_ops)
96
+ expect(batch_result.send_metadata).to be true
97
+ expect(batch_result.send_message).to be true
98
+
99
+ # confirm the server can read the inbound message
100
+ server_thread.join
101
+ server_ops = {
102
+ CallOps::RECV_MESSAGE => nil
103
+ }
104
+ svr_batch = server_call.run_batch(@server_queue, @server_tag, deadline,
105
+ server_ops)
106
+ expect(svr_batch.message).to eq(sent_message)
107
+ end
108
+
109
+ it 'responses written by servers are received by the client' do
110
+ call = new_client_call
111
+ server_call = nil
112
+
113
+ server_thread = Thread.new do
114
+ server_call = server_allows_client_to_proceed
115
+ end
116
+
117
+ client_ops = {
118
+ CallOps::SEND_INITIAL_METADATA => {},
119
+ CallOps::SEND_MESSAGE => sent_message
120
+ }
121
+ batch_result = call.run_batch(@client_queue, @client_tag, deadline,
122
+ client_ops)
123
+ expect(batch_result.send_metadata).to be true
124
+ expect(batch_result.send_message).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
+ CallOps::SEND_MESSAGE => reply_text
131
+ }
132
+ svr_batch = server_call.run_batch(@server_queue, @server_tag, deadline,
133
+ server_ops)
134
+ expect(svr_batch.message).to eq(sent_message)
135
+ expect(svr_batch.send_message).to be true
136
+ end
137
+
138
+ it 'servers can ignore a client write and send a status' do
139
+ call = new_client_call
140
+ server_call = nil
141
+
142
+ server_thread = Thread.new do
143
+ server_call = server_allows_client_to_proceed
144
+ end
145
+
146
+ client_ops = {
147
+ CallOps::SEND_INITIAL_METADATA => {},
148
+ CallOps::SEND_MESSAGE => sent_message
149
+ }
150
+ batch_result = call.run_batch(@client_queue, @client_tag, deadline,
151
+ client_ops)
152
+ expect(batch_result.send_metadata).to be true
153
+ expect(batch_result.send_message).to be true
154
+
155
+ # confirm the server can read the inbound message
156
+ the_status = Struct::Status.new(StatusCodes::OK, 'OK')
157
+ server_thread.join
158
+ server_ops = {
159
+ CallOps::SEND_STATUS_FROM_SERVER => the_status
160
+ }
161
+ svr_batch = server_call.run_batch(@server_queue, @server_tag, deadline,
162
+ server_ops)
163
+ expect(svr_batch.message).to eq nil
164
+ expect(svr_batch.send_status).to be true
165
+ end
166
+
167
+ it 'completes calls by sending status to client and server' do
168
+ call = new_client_call
169
+ server_call = nil
170
+
171
+ server_thread = Thread.new do
172
+ server_call = server_allows_client_to_proceed
173
+ end
174
+
175
+ client_ops = {
176
+ CallOps::SEND_INITIAL_METADATA => {},
177
+ CallOps::SEND_MESSAGE => sent_message
178
+ }
179
+ batch_result = call.run_batch(@client_queue, @client_tag, deadline,
180
+ client_ops)
181
+ expect(batch_result.send_metadata).to be true
182
+ expect(batch_result.send_message).to be true
183
+
184
+ # confirm the server can read the inbound message and respond
185
+ the_status = Struct::Status.new(StatusCodes::OK, 'OK', {})
186
+ server_thread.join
187
+ server_ops = {
188
+ CallOps::RECV_MESSAGE => nil,
189
+ CallOps::SEND_MESSAGE => reply_text,
190
+ CallOps::SEND_STATUS_FROM_SERVER => the_status
191
+ }
192
+ svr_batch = server_call.run_batch(@server_queue, @server_tag, deadline,
193
+ server_ops)
194
+ expect(svr_batch.message).to eq sent_message
195
+ expect(svr_batch.send_status).to be true
196
+ expect(svr_batch.send_message).to be true
197
+
198
+ # confirm the client can receive the server response and status.
199
+ client_ops = {
200
+ CallOps::SEND_CLOSE_FROM_CLIENT => nil,
201
+ CallOps::RECV_MESSAGE => nil,
202
+ CallOps::RECV_STATUS_ON_CLIENT => nil
203
+ }
204
+ batch_result = call.run_batch(@client_queue, @client_tag, deadline,
205
+ client_ops)
206
+ expect(batch_result.send_close).to be true
207
+ expect(batch_result.message).to eq reply_text
208
+ expect(batch_result.status).to eq the_status
209
+
210
+ # confirm the server can receive the client close.
211
+ server_ops = {
212
+ CallOps::RECV_CLOSE_ON_SERVER => nil
213
+ }
214
+ svr_batch = server_call.run_batch(@server_queue, @server_tag, deadline,
215
+ server_ops)
216
+ expect(svr_batch.send_close).to be true
217
+ end
218
+ end
219
+
220
+ shared_examples 'GRPC metadata delivery works OK' do
221
+ include_context 'setup: tags'
222
+
223
+ describe 'from client => server' do
224
+ before(:example) do
225
+ n = 7 # arbitrary number of metadata
226
+ diff_keys_fn = proc { |i| [format('k%d', i), format('v%d', i)] }
227
+ diff_keys = Hash[n.times.collect { |x| diff_keys_fn.call x }]
228
+ null_vals_fn = proc { |i| [format('k%d', i), format('v\0%d', i)] }
229
+ null_vals = Hash[n.times.collect { |x| null_vals_fn.call x }]
230
+ same_keys_fn = proc { |i| [format('k%d', i), [format('v%d', i)] * n] }
231
+ same_keys = Hash[n.times.collect { |x| same_keys_fn.call x }]
232
+ symbol_key = { a_key: 'a val' }
233
+ @valid_metadata = [diff_keys, same_keys, null_vals, symbol_key]
234
+ @bad_keys = []
235
+ @bad_keys << { Object.new => 'a value' }
236
+ @bad_keys << { 1 => 'a value' }
237
+ end
238
+
239
+ it 'raises an exception if a metadata key is invalid' do
240
+ @bad_keys.each do |md|
241
+ call = new_client_call
242
+ client_ops = {
243
+ CallOps::SEND_INITIAL_METADATA => md
244
+ }
245
+ blk = proc do
246
+ call.run_batch(@client_queue, @client_tag, deadline,
247
+ client_ops)
248
+ end
249
+ expect(&blk).to raise_error
250
+ end
251
+ end
252
+
253
+ it 'sends all the metadata pairs when keys and values are valid' do
254
+ @valid_metadata.each do |md|
255
+ recvd_rpc = nil
256
+ rcv_thread = Thread.new do
257
+ recvd_rpc = @server.request_call(@server_queue, @server_tag, deadline)
258
+ end
259
+
260
+ call = new_client_call
261
+ client_ops = {
262
+ CallOps::SEND_INITIAL_METADATA => md
263
+ }
264
+ batch_result = call.run_batch(@client_queue, @client_tag, deadline,
265
+ client_ops)
266
+ expect(batch_result.send_metadata).to be true
267
+
268
+ # confirm the server can receive the client metadata
269
+ rcv_thread.join
270
+ expect(recvd_rpc).to_not eq nil
271
+ recvd_md = recvd_rpc.metadata
272
+ replace_symbols = Hash[md.each_pair.collect { |x, y| [x.to_s, y] }]
273
+ expect(recvd_md).to eq(recvd_md.merge(replace_symbols))
274
+ end
275
+ end
276
+ end
277
+
278
+ describe 'from server => client' do
279
+ before(:example) do
280
+ n = 7 # arbitrary number of metadata
281
+ diff_keys_fn = proc { |i| [format('k%d', i), format('v%d', i)] }
282
+ diff_keys = Hash[n.times.collect { |x| diff_keys_fn.call x }]
283
+ null_vals_fn = proc { |i| [format('k%d', i), format('v\0%d', i)] }
284
+ null_vals = Hash[n.times.collect { |x| null_vals_fn.call x }]
285
+ same_keys_fn = proc { |i| [format('k%d', i), [format('v%d', i)] * n] }
286
+ same_keys = Hash[n.times.collect { |x| same_keys_fn.call x }]
287
+ symbol_key = { a_key: 'a val' }
288
+ @valid_metadata = [diff_keys, same_keys, null_vals, symbol_key]
289
+ @bad_keys = []
290
+ @bad_keys << { Object.new => 'a value' }
291
+ @bad_keys << { 1 => 'a value' }
292
+ end
293
+
294
+ it 'raises an exception if a metadata key is invalid' do
295
+ @bad_keys.each do |md|
296
+ recvd_rpc = nil
297
+ rcv_thread = Thread.new do
298
+ recvd_rpc = @server.request_call(@server_queue, @server_tag, deadline)
299
+ end
300
+
301
+ call = new_client_call
302
+ # client signals that it's done sending metadata to allow server to
303
+ # respond
304
+ client_ops = {
305
+ CallOps::SEND_INITIAL_METADATA => nil
306
+ }
307
+ call.run_batch(@client_queue, @client_tag, deadline, client_ops)
308
+
309
+ # server gets the invocation
310
+ rcv_thread.join
311
+ expect(recvd_rpc).to_not eq nil
312
+ server_ops = {
313
+ CallOps::SEND_INITIAL_METADATA => md
314
+ }
315
+ blk = proc do
316
+ recvd_rpc.call.run_batch(@server_queue, @server_tag, deadline,
317
+ server_ops)
318
+ end
319
+ expect(&blk).to raise_error
320
+ end
321
+ end
322
+
323
+ it 'sends an empty hash if no metadata is added' do
324
+ recvd_rpc = nil
325
+ rcv_thread = Thread.new do
326
+ recvd_rpc = @server.request_call(@server_queue, @server_tag, deadline)
327
+ end
328
+
329
+ call = new_client_call
330
+ # client signals that it's done sending metadata to allow server to
331
+ # respond
332
+ client_ops = {
333
+ CallOps::SEND_INITIAL_METADATA => nil
334
+ }
335
+ call.run_batch(@client_queue, @client_tag, deadline, client_ops)
336
+
337
+ # server gets the invocation but sends no metadata back
338
+ rcv_thread.join
339
+ expect(recvd_rpc).to_not eq nil
340
+ server_call = recvd_rpc.call
341
+ server_ops = {
342
+ CallOps::SEND_INITIAL_METADATA => nil
343
+ }
344
+ server_call.run_batch(@server_queue, @server_tag, deadline, server_ops)
345
+
346
+ # client receives nothing as expected
347
+ client_ops = {
348
+ CallOps::RECV_INITIAL_METADATA => nil
349
+ }
350
+ batch_result = call.run_batch(@client_queue, @client_tag, deadline,
351
+ client_ops)
352
+ expect(batch_result.metadata).to eq({})
353
+ end
354
+
355
+ it 'sends all the pairs when keys and values are valid' do
356
+ @valid_metadata.each do |md|
357
+ recvd_rpc = nil
358
+ rcv_thread = Thread.new do
359
+ recvd_rpc = @server.request_call(@server_queue, @server_tag, deadline)
360
+ end
361
+
362
+ call = new_client_call
363
+ # client signals that it's done sending metadata to allow server to
364
+ # respond
365
+ client_ops = {
366
+ CallOps::SEND_INITIAL_METADATA => nil
367
+ }
368
+ call.run_batch(@client_queue, @client_tag, deadline, client_ops)
369
+
370
+ # server gets the invocation but sends no metadata back
371
+ rcv_thread.join
372
+ expect(recvd_rpc).to_not eq nil
373
+ server_call = recvd_rpc.call
374
+ server_ops = {
375
+ CallOps::SEND_INITIAL_METADATA => md
376
+ }
377
+ server_call.run_batch(@server_queue, @server_tag, deadline, server_ops)
378
+
379
+ # client receives nothing as expected
380
+ client_ops = {
381
+ CallOps::RECV_INITIAL_METADATA => nil
382
+ }
383
+ batch_result = call.run_batch(@client_queue, @client_tag, deadline,
384
+ client_ops)
385
+ replace_symbols = Hash[md.each_pair.collect { |x, y| [x.to_s, y] }]
386
+ expect(batch_result.metadata).to eq(replace_symbols)
387
+ end
388
+ end
389
+ end
390
+ end
391
+
392
+ describe 'the http client/server' do
393
+ before(:example) do
394
+ server_host = '0.0.0.0:0'
395
+ @client_queue = GRPC::Core::CompletionQueue.new
396
+ @server_queue = GRPC::Core::CompletionQueue.new
397
+ @server = GRPC::Core::Server.new(@server_queue, nil)
398
+ server_port = @server.add_http2_port(server_host, :this_port_is_insecure)
399
+ @server.start
400
+ @ch = Channel.new("0.0.0.0:#{server_port}", nil, :this_channel_is_insecure)
401
+ end
402
+
403
+ after(:example) do
404
+ @ch.close
405
+ @server.close(@server_queue, deadline)
406
+ end
407
+
408
+ it_behaves_like 'basic GRPC message delivery is OK' do
409
+ end
410
+
411
+ it_behaves_like 'GRPC metadata delivery works OK' do
412
+ end
413
+ end
414
+
415
+ describe 'the secure http client/server' do
416
+ include_context 'setup: tags'
417
+
418
+ def load_test_certs
419
+ test_root = File.join(File.dirname(__FILE__), 'testdata')
420
+ files = ['ca.pem', 'server1.key', 'server1.pem']
421
+ files.map { |f| File.open(File.join(test_root, f)).read }
422
+ end
423
+
424
+ before(:example) do
425
+ certs = load_test_certs
426
+ server_host = '0.0.0.0:0'
427
+ @client_queue = GRPC::Core::CompletionQueue.new
428
+ @server_queue = GRPC::Core::CompletionQueue.new
429
+ server_creds = GRPC::Core::ServerCredentials.new(
430
+ nil, [{ private_key: certs[1], cert_chain: certs[2] }], false)
431
+ @server = GRPC::Core::Server.new(@server_queue, nil)
432
+ server_port = @server.add_http2_port(server_host, server_creds)
433
+ @server.start
434
+ args = { Channel::SSL_TARGET => 'foo.test.google.fr' }
435
+ @ch = Channel.new("0.0.0.0:#{server_port}", args,
436
+ GRPC::Core::ChannelCredentials.new(certs[0], nil, nil))
437
+ end
438
+
439
+ after(:example) do
440
+ @server.close(@server_queue, deadline)
441
+ end
442
+
443
+ it_behaves_like 'basic GRPC message delivery is OK' do
444
+ end
445
+
446
+ it_behaves_like 'GRPC metadata delivery works OK' do
447
+ end
448
+
449
+ it 'modifies metadata with CallCredentials' do
450
+ auth_proc = proc { { 'k1' => 'updated-v1' } }
451
+ call_creds = GRPC::Core::CallCredentials.new(auth_proc)
452
+ md = { 'k2' => 'v2' }
453
+ expected_md = { 'k1' => 'updated-v1', 'k2' => 'v2' }
454
+ recvd_rpc = nil
455
+ rcv_thread = Thread.new do
456
+ recvd_rpc = @server.request_call(@server_queue, @server_tag, deadline)
457
+ end
458
+
459
+ call = new_client_call
460
+ call.set_credentials! call_creds
461
+ client_ops = {
462
+ CallOps::SEND_INITIAL_METADATA => md
463
+ }
464
+ batch_result = call.run_batch(@client_queue, @client_tag, deadline,
465
+ client_ops)
466
+ expect(batch_result.send_metadata).to be true
467
+
468
+ # confirm the server can receive the client metadata
469
+ rcv_thread.join
470
+ expect(recvd_rpc).to_not eq nil
471
+ recvd_md = recvd_rpc.metadata
472
+ replace_symbols = Hash[expected_md.each_pair.collect { |x, y| [x.to_s, y] }]
473
+ expect(recvd_md).to eq(recvd_md.merge(replace_symbols))
474
+ end
475
+ end