From 5263ca362a9360cb49ba7b5417febcfd161e3c32 Mon Sep 17 00:00:00 2001 From: Chris Jones Date: Tue, 16 Feb 2010 12:44:23 -0600 Subject: [PATCH] Bug 545455: IPDL/C++ test. --- ipc/ipdl/test/cxx/Makefile.in | 2 +- ipc/ipdl/test/cxx/PTestStackHooks.ipdl | 56 ++++++++++ ipc/ipdl/test/cxx/TestStackHooks.cpp | 148 +++++++++++++++++++++++++ ipc/ipdl/test/cxx/TestStackHooks.h | 123 ++++++++++++++++++++ ipc/ipdl/test/cxx/ipdl.mk | 1 + 5 files changed, 329 insertions(+), 1 deletion(-) create mode 100644 ipc/ipdl/test/cxx/PTestStackHooks.ipdl create mode 100644 ipc/ipdl/test/cxx/TestStackHooks.cpp create mode 100644 ipc/ipdl/test/cxx/TestStackHooks.h diff --git a/ipc/ipdl/test/cxx/Makefile.in b/ipc/ipdl/test/cxx/Makefile.in index 17085480426..6c2a0492499 100644 --- a/ipc/ipdl/test/cxx/Makefile.in +++ b/ipc/ipdl/test/cxx/Makefile.in @@ -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 \ diff --git a/ipc/ipdl/test/cxx/PTestStackHooks.ipdl b/ipc/ipdl/test/cxx/PTestStackHooks.ipdl new file mode 100644 index 00000000000..635db3a27ed --- /dev/null +++ b/ipc/ipdl/test/cxx/PTestStackHooks.ipdl @@ -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 diff --git a/ipc/ipdl/test/cxx/TestStackHooks.cpp b/ipc/ipdl/test/cxx/TestStackHooks.cpp new file mode 100644 index 00000000000..c7bd55319dc --- /dev/null +++ b/ipc/ipdl/test/cxx/TestStackHooks.cpp @@ -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(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 diff --git a/ipc/ipdl/test/cxx/TestStackHooks.h b/ipc/ipdl/test/cxx/TestStackHooks.h new file mode 100644 index 00000000000..2f542bc6eb9 --- /dev/null +++ b/ipc/ipdl/test/cxx/TestStackHooks.h @@ -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 diff --git a/ipc/ipdl/test/cxx/ipdl.mk b/ipc/ipdl/test/cxx/ipdl.mk index d05dddc8ba7..16babce65fb 100644 --- a/ipc/ipdl/test/cxx/ipdl.mk +++ b/ipc/ipdl/test/cxx/ipdl.mk @@ -22,5 +22,6 @@ IPDLSRCS = \ PTestShutdown.ipdl \ PTestShutdownSub.ipdl \ PTestShutdownSubsub.ipdl \ + PTestStackHooks.ipdl \ PTestSyncWakeup.ipdl \ $(NULL)