Bug 545053: IPDL/C++ test of hang detector.

This commit is contained in:
Chris Jones 2010-02-11 14:32:17 -06:00
parent 7f56845cb9
commit 2d8c28e487
5 changed files with 203 additions and 0 deletions

View File

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

View File

@ -0,0 +1,28 @@
namespace mozilla {
namespace _ipdltest {
rpc protocol PTestHangs {
both:
rpc StackFrame();
child:
rpc Hang();
__delete__();
state START:
call StackFrame goto FRAME2;
// So as to test unwinding the RPC stack
state FRAME2: answer StackFrame goto FRAME3;
state FRAME3: call StackFrame goto FRAME4;
state FRAME4: answer StackFrame goto HANG;
state HANG: call Hang goto DEATH;
state DEATH:
send __delete__;
};
} // namespace _ipdltest
} // namespace mozilla

View File

@ -0,0 +1,99 @@
#include "base/process_util.h"
#include "TestHangs.h"
#include "IPDLUnitTests.h" // fail etc.
using base::KillProcess;
// XXX could drop this; very conservative
static const int kTimeoutSecs = 5;
namespace mozilla {
namespace _ipdltest {
//-----------------------------------------------------------------------------
// parent
TestHangsParent::TestHangsParent() : mFramesToGo(2)
{
MOZ_COUNT_CTOR(TestHangsParent);
}
TestHangsParent::~TestHangsParent()
{
MOZ_COUNT_DTOR(TestHangsParent);
}
void
TestHangsParent::Main()
{
SetReplyTimeoutMs(1000 * kTimeoutSecs);
if (CallStackFrame())
fail("should have timed out!");
Close();
}
bool
TestHangsParent::ShouldContinueFromReplyTimeout()
{
// If we kill the subprocess here, then the "channel error" event
// posted by the IO thread will race with the |Close()| above, in
// |Main()|. As killing the child process will probably be a
// common action to take from ShouldContinue(), we need to ensure
// that *Channel can deal.
// XXX: OtherProcess() is a semi-private API, but using it is
// OK until we start worrying about inter-thread comm
if (!KillProcess(OtherProcess(), 0, false))
fail("terminating child process");
return false;
}
bool
TestHangsParent::AnswerStackFrame()
{
if (--mFramesToGo) {
if (CallStackFrame())
fail("should have timed out!");
}
else {
if (CallHang())
fail("should have timed out!");
}
return true;
}
//-----------------------------------------------------------------------------
// child
TestHangsChild::TestHangsChild()
{
MOZ_COUNT_CTOR(TestHangsChild);
}
TestHangsChild::~TestHangsChild()
{
MOZ_COUNT_DTOR(TestHangsChild);
}
bool
TestHangsChild::AnswerHang()
{
puts(" (child process is hanging now)");
// XXX: pause() is right for this, but windows doesn't appear to
// implement it. So sleep for 100,000 seconds instead.
PR_Sleep(PR_SecondsToInterval(100000));
fail("should have been killed!");
return false; // not reached
}
} // namespace _ipdltest
} // namespace mozilla

View File

@ -0,0 +1,74 @@
#ifndef mozilla__ipdltest_TestHangs_h
#define mozilla__ipdltest_TestHangs_h 1
#include "mozilla/_ipdltest/IPDLUnitTests.h"
#include "mozilla/_ipdltest/PTestHangsParent.h"
#include "mozilla/_ipdltest/PTestHangsChild.h"
namespace mozilla {
namespace _ipdltest {
class TestHangsParent :
public PTestHangsParent
{
public:
TestHangsParent();
virtual ~TestHangsParent();
void Main();
protected:
NS_OVERRIDE
virtual bool ShouldContinueFromReplyTimeout();
NS_OVERRIDE
virtual bool AnswerStackFrame();
NS_OVERRIDE
virtual void ActorDestroy(ActorDestroyReason why)
{
if (AbnormalShutdown != why)
fail("unexpected destruction!");
passed("ok");
QuitParent();
}
// XXX hack around lack of State()
int mFramesToGo;
};
class TestHangsChild :
public PTestHangsChild
{
public:
TestHangsChild();
virtual ~TestHangsChild();
protected:
NS_OVERRIDE
virtual bool AnswerStackFrame()
{
if (!CallStackFrame())
fail("shouldn't be able to observe this failure");
return true;
}
NS_OVERRIDE
virtual bool AnswerHang();
NS_OVERRIDE
virtual void ActorDestroy(ActorDestroyReason why)
{
fail("should have been mercilessly killed");
}
};
} // namespace _ipdltest
} // namespace mozilla
#endif // ifndef mozilla__ipdltest_TestHangs_h

View File

@ -6,6 +6,7 @@ IPDLSRCS = \
PTestDesc.ipdl \
PTestDescSub.ipdl \
PTestDescSubsub.ipdl \
PTestHangs.ipdl \
PTestLatency.ipdl \
PTestManyChildAllocs.ipdl \
PTestManyChildAllocsSub.ipdl \