blob: 9228f7df272f8c6bea3aad7fe159ee0cc1d7480d [file] [log] [blame]
nnoble097ef9b2014-12-01 17:06:10 -08001# Copyright 2014, 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
30require 'grpc'
31require 'port_picker'
32
nnoble0c475f02014-12-05 15:37:39 -080033include GRPC::Core::StatusCodes
nnoble097ef9b2014-12-01 17:06:10 -080034
nnoble0c475f02014-12-05 15:37:39 -080035describe GRPC::Core::RpcErrors do
nnoble097ef9b2014-12-01 17:06:10 -080036
37 before(:each) do
38 @known_types = {
39 :OK => 0,
40 :ERROR => 1,
41 :NOT_ON_SERVER => 2,
42 :NOT_ON_CLIENT => 3,
43 :ALREADY_INVOKED => 4,
44 :NOT_INVOKED => 5,
45 :ALREADY_FINISHED => 6,
46 :TOO_MANY_OPERATIONS => 7,
47 :INVALID_FLAGS => 8,
48 :ErrorMessages => {
49 0=>'ok',
50 1=>'unknown error',
51 2=>'not available on a server',
52 3=>'not available on a client',
53 4=>'call is already invoked',
54 5=>'call is not yet invoked',
55 6=>'call is already finished',
56 7=>'outstanding read or write present',
57 8=>'a bad flag was given',
58 }
59 }
60 end
61
62 it 'should have symbols for all the known error codes' do
nnoble0c475f02014-12-05 15:37:39 -080063 m = GRPC::Core::RpcErrors
nnoble097ef9b2014-12-01 17:06:10 -080064 syms_and_codes = m.constants.collect { |c| [c, m.const_get(c)] }
65 expect(Hash[syms_and_codes]).to eq(@known_types)
66 end
67
68end
69
nnoble0c475f02014-12-05 15:37:39 -080070describe GRPC::Core::Call do
nnoble097ef9b2014-12-01 17:06:10 -080071
72 before(:each) do
73 @tag = Object.new
nnoble0c475f02014-12-05 15:37:39 -080074 @client_queue = GRPC::Core::CompletionQueue.new
75 @server_queue = GRPC::Core::CompletionQueue.new
nnoble097ef9b2014-12-01 17:06:10 -080076 port = find_unused_tcp_port
77 host = "localhost:#{port}"
nnoble0c475f02014-12-05 15:37:39 -080078 @server = GRPC::Core::Server.new(@server_queue, nil)
nnoble097ef9b2014-12-01 17:06:10 -080079 @server.add_http2_port(host)
nnoble0c475f02014-12-05 15:37:39 -080080 @ch = GRPC::Core::Channel.new(host, nil)
nnoble097ef9b2014-12-01 17:06:10 -080081 end
82
83 after(:each) do
84 @server.close
85 end
86
87 describe '#start_read' do
88 it 'should fail if called immediately' do
nnoble0c475f02014-12-05 15:37:39 -080089 expect { make_test_call.start_read(@tag) }.to raise_error GRPC::Core::CallError
nnoble097ef9b2014-12-01 17:06:10 -080090 end
91 end
92
93 describe '#start_write' do
94 it 'should fail if called immediately' do
nnoble0c475f02014-12-05 15:37:39 -080095 bytes = GRPC::Core::ByteBuffer.new('test string')
nnoble097ef9b2014-12-01 17:06:10 -080096 expect { make_test_call.start_write(bytes, @tag) }
nnoble0c475f02014-12-05 15:37:39 -080097 .to raise_error GRPC::Core::CallError
nnoble097ef9b2014-12-01 17:06:10 -080098 end
99 end
100
101 describe '#start_write_status' do
102 it 'should fail if called immediately' do
nnoble0c475f02014-12-05 15:37:39 -0800103 sts = GRPC::Core::Status.new(153, 'test detail')
nnoble097ef9b2014-12-01 17:06:10 -0800104 expect { make_test_call.start_write_status(sts, @tag) }
nnoble0c475f02014-12-05 15:37:39 -0800105 .to raise_error GRPC::Core::CallError
nnoble097ef9b2014-12-01 17:06:10 -0800106 end
107 end
108
109 describe '#writes_done' do
110 it 'should fail if called immediately' do
nnoble0c475f02014-12-05 15:37:39 -0800111 expect { make_test_call.writes_done(@tag) }.to raise_error GRPC::Core::CallError
nnoble097ef9b2014-12-01 17:06:10 -0800112 end
113 end
114
115 describe '#add_metadata' do
116 it 'adds metadata to a call without fail' do
117 call = make_test_call
118 n = 37
119 metadata = Hash[n.times.collect { |i| ["key%d" % i, "value%d" %i] } ]
120 expect { call.add_metadata(metadata) }.to_not raise_error
121 end
122 end
123
124 describe '#start_invoke' do
125 it 'should cause the INVOKE_ACCEPTED event' do
126 call = make_test_call
127 expect(call.start_invoke(@client_queue, @tag, @tag, @tag)).to be_nil
128 ev = @client_queue.next(deadline)
nnoble0c475f02014-12-05 15:37:39 -0800129 expect(ev.call).to be_a(GRPC::Core::Call)
nnoble097ef9b2014-12-01 17:06:10 -0800130 expect(ev.tag).to be(@tag)
nnoble0c475f02014-12-05 15:37:39 -0800131 expect(ev.type).to be(GRPC::Core::CompletionType::INVOKE_ACCEPTED)
nnoble097ef9b2014-12-01 17:06:10 -0800132 expect(ev.call).to_not be(call)
133 end
134 end
135
136 describe '#start_write' do
137 it 'should cause the WRITE_ACCEPTED event' do
138 call = make_test_call
139 call.start_invoke(@client_queue, @tag, @tag, @tag)
140 ev = @client_queue.next(deadline)
nnoble0c475f02014-12-05 15:37:39 -0800141 expect(ev.type).to be(GRPC::Core::CompletionType::INVOKE_ACCEPTED)
142 expect(call.start_write(GRPC::Core::ByteBuffer.new('test_start_write'),
nnoble097ef9b2014-12-01 17:06:10 -0800143 @tag)).to be_nil
144 ev = @client_queue.next(deadline)
nnoble0c475f02014-12-05 15:37:39 -0800145 expect(ev.call).to be_a(GRPC::Core::Call)
146 expect(ev.type).to be(GRPC::Core::CompletionType::WRITE_ACCEPTED)
nnoble097ef9b2014-12-01 17:06:10 -0800147 expect(ev.tag).to be(@tag)
148 end
149 end
150
151 describe '#status' do
152 it 'can save the status and read it back' do
153 call = make_test_call
nnoble0c475f02014-12-05 15:37:39 -0800154 sts = GRPC::Core::Status.new(OK, 'OK')
nnoble097ef9b2014-12-01 17:06:10 -0800155 expect { call.status = sts }.not_to raise_error
156 expect(call.status).to be(sts)
157 end
158
159 it 'must be set to a status' do
160 call = make_test_call
161 bad_sts = Object.new
162 expect { call.status = bad_sts }.to raise_error(TypeError)
163 end
164
165 it 'can be set to nil' do
166 call = make_test_call
167 expect { call.status = nil }.not_to raise_error
168 end
169 end
170
171 describe '#metadata' do
172 it 'can save the metadata hash and read it back' do
173 call = make_test_call
174 md = {'k1' => 'v1', 'k2' => 'v2'}
175 expect { call.metadata = md }.not_to raise_error
176 expect(call.metadata).to be(md)
177 end
178
179 it 'must be set with a hash' do
180 call = make_test_call
181 bad_md = Object.new
182 expect { call.metadata = bad_md }.to raise_error(TypeError)
183 end
184
185 it 'can be set to nil' do
186 call = make_test_call
187 expect { call.metadata = nil }.not_to raise_error
188 end
189 end
190
191
192 def make_test_call
193 @ch.create_call('dummy_method', 'dummy_host', deadline)
194 end
195
196 def deadline
197 Time.now + 2 # in 2 seconds; arbitrary
198 end
199
200end