Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Crashpad Authors. All rights reserved. | 1 // Copyright 2014 The Crashpad Authors. All rights reserved. |
| 2 // | 2 // |
| 3 // Licensed under the Apache License, Version 2.0 (the "License"); | 3 // Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 // you may not use this file except in compliance with the License. | 4 // you may not use this file except in compliance with the License. |
| 5 // You may obtain a copy of the License at | 5 // You may obtain a copy of the License at |
| 6 // | 6 // |
| 7 // http://www.apache.org/licenses/LICENSE-2.0 | 7 // http://www.apache.org/licenses/LICENSE-2.0 |
| 8 // | 8 // |
| 9 // Unless required by applicable law or agreed to in writing, software | 9 // Unless required by applicable law or agreed to in writing, software |
| 10 // distributed under the License is distributed on an "AS IS" BASIS, | 10 // distributed under the License is distributed on an "AS IS" BASIS, |
| 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 // See the License for the specific language governing permissions and | 12 // See the License for the specific language governing permissions and |
| 13 // limitations under the License. | 13 // limitations under the License. |
| 14 | 14 |
| 15 #include "util/mach/child_port_handshake.h" | 15 #include "util/mach/child_port_handshake.h" |
| 16 | 16 |
| 17 #include "base/mac/scoped_mach_port.h" | 17 #include "base/mac/scoped_mach_port.h" |
| 18 #include "gtest/gtest.h" | 18 #include "gtest/gtest.h" |
| 19 #include "test/multiprocess.h" | 19 #include "test/multiprocess.h" |
| 20 #include "util/mach/child_port_types.h" | 20 #include "util/mach/child_port_types.h" |
| 21 #include "util/mach/mach_extensions.h" | 21 #include "util/mach/mach_extensions.h" |
| 22 | 22 |
| 23 namespace crashpad { | 23 namespace crashpad { |
| 24 namespace test { | 24 namespace test { |
| 25 namespace { | 25 namespace { |
| 26 | 26 |
| 27 class ChildPortHandshakeTest : public Multiprocess { | 27 class ChildPortHandshakeTest : public Multiprocess { |
| 28 public: | 28 public: |
| 29 enum TestType { | 29 enum class ClientProcess { |
| 30 kTestTypeChildChecksIn = 0, | 30 // The child runs the client and the parent runs the server. |
| 31 kTestTypeChildDoesNotCheckIn_ReadsPipe, | 31 kChildClient = 0, |
| 32 kTestTypeChildDoesNotCheckIn, | 32 |
| 33 kTestTypeTokenIncorrect, | 33 // The parent runs the client and the child runs the server. |
| 34 kTestTypeTokenIncorrectThenCorrect, | 34 kParentClient, |
| 35 }; | 35 }; |
| 36 | 36 |
| 37 explicit ChildPortHandshakeTest(TestType test_type) | 37 enum class TestType { |
| 38 : Multiprocess(), child_port_handshake_(), test_type_(test_type) {} | 38 // The client checks in with the server, transferring a receive right. |
| 39 ~ChildPortHandshakeTest() {} | 39 kClientChecksIn_ReceiveRight = 0, |
| 40 | |
| 41 // In this test, the client checks in with the server normally. It sends a | |
| 42 // copy of its bootstrap port to the server, because both parent and child | |
| 43 // should have the same bootstrap port, allowing for verification. | |
| 44 kClientChecksIn_SendRight, | |
| 45 | |
| 46 // The client checks in with the server, transferring a send-once right. | |
| 47 kClientChecksIn_SendOnceRight, | |
| 48 | |
| 49 // In this test, the client reads from its pipe, and subsequently exits | |
| 50 // without checking in. This tests that the server properly detects that it | |
| 51 // has lost its client after sending instructions to it via the pipe, while | |
| 52 // waiting for a check-in message. | |
| 53 kClientDoesNotCheckIn, | |
|
Robert Sesek
2015/10/28 21:40:03
Worth having a test for if the server dies and the
| |
| 54 | |
| 55 // In this test, the client exits without checking in. This tests that the | |
| 56 // server properly detects that it has lost a client. Whether or not the | |
| 57 // client closes the pipe before the server writes to it is a race, and the | |
| 58 // server needs to be able to detect client loss in both cases, so the | |
| 59 // ClientDoesNotCheckIn_ReadsPipe and NoClient tests also exist to test | |
| 60 // these individual cases more deterministically. | |
| 61 kClientDoesNotCheckIn_ReadsPipe, | |
| 62 | |
| 63 // In this test, the client checks in with the server with an incorrect | |
| 64 // token value and a copy of its own task port. The server should reject the | |
| 65 // message because of the invalid token, and return MACH_PORT_NULL to its | |
| 66 // caller. | |
| 67 kTokenIncorrect, | |
| 68 | |
| 69 // In this test, the client checks in with the server with an incorrect | |
| 70 // token value and a copy of its own task port, and subsequently, the | |
| 71 // correct token value and a copy of its bootstrap port. The server should | |
| 72 // reject the first because of the invalid token, but it should continue | |
| 73 // waiting for a message with a valid token as long as the pipe remains | |
| 74 // open. It should wind wind up returning the bootstrap port, allowing for | |
| 75 // verification. | |
| 76 kTokenIncorrectThenCorrect, | |
| 77 }; | |
| 78 | |
| 79 ChildPortHandshakeTest(ClientProcess client_process, TestType test_type) | |
| 80 : Multiprocess(), | |
| 81 child_port_handshake_(), | |
| 82 client_process_(client_process), | |
| 83 test_type_(test_type) { | |
| 84 } | |
| 85 | |
| 86 ~ChildPortHandshakeTest() { | |
| 87 } | |
| 40 | 88 |
| 41 private: | 89 private: |
| 42 // Multiprocess: | 90 void RunServer() { |
| 43 | 91 base::mac::ScopedMachReceiveRight receive_right; |
| 44 void MultiprocessParent() override { | 92 base::mac::ScopedMachSendRight send_right; |
| 45 base::mac::ScopedMachSendRight child_port( | 93 if (test_type_ == TestType::kClientChecksIn_ReceiveRight) { |
| 46 child_port_handshake_.RunServer()); | 94 receive_right.reset(child_port_handshake_.RunServer( |
| 95 ChildPortHandshake::PortRightType::kReceiveRight)); | |
| 96 } else { | |
| 97 send_right.reset(child_port_handshake_.RunServer( | |
| 98 ChildPortHandshake::PortRightType::kSendRight)); | |
| 99 } | |
| 100 | |
| 47 switch (test_type_) { | 101 switch (test_type_) { |
| 48 case kTestTypeChildChecksIn: | 102 case TestType::kClientChecksIn_ReceiveRight: |
| 49 case kTestTypeTokenIncorrectThenCorrect: | 103 EXPECT_TRUE(receive_right.is_valid()); |
| 50 EXPECT_EQ(bootstrap_port, child_port); | 104 break; |
| 51 break; | 105 |
| 52 | 106 case TestType::kClientChecksIn_SendRight: |
| 53 case kTestTypeChildDoesNotCheckIn_ReadsPipe: | 107 case TestType::kTokenIncorrectThenCorrect: |
| 54 case kTestTypeChildDoesNotCheckIn: | 108 EXPECT_EQ(bootstrap_port, send_right); |
| 55 case kTestTypeTokenIncorrect: | 109 break; |
| 56 EXPECT_EQ(kMachPortNull, child_port); | 110 |
| 57 break; | 111 case TestType::kClientChecksIn_SendOnceRight: |
| 58 } | 112 EXPECT_TRUE(send_right.is_valid()); |
| 59 } | 113 EXPECT_NE(bootstrap_port, send_right); |
| 60 | 114 break; |
| 61 void MultiprocessChild() override { | 115 |
| 62 int read_pipe = child_port_handshake_.ReadPipeFD(); | 116 case TestType::kClientDoesNotCheckIn: |
| 117 case TestType::kClientDoesNotCheckIn_ReadsPipe: | |
| 118 case TestType::kTokenIncorrect: | |
| 119 EXPECT_FALSE(send_right.is_valid()); | |
| 120 break; | |
| 121 } | |
| 122 } | |
| 123 | |
| 124 void RunClient() { | |
| 63 switch (test_type_) { | 125 switch (test_type_) { |
| 64 case kTestTypeChildChecksIn: | 126 case TestType::kClientChecksIn_SendRight: { |
| 65 ChildPortHandshake::RunClient( | 127 ASSERT_TRUE(child_port_handshake_.RunClient(bootstrap_port, |
| 66 read_pipe, bootstrap_port, MACH_MSG_TYPE_COPY_SEND); | 128 MACH_MSG_TYPE_COPY_SEND)); |
| 67 break; | 129 break; |
| 68 | 130 } |
| 69 case kTestTypeChildDoesNotCheckIn_ReadsPipe: { | 131 |
| 132 case TestType::kClientChecksIn_ReceiveRight: { | |
| 133 mach_port_t receive_right = NewMachPort(MACH_PORT_RIGHT_RECEIVE); | |
| 134 ASSERT_TRUE(child_port_handshake_.RunClient( | |
| 135 receive_right, MACH_MSG_TYPE_MOVE_RECEIVE)); | |
| 136 break; | |
| 137 } | |
| 138 | |
| 139 case TestType::kClientChecksIn_SendOnceRight: { | |
| 140 base::mac::ScopedMachReceiveRight receive_right( | |
| 141 NewMachPort(MACH_PORT_RIGHT_RECEIVE)); | |
| 142 ASSERT_TRUE(child_port_handshake_.RunClient( | |
| 143 receive_right.get(), MACH_MSG_TYPE_MAKE_SEND_ONCE)); | |
| 144 break; | |
| 145 } | |
| 146 | |
| 147 case TestType::kClientDoesNotCheckIn: { | |
| 148 child_port_handshake_.ServerWriteFD().reset(); | |
| 149 child_port_handshake_.ClientReadFD().reset(); | |
| 150 break; | |
| 151 } | |
| 152 | |
| 153 case TestType::kClientDoesNotCheckIn_ReadsPipe: { | |
| 70 // Don’t run the standard client routine. Instead, drain the pipe, which | 154 // Don’t run the standard client routine. Instead, drain the pipe, which |
| 71 // will get the parent to the point that it begins waiting for a | 155 // will get the parent to the point that it begins waiting for a |
| 72 // check-in message. Then, exit. The pipe is drained using the same | 156 // check-in message. Then, exit. The pipe is drained using the same |
| 73 // implementation that the real client would use. | 157 // implementation that the real client would use. |
| 158 child_port_handshake_.ServerWriteFD().reset(); | |
| 159 base::ScopedFD client_read_fd = child_port_handshake_.ClientReadFD(); | |
| 74 child_port_token_t token; | 160 child_port_token_t token; |
| 75 std::string service_name; | 161 std::string service_name; |
| 76 ChildPortHandshake::RunClientInternal_ReadPipe( | 162 ASSERT_TRUE(ChildPortHandshake::RunClientInternal_ReadPipe( |
| 77 read_pipe, &token, &service_name); | 163 client_read_fd.get(), &token, &service_name)); |
| 78 break; | 164 break; |
| 79 } | 165 } |
| 80 | 166 |
| 81 case kTestTypeChildDoesNotCheckIn: | 167 case TestType::kTokenIncorrect: { |
| 82 break; | |
| 83 | |
| 84 case kTestTypeTokenIncorrect: { | |
| 85 // Don’t run the standard client routine. Instead, read the token and | 168 // Don’t run the standard client routine. Instead, read the token and |
| 86 // service name, mutate the token, and then check in with the bad token. | 169 // service name, mutate the token, and then check in with the bad token. |
| 87 // The parent should reject the message. | 170 // The parent should reject the message. |
| 171 child_port_handshake_.ServerWriteFD().reset(); | |
| 172 base::ScopedFD client_read_fd = child_port_handshake_.ClientReadFD(); | |
| 88 child_port_token_t token; | 173 child_port_token_t token; |
| 89 std::string service_name; | 174 std::string service_name; |
| 90 ChildPortHandshake::RunClientInternal_ReadPipe( | 175 ASSERT_TRUE(ChildPortHandshake::RunClientInternal_ReadPipe( |
| 91 read_pipe, &token, &service_name); | 176 client_read_fd.get(), &token, &service_name)); |
| 92 child_port_token_t bad_token = ~token; | 177 child_port_token_t bad_token = ~token; |
| 93 ChildPortHandshake::RunClientInternal_SendCheckIn( | 178 ASSERT_TRUE(ChildPortHandshake::RunClientInternal_SendCheckIn( |
| 94 service_name, bad_token, mach_task_self(), MACH_MSG_TYPE_COPY_SEND); | 179 service_name, |
| 95 break; | 180 bad_token, |
| 96 } | 181 mach_task_self(), |
| 97 | 182 MACH_MSG_TYPE_COPY_SEND)); |
| 98 case kTestTypeTokenIncorrectThenCorrect: { | 183 break; |
| 184 } | |
| 185 | |
| 186 case TestType::kTokenIncorrectThenCorrect: { | |
| 99 // Don’t run the standard client routine. Instead, read the token and | 187 // Don’t run the standard client routine. Instead, read the token and |
| 100 // service name. Mutate the token, and check in with the bad token, | 188 // service name. Mutate the token, and check in with the bad token, |
| 101 // expecting the parent to reject the message. Then, check in with the | 189 // expecting the parent to reject the message. Then, check in with the |
| 102 // correct token, expecting the parent to accept it. | 190 // correct token, expecting the parent to accept it. |
| 191 child_port_handshake_.ServerWriteFD().reset(); | |
| 192 base::ScopedFD client_read_fd = child_port_handshake_.ClientReadFD(); | |
| 103 child_port_token_t token; | 193 child_port_token_t token; |
| 104 std::string service_name; | 194 std::string service_name; |
| 105 ChildPortHandshake::RunClientInternal_ReadPipe( | 195 ASSERT_TRUE(ChildPortHandshake::RunClientInternal_ReadPipe( |
| 106 read_pipe, &token, &service_name); | 196 client_read_fd.release(), &token, &service_name)); |
| 107 child_port_token_t bad_token = ~token; | 197 child_port_token_t bad_token = ~token; |
| 108 ChildPortHandshake::RunClientInternal_SendCheckIn( | 198 ASSERT_TRUE(ChildPortHandshake::RunClientInternal_SendCheckIn( |
| 109 service_name, bad_token, mach_task_self(), MACH_MSG_TYPE_COPY_SEND); | 199 service_name, |
| 110 ChildPortHandshake::RunClientInternal_SendCheckIn( | 200 bad_token, |
| 111 service_name, token, bootstrap_port, MACH_MSG_TYPE_COPY_SEND); | 201 mach_task_self(), |
| 112 break; | 202 MACH_MSG_TYPE_COPY_SEND)); |
| 113 } | 203 ASSERT_TRUE(ChildPortHandshake::RunClientInternal_SendCheckIn( |
| 204 service_name, token, bootstrap_port, MACH_MSG_TYPE_COPY_SEND)); | |
| 205 break; | |
| 206 } | |
| 207 } | |
| 208 } | |
| 209 | |
| 210 // Multiprocess: | |
| 211 | |
| 212 void MultiprocessParent() override { | |
| 213 switch (client_process_) { | |
| 214 case ClientProcess::kChildClient: | |
| 215 RunServer(); | |
| 216 break; | |
| 217 case ClientProcess::kParentClient: | |
| 218 RunClient(); | |
| 219 break; | |
| 220 } | |
| 221 } | |
| 222 | |
| 223 void MultiprocessChild() override { | |
| 224 switch (client_process_) { | |
| 225 case ClientProcess::kChildClient: | |
| 226 RunClient(); | |
| 227 break; | |
| 228 case ClientProcess::kParentClient: | |
| 229 RunServer(); | |
| 230 break; | |
| 114 } | 231 } |
| 115 } | 232 } |
| 116 | 233 |
| 117 private: | 234 private: |
| 118 ChildPortHandshake child_port_handshake_; | 235 ChildPortHandshake child_port_handshake_; |
| 236 ClientProcess client_process_; | |
| 119 TestType test_type_; | 237 TestType test_type_; |
| 120 | 238 |
| 121 DISALLOW_COPY_AND_ASSIGN(ChildPortHandshakeTest); | 239 DISALLOW_COPY_AND_ASSIGN(ChildPortHandshakeTest); |
| 122 }; | 240 }; |
| 123 | 241 |
| 124 TEST(ChildPortHandshake, ChildChecksIn) { | 242 TEST(ChildPortHandshake, ChildClientChecksIn_ReceiveRight) { |
| 125 // In this test, the client checks in with the server normally. It sends a | 243 ChildPortHandshakeTest test( |
| 126 // copy of its bootstrap port to the server, because both parent and child | 244 ChildPortHandshakeTest::ClientProcess::kChildClient, |
| 127 // should have the same bootstrap port, allowing for verification. | 245 ChildPortHandshakeTest::TestType::kClientChecksIn_ReceiveRight); |
| 128 ChildPortHandshakeTest test(ChildPortHandshakeTest::kTestTypeChildChecksIn); | 246 test.Run(); |
| 129 test.Run(); | 247 } |
| 130 } | 248 |
| 131 | 249 TEST(ChildPortHandshake, ChildClientChecksIn_SendRight) { |
| 132 TEST(ChildPortHandshake, ChildDoesNotCheckIn) { | 250 ChildPortHandshakeTest test( |
| 133 // In this test, the client exits without checking in. This tests that the | 251 ChildPortHandshakeTest::ClientProcess::kChildClient, |
| 134 // server properly detects that it has lost a client. Whether or not the | 252 ChildPortHandshakeTest::TestType::kClientChecksIn_SendRight); |
| 135 // client closes the pipe before the server writes to it is a race, and the | 253 test.Run(); |
| 136 // server needs to be able to detect client loss in both cases, so the | 254 } |
| 137 // ChildDoesNotCheckIn_ReadsPipe and NoChild tests also exist to test these | 255 |
| 138 // individual cases more deterministically. | 256 TEST(ChildPortHandshake, ChildClientChecksIn_SendOnceRight) { |
| 139 ChildPortHandshakeTest test( | 257 ChildPortHandshakeTest test( |
| 140 ChildPortHandshakeTest::kTestTypeChildDoesNotCheckIn); | 258 ChildPortHandshakeTest::ClientProcess::kChildClient, |
| 141 test.Run(); | 259 ChildPortHandshakeTest::TestType::kClientChecksIn_SendOnceRight); |
| 142 } | 260 test.Run(); |
| 143 | 261 } |
| 144 TEST(ChildPortHandshake, ChildDoesNotCheckIn_ReadsPipe) { | 262 |
| 145 // In this test, the client reads from its pipe, and subsequently exits | 263 TEST(ChildPortHandshake, ChildClientDoesNotCheckIn) { |
| 146 // without checking in. This tests that the server properly detects that it | 264 ChildPortHandshakeTest test( |
| 147 // has lost its client after sending instructions to it via the pipe, while | 265 ChildPortHandshakeTest::ClientProcess::kChildClient, |
| 148 // waiting for a check-in message. | 266 ChildPortHandshakeTest::TestType::kClientDoesNotCheckIn); |
| 149 ChildPortHandshakeTest test( | 267 test.Run(); |
| 150 ChildPortHandshakeTest::kTestTypeChildDoesNotCheckIn_ReadsPipe); | 268 } |
| 151 test.Run(); | 269 |
| 152 } | 270 TEST(ChildPortHandshake, ChildClientDoesNotCheckIn_ReadsPipe) { |
| 153 | 271 ChildPortHandshakeTest test( |
| 154 TEST(ChildPortHandshake, TokenIncorrect) { | 272 ChildPortHandshakeTest::ClientProcess::kChildClient, |
| 155 // In this test, the client checks in with the server with an incorrect token | 273 ChildPortHandshakeTest::TestType::kClientDoesNotCheckIn_ReadsPipe); |
| 156 // value and a copy of its own task port. The server should reject the message | 274 test.Run(); |
| 157 // because of the invalid token, and return MACH_PORT_NULL to its caller. | 275 } |
| 158 ChildPortHandshakeTest test(ChildPortHandshakeTest::kTestTypeTokenIncorrect); | 276 |
| 159 test.Run(); | 277 TEST(ChildPortHandshake, ChildClientTokenIncorrect) { |
| 160 } | 278 ChildPortHandshakeTest test( |
| 161 | 279 ChildPortHandshakeTest::ClientProcess::kChildClient, |
| 162 TEST(ChildPortHandshake, TokenIncorrectThenCorrect) { | 280 ChildPortHandshakeTest::TestType::kTokenIncorrect); |
| 163 // In this test, the client checks in with the server with an incorrect token | 281 test.Run(); |
| 164 // value and a copy of its own task port, and subsequently, the correct token | 282 } |
| 165 // value and a copy of its bootstrap port. The server should reject the first | 283 |
| 166 // because of the invalid token, but it should continue waiting for a message | 284 TEST(ChildPortHandshake, ChildClientTokenIncorrectThenCorrect) { |
| 167 // with a valid token as long as the pipe remains open. It should wind wind up | 285 ChildPortHandshakeTest test( |
| 168 // returning the bootstrap port, allowing for verification. | 286 ChildPortHandshakeTest::ClientProcess::kChildClient, |
| 169 ChildPortHandshakeTest test( | 287 ChildPortHandshakeTest::TestType::kTokenIncorrectThenCorrect); |
| 170 ChildPortHandshakeTest::kTestTypeTokenIncorrectThenCorrect); | 288 test.Run(); |
| 171 test.Run(); | 289 } |
| 172 } | 290 |
| 173 | 291 TEST(ChildPortHandshake, ParentClientChecksIn_ReceiveRight) { |
| 174 TEST(ChildPortHandshake, NoChild) { | 292 ChildPortHandshakeTest test( |
| 175 // In this test, the client never checks in with the parent because the child | 293 ChildPortHandshakeTest::ClientProcess::kParentClient, |
| 176 // never even runs. This tests that the server properly detects that it has | 294 ChildPortHandshakeTest::TestType::kClientChecksIn_ReceiveRight); |
| 177 // no client at all, and does not terminate execution with an error such as | 295 test.Run(); |
| 296 } | |
| 297 | |
| 298 TEST(ChildPortHandshake, ParentClientChecksIn_SendRight) { | |
| 299 ChildPortHandshakeTest test( | |
| 300 ChildPortHandshakeTest::ClientProcess::kParentClient, | |
| 301 ChildPortHandshakeTest::TestType::kClientChecksIn_SendRight); | |
| 302 test.Run(); | |
| 303 } | |
| 304 | |
| 305 TEST(ChildPortHandshake, ParentClientChecksIn_SendOnceRight) { | |
| 306 ChildPortHandshakeTest test( | |
| 307 ChildPortHandshakeTest::ClientProcess::kParentClient, | |
| 308 ChildPortHandshakeTest::TestType::kClientChecksIn_SendOnceRight); | |
| 309 test.Run(); | |
| 310 } | |
| 311 | |
| 312 TEST(ChildPortHandshake, ParentClientDoesNotCheckIn) { | |
| 313 ChildPortHandshakeTest test( | |
| 314 ChildPortHandshakeTest::ClientProcess::kParentClient, | |
| 315 ChildPortHandshakeTest::TestType::kClientDoesNotCheckIn); | |
| 316 test.Run(); | |
| 317 } | |
| 318 | |
| 319 TEST(ChildPortHandshake, ParentClientDoesNotCheckIn_ReadsPipe) { | |
| 320 ChildPortHandshakeTest test( | |
| 321 ChildPortHandshakeTest::ClientProcess::kParentClient, | |
| 322 ChildPortHandshakeTest::TestType::kClientDoesNotCheckIn_ReadsPipe); | |
| 323 test.Run(); | |
| 324 } | |
| 325 | |
| 326 TEST(ChildPortHandshake, ParentClientTokenIncorrect) { | |
| 327 ChildPortHandshakeTest test( | |
| 328 ChildPortHandshakeTest::ClientProcess::kParentClient, | |
| 329 ChildPortHandshakeTest::TestType::kTokenIncorrect); | |
| 330 test.Run(); | |
| 331 } | |
| 332 | |
| 333 TEST(ChildPortHandshake, ParentClientTokenIncorrectThenCorrect) { | |
| 334 ChildPortHandshakeTest test( | |
| 335 ChildPortHandshakeTest::ClientProcess::kParentClient, | |
| 336 ChildPortHandshakeTest::TestType::kTokenIncorrectThenCorrect); | |
| 337 test.Run(); | |
| 338 } | |
| 339 | |
| 340 TEST(ChildPortHandshake, NoClient) { | |
| 341 // In this test, the client never checks in with the server because it never | |
| 342 // even runs. This tests that the server properly detects that it has no | |
| 343 // client at all, and does not terminate execution with an error such as | |
| 178 // “broken pipe” when attempting to send instructions to the client. This test | 344 // “broken pipe” when attempting to send instructions to the client. This test |
| 179 // is similar to ChildDoesNotCheckIn, but because there’s no child at all, the | 345 // is similar to kClientDoesNotCheckIn, but because there’s no client at all, |
| 180 // server is guaranteed to see that its pipe partner is gone. | 346 // the server is guaranteed to see that its pipe partner is gone. |
| 181 ChildPortHandshake child_port_handshake; | 347 ChildPortHandshake child_port_handshake; |
| 182 base::mac::ScopedMachSendRight child_port(child_port_handshake.RunServer()); | 348 base::mac::ScopedMachSendRight child_port(child_port_handshake.RunServer( |
| 183 EXPECT_EQ(kMachPortNull, child_port); | 349 ChildPortHandshake::PortRightType::kSendRight)); |
| 350 EXPECT_FALSE(child_port.is_valid()); | |
| 184 } | 351 } |
| 185 | 352 |
| 186 } // namespace | 353 } // namespace |
| 187 } // namespace test | 354 } // namespace test |
| 188 } // namespace crashpad | 355 } // namespace crashpad |
| OLD | NEW |