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_duplicate.grpc.pb.h"
48 : #include "test/cpp/util/echo.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 6 : class CrashTest : public ::testing::Test {
63 : protected:
64 6 : CrashTest() {}
65 :
66 : std::unique_ptr<grpc::cpp::test::util::TestService::Stub>
67 6 : CreateServerAndStub() {
68 6 : auto port = grpc_pick_unused_port_or_die();
69 6 : std::ostringstream addr_stream;
70 6 : addr_stream << "localhost:" << port;
71 12 : auto addr = addr_stream.str();
72 : server_.reset(new SubProcess({
73 : g_root + "/client_crash_test_server", "--address=" + addr,
74 6 : }));
75 6 : GPR_ASSERT(server_);
76 : return grpc::cpp::test::util::TestService::NewStub(
77 12 : CreateChannel(addr, InsecureCredentials()));
78 : }
79 :
80 6 : void KillServer() { server_.reset(); }
81 :
82 : private:
83 : std::unique_ptr<SubProcess> server_;
84 : };
85 :
86 13 : TEST_F(CrashTest, KillBeforeWrite) {
87 3 : auto stub = CreateServerAndStub();
88 :
89 6 : EchoRequest request;
90 6 : EchoResponse response;
91 6 : ClientContext context;
92 :
93 6 : auto stream = stub->BidiStream(&context);
94 :
95 3 : request.set_message("Hello");
96 3 : EXPECT_TRUE(stream->Write(request));
97 3 : EXPECT_TRUE(stream->Read(&response));
98 3 : EXPECT_EQ(response.message(), request.message());
99 :
100 3 : KillServer();
101 :
102 3 : request.set_message("You should be dead");
103 : // This may succeed or fail depending on the state of the TCP connection
104 3 : stream->Write(request);
105 : // But the read will definitely fail
106 3 : EXPECT_FALSE(stream->Read(&response));
107 :
108 6 : EXPECT_FALSE(stream->Finish().ok());
109 3 : }
110 :
111 13 : TEST_F(CrashTest, KillAfterWrite) {
112 3 : auto stub = CreateServerAndStub();
113 :
114 6 : EchoRequest request;
115 6 : EchoResponse response;
116 6 : ClientContext context;
117 :
118 6 : auto stream = stub->BidiStream(&context);
119 :
120 3 : request.set_message("Hello");
121 3 : EXPECT_TRUE(stream->Write(request));
122 3 : EXPECT_TRUE(stream->Read(&response));
123 3 : EXPECT_EQ(response.message(), request.message());
124 :
125 3 : request.set_message("I'm going to kill you");
126 3 : EXPECT_TRUE(stream->Write(request));
127 :
128 3 : KillServer();
129 :
130 : // This may succeed or fail depending on how quick the server was
131 3 : stream->Read(&response);
132 :
133 6 : EXPECT_FALSE(stream->Finish().ok());
134 3 : }
135 :
136 : } // namespace
137 :
138 : } // namespace testing
139 : } // namespace grpc
140 :
141 1 : int main(int argc, char** argv) {
142 1 : std::string me = argv[0];
143 1 : auto lslash = me.rfind('/');
144 1 : if (lslash != std::string::npos) {
145 1 : g_root = me.substr(0, lslash);
146 : } else {
147 0 : g_root = ".";
148 : }
149 :
150 1 : grpc_test_init(argc, argv);
151 1 : ::testing::InitGoogleTest(&argc, argv);
152 : // Order seems to matter on these tests: run three times to eliminate that
153 4 : for (int i = 0; i < 3; i++) {
154 3 : if (RUN_ALL_TESTS() != 0) {
155 0 : return 1;
156 : }
157 : }
158 1 : return 0;
159 3 : }
|