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 <grpc/grpc.h>
35 : #include <grpc/support/thd.h>
36 : #include <grpc/support/time.h>
37 : #include <grpc++/channel.h>
38 : #include <grpc++/client_context.h>
39 : #include <grpc++/create_channel.h>
40 : #include <grpc++/server.h>
41 : #include <grpc++/server_builder.h>
42 : #include <grpc++/server_context.h>
43 : #include <gtest/gtest.h>
44 :
45 : #include "test/core/util/port.h"
46 : #include "test/core/util/test_config.h"
47 : #include "test/cpp/util/echo.grpc.pb.h"
48 : #include "test/cpp/util/echo_duplicate.grpc.pb.h"
49 : #include "test/cpp/util/subprocess.h"
50 :
51 : using grpc::cpp::test::util::EchoRequest;
52 : using grpc::cpp::test::util::EchoResponse;
53 : using std::chrono::system_clock;
54 :
55 1 : static std::string g_root;
56 :
57 : namespace grpc {
58 : namespace testing {
59 :
60 : namespace {
61 :
62 2 : class ServiceImpl GRPC_FINAL
63 : : public ::grpc::cpp::test::util::TestService::Service {
64 : public:
65 2 : ServiceImpl() : bidi_stream_count_(0), response_stream_count_(0) {}
66 :
67 1 : Status BidiStream(ServerContext* context,
68 : ServerReaderWriter<EchoResponse, EchoRequest>* stream)
69 : GRPC_OVERRIDE {
70 1 : bidi_stream_count_++;
71 1 : EchoRequest request;
72 2 : EchoResponse response;
73 7 : while (stream->Read(&request)) {
74 5 : gpr_log(GPR_INFO, "recv msg %s", request.message().c_str());
75 5 : response.set_message(request.message());
76 5 : stream->Write(response);
77 : gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
78 5 : gpr_time_from_seconds(1, GPR_TIMESPAN)));
79 : }
80 2 : return Status::OK;
81 : }
82 :
83 1 : Status ResponseStream(ServerContext* context, const EchoRequest* request,
84 : ServerWriter<EchoResponse>* writer) GRPC_OVERRIDE {
85 1 : EchoResponse response;
86 1 : response_stream_count_++;
87 6 : for (int i = 0;; i++) {
88 6 : std::ostringstream msg;
89 6 : msg << "Hello " << i;
90 6 : response.set_message(msg.str());
91 6 : if (!writer->Write(response)) break;
92 : gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
93 5 : gpr_time_from_seconds(1, GPR_TIMESPAN)));
94 10 : }
95 1 : return Status::OK;
96 : }
97 :
98 1 : int bidi_stream_count() { return bidi_stream_count_; }
99 :
100 1 : int response_stream_count() { return response_stream_count_; }
101 :
102 : private:
103 : int bidi_stream_count_;
104 : int response_stream_count_;
105 : };
106 :
107 2 : class CrashTest : public ::testing::Test {
108 : protected:
109 2 : CrashTest() {}
110 :
111 2 : std::unique_ptr<Server> CreateServerAndClient(const std::string& mode) {
112 2 : auto port = grpc_pick_unused_port_or_die();
113 2 : std::ostringstream addr_stream;
114 2 : addr_stream << "localhost:" << port;
115 4 : auto addr = addr_stream.str();
116 : client_.reset(new SubProcess({g_root + "/server_crash_test_client",
117 2 : "--address=" + addr, "--mode=" + mode}));
118 2 : GPR_ASSERT(client_);
119 :
120 4 : ServerBuilder builder;
121 2 : builder.AddListeningPort(addr, grpc::InsecureServerCredentials());
122 2 : builder.RegisterService(&service_);
123 4 : return builder.BuildAndStart();
124 : }
125 :
126 2 : void KillClient() { client_.reset(); }
127 :
128 1 : bool HadOneBidiStream() { return service_.bidi_stream_count() == 1; }
129 :
130 1 : bool HadOneResponseStream() { return service_.response_stream_count() == 1; }
131 :
132 : private:
133 : std::unique_ptr<SubProcess> client_;
134 : ServiceImpl service_;
135 : };
136 :
137 5 : TEST_F(CrashTest, ResponseStream) {
138 1 : auto server = CreateServerAndClient("response");
139 :
140 : gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
141 1 : gpr_time_from_seconds(5, GPR_TIMESPAN)));
142 1 : KillClient();
143 1 : server->Shutdown();
144 1 : GPR_ASSERT(HadOneResponseStream());
145 1 : }
146 :
147 5 : TEST_F(CrashTest, BidiStream) {
148 1 : auto server = CreateServerAndClient("bidi");
149 :
150 : gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
151 1 : gpr_time_from_seconds(5, GPR_TIMESPAN)));
152 1 : KillClient();
153 1 : server->Shutdown();
154 1 : GPR_ASSERT(HadOneBidiStream());
155 1 : }
156 :
157 : } // namespace
158 :
159 : } // namespace testing
160 : } // namespace grpc
161 :
162 1 : int main(int argc, char** argv) {
163 1 : std::string me = argv[0];
164 1 : auto lslash = me.rfind('/');
165 1 : if (lslash != std::string::npos) {
166 1 : g_root = me.substr(0, lslash);
167 : } else {
168 0 : g_root = ".";
169 : }
170 :
171 1 : grpc_test_init(argc, argv);
172 1 : ::testing::InitGoogleTest(&argc, argv);
173 1 : return RUN_ALL_TESTS();
174 3 : }
|