TestUrgency.cpp (3349B)
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 sync messages preempt other messages in the expected way. 9 */ 10 11 #include "gtest/gtest.h" 12 13 #include "mozilla/_ipdltest/IPDLUnitTest.h" 14 #include "mozilla/_ipdltest/PTestUrgencyChild.h" 15 #include "mozilla/_ipdltest/PTestUrgencyParent.h" 16 17 using namespace mozilla::ipc; 18 19 namespace mozilla::_ipdltest { 20 21 enum { 22 kFirstTestBegin = 1, 23 kFirstTestGotReply, 24 kSecondTestBegin, 25 kSecondTestGotReply, 26 }; 27 28 class TestUrgencyParent : public PTestUrgencyParent { 29 NS_INLINE_DECL_REFCOUNTING(TestUrgencyParent, override) 30 private: 31 IPCResult RecvTest1(uint32_t* value) final override { 32 EXPECT_TRUE(SendReply1(value)); 33 EXPECT_EQ(*value, (uint32_t)99) << "unexpected value"; 34 return IPC_OK(); 35 } 36 37 IPCResult RecvTest2() final override { 38 uint32_t value; 39 inreply_ = true; 40 EXPECT_TRUE(SendReply2(&value)); 41 inreply_ = false; 42 EXPECT_EQ(value, (uint32_t)500) << "unexpected value"; 43 return IPC_OK(); 44 } 45 46 IPCResult RecvTest3(uint32_t* value) final override { 47 EXPECT_FALSE(inreply_) << "nested non-urgent on top of urgent message"; 48 *value = 1000; 49 return IPC_OK(); 50 } 51 52 IPCResult RecvFinalTest_Begin() final override { return IPC_OK(); } 53 54 ~TestUrgencyParent() = default; 55 56 bool inreply_ = false; 57 }; 58 59 class TestUrgencyChild : public PTestUrgencyChild { 60 NS_INLINE_DECL_REFCOUNTING(TestUrgencyChild, override) 61 private: 62 IPCResult RecvStart() final override { 63 uint32_t result; 64 65 // Send a synchronous message, expect to get an urgent message while 66 // blocked. 67 test_ = kFirstTestBegin; 68 EXPECT_TRUE(SendTest1(&result)); 69 EXPECT_EQ(result, (uint32_t)99) << "wrong value from SendTest1"; 70 EXPECT_EQ(test_, kFirstTestGotReply) 71 << "never received first urgent message"; 72 73 // Initiate the next test by sending an asynchronous message, then becoming 74 // blocked. This tests that the urgent message is still delivered properly, 75 // and that the parent does not try to service the sync 76 test_ = kSecondTestBegin; 77 EXPECT_TRUE(SendTest2()); 78 EXPECT_TRUE(SendTest3(&result)); 79 EXPECT_EQ(test_, kSecondTestGotReply) 80 << "never received second urgent message"; 81 EXPECT_EQ(result, (uint32_t)1000) << "wrong value from SendTest3"; 82 83 EXPECT_TRUE(SendFinalTest_Begin()); 84 85 Close(); 86 87 return IPC_OK(); 88 } 89 90 IPCResult RecvReply1(uint32_t* reply) final override { 91 EXPECT_EQ(test_, kFirstTestBegin) << "wrong test state in RecvReply1"; 92 93 *reply = 99; 94 test_ = kFirstTestGotReply; 95 return IPC_OK(); 96 } 97 98 IPCResult RecvReply2(uint32_t* reply) final override { 99 EXPECT_EQ(test_, kSecondTestBegin) << "wrong test state in RecvReply2"; 100 101 *reply = 500; 102 test_ = kSecondTestGotReply; 103 return IPC_OK(); 104 } 105 106 ~TestUrgencyChild() = default; 107 108 uint32_t test_ = 0; 109 }; 110 111 // Only run cross-process because we need to send nested sync messages (this can 112 // only be done from the main thread). 113 IPDL_TEST_ON(CROSSPROCESS, TestUrgency) { EXPECT_TRUE(mActor->SendStart()); } 114 115 } // namespace mozilla::_ipdltest