IPDLUnitTest.h (4954B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 5 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef mozilla__ipdltest_IPDLUnitTest_h 8 #define mozilla__ipdltest_IPDLUnitTest_h 9 10 #include "mozilla/_ipdltest/IPDLUnitTestChild.h" 11 #include "mozilla/_ipdltest/IPDLUnitTestParent.h" 12 #include "mozilla/ipc/ProtocolUtils.h" 13 14 namespace mozilla::_ipdltest { 15 16 // Should be called from static constructors to register a child actor 17 // constructor so that it can be called from the child process. 18 const char* RegisterAllocChildActor( 19 const char* aName, mozilla::ipc::IToplevelProtocol* (*aFunc)()); 20 21 // Internal helper type used to declare IPDL tests. 22 class IPDLTestHelper { 23 public: 24 void TestWrapper(bool aCrossProcess); 25 virtual const char* GetName() = 0; 26 virtual ipc::IToplevelProtocol* GetActor() = 0; 27 virtual void TestBody() = 0; 28 }; 29 30 #define IPDL_TEST_CLASS_NAME_(actorname, ...) IPDL_TEST_##actorname##__VA_ARGS__ 31 32 #define IPDL_TEST_HEAD_(actorname, ...) \ 33 class IPDL_TEST_CLASS_NAME_(actorname, ##__VA_ARGS__) \ 34 : public ::mozilla::_ipdltest::IPDLTestHelper { \ 35 public: \ 36 IPDL_TEST_CLASS_NAME_(actorname, ##__VA_ARGS__) \ 37 () : mActor(new actorname##Parent) {} \ 38 \ 39 private: \ 40 void TestBody() override; \ 41 const char* GetName() override { return sName; }; \ 42 actorname##Parent* GetActor() override { return mActor; }; \ 43 \ 44 RefPtr<actorname##Parent> mActor; \ 45 static const char* sName; \ 46 }; \ 47 const char* IPDL_TEST_CLASS_NAME_(actorname, ##__VA_ARGS__)::sName = \ 48 ::mozilla::_ipdltest::RegisterAllocChildActor( \ 49 #actorname, []() -> ::mozilla::ipc::IToplevelProtocol* { \ 50 return new actorname##Child; \ 51 }); 52 53 #define IPDL_TEST_DECL_CROSSPROCESS_(actorname, ...) \ 54 TEST(IPDLTest_CrossProcess, actorname##__VA_ARGS__) \ 55 { \ 56 IPDL_TEST_CLASS_NAME_(actorname, ##__VA_ARGS__) test; \ 57 test.TestWrapper(true); \ 58 } 59 60 #define IPDL_TEST_DECL_CROSSTHREAD_(actorname, ...) \ 61 TEST(IPDLTest_CrossThread, actorname##__VA_ARGS__) \ 62 { \ 63 IPDL_TEST_CLASS_NAME_(actorname, ##__VA_ARGS__) test; \ 64 test.TestWrapper(false); \ 65 } 66 67 #define IPDL_TEST_DECL_ANY_(actorname, ...) \ 68 IPDL_TEST_DECL_CROSSPROCESS_(actorname, ##__VA_ARGS__) \ 69 IPDL_TEST_DECL_CROSSTHREAD_(actorname, ##__VA_ARGS__) 70 71 #define IPDL_TEST_BODY_SEGUE_(actorname, ...) \ 72 void IPDL_TEST_CLASS_NAME_(actorname, ##__VA_ARGS__)::TestBody() 73 74 // Declare an IPDL unit test. The `mode` should be set to either `CROSSTHREAD`, 75 // `CROSSPROCESS`, or `ANY` to run in the selected configuration(s). The actor 76 // `actorname` will be instantiated by default-constructing the parent & child 77 // actors in the relevant processes, and the test block will be executed, with 78 // `mActor` being a pointer to the parent actor. The test is asynchronous, and 79 // will end when the IPDL connection between the created actors is destroyed. 80 // `aCrossProcess` will indicate whether the test is running cross-process 81 // (true) or cross-thread (false). 82 // 83 // You can optionally pass a single additional argument which provides a 84 // `testname`, which will be appended to `actorname` as the full GTest test 85 // name. It should be of the form usually passed to the `TEST` gtest macro (an 86 // identifier). 87 // 88 // GTest assertions fired in the child process will be relayed to the parent 89 // process, and should generally function correctly. 90 #define IPDL_TEST_ON(mode, actorname, ...) \ 91 IPDL_TEST_HEAD_(actorname, ##__VA_ARGS__) \ 92 IPDL_TEST_DECL_##mode##_(actorname, ##__VA_ARGS__) \ 93 IPDL_TEST_BODY_SEGUE_(actorname, ##__VA_ARGS__) 94 95 // Declare an IPDL unit test that will run in both cross-thread and 96 // cross-process configurations. See the documentation of IPDL_TEST_ON for more 97 // info. 98 #define IPDL_TEST(actorname, ...) IPDL_TEST_ON(ANY, actorname, ##__VA_ARGS__) 99 100 } // namespace mozilla::_ipdltest 101 102 #endif // mozilla__ipdltest_IPDLUnitTest_h