diff options
Diffstat (limited to 'ipc/ipdl/test/gtest/TestCancel.cpp')
-rw-r--r-- | ipc/ipdl/test/gtest/TestCancel.cpp | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/ipc/ipdl/test/gtest/TestCancel.cpp b/ipc/ipdl/test/gtest/TestCancel.cpp new file mode 100644 index 0000000000..79f31751dd --- /dev/null +++ b/ipc/ipdl/test/gtest/TestCancel.cpp @@ -0,0 +1,126 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * Test that IPC channel transaction cancellation (which applies to nested sync + * messages) works as expected. + */ + +#include "gtest/gtest.h" + +#include "mozilla/_ipdltest/IPDLUnitTest.h" +#include "mozilla/_ipdltest/PTestCancelChild.h" +#include "mozilla/_ipdltest/PTestCancelParent.h" + +using namespace mozilla::ipc; + +namespace mozilla::_ipdltest { + +class TestCancelParent : public PTestCancelParent { + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(TestCancelParent, override) + private: + IPCResult RecvCallNestedCancel() final override { + EXPECT_FALSE(SendNestedCancel()) << "SendNestedCancel should fail"; + EXPECT_EQ(GetIPCChannel()->LastSendError(), + SyncSendError::CancelledAfterSend) + << "SendNestedCancel should be cancelled"; + + return IPC_OK(); + } + + IPCResult RecvNestedCancelParent() final override { + GetIPCChannel()->CancelCurrentTransaction(); + return IPC_OK(); + } + + IPCResult RecvCheckParent(uint32_t* reply) final override { + *reply = 42; + return IPC_OK(); + } + + ~TestCancelParent() = default; +}; + +class TestCancelChild : public PTestCancelChild { + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(TestCancelChild, override) + private: + IPCResult RecvImmediateCancel() final override { + GetIPCChannel()->CancelCurrentTransaction(); + + uint32_t value = 0; + EXPECT_FALSE(SendCheckParent(&value)) << "channel should be closing"; + + return IPC_OK(); + } + + IPCResult RecvStartNestedCancel() final override { + EXPECT_FALSE(SendCallNestedCancel()); + + Close(); + return IPC_OK(); + } + + IPCResult RecvNestedCancel() final override { + GetIPCChannel()->CancelCurrentTransaction(); + + uint32_t value = 0; + EXPECT_TRUE(SendCheckParent(&value)) << "channel should be closing"; + + return IPC_OK(); + } + + IPCResult RecvStartNestedCancelParent() final override { + EXPECT_FALSE(SendNestedCancelParent()) + << "SendNestedCancelParent should fail"; + EXPECT_EQ(GetIPCChannel()->LastSendError(), + SyncSendError::CancelledAfterSend) + << "SendNestedCancelParent should be cancelled"; + + uint32_t value = 0; + EXPECT_FALSE(SendCheckParent(&value)); + + return IPC_OK(); + } + + IPCResult RecvCheckChild(uint32_t* reply) final override { + *reply = 42; + return IPC_OK(); + } + + ~TestCancelChild() = default; +}; + +// Nested sync messages can only be received on the main thread, so threaded +// tests can't be run (the child actor won't be on the main thread). + +IPDL_TEST_ON(CROSSPROCESS, TestCancel, ImmediateCancel) { + EXPECT_FALSE(mActor->SendImmediateCancel()) << "should immediately cancel"; + EXPECT_EQ(mActor->GetIPCChannel()->LastSendError(), + SyncSendError::CancelledAfterSend); + + uint32_t value = 0; + EXPECT_TRUE(mActor->SendCheckChild(&value)); + EXPECT_EQ(value, (uint32_t)42); + + mActor->Close(); +} + +IPDL_TEST_ON(CROSSPROCESS, TestCancel, NestedCancel) { + EXPECT_TRUE(mActor->SendStartNestedCancel()); +} + +IPDL_TEST_ON(CROSSPROCESS, TestCancel, NestedCancelParent) { + EXPECT_FALSE(mActor->SendStartNestedCancelParent()) + << "StartNestedCancelParent should be cancelled"; + + uint32_t value = 0; + EXPECT_TRUE(mActor->SendCheckChild(&value)); + EXPECT_EQ(value, (uint32_t)42); + + mActor->Close(); +} + +} // namespace mozilla::_ipdltest |