grpc 0.6.0 → 0.6.1
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 +4 -4
- data/.rspec +1 -0
- data/.rubocop_todo.yml +12 -20
- data/CHANGELOG.md +11 -0
- data/Rakefile +1 -0
- data/bin/apis/pubsub_demo.rb +3 -6
- data/bin/interop/interop_client.rb +43 -3
- data/bin/interop/interop_server.rb +1 -1
- data/bin/math_server.rb +1 -1
- data/bin/noproto_server.rb +1 -1
- data/ext/grpc/rb_byte_buffer.c +15 -189
- data/ext/grpc/rb_byte_buffer.h +4 -12
- data/ext/grpc/rb_call.c +514 -307
- data/ext/grpc/rb_call.h +4 -4
- data/ext/grpc/rb_channel.c +58 -34
- data/ext/grpc/rb_channel.h +0 -3
- data/ext/grpc/rb_channel_args.c +13 -4
- data/ext/grpc/rb_completion_queue.c +50 -23
- data/ext/grpc/rb_completion_queue.h +7 -3
- data/ext/grpc/rb_credentials.c +40 -28
- data/ext/grpc/rb_credentials.h +0 -4
- data/ext/grpc/rb_grpc.c +86 -67
- data/ext/grpc/rb_grpc.h +20 -10
- data/ext/grpc/rb_server.c +119 -26
- data/ext/grpc/rb_server.h +0 -4
- data/ext/grpc/rb_server_credentials.c +29 -16
- data/ext/grpc/rb_server_credentials.h +0 -4
- data/grpc.gemspec +11 -8
- data/lib/grpc.rb +1 -1
- data/lib/grpc/errors.rb +8 -7
- data/lib/grpc/generic/active_call.rb +104 -171
- data/lib/grpc/generic/bidi_call.rb +32 -60
- data/lib/grpc/generic/client_stub.rb +42 -31
- data/lib/grpc/generic/rpc_desc.rb +7 -12
- data/lib/grpc/generic/rpc_server.rb +253 -170
- data/lib/grpc/{core/event.rb → notifier.rb} +25 -9
- data/lib/grpc/version.rb +1 -1
- data/spec/call_spec.rb +23 -40
- data/spec/channel_spec.rb +11 -20
- data/spec/client_server_spec.rb +193 -175
- data/spec/credentials_spec.rb +2 -2
- data/spec/generic/active_call_spec.rb +59 -85
- data/spec/generic/client_stub_spec.rb +46 -64
- data/spec/generic/rpc_desc_spec.rb +50 -80
- data/spec/generic/rpc_server_pool_spec.rb +2 -3
- data/spec/generic/rpc_server_spec.rb +158 -29
- data/spec/server_spec.rb +1 -1
- data/spec/spec_helper.rb +8 -4
- metadata +27 -37
- data/ext/grpc/rb_event.c +0 -361
- data/ext/grpc/rb_event.h +0 -53
- data/ext/grpc/rb_metadata.c +0 -215
- data/ext/grpc/rb_metadata.h +0 -53
- data/spec/alloc_spec.rb +0 -44
- data/spec/byte_buffer_spec.rb +0 -67
- data/spec/event_spec.rb +0 -53
- data/spec/metadata_spec.rb +0 -64
@@ -27,17 +27,33 @@
|
|
27
27
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
28
28
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
29
29
|
|
30
|
-
require 'grpc'
|
31
|
-
|
32
30
|
# GRPC contains the General RPC module.
|
33
31
|
module GRPC
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
32
|
+
# Notifier is useful high-level synchronization primitive.
|
33
|
+
class Notifier
|
34
|
+
attr_reader :payload, :notified
|
35
|
+
alias_method :notified?, :notified
|
36
|
+
|
37
|
+
def initialize
|
38
|
+
@mutex = Mutex.new
|
39
|
+
@cvar = ConditionVariable.new
|
40
|
+
@notified = false
|
41
|
+
@payload = nil
|
42
|
+
end
|
43
|
+
|
44
|
+
def wait
|
45
|
+
@mutex.synchronize do
|
46
|
+
@cvar.wait(@mutex) until notified?
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def notify(payload)
|
51
|
+
@mutex.synchronize do
|
52
|
+
return Error.new('already notified') if notified?
|
53
|
+
@payload = payload
|
54
|
+
@notified = true
|
55
|
+
@cvar.signal
|
56
|
+
return nil
|
41
57
|
end
|
42
58
|
end
|
43
59
|
end
|
data/lib/grpc/version.rb
CHANGED
data/spec/call_spec.rb
CHANGED
@@ -66,51 +66,34 @@ describe GRPC::Core::RpcErrors do
|
|
66
66
|
end
|
67
67
|
end
|
68
68
|
|
69
|
-
describe GRPC::Core::
|
69
|
+
describe GRPC::Core::CallOps do
|
70
70
|
before(:each) do
|
71
|
-
@
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
describe '#start_write' do
|
85
|
-
xit 'should fail if called immediately' do
|
86
|
-
bytes = GRPC::Core::ByteBuffer.new('test string')
|
87
|
-
blk = proc { make_test_call.start_write(bytes, @tag) }
|
88
|
-
expect(&blk).to raise_error GRPC::Core::CallError
|
89
|
-
end
|
71
|
+
@known_types = {
|
72
|
+
SEND_INITIAL_METADATA: 0,
|
73
|
+
SEND_MESSAGE: 1,
|
74
|
+
SEND_CLOSE_FROM_CLIENT: 2,
|
75
|
+
SEND_STATUS_FROM_SERVER: 3,
|
76
|
+
RECV_INITIAL_METADATA: 4,
|
77
|
+
RECV_MESSAGE: 5,
|
78
|
+
RECV_STATUS_ON_CLIENT: 6,
|
79
|
+
RECV_CLOSE_ON_SERVER: 7
|
80
|
+
}
|
90
81
|
end
|
91
82
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
end
|
83
|
+
it 'should have symbols for all the known operation types' do
|
84
|
+
m = GRPC::Core::CallOps
|
85
|
+
syms_and_codes = m.constants.collect { |c| [c, m.const_get(c)] }
|
86
|
+
expect(Hash[syms_and_codes]).to eq(@known_types)
|
97
87
|
end
|
88
|
+
end
|
98
89
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
end
|
104
|
-
end
|
90
|
+
describe GRPC::Core::Call do
|
91
|
+
let(:client_queue) { GRPC::Core::CompletionQueue.new }
|
92
|
+
let(:test_tag) { Object.new }
|
93
|
+
let(:fake_host) { 'localhost:10101' }
|
105
94
|
|
106
|
-
|
107
|
-
|
108
|
-
call = make_test_call
|
109
|
-
n = 37
|
110
|
-
one_md = proc { |x| [sprintf('key%d', x), sprintf('value%d', x)] }
|
111
|
-
metadata = Hash[n.times.collect { |i| one_md.call i }]
|
112
|
-
expect { call.add_metadata(metadata) }.to_not raise_error
|
113
|
-
end
|
95
|
+
before(:each) do
|
96
|
+
@ch = GRPC::Core::Channel.new(fake_host, nil)
|
114
97
|
end
|
115
98
|
|
116
99
|
describe '#status' do
|
@@ -154,7 +137,7 @@ describe GRPC::Core::Call do
|
|
154
137
|
end
|
155
138
|
|
156
139
|
def make_test_call
|
157
|
-
@ch.create_call('dummy_method', 'dummy_host', deadline)
|
140
|
+
@ch.create_call(client_queue, 'dummy_method', 'dummy_host', deadline)
|
158
141
|
end
|
159
142
|
|
160
143
|
def deadline
|
data/spec/channel_spec.rb
CHANGED
@@ -36,16 +36,13 @@ def load_test_certs
|
|
36
36
|
end
|
37
37
|
|
38
38
|
describe GRPC::Core::Channel do
|
39
|
-
|
39
|
+
let(:fake_host) { 'localhost:0' }
|
40
|
+
let(:cq) { GRPC::Core::CompletionQueue.new }
|
40
41
|
|
41
42
|
def create_test_cert
|
42
43
|
GRPC::Core::Credentials.new(load_test_certs[0])
|
43
44
|
end
|
44
45
|
|
45
|
-
before(:each) do
|
46
|
-
@cq = GRPC::Core::CompletionQueue.new
|
47
|
-
end
|
48
|
-
|
49
46
|
shared_examples '#new' do
|
50
47
|
it 'take a host name without channel args' do
|
51
48
|
expect { GRPC::Core::Channel.new('dummy_host', nil) }.not_to raise_error
|
@@ -61,7 +58,7 @@ describe GRPC::Core::Channel do
|
|
61
58
|
it 'does not take a hash with bad values as channel args' do
|
62
59
|
blk = construct_with_args(symbol: Object.new)
|
63
60
|
expect(&blk).to raise_error TypeError
|
64
|
-
blk = construct_with_args('1' =>
|
61
|
+
blk = construct_with_args('1' => {})
|
65
62
|
expect(&blk).to raise_error TypeError
|
66
63
|
end
|
67
64
|
|
@@ -115,25 +112,23 @@ describe GRPC::Core::Channel do
|
|
115
112
|
|
116
113
|
describe '#create_call' do
|
117
114
|
it 'creates a call OK' do
|
118
|
-
|
119
|
-
ch = GRPC::Core::Channel.new(host, nil)
|
115
|
+
ch = GRPC::Core::Channel.new(fake_host, nil)
|
120
116
|
|
121
117
|
deadline = Time.now + 5
|
122
118
|
|
123
119
|
blk = proc do
|
124
|
-
ch.create_call('dummy_method', 'dummy_host', deadline)
|
120
|
+
ch.create_call(cq, 'dummy_method', 'dummy_host', deadline)
|
125
121
|
end
|
126
122
|
expect(&blk).to_not raise_error
|
127
123
|
end
|
128
124
|
|
129
125
|
it 'raises an error if called on a closed channel' do
|
130
|
-
|
131
|
-
ch = GRPC::Core::Channel.new(host, nil)
|
126
|
+
ch = GRPC::Core::Channel.new(fake_host, nil)
|
132
127
|
ch.close
|
133
128
|
|
134
129
|
deadline = Time.now + 5
|
135
130
|
blk = proc do
|
136
|
-
ch.create_call('dummy_method', 'dummy_host', deadline)
|
131
|
+
ch.create_call(cq, 'dummy_method', 'dummy_host', deadline)
|
137
132
|
end
|
138
133
|
expect(&blk).to raise_error(RuntimeError)
|
139
134
|
end
|
@@ -141,15 +136,13 @@ describe GRPC::Core::Channel do
|
|
141
136
|
|
142
137
|
describe '#destroy' do
|
143
138
|
it 'destroys a channel ok' do
|
144
|
-
|
145
|
-
ch = GRPC::Core::Channel.new(host, nil)
|
139
|
+
ch = GRPC::Core::Channel.new(fake_host, nil)
|
146
140
|
blk = proc { ch.destroy }
|
147
141
|
expect(&blk).to_not raise_error
|
148
142
|
end
|
149
143
|
|
150
144
|
it 'can be called more than once without error' do
|
151
|
-
|
152
|
-
ch = GRPC::Core::Channel.new(host, nil)
|
145
|
+
ch = GRPC::Core::Channel.new(fake_host, nil)
|
153
146
|
blk = proc { ch.destroy }
|
154
147
|
blk.call
|
155
148
|
expect(&blk).to_not raise_error
|
@@ -164,15 +157,13 @@ describe GRPC::Core::Channel do
|
|
164
157
|
|
165
158
|
describe '#close' do
|
166
159
|
it 'closes a channel ok' do
|
167
|
-
|
168
|
-
ch = GRPC::Core::Channel.new(host, nil)
|
160
|
+
ch = GRPC::Core::Channel.new(fake_host, nil)
|
169
161
|
blk = proc { ch.close }
|
170
162
|
expect(&blk).to_not raise_error
|
171
163
|
end
|
172
164
|
|
173
165
|
it 'can be called more than once without error' do
|
174
|
-
|
175
|
-
ch = GRPC::Core::Channel.new(host, nil)
|
166
|
+
ch = GRPC::Core::Channel.new(fake_host, nil)
|
176
167
|
blk = proc { ch.close }
|
177
168
|
blk.call
|
178
169
|
expect(&blk).to_not raise_error
|
data/spec/client_server_spec.rb
CHANGED
@@ -30,7 +30,6 @@
|
|
30
30
|
require 'grpc'
|
31
31
|
require 'spec_helper'
|
32
32
|
|
33
|
-
include GRPC::Core::CompletionType
|
34
33
|
include GRPC::Core
|
35
34
|
|
36
35
|
def load_test_certs
|
@@ -40,6 +39,8 @@ def load_test_certs
|
|
40
39
|
end
|
41
40
|
|
42
41
|
shared_context 'setup: tags' do
|
42
|
+
let(:sent_message) { 'sent message' }
|
43
|
+
let(:reply_text) { 'the reply' }
|
43
44
|
before(:example) do
|
44
45
|
@server_finished_tag = Object.new
|
45
46
|
@client_finished_tag = Object.new
|
@@ -52,153 +53,136 @@ shared_context 'setup: tags' do
|
|
52
53
|
Time.now + 2
|
53
54
|
end
|
54
55
|
|
55
|
-
def expect_next_event_on(queue, type, tag)
|
56
|
-
ev = queue.pluck(tag, deadline)
|
57
|
-
if type.nil?
|
58
|
-
expect(ev).to be_nil
|
59
|
-
else
|
60
|
-
expect(ev).to_not be_nil
|
61
|
-
expect(ev.type).to be(type)
|
62
|
-
end
|
63
|
-
ev
|
64
|
-
end
|
65
|
-
|
66
56
|
def server_allows_client_to_proceed
|
67
|
-
@server.request_call(@server_tag)
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
server_call.server_end_initial_metadata
|
57
|
+
recvd_rpc = @server.request_call(@server_queue, @server_tag, deadline)
|
58
|
+
expect(recvd_rpc).to_not eq nil
|
59
|
+
server_call = recvd_rpc.call
|
60
|
+
ops = { CallOps::SEND_INITIAL_METADATA => {} }
|
61
|
+
svr_batch = server_call.run_batch(@server_queue, @server_tag, deadline, ops)
|
62
|
+
expect(svr_batch.send_metadata).to be true
|
74
63
|
server_call
|
75
64
|
end
|
76
65
|
|
77
|
-
def server_responds_with(server_call, reply_text)
|
78
|
-
reply = ByteBuffer.new(reply_text)
|
79
|
-
server_call.start_read(@server_tag)
|
80
|
-
ev = @server_queue.pluck(@server_tag, TimeConsts::INFINITE_FUTURE)
|
81
|
-
expect(ev.type).to be(READ)
|
82
|
-
server_call.start_write(reply, @server_tag)
|
83
|
-
ev = @server_queue.pluck(@server_tag, TimeConsts::INFINITE_FUTURE)
|
84
|
-
expect(ev).not_to be_nil
|
85
|
-
expect(ev.type).to be(WRITE_ACCEPTED)
|
86
|
-
end
|
87
|
-
|
88
|
-
def client_sends(call, sent = 'a message')
|
89
|
-
req = ByteBuffer.new(sent)
|
90
|
-
call.start_write(req, @tag)
|
91
|
-
ev = @client_queue.pluck(@tag, TimeConsts::INFINITE_FUTURE)
|
92
|
-
expect(ev).not_to be_nil
|
93
|
-
expect(ev.type).to be(WRITE_ACCEPTED)
|
94
|
-
sent
|
95
|
-
end
|
96
|
-
|
97
66
|
def new_client_call
|
98
|
-
@ch.create_call('/method', 'foo.test.google.fr', deadline)
|
67
|
+
@ch.create_call(@client_queue, '/method', 'foo.test.google.fr', deadline)
|
99
68
|
end
|
100
69
|
end
|
101
70
|
|
102
71
|
shared_examples 'basic GRPC message delivery is OK' do
|
72
|
+
include GRPC::Core
|
103
73
|
include_context 'setup: tags'
|
104
74
|
|
105
|
-
it 'servers receive requests from clients and
|
106
|
-
reply = ByteBuffer.new('the server payload')
|
75
|
+
it 'servers receive requests from clients and can respond' do
|
107
76
|
call = new_client_call
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
# server_call.server_accept(@server_queue, @server_finished_tag)
|
117
|
-
# server_call.server_end_initial_metadata
|
118
|
-
server_call = server_allows_client_to_proceed
|
119
|
-
|
120
|
-
# client sends a message
|
121
|
-
msg = client_sends(call)
|
77
|
+
client_ops = {
|
78
|
+
CallOps::SEND_INITIAL_METADATA => {},
|
79
|
+
CallOps::SEND_MESSAGE => sent_message
|
80
|
+
}
|
81
|
+
batch_result = call.run_batch(@client_queue, @client_tag, deadline,
|
82
|
+
client_ops)
|
83
|
+
expect(batch_result.send_metadata).to be true
|
84
|
+
expect(batch_result.send_message).to be true
|
122
85
|
|
123
86
|
# confirm the server can read the inbound message
|
124
|
-
server_call
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
87
|
+
server_call = server_allows_client_to_proceed
|
88
|
+
server_ops = {
|
89
|
+
CallOps::RECV_MESSAGE => nil
|
90
|
+
}
|
91
|
+
svr_batch = server_call.run_batch(@server_queue, @server_tag, deadline,
|
92
|
+
server_ops)
|
93
|
+
expect(svr_batch.message).to eq(sent_message)
|
131
94
|
end
|
132
95
|
|
133
96
|
it 'responses written by servers are received by the client' do
|
134
97
|
call = new_client_call
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
98
|
+
client_ops = {
|
99
|
+
CallOps::SEND_INITIAL_METADATA => {},
|
100
|
+
CallOps::SEND_MESSAGE => sent_message
|
101
|
+
}
|
102
|
+
batch_result = call.run_batch(@client_queue, @client_tag, deadline,
|
103
|
+
client_ops)
|
104
|
+
expect(batch_result.send_metadata).to be true
|
105
|
+
expect(batch_result.send_message).to be true
|
139
106
|
|
140
|
-
|
141
|
-
|
142
|
-
|
107
|
+
# confirm the server can read the inbound message
|
108
|
+
server_call = server_allows_client_to_proceed
|
109
|
+
server_ops = {
|
110
|
+
CallOps::RECV_MESSAGE => nil,
|
111
|
+
CallOps::SEND_MESSAGE => reply_text
|
112
|
+
}
|
113
|
+
svr_batch = server_call.run_batch(@server_queue, @server_tag, deadline,
|
114
|
+
server_ops)
|
115
|
+
expect(svr_batch.message).to eq(sent_message)
|
116
|
+
expect(svr_batch.send_message).to be true
|
143
117
|
end
|
144
118
|
|
145
119
|
it 'servers can ignore a client write and send a status' do
|
146
120
|
call = new_client_call
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
server_call
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
expect_next_event_on(@client_queue, CLIENT_METADATA_READ,
|
167
|
-
@client_metadata_tag)
|
168
|
-
ev = expect_next_event_on(@client_queue, READ, @tag)
|
169
|
-
expect(ev.tag).to be(@tag)
|
170
|
-
expect(ev.result.to_s).to eq('')
|
171
|
-
|
172
|
-
# finally, after client sends writes_done, they get the finished.
|
173
|
-
call.writes_done(@tag)
|
174
|
-
expect_next_event_on(@client_queue, FINISH_ACCEPTED, @tag)
|
175
|
-
ev = expect_next_event_on(@client_queue, FINISHED, @client_finished_tag)
|
176
|
-
expect(ev.result.code).to eq(StatusCodes::NOT_FOUND)
|
121
|
+
client_ops = {
|
122
|
+
CallOps::SEND_INITIAL_METADATA => {},
|
123
|
+
CallOps::SEND_MESSAGE => sent_message
|
124
|
+
}
|
125
|
+
batch_result = call.run_batch(@client_queue, @client_tag, deadline,
|
126
|
+
client_ops)
|
127
|
+
expect(batch_result.send_metadata).to be true
|
128
|
+
expect(batch_result.send_message).to be true
|
129
|
+
|
130
|
+
# confirm the server can read the inbound message
|
131
|
+
the_status = Struct::Status.new(StatusCodes::OK, 'OK')
|
132
|
+
server_call = server_allows_client_to_proceed
|
133
|
+
server_ops = {
|
134
|
+
CallOps::SEND_STATUS_FROM_SERVER => the_status
|
135
|
+
}
|
136
|
+
svr_batch = server_call.run_batch(@server_queue, @server_tag, deadline,
|
137
|
+
server_ops)
|
138
|
+
expect(svr_batch.message).to eq nil
|
139
|
+
expect(svr_batch.send_status).to be true
|
177
140
|
end
|
178
141
|
|
179
142
|
it 'completes calls by sending status to client and server' do
|
180
143
|
call = new_client_call
|
181
|
-
|
144
|
+
client_ops = {
|
145
|
+
CallOps::SEND_INITIAL_METADATA => {},
|
146
|
+
CallOps::SEND_MESSAGE => sent_message
|
147
|
+
}
|
148
|
+
batch_result = call.run_batch(@client_queue, @client_tag, deadline,
|
149
|
+
client_ops)
|
150
|
+
expect(batch_result.send_metadata).to be true
|
151
|
+
expect(batch_result.send_message).to be true
|
152
|
+
|
153
|
+
# confirm the server can read the inbound message and respond
|
154
|
+
the_status = Struct::Status.new(StatusCodes::OK, 'OK', {})
|
182
155
|
server_call = server_allows_client_to_proceed
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
156
|
+
server_ops = {
|
157
|
+
CallOps::RECV_MESSAGE => nil,
|
158
|
+
CallOps::SEND_MESSAGE => reply_text,
|
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 sent_message
|
164
|
+
expect(svr_batch.send_status).to be true
|
165
|
+
expect(svr_batch.send_message).to be true
|
166
|
+
|
167
|
+
# confirm the client can receive the server response and status.
|
168
|
+
client_ops = {
|
169
|
+
CallOps::SEND_CLOSE_FROM_CLIENT => nil,
|
170
|
+
CallOps::RECV_MESSAGE => nil,
|
171
|
+
CallOps::RECV_STATUS_ON_CLIENT => nil
|
172
|
+
}
|
173
|
+
batch_result = call.run_batch(@client_queue, @client_tag, deadline,
|
174
|
+
client_ops)
|
175
|
+
expect(batch_result.send_close).to be true
|
176
|
+
expect(batch_result.message).to eq reply_text
|
177
|
+
expect(batch_result.status).to eq the_status
|
178
|
+
|
179
|
+
# confirm the server can receive the client close.
|
180
|
+
server_ops = {
|
181
|
+
CallOps::RECV_CLOSE_ON_SERVER => nil
|
182
|
+
}
|
183
|
+
svr_batch = server_call.run_batch(@server_queue, @server_tag, deadline,
|
184
|
+
server_ops)
|
185
|
+
expect(svr_batch.send_close).to be true
|
202
186
|
end
|
203
187
|
end
|
204
188
|
|
@@ -208,11 +192,11 @@ shared_examples 'GRPC metadata delivery works OK' do
|
|
208
192
|
describe 'from client => server' do
|
209
193
|
before(:example) do
|
210
194
|
n = 7 # arbitrary number of metadata
|
211
|
-
diff_keys_fn = proc { |i| [
|
195
|
+
diff_keys_fn = proc { |i| [format('k%d', i), format('v%d', i)] }
|
212
196
|
diff_keys = Hash[n.times.collect { |x| diff_keys_fn.call x }]
|
213
|
-
null_vals_fn = proc { |i| [
|
197
|
+
null_vals_fn = proc { |i| [format('k%d', i), format('v\0%d', i)] }
|
214
198
|
null_vals = Hash[n.times.collect { |x| null_vals_fn.call x }]
|
215
|
-
same_keys_fn = proc { |i| [
|
199
|
+
same_keys_fn = proc { |i| [format('k%d', i), [format('v%d', i)] * n] }
|
216
200
|
same_keys = Hash[n.times.collect { |x| same_keys_fn.call x }]
|
217
201
|
symbol_key = { a_key: 'a val' }
|
218
202
|
@valid_metadata = [diff_keys, same_keys, null_vals, symbol_key]
|
@@ -224,25 +208,33 @@ shared_examples 'GRPC metadata delivery works OK' do
|
|
224
208
|
it 'raises an exception if a metadata key is invalid' do
|
225
209
|
@bad_keys.each do |md|
|
226
210
|
call = new_client_call
|
227
|
-
|
211
|
+
client_ops = {
|
212
|
+
CallOps::SEND_INITIAL_METADATA => md
|
213
|
+
}
|
214
|
+
blk = proc do
|
215
|
+
call.run_batch(@client_queue, @client_tag, deadline,
|
216
|
+
client_ops)
|
217
|
+
end
|
218
|
+
expect(&blk).to raise_error
|
228
219
|
end
|
229
220
|
end
|
230
221
|
|
231
222
|
it 'sends all the metadata pairs when keys and values are valid' do
|
232
223
|
@valid_metadata.each do |md|
|
233
224
|
call = new_client_call
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
call.
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
225
|
+
client_ops = {
|
226
|
+
CallOps::SEND_INITIAL_METADATA => md
|
227
|
+
}
|
228
|
+
batch_result = call.run_batch(@client_queue, @client_tag, deadline,
|
229
|
+
client_ops)
|
230
|
+
expect(batch_result.send_metadata).to be true
|
231
|
+
|
232
|
+
# confirm the server can receive the client metadata
|
233
|
+
recvd_rpc = @server.request_call(@server_queue, @server_tag, deadline)
|
234
|
+
expect(recvd_rpc).to_not eq nil
|
235
|
+
recvd_md = recvd_rpc.metadata
|
243
236
|
replace_symbols = Hash[md.each_pair.collect { |x, y| [x.to_s, y] }]
|
244
|
-
|
245
|
-
expect(result.merge(replace_symbols)).to eq(result)
|
237
|
+
expect(recvd_md).to eq(recvd_md.merge(replace_symbols))
|
246
238
|
end
|
247
239
|
end
|
248
240
|
end
|
@@ -250,11 +242,11 @@ shared_examples 'GRPC metadata delivery works OK' do
|
|
250
242
|
describe 'from server => client' do
|
251
243
|
before(:example) do
|
252
244
|
n = 7 # arbitrary number of metadata
|
253
|
-
diff_keys_fn = proc { |i| [
|
245
|
+
diff_keys_fn = proc { |i| [format('k%d', i), format('v%d', i)] }
|
254
246
|
diff_keys = Hash[n.times.collect { |x| diff_keys_fn.call x }]
|
255
|
-
null_vals_fn = proc { |i| [
|
247
|
+
null_vals_fn = proc { |i| [format('k%d', i), format('v\0%d', i)] }
|
256
248
|
null_vals = Hash[n.times.collect { |x| null_vals_fn.call x }]
|
257
|
-
same_keys_fn = proc { |i| [
|
249
|
+
same_keys_fn = proc { |i| [format('k%d', i), [format('v%d', i)] * n] }
|
258
250
|
same_keys = Hash[n.times.collect { |x| same_keys_fn.call x }]
|
259
251
|
symbol_key = { a_key: 'a val' }
|
260
252
|
@valid_metadata = [diff_keys, same_keys, null_vals, symbol_key]
|
@@ -266,55 +258,81 @@ shared_examples 'GRPC metadata delivery works OK' do
|
|
266
258
|
it 'raises an exception if a metadata key is invalid' do
|
267
259
|
@bad_keys.each do |md|
|
268
260
|
call = new_client_call
|
269
|
-
|
261
|
+
# client signals that it's done sending metadata to allow server to
|
262
|
+
# respond
|
263
|
+
client_ops = {
|
264
|
+
CallOps::SEND_INITIAL_METADATA => nil
|
265
|
+
}
|
266
|
+
call.run_batch(@client_queue, @client_tag, deadline, client_ops)
|
270
267
|
|
271
268
|
# server gets the invocation
|
272
|
-
@server.request_call(@server_tag)
|
273
|
-
|
274
|
-
|
269
|
+
recvd_rpc = @server.request_call(@server_queue, @server_tag, deadline)
|
270
|
+
expect(recvd_rpc).to_not eq nil
|
271
|
+
server_ops = {
|
272
|
+
CallOps::SEND_INITIAL_METADATA => md
|
273
|
+
}
|
274
|
+
blk = proc do
|
275
|
+
recvd_rpc.call.run_batch(@server_queue, @server_tag, deadline,
|
276
|
+
server_ops)
|
277
|
+
end
|
278
|
+
expect(&blk).to raise_error
|
275
279
|
end
|
276
280
|
end
|
277
281
|
|
278
|
-
it 'sends
|
282
|
+
it 'sends an empty hash if no metadata is added' do
|
279
283
|
call = new_client_call
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
#
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
284
|
+
# client signals that it's done sending metadata to allow server to
|
285
|
+
# respond
|
286
|
+
client_ops = {
|
287
|
+
CallOps::SEND_INITIAL_METADATA => nil
|
288
|
+
}
|
289
|
+
call.run_batch(@client_queue, @client_tag, deadline, client_ops)
|
290
|
+
|
291
|
+
# server gets the invocation but sends no metadata back
|
292
|
+
recvd_rpc = @server.request_call(@server_queue, @server_tag, deadline)
|
293
|
+
expect(recvd_rpc).to_not eq nil
|
294
|
+
server_call = recvd_rpc.call
|
295
|
+
server_ops = {
|
296
|
+
CallOps::SEND_INITIAL_METADATA => nil
|
297
|
+
}
|
298
|
+
server_call.run_batch(@server_queue, @server_tag, deadline, server_ops)
|
299
|
+
|
300
|
+
# client receives nothing as expected
|
301
|
+
client_ops = {
|
302
|
+
CallOps::RECV_INITIAL_METADATA => nil
|
303
|
+
}
|
304
|
+
batch_result = call.run_batch(@client_queue, @client_tag, deadline,
|
305
|
+
client_ops)
|
306
|
+
expect(batch_result.metadata).to eq({})
|
296
307
|
end
|
297
308
|
|
298
309
|
it 'sends all the pairs when keys and values are valid' do
|
299
310
|
@valid_metadata.each do |md|
|
300
311
|
call = new_client_call
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
#
|
309
|
-
|
310
|
-
|
311
|
-
server_call.
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
312
|
+
# client signals that it's done sending metadata to allow server to
|
313
|
+
# respond
|
314
|
+
client_ops = {
|
315
|
+
CallOps::SEND_INITIAL_METADATA => nil
|
316
|
+
}
|
317
|
+
call.run_batch(@client_queue, @client_tag, deadline, client_ops)
|
318
|
+
|
319
|
+
# server gets the invocation but sends no metadata back
|
320
|
+
recvd_rpc = @server.request_call(@server_queue, @server_tag, deadline)
|
321
|
+
expect(recvd_rpc).to_not eq nil
|
322
|
+
server_call = recvd_rpc.call
|
323
|
+
server_ops = {
|
324
|
+
CallOps::SEND_INITIAL_METADATA => md
|
325
|
+
}
|
326
|
+
server_call.run_batch(@server_queue, @server_tag, deadline, server_ops)
|
327
|
+
|
328
|
+
# client receives nothing as expected
|
329
|
+
client_ops = {
|
330
|
+
CallOps::RECV_INITIAL_METADATA => nil
|
331
|
+
}
|
332
|
+
batch_result = call.run_batch(@client_queue, @client_tag, deadline,
|
333
|
+
client_ops)
|
316
334
|
replace_symbols = Hash[md.each_pair.collect { |x, y| [x.to_s, y] }]
|
317
|
-
expect(
|
335
|
+
expect(batch_result.metadata).to eq(replace_symbols)
|
318
336
|
end
|
319
337
|
end
|
320
338
|
end
|