| 125 | } |
| 126 | |
| 127 | void DoTestServerDisconnects(bool accept, const std::string &message) { |
| 128 | NO_FATALS(BindAndListen("0.0.0.0:0")); |
| 129 | |
| 130 | CountDownLatch latch(1); |
| 131 | scoped_refptr<kudu::Thread> t; |
| 132 | Status status = kudu::Thread::Create("pool", "worker", ([&]{ |
| 133 | if (accept) { |
| 134 | Sockaddr new_addr; |
| 135 | Socket sock; |
| 136 | CHECK_OK(listener_.Accept(&sock, &new_addr, 0)); |
| 137 | CHECK_OK(sock.Close()); |
| 138 | } else { |
| 139 | while (!latch.WaitFor(MonoDelta::FromMilliseconds(10))) {} |
| 140 | CHECK_OK(listener_.Close()); |
| 141 | } |
| 142 | }), &t); |
| 143 | ASSERT_OK(status); |
| 144 | SCOPED_CLEANUP({ |
| 145 | latch.CountDown(); |
| 146 | if (t) { |
| 147 | t->Join(); |
| 148 | } |
| 149 | }); |
| 150 | |
| 151 | Socket client = ConnectToListeningServer(); |
| 152 | int n; |
| 153 | std::unique_ptr<uint8_t[]> buf(new uint8_t[kEchoChunkSize]); |
| 154 | const auto s = client.Recv(buf.get(), kEchoChunkSize, &n); |
| 155 | |
| 156 | ASSERT_TRUE(s.IsNetworkError()) << s.ToString(); |
| 157 | ASSERT_STR_MATCHES(s.message().ToString(), message); |
| 158 | } |
| 159 | |
| 160 | void DoUnixSocketTest(const string& path) { |
| 161 | const string kData = "hello world over a socket"; |