ipc/ipdl/test/cxx/IPDLUnitTests.template.cpp

Wed, 31 Dec 2014 13:27:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 13:27:57 +0100
branch
TOR_BUG_3246
changeset 6
8bccb770b82d
permissions
-rw-r--r--

Ignore runtime configuration files generated during quality assurance.

     1 //
     2 // Autogenerated from Python template.  Hands off.
     3 //
     5 #include <stdlib.h>
     6 #include <string.h>
     8 #include "IPDLUnitTests.h"
    10 #include "base/command_line.h"
    11 #include "base/string_util.h"
    12 #include "base/thread.h"
    14 #include "nsRegion.h"
    16 #include "IPDLUnitTestSubprocess.h"
    18 //-----------------------------------------------------------------------------
    19 //===== TEMPLATED =====
    20 ${INCLUDES}
    21 //-----------------------------------------------------------------------------
    23 using namespace base;
    24 using namespace std;
    26 namespace mozilla {
    27 namespace _ipdltest {
    29 void* gParentActor;
    30 IPDLUnitTestSubprocess* gSubprocess;
    32 void* gChildActor;
    34 // Note: in threaded mode, this will be non-null (for both parent and
    35 // child, since they share one set of globals).  
    36 Thread* gChildThread;
    37 MessageLoop *gParentMessageLoop;
    38 bool gParentDone;
    39 bool gChildDone;
    41 //-----------------------------------------------------------------------------
    42 // data/functions accessed by both parent and child processes
    44 char* gIPDLUnitTestName = nullptr;
    46 const char* const
    47 IPDLUnitTestName()
    48 {
    49     if (!gIPDLUnitTestName) {
    50 #if defined(OS_WIN)
    51         vector<wstring> args =
    52             CommandLine::ForCurrentProcess()->GetLooseValues();
    53         gIPDLUnitTestName = ::strdup(WideToUTF8(args[0]).c_str());
    54 #elif defined(OS_POSIX)
    55         vector<string> argv = CommandLine::ForCurrentProcess()->argv();
    56         gIPDLUnitTestName = ::moz_xstrdup(argv[1].c_str());
    57 #else
    58 #  error Sorry
    59 #endif
    60     }
    61     return gIPDLUnitTestName;
    62 }
    64 } // namespace _ipdltest
    65 } // namespace mozilla
    68 namespace {
    70 enum IPDLUnitTestType {
    71     NoneTest = 0,
    73 //-----------------------------------------------------------------------------
    74 //===== TEMPLATED =====
    75 ${ENUM_VALUES}
    77     LastTest = ${LAST_ENUM}
    78 //-----------------------------------------------------------------------------
    79 };
    82 IPDLUnitTestType
    83 IPDLUnitTestFromString(const char* const aString)
    84 {
    85     if (!aString)
    86         return static_cast<IPDLUnitTestType>(0);
    87 //-----------------------------------------------------------------------------
    88 //===== TEMPLATED =====
    89 ${STRING_TO_ENUMS}
    90 //-----------------------------------------------------------------------------
    91     else
    92         return static_cast<IPDLUnitTestType>(0);
    93 }
    96 const char* const
    97 IPDLUnitTestToString(IPDLUnitTestType aTest)
    98 {
    99     switch (aTest) {
   100 //-----------------------------------------------------------------------------
   101 //===== TEMPLATED =====
   102 ${ENUM_TO_STRINGS}
   103 //-----------------------------------------------------------------------------
   105     default:
   106         return nullptr;
   107     }
   108 }
   111 IPDLUnitTestType
   112 IPDLUnitTest()
   113 {
   114     return IPDLUnitTestFromString(::mozilla::_ipdltest::IPDLUnitTestName());
   115 }
   118 } // namespace <anon>
   121 //-----------------------------------------------------------------------------
   122 // parent process only
   124 namespace mozilla {
   125 namespace _ipdltest {
   127 void
   128 DeferredParentShutdown();
   130 void
   131 IPDLUnitTestThreadMain(char *testString);
   133 void
   134 IPDLUnitTestMain(void* aData)
   135 {
   136     char* testString = reinterpret_cast<char*>(aData);
   138     // Check if we are to run the test using threads instead:
   139     const char *prefix = "thread:";
   140     const int prefixLen = strlen(prefix);
   141     if (!strncmp(testString, prefix, prefixLen)) {
   142         IPDLUnitTestThreadMain(testString + prefixLen);
   143         return;
   144     }
   146     IPDLUnitTestType test = IPDLUnitTestFromString(testString);
   147     if (!test) {
   148         // use this instead of |fail()| because we don't know what the test is
   149         fprintf(stderr, MOZ_IPDL_TESTFAIL_LABEL "| %s | unknown unit test %s\n",
   150                 "<--->", testString);
   151         NS_RUNTIMEABORT("can't continue");
   152     }
   153     gIPDLUnitTestName = testString;
   155     // Check whether this test is enabled for processes:
   156     switch (test) {
   157 //-----------------------------------------------------------------------------
   158 //===== TEMPLATED =====
   159 ${PARENT_ENABLED_CASES_PROC}
   160 //-----------------------------------------------------------------------------
   162     default:
   163         fail("not reached");
   164         return;                 // unreached
   165     }
   167     printf(MOZ_IPDL_TESTINFO_LABEL "| running test | %s\n", gIPDLUnitTestName);
   169     std::vector<std::string> testCaseArgs;
   170     testCaseArgs.push_back(testString);
   172     gSubprocess = new IPDLUnitTestSubprocess();
   173     if (!gSubprocess->SyncLaunch(testCaseArgs))
   174         fail("problem launching subprocess");
   176     IPC::Channel* transport = gSubprocess->GetChannel();
   177     if (!transport)
   178         fail("no transport");
   180     base::ProcessHandle child = gSubprocess->GetChildProcessHandle();
   182     switch (test) {
   183 //-----------------------------------------------------------------------------
   184 //===== TEMPLATED =====
   185 ${PARENT_MAIN_CASES_PROC}
   186 //-----------------------------------------------------------------------------
   188     default:
   189         fail("not reached");
   190         return;                 // unreached
   191     }
   192 }
   194 void
   195 IPDLUnitTestThreadMain(char *testString)
   196 {
   197     IPDLUnitTestType test = IPDLUnitTestFromString(testString);
   198     if (!test) {
   199         // use this instead of |fail()| because we don't know what the test is
   200         fprintf(stderr, MOZ_IPDL_TESTFAIL_LABEL "| %s | unknown unit test %s\n",
   201                 "<--->", testString);
   202         NS_RUNTIMEABORT("can't continue");
   203     }
   204     gIPDLUnitTestName = testString;
   206     // Check whether this test is enabled for threads:
   207     switch (test) {
   208 //-----------------------------------------------------------------------------
   209 //===== TEMPLATED =====
   210 ${PARENT_ENABLED_CASES_THREAD}
   211 //-----------------------------------------------------------------------------
   213     default:
   214         fail("not reached");
   215         return;                 // unreached
   216     }
   218     printf(MOZ_IPDL_TESTINFO_LABEL "| running test | %s\n", gIPDLUnitTestName);
   220     std::vector<std::string> testCaseArgs;
   221     testCaseArgs.push_back(testString);
   223     gChildThread = new Thread("ParentThread");
   224     if (!gChildThread->Start())
   225         fail("starting parent thread");
   227     gParentMessageLoop = MessageLoop::current();
   228     MessageLoop *childMessageLoop = gChildThread->message_loop();
   230     switch (test) {
   231 //-----------------------------------------------------------------------------
   232 //===== TEMPLATED =====
   233 ${PARENT_MAIN_CASES_THREAD}
   234 //-----------------------------------------------------------------------------
   236     default:
   237         fail("not reached");
   238         return;                 // unreached
   239     }
   240 }
   242 void
   243 DeleteParentActor()
   244 {
   245     if (!gParentActor)
   246         return;
   248     switch (IPDLUnitTest()) {
   249 //-----------------------------------------------------------------------------
   250 //===== TEMPLATED =====
   251 ${PARENT_DELETE_CASES}
   252 //-----------------------------------------------------------------------------
   253     default:  ::mozilla::_ipdltest::fail("???");
   254     }
   255 }
   257 void
   258 QuitXPCOM()
   259 {
   260   DeleteParentActor();
   262   static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
   263   nsCOMPtr<nsIAppShell> appShell (do_GetService(kAppShellCID));
   264   appShell->Exit();
   265 }
   267 void
   268 DeleteSubprocess(MessageLoop* uiLoop)
   269 {
   270   // pong to QuitXPCOM
   271   delete gSubprocess;
   272   uiLoop->PostTask(FROM_HERE, NewRunnableFunction(QuitXPCOM));
   273 }
   275 void
   276 DeferredParentShutdown()
   277 {
   278     // ping to DeleteSubprocess
   279     XRE_GetIOMessageLoop()->PostTask(
   280         FROM_HERE,
   281         NewRunnableFunction(DeleteSubprocess, MessageLoop::current()));
   282 }
   284 void 
   285 TryThreadedShutdown()
   286 {
   287     // Stop if either: 
   288     // - the child has not finished, 
   289     // - the parent has not finished,
   290     // - or this code has already executed.
   291     // Remember: this TryThreadedShutdown() task is enqueued
   292     // by both parent and child (though always on parent's msg loop).
   293     if (!gChildDone || !gParentDone || !gChildThread)
   294         return;
   296     delete gChildThread;
   297     gChildThread = 0;
   298     DeferredParentShutdown();
   299 }
   301 void 
   302 ChildCompleted()
   303 {
   304     // Executes on the parent message loop once child has completed.
   305     gChildDone = true;
   306     TryThreadedShutdown();
   307 }
   309 void
   310 QuitParent()
   311 {
   312     if (gChildThread) {
   313         gParentDone = true;
   314         MessageLoop::current()->PostTask(
   315             FROM_HERE, NewRunnableFunction(TryThreadedShutdown));
   316     } else {
   317         // defer "real" shutdown to avoid *Channel::Close() racing with the
   318         // deletion of the subprocess
   319         MessageLoop::current()->PostTask(
   320             FROM_HERE, NewRunnableFunction(DeferredParentShutdown));
   321     }
   322 }
   324 void
   325 QuitChild()
   326 {
   327     if (gChildThread) { // Threaded-mode test
   328         gParentMessageLoop->PostTask(
   329             FROM_HERE, NewRunnableFunction(ChildCompleted));
   330     } else { // Process-mode test
   331         XRE_ShutdownChildProcess();
   332     }
   333 }
   335 } // namespace _ipdltest
   336 } // namespace mozilla
   339 //-----------------------------------------------------------------------------
   340 // child process only
   342 namespace mozilla {
   343 namespace _ipdltest {
   345 void
   346 DeleteChildActor()
   347 {
   348     if (!gChildActor)
   349         return;
   351     switch (IPDLUnitTest()) {
   352 //-----------------------------------------------------------------------------
   353 //===== TEMPLATED =====
   354 ${CHILD_DELETE_CASES}
   355 //-----------------------------------------------------------------------------
   356     default:  ::mozilla::_ipdltest::fail("???");
   357     }
   358 }
   360 void
   361 IPDLUnitTestChildInit(IPC::Channel* transport,
   362                       base::ProcessHandle parent,
   363                       MessageLoop* worker)
   364 {
   365     if (atexit(DeleteChildActor))
   366         fail("can't install atexit() handler");
   368     switch (IPDLUnitTest()) {
   369 //-----------------------------------------------------------------------------
   370 //===== TEMPLATED =====
   371 ${CHILD_INIT_CASES}
   372 //-----------------------------------------------------------------------------
   374     default:
   375         fail("not reached");
   376         return;                 // unreached
   377     }
   378 }
   380 } // namespace _ipdltest
   381 } // namespace mozilla

mercurial