grpc 0.5.0
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.
- checksums.yaml +7 -0
- data/.gitignore +15 -0
- data/.rspec +1 -0
- data/.rubocop.yml +10 -0
- data/.rubocop_todo.yml +52 -0
- data/Gemfile +4 -0
- data/README.md +82 -0
- data/Rakefile +54 -0
- data/bin/apis/google/protobuf/empty.rb +44 -0
- data/bin/apis/pubsub_demo.rb +267 -0
- data/bin/apis/tech/pubsub/proto/pubsub.rb +174 -0
- data/bin/apis/tech/pubsub/proto/pubsub_services.rb +103 -0
- data/bin/interop/README.md +8 -0
- data/bin/interop/interop_client.rb +334 -0
- data/bin/interop/interop_server.rb +192 -0
- data/bin/interop/test/cpp/interop/empty.rb +44 -0
- data/bin/interop/test/cpp/interop/messages.rb +89 -0
- data/bin/interop/test/cpp/interop/test.rb +43 -0
- data/bin/interop/test/cpp/interop/test_services.rb +60 -0
- data/bin/math.proto +80 -0
- data/bin/math.rb +61 -0
- data/bin/math_client.rb +147 -0
- data/bin/math_server.rb +190 -0
- data/bin/math_services.rb +56 -0
- data/bin/noproto_client.rb +108 -0
- data/bin/noproto_server.rb +112 -0
- data/ext/grpc/extconf.rb +76 -0
- data/ext/grpc/rb_byte_buffer.c +241 -0
- data/ext/grpc/rb_byte_buffer.h +54 -0
- data/ext/grpc/rb_call.c +569 -0
- data/ext/grpc/rb_call.h +59 -0
- data/ext/grpc/rb_channel.c +264 -0
- data/ext/grpc/rb_channel.h +49 -0
- data/ext/grpc/rb_channel_args.c +154 -0
- data/ext/grpc/rb_channel_args.h +52 -0
- data/ext/grpc/rb_completion_queue.c +185 -0
- data/ext/grpc/rb_completion_queue.h +50 -0
- data/ext/grpc/rb_credentials.c +281 -0
- data/ext/grpc/rb_credentials.h +50 -0
- data/ext/grpc/rb_event.c +361 -0
- data/ext/grpc/rb_event.h +53 -0
- data/ext/grpc/rb_grpc.c +274 -0
- data/ext/grpc/rb_grpc.h +74 -0
- data/ext/grpc/rb_metadata.c +215 -0
- data/ext/grpc/rb_metadata.h +53 -0
- data/ext/grpc/rb_server.c +278 -0
- data/ext/grpc/rb_server.h +50 -0
- data/ext/grpc/rb_server_credentials.c +210 -0
- data/ext/grpc/rb_server_credentials.h +50 -0
- data/grpc.gemspec +41 -0
- data/lib/grpc.rb +39 -0
- data/lib/grpc/core/event.rb +44 -0
- data/lib/grpc/core/time_consts.rb +71 -0
- data/lib/grpc/errors.rb +61 -0
- data/lib/grpc/generic/active_call.rb +536 -0
- data/lib/grpc/generic/bidi_call.rb +221 -0
- data/lib/grpc/generic/client_stub.rb +413 -0
- data/lib/grpc/generic/rpc_desc.rb +150 -0
- data/lib/grpc/generic/rpc_server.rb +404 -0
- data/lib/grpc/generic/service.rb +235 -0
- data/lib/grpc/logconfig.rb +40 -0
- data/lib/grpc/version.rb +33 -0
- data/spec/alloc_spec.rb +44 -0
- data/spec/byte_buffer_spec.rb +67 -0
- data/spec/call_spec.rb +163 -0
- data/spec/channel_spec.rb +181 -0
- data/spec/client_server_spec.rb +372 -0
- data/spec/completion_queue_spec.rb +74 -0
- data/spec/credentials_spec.rb +71 -0
- data/spec/event_spec.rb +53 -0
- data/spec/generic/active_call_spec.rb +373 -0
- data/spec/generic/client_stub_spec.rb +519 -0
- data/spec/generic/rpc_desc_spec.rb +357 -0
- data/spec/generic/rpc_server_pool_spec.rb +139 -0
- data/spec/generic/rpc_server_spec.rb +404 -0
- data/spec/generic/service_spec.rb +342 -0
- data/spec/metadata_spec.rb +64 -0
- data/spec/server_credentials_spec.rb +69 -0
- data/spec/server_spec.rb +212 -0
- data/spec/spec_helper.rb +51 -0
- data/spec/testdata/README +1 -0
- data/spec/testdata/ca.pem +15 -0
- data/spec/testdata/server1.key +16 -0
- data/spec/testdata/server1.pem +16 -0
- data/spec/time_consts_spec.rb +89 -0
- metadata +353 -0
@@ -0,0 +1,74 @@
|
|
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::CompletionQueue do
|
33
|
+
before(:example) do
|
34
|
+
@cq = GRPC::Core::CompletionQueue.new
|
35
|
+
end
|
36
|
+
|
37
|
+
describe '#new' do
|
38
|
+
it 'is constructed successufully' do
|
39
|
+
expect { GRPC::Core::CompletionQueue.new }.not_to raise_error
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe '#next' do
|
44
|
+
it 'can be called without failing' do
|
45
|
+
expect { @cq.next(3) }.not_to raise_error
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'can be called with a time constant' do
|
49
|
+
# don't use INFINITE_FUTURE, as are no events and this blocks.
|
50
|
+
#
|
51
|
+
# don't use INFINITE_PAST, as this fails on docker, and does not need to
|
52
|
+
# be tested, as its not used anywhere in the ruby implementation
|
53
|
+
a_time = GRPC::Core::TimeConsts::ZERO
|
54
|
+
expect { @cq.next(a_time) }.not_to raise_error
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe '#pluck' do
|
59
|
+
it 'can be called without failing' do
|
60
|
+
tag = Object.new
|
61
|
+
expect { @cq.pluck(tag, 3) }.not_to raise_error
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'can be called with a time constant' do
|
65
|
+
# don't use INFINITE_FUTURE, as there no events and this blocks.
|
66
|
+
#
|
67
|
+
# don't use INFINITE_PAST, as this fails on docker, and does not need to
|
68
|
+
# be tested, as its not used anywhere in the ruby implementation
|
69
|
+
tag = Object.new
|
70
|
+
a_time = GRPC::Core::TimeConsts::ZERO
|
71
|
+
expect { @cq.pluck(tag, a_time) }.not_to raise_error
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,71 @@
|
|
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.pem', 'server1.key']
|
35
|
+
files.map { |f| File.open(File.join(test_root, f)).read }
|
36
|
+
end
|
37
|
+
|
38
|
+
Credentials = GRPC::Core::Credentials
|
39
|
+
|
40
|
+
describe Credentials do
|
41
|
+
describe '#new' do
|
42
|
+
it 'can be constructed with fake inputs' do
|
43
|
+
expect { Credentials.new('root_certs', 'key', 'cert') }.not_to raise_error
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'it can be constructed using specific test certificates' do
|
47
|
+
certs = load_test_certs
|
48
|
+
expect { Credentials.new(*certs) }.not_to raise_error
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'can be constructed with server roots certs only' do
|
52
|
+
root_cert, _, _ = load_test_certs
|
53
|
+
expect { Credentials.new(root_cert) }.not_to raise_error
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'cannot be constructed with a nil server roots' do
|
57
|
+
_, client_key, client_chain = load_test_certs
|
58
|
+
blk = proc { Credentials.new(nil, client_key, client_chain) }
|
59
|
+
expect(&blk).to raise_error
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe '#compose' do
|
64
|
+
it 'can be completed OK' do
|
65
|
+
certs = load_test_certs
|
66
|
+
cred1 = Credentials.new(*certs)
|
67
|
+
cred2 = Credentials.new(*certs)
|
68
|
+
expect { cred1.compose(cred2) }.to_not raise_error
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
data/spec/event_spec.rb
ADDED
@@ -0,0 +1,53 @@
|
|
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::CompletionType do
|
33
|
+
before(:each) do
|
34
|
+
@known_types = {
|
35
|
+
QUEUE_SHUTDOWN: 0,
|
36
|
+
OP_COMPLETE: 1,
|
37
|
+
READ: 2,
|
38
|
+
WRITE_ACCEPTED: 3,
|
39
|
+
FINISH_ACCEPTED: 4,
|
40
|
+
CLIENT_METADATA_READ: 5,
|
41
|
+
FINISHED: 6,
|
42
|
+
SERVER_RPC_NEW: 7,
|
43
|
+
SERVER_SHUTDOWN: 8,
|
44
|
+
RESERVED: 9
|
45
|
+
}
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'should have all the known types' do
|
49
|
+
mod = GRPC::Core::CompletionType
|
50
|
+
blk = proc { Hash[mod.constants.collect { |c| [c, mod.const_get(c)] }] }
|
51
|
+
expect(blk.call).to eq(@known_types)
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,373 @@
|
|
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::ActiveCall do
|
35
|
+
ActiveCall = GRPC::ActiveCall
|
36
|
+
Call = GRPC::Core::Call
|
37
|
+
CompletionType = GRPC::Core::CompletionType
|
38
|
+
|
39
|
+
before(:each) do
|
40
|
+
@pass_through = proc { |x| x }
|
41
|
+
@server_tag = Object.new
|
42
|
+
@server_done_tag = Object.new
|
43
|
+
@tag = Object.new
|
44
|
+
|
45
|
+
@client_queue = GRPC::Core::CompletionQueue.new
|
46
|
+
@server_queue = GRPC::Core::CompletionQueue.new
|
47
|
+
host = '0.0.0.0:0'
|
48
|
+
@server = GRPC::Core::Server.new(@server_queue, nil)
|
49
|
+
server_port = @server.add_http2_port(host)
|
50
|
+
@server.start
|
51
|
+
@ch = GRPC::Core::Channel.new("localhost:#{server_port}", nil)
|
52
|
+
end
|
53
|
+
|
54
|
+
after(:each) do
|
55
|
+
@server.close
|
56
|
+
end
|
57
|
+
|
58
|
+
describe 'restricted view methods' do
|
59
|
+
before(:each) do
|
60
|
+
call = make_test_call
|
61
|
+
done_tag, meta_tag = ActiveCall.client_invoke(call, @client_queue,
|
62
|
+
deadline)
|
63
|
+
@client_call = ActiveCall.new(call, @client_queue, @pass_through,
|
64
|
+
@pass_through, deadline,
|
65
|
+
finished_tag: done_tag,
|
66
|
+
read_metadata_tag: meta_tag)
|
67
|
+
end
|
68
|
+
|
69
|
+
describe '#multi_req_view' do
|
70
|
+
xit 'exposes a fixed subset of the ActiveCall methods' do
|
71
|
+
want = %w(cancelled, deadline, each_remote_read, shutdown)
|
72
|
+
v = @client_call.multi_req_view
|
73
|
+
want.each do |w|
|
74
|
+
expect(v.methods.include?(w))
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
describe '#single_req_view' do
|
80
|
+
xit 'exposes a fixed subset of the ActiveCall methods' do
|
81
|
+
want = %w(cancelled, deadline, shutdown)
|
82
|
+
v = @client_call.single_req_view
|
83
|
+
want.each do |w|
|
84
|
+
expect(v.methods.include?(w))
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
describe '#remote_send' do
|
91
|
+
it 'allows a client to send a payload to the server' do
|
92
|
+
call = make_test_call
|
93
|
+
done_tag, meta_tag = ActiveCall.client_invoke(call, @client_queue,
|
94
|
+
deadline)
|
95
|
+
@client_call = ActiveCall.new(call, @client_queue, @pass_through,
|
96
|
+
@pass_through, deadline,
|
97
|
+
finished_tag: done_tag,
|
98
|
+
read_metadata_tag: meta_tag)
|
99
|
+
msg = 'message is a string'
|
100
|
+
@client_call.remote_send(msg)
|
101
|
+
|
102
|
+
# check that server rpc new was received
|
103
|
+
@server.request_call(@server_tag)
|
104
|
+
ev = @server_queue.next(deadline)
|
105
|
+
expect(ev.type).to be(CompletionType::SERVER_RPC_NEW)
|
106
|
+
expect(ev.call).to be_a(Call)
|
107
|
+
expect(ev.tag).to be(@server_tag)
|
108
|
+
|
109
|
+
# Accept the call, and verify that the server reads the response ok.
|
110
|
+
ev.call.server_accept(@client_queue, @server_tag)
|
111
|
+
ev.call.server_end_initial_metadata
|
112
|
+
server_call = ActiveCall.new(ev.call, @client_queue, @pass_through,
|
113
|
+
@pass_through, deadline)
|
114
|
+
expect(server_call.remote_read).to eq(msg)
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'marshals the payload using the marshal func' do
|
118
|
+
call = make_test_call
|
119
|
+
done_tag, meta_tag = ActiveCall.client_invoke(call, @client_queue,
|
120
|
+
deadline)
|
121
|
+
marshal = proc { |x| 'marshalled:' + x }
|
122
|
+
client_call = ActiveCall.new(call, @client_queue, marshal,
|
123
|
+
@pass_through, deadline,
|
124
|
+
finished_tag: done_tag,
|
125
|
+
read_metadata_tag: meta_tag)
|
126
|
+
msg = 'message is a string'
|
127
|
+
client_call.remote_send(msg)
|
128
|
+
|
129
|
+
# confirm that the message was marshalled
|
130
|
+
@server.request_call(@server_tag)
|
131
|
+
ev = @server_queue.next(deadline)
|
132
|
+
ev.call.server_accept(@client_queue, @server_tag)
|
133
|
+
ev.call.server_end_initial_metadata
|
134
|
+
server_call = ActiveCall.new(ev.call, @client_queue, @pass_through,
|
135
|
+
@pass_through, deadline)
|
136
|
+
expect(server_call.remote_read).to eq('marshalled:' + msg)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
describe '#client_invoke' do
|
141
|
+
it 'sends keywords as metadata to the server when the are present' do
|
142
|
+
call = make_test_call
|
143
|
+
ActiveCall.client_invoke(call, @client_queue, deadline,
|
144
|
+
k1: 'v1', k2: 'v2')
|
145
|
+
@server.request_call(@server_tag)
|
146
|
+
ev = @server_queue.next(deadline)
|
147
|
+
expect(ev).to_not be_nil
|
148
|
+
expect(ev.result.metadata['k1']).to eq('v1')
|
149
|
+
expect(ev.result.metadata['k2']).to eq('v2')
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
describe '#remote_read' do
|
154
|
+
it 'reads the response sent by a server' do
|
155
|
+
call = make_test_call
|
156
|
+
done_tag, meta_tag = ActiveCall.client_invoke(call, @client_queue,
|
157
|
+
deadline)
|
158
|
+
client_call = ActiveCall.new(call, @client_queue, @pass_through,
|
159
|
+
@pass_through, deadline,
|
160
|
+
finished_tag: done_tag,
|
161
|
+
read_metadata_tag: meta_tag)
|
162
|
+
msg = 'message is a string'
|
163
|
+
client_call.remote_send(msg)
|
164
|
+
server_call = expect_server_to_receive(msg)
|
165
|
+
server_call.remote_send('server_response')
|
166
|
+
expect(client_call.remote_read).to eq('server_response')
|
167
|
+
end
|
168
|
+
|
169
|
+
it 'saves no metadata when the server adds no metadata' do
|
170
|
+
call = make_test_call
|
171
|
+
done_tag, meta_tag = ActiveCall.client_invoke(call, @client_queue,
|
172
|
+
deadline)
|
173
|
+
client_call = ActiveCall.new(call, @client_queue, @pass_through,
|
174
|
+
@pass_through, deadline,
|
175
|
+
finished_tag: done_tag,
|
176
|
+
read_metadata_tag: meta_tag)
|
177
|
+
msg = 'message is a string'
|
178
|
+
client_call.remote_send(msg)
|
179
|
+
server_call = expect_server_to_receive(msg)
|
180
|
+
server_call.remote_send('ignore me')
|
181
|
+
expect(client_call.metadata).to be_nil
|
182
|
+
client_call.remote_read
|
183
|
+
expect(client_call.metadata).to eq({})
|
184
|
+
end
|
185
|
+
|
186
|
+
it 'saves metadata add by the server' do
|
187
|
+
call = make_test_call
|
188
|
+
done_tag, meta_tag = ActiveCall.client_invoke(call, @client_queue,
|
189
|
+
deadline)
|
190
|
+
client_call = ActiveCall.new(call, @client_queue, @pass_through,
|
191
|
+
@pass_through, deadline,
|
192
|
+
finished_tag: done_tag,
|
193
|
+
read_metadata_tag: meta_tag)
|
194
|
+
msg = 'message is a string'
|
195
|
+
client_call.remote_send(msg)
|
196
|
+
server_call = expect_server_to_receive(msg, k1: 'v1', k2: 'v2')
|
197
|
+
server_call.remote_send('ignore me')
|
198
|
+
expect(client_call.metadata).to be_nil
|
199
|
+
client_call.remote_read
|
200
|
+
expected = { 'k1' => 'v1', 'k2' => 'v2' }
|
201
|
+
expect(client_call.metadata).to eq(expected)
|
202
|
+
end
|
203
|
+
|
204
|
+
it 'get a nil msg before a status when an OK status is sent' do
|
205
|
+
call = make_test_call
|
206
|
+
done_tag, meta_tag = ActiveCall.client_invoke(call, @client_queue,
|
207
|
+
deadline)
|
208
|
+
client_call = ActiveCall.new(call, @client_queue, @pass_through,
|
209
|
+
@pass_through, deadline,
|
210
|
+
finished_tag: done_tag,
|
211
|
+
read_metadata_tag: meta_tag)
|
212
|
+
msg = 'message is a string'
|
213
|
+
client_call.remote_send(msg)
|
214
|
+
client_call.writes_done(false)
|
215
|
+
server_call = expect_server_to_receive(msg)
|
216
|
+
server_call.remote_send('server_response')
|
217
|
+
server_call.send_status(OK, 'OK')
|
218
|
+
expect(client_call.remote_read).to eq('server_response')
|
219
|
+
res = client_call.remote_read
|
220
|
+
expect(res).to be_nil
|
221
|
+
end
|
222
|
+
|
223
|
+
it 'unmarshals the response using the unmarshal func' do
|
224
|
+
call = make_test_call
|
225
|
+
done_tag, meta_tag = ActiveCall.client_invoke(call, @client_queue,
|
226
|
+
deadline)
|
227
|
+
unmarshal = proc { |x| 'unmarshalled:' + x }
|
228
|
+
client_call = ActiveCall.new(call, @client_queue, @pass_through,
|
229
|
+
unmarshal, deadline,
|
230
|
+
finished_tag: done_tag,
|
231
|
+
read_metadata_tag: meta_tag)
|
232
|
+
|
233
|
+
# confirm the client receives the unmarshalled message
|
234
|
+
msg = 'message is a string'
|
235
|
+
client_call.remote_send(msg)
|
236
|
+
server_call = expect_server_to_receive(msg)
|
237
|
+
server_call.remote_send('server_response')
|
238
|
+
expect(client_call.remote_read).to eq('unmarshalled:server_response')
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
describe '#each_remote_read' do
|
243
|
+
it 'creates an Enumerator' do
|
244
|
+
call = make_test_call
|
245
|
+
client_call = ActiveCall.new(call, @client_queue, @pass_through,
|
246
|
+
@pass_through, deadline)
|
247
|
+
expect(client_call.each_remote_read).to be_a(Enumerator)
|
248
|
+
end
|
249
|
+
|
250
|
+
it 'the returns an enumerator that can read n responses' do
|
251
|
+
call = make_test_call
|
252
|
+
done_tag, meta_tag = ActiveCall.client_invoke(call, @client_queue,
|
253
|
+
deadline)
|
254
|
+
client_call = ActiveCall.new(call, @client_queue, @pass_through,
|
255
|
+
@pass_through, deadline,
|
256
|
+
finished_tag: done_tag,
|
257
|
+
read_metadata_tag: meta_tag)
|
258
|
+
msg = 'message is 4a string'
|
259
|
+
reply = 'server_response'
|
260
|
+
client_call.remote_send(msg)
|
261
|
+
server_call = expect_server_to_receive(msg)
|
262
|
+
e = client_call.each_remote_read
|
263
|
+
n = 3 # arbitrary value > 1
|
264
|
+
n.times do
|
265
|
+
server_call.remote_send(reply)
|
266
|
+
expect(e.next).to eq(reply)
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
it 'the returns an enumerator that stops after an OK Status' do
|
271
|
+
call = make_test_call
|
272
|
+
done_tag, meta_tag = ActiveCall.client_invoke(call, @client_queue,
|
273
|
+
deadline)
|
274
|
+
client_call = ActiveCall.new(call, @client_queue, @pass_through,
|
275
|
+
@pass_through, deadline,
|
276
|
+
read_metadata_tag: meta_tag,
|
277
|
+
finished_tag: done_tag)
|
278
|
+
msg = 'message is a string'
|
279
|
+
reply = 'server_response'
|
280
|
+
client_call.remote_send(msg)
|
281
|
+
client_call.writes_done(false)
|
282
|
+
server_call = expect_server_to_receive(msg)
|
283
|
+
e = client_call.each_remote_read
|
284
|
+
n = 3 # arbitrary value > 1
|
285
|
+
n.times do
|
286
|
+
server_call.remote_send(reply)
|
287
|
+
expect(e.next).to eq(reply)
|
288
|
+
end
|
289
|
+
server_call.send_status(OK, 'OK')
|
290
|
+
expect { e.next }.to raise_error(StopIteration)
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
294
|
+
describe '#writes_done' do
|
295
|
+
it 'finishes ok if the server sends a status response' do
|
296
|
+
call = make_test_call
|
297
|
+
done_tag, meta_tag = ActiveCall.client_invoke(call, @client_queue,
|
298
|
+
deadline)
|
299
|
+
client_call = ActiveCall.new(call, @client_queue, @pass_through,
|
300
|
+
@pass_through, deadline,
|
301
|
+
finished_tag: done_tag,
|
302
|
+
read_metadata_tag: meta_tag)
|
303
|
+
msg = 'message is a string'
|
304
|
+
client_call.remote_send(msg)
|
305
|
+
expect { client_call.writes_done(false) }.to_not raise_error
|
306
|
+
server_call = expect_server_to_receive(msg)
|
307
|
+
server_call.remote_send('server_response')
|
308
|
+
expect(client_call.remote_read).to eq('server_response')
|
309
|
+
server_call.send_status(OK, 'status code is OK')
|
310
|
+
expect { client_call.finished }.to_not raise_error
|
311
|
+
end
|
312
|
+
|
313
|
+
it 'finishes ok if the server sends an early status response' do
|
314
|
+
call = make_test_call
|
315
|
+
done_tag, meta_tag = ActiveCall.client_invoke(call, @client_queue,
|
316
|
+
deadline)
|
317
|
+
client_call = ActiveCall.new(call, @client_queue, @pass_through,
|
318
|
+
@pass_through, deadline,
|
319
|
+
read_metadata_tag: meta_tag,
|
320
|
+
finished_tag: done_tag)
|
321
|
+
msg = 'message is a string'
|
322
|
+
client_call.remote_send(msg)
|
323
|
+
server_call = expect_server_to_receive(msg)
|
324
|
+
server_call.remote_send('server_response')
|
325
|
+
server_call.send_status(OK, 'status code is OK')
|
326
|
+
expect(client_call.remote_read).to eq('server_response')
|
327
|
+
expect { client_call.writes_done(false) }.to_not raise_error
|
328
|
+
expect { client_call.finished }.to_not raise_error
|
329
|
+
end
|
330
|
+
|
331
|
+
it 'finishes ok if writes_done is true' do
|
332
|
+
call = make_test_call
|
333
|
+
done_tag, meta_tag = ActiveCall.client_invoke(call, @client_queue,
|
334
|
+
deadline)
|
335
|
+
client_call = ActiveCall.new(call, @client_queue, @pass_through,
|
336
|
+
@pass_through, deadline,
|
337
|
+
read_metadata_tag: meta_tag,
|
338
|
+
finished_tag: done_tag)
|
339
|
+
msg = 'message is a string'
|
340
|
+
client_call.remote_send(msg)
|
341
|
+
server_call = expect_server_to_receive(msg)
|
342
|
+
server_call.remote_send('server_response')
|
343
|
+
server_call.send_status(OK, 'status code is OK')
|
344
|
+
expect(client_call.remote_read).to eq('server_response')
|
345
|
+
expect { client_call.writes_done(true) }.to_not raise_error
|
346
|
+
end
|
347
|
+
end
|
348
|
+
|
349
|
+
def expect_server_to_receive(sent_text, **kw)
|
350
|
+
c = expect_server_to_be_invoked(**kw)
|
351
|
+
expect(c.remote_read).to eq(sent_text)
|
352
|
+
c
|
353
|
+
end
|
354
|
+
|
355
|
+
def expect_server_to_be_invoked(**kw)
|
356
|
+
@server.request_call(@server_tag)
|
357
|
+
ev = @server_queue.next(deadline)
|
358
|
+
ev.call.add_metadata(kw)
|
359
|
+
ev.call.server_accept(@client_queue, @server_done_tag)
|
360
|
+
ev.call.server_end_initial_metadata
|
361
|
+
ActiveCall.new(ev.call, @client_queue, @pass_through,
|
362
|
+
@pass_through, deadline,
|
363
|
+
finished_tag: @server_done_tag)
|
364
|
+
end
|
365
|
+
|
366
|
+
def make_test_call
|
367
|
+
@ch.create_call('dummy_method', 'dummy_host', deadline)
|
368
|
+
end
|
369
|
+
|
370
|
+
def deadline
|
371
|
+
Time.now + 1 # in 1 second; arbitrary
|
372
|
+
end
|
373
|
+
end
|