TestCancel.cpp (3579B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 5 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 /* 8 * Test that IPC channel transaction cancellation (which applies to nested sync 9 * messages) works as expected. 10 */ 11 12 #include "gtest/gtest.h" 13 14 #include "mozilla/_ipdltest/IPDLUnitTest.h" 15 #include "mozilla/_ipdltest/PTestCancelChild.h" 16 #include "mozilla/_ipdltest/PTestCancelParent.h" 17 18 using namespace mozilla::ipc; 19 20 namespace mozilla::_ipdltest { 21 22 class TestCancelParent : public PTestCancelParent { 23 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(TestCancelParent, override) 24 private: 25 IPCResult RecvCallNestedCancel() final override { 26 EXPECT_FALSE(SendNestedCancel()) << "SendNestedCancel should fail"; 27 EXPECT_EQ(GetIPCChannel()->LastSendError(), 28 SyncSendError::CancelledAfterSend) 29 << "SendNestedCancel should be cancelled"; 30 31 return IPC_OK(); 32 } 33 34 IPCResult RecvNestedCancelParent() final override { 35 GetIPCChannel()->CancelCurrentTransaction(); 36 return IPC_OK(); 37 } 38 39 IPCResult RecvCheckParent(uint32_t* reply) final override { 40 *reply = 42; 41 return IPC_OK(); 42 } 43 44 ~TestCancelParent() = default; 45 }; 46 47 class TestCancelChild : public PTestCancelChild { 48 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(TestCancelChild, override) 49 private: 50 IPCResult RecvImmediateCancel() final override { 51 GetIPCChannel()->CancelCurrentTransaction(); 52 53 uint32_t value = 0; 54 EXPECT_FALSE(SendCheckParent(&value)) << "channel should be closing"; 55 56 return IPC_OK(); 57 } 58 59 IPCResult RecvStartNestedCancel() final override { 60 EXPECT_FALSE(SendCallNestedCancel()); 61 62 Close(); 63 return IPC_OK(); 64 } 65 66 IPCResult RecvNestedCancel() final override { 67 GetIPCChannel()->CancelCurrentTransaction(); 68 69 uint32_t value = 0; 70 EXPECT_TRUE(SendCheckParent(&value)) << "channel should be closing"; 71 72 return IPC_OK(); 73 } 74 75 IPCResult RecvStartNestedCancelParent() final override { 76 EXPECT_FALSE(SendNestedCancelParent()) 77 << "SendNestedCancelParent should fail"; 78 EXPECT_EQ(GetIPCChannel()->LastSendError(), 79 SyncSendError::CancelledAfterSend) 80 << "SendNestedCancelParent should be cancelled"; 81 82 uint32_t value = 0; 83 EXPECT_FALSE(SendCheckParent(&value)); 84 85 return IPC_OK(); 86 } 87 88 IPCResult RecvCheckChild(uint32_t* reply) final override { 89 *reply = 42; 90 return IPC_OK(); 91 } 92 93 ~TestCancelChild() = default; 94 }; 95 96 // Nested sync messages can only be received on the main thread, so threaded 97 // tests can't be run (the child actor won't be on the main thread). 98 99 IPDL_TEST_ON(CROSSPROCESS, TestCancel, ImmediateCancel) { 100 EXPECT_FALSE(mActor->SendImmediateCancel()) << "should immediately cancel"; 101 EXPECT_EQ(mActor->GetIPCChannel()->LastSendError(), 102 SyncSendError::CancelledAfterSend); 103 104 uint32_t value = 0; 105 EXPECT_TRUE(mActor->SendCheckChild(&value)); 106 EXPECT_EQ(value, (uint32_t)42); 107 108 mActor->Close(); 109 } 110 111 IPDL_TEST_ON(CROSSPROCESS, TestCancel, NestedCancel) { 112 EXPECT_TRUE(mActor->SendStartNestedCancel()); 113 } 114 115 IPDL_TEST_ON(CROSSPROCESS, TestCancel, NestedCancelParent) { 116 EXPECT_FALSE(mActor->SendStartNestedCancelParent()) 117 << "StartNestedCancelParent should be cancelled"; 118 119 uint32_t value = 0; 120 EXPECT_TRUE(mActor->SendCheckChild(&value)); 121 EXPECT_EQ(value, (uint32_t)42); 122 123 mActor->Close(); 124 } 125 126 } // namespace mozilla::_ipdltest