blob: 10f4944b5476d36440724bede3c8ecdfc9b35a2f [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();
79 auto addr = (std::ostringstream() << "localhost:" << port).str();
80 server_.reset(new SubProcess({
Craig Tiller3cdd9bb2015-05-15 14:43:47 -070081 (std::ostringstream() << g_root << "/crash_test_server").str(),
82 (std::ostringstream() << "--address=" << addr).str(),
Craig Tillerfbac5f12015-05-15 14:20:44 -070083 }));
84 GPR_ASSERT(server_);
Craig Tiller3cdd9bb2015-05-15 14:43:47 -070085 return grpc::cpp::test::util::TestService::NewStub(
86 CreateChannel(addr, InsecureCredentials(), ChannelArguments()));
Craig Tillerfbac5f12015-05-15 14:20:44 -070087 }
88
89 void KillServer() {
90 server_.reset();
Craig Tiller069daa32015-05-15 14:40:53 -070091 // give some time for the TCP connection to drop
92 gpr_sleep_until(gpr_time_add(gpr_now(), gpr_time_from_seconds(1)));
Craig Tillerfbac5f12015-05-15 14:20:44 -070093 }
94
95 private:
96 std::unique_ptr<SubProcess> server_;
97};
98
99TEST_F(CrashTest, KillAfterWrite) {
100 auto stub = CreateServerAndStub();
101
102 EchoRequest request;
103 EchoResponse response;
104 ClientContext context;
105
106 auto stream = stub->BidiStream(&context);
107
108 request.set_message("Hello");
109 EXPECT_TRUE(stream->Write(request));
110 EXPECT_TRUE(stream->Read(&response));
111 EXPECT_EQ(response.message(), request.message());
112
113 request.set_message("I'm going to kill you");
114 EXPECT_TRUE(stream->Write(request));
115
116 KillServer();
117
118 EXPECT_FALSE(stream->Read(&response));
119
120 EXPECT_FALSE(stream->Finish().IsOk());
121}
122
123TEST_F(CrashTest, KillBeforeWrite) {
124 auto stub = CreateServerAndStub();
125
126 EchoRequest request;
127 EchoResponse response;
128 ClientContext context;
129
130 auto stream = stub->BidiStream(&context);
131
132 request.set_message("Hello");
133 EXPECT_TRUE(stream->Write(request));
134 EXPECT_TRUE(stream->Read(&response));
135 EXPECT_EQ(response.message(), request.message());
136
137 KillServer();
138
139 request.set_message("You should be dead");
140 EXPECT_FALSE(stream->Write(request));
141 EXPECT_FALSE(stream->Read(&response));
142
143 EXPECT_FALSE(stream->Finish().IsOk());
144}
145
146} // namespace
147
148} // namespace testing
149} // namespace grpc
150
151int main(int argc, char** argv) {
152 std::string me = argv[0];
153 auto lslash = me.rfind('/');
154 if (lslash != std::string::npos) {
155 g_root = me.substr(0, lslash);
156 } else {
157 g_root = ".";
158 }
159
160 grpc_test_init(argc, argv);
161 ::testing::InitGoogleTest(&argc, argv);
162 return RUN_ALL_TESTS();
163}