michael@0: #include "TestUrgency.h" michael@0: michael@0: #include "IPDLUnitTests.h" // fail etc. michael@0: #if defined(OS_POSIX) michael@0: #include michael@0: #else michael@0: #include michael@0: #endif michael@0: michael@0: template<> michael@0: struct RunnableMethodTraits michael@0: { michael@0: static void RetainCallee(mozilla::_ipdltest::TestUrgencyParent* obj) { } michael@0: static void ReleaseCallee(mozilla::_ipdltest::TestUrgencyParent* obj) { } michael@0: }; michael@0: michael@0: namespace mozilla { michael@0: namespace _ipdltest { michael@0: michael@0: #if defined(OS_POSIX) michael@0: static void Sleep(int ms) michael@0: { michael@0: sleep(ms / 1000); michael@0: } michael@0: #endif michael@0: michael@0: //----------------------------------------------------------------------------- michael@0: // parent michael@0: michael@0: TestUrgencyParent::TestUrgencyParent() michael@0: : inreply_(false) michael@0: { michael@0: MOZ_COUNT_CTOR(TestUrgencyParent); michael@0: } michael@0: michael@0: TestUrgencyParent::~TestUrgencyParent() michael@0: { michael@0: MOZ_COUNT_DTOR(TestUrgencyParent); michael@0: } michael@0: michael@0: void michael@0: TestUrgencyParent::Main() michael@0: { michael@0: if (!SendStart()) michael@0: fail("sending Start"); michael@0: } michael@0: michael@0: bool michael@0: TestUrgencyParent::RecvTest1(uint32_t *value) michael@0: { michael@0: if (!CallReply1(value)) michael@0: fail("sending Reply1"); michael@0: if (*value != 99) michael@0: fail("bad value"); michael@0: return true; michael@0: } michael@0: michael@0: bool michael@0: TestUrgencyParent::RecvTest2() michael@0: { michael@0: uint32_t value; michael@0: inreply_ = true; michael@0: if (!CallReply2(&value)) michael@0: fail("sending Reply2"); michael@0: inreply_ = false; michael@0: if (value != 500) michael@0: fail("bad value"); michael@0: return true; michael@0: } michael@0: michael@0: bool michael@0: TestUrgencyParent::RecvTest3(uint32_t *value) michael@0: { michael@0: if (inreply_) michael@0: fail("nested non-urgent on top of urgent rpc"); michael@0: *value = 1000; michael@0: return true; michael@0: } michael@0: michael@0: bool michael@0: TestUrgencyParent::RecvFinalTest_Begin() michael@0: { michael@0: SetReplyTimeoutMs(2000); michael@0: if (CallFinalTest_Hang()) michael@0: fail("should have failed due to timeout"); michael@0: if (!GetIPCChannel()->Unsound_IsClosed()) michael@0: fail("channel should have closed"); michael@0: michael@0: MessageLoop::current()->PostTask( michael@0: FROM_HERE, michael@0: NewRunnableMethod(this, &TestUrgencyParent::Close)); michael@0: return false; michael@0: } michael@0: michael@0: //----------------------------------------------------------------------------- michael@0: // child michael@0: michael@0: enum { michael@0: kFirstTestBegin = 1, michael@0: kFirstTestGotReply, michael@0: kSecondTestBegin, michael@0: kSecondTestGotReply, michael@0: }; michael@0: michael@0: bool michael@0: TestUrgencyChild::RecvStart() michael@0: { michael@0: uint32_t result; michael@0: michael@0: // Send a synchronous message, expect to get an urgent message while michael@0: // blocked. michael@0: test_ = kFirstTestBegin; michael@0: if (!SendTest1(&result)) michael@0: fail("calling SendTest1"); michael@0: if (result != 99) michael@0: fail("bad result in RecvStart"); michael@0: if (test_ != kFirstTestGotReply) michael@0: fail("never received urgent message"); michael@0: michael@0: // Initiate the next test by sending an asynchronous message, then becoming michael@0: // blocked. This tests that the urgent message is still delivered properly, michael@0: // and that the parent does not try to service the sync michael@0: test_ = kSecondTestBegin; michael@0: if (!SendTest2()) michael@0: fail("calling SendTest2"); michael@0: if (!SendTest3(&result)) michael@0: fail("calling SendTest3"); michael@0: if (test_ != kSecondTestGotReply) michael@0: fail("never received urgent message #2"); michael@0: if (result != 1000) michael@0: fail("wrong value from test3"); michael@0: michael@0: // This must be the last test, since the child process may die. michael@0: if (SendFinalTest_Begin()) michael@0: fail("Final test should not have succeeded"); michael@0: michael@0: Close(); michael@0: michael@0: return true; michael@0: } michael@0: michael@0: bool michael@0: TestUrgencyChild::AnswerReply1(uint32_t *reply) michael@0: { michael@0: if (test_ != kFirstTestBegin) michael@0: fail("wrong test # in AnswerReply1"); michael@0: michael@0: *reply = 99; michael@0: test_ = kFirstTestGotReply; michael@0: return true; michael@0: } michael@0: michael@0: bool michael@0: TestUrgencyChild::AnswerReply2(uint32_t *reply) michael@0: { michael@0: if (test_ != kSecondTestBegin) michael@0: fail("wrong test # in AnswerReply2"); michael@0: michael@0: // sleep for 5 seconds so the parent process tries to deliver more messages. michael@0: Sleep(5000); michael@0: michael@0: *reply = 500; michael@0: test_ = kSecondTestGotReply; michael@0: return true; michael@0: } michael@0: michael@0: bool michael@0: TestUrgencyChild::AnswerFinalTest_Hang() michael@0: { michael@0: Sleep(10); michael@0: return true; michael@0: } michael@0: michael@0: TestUrgencyChild::TestUrgencyChild() michael@0: : test_(0) michael@0: { michael@0: MOZ_COUNT_CTOR(TestUrgencyChild); michael@0: } michael@0: michael@0: TestUrgencyChild::~TestUrgencyChild() michael@0: { michael@0: MOZ_COUNT_DTOR(TestUrgencyChild); michael@0: } michael@0: michael@0: } // namespace _ipdltest michael@0: } // namespace mozilla