blob: b8f9fcf2289d524394f6cb73261df94b3eccf334 [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
34#include <thread>
35#include "src/cpp/server/rpc_service_method.h"
36#include "test/cpp/util/echo.pb.h"
37#include "net/util/netutil.h"
38#include <grpc++/channel_interface.h>
39#include <grpc++/client_context.h>
40#include <grpc++/create_channel.h>
41#include <grpc++/server.h>
42#include <grpc++/server_builder.h>
yangga4b6f5d2014-12-17 15:53:12 -080043#include <grpc++/server_context.h>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080044#include <grpc++/status.h>
nnoble0c475f02014-12-05 15:37:39 -080045#include <grpc++/stream.h>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080046#include <gtest/gtest.h>
47
48#include <grpc/grpc.h>
49#include <grpc/support/thd.h>
50
51using grpc::cpp::test::util::EchoRequest;
52using grpc::cpp::test::util::EchoResponse;
53using grpc::cpp::test::util::TestService;
54
55namespace grpc {
56
57class TestServiceImpl : public TestService::Service {
58 public:
yangga4b6f5d2014-12-17 15:53:12 -080059 Status Echo(ServerContext* context, const EchoRequest* request,
60 EchoResponse* response) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080061 response->set_message(request->message());
62 return Status::OK;
63 }
nnoble0c475f02014-12-05 15:37:39 -080064
65 // Unimplemented is left unimplemented to test the returned error.
66
yangga4b6f5d2014-12-17 15:53:12 -080067 Status RequestStream(ServerContext* context,
68 ServerReader<EchoRequest>* reader,
nnoble0c475f02014-12-05 15:37:39 -080069 EchoResponse* response) {
70 EchoRequest request;
71 response->set_message("");
72 while (reader->Read(&request)) {
73 response->mutable_message()->append(request.message());
74 }
75 return Status::OK;
76 }
77
78 // Return 3 messages.
79 // TODO(yangg) make it generic by adding a parameter into EchoRequest
yangga4b6f5d2014-12-17 15:53:12 -080080 Status ResponseStream(ServerContext* context, const EchoRequest* request,
nnoble0c475f02014-12-05 15:37:39 -080081 ServerWriter<EchoResponse>* writer) {
82 EchoResponse response;
83 response.set_message(request->message() + "0");
84 writer->Write(response);
85 response.set_message(request->message() + "1");
86 writer->Write(response);
87 response.set_message(request->message() + "2");
88 writer->Write(response);
89
90 return Status::OK;
91 }
92
yangga4b6f5d2014-12-17 15:53:12 -080093 Status BidiStream(ServerContext* context,
94 ServerReaderWriter<EchoResponse, EchoRequest>* stream) {
nnoble0c475f02014-12-05 15:37:39 -080095 EchoRequest request;
96 EchoResponse response;
97 while (stream->Read(&request)) {
98 gpr_log(GPR_INFO, "recv msg %s", request.message().c_str());
99 response.set_message(request.message());
100 stream->Write(response);
101 }
102 return Status::OK;
103 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800104};
105
106class End2endTest : public ::testing::Test {
107 protected:
108 void SetUp() override {
109 int port = PickUnusedPortOrDie();
110 server_address_ << "localhost:" << port;
111 // Setup server
112 ServerBuilder builder;
113 builder.AddPort(server_address_.str());
nnoble0c475f02014-12-05 15:37:39 -0800114 builder.RegisterService(service_.service());
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800115 server_ = builder.BuildAndStart();
116 }
117
118 void TearDown() override {
119 server_->Shutdown();
120 }
121
122 std::unique_ptr<Server> server_;
123 std::ostringstream server_address_;
nnoble0c475f02014-12-05 15:37:39 -0800124 TestServiceImpl service_;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800125};
126
127static void SendRpc(const grpc::string& server_address, int num_rpcs) {
128 std::shared_ptr<ChannelInterface> channel =
129 CreateChannel(server_address);
130 TestService::Stub* stub = TestService::NewStub(channel);
131 EchoRequest request;
132 EchoResponse response;
133 request.set_message("Hello");
134
135 for (int i = 0; i < num_rpcs; ++i) {
136 ClientContext context;
137 Status s = stub->Echo(&context, request, &response);
138 EXPECT_EQ(response.message(), request.message());
139 EXPECT_TRUE(s.IsOk());
140 }
141
142 delete stub;
143}
144
145TEST_F(End2endTest, SimpleRpc) {
146 SendRpc(server_address_.str(), 1);
147}
148
149TEST_F(End2endTest, MultipleRpcs) {
150 vector<std::thread*> threads;
151 for (int i = 0; i < 10; ++i) {
152 threads.push_back(new std::thread(SendRpc, server_address_.str(), 10));
153 }
154 for (int i = 0; i < 10; ++i) {
155 threads[i]->join();
156 delete threads[i];
157 }
158}
159
nnoble0c475f02014-12-05 15:37:39 -0800160TEST_F(End2endTest, UnimplementedRpc) {
161 std::shared_ptr<ChannelInterface> channel =
162 CreateChannel(server_address_.str());
163 TestService::Stub* stub = TestService::NewStub(channel);
164 EchoRequest request;
165 EchoResponse response;
166 request.set_message("Hello");
167
168 ClientContext context;
169 Status s = stub->Unimplemented(&context, request, &response);
170 EXPECT_FALSE(s.IsOk());
171 EXPECT_EQ(s.code(), grpc::StatusCode::UNIMPLEMENTED);
172 EXPECT_EQ(s.details(), "");
173 EXPECT_EQ(response.message(), "");
174
175 delete stub;
176}
177
178TEST_F(End2endTest, RequestStreamOneRequest) {
179 std::shared_ptr<ChannelInterface> channel =
180 CreateChannel(server_address_.str());
181 TestService::Stub* stub = TestService::NewStub(channel);
182 EchoRequest request;
183 EchoResponse response;
184 ClientContext context;
185
186 ClientWriter<EchoRequest>* stream = stub->RequestStream(&context, &response);
187 request.set_message("hello");
188 EXPECT_TRUE(stream->Write(request));
189 stream->WritesDone();
190 Status s = stream->Wait();
191 EXPECT_EQ(response.message(), request.message());
192 EXPECT_TRUE(s.IsOk());
193
194 delete stream;
195 delete stub;
196}
197
198TEST_F(End2endTest, RequestStreamTwoRequests) {
199 std::shared_ptr<ChannelInterface> channel =
200 CreateChannel(server_address_.str());
201 TestService::Stub* stub = TestService::NewStub(channel);
202 EchoRequest request;
203 EchoResponse response;
204 ClientContext context;
205
206 ClientWriter<EchoRequest>* stream = stub->RequestStream(&context, &response);
207 request.set_message("hello");
208 EXPECT_TRUE(stream->Write(request));
209 EXPECT_TRUE(stream->Write(request));
210 stream->WritesDone();
211 Status s = stream->Wait();
212 EXPECT_EQ(response.message(), "hellohello");
213 EXPECT_TRUE(s.IsOk());
214
215 delete stream;
216 delete stub;
217}
218
219TEST_F(End2endTest, ResponseStream) {
220 std::shared_ptr<ChannelInterface> channel =
221 CreateChannel(server_address_.str());
222 TestService::Stub* stub = TestService::NewStub(channel);
223 EchoRequest request;
224 EchoResponse response;
225 ClientContext context;
226 request.set_message("hello");
227
228 ClientReader<EchoResponse>* stream = stub->ResponseStream(&context, &request);
229 EXPECT_TRUE(stream->Read(&response));
230 EXPECT_EQ(response.message(), request.message() + "0");
231 EXPECT_TRUE(stream->Read(&response));
232 EXPECT_EQ(response.message(), request.message() + "1");
233 EXPECT_TRUE(stream->Read(&response));
234 EXPECT_EQ(response.message(), request.message() + "2");
235 EXPECT_FALSE(stream->Read(&response));
236
237 Status s = stream->Wait();
238 EXPECT_TRUE(s.IsOk());
239
240 delete stream;
241 delete stub;
242}
243
244TEST_F(End2endTest, BidiStream) {
245 std::shared_ptr<ChannelInterface> channel =
246 CreateChannel(server_address_.str());
247 TestService::Stub* stub = TestService::NewStub(channel);
248 EchoRequest request;
249 EchoResponse response;
250 ClientContext context;
251 grpc::string msg("hello");
252
253 ClientReaderWriter<EchoRequest, EchoResponse>* stream =
254 stub->BidiStream(&context);
255
256 request.set_message(msg + "0");
257 EXPECT_TRUE(stream->Write(request));
258 EXPECT_TRUE(stream->Read(&response));
259 EXPECT_EQ(response.message(), request.message());
260
261 request.set_message(msg + "1");
262 EXPECT_TRUE(stream->Write(request));
263 EXPECT_TRUE(stream->Read(&response));
264 EXPECT_EQ(response.message(), request.message());
265
266 request.set_message(msg + "2");
267 EXPECT_TRUE(stream->Write(request));
268 EXPECT_TRUE(stream->Read(&response));
269 EXPECT_EQ(response.message(), request.message());
270
271 stream->WritesDone();
272 EXPECT_FALSE(stream->Read(&response));
273
274 Status s = stream->Wait();
275 EXPECT_TRUE(s.IsOk());
276
277 delete stream;
278 delete stub;
279}
280
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800281} // namespace grpc
282
283int main(int argc, char** argv) {
284 grpc_init();
285 ::testing::InitGoogleTest(&argc, argv);
286 int result = RUN_ALL_TESTS();
287 grpc_shutdown();
288 return result;
289}