Line data Source code
1 : /*
2 : *
3 : * Copyright 2015, 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 :
36 : #include <grpc/grpc.h>
37 : #include <grpc/support/sync.h>
38 : #include <grpc++/channel.h>
39 : #include <grpc++/client_context.h>
40 : #include <grpc++/create_channel.h>
41 : #include <grpc++/server.h>
42 : #include <grpc++/server_builder.h>
43 : #include <grpc++/server_context.h>
44 : #include <gtest/gtest.h>
45 :
46 : #include "src/core/support/env.h"
47 : #include "test/core/util/test_config.h"
48 : #include "test/core/util/port.h"
49 : #include "test/cpp/util/echo.grpc.pb.h"
50 :
51 : using grpc::cpp::test::util::EchoRequest;
52 : using grpc::cpp::test::util::EchoResponse;
53 :
54 : namespace grpc {
55 : namespace testing {
56 :
57 1 : class TestServiceImpl : public ::grpc::cpp::test::util::TestService::Service {
58 : public:
59 1 : explicit TestServiceImpl(gpr_event* ev) : ev_(ev) {}
60 :
61 1 : Status Echo(ServerContext* context, const EchoRequest* request,
62 : EchoResponse* response) GRPC_OVERRIDE {
63 1 : gpr_event_set(ev_, (void*)1);
64 1 : while (!context->IsCancelled()) {
65 : }
66 1 : return Status::OK;
67 : }
68 :
69 : private:
70 : gpr_event* ev_;
71 : };
72 :
73 1 : class ShutdownTest : public ::testing::Test {
74 : public:
75 1 : ShutdownTest() : shutdown_(false), service_(&ev_) { gpr_event_init(&ev_); }
76 :
77 1 : void SetUp() GRPC_OVERRIDE {
78 1 : port_ = grpc_pick_unused_port_or_die();
79 1 : server_ = SetUpServer(port_);
80 1 : }
81 :
82 1 : std::unique_ptr<Server> SetUpServer(const int port) {
83 1 : grpc::string server_address = "localhost:" + to_string(port);
84 :
85 2 : ServerBuilder builder;
86 1 : builder.AddListeningPort(server_address, InsecureServerCredentials());
87 1 : builder.RegisterService(&service_);
88 1 : std::unique_ptr<Server> server = builder.BuildAndStart();
89 2 : return server;
90 : }
91 :
92 1 : void TearDown() GRPC_OVERRIDE { GPR_ASSERT(shutdown_); }
93 :
94 1 : void ResetStub() {
95 1 : string target = "dns:localhost:" + to_string(port_);
96 1 : channel_ = CreateChannel(target, InsecureCredentials());
97 1 : stub_ = grpc::cpp::test::util::TestService::NewStub(channel_);
98 1 : }
99 :
100 2 : string to_string(const int number) {
101 2 : std::stringstream strs;
102 2 : strs << number;
103 2 : return strs.str();
104 : }
105 :
106 1 : void SendRequest() {
107 1 : EchoRequest request;
108 2 : EchoResponse response;
109 1 : request.set_message("Hello");
110 2 : ClientContext context;
111 1 : GPR_ASSERT(!shutdown_);
112 2 : Status s = stub_->Echo(&context, request, &response);
113 2 : GPR_ASSERT(shutdown_);
114 1 : }
115 :
116 : protected:
117 : std::shared_ptr<Channel> channel_;
118 : std::unique_ptr<grpc::cpp::test::util::TestService::Stub> stub_;
119 : std::unique_ptr<Server> server_;
120 : bool shutdown_;
121 : int port_;
122 : gpr_event ev_;
123 : TestServiceImpl service_;
124 : };
125 :
126 : // Tests zookeeper state change between two RPCs
127 : // TODO(ctiller): leaked objects in this test
128 5 : TEST_F(ShutdownTest, ShutdownTest) {
129 1 : ResetStub();
130 :
131 : // send the request in a background thread
132 1 : std::thread thr(std::bind(&ShutdownTest::SendRequest, this));
133 :
134 : // wait for the server to get the event
135 1 : gpr_event_wait(&ev_, gpr_inf_future(GPR_CLOCK_MONOTONIC));
136 :
137 1 : shutdown_ = true;
138 :
139 : // shutdown should trigger cancellation causing everything to shutdown
140 : auto deadline =
141 1 : std::chrono::system_clock::now() + std::chrono::microseconds(100);
142 1 : server_->Shutdown(deadline);
143 1 : EXPECT_GE(std::chrono::system_clock::now(), deadline);
144 :
145 1 : thr.join();
146 1 : }
147 :
148 : } // namespace testing
149 : } // namespace grpc
150 :
151 1 : int main(int argc, char** argv) {
152 1 : grpc_test_init(argc, argv);
153 1 : ::testing::InitGoogleTest(&argc, argv);
154 1 : return RUN_ALL_TESTS();
155 3 : }
|