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, |
(...skipping 20 matching lines...) Expand all Loading... |
31 using testing::Eq; | 31 using testing::Eq; |
32 using testing::Invoke; | 32 using testing::Invoke; |
33 using testing::Ne; | 33 using testing::Ne; |
34 using testing::Pointee; | 34 using testing::Pointee; |
35 using testing::ResultOf; | 35 using testing::ResultOf; |
36 using testing::Return; | 36 using testing::Return; |
37 using testing::SetArgPointee; | 37 using testing::SetArgPointee; |
38 using testing::StrictMock; | 38 using testing::StrictMock; |
39 using testing::WithArg; | 39 using testing::WithArg; |
40 | 40 |
41 //! \brief Allocates and returns a new receive right. | |
42 //! | |
43 //! \return The new receive right. On failure, `MACH_PORT_NULL` with a gtest | |
44 //! failure added. | |
45 mach_port_t NewReceiveRight() { | |
46 mach_port_t receive_right; | |
47 kern_return_t kr = mach_port_allocate( | |
48 mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &receive_right); | |
49 if (kr != KERN_SUCCESS) { | |
50 EXPECT_EQ(KERN_SUCCESS, kr) << MachErrorMessage(kr, "mach_port_allocate"); | |
51 return MACH_PORT_NULL; | |
52 } | |
53 return receive_right; | |
54 } | |
55 | |
56 //! \brief Adds a send right to an existing receive right. | 41 //! \brief Adds a send right to an existing receive right. |
57 //! | 42 //! |
58 //! \param[in] receive_right The receive right to add a send right to. | 43 //! \param[in] receive_right The receive right to add a send right to. |
59 //! | 44 //! |
60 //! \return The send right, which will have the same name as the receive right. | 45 //! \return The send right, which will have the same name as the receive right. |
61 //! On failure, `MACH_PORT_NULL` with a gtest failure added. | 46 //! On failure, `MACH_PORT_NULL` with a gtest failure added. |
62 mach_port_t SendRightFromReceiveRight(mach_port_t receive_right) { | 47 mach_port_t SendRightFromReceiveRight(mach_port_t receive_right) { |
63 kern_return_t kr = mach_port_insert_right( | 48 kern_return_t kr = mach_port_insert_right( |
64 mach_task_self(), receive_right, receive_right, MACH_MSG_TYPE_MAKE_SEND); | 49 mach_task_self(), receive_right, receive_right, MACH_MSG_TYPE_MAKE_SEND); |
65 if (kr != KERN_SUCCESS) { | 50 if (kr != KERN_SUCCESS) { |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
265 //! \brief Returns the receive right to be used for the server. | 250 //! \brief Returns the receive right to be used for the server. |
266 //! | 251 //! |
267 //! This receive right is created lazily on a per-test basis. It is destroyed | 252 //! This receive right is created lazily on a per-test basis. It is destroyed |
268 //! by TearDown() at the conclusion of each test. | 253 //! by TearDown() at the conclusion of each test. |
269 //! | 254 //! |
270 //! \return The server port receive right, creating it if one has not yet been | 255 //! \return The server port receive right, creating it if one has not yet been |
271 //! established for the current test. On failure, returns `MACH_PORT_NULL` | 256 //! established for the current test. On failure, returns `MACH_PORT_NULL` |
272 //! with a gtest failure added. | 257 //! with a gtest failure added. |
273 mach_port_t ServerPort() { | 258 mach_port_t ServerPort() { |
274 if (!server_port_) { | 259 if (!server_port_) { |
275 server_port_.reset(NewReceiveRight()); | 260 server_port_.reset(NewMachPort(MACH_PORT_RIGHT_RECEIVE)); |
| 261 EXPECT_NE(kMachPortNull, server_port_); |
276 } | 262 } |
277 | 263 |
278 return server_port_; | 264 return server_port_; |
279 } | 265 } |
280 | 266 |
281 // testing::Test: | 267 // testing::Test: |
282 void TearDown() override { | 268 void TearDown() override { |
283 server_port_.reset(); | 269 server_port_.reset(); |
284 } | 270 } |
285 | 271 |
(...skipping 28 matching lines...) Expand all Loading... |
314 } | 300 } |
315 | 301 |
316 // When no notifications are requested, nothing should happen. | 302 // When no notifications are requested, nothing should happen. |
317 TEST_F(NotifyServerTest, NoNotification) { | 303 TEST_F(NotifyServerTest, NoNotification) { |
318 RunServer(); | 304 RunServer(); |
319 } | 305 } |
320 | 306 |
321 // When a send-once right with a dead-name notification request is deallocated, | 307 // When a send-once right with a dead-name notification request is deallocated, |
322 // a port-deleted notification should be generated. | 308 // a port-deleted notification should be generated. |
323 TEST_F(NotifyServerTest, MachNotifyPortDeleted) { | 309 TEST_F(NotifyServerTest, MachNotifyPortDeleted) { |
324 base::mac::ScopedMachReceiveRight receive_right(NewReceiveRight()); | 310 base::mac::ScopedMachReceiveRight receive_right( |
| 311 NewMachPort(MACH_PORT_RIGHT_RECEIVE)); |
325 ASSERT_NE(kMachPortNull, receive_right); | 312 ASSERT_NE(kMachPortNull, receive_right); |
326 | 313 |
327 base::mac::ScopedMachSendRight send_once_right( | 314 base::mac::ScopedMachSendRight send_once_right( |
328 SendOnceRightFromReceiveRight(receive_right)); | 315 SendOnceRightFromReceiveRight(receive_right)); |
329 ASSERT_NE(kMachPortNull, send_once_right); | 316 ASSERT_NE(kMachPortNull, send_once_right); |
330 | 317 |
331 ASSERT_TRUE(RequestMachPortNotification( | 318 ASSERT_TRUE(RequestMachPortNotification( |
332 send_once_right, MACH_NOTIFY_DEAD_NAME, 0)); | 319 send_once_right, MACH_NOTIFY_DEAD_NAME, 0)); |
333 | 320 |
334 EXPECT_CALL(*this, DoMachNotifyPortDeleted(ServerPort(), | 321 EXPECT_CALL(*this, DoMachNotifyPortDeleted(ServerPort(), |
335 send_once_right.get(), | 322 send_once_right.get(), |
336 Ne(nullptr))) | 323 Ne(nullptr))) |
337 .WillOnce(Return(MIG_NO_REPLY)) | 324 .WillOnce(Return(MIG_NO_REPLY)) |
338 .RetiresOnSaturation(); | 325 .RetiresOnSaturation(); |
339 | 326 |
340 send_once_right.reset(); | 327 send_once_right.reset(); |
341 | 328 |
342 RunServer(); | 329 RunServer(); |
343 } | 330 } |
344 | 331 |
345 // When a receive right with a port-destroyed notification request is destroyed, | 332 // When a receive right with a port-destroyed notification request is destroyed, |
346 // a port-destroyed notification should be generated. | 333 // a port-destroyed notification should be generated. |
347 TEST_F(NotifyServerTest, MachNotifyPortDestroyed) { | 334 TEST_F(NotifyServerTest, MachNotifyPortDestroyed) { |
348 base::mac::ScopedMachReceiveRight receive_right(NewReceiveRight()); | 335 base::mac::ScopedMachReceiveRight receive_right( |
| 336 NewMachPort(MACH_PORT_RIGHT_RECEIVE)); |
349 ASSERT_NE(kMachPortNull, receive_right); | 337 ASSERT_NE(kMachPortNull, receive_right); |
350 | 338 |
351 ASSERT_TRUE(RequestMachPortNotification( | 339 ASSERT_TRUE(RequestMachPortNotification( |
352 receive_right, MACH_NOTIFY_PORT_DESTROYED, 0)); | 340 receive_right, MACH_NOTIFY_PORT_DESTROYED, 0)); |
353 | 341 |
354 EXPECT_CALL(*this, DoMachNotifyPortDestroyed(ServerPort(), | 342 EXPECT_CALL(*this, DoMachNotifyPortDestroyed(ServerPort(), |
355 ResultOf(IsReceiveRight, true), | 343 ResultOf(IsReceiveRight, true), |
356 Ne(nullptr), | 344 Ne(nullptr), |
357 Pointee(Eq(false)))) | 345 Pointee(Eq(false)))) |
358 .WillOnce(DoAll(SetArgPointee<3>(true), Return(MIG_NO_REPLY))) | 346 .WillOnce(DoAll(SetArgPointee<3>(true), Return(MIG_NO_REPLY))) |
359 .RetiresOnSaturation(); | 347 .RetiresOnSaturation(); |
360 | 348 |
361 receive_right.reset(); | 349 receive_right.reset(); |
362 | 350 |
363 RunServer(); | 351 RunServer(); |
364 } | 352 } |
365 | 353 |
366 // When a receive right with a port-destroyed notification request is not | 354 // When a receive right with a port-destroyed notification request is not |
367 // destroyed, no port-destroyed notification should be generated. | 355 // destroyed, no port-destroyed notification should be generated. |
368 TEST_F(NotifyServerTest, MachNotifyPortDestroyed_NoNotification) { | 356 TEST_F(NotifyServerTest, MachNotifyPortDestroyed_NoNotification) { |
369 base::mac::ScopedMachReceiveRight receive_right(NewReceiveRight()); | 357 base::mac::ScopedMachReceiveRight receive_right( |
| 358 NewMachPort(MACH_PORT_RIGHT_RECEIVE)); |
370 ASSERT_NE(kMachPortNull, receive_right); | 359 ASSERT_NE(kMachPortNull, receive_right); |
371 | 360 |
372 ASSERT_TRUE(RequestMachPortNotification( | 361 ASSERT_TRUE(RequestMachPortNotification( |
373 receive_right, MACH_NOTIFY_PORT_DESTROYED, 0)); | 362 receive_right, MACH_NOTIFY_PORT_DESTROYED, 0)); |
374 | 363 |
375 RunServer(); | 364 RunServer(); |
376 } | 365 } |
377 | 366 |
378 // When a no-senders notification request is registered for a receive right with | 367 // When a no-senders notification request is registered for a receive right with |
379 // no senders, a no-senders notification should be generated. | 368 // no senders, a no-senders notification should be generated. |
380 TEST_F(NotifyServerTest, MachNotifyNoSenders_NoSendRight) { | 369 TEST_F(NotifyServerTest, MachNotifyNoSenders_NoSendRight) { |
381 base::mac::ScopedMachReceiveRight receive_right(NewReceiveRight()); | 370 base::mac::ScopedMachReceiveRight receive_right( |
| 371 NewMachPort(MACH_PORT_RIGHT_RECEIVE)); |
382 ASSERT_NE(kMachPortNull, receive_right); | 372 ASSERT_NE(kMachPortNull, receive_right); |
383 | 373 |
384 ASSERT_TRUE(RequestMachPortNotification( | 374 ASSERT_TRUE(RequestMachPortNotification( |
385 receive_right, MACH_NOTIFY_NO_SENDERS, 0)); | 375 receive_right, MACH_NOTIFY_NO_SENDERS, 0)); |
386 | 376 |
387 EXPECT_CALL(*this, DoMachNotifyNoSenders(ServerPort(), 0, Ne(nullptr))) | 377 EXPECT_CALL(*this, DoMachNotifyNoSenders(ServerPort(), 0, Ne(nullptr))) |
388 .WillOnce(Return(MIG_NO_REPLY)) | 378 .WillOnce(Return(MIG_NO_REPLY)) |
389 .RetiresOnSaturation(); | 379 .RetiresOnSaturation(); |
390 | 380 |
391 RunServer(); | 381 RunServer(); |
392 } | 382 } |
393 | 383 |
394 // When the last send right corresponding to a receive right with a no-senders | 384 // When the last send right corresponding to a receive right with a no-senders |
395 // notification request is deallocated, a no-senders notification should be | 385 // notification request is deallocated, a no-senders notification should be |
396 // generated. | 386 // generated. |
397 TEST_F(NotifyServerTest, MachNotifyNoSenders_SendRightDeallocated) { | 387 TEST_F(NotifyServerTest, MachNotifyNoSenders_SendRightDeallocated) { |
398 base::mac::ScopedMachReceiveRight receive_right(NewReceiveRight()); | 388 base::mac::ScopedMachReceiveRight receive_right( |
| 389 NewMachPort(MACH_PORT_RIGHT_RECEIVE)); |
399 ASSERT_NE(kMachPortNull, receive_right); | 390 ASSERT_NE(kMachPortNull, receive_right); |
400 | 391 |
401 base::mac::ScopedMachSendRight send_right( | 392 base::mac::ScopedMachSendRight send_right( |
402 SendRightFromReceiveRight(receive_right)); | 393 SendRightFromReceiveRight(receive_right)); |
403 ASSERT_NE(kMachPortNull, send_right); | 394 ASSERT_NE(kMachPortNull, send_right); |
404 | 395 |
405 ASSERT_TRUE(RequestMachPortNotification( | 396 ASSERT_TRUE(RequestMachPortNotification( |
406 receive_right, MACH_NOTIFY_NO_SENDERS, 1)); | 397 receive_right, MACH_NOTIFY_NO_SENDERS, 1)); |
407 | 398 |
408 EXPECT_CALL(*this, DoMachNotifyNoSenders(ServerPort(), 1, Ne(nullptr))) | 399 EXPECT_CALL(*this, DoMachNotifyNoSenders(ServerPort(), 1, Ne(nullptr))) |
409 .WillOnce(Return(MIG_NO_REPLY)) | 400 .WillOnce(Return(MIG_NO_REPLY)) |
410 .RetiresOnSaturation(); | 401 .RetiresOnSaturation(); |
411 | 402 |
412 send_right.reset(); | 403 send_right.reset(); |
413 | 404 |
414 RunServer(); | 405 RunServer(); |
415 } | 406 } |
416 | 407 |
417 // When the a receive right with a no-senders notification request never loses | 408 // When the a receive right with a no-senders notification request never loses |
418 // all senders, no no-senders notification should be generated. | 409 // all senders, no no-senders notification should be generated. |
419 TEST_F(NotifyServerTest, MachNotifyNoSenders_NoNotification) { | 410 TEST_F(NotifyServerTest, MachNotifyNoSenders_NoNotification) { |
420 base::mac::ScopedMachReceiveRight receive_right(NewReceiveRight()); | 411 base::mac::ScopedMachReceiveRight receive_right( |
| 412 NewMachPort(MACH_PORT_RIGHT_RECEIVE)); |
421 ASSERT_NE(kMachPortNull, receive_right); | 413 ASSERT_NE(kMachPortNull, receive_right); |
422 | 414 |
423 base::mac::ScopedMachSendRight send_right_0( | 415 base::mac::ScopedMachSendRight send_right_0( |
424 SendRightFromReceiveRight(receive_right)); | 416 SendRightFromReceiveRight(receive_right)); |
425 ASSERT_NE(kMachPortNull, send_right_0); | 417 ASSERT_NE(kMachPortNull, send_right_0); |
426 | 418 |
427 base::mac::ScopedMachSendRight send_right_1( | 419 base::mac::ScopedMachSendRight send_right_1( |
428 SendRightFromReceiveRight(receive_right)); | 420 SendRightFromReceiveRight(receive_right)); |
429 ASSERT_NE(kMachPortNull, send_right_1); | 421 ASSERT_NE(kMachPortNull, send_right_1); |
430 | 422 |
(...skipping 21 matching lines...) Expand all Loading... |
452 | 444 |
453 send_once_right.reset(); | 445 send_once_right.reset(); |
454 | 446 |
455 RunServer(); | 447 RunServer(); |
456 } | 448 } |
457 | 449 |
458 // When a send-once right is sent to a receiver that never dequeues the message, | 450 // When a send-once right is sent to a receiver that never dequeues the message, |
459 // the send-once right is destroyed, and a send-once notification should appear | 451 // the send-once right is destroyed, and a send-once notification should appear |
460 // on the reply port. | 452 // on the reply port. |
461 TEST_F(NotifyServerTest, MachNotifySendOnce_ImplicitDeallocation) { | 453 TEST_F(NotifyServerTest, MachNotifySendOnce_ImplicitDeallocation) { |
462 base::mac::ScopedMachReceiveRight receive_right(NewReceiveRight()); | 454 base::mac::ScopedMachReceiveRight receive_right( |
| 455 NewMachPort(MACH_PORT_RIGHT_RECEIVE)); |
463 ASSERT_NE(kMachPortNull, receive_right); | 456 ASSERT_NE(kMachPortNull, receive_right); |
464 | 457 |
465 mach_msg_empty_send_t message = {}; | 458 mach_msg_empty_send_t message = {}; |
466 message.header.msgh_bits = | 459 message.header.msgh_bits = |
467 MACH_MSGH_BITS(MACH_MSG_TYPE_MAKE_SEND, MACH_MSG_TYPE_MAKE_SEND_ONCE); | 460 MACH_MSGH_BITS(MACH_MSG_TYPE_MAKE_SEND, MACH_MSG_TYPE_MAKE_SEND_ONCE); |
468 message.header.msgh_size = sizeof(message); | 461 message.header.msgh_size = sizeof(message); |
469 message.header.msgh_remote_port = receive_right; | 462 message.header.msgh_remote_port = receive_right; |
470 message.header.msgh_local_port = ServerPort(); | 463 message.header.msgh_local_port = ServerPort(); |
471 mach_msg_return_t mr = mach_msg(&message.header, | 464 mach_msg_return_t mr = mach_msg(&message.header, |
472 MACH_SEND_MSG | MACH_SEND_TIMEOUT, | 465 MACH_SEND_MSG | MACH_SEND_TIMEOUT, |
(...skipping 10 matching lines...) Expand all Loading... |
483 | 476 |
484 receive_right.reset(); | 477 receive_right.reset(); |
485 | 478 |
486 RunServer(); | 479 RunServer(); |
487 } | 480 } |
488 | 481 |
489 // When the receive right corresponding to a send-once right with a dead-name | 482 // When the receive right corresponding to a send-once right with a dead-name |
490 // notification request is destroyed, a dead-name notification should be | 483 // notification request is destroyed, a dead-name notification should be |
491 // generated. | 484 // generated. |
492 TEST_F(NotifyServerTest, MachNotifyDeadName) { | 485 TEST_F(NotifyServerTest, MachNotifyDeadName) { |
493 base::mac::ScopedMachReceiveRight receive_right(NewReceiveRight()); | 486 base::mac::ScopedMachReceiveRight receive_right( |
| 487 NewMachPort(MACH_PORT_RIGHT_RECEIVE)); |
494 ASSERT_NE(kMachPortNull, receive_right); | 488 ASSERT_NE(kMachPortNull, receive_right); |
495 | 489 |
496 base::mac::ScopedMachSendRight send_once_right( | 490 base::mac::ScopedMachSendRight send_once_right( |
497 SendOnceRightFromReceiveRight(receive_right)); | 491 SendOnceRightFromReceiveRight(receive_right)); |
498 ASSERT_NE(kMachPortNull, send_once_right); | 492 ASSERT_NE(kMachPortNull, send_once_right); |
499 | 493 |
500 ASSERT_TRUE(RequestMachPortNotification( | 494 ASSERT_TRUE(RequestMachPortNotification( |
501 send_once_right, MACH_NOTIFY_DEAD_NAME, 0)); | 495 send_once_right, MACH_NOTIFY_DEAD_NAME, 0)); |
502 | 496 |
503 // send_once_right becomes a dead name with the send-once right’s original | 497 // send_once_right becomes a dead name with the send-once right’s original |
(...skipping 16 matching lines...) Expand all Loading... |
520 EXPECT_TRUE(IsRight(send_once_right, MACH_PORT_TYPE_DEAD_NAME)); | 514 EXPECT_TRUE(IsRight(send_once_right, MACH_PORT_TYPE_DEAD_NAME)); |
521 | 515 |
522 EXPECT_EQ(0u, RightRefCount(send_once_right, MACH_PORT_RIGHT_SEND_ONCE)); | 516 EXPECT_EQ(0u, RightRefCount(send_once_right, MACH_PORT_RIGHT_SEND_ONCE)); |
523 EXPECT_EQ(1u, DeadNameRightRefCount(send_once_right)); | 517 EXPECT_EQ(1u, DeadNameRightRefCount(send_once_right)); |
524 } | 518 } |
525 | 519 |
526 // When the receive right corresponding to a send-once right with a dead-name | 520 // When the receive right corresponding to a send-once right with a dead-name |
527 // notification request is not destroyed, no dead-name notification should be | 521 // notification request is not destroyed, no dead-name notification should be |
528 // generated. | 522 // generated. |
529 TEST_F(NotifyServerTest, MachNotifyDeadName_NoNotification) { | 523 TEST_F(NotifyServerTest, MachNotifyDeadName_NoNotification) { |
530 base::mac::ScopedMachReceiveRight receive_right(NewReceiveRight()); | 524 base::mac::ScopedMachReceiveRight receive_right( |
| 525 NewMachPort(MACH_PORT_RIGHT_RECEIVE)); |
531 ASSERT_NE(kMachPortNull, receive_right); | 526 ASSERT_NE(kMachPortNull, receive_right); |
532 | 527 |
533 base::mac::ScopedMachSendRight send_once_right( | 528 base::mac::ScopedMachSendRight send_once_right( |
534 SendOnceRightFromReceiveRight(receive_right)); | 529 SendOnceRightFromReceiveRight(receive_right)); |
535 ASSERT_NE(kMachPortNull, send_once_right); | 530 ASSERT_NE(kMachPortNull, send_once_right); |
536 | 531 |
537 ASSERT_TRUE(RequestMachPortNotification( | 532 ASSERT_TRUE(RequestMachPortNotification( |
538 send_once_right, MACH_NOTIFY_DEAD_NAME, 0)); | 533 send_once_right, MACH_NOTIFY_DEAD_NAME, 0)); |
539 | 534 |
540 RunServer(); | 535 RunServer(); |
541 | 536 |
542 EXPECT_FALSE(IsRight(send_once_right, MACH_PORT_TYPE_DEAD_NAME)); | 537 EXPECT_FALSE(IsRight(send_once_right, MACH_PORT_TYPE_DEAD_NAME)); |
543 | 538 |
544 EXPECT_EQ(1u, RightRefCount(send_once_right, MACH_PORT_RIGHT_SEND_ONCE)); | 539 EXPECT_EQ(1u, RightRefCount(send_once_right, MACH_PORT_RIGHT_SEND_ONCE)); |
545 EXPECT_EQ(0u, DeadNameRightRefCount(send_once_right)); | 540 EXPECT_EQ(0u, DeadNameRightRefCount(send_once_right)); |
546 } | 541 } |
547 | 542 |
548 } // namespace | 543 } // namespace |
549 } // namespace test | 544 } // namespace test |
550 } // namespace crashpad | 545 } // namespace crashpad |
OLD | NEW |