Test for bug 775777. r=bent
authorChris Jones <jones.chris.g@gmail.com>
Thu, 20 Sep 2012 12:30:53 -0700
changeset 107769 b68455ccdd9a5b87035b71a64a653e307fb5b372
parent 107768 7c9af3e022dac973a22cd0c42b7a1d59a08774d8
child 107770 dd72607cee2f5cc820f71aeedd9976b2af8943df
push id82
push usershu@rfrn.org
push dateFri, 05 Oct 2012 13:20:22 +0000
reviewersbent
bugs775777
milestone18.0a1
Test for bug 775777. r=bent
ipc/ipdl/test/cxx/IPDLUnitTestUtils.h
ipc/ipdl/test/cxx/Makefile.in
ipc/ipdl/test/cxx/PTestActorPunning.ipdl
ipc/ipdl/test/cxx/PTestActorPunningPunned.ipdl
ipc/ipdl/test/cxx/PTestActorPunningSub.ipdl
ipc/ipdl/test/cxx/TestActorPunning.cpp
ipc/ipdl/test/cxx/TestActorPunning.h
ipc/ipdl/test/cxx/ipdl.mk
new file mode 100644
--- /dev/null
+++ b/ipc/ipdl/test/cxx/IPDLUnitTestUtils.h
@@ -0,0 +1,27 @@
+
+#ifndef mozilla__ipdltest_IPDLUnitTestUtils
+#define mozilla__ipdltest_IPDLUnitTestUtils 1
+
+namespace mozilla {
+namespace _ipdltest {
+
+struct Bad {};
+
+} // namespace _ipdltest
+} // namespace mozilla
+
+namespace IPC {
+
+template<>
+struct ParamTraits<mozilla::_ipdltest::Bad>
+{
+  typedef mozilla::_ipdltest::Bad paramType;
+
+  // Defined in TestActorPunning.cpp.
+  static void Write(Message* aMsg, const paramType& aParam);
+  static bool Read(const Message* aMsg, void** aIter, paramType* aResult);
+};
+
+} // namespace IPC
+
+#endif // mozilla__ipdltest_IPDLUnitTestUtils
--- a/ipc/ipdl/test/cxx/Makefile.in
+++ b/ipc/ipdl/test/cxx/Makefile.in
@@ -13,24 +13,26 @@ TOOL_DIRS += app
 
 MODULE = ipdlunittest
 
 EXPORTS_NAMESPACES = mozilla/_ipdltest
 EXPORTS_mozilla/_ipdltest =  \
   IPDLUnitTests.h  \
   IPDLUnitTestProcessChild.h  \
   IPDLUnitTestTypes.h \
+  IPDLUnitTestUtils.h \
   $(NULL)
 
 LIBRARY_NAME = $(MODULE)_s
 LIBXUL_LIBRARY = 1
 FORCE_STATIC_LIB = 1
 EXPORT_LIBRARY = 1
 
 IPDLTESTS = \
+  TestActorPunning \
   TestBlockChild \
   TestBridgeMain \
   TestCrashCleanup \
   TestDataStructures \
   TestDesc \
   TestFailedCtor \
   TestHangs \
   TestJSON \
