diff options
Diffstat (limited to 'ipc/ipdl/test/gtest/TestInduceConnectionError.cpp')
-rw-r--r-- | ipc/ipdl/test/gtest/TestInduceConnectionError.cpp | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/ipc/ipdl/test/gtest/TestInduceConnectionError.cpp b/ipc/ipdl/test/gtest/TestInduceConnectionError.cpp new file mode 100644 index 0000000000..988e22fe5a --- /dev/null +++ b/ipc/ipdl/test/gtest/TestInduceConnectionError.cpp @@ -0,0 +1,95 @@ +/* -*- 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/. */ + +#include "gtest/gtest.h" + +#include "mozilla/SpinEventLoopUntil.h" +#include "mozilla/_ipdltest/IPDLUnitTest.h" +#include "mozilla/_ipdltest/PTestInduceConnectionErrorChild.h" +#include "mozilla/_ipdltest/PTestInduceConnectionErrorParent.h" + +using namespace mozilla::ipc; + +namespace mozilla::_ipdltest { + +class TestInduceConnectionErrorChild : public PTestInduceConnectionErrorChild { + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(TestInduceConnectionErrorChild, + override) + + public: + IPCResult RecvBegin() override { + SendFirstMessage(); + SendFollowupMessage(); + Close(); + return IPC_OK(); + } + + private: + ~TestInduceConnectionErrorChild() = default; +}; + +class TestInduceConnectionErrorParent + : public PTestInduceConnectionErrorParent { + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(TestInduceConnectionErrorParent, + override) + + IPCResult RecvFirstMessage() override { + EXPECT_TRUE(CanSend()) << "Actor still alive before inducing"; + GetIPCChannel()->InduceConnectionError(); + EXPECT_TRUE(CanSend()) + << "Actor still alive after inducing - notification will be async"; + mRecvdFirstMessage = true; + + GetCurrentSerialEventTarget()->Dispatch(NS_NewRunnableFunction( + "AfterRecvFirstMessage", [self = RefPtr{this}]() { + EXPECT_FALSE(self->CanSend()) + << "Actor shut down after spinning the event loop"; + self->mTestComplete = true; + })); + return IPC_OK(); + } + + IPCResult RecvFollowupMessage() override { + MOZ_CRASH( + "Should never receive followup message, despite them being sent " + "together"); + } + + void ActorDestroy(ActorDestroyReason aReason) override { + EXPECT_TRUE(mRecvdFirstMessage) + << "Should have mRecvdFirstMessage set before ActorDestroy"; + EXPECT_FALSE(mTestComplete) << "The test has not completed"; + EXPECT_EQ(aReason, ActorDestroyReason::AbnormalShutdown) + << "Should be an abnormal shutdown"; + mDestroyReason = Some(aReason); + } + + bool mRecvdFirstMessage = false; + bool mTestComplete = false; + Maybe<ActorDestroyReason> mDestroyReason; + + private: + ~TestInduceConnectionErrorParent() = default; +}; + +IPDL_TEST(TestInduceConnectionError) { + bool ok = mActor->SendBegin(); + GTEST_ASSERT_TRUE(ok); + + // Wait for the actor to be shut down. + SpinEventLoopUntil("TestInduceConnectionError"_ns, + [&] { return mActor->mTestComplete; }); + EXPECT_TRUE(mActor->mRecvdFirstMessage) + << "Actor should have received first message, but not second one"; + EXPECT_FALSE(mActor->CanSend()) << "Actor can no longer send"; + GTEST_ASSERT_TRUE(mActor->mDestroyReason.isSome()) + << "Actor should have been destroyed"; + EXPECT_EQ(*mActor->mDestroyReason, + IProtocol::ActorDestroyReason::AbnormalShutdown) + << "Actor should have an 'abnormal shutdown'"; +} + +} // namespace mozilla::_ipdltest |