summaryrefslogtreecommitdiffstats
path: root/ipc/ipdl/test/gtest/IPDLUnitTest.h
diff options
context:
space:
mode:
Diffstat (limited to 'ipc/ipdl/test/gtest/IPDLUnitTest.h')
-rw-r--r--ipc/ipdl/test/gtest/IPDLUnitTest.h79
1 files changed, 79 insertions, 0 deletions
diff --git a/ipc/ipdl/test/gtest/IPDLUnitTest.h b/ipc/ipdl/test/gtest/IPDLUnitTest.h
new file mode 100644
index 0000000000..f4548b508c
--- /dev/null
+++ b/ipc/ipdl/test/gtest/IPDLUnitTest.h
@@ -0,0 +1,79 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla__ipdltest_IPDLUnitTest_h
+#define mozilla__ipdltest_IPDLUnitTest_h
+
+#include "mozilla/_ipdltest/IPDLUnitTestChild.h"
+#include "mozilla/_ipdltest/IPDLUnitTestParent.h"
+#include "mozilla/ipc/ProtocolUtils.h"
+
+namespace mozilla::_ipdltest {
+
+// Should be called from static constructors to register a child actor
+// constructor so that it can be called from the child process.
+const char* RegisterAllocChildActor(
+ const char* aName, mozilla::ipc::IToplevelProtocol* (*aFunc)());
+
+// Internal helper type used to declare IPDL tests.
+class IPDLTestHelper {
+ public:
+ void TestWrapper(bool aCrossProcess);
+ virtual const char* GetName() = 0;
+ virtual ipc::IToplevelProtocol* GetActor() = 0;
+ virtual void TestBody() = 0;
+};
+
+#define IPDL_TEST_CLASS_NAME_(actorname) IPDL_TEST_##actorname
+
+#define IPDL_TEST_HEAD_(actorname) \
+ class IPDL_TEST_CLASS_NAME_(actorname) \
+ : public ::mozilla::_ipdltest::IPDLTestHelper { \
+ public: \
+ IPDL_TEST_CLASS_NAME_(actorname)() : mActor(new actorname##Parent) {} \
+ \
+ private: \
+ void TestBody() override; \
+ const char* GetName() override { return sName; }; \
+ actorname##Parent* GetActor() override { return mActor; }; \
+ \
+ RefPtr<actorname##Parent> mActor; \
+ static const char* sName; \
+ }; \
+ const char* IPDL_TEST_CLASS_NAME_(actorname)::sName = \
+ ::mozilla::_ipdltest::RegisterAllocChildActor( \
+ #actorname, []() -> ::mozilla::ipc::IToplevelProtocol* { \
+ return new actorname##Child; \
+ });
+
+#define IPDL_TEST_DECL_(testgroup, actorname, crossprocess) \
+ TEST(testgroup, actorname) \
+ { \
+ IPDL_TEST_CLASS_NAME_(actorname) test; \
+ test.TestWrapper(crossprocess); \
+ }
+
+#define IPDL_TEST_BODY_SEGUE_(actorname) \
+ void IPDL_TEST_CLASS_NAME_(actorname)::TestBody()
+
+// Declare a basic IPDL unit test which will be run in both both cross-thread
+// and cross-process configurations. The actor `actorname` will be instantiated
+// by default-constructing the parent & child actors in the relevant processes,
+// and the test block will be executed, with `mActor` being a pointer to the
+// parent actor. The test is asynchronous, and will end when the IPDL connection
+// between the created actors is destroyed.
+//
+// GTest assertions fired in the child process will be relayed to the parent
+// process, and should generally function correctly.
+#define IPDL_TEST(actorname) \
+ IPDL_TEST_HEAD_(actorname) \
+ IPDL_TEST_DECL_(IPDLTest_CrossProcess, actorname, true) \
+ IPDL_TEST_DECL_(IPDLTest_CrossThread, actorname, false) \
+ IPDL_TEST_BODY_SEGUE_(actorname)
+
+} // namespace mozilla::_ipdltest
+
+#endif // mozilla__ipdltest_IPDLUnitTest_h