blob: e9f0ce90977dfb93da129fb613f1f3cdb039bb78 [file] [log] [blame]
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001/*
2 *
Craig Tiller06059952015-02-18 08:34:56 -08003 * Copyright 2015, Google Inc.
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08004 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following disclaimer
14 * in the documentation and/or other materials provided with the
15 * distribution.
16 * * Neither the name of Google Inc. nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 */
33
yangged5e7e02015-01-06 10:16:15 -080034#include <chrono>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080035#include <thread>
yangged5e7e02015-01-06 10:16:15 -080036
Craig Tiller14e60e92015-01-13 17:26:46 -080037#include "test/core/util/test_config.h"
Craig Tiller35e39712015-01-12 16:41:24 -080038#include "test/cpp/util/echo_duplicate.pb.h"
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080039#include "test/cpp/util/echo.pb.h"
yangged5e7e02015-01-06 10:16:15 -080040#include "src/cpp/util/time.h"
Craig Tiller7418d012015-02-11 15:25:03 -080041#include "src/cpp/server/thread_pool.h"
yangg59dfc902014-12-19 14:00:14 -080042#include <grpc++/channel_arguments.h>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080043#include <grpc++/channel_interface.h>
44#include <grpc++/client_context.h>
45#include <grpc++/create_channel.h>
yangg4105e2b2015-01-09 14:19:44 -080046#include <grpc++/credentials.h>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080047#include <grpc++/server.h>
48#include <grpc++/server_builder.h>
yangga4b6f5d2014-12-17 15:53:12 -080049#include <grpc++/server_context.h>
Craig Tiller42bc87c2015-02-23 08:50:19 -080050#include <grpc++/server_credentials.h>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080051#include <grpc++/status.h>
nnoble0c475f02014-12-05 15:37:39 -080052#include <grpc++/stream.h>
Craig Tiller35e39712015-01-12 16:41:24 -080053#include "test/core/util/port.h"
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080054#include <gtest/gtest.h>
55
56#include <grpc/grpc.h>
57#include <grpc/support/thd.h>
yangged5e7e02015-01-06 10:16:15 -080058#include <grpc/support/time.h>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080059
60using grpc::cpp::test::util::EchoRequest;
61using grpc::cpp::test::util::EchoResponse;
yangged5e7e02015-01-06 10:16:15 -080062using std::chrono::system_clock;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080063
64namespace grpc {
yangged5e7e02015-01-06 10:16:15 -080065namespace testing {
66
67namespace {
68
69// When echo_deadline is requested, deadline seen in the ServerContext is set in
70// the response in seconds.
71void MaybeEchoDeadline(ServerContext* context, const EchoRequest* request,
72 EchoResponse* response) {
73 if (request->has_param() && request->param().echo_deadline()) {
74 gpr_timespec deadline = gpr_inf_future;
75 if (context->absolute_deadline() != system_clock::time_point::max()) {
76 Timepoint2Timespec(context->absolute_deadline(), &deadline);
77 }
78 response->mutable_param()->set_request_deadline(deadline.tv_sec);
79 }
80}
Craig Tiller7418d012015-02-11 15:25:03 -080081
yangged5e7e02015-01-06 10:16:15 -080082} // namespace
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080083
yangg1456d152015-01-08 15:39:58 -080084class TestServiceImpl : public ::grpc::cpp::test::util::TestService::Service {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080085 public:
yangga4b6f5d2014-12-17 15:53:12 -080086 Status Echo(ServerContext* context, const EchoRequest* request,
yangg1456d152015-01-08 15:39:58 -080087 EchoResponse* response) override {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080088 response->set_message(request->message());
yangged5e7e02015-01-06 10:16:15 -080089 MaybeEchoDeadline(context, request, response);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080090 return Status::OK;
91 }
nnoble0c475f02014-12-05 15:37:39 -080092
93 // Unimplemented is left unimplemented to test the returned error.
94
yangga4b6f5d2014-12-17 15:53:12 -080095 Status RequestStream(ServerContext* context,
96 ServerReader<EchoRequest>* reader,
yangg1456d152015-01-08 15:39:58 -080097 EchoResponse* response) override {
nnoble0c475f02014-12-05 15:37:39 -080098 EchoRequest request;
99 response->set_message("");
100 while (reader->Read(&request)) {
101 response->mutable_message()->append(request.message());
102 }
103 return Status::OK;
104 }
105
106 // Return 3 messages.
107 // TODO(yangg) make it generic by adding a parameter into EchoRequest
yangga4b6f5d2014-12-17 15:53:12 -0800108 Status ResponseStream(ServerContext* context, const EchoRequest* request,
yangg1456d152015-01-08 15:39:58 -0800109 ServerWriter<EchoResponse>* writer) override {
nnoble0c475f02014-12-05 15:37:39 -0800110 EchoResponse response;
111 response.set_message(request->message() + "0");
112 writer->Write(response);
113 response.set_message(request->message() + "1");
114 writer->Write(response);
115 response.set_message(request->message() + "2");
116 writer->Write(response);
117
118 return Status::OK;
119 }
120
yangg1456d152015-01-08 15:39:58 -0800121 Status BidiStream(
122 ServerContext* context,
123 ServerReaderWriter<EchoResponse, EchoRequest>* stream) override {
nnoble0c475f02014-12-05 15:37:39 -0800124 EchoRequest request;
125 EchoResponse response;
126 while (stream->Read(&request)) {
127 gpr_log(GPR_INFO, "recv msg %s", request.message().c_str());
128 response.set_message(request.message());
129 stream->Write(response);
130 }
131 return Status::OK;
132 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800133};
134
yangg1456d152015-01-08 15:39:58 -0800135class TestServiceImplDupPkg
136 : public ::grpc::cpp::test::util::duplicate::TestService::Service {
137 public:
138 Status Echo(ServerContext* context, const EchoRequest* request,
139 EchoResponse* response) override {
140 response->set_message("no package");
141 return Status::OK;
142 }
143};
144
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800145class End2endTest : public ::testing::Test {
146 protected:
Craig Tiller7418d012015-02-11 15:25:03 -0800147 End2endTest() : thread_pool_(2) {}
148
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800149 void SetUp() override {
Craig Tiller35e39712015-01-12 16:41:24 -0800150 int port = grpc_pick_unused_port_or_die();
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800151 server_address_ << "localhost:" << port;
152 // Setup server
153 ServerBuilder builder;
Craig Tiller42bc87c2015-02-23 08:50:19 -0800154 builder.AddPort(server_address_.str(), InsecureServerCredentials());
Craig Tillerf8ac5d82015-02-09 16:24:20 -0800155 builder.RegisterService(&service_);
156 builder.RegisterService(&dup_pkg_service_);
Craig Tiller7418d012015-02-11 15:25:03 -0800157 builder.SetThreadPool(&thread_pool_);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800158 server_ = builder.BuildAndStart();
159 }
160
Craig Tillerb5dcec52015-01-13 11:13:42 -0800161 void TearDown() override { server_->Shutdown(); }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800162
yangg1456d152015-01-08 15:39:58 -0800163 void ResetStub() {
Craig Tiller47c83fd2015-02-21 22:45:35 -0800164 std::shared_ptr<ChannelInterface> channel = CreateChannel(
165 server_address_.str(), InsecureCredentials(), ChannelArguments());
yangg1456d152015-01-08 15:39:58 -0800166 stub_.reset(grpc::cpp::test::util::TestService::NewStub(channel));
167 }
168
169 std::unique_ptr<grpc::cpp::test::util::TestService::Stub> stub_;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800170 std::unique_ptr<Server> server_;
171 std::ostringstream server_address_;
nnoble0c475f02014-12-05 15:37:39 -0800172 TestServiceImpl service_;
yangg1456d152015-01-08 15:39:58 -0800173 TestServiceImplDupPkg dup_pkg_service_;
Craig Tiller7418d012015-02-11 15:25:03 -0800174 ThreadPool thread_pool_;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800175};
176
yangg1456d152015-01-08 15:39:58 -0800177static void SendRpc(grpc::cpp::test::util::TestService::Stub* stub,
178 int num_rpcs) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800179 EchoRequest request;
180 EchoResponse response;
181 request.set_message("Hello");
182
183 for (int i = 0; i < num_rpcs; ++i) {
184 ClientContext context;
185 Status s = stub->Echo(&context, request, &response);
186 EXPECT_EQ(response.message(), request.message());
187 EXPECT_TRUE(s.IsOk());
188 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800189}
190
191TEST_F(End2endTest, SimpleRpc) {
yangg1456d152015-01-08 15:39:58 -0800192 ResetStub();
193 SendRpc(stub_.get(), 1);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800194}
195
196TEST_F(End2endTest, MultipleRpcs) {
yangg1456d152015-01-08 15:39:58 -0800197 ResetStub();
Craig Tiller35e39712015-01-12 16:41:24 -0800198 std::vector<std::thread*> threads;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800199 for (int i = 0; i < 10; ++i) {
yangg1456d152015-01-08 15:39:58 -0800200 threads.push_back(new std::thread(SendRpc, stub_.get(), 10));
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800201 }
202 for (int i = 0; i < 10; ++i) {
203 threads[i]->join();
204 delete threads[i];
205 }
206}
207
yanggda029e32014-12-18 10:24:04 -0800208// Set a 10us deadline and make sure proper error is returned.
209TEST_F(End2endTest, RpcDeadlineExpires) {
yangg1456d152015-01-08 15:39:58 -0800210 ResetStub();
yanggda029e32014-12-18 10:24:04 -0800211 EchoRequest request;
212 EchoResponse response;
213 request.set_message("Hello");
214
215 ClientContext context;
216 std::chrono::system_clock::time_point deadline =
217 std::chrono::system_clock::now() + std::chrono::microseconds(10);
218 context.set_absolute_deadline(deadline);
yangg1456d152015-01-08 15:39:58 -0800219 Status s = stub_->Echo(&context, request, &response);
Craig Tiller7b018782015-01-16 09:53:39 -0800220 EXPECT_EQ(StatusCode::DEADLINE_EXCEEDED, s.code());
yanggda029e32014-12-18 10:24:04 -0800221}
222
yangged5e7e02015-01-06 10:16:15 -0800223// Set a long but finite deadline.
224TEST_F(End2endTest, RpcLongDeadline) {
yangg1456d152015-01-08 15:39:58 -0800225 ResetStub();
yangged5e7e02015-01-06 10:16:15 -0800226 EchoRequest request;
227 EchoResponse response;
228 request.set_message("Hello");
229
230 ClientContext context;
231 std::chrono::system_clock::time_point deadline =
232 std::chrono::system_clock::now() + std::chrono::hours(1);
233 context.set_absolute_deadline(deadline);
yangg1456d152015-01-08 15:39:58 -0800234 Status s = stub_->Echo(&context, request, &response);
yangged5e7e02015-01-06 10:16:15 -0800235 EXPECT_EQ(response.message(), request.message());
236 EXPECT_TRUE(s.IsOk());
yangged5e7e02015-01-06 10:16:15 -0800237}
238
239// Ask server to echo back the deadline it sees.
240TEST_F(End2endTest, EchoDeadline) {
yangg1456d152015-01-08 15:39:58 -0800241 ResetStub();
yangged5e7e02015-01-06 10:16:15 -0800242 EchoRequest request;
243 EchoResponse response;
244 request.set_message("Hello");
245 request.mutable_param()->set_echo_deadline(true);
246
247 ClientContext context;
248 std::chrono::system_clock::time_point deadline =
249 std::chrono::system_clock::now() + std::chrono::seconds(100);
250 context.set_absolute_deadline(deadline);
yangg1456d152015-01-08 15:39:58 -0800251 Status s = stub_->Echo(&context, request, &response);
yangged5e7e02015-01-06 10:16:15 -0800252 EXPECT_EQ(response.message(), request.message());
253 EXPECT_TRUE(s.IsOk());
254 gpr_timespec sent_deadline;
255 Timepoint2Timespec(deadline, &sent_deadline);
256 // Allow 1 second error.
257 EXPECT_LE(response.param().request_deadline() - sent_deadline.tv_sec, 1);
258 EXPECT_GE(response.param().request_deadline() - sent_deadline.tv_sec, -1);
yangged5e7e02015-01-06 10:16:15 -0800259}
260
261// Ask server to echo back the deadline it sees. The rpc has no deadline.
262TEST_F(End2endTest, EchoDeadlineForNoDeadlineRpc) {
yangg1456d152015-01-08 15:39:58 -0800263 ResetStub();
yangged5e7e02015-01-06 10:16:15 -0800264 EchoRequest request;
265 EchoResponse response;
266 request.set_message("Hello");
267 request.mutable_param()->set_echo_deadline(true);
268
269 ClientContext context;
yangg1456d152015-01-08 15:39:58 -0800270 Status s = stub_->Echo(&context, request, &response);
yangged5e7e02015-01-06 10:16:15 -0800271 EXPECT_EQ(response.message(), request.message());
272 EXPECT_TRUE(s.IsOk());
273 EXPECT_EQ(response.param().request_deadline(), gpr_inf_future.tv_sec);
yangged5e7e02015-01-06 10:16:15 -0800274}
275
nnoble0c475f02014-12-05 15:37:39 -0800276TEST_F(End2endTest, UnimplementedRpc) {
yangg1456d152015-01-08 15:39:58 -0800277 ResetStub();
nnoble0c475f02014-12-05 15:37:39 -0800278 EchoRequest request;
279 EchoResponse response;
280 request.set_message("Hello");
281
282 ClientContext context;
yangg1456d152015-01-08 15:39:58 -0800283 Status s = stub_->Unimplemented(&context, request, &response);
nnoble0c475f02014-12-05 15:37:39 -0800284 EXPECT_FALSE(s.IsOk());
285 EXPECT_EQ(s.code(), grpc::StatusCode::UNIMPLEMENTED);
286 EXPECT_EQ(s.details(), "");
287 EXPECT_EQ(response.message(), "");
nnoble0c475f02014-12-05 15:37:39 -0800288}
289
290TEST_F(End2endTest, RequestStreamOneRequest) {
yangg1456d152015-01-08 15:39:58 -0800291 ResetStub();
nnoble0c475f02014-12-05 15:37:39 -0800292 EchoRequest request;
293 EchoResponse response;
294 ClientContext context;
295
yangg1456d152015-01-08 15:39:58 -0800296 ClientWriter<EchoRequest>* stream = stub_->RequestStream(&context, &response);
nnoble0c475f02014-12-05 15:37:39 -0800297 request.set_message("hello");
298 EXPECT_TRUE(stream->Write(request));
299 stream->WritesDone();
Craig Tillerf8ac5d82015-02-09 16:24:20 -0800300 Status s = stream->Finish();
nnoble0c475f02014-12-05 15:37:39 -0800301 EXPECT_EQ(response.message(), request.message());
302 EXPECT_TRUE(s.IsOk());
303
304 delete stream;
nnoble0c475f02014-12-05 15:37:39 -0800305}
306
307TEST_F(End2endTest, RequestStreamTwoRequests) {
yangg1456d152015-01-08 15:39:58 -0800308 ResetStub();
nnoble0c475f02014-12-05 15:37:39 -0800309 EchoRequest request;
310 EchoResponse response;
311 ClientContext context;
312
yangg1456d152015-01-08 15:39:58 -0800313 ClientWriter<EchoRequest>* stream = stub_->RequestStream(&context, &response);
nnoble0c475f02014-12-05 15:37:39 -0800314 request.set_message("hello");
315 EXPECT_TRUE(stream->Write(request));
316 EXPECT_TRUE(stream->Write(request));
317 stream->WritesDone();
Craig Tillerf8ac5d82015-02-09 16:24:20 -0800318 Status s = stream->Finish();
nnoble0c475f02014-12-05 15:37:39 -0800319 EXPECT_EQ(response.message(), "hellohello");
320 EXPECT_TRUE(s.IsOk());
321
322 delete stream;
nnoble0c475f02014-12-05 15:37:39 -0800323}
324
325TEST_F(End2endTest, ResponseStream) {
yangg1456d152015-01-08 15:39:58 -0800326 ResetStub();
nnoble0c475f02014-12-05 15:37:39 -0800327 EchoRequest request;
328 EchoResponse response;
329 ClientContext context;
330 request.set_message("hello");
331
Craig Tiller47c83fd2015-02-21 22:45:35 -0800332 ClientReader<EchoResponse>* stream = stub_->ResponseStream(&context, request);
nnoble0c475f02014-12-05 15:37:39 -0800333 EXPECT_TRUE(stream->Read(&response));
334 EXPECT_EQ(response.message(), request.message() + "0");
335 EXPECT_TRUE(stream->Read(&response));
336 EXPECT_EQ(response.message(), request.message() + "1");
337 EXPECT_TRUE(stream->Read(&response));
338 EXPECT_EQ(response.message(), request.message() + "2");
339 EXPECT_FALSE(stream->Read(&response));
340
Craig Tiller4d0fb5f2015-02-09 16:27:22 -0800341 Status s = stream->Finish();
nnoble0c475f02014-12-05 15:37:39 -0800342 EXPECT_TRUE(s.IsOk());
343
344 delete stream;
nnoble0c475f02014-12-05 15:37:39 -0800345}
346
347TEST_F(End2endTest, BidiStream) {
yangg1456d152015-01-08 15:39:58 -0800348 ResetStub();
nnoble0c475f02014-12-05 15:37:39 -0800349 EchoRequest request;
350 EchoResponse response;
351 ClientContext context;
352 grpc::string msg("hello");
353
354 ClientReaderWriter<EchoRequest, EchoResponse>* stream =
yangg1456d152015-01-08 15:39:58 -0800355 stub_->BidiStream(&context);
nnoble0c475f02014-12-05 15:37:39 -0800356
357 request.set_message(msg + "0");
358 EXPECT_TRUE(stream->Write(request));
359 EXPECT_TRUE(stream->Read(&response));
360 EXPECT_EQ(response.message(), request.message());
361
362 request.set_message(msg + "1");
363 EXPECT_TRUE(stream->Write(request));
364 EXPECT_TRUE(stream->Read(&response));
365 EXPECT_EQ(response.message(), request.message());
366
367 request.set_message(msg + "2");
368 EXPECT_TRUE(stream->Write(request));
369 EXPECT_TRUE(stream->Read(&response));
370 EXPECT_EQ(response.message(), request.message());
371
372 stream->WritesDone();
373 EXPECT_FALSE(stream->Read(&response));
374
Craig Tiller4d0fb5f2015-02-09 16:27:22 -0800375 Status s = stream->Finish();
nnoble0c475f02014-12-05 15:37:39 -0800376 EXPECT_TRUE(s.IsOk());
377
378 delete stream;
yangg1456d152015-01-08 15:39:58 -0800379}
380
381// Talk to the two services with the same name but different package names.
382// The two stubs are created on the same channel.
383TEST_F(End2endTest, DiffPackageServices) {
Craig Tiller47c83fd2015-02-21 22:45:35 -0800384 std::shared_ptr<ChannelInterface> channel = CreateChannel(
385 server_address_.str(), InsecureCredentials(), ChannelArguments());
yangg1456d152015-01-08 15:39:58 -0800386
387 EchoRequest request;
388 EchoResponse response;
389 request.set_message("Hello");
390
391 std::unique_ptr<grpc::cpp::test::util::TestService::Stub> stub(
392 grpc::cpp::test::util::TestService::NewStub(channel));
393 ClientContext context;
394 Status s = stub->Echo(&context, request, &response);
395 EXPECT_EQ(response.message(), request.message());
396 EXPECT_TRUE(s.IsOk());
397
398 std::unique_ptr<grpc::cpp::test::util::duplicate::TestService::Stub>
399 dup_pkg_stub(
400 grpc::cpp::test::util::duplicate::TestService::NewStub(channel));
401 ClientContext context2;
402 s = dup_pkg_stub->Echo(&context2, request, &response);
403 EXPECT_EQ("no package", response.message());
404 EXPECT_TRUE(s.IsOk());
nnoble0c475f02014-12-05 15:37:39 -0800405}
406
yangg4105e2b2015-01-09 14:19:44 -0800407// rpc and stream should fail on bad credentials.
408TEST_F(End2endTest, BadCredentials) {
409 std::unique_ptr<Credentials> bad_creds =
Craig Tiller47c83fd2015-02-21 22:45:35 -0800410 ServiceAccountCredentials("", "", std::chrono::seconds(1));
yangg4105e2b2015-01-09 14:19:44 -0800411 EXPECT_EQ(nullptr, bad_creds.get());
412 std::shared_ptr<ChannelInterface> channel =
413 CreateChannel(server_address_.str(), bad_creds, ChannelArguments());
414 std::unique_ptr<grpc::cpp::test::util::TestService::Stub> stub(
415 grpc::cpp::test::util::TestService::NewStub(channel));
416 EchoRequest request;
417 EchoResponse response;
418 ClientContext context;
419 grpc::string msg("hello");
420
421 Status s = stub->Echo(&context, request, &response);
422 EXPECT_EQ("", response.message());
423 EXPECT_FALSE(s.IsOk());
424 EXPECT_EQ(StatusCode::UNKNOWN, s.code());
425 EXPECT_EQ("Rpc sent on a lame channel.", s.details());
426
427 ClientContext context2;
428 ClientReaderWriter<EchoRequest, EchoResponse>* stream =
429 stub->BidiStream(&context2);
Craig Tiller4d0fb5f2015-02-09 16:27:22 -0800430 s = stream->Finish();
yangg4105e2b2015-01-09 14:19:44 -0800431 EXPECT_FALSE(s.IsOk());
432 EXPECT_EQ(StatusCode::UNKNOWN, s.code());
433 EXPECT_EQ("Rpc sent on a lame channel.", s.details());
434
435 delete stream;
436}
437
yangged5e7e02015-01-06 10:16:15 -0800438} // namespace testing
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800439} // namespace grpc
440
441int main(int argc, char** argv) {
Craig Tiller14e60e92015-01-13 17:26:46 -0800442 grpc_test_init(argc, argv);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800443 grpc_init();
444 ::testing::InitGoogleTest(&argc, argv);
445 int result = RUN_ALL_TESTS();
446 grpc_shutdown();
Craig Tillerec3257c2015-02-12 15:59:43 -0800447 google::protobuf::ShutdownProtobufLibrary();
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800448 return result;
Craig Tiller190d3602015-02-18 09:23:38 -0800449}