summaryrefslogtreecommitdiffstats
path: root/ipc/ipdl/test/cxx/TestShutdown.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ipc/ipdl/test/cxx/TestShutdown.cpp')
-rw-r--r--ipc/ipdl/test/cxx/TestShutdown.cpp185
1 files changed, 185 insertions, 0 deletions
diff --git a/ipc/ipdl/test/cxx/TestShutdown.cpp b/ipc/ipdl/test/cxx/TestShutdown.cpp
new file mode 100644
index 0000000000..502695bd88
--- /dev/null
+++ b/ipc/ipdl/test/cxx/TestShutdown.cpp
@@ -0,0 +1,185 @@
+#include "TestShutdown.h"
+
+namespace mozilla {
+namespace _ipdltest {
+
+//-----------------------------------------------------------------------------
+// Parent side
+void TestShutdownParent::Main() {
+ if (!SendStart()) fail("sending Start()");
+}
+
+void TestShutdownParent::ActorDestroy(ActorDestroyReason why) {
+ if (AbnormalShutdown != why) fail("should have ended test with crash!");
+
+ passed("ok");
+
+ QuitParent();
+}
+
+void TestShutdownSubParent::ActorDestroy(ActorDestroyReason why) {
+ if (Manager()->ManagedPTestShutdownSubParent().Count() == 0)
+ fail("manager should still have managees!");
+
+ if (mExpectCrash && AbnormalShutdown != why)
+ fail("expected crash!");
+ else if (!mExpectCrash && AbnormalShutdown == why)
+ fail("wasn't expecting crash!");
+
+ if (mExpectCrash && 0 == ManagedPTestShutdownSubsubParent().Count())
+ fail("expected to *still* have kids");
+}
+
+void TestShutdownSubsubParent::ActorDestroy(ActorDestroyReason why) {
+ if (Manager()->ManagedPTestShutdownSubsubParent().Count() == 0)
+ fail("manager should still have managees!");
+
+ if (mExpectParentDeleted && AncestorDeletion != why)
+ fail("expected ParentDeleted == why");
+ else if (!mExpectParentDeleted && AncestorDeletion == why)
+ fail("wasn't expecting parent delete");
+}
+
+//-----------------------------------------------------------------------------
+// Child side
+
+mozilla::ipc::IPCResult TestShutdownChild::RecvStart() {
+ // test 1: alloc some actors and subactors, delete in
+ // managee-before-manager order
+ {
+ bool expectCrash = false, expectParentDeleted = false;
+
+ PTestShutdownSubChild* c1 = SendPTestShutdownSubConstructor(expectCrash);
+ if (!c1) fail("problem sending ctor");
+
+ PTestShutdownSubChild* c2 = SendPTestShutdownSubConstructor(expectCrash);
+ if (!c2) fail("problem sending ctor");
+
+ PTestShutdownSubsubChild* c1s1 =
+ c1->SendPTestShutdownSubsubConstructor(expectParentDeleted);
+ if (!c1s1) fail("problem sending ctor");
+ PTestShutdownSubsubChild* c1s2 =
+ c1->SendPTestShutdownSubsubConstructor(expectParentDeleted);
+ if (!c1s2) fail("problem sending ctor");
+
+ PTestShutdownSubsubChild* c2s1 =
+ c2->SendPTestShutdownSubsubConstructor(expectParentDeleted);
+ if (!c2s1) fail("problem sending ctor");
+ PTestShutdownSubsubChild* c2s2 =
+ c2->SendPTestShutdownSubsubConstructor(expectParentDeleted);
+ if (!c2s2) fail("problem sending ctor");
+
+ if (!PTestShutdownSubsubChild::Send__delete__(c1s1))
+ fail("problem sending dtor");
+ if (!PTestShutdownSubsubChild::Send__delete__(c1s2))
+ fail("problem sending dtor");
+ if (!PTestShutdownSubsubChild::Send__delete__(c2s1))
+ fail("problem sending dtor");
+ if (!PTestShutdownSubsubChild::Send__delete__(c2s2))
+ fail("problem sending dtor");
+
+ if (!c1->CallStackFrame()) fail("problem creating dummy stack frame");
+ if (!c2->CallStackFrame()) fail("problem creating dummy stack frame");
+ }
+
+ // test 2: alloc some actors and subactors, delete managers first
+ {
+ bool expectCrash = false, expectParentDeleted = true;
+
+ PTestShutdownSubChild* c1 = SendPTestShutdownSubConstructor(expectCrash);
+ if (!c1) fail("problem sending ctor");
+
+ PTestShutdownSubChild* c2 = SendPTestShutdownSubConstructor(expectCrash);
+ if (!c2) fail("problem sending ctor");
+
+ PTestShutdownSubsubChild* c1s1 =
+ c1->SendPTestShutdownSubsubConstructor(expectParentDeleted);
+ if (!c1s1) fail("problem sending ctor");
+ PTestShutdownSubsubChild* c1s2 =
+ c1->SendPTestShutdownSubsubConstructor(expectParentDeleted);
+ if (!c1s2) fail("problem sending ctor");
+
+ PTestShutdownSubsubChild* c2s1 =
+ c2->SendPTestShutdownSubsubConstructor(expectParentDeleted);
+ if (!c2s1) fail("problem sending ctor");
+ PTestShutdownSubsubChild* c2s2 =
+ c2->SendPTestShutdownSubsubConstructor(expectParentDeleted);
+ if (!c2s2) fail("problem sending ctor");
+
+ // delete parents without deleting kids
+ if (!c1->CallStackFrame()) fail("problem creating dummy stack frame");
+ if (!c2->CallStackFrame()) fail("problem creating dummy stack frame");
+ }
+
+ // test 3: alloc some actors and subactors, then crash
+ {
+ bool expectCrash = true, expectParentDeleted = false;
+
+ PTestShutdownSubChild* c1 = SendPTestShutdownSubConstructor(expectCrash);
+ if (!c1) fail("problem sending ctor");
+
+ PTestShutdownSubChild* c2 = SendPTestShutdownSubConstructor(expectCrash);
+ if (!c2) fail("problem sending ctor");
+
+ PTestShutdownSubsubChild* c1s1 =
+ c1->SendPTestShutdownSubsubConstructor(expectParentDeleted);
+ if (!c1s1) fail("problem sending ctor");
+ PTestShutdownSubsubChild* c1s2 =
+ c1->SendPTestShutdownSubsubConstructor(expectParentDeleted);
+ if (!c1s2) fail("problem sending ctor");
+
+ PTestShutdownSubsubChild* c2s1 =
+ c2->SendPTestShutdownSubsubConstructor(expectParentDeleted);
+ if (!c2s1) fail("problem sending ctor");
+ PTestShutdownSubsubChild* c2s2 =
+ c2->SendPTestShutdownSubsubConstructor(expectParentDeleted);
+ if (!c2s2) fail("problem sending ctor");
+
+ // make sure the ctors have been processed by the other side;
+ // the write end of the socket may temporarily be unwriteable
+ if (!SendSync()) fail("can't synchronize with parent");
+
+ // "crash", but without tripping tinderbox assert/abort
+ // detectors
+ _exit(0);
+ }
+}
+
+void TestShutdownChild::ActorDestroy(ActorDestroyReason why) {
+ fail("hey wait ... we should have crashed!");
+}
+
+mozilla::ipc::IPCResult TestShutdownSubChild::AnswerStackFrame() {
+ if (!PTestShutdownSubChild::Send__delete__(this))
+ fail("problem sending dtor");
+
+ // WATCH OUT! |this| has just deleted
+
+ return IPC_OK();
+}
+
+void TestShutdownSubChild::ActorDestroy(ActorDestroyReason why) {
+ if (Manager()->ManagedPTestShutdownSubChild().Count() == 0)
+ fail("manager should still have managees!");
+
+ if (mExpectCrash && AbnormalShutdown != why)
+ fail("expected crash!");
+ else if (!mExpectCrash && AbnormalShutdown == why)
+ fail("wasn't expecting crash!");
+
+ if (mExpectCrash && 0 == ManagedPTestShutdownSubsubChild().Count())
+ fail("expected to *still* have kids");
+}
+
+void TestShutdownSubsubChild::ActorDestroy(ActorDestroyReason why) {
+ if (Manager()->ManagedPTestShutdownSubsubChild().Count() == 0)
+ fail("manager should still have managees!");
+
+ if (mExpectParentDeleted && AncestorDeletion != why)
+ fail("expected ParentDeleted == why");
+ else if (!mExpectParentDeleted && AncestorDeletion == why)
+ fail("wasn't expecting parent delete");
+}
+
+} // namespace _ipdltest
+} // namespace mozilla