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.

Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +1 -0
  3. data/.rubocop_todo.yml +12 -20
  4. data/CHANGELOG.md +11 -0
  5. data/Rakefile +1 -0
  6. data/bin/apis/pubsub_demo.rb +3 -6
  7. data/bin/interop/interop_client.rb +43 -3
  8. data/bin/interop/interop_server.rb +1 -1
  9. data/bin/math_server.rb +1 -1
  10. data/bin/noproto_server.rb +1 -1
  11. data/ext/grpc/rb_byte_buffer.c +15 -189
  12. data/ext/grpc/rb_byte_buffer.h +4 -12
  13. data/ext/grpc/rb_call.c +514 -307
  14. data/ext/grpc/rb_call.h +4 -4
  15. data/ext/grpc/rb_channel.c +58 -34
  16. data/ext/grpc/rb_channel.h +0 -3
  17. data/ext/grpc/rb_channel_args.c +13 -4
  18. data/ext/grpc/rb_completion_queue.c +50 -23
  19. data/ext/grpc/rb_completion_queue.h +7 -3
  20. data/ext/grpc/rb_credentials.c +40 -28
  21. data/ext/grpc/rb_credentials.h +0 -4
  22. data/ext/grpc/rb_grpc.c +86 -67
  23. data/ext/grpc/rb_grpc.h +20 -10
  24. data/ext/grpc/rb_server.c +119 -26
  25. data/ext/grpc/rb_server.h +0 -4
  26. data/ext/grpc/rb_server_credentials.c +29 -16
  27. data/ext/grpc/rb_server_credentials.h +0 -4
  28. data/grpc.gemspec +11 -8
  29. data/lib/grpc.rb +1 -1
  30. data/lib/grpc/errors.rb +8 -7
  31. data/lib/grpc/generic/active_call.rb +104 -171
  32. data/lib/grpc/generic/bidi_call.rb +32 -60
  33. data/lib/grpc/generic/client_stub.rb +42 -31
  34. data/lib/grpc/generic/rpc_desc.rb +7 -12
  35. data/lib/grpc/generic/rpc_server.rb +253 -170
  36. data/lib/grpc/{core/event.rb → notifier.rb} +25 -9
  37. data/lib/grpc/version.rb +1 -1
  38. data/spec/call_spec.rb +23 -40
  39. data/spec/channel_spec.rb +11 -20
  40. data/spec/client_server_spec.rb +193 -175
  41. data/spec/credentials_spec.rb +2 -2
  42. data/spec/generic/active_call_spec.rb +59 -85
  43. data/spec/generic/client_stub_spec.rb +46 -64
  44. data/spec/generic/rpc_desc_spec.rb +50 -80
  45. data/spec/generic/rpc_server_pool_spec.rb +2 -3
  46. data/spec/generic/rpc_server_spec.rb +158 -29
  47. data/spec/server_spec.rb +1 -1
  48. data/spec/spec_helper.rb +8 -4
  49. metadata +27 -37
  50. data/ext/grpc/rb_event.c +0 -361
  51. data/ext/grpc/rb_event.h +0 -53
  52. data/ext/grpc/rb_metadata.c +0 -215
  53. data/ext/grpc/rb_metadata.h +0 -53
  54. data/spec/alloc_spec.rb +0 -44
  55. data/spec/byte_buffer_spec.rb +0 -67
  56. data/spec/event_spec.rb +0 -53
  57. 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
- module Core
35
- # Event is a class defined in the c extension
36
- #
37
- # Here, we add an inspect method.
38
- class Event
39
- def inspect
40
- "<#{self.class}: type:#{type}, tag:#{tag} result:#{result}>"
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
@@ -29,5 +29,5 @@
29
29
 
30
30
  # GRPC contains the General RPC module.
31
31
  module GRPC
32
- VERSION = '0.6.0'
32
+ VERSION = '0.6.1'
33
33
  end
@@ -66,51 +66,34 @@ describe GRPC::Core::RpcErrors do
66
66
  end
