Bug 545455: IPDL/C++ test.

This commit is contained in:
Chris Jones 2010-02-16 12:44:23 -06:00
parent c944b75ac7
commit 5263ca362a
5 changed files with 329 additions and 1 deletions

View File

@ -57,11 +57,11 @@ LIBXUL_LIBRARY = 1
FORCE_STATIC_LIB = 1
EXPORT_LIBRARY = 1
# Please keep these organized in the order "easy"-to-"hard"
IPDLTESTS = \
TestSanity \
TestRPCErrorCleanup \
TestCrashCleanup \
TestStackHooks \
TestSyncWakeup \
TestLatency \
TestRPCRaces \

View File

@ -0,0 +1,56 @@
namespace mozilla {
namespace _ipdltest {
rpc protocol PTestStackHooks {
child:
async Start();
// These tests are more fruitful running child->parent, because
// children can send |sync| messages
parent:
async Async();
sync Sync();
rpc Rpc();
both:
rpc StackFrame();
parent:
__delete__();
state START:
send Start goto TEST1;
state TEST1:
recv Async goto TEST2;
state TEST2:
recv Sync goto TEST3;
state TEST3:
answer Rpc goto TEST4;
state TEST4:
answer StackFrame goto TEST4_2;
state TEST4_2:
call StackFrame goto TEST4_3;
state TEST4_3:
recv Async goto TEST5;
state TEST5:
answer StackFrame goto TEST5_2;
state TEST5_2:
call StackFrame goto TEST5_3;
state TEST5_3:
recv Sync goto DEAD;
state DEAD:
recv __delete__;
};
} // namespace mozilla
} // namespace _ipdltest

View File

@ -0,0 +1,148 @@
#include "TestStackHooks.h"
#include "IPDLUnitTests.h" // fail etc.
namespace mozilla {
namespace _ipdltest {
//-----------------------------------------------------------------------------
// parent
TestStackHooksParent::TestStackHooksParent() : mOnStack(false)
{
MOZ_COUNT_CTOR(TestStackHooksParent);
}
TestStackHooksParent::~TestStackHooksParent()
{
MOZ_COUNT_DTOR(TestStackHooksParent);
}
void
TestStackHooksParent::Main()
{
if (!SendStart())
fail("sending Start()");
}
bool
TestStackHooksParent::AnswerStackFrame()
{
if (!mOnStack)
fail("not on C++ stack?!");
if (!CallStackFrame())
fail("calling StackFrame()");
if (!mOnStack)
fail("not on C++ stack?!");
return true;
}
//-----------------------------------------------------------------------------
// child
TestStackHooksChild::TestStackHooksChild() :
mOnStack(false),
mEntered(0),
mExited(0)
{
MOZ_COUNT_CTOR(TestStackHooksChild);
}
TestStackHooksChild::~TestStackHooksChild()
{
MOZ_COUNT_DTOR(TestStackHooksChild);
}
namespace {
void RunTestsFn() {
static_cast<TestStackHooksChild*>(gChildActor)->RunTests();
}
}
bool
TestStackHooksChild::RecvStart()
{
if (!mOnStack)
fail("missed stack notification");
// kick off tests from a runnable so that we can start with
// RPCChannel code on the C++ stack
MessageLoop::current()->PostTask(FROM_HERE,
NewRunnableFunction(RunTestsFn));
return true;
}
bool
TestStackHooksChild::AnswerStackFrame()
{
if (!mOnStack)
fail("missed stack notification");
// FIXME use IPDL state instead
if (4 == mEntered) {
if (!SendAsync())
fail("sending Async()");
}
else if (5 == mEntered) {
if (!SendSync())
fail("sending Sync()");
}
else {
fail("unexpected |mEntered| count");
}
if (!mOnStack)
fail("bad stack exit notification");
return true;
}
void
TestStackHooksChild::RunTests()
{
// 1 because of RecvStart()
if (1 != mEntered)
fail("missed stack notification");
if (mOnStack)
fail("spurious stack notification");
if (!SendAsync())
fail("sending Async()");
if (mOnStack)
fail("spurious stack notification");
if (2 != mEntered)
fail("missed stack notification");
if (!SendSync())
fail("sending Sync()");
if (mOnStack)
fail("spurious stack notification");
if (3 != mEntered)
fail("missed stack notification");
if (!CallRpc())
fail("calling RPC()");
if (mOnStack)
fail("spurious stack notification");
if (4 != mEntered)
fail("missed stack notification");
if (!CallStackFrame())
fail("calling StackFrame()");
if (mOnStack)
fail("spurious stack notification");
if (5 != mEntered)
fail("missed stack notification");
Close();
}
} // namespace _ipdltest
} // namespace mozilla

View File

@ -0,0 +1,123 @@
#ifndef mozilla__ipdltest_TestStackHooks_h
#define mozilla__ipdltest_TestStackHooks_h 1
#include "mozilla/_ipdltest/IPDLUnitTests.h"
#include "mozilla/_ipdltest/PTestStackHooksParent.h"
#include "mozilla/_ipdltest/PTestStackHooksChild.h"
namespace mozilla {
namespace _ipdltest {
class TestStackHooksParent :
public PTestStackHooksParent
{
public:
TestStackHooksParent();
virtual ~TestStackHooksParent();
void Main();
protected:
NS_OVERRIDE
virtual bool RecvAsync() {
if (!mOnStack)
fail("not on C++ stack?!");
return true;
}
NS_OVERRIDE
virtual bool RecvSync() {
if (!mOnStack)
fail("not on C++ stack?!");
return true;
}
NS_OVERRIDE
virtual bool AnswerRpc() {
if (!mOnStack)
fail("not on C++ stack?!");
return true;
}
NS_OVERRIDE
virtual bool AnswerStackFrame();
NS_OVERRIDE
virtual void ActorDestroy(ActorDestroyReason why)
{
if (NormalShutdown != why)
fail("unexpected destruction!");
passed("ok");
QuitParent();
}
NS_OVERRIDE
virtual void EnteredCxxStack() {
mOnStack = true;
}
NS_OVERRIDE
virtual void ExitedCxxStack() {
mOnStack = false;
}
private:
bool mOnStack;
};
class TestStackHooksChild :
public PTestStackHooksChild
{
public:
TestStackHooksChild();
virtual ~TestStackHooksChild();
void RunTests();
protected:
NS_OVERRIDE
virtual bool RecvStart();
NS_OVERRIDE
virtual bool AnswerStackFrame();
NS_OVERRIDE
virtual void ActorDestroy(ActorDestroyReason why)
{
if (NormalShutdown != why)
fail("unexpected destruction!");
if (mEntered != mExited)
fail("unbalanced enter/exit notifications");
if (mOnStack)
fail("computing mOnStack went awry; should have failed above assertion");
QuitChild();
}
NS_OVERRIDE
virtual void EnteredCxxStack() {
++mEntered;
mOnStack = true;
}
NS_OVERRIDE
virtual void ExitedCxxStack() {
++mExited;
mOnStack = false;
}
private:
bool mOnStack;
int mEntered;
int mExited;
};
} // namespace _ipdltest
} // namespace mozilla
#endif // ifndef mozilla__ipdltest_TestStackHooks_h

View File

@ -22,5 +22,6 @@ IPDLSRCS = \
PTestShutdown.ipdl \
PTestShutdownSub.ipdl \
PTestShutdownSubsub.ipdl \
PTestStackHooks.ipdl \
PTestSyncWakeup.ipdl \
$(NULL)