TestInduceConnectionError.cpp (3264B)
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 #include "gtest/gtest.h" 8 9 #include "mozilla/SpinEventLoopUntil.h" 10 #include "mozilla/_ipdltest/IPDLUnitTest.h" 11 #include "mozilla/_ipdltest/PTestInduceConnectionErrorChild.h" 12 #include "mozilla/_ipdltest/PTestInduceConnectionErrorParent.h" 13 14 using namespace mozilla::ipc; 15 16 namespace mozilla::_ipdltest { 17 18 class TestInduceConnectionErrorChild : public PTestInduceConnectionErrorChild { 19 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(TestInduceConnectionErrorChild, 20 override) 21 22 public: 23 IPCResult RecvBegin() override { 24 SendFirstMessage(); 25 SendFollowupMessage(); 26 Close(); 27 return IPC_OK(); 28 } 29 30 private: 31 ~TestInduceConnectionErrorChild() = default; 32 }; 33 34 class TestInduceConnectionErrorParent 35 : public PTestInduceConnectionErrorParent { 36 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(TestInduceConnectionErrorParent, 37 override) 38 39 IPCResult RecvFirstMessage() override { 40 EXPECT_TRUE(CanSend()) << "Actor still alive before inducing"; 41 GetIPCChannel()->InduceConnectionError(); 42 EXPECT_TRUE(CanSend()) 43 << "Actor still alive after inducing - notification will be async"; 44 mRecvdFirstMessage = true; 45 46 GetCurrentSerialEventTarget()->Dispatch(NS_NewRunnableFunction( 47 "AfterRecvFirstMessage", [self = RefPtr{this}]() { 48 EXPECT_FALSE(self->CanSend()) 49 << "Actor shut down after spinning the event loop"; 50 self->mTestComplete = true; 51 })); 52 return IPC_OK(); 53 } 54 55 IPCResult RecvFollowupMessage() override { 56 MOZ_CRASH( 57 "Should never receive followup message, despite them being sent " 58 "together"); 59 } 60 61 void ActorDestroy(ActorDestroyReason aReason) override { 62 EXPECT_TRUE(mRecvdFirstMessage) 63 << "Should have mRecvdFirstMessage set before ActorDestroy"; 64 EXPECT_FALSE(mTestComplete) << "The test has not completed"; 65 EXPECT_EQ(aReason, ActorDestroyReason::AbnormalShutdown) 66 << "Should be an abnormal shutdown"; 67 mDestroyReason = Some(aReason); 68 } 69 70 bool mRecvdFirstMessage = false; 71 bool mTestComplete = false; 72 Maybe<ActorDestroyReason> mDestroyReason; 73 74 private: 75 ~TestInduceConnectionErrorParent() = default; 76 }; 77 78 IPDL_TEST(TestInduceConnectionError) { 79 bool ok = mActor->SendBegin(); 80 GTEST_ASSERT_TRUE(ok); 81 82 // Wait for the actor to be shut down. 83 SpinEventLoopUntil("TestInduceConnectionError"_ns, 84 [&] { return mActor->mTestComplete; }); 85 EXPECT_TRUE(mActor->mRecvdFirstMessage) 86 << "Actor should have received first message, but not second one"; 87 EXPECT_FALSE(mActor->CanSend()) << "Actor can no longer send"; 88 GTEST_ASSERT_TRUE(mActor->mDestroyReason.isSome()) 89 << "Actor should have been destroyed"; 90 EXPECT_EQ(*mActor->mDestroyReason, 91 IProtocol::ActorDestroyReason::AbnormalShutdown) 92 << "Actor should have an 'abnormal shutdown'"; 93 } 94 95 } // namespace mozilla::_ipdltest