67
67
  end
68
68
 
69
- describe GRPC::Core::Call do
69
+ describe GRPC::Core::CallOps do
70
70
  before(:each) do
71
- @tag = Object.new
72
- @client_queue = GRPC::Core::CompletionQueue.new
73
- fake_host = 'localhost:10101'
74
- @ch = GRPC::Core::Channel.new(fake_host, nil)
75
- end
76
-
77
- describe '#start_read' do
78
- xit 'should fail if called immediately' do
79
- blk = proc { make_test_call.start_read(@tag) }
80
- expect(&blk).to raise_error GRPC::Core::CallError
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
- describe '#start_write_status' do
93
- xit 'should fail if called immediately' do
94
- blk = proc { make_test_call.start_write_status(153, 'x', @tag) }
95
- expect(&blk).to raise_error GRPC::Core::CallError
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
- describe '#writes_done' do
100
- xit 'should fail if called immediately' do
101
- blk = proc { make_test_call.writes_done(Object.new) }
102
- expect(&blk).to raise_error GRPC::Core::CallError
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
- describe '#add_metadata' do
107
- it 'adds metadata to a call without fail' do
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
@@ -36,16 +36,13 @@ def load_test_certs
36
36
  end
37
37
 
38
38
  describe GRPC::Core::Channel do
