blob: 94a04aed37d7867c729e68bb8148ac79e5643cbf [file] [log] [blame]
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001/*
2 *
3 * Copyright 2014, Google Inc.
4 * 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"
yangg59dfc902014-12-19 14:00:14 -080041#include <grpc++/channel_arguments.h>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080042#include <grpc++/channel_interface.h>
43#include <grpc++/client_context.h>
44#include <grpc++/create_channel.h>
yangg4105e2b2015-01-09 14:19:44 -080045#include <grpc++/credentials.h>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080046#include <grpc++/server.h>
47#include <grpc++/server_builder.h>
yangga4b6f5d2014-12-17 15:53:12 -080048#include <grpc++/server_context.h>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080049#include <grpc++/status.h>
nnoble0c475f02014-12-05 15:37:39 -080050#include <grpc++/stream.h>
Craig Tiller35e39712015-01-12 16:41:24 -080051#include "test/core/util/port.h"
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080052#include <gtest/gtest.h>
53
54#include <grpc/grpc.h>
55#include <grpc/support/thd.h>
yangged5e7e02015-01-06 10:16:15 -080056#include <grpc/support/time.h>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080057
58using grpc::cpp::test::util::EchoRequest;
59using grpc::cpp::test::util::EchoResponse;
yangged5e7e02015-01-06 10:16:15 -080060using std::chrono::system_clock;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080061
62namespace grpc {
yangged5e7e02015-01-06 10:16:15 -080063namespace testing {
64
65namespace {
66
67// When echo_deadline is requested, deadline seen in the ServerContext is set in
68// the response in seconds.
69void MaybeEchoDeadline(ServerContext* context, const EchoRequest* request,
70 EchoResponse* response) {
71 if (request->has_param() && request->param().echo_deadline()) {
72 gpr_timespec deadline = gpr_inf_future;
73 if (context->absolute_deadline() != system_clock::time_point::max()) {
74 Timepoint2Timespec(context->absolute_deadline(), &deadline);
75 }
76 response->mutable_param()->set_request_deadline(deadline.tv_sec);
77 }
78}
79} // namespace
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080080
yangg1456d152015-01-08 15:39:58 -080081class TestServiceImpl : public ::grpc::cpp::test::util::TestService::Service {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080082 public:
yangga4b6f5d2014-12-17 15:53:12 -080083 Status Echo(ServerContext* context, const EchoRequest* request,
yangg1456d152015-01-08 15:39:58 -080084 EchoResponse* response) override {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080085 response->set_message(request->message());
yangged5e7e02015-01-06 10:16:15 -080086 MaybeEchoDeadline(context, request, response);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080087 return Status::OK;
88 }
nnoble0c475f02014-12-05 15:37:39 -080089
90 // Unimplemented is left unimplemented to test the returned error.
91
yangga4b6f5d2014-12-17 15:53:12 -080092 Status RequestStream(ServerContext* context,
93 ServerReader<EchoRequest>* reader,
yangg1456d152015-01-08 15:39:58 -080094 EchoResponse* response) override {
nnoble0c475f02014-12-05 15:37:39 -080095 EchoRequest request;
96 response->set_message("");
97 while (reader->Read(&request)) {
98 response->mutable_message()->append(request.message());
99 }
100 return Status::OK;
101 }
102
103 // Return 3 messages.
104 // TODO(yangg) make it generic by adding a parameter into EchoRequest
yangga4b6f5d2014-12-17 15:53:12 -0800105 Status ResponseStream(ServerContext* context, const EchoRequest* request,
yangg1456d152015-01-08 15:39:58 -0800106 ServerWriter<EchoResponse>* writer) override {
nnoble0c475f02014-12-05 15:37:39 -0800107 EchoResponse response;
108 response.set_message(request->message() + "0");
109 writer->Write(response);
110 response.set_message(request->message() + "1");
111 writer->Write(response);
112 response.set_message(request->message() + "2");
113 writer->Write(response);
114
115 return Status::OK;
116 }
117
yangg1456d152015-01-08 15:39:58 -0800118 Status BidiStream(
119 ServerContext* context,
120 ServerReaderWriter<EchoResponse, EchoRequest>* stream) override {
nnoble0c475f02014-12-05 15:37:39 -0800121 EchoRequest request;
122 EchoResponse response;
123 while (stream->Read(&request)) {
124 gpr_log(GPR_INFO, "recv msg %s", request.message().c_str());
125 response.set_message(request.message());
126 stream->Write(response);
127 }
128 return Status::OK;
129 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800130};
131
yangg1456d152015-01-08 15:39:58 -0800132class TestServiceImplDupPkg
133 : public ::grpc::cpp::test::util::duplicate::TestService::Service {
134 public:
135 Status Echo(ServerContext* context, const EchoRequest* request,
136 EchoResponse* response) override {
137 response->set_message("no package");
138 return Status::OK;
139 }
140};
141
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800142class End2endTest : public ::testing::Test {
143 protected:
144 void SetUp() override {
Craig Tiller35e39712015-01-12 16:41:24 -0800145 int port = grpc_pick_unused_port_or_die();
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800146 server_address_ << "localhost:" << port;
147 // Setup server
148 ServerBuilder builder;
149 builder.AddPort(server_address_.str());
Craig Tillerf8ac5d82015-02-09 16:24:20 -0800150 builder.RegisterService(&service_);
151 builder.RegisterService(&dup_pkg_service_);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800152 server_ = builder.BuildAndStart();
153 }
154
Craig Tillerb5dcec52015-01-13 11:13:42 -0800155 void TearDown() override { server_->Shutdown(); }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800156
yangg1456d152015-01-08 15:39:58 -0800157 void ResetStub() {
158 std::shared_ptr<ChannelInterface> channel =
159 CreateChannel(server_address_.str(), ChannelArguments());
160 stub_.reset(grpc::cpp::test::util::TestService::NewStub(channel));
161 }
162
163 std::unique_ptr<grpc::cpp::test::util::TestService::Stub> stub_;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800164 std::unique_ptr<Server> server_;
165 std::ostringstream server_address_;
nnoble0c475f02014-12-05 15:37:39 -0800166 TestServiceImpl service_;
yangg1456d152015-01-08 15:39:58 -0800167 TestServiceImplDupPkg dup_pkg_service_;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800168};
169
yangg1456d152015-01-08 15:39:58 -0800170static void SendRpc(grpc::cpp::test::util::TestService::Stub* stub,
171 int num_rpcs) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800172 EchoRequest request;
173 EchoResponse response;
174 request.set_message("Hello");
175
176 for (int i = 0; i < num_rpcs; ++i) {
177 ClientContext context;
178 Status s = stub->Echo(&context, request, &response);
179 EXPECT_EQ(response.message(), request.message());
180 EXPECT_TRUE(s.IsOk());
181 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800182}
183
184TEST_F(End2endTest, SimpleRpc) {
yangg1456d152015-01-08 15:39:58 -0800185 ResetStub();
186 SendRpc(stub_.get(), 1);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800187}
188
189TEST_F(End2endTest, MultipleRpcs) {
yangg1456d152015-01-08 15:39:58 -0800190 ResetStub();
Craig Tiller35e39712015-01-12 16:41:24 -0800191 std::vector<std::thread*> threads;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800192 for (int i = 0; i < 10; ++i) {
yangg1456d152015-01-08 15:39:58 -0800193 threads.push_back(new std::thread(SendRpc, stub_.get(), 10));
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800194 }
195 for (int i = 0; i < 10; ++i) {
196 threads[i]->join();
197 delete threads[i];
198 }
199}
200
yanggda029e32014-12-18 10:24:04 -0800201// Set a 10us deadline and make sure proper error is returned.
202TEST_F(End2endTest, RpcDeadlineExpires) {
yangg1456d152015-01-08 15:39:58 -0800203 ResetStub();
yanggda029e32014-12-18 10:24:04 -0800204 EchoRequest request;
205 EchoResponse response;
206 request.set_message("Hello");
207
208 ClientContext context;
209 std::chrono::system_clock::time_point deadline =
210 std::chrono::system_clock::now() + std::chrono::microseconds(10);
211 context.set_absolute_deadline(deadline);
yangg1456d152015-01-08 15:39:58 -0800212 Status s = stub_->Echo(&context, request, &response);
Craig Tiller7b018782015-01-16 09:53:39 -0800213 EXPECT_EQ(StatusCode::DEADLINE_EXCEEDED, s.code());
yanggda029e32014-12-18 10:24:04 -0800214}
215
yangged5e7e02015-01-06 10:16:15 -0800216// Set a long but finite deadline.
217TEST_F(End2endTest, RpcLongDeadline) {
yangg1456d152015-01-08 15:39:58 -0800218 ResetStub();
yangged5e7e02015-01-06 10:16:15 -0800219 EchoRequest request;
220 EchoResponse response;
221 request.set_message("Hello");
222
223 ClientContext context;
224 std::chrono::system_clock::time_point deadline =
225 std::chrono::system_clock::now() + std::chrono::hours(1);
226 context.set_absolute_deadline(deadline);
yangg1456d152015-01-08 15:39:58 -0800227 Status s = stub_->Echo(&context, request, &response);
yangged5e7e02015-01-06 10:16:15 -0800228 EXPECT_EQ(response.message(), request.message());
229 EXPECT_TRUE(s.IsOk());
yangged5e7e02015-01-06 10:16:15 -0800230}
231
232// Ask server to echo back the deadline it sees.
233TEST_F(End2endTest, EchoDeadline) {
yangg1456d152015-01-08 15:39:58 -0800234 ResetStub();
yangged5e7e02015-01-06 10:16:15 -0800235 EchoRequest request;
236 EchoResponse response;
237 request.set_message("Hello");
238 request.mutable_param()->set_echo_deadline(true);
239
240 ClientContext context;
241 std::chrono::system_clock::time_point deadline =
242 std::chrono::system_clock::now() + std::chrono::seconds(100);
243 context.set_absolute_deadline(deadline);
yangg1456d152015-01-08 15:39:58 -0800244 Status s = stub_->Echo(&context, request, &response);
yangged5e7e02015-01-06 10:16:15 -0800245 EXPECT_EQ(response.message(), request.message());
246 EXPECT_TRUE(s.IsOk());
247 gpr_timespec sent_deadline;
248 Timepoint2Timespec(deadline, &sent_deadline);
249 // Allow 1 second error.
250 EXPECT_LE(response.param().request_deadline() - sent_deadline.tv_sec, 1);
251 EXPECT_GE(response.param().request_deadline() - sent_deadline.tv_sec, -1);
yangged5e7e02015-01-06 10:16:15 -0800252}
253
254// Ask server to echo back the deadline it sees. The rpc has no deadline.
255TEST_F(End2endTest, EchoDeadlineForNoDeadlineRpc) {
yangg1456d152015-01-08 15:39:58 -0800256 ResetStub();
yangged5e7e02015-01-06 10:16:15 -0800257 EchoRequest request;
258 EchoResponse response;
259 request.set_message("Hello");
260 request.mutable_param()->set_echo_deadline(true);
261
262 ClientContext context;
yangg1456d152015-01-08 15:39:58 -0800263 Status s = stub_->Echo(&context, request, &response);
yangged5e7e02015-01-06 10:16:15 -0800264 EXPECT_EQ(response.message(), request.message());
265 EXPECT_TRUE(s.IsOk());
266 EXPECT_EQ(response.param().request_deadline(), gpr_inf_future.tv_sec);
yangged5e7e02015-01-06 10:16:15 -0800267}
268
nnoble0c475f02014-12-05 15:37:39 -0800269TEST_F(End2endTest, UnimplementedRpc) {
yangg1456d152015-01-08 15:39:58 -0800270 ResetStub();
nnoble0c475f02014-12-05 15:37:39 -0800271 EchoRequest request;
272 EchoResponse response;
273 request.set_message("Hello");
274
275 ClientContext context;
yangg1456d152015-01-08 15:39:58 -0800276 Status s = stub_->Unimplemented(&context, request, &response);
nnoble0c475f02014-12-05 15:37:39 -0800277 EXPECT_FALSE(s.IsOk());
278 EXPECT_EQ(s.code(), grpc::StatusCode::UNIMPLEMENTED);
279 EXPECT_EQ(s.details(), "");
280 EXPECT_EQ(response.message(), "");
nnoble0c475f02014-12-05 15:37:39 -0800281}
282
283TEST_F(End2endTest, RequestStreamOneRequest) {
yangg1456d152015-01-08 15:39:58 -0800284 ResetStub();
nnoble0c475f02014-12-05 15:37:39 -0800285 EchoRequest request;
286 EchoResponse response;
287 ClientContext context;
288
yangg1456d152015-01-08 15:39:58 -0800289 ClientWriter<EchoRequest>* stream = stub_->RequestStream(&context, &response);
nnoble0c475f02014-12-05 15:37:39 -0800290 request.set_message("hello");
291 EXPECT_TRUE(stream->Write(request));
292 stream->WritesDone();
Craig Tillerf8ac5d82015-02-09 16:24:20 -0800293 Status s = stream->Finish();
nnoble0c475f02014-12-05 15:37:39 -0800294 EXPECT_EQ(response.message(), request.message());
295 EXPECT_TRUE(s.IsOk());
296
297 delete stream;
nnoble0c475f02014-12-05 15:37:39 -0800298}
299
300TEST_F(End2endTest, RequestStreamTwoRequests) {
yangg1456d152015-01-08 15:39:58 -0800301 ResetStub();
nnoble0c475f02014-12-05 15:37:39 -0800302 EchoRequest request;
303 EchoResponse response;
304 ClientContext context;
305
yangg1456d152015-01-08 15:39:58 -0800306 ClientWriter<EchoRequest>* stream = stub_->RequestStream(&context, &response);
nnoble0c475f02014-12-05 15:37:39 -0800307 request.set_message("hello");
308 EXPECT_TRUE(stream->Write(request));
309 EXPECT_TRUE(stream->Write(request));
310 stream->WritesDone();
Craig Tillerf8ac5d82015-02-09 16:24:20 -0800311 Status s = stream->Finish();
nnoble0c475f02014-12-05 15:37:39 -0800312 EXPECT_EQ(response.message(), "hellohello");
313 EXPECT_TRUE(s.IsOk());
314
315 delete stream;
nnoble0c475f02014-12-05 15:37:39 -0800316}
317
318TEST_F(End2endTest, ResponseStream) {
yangg1456d152015-01-08 15:39:58 -0800319 ResetStub();
nnoble0c475f02014-12-05 15:37:39 -0800320 EchoRequest request;
321 EchoResponse response;
322 ClientContext context;
323 request.set_message("hello");
324
yangg1456d152015-01-08 15:39:58 -0800325 ClientReader<EchoResponse>* stream =
326 stub_->ResponseStream(&context, &request);
nnoble0c475f02014-12-05 15:37:39 -0800327 EXPECT_TRUE(stream->Read(&response));
328 EXPECT_EQ(response.message(), request.message() + "0");
329 EXPECT_TRUE(stream->Read(&response));
330 EXPECT_EQ(response.message(), request.message() + "1");
331 EXPECT_TRUE(stream->Read(&response));
332 EXPECT_EQ(response.message(), request.message() + "2");
333 EXPECT_FALSE(stream->Read(&response));
334
335 Status s = stream->Wait();
336 EXPECT_TRUE(s.IsOk());
337
338 delete stream;
nnoble0c475f02014-12-05 15:37:39 -0800339}
340
341TEST_F(End2endTest, BidiStream) {
yangg1456d152015-01-08 15:39:58 -0800342 ResetStub();
nnoble0c475f02014-12-05 15:37:39 -0800343 EchoRequest request;
344 EchoResponse response;
345 ClientContext context;
346 grpc::string msg("hello");
347
348 ClientReaderWriter<EchoRequest, EchoResponse>* stream =
yangg1456d152015-01-08 15:39:58 -0800349 stub_->BidiStream(&context);
nnoble0c475f02014-12-05 15:37:39 -0800350
351 request.set_message(msg + "0");
352 EXPECT_TRUE(stream->Write(request));
353 EXPECT_TRUE(stream->Read(&response));
354 EXPECT_EQ(response.message(), request.message());
355
356 request.set_message(msg + "1");
357 EXPECT_TRUE(stream->Write(request));
358 EXPECT_TRUE(stream->Read(&response));
359 EXPECT_EQ(response.message(), request.message());
360
361 request.set_message(msg + "2");
362 EXPECT_TRUE(stream->Write(request));
363 EXPECT_TRUE(stream->Read(&response));
364 EXPECT_EQ(response.message(), request.message());
365
366 stream->WritesDone();
367 EXPECT_FALSE(stream->Read(&response));
368
369 Status s = stream->Wait();
370 EXPECT_TRUE(s.IsOk());
371
372 delete stream;
yangg1456d152015-01-08 15:39:58 -0800373}
374
375// Talk to the two services with the same name but different package names.
376// The two stubs are created on the same channel.
377TEST_F(End2endTest, DiffPackageServices) {
378 std::shared_ptr<ChannelInterface> channel =
379 CreateChannel(server_address_.str(), ChannelArguments());
380
381 EchoRequest request;
382 EchoResponse response;
383 request.set_message("Hello");
384
385 std::unique_ptr<grpc::cpp::test::util::TestService::Stub> stub(
386 grpc::cpp::test::util::TestService::NewStub(channel));
387 ClientContext context;
388 Status s = stub->Echo(&context, request, &response);
389 EXPECT_EQ(response.message(), request.message());
390 EXPECT_TRUE(s.IsOk());
391
392 std::unique_ptr<grpc::cpp::test::util::duplicate::TestService::Stub>
393 dup_pkg_stub(
394 grpc::cpp::test::util::duplicate::TestService::NewStub(channel));
395 ClientContext context2;
396 s = dup_pkg_stub->Echo(&context2, request, &response);
397 EXPECT_EQ("no package", response.message());
398 EXPECT_TRUE(s.IsOk());
nnoble0c475f02014-12-05 15:37:39 -0800399}
400
yangg4105e2b2015-01-09 14:19:44 -0800401// rpc and stream should fail on bad credentials.
402TEST_F(End2endTest, BadCredentials) {
403 std::unique_ptr<Credentials> bad_creds =
404 CredentialsFactory::ServiceAccountCredentials("", "",
405 std::chrono::seconds(1));
406 EXPECT_EQ(nullptr, bad_creds.get());
407 std::shared_ptr<ChannelInterface> channel =
408 CreateChannel(server_address_.str(), bad_creds, ChannelArguments());
409 std::unique_ptr<grpc::cpp::test::util::TestService::Stub> stub(
410 grpc::cpp::test::util::TestService::NewStub(channel));
411 EchoRequest request;
412 EchoResponse response;
413 ClientContext context;
414 grpc::string msg("hello");
415
416 Status s = stub->Echo(&context, request, &response);
417 EXPECT_EQ("", response.message());
418 EXPECT_FALSE(s.IsOk());
419 EXPECT_EQ(StatusCode::UNKNOWN, s.code());
420 EXPECT_EQ("Rpc sent on a lame channel.", s.details());
421
422 ClientContext context2;
423 ClientReaderWriter<EchoRequest, EchoResponse>* stream =
424 stub->BidiStream(&context2);
425 s = stream->Wait();
426 EXPECT_FALSE(s.IsOk());
427 EXPECT_EQ(StatusCode::UNKNOWN, s.code());
428 EXPECT_EQ("Rpc sent on a lame channel.", s.details());
429
430 delete stream;
431}
432
yangged5e7e02015-01-06 10:16:15 -0800433} // namespace testing
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800434} // namespace grpc
435
436int main(int argc, char** argv) {
Craig Tiller14e60e92015-01-13 17:26:46 -0800437 grpc_test_init(argc, argv);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800438 grpc_init();
439 ::testing::InitGoogleTest(&argc, argv);
440 int result = RUN_ALL_TESTS();
441 grpc_shutdown();
442 return result;
443}