diff options
Diffstat (limited to 'ipc/ipdl/test/gtest/TestUrgency.cpp')
-rw-r--r-- | ipc/ipdl/test/gtest/TestUrgency.cpp | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/ipc/ipdl/test/gtest/TestUrgency.cpp b/ipc/ipdl/test/gtest/TestUrgency.cpp new file mode 100644 index 0000000000..a4f7d0ea3e --- /dev/null +++ b/ipc/ipdl/test/gtest/TestUrgency.cpp @@ -0,0 +1,115 @@ +/* -*- 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 sync messages preempt other messages in the expected way. + */ + +#include "gtest/gtest.h" + +#include "mozilla/_ipdltest/IPDLUnitTest.h" +#include "mozilla/_ipdltest/PTestUrgencyChild.h" +#include "mozilla/_ipdltest/PTestUrgencyParent.h" + +using namespace mozilla::ipc; + +namespace mozilla::_ipdltest { + +enum { + kFirstTestBegin = 1, + kFirstTestGotReply, + kSecondTestBegin, + kSecondTestGotReply, +}; + +class TestUrgencyParent : public PTestUrgencyParent { + NS_INLINE_DECL_REFCOUNTING(TestUrgencyParent, override) + private: + IPCResult RecvTest1(uint32_t* value) final override { + EXPECT_TRUE(SendReply1(value)); + EXPECT_EQ(*value, (uint32_t)99) << "unexpected value"; + return IPC_OK(); + } + + IPCResult RecvTest2() final override { + uint32_t value; + inreply_ = true; + EXPECT_TRUE(SendReply2(&value)); + inreply_ = false; + EXPECT_EQ(value, (uint32_t)500) << "unexpected value"; + return IPC_OK(); + } + + IPCResult RecvTest3(uint32_t* value) final override { + EXPECT_FALSE(inreply_) << "nested non-urgent on top of urgent message"; + *value = 1000; + return IPC_OK(); + } + + IPCResult RecvFinalTest_Begin() final override { return IPC_OK(); } + + ~TestUrgencyParent() = default; + + bool inreply_ = false; +}; + +class TestUrgencyChild : public PTestUrgencyChild { + NS_INLINE_DECL_REFCOUNTING(TestUrgencyChild, override) + private: + IPCResult RecvStart() final override { + uint32_t result; + + // Send a synchronous message, expect to get an urgent message while + // blocked. + test_ = kFirstTestBegin; + EXPECT_TRUE(SendTest1(&result)); + EXPECT_EQ(result, (uint32_t)99) << "wrong value from SendTest1"; + EXPECT_EQ(test_, kFirstTestGotReply) + << "never received first urgent message"; + + // Initiate the next test by sending an asynchronous message, then becoming + // blocked. This tests that the urgent message is still delivered properly, + // and that the parent does not try to service the sync + test_ = kSecondTestBegin; + EXPECT_TRUE(SendTest2()); + EXPECT_TRUE(SendTest3(&result)); + EXPECT_EQ(test_, kSecondTestGotReply) + << "never received second urgent message"; + EXPECT_EQ(result, (uint32_t)1000) << "wrong value from SendTest3"; + + EXPECT_TRUE(SendFinalTest_Begin()); + + Close(); + + return IPC_OK(); + } + + IPCResult RecvReply1(uint32_t* reply) final override { + EXPECT_EQ(test_, kFirstTestBegin) << "wrong test state in RecvReply1"; + + *reply = 99; + test_ = kFirstTestGotReply; + return IPC_OK(); + } + + IPCResult RecvReply2(uint32_t* reply) final override { + EXPECT_EQ(test_, kSecondTestBegin) << "wrong test state in RecvReply2"; + + *reply = 500; + test_ = kSecondTestGotReply; + return IPC_OK(); + } + + ~TestUrgencyChild() = default; + + uint32_t test_ = 0; +}; + +// Only run cross-process because we need to send nested sync messages (this can +// only be done from the main thread). +IPDL_TEST_ON(CROSSPROCESS, TestUrgency) { EXPECT_TRUE(mActor->SendStart()); } + +} // namespace mozilla::_ipdltest |