1 /* 2 * 3 * Copyright 2015 gRPC authors. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19 #include <grpc/grpc.h> 20 #include <grpc/support/log.h> 21 #include <grpc/support/time.h> 22 #include <grpcpp/channel.h> 23 #include <grpcpp/client_context.h> 24 #include <grpcpp/create_channel.h> 25 #include <grpcpp/server.h> 26 #include <grpcpp/server_builder.h> 27 #include <grpcpp/server_context.h> 28 29 #include "src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h" 30 #include "src/proto/grpc/testing/echo.grpc.pb.h" 31 #include "test/core/util/port.h" 32 #include "test/core/util/test_config.h" 33 #include "test/cpp/util/subprocess.h" 34 35 #include <gtest/gtest.h> 36 37 using grpc::testing::EchoRequest; 38 using grpc::testing::EchoResponse; 39 using std::chrono::system_clock; 40 41 static std::string g_root; 42 43 namespace grpc { 44 namespace testing { 45 46 namespace { 47 48 class CrashTest : public ::testing::Test { 49 protected: 50 CrashTest() {} 51 52 std::unique_ptr<grpc::testing::EchoTestService::Stub> CreateServerAndStub() { 53 auto port = grpc_pick_unused_port_or_die(); 54 std::ostringstream addr_stream; 55 addr_stream << "localhost:" << port; 56 auto addr = addr_stream.str(); 57 server_.reset(new SubProcess({ 58 g_root + "/client_crash_test_server", 59 "--address=" + addr, 60 })); 61 GPR_ASSERT(server_); 62 return grpc::testing::EchoTestService::NewStub( 63 CreateChannel(addr, InsecureChannelCredentials())); 64 } 65 66 void KillServer() { server_.reset(); } 67 68 private: 69 std::unique_ptr<SubProcess> server_; 70 }; 71 72 TEST_F(CrashTest, KillBeforeWrite) { 73 auto stub = CreateServerAndStub(); 74 75 EchoRequest request; 76 EchoResponse response; 77 ClientContext context; 78 context.set_wait_for_ready(true); 79 80 auto stream = stub->BidiStream(&context); 81 82 request.set_message("Hello"); 83 EXPECT_TRUE(stream->Write(request)); 84 EXPECT_TRUE(stream->Read(&response)); 85 EXPECT_EQ(response.message(), request.message()); 86 87 KillServer(); 88 89 request.set_message("You should be dead"); 90 // This may succeed or fail depending on the state of the TCP connection 91 stream->Write(request); 92 // But the read will definitely fail 93 EXPECT_FALSE(stream->Read(&response)); 94 95 EXPECT_FALSE(stream->Finish().ok()); 96 } 97 98 TEST_F(CrashTest, KillAfterWrite) { 99 auto stub = CreateServerAndStub(); 100 101 EchoRequest request; 102 EchoResponse response; 103 ClientContext context; 104 context.set_wait_for_ready(true); 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 // This may succeed or fail depending on how quick the server was 119 stream->Read(&response); 120 121 EXPECT_FALSE(stream->Finish().ok()); 122 } 123 124 } // namespace 125 126 } // namespace testing 127 } // namespace grpc 128 129 int main(int argc, char** argv) { 130 std::string me = argv[0]; 131 auto lslash = me.rfind('/'); 132 if (lslash != std::string::npos) { 133 g_root = me.substr(0, lslash); 134 } else { 135 g_root = "."; 136 } 137 138 grpc_test_init(argc, argv); 139 ::testing::InitGoogleTest(&argc, argv); 140 // Order seems to matter on these tests: run three times to eliminate that 141 for (int i = 0; i < 3; i++) { 142 if (RUN_ALL_TESTS() != 0) { 143 return 1; 144 } 145 } 146 return 0; 147 } 148