39
- FAKE_HOST = 'localhost:0'
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' => Hash.new)
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
- host = FAKE_HOST
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
- host = FAKE_HOST
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
- host = FAKE_HOST
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
- host = FAKE_HOST
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
- host = FAKE_HOST
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
- host = FAKE_HOST
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
@@ -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
- ev = @server_queue.pluck(@server_tag, deadline)
69
- expect(ev).not_to be_nil
70
- expect(ev.type).to be(SERVER_RPC_NEW)
71
- server_call = ev.call
72
- server_call.server_accept(@server_queue, @server_finished_tag)
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 start responding' do
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
- call.invoke(@client_queue, @client_metadata_tag, @client_finished_tag)
109
-
110
- # check the server rpc new was received
111
- # @server.request_call(@server_tag)
112
- # ev = expect_next_event_on(@server_queue, SERVER_RPC_NEW, @server_tag)
113
-
114
- # accept the call
115
- # server_call = ev.call
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.start_read(@server_tag)
125
- ev = expect_next_event_on(@server_queue, READ, @server_tag)
126
- expect(ev.result.to_s).to eq(msg)
127
-
128
- # the server response
129
- server_call.start_write(reply, @server_tag)
130
- expect_next_event_on(@server_queue, WRITE_ACCEPTED, @server_tag)
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
- call.invoke(@client_queue, @client_metadata_tag, @client_finished_tag)
136
- server_call = server_allows_client_to_proceed
137
- client_sends(call)
138
- server_responds_with(server_call, 'server_response')
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
- call.start_read(@tag)
141
- ev = expect_next_event_on(@client_queue, READ, @tag)
142
- expect(ev.result.to_s).to eq('server_response')
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
- call.invoke(@client_queue, @client_metadata_tag, @client_finished_tag)
148
-
149
- # check the server rpc new was received
150
- @server.request_call(@server_tag)
151
- ev = expect_next_event_on(@server_queue, SERVER_RPC_NEW, @server_tag)
152
- expect(ev.tag).to be(@server_tag)
153
-
154
- # accept the call - need to do this to sent status.
155
- server_call = ev.call
156
- server_call.server_accept(@server_queue, @server_finished_tag)
157
- server_call.server_end_initial_metadata
158
- server_call.start_write_status(StatusCodes::NOT_FOUND, 'not found',
159
- @server_tag)
160
-
161
- # Client sends some data
162
- client_sends(call)
163
-
164
- # client gets an empty response for the read, preceeded by some metadata.
165
- call.start_read(@tag)
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
- call.invoke(@client_queue, @client_metadata_tag, @client_finished_tag)
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
- client_sends(call)
184
- server_responds_with(server_call, 'server_response')
185
- server_call.start_write_status(10_101, 'status code is 10101', @server_tag)
186
-
187
- # first the client says writes are done
188
- call.start_read(@tag)
189
- expect_next_event_on(@client_queue, READ, @tag)
190
- call.writes_done(@tag)
191
-
192
- # but nothing happens until the server sends a status
193
- expect_next_event_on(@server_queue, FINISH_ACCEPTED, @server_tag)
194
- ev = expect_next_event_on(@server_queue, FINISHED, @server_finished_tag)
195
- expect(ev.result).to be_a(Struct::Status)
196
-
197
- # client gets FINISHED
198
- expect_next_event_on(@client_queue, FINISH_ACCEPTED, @tag)
199
- ev = expect_next_event_on(@client_queue, FINISHED, @client_finished_tag)
200
- expect(ev.result.details).to eq('status code is 10101')
201
- expect(ev.result.code).to eq(10_101)
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| [sprintf('k%d', i), sprintf('v%d', 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| [sprintf('k%d', i), sprintf('v\0%d', 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| [sprintf('k%d', i), [sprintf('v%d', i)] * n] }
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
- expect { call.add_metadata(md) }.to raise_error
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
- call.add_metadata(md)
235
-
236
- # Client begins a call OK
237
- call.invoke(@client_queue, @client_metadata_tag, @client_finished_tag)
238
-
239
- # ... server has all metadata available even though the client did not
240
- # send a write
241
- @server.request_call(@server_tag)
242
- ev = expect_next_event_on(@server_queue, SERVER_RPC_NEW, @server_tag)
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
- result = ev.result.metadata
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| [sprintf('k%d', i), sprintf('v%d', 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| [sprintf('k%d', i), sprintf('v\0%d', 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| [sprintf('k%d', i), [sprintf('v%d', i)] * n] }
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
- call.invoke(@client_queue, @client_metadata_tag, @client_finished_tag)
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
- ev = expect_next_event_on(@server_queue, SERVER_RPC_NEW, @server_tag)
274
- expect { ev.call.add_metadata(md) }.to raise_error
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 a hash that contains the status when no metadata is added' do
282
+ it 'sends an empty hash if no metadata is added' do
279
283
  call = new_client_call
280
- call.invoke(@client_queue, @client_metadata_tag, @client_finished_tag)
281
-
282
- # server gets the invocation
283
- @server.request_call(@server_tag)
284
- ev = expect_next_event_on(@server_queue, SERVER_RPC_NEW, @server_tag)
285
- server_call = ev.call
286
-
287
- # ... server accepts the call without adding metadata
288
- server_call.server_accept(@server_queue, @server_finished_tag)
289
- server_call.server_end_initial_metadata
290
-
291
- # there is the HTTP status metadata, though there should not be any
292
- # TODO: update this with the bug number to be resolved
293
- ev = expect_next_event_on(@client_queue, CLIENT_METADATA_READ,
294
- @client_metadata_tag)
295
- expect(ev.result).to eq({})
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
- call.invoke(@client_queue, @client_metadata_tag, @client_finished_tag)
302
-
303
- # server gets the invocation
304
- @server.request_call(@server_tag)
305
- ev = expect_next_event_on(@server_queue, SERVER_RPC_NEW, @server_tag)
306
- server_call = ev.call
307
-
308
- # ... server adds metadata and accepts the call
309
- server_call.add_metadata(md)
310
- server_call.server_accept(@server_queue, @server_finished_tag)
311
- server_call.server_end_initial_metadata
312
-
313
- # Now the client can read the metadata
314
- ev = expect_next_event_on(@client_queue, CLIENT_METADATA_READ,
315
- @client_metadata_tag)
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(ev.result).to eq(replace_symbols)
335
+ expect(batch_result.metadata).to eq(replace_symbols)
318
336
  end
319
337
  end
320
338
  end