blob: 628b3e254381af76bf68dc387fa6a0d93dd51b16 [file] [log] [blame]
Craig Tillerfbac5f12015-05-15 14:20:44 -07001/*
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 "test/core/util/port.h"
37#include "test/core/util/test_config.h"
38#include "test/cpp/util/echo_duplicate.grpc.pb.h"
39#include "test/cpp/util/echo.grpc.pb.h"
40#include "src/cpp/server/thread_pool.h"
41#include <grpc++/channel_arguments.h>
42#include <grpc++/channel_interface.h>
43#include <grpc++/client_context.h>
44#include <grpc++/create_channel.h>
45#include <grpc++/credentials.h>
46#include <grpc++/server.h>
47#include <grpc++/server_builder.h>
48#include <grpc++/server_context.h>
49#include <grpc++/server_credentials.h>
50#include <grpc++/status.h>
51#include <grpc++/stream.h>
52#include <grpc++/time.h>
53#include <gtest/gtest.h>
54
55#include <grpc/grpc.h>
56#include <grpc/support/thd.h>
57#include <grpc/support/time.h>
58
59#include "test/cpp/util/subprocess.h"
60
61using grpc::cpp::test::util::EchoRequest;
62using grpc::cpp::test::util::EchoResponse;
63using std::chrono::system_clock;
64
65static std::string g_root;
66
67namespace grpc {
68namespace testing {
69
70namespace {
71
72class CrashTest : public ::testing::Test {
73 protected:
74 CrashTest() {}
75
Craig Tiller3cdd9bb2015-05-15 14:43:47 -070076 std::unique_ptr<grpc::cpp::test::util::TestService::Stub>
77 CreateServerAndStub() {
Craig Tillerfbac5f12015-05-15 14:20:44 -070078 auto port = grpc_pick_unused_port_or_die();
Craig Tillera969d7c2015-05-15 15:47:51 -070079 std::ostringstream addr_stream;
80 addr_stream << "localhost:" << port;
81 auto addr = addr_stream.str();
Craig Tillerfbac5f12015-05-15 14:20:44 -070082 server_.reset(new SubProcess({
Craig Tillera969d7c2015-05-15 15:47:51 -070083 g_root + "/crash_test_server",
84 "--address=" + addr,
Craig Tillerfbac5f12015-05-15 14:20:44 -070085 }));
86 GPR_ASSERT(server_);
Craig Tiller3cdd9bb2015-05-15 14:43:47 -070087 return grpc::cpp::test::util::TestService::NewStub(
88 CreateChannel(addr, InsecureCredentials(), ChannelArguments()));
Craig Tillerfbac5f12015-05-15 14:20:44 -070089 }
90
91 void KillServer() {
92 server_.reset();
Craig Tiller069daa32015-05-15 14:40:53 -070093 // give some time for the TCP connection to drop
94 gpr_sleep_until(gpr_time_add(gpr_now(), gpr_time_from_seconds(1)));
Craig Tillerfbac5f12015-05-15 14:20:44 -070095 }
96
97 private:
98 std::unique_ptr<SubProcess> server_;
99};
100
101TEST_F(CrashTest, KillAfterWrite) {
102 auto stub = CreateServerAndStub();
103
104 EchoRequest request;
105 EchoResponse response;
106 ClientContext context;
107
108 auto stream = stub->BidiStream(&context);
109
110 request.set_message("Hello");
111 EXPECT_TRUE(stream->Write(request));
112 EXPECT_TRUE(stream->Read(&response));
113 EXPECT_EQ(response.message(), request.message());
114
115 request.set_message("I'm going to kill you");
116 EXPECT_TRUE(stream->Write(request));
117
118 KillServer();
119
120 EXPECT_FALSE(stream->Read(&response));
121
122 EXPECT_FALSE(stream->Finish().IsOk());
123}
124
125TEST_F(CrashTest, KillBeforeWrite) {
126 auto stub = CreateServerAndStub();
127
128 EchoRequest request;
129 EchoResponse response;
130 ClientContext context;
131
132 auto stream = stub->BidiStream(&context);
133
134 request.set_message("Hello");
135 EXPECT_TRUE(stream->Write(request));
136 EXPECT_TRUE(stream->Read(&response));
137 EXPECT_EQ(response.message(), request.message());
138
139 KillServer();
140
141 request.set_message("You should be dead");
142 EXPECT_FALSE(stream->Write(request));
143 EXPECT_FALSE(stream->Read(&response));
144
145 EXPECT_FALSE(stream->Finish().IsOk());
146}
147
148} // namespace
149
150} // namespace testing
151} // namespace grpc
152
153int main(int argc, char** argv) {
154 std::string me = argv[0];
155 auto lslash = me.rfind('/');
156 if (lslash != std::string::npos) {
157 g_root = me.substr(0, lslash);
158 } else {
159 g_root = ".";
160 }
161
162 grpc_test_init(argc, argv);
163 ::testing::InitGoogleTest(&argc, argv);
164 return RUN_ALL_TESTS();
165}