Bug 540886, part 3: IPDL/C++ test for BlockChild()/UnblockChild(). r=bnewman

--HG--
extra : transplant_source : h%0DM%F8%C5s%82%97%28%AEH%91%86%00%0E%99%A0%05T%1B
This commit is contained in:
Chris Jones 2010-01-27 00:41:33 -06:00
Родитель d12280389c
Коммит 35245fa672
5 изменённых файлов: 298 добавлений и 0 удалений

Просмотреть файл

@ -66,6 +66,7 @@ IPDLTESTS = \
TestLatency \
TestRPCRaces \
TestRacyRPCReplies \
TestBlockChild \
TestManyChildAllocs \
TestDesc \
TestMultiMgrs \

Просмотреть файл

@ -0,0 +1,51 @@
namespace mozilla {
namespace _ipdltest {
rpc protocol PTestBlockChild {
both:
rpc StackFrame();
child:
async Poke1();
async Poke2();
async LastPoke();
async __delete__();
parent:
async P1();
async P2();
async Done();
state START:
// here we |BlockChild()| in the C++
send Poke1 goto CHILD_BLOCKED;
state CHILD_BLOCKED:
call StackFrame goto CHILD_BLOCKED_RPC;
state CHILD_BLOCKED_RPC:
answer StackFrame goto CHILD_BLOCKED_RPC_POKE;
state CHILD_BLOCKED_RPC_POKE:
send Poke2 goto CHILD_STILL_BLOCKED;
// RPC stack frame gone. child should still be blocked
state CHILD_STILL_BLOCKED:
send LastPoke goto CHILD_FLUSH_QUEUE;
// here we |UnblockChild()| in the C++
state CHILD_FLUSH_QUEUE:
recv P1 goto CHILD_FLUSH_QUEUE_P2;
state CHILD_FLUSH_QUEUE_P2:
recv P2 goto CHILD_FLUSH_QUEUE_DONE;
state CHILD_FLUSH_QUEUE_DONE:
recv Done goto DONE;
state DONE:
send __delete__;
};
} // namespace _ipdltest
} // namespace mozilla

Просмотреть файл

@ -0,0 +1,149 @@
#include "TestBlockChild.h"
#include "IPDLUnitTests.h" // fail etc.
template<>
struct RunnableMethodTraits<mozilla::_ipdltest::TestBlockChildChild>
{
typedef mozilla::_ipdltest::TestBlockChildChild T;
static void RetainCallee(T* obj) { }
static void ReleaseCallee(T* obj) { }
};
namespace mozilla {
namespace _ipdltest {
//-----------------------------------------------------------------------------
// parent
void
TestBlockChildParent::Main()
{
BlockChildInLowerFrame();
if (!SendPoke1())
fail("couldn't poke the child");
if (!CallStackFrame())
fail("couldn't poke the child");
if (!SendLastPoke())
fail("couldn't poke the child");
if (!UnblockChild())
fail("can't UnblockChild()!");
mChildBlocked = false;
}
void
TestBlockChildParent::BlockChildInLowerFrame()
{
if (!BlockChild())
fail("can't BlockChild()!");
// child should be blocked and stay blocked after this returns
mChildBlocked = true;
}
bool
TestBlockChildParent::AnswerStackFrame()
{
if (!SendPoke2())
fail("couldn't poke the child");
return true;
}
bool
TestBlockChildParent::RecvP1()
{
if (mChildBlocked)
fail("child shouldn't been able to slip this past the blockade!");
mGotP1 = true;
return true;
}
bool
TestBlockChildParent::RecvP2()
{
if (mChildBlocked)
fail("child shouldn't been able to slip this past the blockade!");
mGotP2 = true;
return true;
}
bool
TestBlockChildParent::RecvDone()
{
if (mChildBlocked)
fail("child shouldn't been able to slip this past the blockade!");
// XXX IPDL transition checking makes this redundant, but never
// hurts to double-check, especially if we eventually turn off
// state checking in OPT builds
if (!mGotP1)
fail("should have received P1!");
if (!mGotP2)
fail("should have received P2!");
Close();
return true;
}
//-----------------------------------------------------------------------------
// child
bool
TestBlockChildChild::RecvPoke1()
{
MessageLoop::current()->PostTask(
FROM_HERE, NewRunnableMethod(this, &TestBlockChildChild::OnPoke1));
return true;
}
bool
TestBlockChildChild::AnswerStackFrame()
{
return CallStackFrame();
}
bool
TestBlockChildChild::RecvPoke2()
{
MessageLoop::current()->PostTask(
FROM_HERE, NewRunnableMethod(this, &TestBlockChildChild::OnPoke2));
return true;
}
bool
TestBlockChildChild::RecvLastPoke()
{
MessageLoop::current()->PostTask(
FROM_HERE, NewRunnableMethod(this, &TestBlockChildChild::OnLastPoke));
return true;
}
void
TestBlockChildChild::OnPoke1()
{
if (!SendP1())
fail("couldn't send P1");
}
void
TestBlockChildChild::OnPoke2()
{
if (!SendP2())
fail("couldn't send P2");
}
void
TestBlockChildChild::OnLastPoke()
{
if (!SendDone())
fail("couldn't send Done");
}
} // namespace _ipdltest
} // namespace mozilla

Просмотреть файл

@ -0,0 +1,96 @@
#ifndef mozilla__ipdltest_TestBlockChild_h
#define mozilla__ipdltest_TestBlockChild_h 1
#include "mozilla/_ipdltest/IPDLUnitTests.h"
#include "mozilla/_ipdltest/PTestBlockChildParent.h"
#include "mozilla/_ipdltest/PTestBlockChildChild.h"
namespace mozilla {
namespace _ipdltest {
class TestBlockChildParent :
public PTestBlockChildParent
{
public:
TestBlockChildParent() : mChildBlocked(false),
mGotP1(false),
mGotP2(false)
{ }
virtual ~TestBlockChildParent() { }
void Main();
protected:
NS_OVERRIDE
virtual bool AnswerStackFrame();
NS_OVERRIDE
virtual bool RecvP1();
NS_OVERRIDE
virtual bool RecvP2();
NS_OVERRIDE
virtual bool RecvDone();
NS_OVERRIDE
virtual void ActorDestroy(ActorDestroyReason why)
{
if (NormalShutdown != why)
fail("unexpected destruction!");
passed("ok");
QuitParent();
}
private:
void BlockChildInLowerFrame();
bool mChildBlocked;
bool mGotP1;
bool mGotP2;
bool mGotP3;
};
class TestBlockChildChild :
public PTestBlockChildChild
{
public:
TestBlockChildChild() { }
virtual ~TestBlockChildChild() { }
protected:
NS_OVERRIDE
virtual bool RecvPoke1();
NS_OVERRIDE
virtual bool AnswerStackFrame();
NS_OVERRIDE
virtual bool RecvPoke2();
NS_OVERRIDE
virtual bool RecvLastPoke();
NS_OVERRIDE
virtual void ActorDestroy(ActorDestroyReason why)
{
if (NormalShutdown != why)
fail("unexpected destruction!");
QuitChild();
}
private:
void OnPoke1();
void OnPoke2();
void OnLastPoke();
};
} // namespace _ipdltest
} // namespace mozilla
#endif // ifndef mozilla__ipdltest_TestBlockChild_h

Просмотреть файл

@ -1,6 +1,7 @@
IPDLSRCS = \
PTestArrays.ipdl \
PTestArraysSub.ipdl \
PTestBlockChild.ipdl \
PTestCrashCleanup.ipdl \
PTestDesc.ipdl \
PTestDescSub.ipdl \