new file mode 100644
--- /dev/null
+++ b/ipc/ipdl/test/cxx/PTestActorPunning.ipdl
@@ -0,0 +1,39 @@
+
+include protocol PTestActorPunningPunned;
+include protocol PTestActorPunningSub;
+include "mozilla/_ipdltest/IPDLUnitTestUtils.h";
+
+using mozilla::_ipdltest::Bad;
+
+namespace mozilla {
+namespace _ipdltest {
+
+protocol PTestActorPunning {
+    manages PTestActorPunningPunned;
+    manages PTestActorPunningSub;
+
+child:
+    Start();
+
+parent:
+    PTestActorPunningPunned();
+    PTestActorPunningSub();
+    Pun(PTestActorPunningSub a, Bad bad);
+    __delete__();
+
+
+state PING:
+    send Start goto CONSTRUCTING;
+
+state CONSTRUCTING:
+    recv PTestActorPunningPunned goto CONSTRUCTING;
+    recv PTestActorPunningSub goto CONSTRUCTING;
+    recv Pun goto DEAD;
+    // We never make it past this transition, --> error.
+
+state DEAD:
+    recv __delete__;
+};
+
+} // namespace mozilla
+} // namespace _ipdltest
new file mode 100644
--- /dev/null
+++ b/ipc/ipdl/test/cxx/PTestActorPunningPunned.ipdl
@@ -0,0 +1,15 @@
+
+include protocol PTestActorPunning;
+
+namespace mozilla {
+namespace _ipdltest {
+
+protocol PTestActorPunningPunned {
+    manager PTestActorPunning;
+
+child:
+    __delete__();
+};
+
+} // namespace mozilla
+} // namespace _ipdltes
new file mode 100644
--- /dev/null
+++ b/ipc/ipdl/test/cxx/PTestActorPunningSub.ipdl
@@ -0,0 +1,16 @@
+
+include protocol PTestActorPunning;
+
+namespace mozilla {
+namespace _ipdltest {
+
+protocol PTestActorPunningSub {
+    manager PTestActorPunning;
+
+child:
+    Bad();
+    __delete__();
+};
+
+} // namespace mozilla
+} // namespace _ipdltes
new file mode 100644
--- /dev/null
+++ b/ipc/ipdl/test/cxx/TestActorPunning.cpp
@@ -0,0 +1,131 @@
+#include "TestActorPunning.h"
+
+#include "IPDLUnitTests.h"      // fail etc.
+
+namespace mozilla {
+namespace _ipdltest {
+
+//-----------------------------------------------------------------------------
+// parent
+
+void
+TestActorPunningParent::Main()
+{
+    if (!SendStart())
+        fail("sending Start");
+}
+
+bool
+TestActorPunningParent::RecvPun(PTestActorPunningSubParent* a, const Bad& bad)
+{
+    if (a->SendBad())
+        fail("bad!");
+    fail("shouldn't have received this message in the first place");
+    return true;
+}
+
+PTestActorPunningPunnedParent*
+TestActorPunningParent::AllocPTestActorPunningPunned()
+{
+    return new TestActorPunningPunnedParent();
+}
+
+bool
+TestActorPunningParent::DeallocPTestActorPunningPunned(PTestActorPunningPunnedParent* a)
+{
+    delete a;
+    return true;
+}
+
+PTestActorPunningSubParent*
+TestActorPunningParent::AllocPTestActorPunningSub()
+{
+    return new TestActorPunningSubParent();
+}
+
+bool
+TestActorPunningParent::DeallocPTestActorPunningSub(PTestActorPunningSubParent* a)
+{
+    delete a;
+    return true;
+}
+
+//-----------------------------------------------------------------------------
+// child
+
+PTestActorPunningPunnedChild*
+TestActorPunningChild::AllocPTestActorPunningPunned()
+{
+    return new TestActorPunningPunnedChild();
+}
+
+bool
+TestActorPunningChild::DeallocPTestActorPunningPunned(PTestActorPunningPunnedChild*)
+{
+    fail("should have died by now");
+    return true;
+}
+
+PTestActorPunningSubChild*
+TestActorPunningChild::AllocPTestActorPunningSub()
+{
+    return new TestActorPunningSubChild();
+}
+
+bool
+TestActorPunningChild::DeallocPTestActorPunningSub(PTestActorPunningSubChild*)
+{
+    fail("should have died by now");
+    return true;
+}
+
+bool
+TestActorPunningChild::RecvStart()
+{
+    SendPTestActorPunningSubConstructor();
+    SendPTestActorPunningPunnedConstructor();
+    PTestActorPunningSubChild* a = SendPTestActorPunningSubConstructor();
+    // We can't assert whether this succeeds or fails, due to race
+    // conditions.
+    SendPun(a, Bad());
+    return true;
+}
+
+bool
+TestActorPunningSubChild::RecvBad()
+{
+    fail("things are going really badly right now");
+    return true;
+}
+
+
+} // namespace _ipdltest
+} // namespace mozilla
+
+namespace IPC {
+using namespace mozilla::_ipdltest;
+using namespace mozilla::ipc;
+
+/*static*/ void
+ParamTraits<Bad>::Write(Message* aMsg, const paramType& aParam)
+{
+    char* ptr = aMsg->BeginWriteData(4);
+    ptr -= intptr_t(sizeof(int));
+    ptr -= intptr_t(sizeof(ActorHandle));
+    ActorHandle* ah = reinterpret_cast<ActorHandle*>(ptr);
+    if (ah->mId != -3)
+        fail("guessed wrong offset (value is %d, should be -3)", ah->mId);
+    ah->mId = -2;
+}
+
+/*static*/ bool
+ParamTraits<Bad>::Read(const Message* aMsg, void** aIter, paramType* aResult)
+{
+    const char* ptr;
+    int len;
+    aMsg->ReadData(aIter, &ptr, &len);
+    return true;
+}
+
+} // namespace IPC
+
new file mode 100644
--- /dev/null
+++ b/ipc/ipdl/test/cxx/TestActorPunning.h
@@ -0,0 +1,106 @@
+#ifndef mozilla__ipdltest_TestActorPunning_h
+#define mozilla__ipdltest_TestActorPunning_h 1
+
+#include "mozilla/_ipdltest/IPDLUnitTests.h"
+
+#include "mozilla/_ipdltest/PTestActorPunningParent.h"
+#include "mozilla/_ipdltest/PTestActorPunningPunnedParent.h"
+#include "mozilla/_ipdltest/PTestActorPunningSubParent.h"
+#include "mozilla/_ipdltest/PTestActorPunningChild.h"
+#include "mozilla/_ipdltest/PTestActorPunningPunnedChild.h"
+#include "mozilla/_ipdltest/PTestActorPunningSubChild.h"
+
+namespace mozilla {
+namespace _ipdltest {
+
+
+class TestActorPunningParent :
+    public PTestActorPunningParent
+{
+public:
+    static bool RunTestInProcesses() { return true; }
+    static bool RunTestInThreads() { return false; }
+
+    void Main();
+
+protected:
+    PTestActorPunningPunnedParent* AllocPTestActorPunningPunned() MOZ_OVERRIDE;
+    bool DeallocPTestActorPunningPunned(PTestActorPunningPunnedParent* a) MOZ_OVERRIDE;
+
+    PTestActorPunningSubParent* AllocPTestActorPunningSub() MOZ_OVERRIDE;
+    bool DeallocPTestActorPunningSub(PTestActorPunningSubParent* a) MOZ_OVERRIDE;
+
+    virtual bool RecvPun(PTestActorPunningSubParent* a, const Bad& bad) MOZ_OVERRIDE;
+
+    virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE
+    {
+        if (NormalShutdown == why)
+            fail("should have died from error!");  
+        passed("ok");
+        QuitParent();
+    }
+};
+
+class TestActorPunningPunnedParent :
+    public PTestActorPunningPunnedParent
+{
+public:
+    TestActorPunningPunnedParent() {}
+    virtual ~TestActorPunningPunnedParent() {}
+};
+
+class TestActorPunningSubParent :
+    public PTestActorPunningSubParent
+{
+public:
+    TestActorPunningSubParent() {}
+    virtual ~TestActorPunningSubParent() {}
+};
+
+
+class TestActorPunningChild :
+    public PTestActorPunningChild
+{
+public:
+    TestActorPunningChild() {}
+    virtual ~TestActorPunningChild() {}
+
+protected:
+    PTestActorPunningPunnedChild* AllocPTestActorPunningPunned() MOZ_OVERRIDE;
+    bool DeallocPTestActorPunningPunned(PTestActorPunningPunnedChild* a) MOZ_OVERRIDE;
+
+    PTestActorPunningSubChild* AllocPTestActorPunningSub() MOZ_OVERRIDE;
+    bool DeallocPTestActorPunningSub(PTestActorPunningSubChild* a) MOZ_OVERRIDE;
+
+    virtual bool RecvStart() MOZ_OVERRIDE;
+
+    virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE
+    {
+        fail("should have been killed off!");
+    }
+};
+
+class TestActorPunningPunnedChild :
+    public PTestActorPunningPunnedChild
+{
+public:
+    TestActorPunningPunnedChild() {}
+    virtual ~TestActorPunningPunnedChild() {}
+};
+
+class TestActorPunningSubChild :
+    public PTestActorPunningSubChild
+{
+public:
+    TestActorPunningSubChild() {}
+    virtual ~TestActorPunningSubChild() {}
+
+    virtual bool RecvBad() MOZ_OVERRIDE;
+};
+
+
+} // namespace _ipdltest
+} // namespace mozilla
+
+
+#endif // ifndef mozilla__ipdltest_TestActorPunning_h
--- a/ipc/ipdl/test/cxx/ipdl.mk
+++ b/ipc/ipdl/test/cxx/ipdl.mk
@@ -1,9 +1,12 @@
 IPDLSRCS =					\
+  PTestActorPunning.ipdl			\
+  PTestActorPunningPunned.ipdl			\
+  PTestActorPunningSub.ipdl			\
   PTestBlockChild.ipdl				\
   PTestBridgeMain.ipdl				\
   PTestBridgeSub.ipdl				\
   PTestBridgeMainSub.ipdl			\
   PTestCrashCleanup.ipdl			\
   PTestDataStructures.ipdl			\
   PTestDataStructuresCommon.ipdlh		\
   PTestDataStructuresSub.ipdl			\