コード例 #1
0
ファイル: tstRTIsoFs.cpp プロジェクト: svn2github/virtualbox
int main(int argc, char **argv)
{
    RTTEST hTest;
    RTEXITCODE rcExit = RTTestInitExAndCreate(argc, &argv, 0 /*fRtInit*/, "tstRTIsoFs", &hTest);
    if (rcExit != RTEXITCODE_SUCCESS)
        return rcExit;
    if (argc <= 1)
        return RTTestSkipAndDestroy(hTest, "no input");

    /*
     * First argument is the ISO to open.
     */
    RTISOFSFILE IsoFs;
    int rc = RTIsoFsOpen(&IsoFs, argv[1]);
    if (RT_SUCCESS(rc))
    {
        /*
         * Remaining arguments specifies files in the ISO that we wish information
         * about and optionally extract.
         */
        for (int i = 2; i < argc; i++)
        {
            char *pszFile = argv[i];
            char  chSaved = 0;
            char *pszDst  = strchr(pszFile, '=');
            if (pszDst)
            {
                chSaved = *pszDst;
                *pszDst = '\0';
            }

            uint32_t    offFile = UINT32_MAX / 2;
            size_t      cbFile  = UINT32_MAX / 2;
            rc = RTIsoFsGetFileInfo(&IsoFs, pszFile, &offFile, &cbFile);
            if (RT_SUCCESS(rc))
            {
                RTTestPrintf(hTest, RTTESTLVL_ALWAYS, "%s: %u bytes at %#x\n", pszFile, (uint32_t)cbFile, offFile);
                if (pszDst)
                {
                    rc = RTIsoFsExtractFile(&IsoFs, pszFile, pszDst);
                    if (RT_SUCCESS(rc))
                        RTTestPrintf(hTest, RTTESTLVL_ALWAYS, "%s: saved as '%s'.\n", pszFile, pszDst);
                    else
                        RTTestFailed(hTest, "RTIsoFsExtractFile failed to extract '%s' to '%s': %Rrc", pszFile, pszDst, rc);
                }
            }
            else
                RTTestFailed(hTest, "RTIsoFsGetFileInfo failed for '%s': %Rrc", pszFile, rc);

            if (pszDst)
                pszDst[-1] = chSaved;
        }

        RTIsoFsClose(&IsoFs);
    }
    else
        RTTestFailed(hTest, "RTIsoFsOpen failed to open '%s': %Rrc", argv[1], rc);
    return RTTestSummaryAndDestroy(hTest);
}
コード例 #2
0
static int testSessionWait(RTTEST hTest, const char *pszExecPath)
{
    RTTestSub(hTest, "testSessionWait");

    RTLOCALIPCSERVER ipcServer;
    int rc = RTLocalIpcServerCreate(&ipcServer, "tstRTLocalIpcSessionWait",
                                    RTLOCALIPC_FLAGS_MULTI_SESSION);
    if (RT_SUCCESS(rc))
    {
        LOCALIPCTHREADCTX threadCtx = { ipcServer, hTest };

        /* Spawn a simple worker thread and let it listen for incoming connections.
         * In the meanwhile we try to cancel the server and see what happens. */
        RTTHREAD hThread;
        rc = RTThreadCreate(&hThread, testSessionWaitThread,
                            &threadCtx, 0 /* Stack */, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "tstIpc3");
        if (RT_SUCCESS(rc))
        {
            do
            {
                RTPROCESS hProc;
                const char *apszArgs[4] = { pszExecPath, "child", "tstRTLocalIpcSessionWaitFork", NULL };
                RTTEST_CHECK_RC_BREAK(hTest, RTProcCreate(pszExecPath, apszArgs,
                                      RTENV_DEFAULT, 0 /* fFlags*/, &hProc), VINF_SUCCESS);
                RTThreadSleep(5000); /* Let the server run for some time ... */
                RTTestPrintf(hTest, RTTESTLVL_INFO, "Cancelling server listening\n");
                RTTEST_CHECK_RC_BREAK(hTest, RTLocalIpcServerCancel(ipcServer), VINF_SUCCESS);
                /* Wait for the server thread to terminate. */
                int threadRc;
                RTTEST_CHECK_RC(hTest, RTThreadWait(hThread,
                                                    30 * 1000 /* 30s timeout */, &threadRc), VINF_SUCCESS);
                RTTEST_CHECK_RC_BREAK(hTest, threadRc, VERR_CANCELLED);
                RTTEST_CHECK_RC(hTest, RTLocalIpcServerDestroy(ipcServer), VINF_SUCCESS);
                RTTestPrintf(hTest, RTTESTLVL_INFO, "Server thread terminated successfully\n");
                /* Check if the child ran successfully. */
                RTPROCSTATUS stsChild;
                RTTEST_CHECK_RC_BREAK(hTest, RTProcWait(hProc, RTPROCWAIT_FLAGS_BLOCK, &stsChild), VINF_SUCCESS);
                RTTestPrintf(hTest, RTTESTLVL_INFO, "Child terminated\n");
                RTTEST_CHECK_BREAK(hTest, stsChild.enmReason == RTPROCEXITREASON_NORMAL);
                RTTEST_CHECK_BREAK(hTest, stsChild.iStatus == 0);
            }
            while (0);
        }
        else
            RTTestFailed(hTest, "Unable to create thread for cancelling server, rc=%Rrc\n", rc);
    }
    else
        RTTestFailed(hTest, "Unable to create IPC server, rc=%Rrc\n", rc);

    return VINF_SUCCESS;
}
コード例 #3
0
ファイル: UsbTest.cpp プロジェクト: mcenirm/vbox
/**
 * Test execution worker.
 *
 * @returns nothing.
 * @param   pszDevice    The device to use for testing.
 */
static void usbTestExec(const char *pszDevice)
{
    int iDevFd;

    RTTestSub(g_hTest, "Opening device");
    iDevFd = open(pszDevice, O_RDWR);
    if (iDevFd != -1)
    {
        USBTESTPARAMS Params;

        RTTestPassed(g_hTest, "Opening device successful\n");

        /*
         * Fill params with some defaults.
         * @todo: Make them configurable.
         */
        Params.cIterations = 1000;
        Params.cbData = 512;
        Params.cbVariation = 512;
        Params.cSgLength = 32;

        for (unsigned i = 0; i < USBTEST_TEST_CASES; i++)
        {
            RTTestSub(g_hTest, g_apszTests[i]);

            Params.idxTest = i;

            /* Assume the test interface has the number 0 for now. */
            int rcPosix = usbTestIoctl(iDevFd, 0, &Params);
            if (rcPosix < 0 && errno == EOPNOTSUPP)
            {
                RTTestSkipped(g_hTest, "Not supported");
                continue;
            }

            if (rcPosix < 0)
                RTTestFailed(g_hTest, "Test failed with %Rrc\n", RTErrConvertFromErrno(errno));
            else
            {
                uint64_t u64Ns = Params.TimeTest.tv_sec * RT_NS_1SEC + Params.TimeTest.tv_usec * RT_NS_1US;
                RTTestValue(g_hTest, "Runtime", u64Ns, RTTESTUNIT_NS);
            }
            RTTestSubDone(g_hTest);
        }

        close(iDevFd);
    }
    else
        RTTestFailed(g_hTest, "Opening device failed with %Rrc\n", RTErrConvertFromErrno(errno));

}
コード例 #4
0
ファイル: tstRTVfs.cpp プロジェクト: jeppeter/vbox
static void tstVfsIoFromStandardHandle(RTTEST hTest, RTHANDLESTD enmHandle)
{
    RTTestSubF(hTest, "RTVfsIoStrmFromStdHandle(%s)", StandardHandleToString(enmHandle));

    RTVFSIOSTREAM hVfsIos = NIL_RTVFSIOSTREAM;
    int rc = RTVfsIoStrmFromStdHandle(enmHandle, 0, true /*fLeaveOpen*/, &hVfsIos);
    if (RT_SUCCESS(rc))
    {
        if (   enmHandle == RTHANDLESTD_OUTPUT
            || enmHandle == RTHANDLESTD_ERROR)
        {
            char szTmp[80];
            size_t cchTmp = RTStrPrintf(szTmp, sizeof(szTmp), "Test output to %s\n", StandardHandleToString(enmHandle));

            size_t cbWritten;
            RTTESTI_CHECK_RC(rc = RTVfsIoStrmWrite(hVfsIos, szTmp, cchTmp, true /*fBlocking*/, &cbWritten), VINF_SUCCESS);
            if (RT_SUCCESS(rc))
                RTTESTI_CHECK(cbWritten == cchTmp);
        }

        uint32_t cRefs = RTVfsIoStrmRelease(hVfsIos);
        RTTESTI_CHECK_MSG(cRefs == 0, ("cRefs=%#x\n", cRefs));
    }
    else
        RTTestFailed(hTest, "Error creating VFS I/O stream for %s: %Rrc\n", StandardHandleToString(enmHandle), rc);
}
コード例 #5
0
ファイル: tstRTJson.cpp プロジェクト: svn2github/virtualbox
/**
 * Some basic tests to detect malformed JSON.
 */
static void tstBasic(RTTEST hTest)
{
    RTTestSub(hTest, "Basic valid/malformed tests");
    static struct
    {
        const char *pszJson;
        int         iRcResult;
    } const aTests[] =
    {
        { "",              VERR_JSON_MALFORMED },
        { ",",             VERR_JSON_MALFORMED },
        { ":",             VERR_JSON_MALFORMED },
        { "   \n\t{",      VERR_JSON_MALFORMED },
        { "}",             VERR_JSON_MALFORMED },
        { "[",             VERR_JSON_MALFORMED },
        { "]",             VERR_JSON_MALFORMED },
        { "[ \"test\" : ", VERR_JSON_MALFORMED },
        { "null",          VINF_SUCCESS },
        { "true",          VINF_SUCCESS },
        { "false",         VINF_SUCCESS },
        { "100",           VINF_SUCCESS },
        { "\"test\"",      VINF_SUCCESS },
        { "{ }",           VINF_SUCCESS },
        { "[ ]",           VINF_SUCCESS },
        { "[ 100, 200 ]",  VINF_SUCCESS },
        { "{ \"1\": 1 }",  VINF_SUCCESS },
        { "{ \"1\": 1, \"2\": 2 }", VINF_SUCCESS }
    };
    for (unsigned iTest = 0; iTest < RT_ELEMENTS(aTests); iTest++)
    {
        RTJSONVAL hJsonVal = NIL_RTJSONVAL;
        int rc = RTJsonParseFromString(&hJsonVal, aTests[iTest].pszJson, NULL);
        if (rc != aTests[iTest].iRcResult)
            RTTestFailed(hTest, "RTJsonParseFromString() for \"%s\" failed, expected %Rrc got %Rrc\n",
                         aTests[iTest].pszJson, aTests[iTest].iRcResult, rc);
        if (RT_SUCCESS(rc))
        {
            if (hJsonVal != NIL_RTJSONVAL)
                RTJsonValueRelease(hJsonVal);
            else
                RTTestFailed(hTest, "RTJsonParseFromString() returned success but no value\n");
        }
        else if (hJsonVal != NIL_RTJSONVAL)
            RTTestFailed(hTest, "RTJsonParseFromString() failed but a JSON value was returned\n");
    }
}
コード例 #6
0
/**
 * Tries one command string.
 * @param   pDbgc           Pointer to the debugger instance.
 * @param   pszCmds         The command to test.
 * @param   rcCmd           The expected result.
 * @param   fNoExecute      When set, the command is not executed.
 * @param   pszExpected     Expected output.  This does not need to include all
 *                          of the output, just the start of it.  Thus the
 *                          prompt can be omitted.
 */
static void tstTryEx(PDBGC pDbgc, const char *pszCmds, int rcCmd, bool fNoExecute, const char *pszExpected)
{
    RT_ZERO(g_szOutput);
    g_offOutput = 0;
    g_pszInput = pszCmds;
    if (strchr(pszCmds, '\0')[-1] == '\n')
        RTTestPrintfNl(g_hTest, RTTESTLVL_ALWAYS, "RUNNING: %s", pszCmds);
    else
        RTTestPrintfNl(g_hTest, RTTESTLVL_ALWAYS, "RUNNING: %s\n", pszCmds);

    pDbgc->rcCmd = VERR_INTERNAL_ERROR;
    dbgcProcessInput(pDbgc, fNoExecute);
    tstCompleteOutput();

    if (pDbgc->rcCmd != rcCmd)
        RTTestFailed(g_hTest, "rcCmd=%Rrc expected =%Rrc\n", pDbgc->rcCmd, rcCmd);
    else if (   !fNoExecute
             && pszExpected
             && strncmp(pszExpected, g_szOutput, strlen(pszExpected)))
        RTTestFailed(g_hTest, "Wrong output - expected \"%s\"", pszExpected);
}
コード例 #7
0
static uint32_t test2AllocId(struct TestMap2 *p2)
{
    /*
     * Scan sequentially from the last one + 1.
     */
    int32_t idChunk = ++p2->idChunkPrev;
    if (    (uint32_t)idChunk < TEST2_ID_LAST
        &&  idChunk > NIL_TEST2_ID)
    {
        idChunk = ASMBitNextClear(&p2->bmChunkId[0], TEST2_ID_LAST + 1, idChunk);
        if (idChunk > NIL_TEST2_ID)
        {
            if (ASMAtomicBitTestAndSet(&p2->bmChunkId[0], idChunk))
            {
                RTTestFailed(NIL_RTTEST, "line %d: idChunk=%#x", __LINE__, idChunk);
                return NIL_TEST2_ID;
            }
            return p2->idChunkPrev = idChunk;
        }
    }

    /*
     * Ok, scan from the start.
     */
    idChunk = ASMBitFirstClear(&p2->bmChunkId[0], TEST2_ID_LAST + 1);
    if (idChunk <= NIL_TEST2_ID)
    {
        RTTestFailed(NIL_RTTEST, "line %d: idChunk=%#x", __LINE__, idChunk);
        return NIL_TEST2_ID;
    }
    if (ASMAtomicBitTestAndSet(&p2->bmChunkId[0], idChunk))
    {
        RTTestFailed(NIL_RTTEST, "line %d: idChunk=%#x", __LINE__, idChunk);
        return NIL_TEST2_ID;
    }

    return p2->idChunkPrev = idChunk;
}
コード例 #8
0
ファイル: tstRTJson.cpp プロジェクト: svn2github/virtualbox
/**
 * Test that the parser returns the correct values for a valid JSON.
 */
static void tstCorrectness(RTTEST hTest)
{
    RTTestSub(hTest, "Correctness");

    RTJSONVAL hJsonVal = NIL_RTJSONVAL;
    RTTEST_CHECK_RC_OK_RETV(hTest, RTJsonParseFromString(&hJsonVal, g_pszJson, NULL));

    if (hJsonVal != NIL_RTJSONVAL)
    {
        RTJSONVALTYPE enmType = RTJsonValueGetType(hJsonVal);
        if (enmType == RTJSONVALTYPE_OBJECT)
        {
            /* Excercise the other non object APIs to return VERR_JSON_VALUE_INVALID_TYPE. */
            tstCorrectnessRcForInvalidType(hTest, hJsonVal, enmType);
            tstIterator(hTest, hJsonVal);
        }
        else
            RTTestFailed(hTest, "RTJsonParseFromString() returned an invalid JSON value, expected OBJECT got %u\n", enmType);
        RTTEST_CHECK(hTest, RTJsonValueRelease(hJsonVal) == 0);
    }
    else
        RTTestFailed(hTest, "RTJsonParseFromString() returned success but no value\n");
}
コード例 #9
0
int main()
{
    RTTEST hTest;
    RTEXITCODE rcExit = RTTestInitAndCreate("tstRTErrUnique", &hTest);
    if (rcExit != RTEXITCODE_SUCCESS)
        return rcExit;
    RTTestBanner(hTest);

    RTTestSub(hTest, "IPRT status code");
    for (uint32_t i = 0; i < RT_ELEMENTS(g_aErrorMessages) - 1; i++)
        if (!strIsPermissibleDuplicate(&g_aErrorMessages[i]))
            for (uint32_t j = i + 1; j < RT_ELEMENTS(g_aErrorMessages); j++)
                if (   !strIsPermissibleDuplicate(&g_aErrorMessages[j])
                    && g_aErrorMessages[i].iCode == g_aErrorMessages[j].iCode)
                    RTTestFailed(hTest, "Status code %d can mean both '%s' and '%s'",
                                 g_aErrorMessages[i].iCode,
                                 g_aErrorMessages[i].pszDefine,
                                 g_aErrorMessages[j].pszDefine);

    return RTTestSummaryAndDestroy(hTest);
}
コード例 #10
0
int main(int argc, char **argv)
{
#ifndef VBOX
    RTPrintf("tstSup: SKIPPED\n");
    return 0;
#else
    /*
     * Init.
     */
    RTTEST hTest;
    int rc = RTTestInitAndCreate("tstR0ThreadPreemption", &hTest);
    if (rc)
        return rc;
    RTTestBanner(hTest);

    PSUPDRVSESSION pSession;
    rc = SUPR3Init(&pSession);
    if (RT_FAILURE(rc))
    {
        RTTestFailed(hTest, "SUPR3Init failed with rc=%Rrc\n", rc);
        return RTTestSummaryAndDestroy(hTest);
    }

    char szPath[RTPATH_MAX];
    rc = RTPathExecDir(szPath, sizeof(szPath));
    if (RT_SUCCESS(rc))
        rc = RTPathAppend(szPath, sizeof(szPath), "tstR0ThreadPreemption.r0");
    if (RT_FAILURE(rc))
    {
        RTTestFailed(hTest, "Failed constructing .r0 filename (rc=%Rrc)", rc);
        return RTTestSummaryAndDestroy(hTest);
    }

    void *pvImageBase;
    rc = SUPR3LoadServiceModule(szPath, "tstR0ThreadPreemption",
                                "TSTR0ThreadPreemptionSrvReqHandler",
                                &pvImageBase);
    if (RT_FAILURE(rc))
    {
        RTTestFailed(hTest, "SUPR3LoadServiceModule(%s,,,) failed with rc=%Rrc\n", szPath, rc);
        return RTTestSummaryAndDestroy(hTest);
    }

    /* test request */
    struct
    {
        SUPR0SERVICEREQHDR  Hdr;
        char                szMsg[256];
    } Req;

    /*
     * Sanity checks.
     */
    RTTestSub(hTest, "Sanity");
    Req.Hdr.u32Magic = SUPR0SERVICEREQHDR_MAGIC;
    Req.Hdr.cbReq = sizeof(Req);
    Req.szMsg[0] = '\0';
    RTTESTI_CHECK_RC(rc = SUPR3CallR0Service("tstR0ThreadPreemption", sizeof("tstR0ThreadPreemption") - 1,
                          TSTR0THREADPREMEPTION_SANITY_OK, 0, &Req.Hdr), VINF_SUCCESS);
    if (RT_FAILURE(rc))
        return RTTestSummaryAndDestroy(hTest);
    RTTESTI_CHECK_MSG(Req.szMsg[0] == '\0', ("%s", Req.szMsg));
    if (Req.szMsg[0] != '\0')
        return RTTestSummaryAndDestroy(hTest);

    Req.Hdr.u32Magic = SUPR0SERVICEREQHDR_MAGIC;
    Req.Hdr.cbReq = sizeof(Req);
    Req.szMsg[0] = '\0';
    RTTESTI_CHECK_RC(rc = SUPR3CallR0Service("tstR0ThreadPreemption", sizeof("tstR0ThreadPreemption") - 1,
                          TSTR0THREADPREMEPTION_SANITY_FAILURE, 0, &Req.Hdr), VINF_SUCCESS);
    if (RT_FAILURE(rc))
        return RTTestSummaryAndDestroy(hTest);
    RTTESTI_CHECK_MSG(!strncmp(Req.szMsg, "!42failure42", sizeof("!42failure42") - 1), ("%s", Req.szMsg));
    if (strncmp(Req.szMsg, "!42failure42", sizeof("!42failure42") - 1))
        return RTTestSummaryAndDestroy(hTest);

    /*
     * Basic tests, bail out on failure.
     */
    RTTestSub(hTest, "Basics");
    Req.Hdr.u32Magic = SUPR0SERVICEREQHDR_MAGIC;
    Req.Hdr.cbReq = sizeof(Req);
    Req.szMsg[0] = '\0';
    RTTESTI_CHECK_RC(rc = SUPR3CallR0Service("tstR0ThreadPreemption", sizeof("tstR0ThreadPreemption") - 1,
                          TSTR0THREADPREMEPTION_BASIC, 0, &Req.Hdr), VINF_SUCCESS);
    if (RT_FAILURE(rc))
        return RTTestSummaryAndDestroy(hTest);
    if (Req.szMsg[0] == '!')
    {
        RTTestIFailed("%s", &Req.szMsg[1]);
        return RTTestSummaryAndDestroy(hTest);
    }
    if (Req.szMsg[0])
        RTTestIPrintf(RTTESTLVL_ALWAYS, "%s", Req.szMsg);

    /*
     * Stay in ring-0 until preemption is pending.
     */
    RTThreadSleep(250); /** @todo fix GIP initialization? */
    RTTestSub(hTest, "Pending Preemption");
    for (int i = 0; ; i++)
    {
        Req.Hdr.u32Magic = SUPR0SERVICEREQHDR_MAGIC;
        Req.Hdr.cbReq = sizeof(Req);
        Req.szMsg[0] = '\0';
        RTTESTI_CHECK_RC(rc = SUPR3CallR0Service("tstR0ThreadPreemption", sizeof("tstR0ThreadPreemption") - 1,
                              TSTR0THREADPREMEPTION_IS_PENDING, 0, &Req.Hdr), VINF_SUCCESS);
        if (    strcmp(Req.szMsg, "cLoops=1\n")
                ||  i >= 64)
        {
            if (Req.szMsg[0] == '!')
                RTTestIFailed("%s", &Req.szMsg[1]);
            else if (Req.szMsg[0])
                RTTestIPrintf(RTTESTLVL_ALWAYS, "%s", Req.szMsg);
            break;
        }
        if ((i % 3) == 0)
            RTThreadYield();
    }

    /*
     * Test nested RTThreadPreemptDisable calls.
     */
    RTTestSub(hTest, "Nested");
    Req.Hdr.u32Magic = SUPR0SERVICEREQHDR_MAGIC;
    Req.Hdr.cbReq = sizeof(Req);
    Req.szMsg[0] = '\0';
    RTTESTI_CHECK_RC(rc = SUPR3CallR0Service("tstR0ThreadPreemption", sizeof("tstR0ThreadPreemption") - 1,
                          TSTR0THREADPREMEPTION_NESTED, 0, &Req.Hdr), VINF_SUCCESS);
    if (Req.szMsg[0] == '!')
        RTTestIFailed("%s", &Req.szMsg[1]);
    else if (Req.szMsg[0])
        RTTestIPrintf(RTTESTLVL_ALWAYS, "%s", Req.szMsg);

    /*
     * Done.
     */
    return RTTestSummaryAndDestroy(hTest);
#endif
}
コード例 #11
0
static int testSessionConnection(RTTEST hTest, const char *pszExecPath)
{
    RTTestSub(hTest, "testSessionConnection");

    RTLOCALIPCSERVER ipcServer;
    int rc = RTLocalIpcServerCreate(&ipcServer, "tstRTLocalIpcSessionConnection",
                                    RTLOCALIPC_FLAGS_MULTI_SESSION);
    if (RT_SUCCESS(rc))
    {
#ifndef VBOX_TESTCASES_WITH_NO_THREADING
        LOCALIPCTHREADCTX threadCtx = { ipcServer, hTest };

        /* Spawn a simple worker thread and let it listen for incoming connections.
         * In the meanwhile we try to cancel the server and see what happens. */
        RTTHREAD hThread;
        rc = RTThreadCreate(&hThread, testSessionConnectionThread,
                            &threadCtx, 0 /* Stack */, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "tstIpc2");
        if (RT_SUCCESS(rc))
        {
            do
            {
                RTPROCESS hProc;
                const char *apszArgs[4] = { pszExecPath, "child", "tstRTLocalIpcSessionConnectionFork", NULL };
                RTTEST_CHECK_RC_BREAK(hTest, RTProcCreate(pszExecPath, apszArgs,
                                      RTENV_DEFAULT, 0 /* fFlags*/, &hProc), VINF_SUCCESS);
                RTPROCSTATUS stsChild;
                RTTEST_CHECK_RC_BREAK(hTest, RTProcWait(hProc, RTPROCWAIT_FLAGS_BLOCK, &stsChild), VINF_SUCCESS);
                RTTestPrintf(hTest, RTTESTLVL_INFO, "Child terminated, waiting for server thread ...\n");
                RTTEST_CHECK_RC_BREAK(hTest, RTLocalIpcServerCancel(ipcServer), VINF_SUCCESS);
                int threadRc;
                RTTEST_CHECK_RC(hTest, RTThreadWait(hThread,
                                                    30 * 1000 /* 30s timeout */, &threadRc), VINF_SUCCESS);
                RTTEST_CHECK_RC_BREAK(hTest, threadRc,  VERR_CANCELLED);
                RTTestPrintf(hTest, RTTESTLVL_INFO, "Server thread terminated successfully\n");
                RTTEST_CHECK_RC_BREAK(hTest, RTLocalIpcServerDestroy(ipcServer), VINF_SUCCESS);
                RTTEST_CHECK_BREAK(hTest, stsChild.enmReason == RTPROCEXITREASON_NORMAL);
                RTTEST_CHECK_BREAK(hTest, stsChild.iStatus == 0);
            }
            while (0);
        }
        else
            RTTestFailed(hTest, "Unable to create thread for cancelling server, rc=%Rrc\n", rc);
#else
        do
        {
            RTPROCESS hProc;
            const char *apszArgs[4] = { pszExecPath, "child", "tstRTLocalIpcSessionConnectionFork", NULL };
            RTTEST_CHECK_RC_BREAK(hTest, RTProcCreate(pszExecPath, apszArgs,
                                  RTENV_DEFAULT, 0 /* fFlags*/, &hProc), VINF_SUCCESS);
            RTLOCALIPCSESSION ipcSession;
            rc = RTLocalIpcServerListen(ipcServer, &ipcSession);
            if (RT_SUCCESS(rc))
            {
                RTTestPrintf(hTest, RTTESTLVL_INFO, "testSessionConnectionThread: Got new client connection\n");
            }
            else
                RTTestFailed(hTest, "Error while listening, rc=%Rrc\n", rc);

        } while (0);
#endif
    }
    else
        RTTestFailed(hTest, "Unable to create IPC server, rc=%Rrc\n", rc);

    return VINF_SUCCESS;
}
コード例 #12
0
static void testParserAndSplitter(RTTEST hTest)
{
    static struct
    {
        uint16_t    cComps;
        uint16_t    cchPath;
        uint16_t    offSuffix;
        const char *pszPath;
        uint16_t    fProps;
        uint32_t    fFlags;
    } const s_aTests[] =
    {
        { 2,  5,  5,  "/bin/",            RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_DIR_SLASH,                                                RTPATH_STR_F_STYLE_UNIX },
        { 2, 13,  9,  "C:/Config.sys",    RTPATH_PROP_VOLUME | RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME | RTPATH_PROP_SUFFIX,       RTPATH_STR_F_STYLE_DOS },
        { 2, 13, 10,  "C://Config.sys",   RTPATH_PROP_VOLUME | RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME | RTPATH_PROP_SUFFIX | RTPATH_PROP_EXTRA_SLASHES, RTPATH_STR_F_STYLE_DOS },
        { 2, 12,  8,  "C:Config.sys",     RTPATH_PROP_VOLUME | RTPATH_PROP_RELATIVE | RTPATH_PROP_FILENAME | RTPATH_PROP_SUFFIX,                                RTPATH_STR_F_STYLE_DOS },
        { 1, 10,  6,  "Config.sys",       RTPATH_PROP_RELATIVE | RTPATH_PROP_FILENAME | RTPATH_PROP_SUFFIX,                                                     RTPATH_STR_F_STYLE_DOS },
        { 1,  4,  4,  "//./",             RTPATH_PROP_UNC | RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE,                                                      RTPATH_STR_F_STYLE_DOS },
        { 2,  5,  5,  "//./f",            RTPATH_PROP_UNC | RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME,                               RTPATH_STR_F_STYLE_DOS },
        { 2,  5,  6,  "//.//f",           RTPATH_PROP_UNC | RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME | RTPATH_PROP_EXTRA_SLASHES,   RTPATH_STR_F_STYLE_DOS },
        { 3,  7,  7,  "//././f",          RTPATH_PROP_UNC | RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME | RTPATH_PROP_DOT_REFS,        RTPATH_STR_F_STYLE_DOS },
        { 3,  8,  8,  "//.././f",         RTPATH_PROP_UNC | RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME | RTPATH_PROP_DOT_REFS,        RTPATH_STR_F_STYLE_DOS },
        { 3,  9,  9,  "//../../f",        RTPATH_PROP_UNC | RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_RELATIVE | RTPATH_PROP_FILENAME | RTPATH_PROP_DOTDOT_REFS,     RTPATH_STR_F_STYLE_DOS },
        { 1,  1,  1,  "/",                RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE,                                                                        RTPATH_STR_F_STYLE_UNIX },
        { 2,  4,  4,  "/bin",             RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME,                                                 RTPATH_STR_F_STYLE_UNIX },
        { 2,  5,  5,  "/bin/",            RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_DIR_SLASH,                                                RTPATH_STR_F_STYLE_UNIX },
        { 3,  7,  7,  "/bin/ls",          RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME,                                                 RTPATH_STR_F_STYLE_UNIX },
        { 3,  12, 7,  "/etc/rc.conf",     RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME | RTPATH_PROP_SUFFIX,                            RTPATH_STR_F_STYLE_UNIX },
        { 1,  1,  2,  "//",               RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_EXTRA_SLASHES,                                            RTPATH_STR_F_STYLE_UNIX },
        { 1,  1,  3,  "///",              RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_EXTRA_SLASHES,                                            RTPATH_STR_F_STYLE_UNIX },
        { 3,  6,  7,  "/.//bin",          RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_EXTRA_SLASHES | RTPATH_PROP_DOT_REFS | RTPATH_PROP_FILENAME, RTPATH_STR_F_STYLE_UNIX },
        { 1,  3,  3,  "bin",              RTPATH_PROP_RELATIVE | RTPATH_PROP_FILENAME,                                                                          RTPATH_STR_F_STYLE_UNIX },
        { 1,  4,  4,  "bin/",             RTPATH_PROP_RELATIVE | RTPATH_PROP_DIR_SLASH,                                                                         RTPATH_STR_F_STYLE_UNIX },
        { 1,  4,  7,  "bin////",          RTPATH_PROP_RELATIVE | RTPATH_PROP_DIR_SLASH | RTPATH_PROP_EXTRA_SLASHES,                                             RTPATH_STR_F_STYLE_UNIX },
        { 3, 10, 10,  "bin/../usr",       RTPATH_PROP_RELATIVE | RTPATH_PROP_DOTDOT_REFS | RTPATH_PROP_FILENAME,                                                RTPATH_STR_F_STYLE_UNIX },
        { 4, 11, 11,  "/bin/../usr",      RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_RELATIVE | RTPATH_PROP_DOTDOT_REFS | RTPATH_PROP_FILENAME,                       RTPATH_STR_F_STYLE_UNIX },
        { 4,  8,  8,  "/a/.../u",         RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME,                                                 RTPATH_STR_F_STYLE_UNIX },
        { 4,  8,  8,  "/a/.b./u",         RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME,                                                 RTPATH_STR_F_STYLE_UNIX },
        { 4,  8,  8,  "/a/..c/u",         RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME,                                                 RTPATH_STR_F_STYLE_UNIX },
        { 4,  8,  8,  "/a/d../u",         RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME,                                                 RTPATH_STR_F_STYLE_UNIX },
        { 4,  8,  8,  "/a/.e/.u",         RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME,                                                 RTPATH_STR_F_STYLE_UNIX },
        { 4,  8,  8,  "/a/.f/.u",         RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME,                                                 RTPATH_STR_F_STYLE_UNIX },
        { 4,  8,  8,  "/a/.g/u.",         RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME,                                                 RTPATH_STR_F_STYLE_UNIX },
        { 3,  9, 10,  "/a/h/u.ext",       RTPATH_PROP_EXTRA_SLASHES | RTPATH_PROP_RELATIVE,                                                                     RTPATH_STR_F_STYLE_UNIX | RTPATH_STR_F_MIDDLE },
        { 3,  9,  9,  "a/h/u.ext",        RTPATH_PROP_RELATIVE,                                                                                                 RTPATH_STR_F_STYLE_UNIX | RTPATH_STR_F_MIDDLE },
        { 3,  9, 10,  "a/h/u.ext/",       RTPATH_PROP_EXTRA_SLASHES | RTPATH_PROP_RELATIVE,                                                                     RTPATH_STR_F_STYLE_UNIX | RTPATH_STR_F_MIDDLE },
    };

    char szPath1[RTPATH_MAX];
    union
    {
        RTPATHPARSED    Parsed;
        RTPATHSPLIT     Split;
        uint8_t         ab[4096];
    } u;

    RTTestSub(hTest, "RTPathParse");
    for (uint32_t i = 0; i < RT_ELEMENTS(s_aTests); i++)
    {
        memset(&u, i & 1 ? 0xff : 0, sizeof(u));
        int rc = RTPathParse(s_aTests[i].pszPath, &u.Parsed, sizeof(u), s_aTests[i].fFlags);
        if (   rc != VINF_SUCCESS
                || s_aTests[i].cComps    != u.Parsed.cComps
                || s_aTests[i].fProps    != u.Parsed.fProps
                || s_aTests[i].offSuffix != u.Parsed.offSuffix
                || s_aTests[i].cchPath   != u.Parsed.cchPath)
        {
            RTTestFailed(hTest, "i=%d rc=%Rrc %s", i, rc, s_aTests[i].pszPath);
            RTTestFailureDetails(hTest,
                                 "  cComps    %u, got %u\n"
                                 "  fProps    %#x, got %#x, xor=>%#x\n"
                                 "  offSuffix %u, got %u\n"
                                 "  cchPath   %u, got %u\n"
                                 ,
                                 s_aTests[i].cComps,    u.Parsed.cComps,
                                 s_aTests[i].fProps,    u.Parsed.fProps, s_aTests[i].fProps ^ u.Parsed.fProps,
                                 s_aTests[i].offSuffix, u.Parsed.offSuffix,
                                 s_aTests[i].cchPath,   u.Parsed.cchPath);
        }
        else
        {
            rc = RTPathParsedReassemble(s_aTests[i].pszPath, &u.Parsed, s_aTests[i].fFlags & ~RTPATH_STR_F_MIDDLE,
                                        szPath1, sizeof(szPath1));
            if (rc == VINF_SUCCESS)
            {
                RTTESTI_CHECK_MSG(strlen(szPath1) == s_aTests[i].cchPath, ("%s\n", szPath1));
                if (   !(u.Parsed.fProps & RTPATH_PROP_EXTRA_SLASHES)
                        && (s_aTests[i].fFlags & RTPATH_STR_F_STYLE_MASK) != RTPATH_STR_F_STYLE_DOS)
                    RTTESTI_CHECK_MSG(strcmp(szPath1, s_aTests[i].pszPath) == 0, ("%s\n", szPath1));
            }
            else
                RTTestIFailed("RTPathParsedReassemble -> %Rrc", rc);
        }
    }

    RTTestSub(hTest, "RTPathSplit");
    for (uint32_t i = 0; i < RT_ELEMENTS(s_aTests); i++)
    {
        memset(&u, i & 1 ? 0xff : 0, sizeof(u));
        int rc = RTPathSplit(s_aTests[i].pszPath, &u.Split, sizeof(u), s_aTests[i].fFlags);
        if (   rc != VINF_SUCCESS
                || s_aTests[i].cComps    != u.Split.cComps
                || s_aTests[i].fProps    != u.Split.fProps
                || s_aTests[i].cchPath   != u.Split.cchPath)
        {
            RTTestFailed(hTest, "i=%d rc=%Rrc %s", i, rc, s_aTests[i].pszPath);
            RTTestFailureDetails(hTest,
                                 "  cComps    %u, got %u\n"
                                 "  fProps    %#x, got %#x, xor=>%#x\n"
                                 "  cchPath   %u, got %u\n"
                                 ,
                                 s_aTests[i].cComps,    u.Split.cComps,
                                 s_aTests[i].fProps,    u.Split.fProps, s_aTests[i].fProps ^ u.Split.fProps,
                                 s_aTests[i].cchPath,   u.Split.cchPath);
        }
        else
        {
            RTTESTI_CHECK_MSG(*u.Split.pszSuffix == '\0' || *u.Split.pszSuffix == '.', ("%s", u.Split.pszSuffix));
            for (uint32_t idxComp = RTPATH_PROP_HAS_ROOT_SPEC(u.Split.fProps); idxComp < u.Split.cComps; idxComp++)
                if ( (s_aTests[i].fFlags & RTPATH_STR_F_STYLE_MASK) == RTPATH_STR_F_STYLE_DOS
                        ? strpbrk(u.Split.apszComps[idxComp], "/\\")
                        : strchr(u.Split.apszComps[idxComp], RTPATH_SLASH) )
                    RTTestFailed(hTest, "i=%d idxComp=%d '%s'", i, idxComp, u.Split.apszComps[idxComp]);

            PRTPATHSPLIT pSplit = NULL;
            RTTESTI_CHECK_RC(rc = RTPathSplitA(s_aTests[i].pszPath, &pSplit, s_aTests[i].fFlags), VINF_SUCCESS);
            if (RT_SUCCESS(rc))
            {
                RTTESTI_CHECK(pSplit);
                RTTESTI_CHECK(pSplit->cComps   == u.Split.cComps);
                RTTESTI_CHECK(pSplit->fProps   == u.Split.fProps);
                RTTESTI_CHECK(pSplit->cchPath  == u.Split.cchPath);
                RTTESTI_CHECK(pSplit->cbNeeded == u.Split.cbNeeded);
                RTTESTI_CHECK(!strcmp(pSplit->pszSuffix, u.Split.pszSuffix));
                for (uint32_t idxComp = 0; idxComp < u.Split.cComps; idxComp++)
                    RTTESTI_CHECK(!strcmp(pSplit->apszComps[idxComp], pSplit->apszComps[idxComp]));
                RTPathSplitFree(pSplit);
            }

            rc = RTPathSplitReassemble(&u.Split, s_aTests[i].fFlags & ~RTPATH_STR_F_MIDDLE, szPath1, sizeof(szPath1));
            if (rc == VINF_SUCCESS)
            {
                RTTESTI_CHECK_MSG(strlen(szPath1) == s_aTests[i].cchPath, ("%s\n", szPath1));
                if (   !(u.Parsed.fProps & RTPATH_PROP_EXTRA_SLASHES)
                        && (s_aTests[i].fFlags & RTPATH_STR_F_STYLE_MASK) != RTPATH_STR_F_STYLE_DOS)
                    RTTESTI_CHECK_MSG(strcmp(szPath1, s_aTests[i].pszPath) == 0, ("%s\n", szPath1));
            }
            else
                RTTestIFailed("RTPathSplitReassemble -> %Rrc", rc);
        }
    }
}
コード例 #13
0
ファイル: tstX86-1.cpp プロジェクト: jeppeter/vbox
int main()
{
    /*
     * Set up the test environment.
     */
    RTTEST hTest;
    RTEXITCODE rcExit = RTTestInitAndCreate("tstX86-1", &hTest);
    if (rcExit != RTEXITCODE_SUCCESS)
        return rcExit;
    RTTestBanner(hTest);

    g_pbEfPage = (uint8_t *)RTTestGuardedAllocTail(hTest, PAGE_SIZE);
    RTTESTI_CHECK(g_pbEfPage != NULL);

    g_pbEfExecPage = (uint8_t *)RTMemExecAlloc(PAGE_SIZE*2);
    RTTESTI_CHECK(g_pbEfExecPage != NULL);
    RTTESTI_CHECK(!((uintptr_t)g_pbEfExecPage & PAGE_OFFSET_MASK));
    RTTESTI_CHECK_RC(RTMemProtect(g_pbEfExecPage + PAGE_SIZE, PAGE_SIZE, RTMEM_PROT_NONE), VINF_SUCCESS);

#ifdef USE_SIGNAL
    static int const s_aiSigs[] = { SIGBUS, SIGSEGV, SIGFPE, SIGILL };
    for (unsigned i = 0; i < RT_ELEMENTS(s_aiSigs); i++)
    {
        struct sigaction SigAct;
        RTTESTI_CHECK_BREAK(sigaction(s_aiSigs[i], NULL, &SigAct) == 0);
        SigAct.sa_sigaction = sigHandler;
        SigAct.sa_flags    |= SA_SIGINFO;
        RTTESTI_CHECK(sigaction(s_aiSigs[i], &SigAct, NULL) == 0);
    }
#else
    /** @todo implement me. */
#endif


    if (!RTTestErrorCount(hTest))
    {
        /*
         * Do the testing.
         */
        int32_t rc;
#if 0
        RTTestSub(hTest, "Misc 1");
        rc = x861_Test1();
        if (rc != 0)
            RTTestFailed(hTest, "x861_Test1 -> %d", rc);

        RTTestSub(hTest, "Prefixes and groups");
        rc = x861_Test2();
        if (rc != 0)
            RTTestFailed(hTest, "x861_Test2 -> %d", rc);

        RTTestSub(hTest, "fxsave / fxrstor and #PFs");
        rc = x861_Test3();
        if (rc != 0)
            RTTestFailed(hTest, "x861_Test3 -> %d", rc);

        RTTestSub(hTest, "Multibyte NOPs");
        rc = x861_Test4();
        if (rc != 0)
            RTTestFailed(hTest, "x861_Test4 -> %d", rc);
//#endif

        RTTestSub(hTest, "Odd encodings and odd ends");
        rc = x861_Test5();
        if (rc != 0)
            RTTestFailed(hTest, "x861_Test5 -> %d", rc);

//#if 0
        RTTestSub(hTest, "Odd floating point encodings");
        rc = x861_Test6();
        if (rc != 0)
            RTTestFailed(hTest, "x861_Test5 -> %d", rc);

        RTTestSub(hTest, "Floating point exceptions ++");
        rc = x861_Test7();
        if (rc != 0)
            RTTestFailed(hTest, "x861_Test6 -> %d", rc);
#endif

        rc = x861_TestFPUInstr1();
        if (rc != 0)
            RTTestFailed(hTest, "x861_TestFPUInstr1 -> %d", rc);
    }

    return RTTestSummaryAndDestroy(hTest);
}
コード例 #14
0
static void Test4(unsigned cThreads, unsigned cSeconds, unsigned uWritePercent, bool fYield, bool fQuiet)
{
    unsigned i;
    uint64_t acIterations[32];
    RTTHREAD aThreads[RT_ELEMENTS(acIterations)];
    AssertRelease(cThreads <= RT_ELEMENTS(acIterations));

    RTTestSubF(g_hTest, "Test4 - %u threads, %u sec, %u%% writes, %syielding",
               cThreads, cSeconds, uWritePercent, fYield ? "" : "non-");

    /*
     * Init globals.
     */
    g_fYield = fYield;
    g_fQuiet = fQuiet;
    g_fTerminate = false;
    g_uWritePercent = uWritePercent;
    g_cConcurrentWriters = 0;
    g_cConcurrentReaders = 0;

    RTTEST_CHECK_RC_RETV(g_hTest, RTCritSectRwInit(&g_CritSectRw), VINF_SUCCESS);

    /*
     * Create the threads and let them block on the semrw.
     */
    RTTEST_CHECK_RC_RETV(g_hTest, RTCritSectRwEnterExcl(&g_CritSectRw), VINF_SUCCESS);

    for (i = 0; i < cThreads; i++)
    {
        acIterations[i] = 0;
        RTTEST_CHECK_RC_RETV(g_hTest, RTThreadCreateF(&aThreads[i], Test4Thread, &acIterations[i], 0,
                                                      RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE,
                                                      "test-%u", i), VINF_SUCCESS);
    }

    /*
     * Do the test run.
     */
    uint32_t cErrorsBefore = RTTestErrorCount(g_hTest);
    uint64_t u64StartTS = RTTimeNanoTS();
    RTTEST_CHECK_RC(g_hTest, RTCritSectRwLeaveExcl(&g_CritSectRw), VINF_SUCCESS);
    RTThreadSleep(cSeconds * 1000);
    ASMAtomicWriteBool(&g_fTerminate, true);
    uint64_t ElapsedNS = RTTimeNanoTS() - u64StartTS;

    /*
     * Clean up the threads and semaphore.
     */
    for (i = 0; i < cThreads; i++)
        RTTEST_CHECK_RC(g_hTest, RTThreadWait(aThreads[i], 5000, NULL), VINF_SUCCESS);

    RTTEST_CHECK_MSG(g_hTest, g_cConcurrentWriters == 0, (g_hTest, "g_cConcurrentWriters=%u at end of test\n", g_cConcurrentWriters));
    RTTEST_CHECK_MSG(g_hTest, g_cConcurrentReaders == 0, (g_hTest, "g_cConcurrentReaders=%u at end of test\n", g_cConcurrentReaders));

    RTTEST_CHECK_RC(g_hTest, RTCritSectRwDelete(&g_CritSectRw), VINF_SUCCESS);

    if (RTTestErrorCount(g_hTest) != cErrorsBefore)
        RTThreadSleep(100);

    /*
     * Collect and display the results.
     */
    uint64_t cItrTotal = acIterations[0];
    for (i = 1; i < cThreads; i++)
        cItrTotal += acIterations[i];

    uint64_t cItrNormal = cItrTotal / cThreads;
    uint64_t cItrMinOK = cItrNormal / 20; /* 5% */
    uint64_t cItrMaxDeviation = 0;
    for (i = 0; i < cThreads; i++)
    {
        uint64_t cItrDelta = RT_ABS((int64_t)(acIterations[i] - cItrNormal));
        if (acIterations[i] < cItrMinOK)
            RTTestFailed(g_hTest, "Thread %u did less than 5%% of the iterations - %llu (it) vs. %llu (5%%) - %llu%%\n",
                         i, acIterations[i], cItrMinOK, cItrDelta * 100 / cItrNormal);
        else if (cItrDelta > cItrNormal / 2)
            RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS,
                         "Warning! Thread %u deviates by more than 50%% - %llu (it) vs. %llu (avg) - %llu%%\n",
                         i, acIterations[i], cItrNormal, cItrDelta * 100 / cItrNormal);
        if (cItrDelta > cItrMaxDeviation)
            cItrMaxDeviation = cItrDelta;

    }

    //RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS,
    //             "Threads: %u  Total: %llu  Per Sec: %llu  Avg: %llu ns  Max dev: %llu%%\n",
    //             cThreads,
    //             cItrTotal,
    //             cItrTotal / cSeconds,
    //             ElapsedNS / cItrTotal,
    //             cItrMaxDeviation * 100 / cItrNormal
    //             );
    //
    RTTestValue(g_hTest, "Thruput", cItrTotal * UINT32_C(1000000000) / ElapsedNS, RTTESTUNIT_CALLS_PER_SEC);
    RTTestValue(g_hTest, "Max diviation", cItrMaxDeviation * 100 / cItrNormal, RTTESTUNIT_PCT);
}
コード例 #15
0
ファイル: tstFork.cpp プロジェクト: jeppeter/vbox
int main()
{
    /*
     * Init the runtime and stuff.
     */
    RTTEST hTest;
    int rc = RTTestInitAndCreate("tstFork", &hTest);
    if (rc)
        return rc;
    RTTestBanner(hTest);

#ifdef RT_OS_WINDOWS
    RTTestPrintf(hTest, RTTESTLVL_ALWAYS, "Skipped\n");
#else
    /*
     * Get values that are supposed to or change across the fork.
     */
    RTPROCESS const ProcBefore = RTProcSelf();

    /*
     * Fork.
     */
    pid_t pid = fork();
    if (pid == 0)
    {
        /*
         * Check that the values has changed.
         */
        rc = 0;
        if (ProcBefore == RTProcSelf())
        {
            RTTestFailed(hTest, "%RTproc == %RTproc [child]", ProcBefore, RTProcSelf());
            rc = 1;
        }
        return rc;
    }
    if (pid != -1)
    {
        /*
         * Check that the values didn't change.
         */
        RTTEST_CHECK(hTest, ProcBefore == RTProcSelf());

        /*
         * Wait for the child.
         */
        rc = 1;
        while (   waitpid(pid, &rc, 0)
                  && errno == EINTR)
            rc = 1;
        if (!WIFEXITED(rc) || WEXITSTATUS(rc) != 0)
            RTTestFailed(hTest, "rc=%#x", rc);
    }
    else
        RTTestFailed(hTest, "fork() failed: %d - %s", errno, strerror(errno));
#endif

    /*
     * Summary
     */
    return RTTestSummaryAndDestroy(hTest);
}
コード例 #16
0
static int testSessionData(RTTEST hTest, const char *pszExecPath)
{
    RTTestSub(hTest, "testSessionData");

    RTLOCALIPCSERVER ipcServer;
    int rc = RTLocalIpcServerCreate(&ipcServer, "tstRTLocalIpcSessionData",
                                    RTLOCALIPC_FLAGS_MULTI_SESSION);
    if (RT_SUCCESS(rc))
    {
        LOCALIPCTHREADCTX threadCtx = { ipcServer, hTest };
#if 0
        /* Run server + client in threads instead of fork'ed processes (useful for debugging). */
        RTTHREAD hThreadServer, hThreadClient;
        rc = RTThreadCreate(&hThreadServer, testSessionDataThread,
                            &threadCtx, 0 /* Stack */, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "tstIpc4");
        if (RT_SUCCESS(rc))
            rc = RTThreadCreate(&hThreadClient, testSessionDataChildAsThread,
                                &hTest, 0 /* Stack */, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "tstIpc5");
        if (RT_SUCCESS(rc))
        {
            do
            {
                int threadRc;
                RTTEST_CHECK_RC(hTest, RTThreadWait(hThreadServer,
                                                    5 * 60 * 1000 /* 5 minutes timeout */, &threadRc), VINF_SUCCESS);
                RTTEST_CHECK_RC_BREAK(hTest, threadRc, VINF_SUCCESS);
                RTTEST_CHECK_RC(hTest, RTThreadWait(hThreadClient,
                                                    5 * 60 * 1000 /* 5 minutes timeout */, &threadRc), VINF_SUCCESS);
                RTTEST_CHECK_RC_BREAK(hTest, threadRc, VINF_SUCCESS);

            } while (0);
        }
#else
        /* Spawn a simple worker thread and let it listen for incoming connections.
         * In the meanwhile we try to cancel the server and see what happens. */
        RTTHREAD hThread;
        rc = RTThreadCreate(&hThread, testSessionDataThread,
                            &threadCtx, 0 /* Stack */, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "tstIpc4");
        if (RT_SUCCESS(rc))
        {
            do
            {
                RTPROCESS hProc;
                const char *apszArgs[4] = { pszExecPath, "child", "tstRTLocalIpcSessionDataFork", NULL };
                RTTEST_CHECK_RC_BREAK(hTest, RTProcCreate(pszExecPath, apszArgs,
                                      RTENV_DEFAULT, 0 /* fFlags*/, &hProc), VINF_SUCCESS);
                /* Wait for the server thread to terminate. */
                int threadRc;
                RTTEST_CHECK_RC(hTest, RTThreadWait(hThread,
                                                    5 * 60 * 1000 /* 5 minutes timeout */, &threadRc), VINF_SUCCESS);
                RTTEST_CHECK_RC_BREAK(hTest, threadRc, VINF_SUCCESS);
                RTTEST_CHECK_RC(hTest, RTLocalIpcServerDestroy(ipcServer), VINF_SUCCESS);
                RTTestPrintf(hTest, RTTESTLVL_INFO, "Server thread terminated successfully\n");
                /* Check if the child ran successfully. */
                RTPROCSTATUS stsChild;
                RTTEST_CHECK_RC_BREAK(hTest, RTProcWait(hProc, RTPROCWAIT_FLAGS_BLOCK, &stsChild), VINF_SUCCESS);
                RTTestPrintf(hTest, RTTESTLVL_INFO, "Child terminated\n");
                RTTEST_CHECK_BREAK(hTest, stsChild.enmReason == RTPROCEXITREASON_NORMAL);
                RTTEST_CHECK_BREAK(hTest, stsChild.iStatus == 0);
            }
            while (0);
        }
        else
            RTTestFailed(hTest, "Unable to create thread for cancelling server, rc=%Rrc\n", rc);
#endif
    }
    else
        RTTestFailed(hTest, "Unable to create IPC server, rc=%Rrc\n", rc);

    return !RTTestErrorCount(hTest) ? VINF_SUCCESS : VERR_GENERAL_FAILURE /* Doesn't matter */;
}
コード例 #17
0
int main(int argc, char **argv)
{
    /*
     * Init runtime and the test environment.
     */
    int rc = RTR3InitAndSUPLib();
    if (RT_FAILURE(rc))
    {
        RTPrintf("tstVMM: RTR3InitAndSUPLib failed: %Rrc\n", rc);
        return 1;
    }
    RTTEST hTest;
    rc = RTTestCreate("tstVMM", &hTest);
    if (RT_FAILURE(rc))
    {
        RTPrintf("tstVMM: RTTestCreate failed: %Rrc\n", rc);
        return 1;
    }

    /*
     * Parse arguments.
     */
    static const RTGETOPTDEF s_aOptions[] =
    {
        { "--cpus",          'c', RTGETOPT_REQ_UINT8 },
        { "--test",          't', RTGETOPT_REQ_STRING },
    };
    enum
    {
        kTstVMMTest_VMM,  kTstVMMTest_TM
    } enmTestOpt = kTstVMMTest_VMM;

    int ch;
    int i = 1;
    RTGETOPTUNION ValueUnion;
    RTGETOPTSTATE GetState;
    RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, 0);
    while ((ch = RTGetOpt(&GetState, &ValueUnion)))
    {
        switch (ch)
        {
            case 'c':
                g_cCpus = ValueUnion.u8;
                break;

            case 't':
                if (!strcmp("vmm", ValueUnion.psz))
                    enmTestOpt = kTstVMMTest_VMM;
                else if (!strcmp("tm", ValueUnion.psz))
                    enmTestOpt = kTstVMMTest_TM;
                else
                {
                    RTPrintf("tstVMM: unknown test: '%s'\n", ValueUnion.psz);
                    return 1;
                }
                break;

            case 'h':
                RTPrintf("usage: tstVMM [--cpus|-c cpus] [--test <vmm|tm>]\n");
                return 1;

            case 'V':
                RTPrintf("$Revision: $\n");
                return 0;

            default:
                return RTGetOptPrintError(ch, &ValueUnion);
        }
    }

    /*
     * Create the test VM.
     */
    RTPrintf(TESTCASE ": Initializing...\n");
    PVM pVM;
    rc = VMR3Create(g_cCpus, NULL, NULL, NULL, tstVMMConfigConstructor, NULL, &pVM);
    if (RT_SUCCESS(rc))
    {
        PDMR3LdrEnumModules(pVM, tstVMMLdrEnum, NULL);
        RTStrmFlush(g_pStdOut);
        RTThreadSleep(256);

        /*
         * Do the requested testing.
         */
        switch (enmTestOpt)
        {
            case kTstVMMTest_VMM:
            {
                RTTestSub(hTest, "VMM");
                rc = VMR3ReqCallWait(pVM, VMCPUID_ANY, (PFNRT)VMMDoTest, 1, pVM);
                if (RT_FAILURE(rc))
                    RTTestFailed(hTest, "VMMDoTest failed: rc=%Rrc\n", rc);
                break;
            }

            case kTstVMMTest_TM:
            {
                RTTestSub(hTest, "TM");
                for (VMCPUID idCpu = 1; idCpu < g_cCpus; idCpu++)
                {
                    rc = VMR3ReqCallNoWait(pVM, idCpu, (PFNRT)tstTMWorker, 2, pVM, hTest);
                    if (RT_FAILURE(rc))
                        RTTestFailed(hTest, "VMR3ReqCall failed: rc=%Rrc\n", rc);
                }

                rc = VMR3ReqCallWait(pVM, 0 /*idDstCpu*/, (PFNRT)tstTMWorker, 2, pVM, hTest);
                if (RT_FAILURE(rc))
                    RTTestFailed(hTest, "VMMDoTest failed: rc=%Rrc\n", rc);
                break;
            }
        }

        STAMR3Dump(pVM, "*");

        /*
         * Cleanup.
         */
        rc = VMR3PowerOff(pVM);
        if (RT_FAILURE(rc))
            RTTestFailed(hTest, "VMR3PowerOff failed: rc=%Rrc\n", rc);
        rc = VMR3Destroy(pVM);
        if (RT_FAILURE(rc))
            RTTestFailed(hTest, "VMR3Destroy failed: rc=%Rrc\n", rc);
    }
    else
        RTTestFailed(hTest, "VMR3Create failed: rc=%Rrc\n", rc);

    return RTTestSummaryAndDestroy(hTest);
}
コード例 #18
0
int main()
{
    RTTEST hTest;
    int rc = RTTestInitAndCreate("tstRTStrVersion", &hTest);
    if (rc)
        return rc;
    RTTestBanner(hTest);

    RTTestSub(hTest, "RTStrVersionCompare");
    static struct
    {
        const char *pszVer1;
        const char *pszVer2;
        int         iResult;
    } const aTests[] =
    {
        { "",           "",                 0 },
        { "asdf",       "",                 1 },
        { "asdf234",    "1.4.5",            1 },
        { "12.foo006",  "12.6",             1 },
        { "1",          "1",                0 },
        { "1",          "100",              -1},
        { "100",        "1",                1 },
        { "3",          "4",                -1},
        { "1",          "0.1",              1 },
        { "1",          "0.0.0.0.10000",    1 },
        { "0100",       "100",              0 },
        { "1.0.0",      "1",                0 },
        { "1.0.0",      "100.0.0",          -1},
        { "1",          "1.0.3.0",          -1},
        { "1.4.5",      "1.2.3",            1 },
        { "1.2.3",      "1.4.5",            -1},
        { "1.2.3",      "4.5.6",            -1},
        { "1.0.4",      "1.0.3",            1 },
        { "0.1",        "0.0.1",            1 },
        { "0.0.1",      "0.1.1",            -1},
        { "3.1.0",      "3.0.14",           1 },
        { "2.0.12",     "3.0.14",           -1},
        { "3.1",        "3.0.22",           1 },
        { "3.0.14",     "3.1.0",            -1},
        { "45.63",      "04.560.30",        1 },
        { "45.006",     "45.6",             0 },
        { "23.206",     "23.06",            1 },
        { "23.2",       "23.060",           -1},

        { "VirtualBox-2.0.8-Beta2",     "VirtualBox-2.0.8_Beta3-r12345",    -1 },
        { "VirtualBox-2.2.4-Beta2",     "VirtualBox-2.2.2",                  1 },
        { "VirtualBox-2.2.4-Beta3",     "VirtualBox-2.2.2-Beta4",            1 },
        { "VirtualBox-3.1.8-Alpha1",    "VirtualBox-3.1.8-Alpha1-r61454",   -1 },
        { "VirtualBox-3.1.0",           "VirtualBox-3.1.2_Beta1",           -1 },
        { "3.1.0_BETA-r12345",          "3.1.2",                            -1 },
        { "3.1.0_BETA1r12345",          "3.1.0",                            -1 },
        { "3.1.0_BETAr12345",           "3.1.0",                            -1 },
        { "3.1.0_BETA-r12345",          "3.1.0",                            -1 },
        { "3.1.0_BETA-r12345",          "3.1.0",                            -1 },
        { "3.1.0_BETA-r12345",          "3.1.0.0",                          -1 },
        { "3.1.0_BETA",                 "3.1.0.0",                          -1 },
        { "3.1.0_BETA1",                "3.1.0",                            -1 },
        { "3.1.0_BETA-r12345",          "3.1.0r12345",                      -1 },
        { "3.1.0_BETA1-r12345",         "3.1.0_BETA-r12345",                 0 },
        { "3.1.0_BETA1-r12345",         "3.1.0_BETA1-r12345",                0 },
        { "3.1.0_BETA2-r12345",         "3.1.0_BETA1-r12345",                1 },
        { "3.1.0_BETA2-r12345",         "3.1.0_BETA999-r12345",             -1 },
        { "3.1.0_BETA2",                "3.1.0_ABC",                        -1 }, /* ABC isn't indicating a prerelease, BETA does. */
        { "3.1.0_BETA",                 "3.1.0_ATEB",                       -1 },
        { "4.0.0_ALPHAr68482",          "4.0.0_ALPHAr68483",                -1 },
        { "4.0.0_ALPHA1r68482",         "4.0.0_ALPHAr68482",                 0 },
        { "4.0.0_ALPHA-r68482",         "4.0.0_ALPHAr68482",                 0 },
        { "4.0.0_ALPHAr68483",          "4.0.0_BETAr68783",                 -1 },
        { "4.0.0_ALPHAr68483",          "4.0.0_BETA1r68783",                -1 },
        { "4.0.0_ALPHAr68483",          "4.0.0_BETA2r68783",                -1 },
        { "4.0.0_ALPHAr68483",          "4.0.0_BETA2r68784",                -1 },
        { "4.0.6",                      "4.0.6_Ubuntu",                     -1 }, /* Without stripped guest OS string (Ubuntu). */
        { "4.0.6_Windows",              "4.0.6",                             1 }  /* Without stripped guest OS string (Windows). */
    };
    for (unsigned iTest = 0; iTest < RT_ELEMENTS(aTests); iTest++)
    {
        int iResult = RTStrVersionCompare(aTests[iTest].pszVer1, aTests[iTest].pszVer2);
        if (iResult != aTests[iTest].iResult)
            RTTestFailed(hTest, "#%u: '%s' <-> '%s' -> %d, expected %d",
                         iTest, aTests[iTest].pszVer1, aTests[iTest].pszVer2, iResult, aTests[iTest].iResult);

        iResult = -RTStrVersionCompare(aTests[iTest].pszVer2, aTests[iTest].pszVer1);
        if (iResult != aTests[iTest].iResult)
            RTTestFailed(hTest, "#%u: '%s' <-> '%s' -> %d, expected %d [inv]",
                         iTest, aTests[iTest].pszVer1, aTests[iTest].pszVer2, iResult, aTests[iTest].iResult);
    }

    /*
     * Summary.
     */
    return RTTestSummaryAndDestroy(hTest);
}
コード例 #19
0
ファイル: tstRTJson.cpp プロジェクト: svn2github/virtualbox
/**
 * Tests the iterator API for the given JSON array or object value.
 */
static void tstIterator(RTTEST hTest, RTJSONVAL hJsonVal)
{
    RTJSONIT hJsonIt = NIL_RTJSONIT;
    int rc = RTJsonIteratorBegin(hJsonVal, &hJsonIt);
    RTTEST_CHECK(hTest, RT_SUCCESS(rc));
    if (RT_SUCCESS(rc))
    {
        const char *pszName = NULL;
        RTJSONVAL hJsonValMember = NIL_RTJSONVAL;
        rc = RTJsonIteratorQueryValue(hJsonIt, &hJsonValMember, &pszName);
        RTTEST_CHECK(hTest, RT_SUCCESS(rc));
        RTTEST_CHECK(hTest, pszName != NULL);
        RTTEST_CHECK(hTest, hJsonValMember != NIL_RTJSONVAL);
        while (RT_SUCCESS(rc))
        {
            RTJSONVALTYPE enmTypeMember = RTJsonValueGetType(hJsonValMember);
            tstCorrectnessRcForInvalidType(hTest, hJsonValMember, enmTypeMember);

            switch (enmTypeMember)
            {
                case RTJSONVALTYPE_OBJECT:
                    RTTEST_CHECK(hTest, strcmp(pszName, "subobject") == 0);
                    tstIterator(hTest, hJsonValMember);
                    break;
                case RTJSONVALTYPE_ARRAY:
                    RTTEST_CHECK(hTest, strcmp(pszName, "array") == 0);
                    tstArray(hTest, hJsonValMember);
                    break;
                case RTJSONVALTYPE_STRING:
                {
                    RTTEST_CHECK(hTest, strcmp(pszName, "string") == 0);
                    const char *pszStr = NULL;
                    RTTEST_CHECK_RC_OK(hTest, RTJsonValueQueryString(hJsonValMember, &pszStr));
                    RTTEST_CHECK(hTest, strcmp(pszStr, "test") == 0);
                    break;
                }
                case RTJSONVALTYPE_NUMBER:
                {
                    RTTEST_CHECK(hTest, strcmp(pszName, "number") == 0);
                    int64_t i64Num = 0;
                    RTTEST_CHECK_RC_OK(hTest, RTJsonValueQueryInteger(hJsonValMember, &i64Num));
                    RTTEST_CHECK(hTest, i64Num == 100);
                    break;
                }
                case RTJSONVALTYPE_NULL:
                    RTTEST_CHECK(hTest, strcmp(pszName, "null") == 0);
                    break;
                case RTJSONVALTYPE_TRUE:
                    RTTEST_CHECK(hTest, strcmp(pszName, "true") == 0);
                    break;
                case RTJSONVALTYPE_FALSE:
                    RTTEST_CHECK(hTest, strcmp(pszName, "false") == 0);
                    break;
                default:
                    RTTestFailed(hTest, "Invalid JSON value type %u returned\n", enmTypeMember);
            }

            RTTEST_CHECK(hTest, RTJsonValueRelease(hJsonValMember) == 1);
            rc = RTJsonIteratorNext(hJsonIt);
            RTTEST_CHECK(hTest, rc == VINF_SUCCESS || rc == VERR_JSON_ITERATOR_END);
            if (RT_SUCCESS(rc))
                RTTEST_CHECK_RC_OK(hTest, RTJsonIteratorQueryValue(hJsonIt, &hJsonValMember, &pszName));
        }
        RTJsonIteratorFree(hJsonIt);
    }
}
コード例 #20
0
ファイル: tstDBGCParser.cpp プロジェクト: miguelinux/vbox
/**
 * Tries one command string.
 * @param   pDbgc           Pointer to the debugger instance.
 * @param   pszCmds         The command to test.
 * @param   rcCmd           The expected result.
 * @param   fNoExecute      When set, the command is not executed.
 * @param   pszExpected     Expected output.  This does not need to include all
 *                          of the output, just the start of it.  Thus the
 *                          prompt can be omitted.
 * @param   cArgs           The number of expected arguments. -1 if we don't
 *                          want to check the parsed arguments.
 * @param   va              Info about expected parsed arguments. For each
 *                          argument a DBGCVARTYPE, value (depends on type),
 *                          DBGCVARRANGETYPE and optionally range value.
 */
static void tstTryExV(PDBGC pDbgc, const char *pszCmds, int rcCmd, bool fNoExecute, const char *pszExpected,
                      int32_t cArgs, va_list va)
{
    RT_ZERO(g_szOutput);
    g_offOutput = 0;
    g_pszInput = pszCmds;
    if (strchr(pszCmds, '\0')[-1] == '\n')
        RTTestPrintfNl(g_hTest, RTTESTLVL_ALWAYS, "RUNNING: %s", pszCmds);
    else
        RTTestPrintfNl(g_hTest, RTTESTLVL_ALWAYS, "RUNNING: %s\n", pszCmds);

    pDbgc->rcCmd = VERR_INTERNAL_ERROR;
    dbgcProcessInput(pDbgc, fNoExecute);
    tstCompleteOutput();

    if (pDbgc->rcCmd != rcCmd)
        RTTestFailed(g_hTest, "rcCmd=%Rrc expected =%Rrc\n", pDbgc->rcCmd, rcCmd);
    else if (   !fNoExecute
             && pszExpected
             && strncmp(pszExpected, g_szOutput, strlen(pszExpected)))
        RTTestFailed(g_hTest, "Wrong output - expected \"%s\"", pszExpected);

    if (cArgs >= 0)
    {
        PCDBGCVAR paArgs = pDbgc->aArgs;
        for (int32_t iArg = 0; iArg < cArgs; iArg++)
        {
            DBGCVAR ExpectedArg;
            ExpectedArg.enmType = (DBGCVARTYPE)va_arg(va, int/*DBGCVARTYPE*/);
            switch (ExpectedArg.enmType)
            {
                case DBGCVAR_TYPE_GC_FLAT:  ExpectedArg.u.GCFlat    = va_arg(va, RTGCPTR); break;
                case DBGCVAR_TYPE_GC_FAR:   ExpectedArg.u.GCFar.sel = va_arg(va, int /*RTSEL*/);
                                            ExpectedArg.u.GCFar.off = va_arg(va, uint32_t); break;
                case DBGCVAR_TYPE_GC_PHYS:  ExpectedArg.u.GCPhys    = va_arg(va, RTGCPHYS); break;
                case DBGCVAR_TYPE_HC_FLAT:  ExpectedArg.u.pvHCFlat  = va_arg(va, void *); break;
                case DBGCVAR_TYPE_HC_PHYS:  ExpectedArg.u.HCPhys    = va_arg(va, RTHCPHYS); break;
                case DBGCVAR_TYPE_NUMBER:   ExpectedArg.u.u64Number = va_arg(va, uint64_t); break;
                case DBGCVAR_TYPE_STRING:   ExpectedArg.u.pszString = va_arg(va, const char *); break;
                case DBGCVAR_TYPE_SYMBOL:   ExpectedArg.u.pszString = va_arg(va, const char *); break;
                default:
                    RTTestFailed(g_hTest, "enmType=%u iArg=%u\n", ExpectedArg.enmType, iArg);
                    ExpectedArg.u.u64Number = 0;
                    break;
            }
            ExpectedArg.enmRangeType = (DBGCVARRANGETYPE)va_arg(va, int /*DBGCVARRANGETYPE*/);
            switch (ExpectedArg.enmRangeType)
            {
                case DBGCVAR_RANGE_NONE:        ExpectedArg.u64Range = 0; break;
                case DBGCVAR_RANGE_ELEMENTS:    ExpectedArg.u64Range = va_arg(va, uint64_t); break;
                case DBGCVAR_RANGE_BYTES:       ExpectedArg.u64Range = va_arg(va, uint64_t); break;
                    default:
                        RTTestFailed(g_hTest, "enmRangeType=%u iArg=%u\n", ExpectedArg.enmRangeType, iArg);
                        ExpectedArg.u64Range = 0;
                        break;
            }

            if (!DBGCVarAreIdentical(&ExpectedArg, &paArgs[iArg]))
                RTTestFailed(g_hTest,
                             "Arg #%u\n"
                             "actual:   enmType=%u u64=%#RX64 enmRangeType=%u u64Range=%#RX64\n"
                             "expected: enmType=%u u64=%#RX64 enmRangeType=%u u64Range=%#RX64\n",
                             iArg,
                             paArgs[iArg].enmType, paArgs[iArg].u.u64Number, paArgs[iArg].enmRangeType, paArgs[iArg].u64Range,
                             ExpectedArg.enmType, ExpectedArg.u.u64Number, ExpectedArg.enmRangeType, ExpectedArg.u64Range);
        }
    }
コード例 #21
0
ファイル: tstIntNetR0.cpp プロジェクト: LastRitter/vbox-haiku
/**
 * Receive thread.
 * This is reading stuff from the network.
 */
DECLCALLBACK(int) ReceiveThread(RTTHREAD Thread, void *pvArg)
{
    uint32_t    cbReceived  = 0;
    uint32_t    cLostFrames = 0;
    uint32_t    iFrame      = UINT32_MAX;
    PMYARGS     pArgs       = (PMYARGS)pvArg;
    for (;;)
    {
        /*
         * Read data.
         */
        while (IntNetRingHasMoreToRead(&pArgs->pBuf->Recv))
        {
            uint8_t     abBuf[16384 + 1024];
            MYFRAMEHDR *pHdr = (MYFRAMEHDR *)&abBuf[0];
            uint32_t    cb   = IntNetRingReadAndSkipFrame(&pArgs->pBuf->Recv, abBuf);

            /* check for termination frame. */
            if (    pHdr->iFrame   == 0xffffdead
                &&  pHdr->auEos[0] == 0xffffdead
                &&  pHdr->auEos[1] == 0xffffdead
                &&  pHdr->auEos[2] == 0xffffdead)
            {
                pArgs->u64End = RTTimeNanoTS();
                RTThreadSleep(10);
                RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS,
                             "receiver thread %.6Rhxs terminating.\n"
                             "  iFrame=%u  cb=%'u  c=%'u  %'uKB/s  %'ufps  cLost=%'u \n",
                             &pArgs->Mac, iFrame, cbReceived, iFrame - cLostFrames,
                             (unsigned)(cbReceived * 1000000000.0 / 1024 / (pArgs->u64End - pArgs->u64Start)),
                             (unsigned)((iFrame - cLostFrames) * 1000000000.0 / (pArgs->u64End - pArgs->u64Start)),
                             cLostFrames);
                return VINF_SUCCESS;
            }

            /* validate frame header */
            if (    pHdr->DstMac.au16[0] != pArgs->Mac.au16[0]
                ||  pHdr->DstMac.au16[1] != pArgs->Mac.au16[1]
                ||  pHdr->DstMac.au16[2] != pArgs->Mac.au16[2]
                ||  pHdr->SrcMac.au16[0] != pArgs->Mac.au16[0]
                ||  pHdr->SrcMac.au16[1] != pArgs->Mac.au16[1]
                ||  pHdr->SrcMac.au16[2] != (pArgs->Mac.au16[2] + 1) % 2)
            {
                RTTestFailed(g_hTest, "receiver thread %.6Rhxs received frame header: %.16Rhxs\n", &pArgs->Mac, abBuf);
            }

            /* frame stuff and stats. */
            int32_t off = pHdr->iFrame - (iFrame + 1);
            if (off)
            {
                if (off > 0)
                {
#ifndef IGNORE_LOST_FRAMES
                    RTTestFailed(g_hTest, "receiver thread %.6Rhxs: iFrame=%#x *puFrame=%#x off=%d\n",
                                 &pArgs->Mac, iFrame, pHdr->iFrame, off);
#endif
                    cLostFrames += off;
                }
                else
                {
                    cLostFrames++;
                    RTTestFailed(g_hTest, "receiver thread %.6Rhxs: iFrame=%#x *puFrame=%#x off=%d\n",
                                 &pArgs->Mac, iFrame, pHdr->iFrame, off);
                }
            }
            iFrame = pHdr->iFrame;
            cbReceived += cb;
        }

        /*
         * Wait for data.
         */
        int rc = IntNetR0IfWait(pArgs->hIf, g_pSession, RT_INDEFINITE_WAIT);
        switch (rc)
        {
            case VERR_INTERRUPTED:
            case VINF_SUCCESS:
                break;
            case VERR_SEM_DESTROYED:
                RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS,
                             "receiver thread %.6Rhxs terminating. iFrame=%u cb=%'u c=%'u cLost=%'u\n",
                             &pArgs->Mac, iFrame, cbReceived, iFrame - cLostFrames, cLostFrames);
                return VINF_SUCCESS;

            default:
                RTTestFailed(g_hTest, "receiver thread %.6Rhxs got odd return value %Rrc! iFrame=%u cb=%'u c=%'u cLost=%'u\n",
                             &pArgs->Mac, rc, iFrame, cbReceived, iFrame - cLostFrames, cLostFrames);
                return rc;
        }

    }
}
コード例 #22
0
int main(int argc, char **argv)
{
    RTEXITCODE rcExit = RTTestInitAndCreate("tstRTPrfIO", &g_hTest);
    if (rcExit != RTEXITCODE_SUCCESS)
        return rcExit;
    RTTestBanner(g_hTest);

    /*
     * Parse arguments
     */
    static const RTGETOPTDEF s_aOptions[] =
    {
        { "--test-dir",     'd',    RTGETOPT_REQ_STRING },
    };
    bool fFileOpenCloseTest = true;
    bool fFileWriteByteTest = true;
    bool fPathQueryInfoTest = true;
    //bool fFileTests = true;
    //bool fDirTests  = true;

    int ch;
    RTGETOPTUNION ValueUnion;
    RTGETOPTSTATE GetState;
    RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, 0);
    while ((ch = RTGetOpt(&GetState, &ValueUnion)))
    {
        switch (ch)
        {
            case 'd':
                g_pszTestDir = ValueUnion.psz;
                break;

            case 'V':
                RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "$Revision$\n");
                return RTTestSummaryAndDestroy(g_hTest);

            case 'h':
                RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "usage: testname [-d <testdir>]\n");
                return RTTestSummaryAndDestroy(g_hTest);

            default:
                RTTestFailed(g_hTest, "invalid argument");
                RTGetOptPrintError(ch, &ValueUnion);
                return RTTestSummaryAndDestroy(g_hTest);
        }
    }

    /*
     * Set up and check the prerequisites.
     */
    RTTESTI_CHECK_RC(RTPathJoin(g_szTestFile1,      sizeof(g_szTestFile1),      g_pszTestDir, "tstRTPrfIO-TestFile1"), VINF_SUCCESS);
    RTTESTI_CHECK_RC(RTPathJoin(g_szTestDir1,       sizeof(g_szTestDir1),       g_pszTestDir, "tstRTPrfIO-TestDir1"), VINF_SUCCESS);
    RTTESTI_CHECK_RC(RTPathJoin(g_szNotExitingFile, sizeof(g_szNotExitingFile), g_pszTestDir, "tstRTPrfIO-nonexistent-file"), VINF_SUCCESS);
    RTTESTI_CHECK_RC(RTPathJoin(g_szNotExitingDir,  sizeof(g_szNotExitingDir),  g_pszTestDir, "tstRTPrfIO-nonexistent-dir"), VINF_SUCCESS);
    RTTESTI_CHECK_RC(RTPathJoin(g_szNotExitingDirFile, sizeof(g_szNotExitingDirFile),  g_szNotExitingDir, "nonexistent-file"), VINF_SUCCESS);
    RTTESTI_CHECK(RTDirExists(g_pszTestDir));
    if (RTPathExists(g_szTestDir1))
        RTTestFailed(g_hTest, "The primary test directory (%s) already exist, please remove it", g_szTestDir1);
    if (RTPathExists(g_szTestFile1))
        RTTestFailed(g_hTest, "The primary test file (%s) already exist, please remove it", g_szTestFile1);
    if (RTPathExists(g_szNotExitingFile))
        RTTestFailed(g_hTest, "'%s' exists, remove it", g_szNotExitingFile);
    if (RTPathExists(g_szNotExitingDir))
        RTTestFailed(g_hTest, "'%s' exists, remove it", g_szNotExitingDir);
    if (RTPathExists(g_szNotExitingDirFile))
        RTTestFailed(g_hTest, "'%s' exists, remove it", g_szNotExitingDirFile);

    /*
     * Do the testing.
     */
    if (RTTestIErrorCount() == 0)
    {
#if 1
        if (fPathQueryInfoTest)
            benchmarkPathQueryInfo();
        if (fFileOpenCloseTest)
            benchmarkFileOpenClose();
#endif
        if (fFileWriteByteTest)
            benchmarkFileWriteByte();
        //if (fFileTests)
        //    benchmarkFile();
        //if (fDirTests)
        //    benchmarkDir();

        /*
         * Cleanup.
         */
        RTFileDelete(g_szTestFile1);
        RTDirRemoveRecursive(g_szTestDir1, 0);
        RTTESTI_CHECK(RTDirExists(g_pszTestDir));
        RTTESTI_CHECK(!RTPathExists(g_szTestDir1));
        RTTESTI_CHECK(!RTPathExists(g_szTestFile1));
    }

    return RTTestSummaryAndDestroy(g_hTest);
}
コード例 #23
0
ファイル: tstSupSem-Zombie.cpp プロジェクト: miguelinux/vbox
static int mainChild(void)
{
    /*
     * Init.
     */
    int rc = RTR3InitExeNoArguments(RTR3INIT_FLAGS_SUPLIB);
    if (RT_FAILURE(rc))
    {
        RTPrintf("tstSupSem-Zombie-Child: fatal error: RTR3InitExeNoArguments failed with rc=%Rrc\n", rc);
        return 1;
    }

    RTTEST hTest;
    rc = RTTestCreate("tstSupSem-Zombie-Child", &hTest);
    if (RT_FAILURE(rc))
    {
        RTPrintf("tstSupSem-Zombie-Child: fatal error: RTTestCreate failed with rc=%Rrc\n", rc);
        return 1;
    }
    g_hTest = hTest;

    PSUPDRVSESSION pSession;
    rc = SUPR3Init(&pSession);
    if (RT_FAILURE(rc))
    {
        RTTestFailed(hTest, "SUPR3Init failed with rc=%Rrc\n", rc);
        return RTTestSummaryAndDestroy(hTest);
    }
    g_pSession = pSession;

    /*
     * A semaphore of each kind and throw a bunch of threads on them.
     */
    SUPSEMEVENT hEvent = NIL_SUPSEMEVENT;
    RTTESTI_CHECK_RC(rc = SUPSemEventCreate(pSession, &hEvent), VINF_SUCCESS);
    if (RT_SUCCESS(rc))
    {
        SUPSEMEVENTMULTI hEventMulti = NIL_SUPSEMEVENT;
        RTTESTI_CHECK_RC(SUPSemEventMultiCreate(pSession, &hEventMulti), VINF_SUCCESS);
        if (RT_SUCCESS(rc))
        {
            for (uint32_t cThreads = 0; cThreads < 5; cThreads++)
            {
                RTTHREAD hThread;
                RTTESTI_CHECK_RC(RTThreadCreate(&hThread, tstSupSemSRETimed, (void *)hEvent,      0, RTTHREADTYPE_TIMER, 0 /*fFlags*/, "IntSRE"), VINF_SUCCESS);
                RTTESTI_CHECK_RC(RTThreadCreate(&hThread, tstSupSemMRETimed, (void *)hEventMulti, 0, RTTHREADTYPE_TIMER, 0 /*fFlags*/, "IntMRE"), VINF_SUCCESS);
                RTTESTI_CHECK_RC(RTThreadCreate(&hThread, tstSupSemSREInf,   (void *)hEvent,      0, RTTHREADTYPE_TIMER, 0 /*fFlags*/, "IntSRE"), VINF_SUCCESS);
                RTTESTI_CHECK_RC(RTThreadCreate(&hThread, tstSupSemMREInf,   (void *)hEventMulti, 0, RTTHREADTYPE_TIMER, 0 /*fFlags*/, "IntMRE"), VINF_SUCCESS);
                RTThreadSleep(2);
            }
            RTThreadSleep(50);

            /*
             * This is where the test really starts...
             */
            return 0;
        }
    }

    return RTTestSummaryAndDestroy(hTest);
}
コード例 #24
0
static DECLCALLBACK(int) Test4Thread(RTTHREAD ThreadSelf, void *pvUser)
{
    /* Use randomization to get a little more variation of the sync pattern.
       We use a pseudo random generator here so that we don't end up testing
       the speed of the /dev/urandom implementation, but rather the read-write
       semaphores. */
    int rc;
    RTRAND hRand;
    RTTEST_CHECK_RC_OK_RET(g_hTest, rc = RTRandAdvCreateParkMiller(&hRand), rc);
    RTTEST_CHECK_RC_OK_RET(g_hTest, rc = RTRandAdvSeed(hRand, (uintptr_t)ThreadSelf), rc);
    unsigned c100 = RTRandAdvU32Ex(hRand, 0, 99);

    uint64_t *pcItr = (uint64_t *)pvUser;
    bool fWrite;
    for (;;)
    {
        unsigned readrec = RTRandAdvU32Ex(hRand, 0, 3);
        unsigned writerec = RTRandAdvU32Ex(hRand, 0, 3);
        /* Don't overdo recursion testing. */
        if (readrec > 1)
            readrec--;
        if (writerec > 1)
            writerec--;

        fWrite = (c100 < g_uWritePercent);
        if (fWrite)
        {
            for (unsigned i = 0; i <= writerec; i++)
            {
                rc = RTCritSectRwEnterExcl(&g_CritSectRw);
                if (RT_FAILURE(rc))
                {
                    RTTestFailed(g_hTest, "Write recursion %u on %s failed with rc=%Rrc", i, RTThreadSelfName(), rc);
                    break;
                }
            }
            if (RT_FAILURE(rc))
                break;
            if (ASMAtomicIncU32(&g_cConcurrentWriters) != 1)
            {
                RTTestFailed(g_hTest, "g_cConcurrentWriters=%u on %s after write locking it",
                             g_cConcurrentWriters, RTThreadSelfName());
                break;
            }
            if (g_cConcurrentReaders != 0)
            {
                RTTestFailed(g_hTest, "g_cConcurrentReaders=%u on %s after write locking it",
                             g_cConcurrentReaders, RTThreadSelfName());
                break;
            }
        }
        else
        {
            rc = RTCritSectRwEnterShared(&g_CritSectRw);
            if (RT_FAILURE(rc))
            {
                RTTestFailed(g_hTest, "Read locking on %s failed with rc=%Rrc", RTThreadSelfName(), rc);
                break;
            }
            ASMAtomicIncU32(&g_cConcurrentReaders);
            if (g_cConcurrentWriters != 0)
            {
                RTTestFailed(g_hTest, "g_cConcurrentWriters=%u on %s after read locking it",
                             g_cConcurrentWriters, RTThreadSelfName());
                break;
            }
        }
        for (unsigned i = 0; i < readrec; i++)
        {
            rc = RTCritSectRwEnterShared(&g_CritSectRw);
            if (RT_FAILURE(rc))
            {
                RTTestFailed(g_hTest, "Read recursion %u on %s failed with rc=%Rrc", i, RTThreadSelfName(), rc);
                break;
            }
        }
        if (RT_FAILURE(rc))
            break;

        /*
         * Check for fairness: The values of the threads should not differ too much
         */
        (*pcItr)++;

        /*
         * Check for correctness: Give other threads a chance. If the implementation is
         * correct, no other thread will be able to enter this lock now.
         */
        if (g_fYield)
            RTThreadYield();

        for (unsigned i = 0; i < readrec; i++)
        {
            rc = RTCritSectRwLeaveShared(&g_CritSectRw);
            if (RT_FAILURE(rc))
            {
                RTTestFailed(g_hTest, "Read release %u on %s failed with rc=%Rrc", i, RTThreadSelfName(), rc);
                break;
            }
        }
        if (RT_FAILURE(rc))
            break;

        if (fWrite)
        {
            if (ASMAtomicDecU32(&g_cConcurrentWriters) != 0)
            {
                RTTestFailed(g_hTest, "g_cConcurrentWriters=%u on %s before write release",
                             g_cConcurrentWriters, RTThreadSelfName());
                break;
            }
            if (g_cConcurrentReaders != 0)
            {
                RTTestFailed(g_hTest, "g_cConcurrentReaders=%u on %s before write release",
                             g_cConcurrentReaders, RTThreadSelfName());
                break;
            }
            for (unsigned i = 0; i <= writerec; i++)
            {
                rc = RTCritSectRwLeaveExcl(&g_CritSectRw);
                if (RT_FAILURE(rc))
                {
                    RTTestFailed(g_hTest, "Write release %u on %s failed with rc=%Rrc", i, RTThreadSelfName(), rc);
                    break;
                }
            }
        }
        else
        {
            if (g_cConcurrentWriters != 0)
            {
                RTTestFailed(g_hTest, "g_cConcurrentWriters=%u on %s before read release",
                             g_cConcurrentWriters, RTThreadSelfName());
                break;
            }
            ASMAtomicDecU32(&g_cConcurrentReaders);
            rc = RTCritSectRwLeaveShared(&g_CritSectRw);
            if (RT_FAILURE(rc))
            {
                RTTestFailed(g_hTest, "Read release on %s failed with rc=%Rrc", RTThreadSelfName(), rc);
                break;
            }
        }

        if (g_fTerminate)
            break;

        c100++;
        c100 %= 100;
    }
    if (!g_fQuiet)
        RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Thread %s exited with %lld\n", RTThreadSelfName(), *pcItr);
    RTRandAdvDestroy(hRand);
    return VINF_SUCCESS;
}
コード例 #25
0
ファイル: tstSupSem.cpp プロジェクト: rickysarraf/virtualbox
int main(int argc, char **argv)
{
    bool fSys = true;
    bool fGip = false;
#if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2)
    fGip = true;
#endif

    /*
     * Init.
     */
    int rc = RTR3InitExe(argc, &argv, RTR3INIT_FLAGS_SUPLIB);
    if (RT_FAILURE(rc))
        return RTMsgInitFailure(rc);

    if (argc == 2 && !strcmp(argv[1], "child"))
    {
        RTThreadSleep(300);
        return 0;
    }

    RTTEST hTest;
    rc = RTTestCreate("tstSupSem", &hTest);
    if (RT_FAILURE(rc))
    {
        RTPrintf("tstSupSem: fatal error: RTTestCreate failed with rc=%Rrc\n", rc);
        return 1;
    }
    g_hTest = hTest;

    PSUPDRVSESSION pSession;
    rc = SUPR3Init(&pSession);
    if (RT_FAILURE(rc))
    {
        RTTestFailed(hTest, "SUPR3Init failed with rc=%Rrc\n", rc);
        return RTTestSummaryAndDestroy(hTest);
    }
    g_pSession = pSession;
    RTTestBanner(hTest);

    /*
     * Basic API checks.
     */
    RTTestSub(hTest, "Single Release Event (SRE) API");
    SUPSEMEVENT hEvent = NIL_SUPSEMEVENT;
    RTTESTI_CHECK_RC(SUPSemEventCreate(pSession, &hEvent),          VINF_SUCCESS);
    RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent, 0),  VERR_TIMEOUT);
    RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent, 1),  VERR_TIMEOUT);
    RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent, 2),  VERR_TIMEOUT);
    RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent, 8),  VERR_TIMEOUT);
    RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent,20),  VERR_TIMEOUT);
    RTTESTI_CHECK_RC(SUPSemEventSignal(pSession, hEvent),           VINF_SUCCESS);
    RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent, 0),  VINF_SUCCESS);
    RTTESTI_CHECK_RC(SUPSemEventSignal(pSession, hEvent),           VINF_SUCCESS);
    RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent, 1),  VINF_SUCCESS);
    RTTESTI_CHECK_RC(SUPSemEventSignal(pSession, hEvent),           VINF_SUCCESS);
    RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent, 2),  VINF_SUCCESS);
    RTTESTI_CHECK_RC(SUPSemEventSignal(pSession, hEvent),           VINF_SUCCESS);
    RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent, 8),  VINF_SUCCESS);
    RTTESTI_CHECK_RC(SUPSemEventSignal(pSession, hEvent),           VINF_SUCCESS);
    RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent, 20), VINF_SUCCESS);
    RTTESTI_CHECK_RC(SUPSemEventSignal(pSession, hEvent),           VINF_SUCCESS);
    RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent,1000),VINF_SUCCESS);
    RTTESTI_CHECK_RC(SUPSemEventSignal(pSession, hEvent),           VINF_SUCCESS);
    RTTESTI_CHECK_RC(SUPSemEventSignal(pSession, hEvent),           VINF_SUCCESS);
    RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent, 0),  VINF_SUCCESS);
    RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent, 0),  VERR_TIMEOUT);
    RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent, 1),  VERR_TIMEOUT);
    RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent, 2),  VERR_TIMEOUT);
    RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent, 8),  VERR_TIMEOUT);
    RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent,20),  VERR_TIMEOUT);
    RTTESTI_CHECK_RC(SUPSemEventClose(pSession, hEvent),            VINF_OBJECT_DESTROYED);
    RTTESTI_CHECK_RC(SUPSemEventClose(pSession, hEvent),            VERR_INVALID_HANDLE);
    RTTESTI_CHECK_RC(SUPSemEventClose(pSession, NIL_SUPSEMEVENT),   VINF_SUCCESS);

    RTTestSub(hTest, "Multiple Release Event (MRE) API");
    SUPSEMEVENTMULTI hEventMulti = NIL_SUPSEMEVENT;
    RTTESTI_CHECK_RC(SUPSemEventMultiCreate(pSession, &hEventMulti),            VINF_SUCCESS);
    RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 0),    VERR_TIMEOUT);
    RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 1),    VERR_TIMEOUT);
    RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 2),    VERR_TIMEOUT);
    RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 8),    VERR_TIMEOUT);
    RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti,20),    VERR_TIMEOUT);
    RTTESTI_CHECK_RC(SUPSemEventMultiSignal(pSession, hEventMulti),             VINF_SUCCESS);
    RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 0),    VINF_SUCCESS);
    RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 0),    VINF_SUCCESS);
    RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 0),    VINF_SUCCESS);
    RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 1),    VINF_SUCCESS);
    RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 2),    VINF_SUCCESS);
    RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 8),    VINF_SUCCESS);
    RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti,20),    VINF_SUCCESS);
    RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti,1000),  VINF_SUCCESS);
    RTTESTI_CHECK_RC(SUPSemEventMultiSignal(pSession, hEventMulti),             VINF_SUCCESS);
    RTTESTI_CHECK_RC(SUPSemEventMultiSignal(pSession, hEventMulti),             VINF_SUCCESS);
    RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 0),    VINF_SUCCESS);
    RTTESTI_CHECK_RC(SUPSemEventMultiReset(pSession, hEventMulti),              VINF_SUCCESS);
    RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 0),    VERR_TIMEOUT);
    RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 1),    VERR_TIMEOUT);
    RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 2),    VERR_TIMEOUT);
    RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 8),    VERR_TIMEOUT);
    RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti,20),    VERR_TIMEOUT);
    RTTESTI_CHECK_RC(SUPSemEventMultiSignal(pSession, hEventMulti),             VINF_SUCCESS);
    RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 0),    VINF_SUCCESS);
    RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 1),    VINF_SUCCESS);
    RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 2),    VINF_SUCCESS);
    RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 8),    VINF_SUCCESS);
    RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 20),   VINF_SUCCESS);
    RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti,1000),  VINF_SUCCESS);
    RTTESTI_CHECK_RC(SUPSemEventMultiClose(pSession, hEventMulti),              VINF_OBJECT_DESTROYED);
    RTTESTI_CHECK_RC(SUPSemEventMultiClose(pSession, hEventMulti),              VERR_INVALID_HANDLE);
    RTTESTI_CHECK_RC(SUPSemEventMultiClose(pSession, NIL_SUPSEMEVENTMULTI),     VINF_SUCCESS);

#if !defined(RT_OS_OS2) && !defined(RT_OS_WINDOWS)
    RTTestSub(hTest, "SRE Interruptibility");
    RTTESTI_CHECK_RC(SUPSemEventCreate(pSession, &hEvent), VINF_SUCCESS);
    g_cMillies = RT_INDEFINITE_WAIT;
    RTTHREAD hThread = NIL_RTTHREAD;
    RTTESTI_CHECK_RC(RTThreadCreate(&hThread, tstSupSemInterruptibleSRE, (void *)hEvent, 0, RTTHREADTYPE_TIMER, RTTHREADFLAGS_WAITABLE, "IntSRE"), VINF_SUCCESS);
    RTTESTI_CHECK_RC(RTThreadUserWait(hThread, 60*1000), VINF_SUCCESS);
    RTThreadSleep(120);
    RTThreadPoke(hThread);
    int rcThread = VINF_SUCCESS;
    RTTESTI_CHECK_RC(RTThreadWait(hThread, 60*1000, &rcThread), VINF_SUCCESS);
    RTTESTI_CHECK_RC(rcThread, VERR_INTERRUPTED);
    RTTESTI_CHECK_RC(SUPSemEventClose(pSession, hEvent), VINF_OBJECT_DESTROYED);

    RTTESTI_CHECK_RC(SUPSemEventCreate(pSession, &hEvent), VINF_SUCCESS);
    g_cMillies = 120*1000;
    hThread = NIL_RTTHREAD;
    RTTESTI_CHECK_RC(RTThreadCreate(&hThread, tstSupSemInterruptibleSRE, (void *)hEvent, 0, RTTHREADTYPE_TIMER, RTTHREADFLAGS_WAITABLE, "IntSRE"), VINF_SUCCESS);
    RTTESTI_CHECK_RC(RTThreadUserWait(hThread, 60*1000), VINF_SUCCESS);
    RTThreadSleep(120);
    RTThreadPoke(hThread);
    rcThread = VINF_SUCCESS;
    RTTESTI_CHECK_RC(RTThreadWait(hThread, 60*1000, &rcThread), VINF_SUCCESS);
    RTTESTI_CHECK_RC(rcThread, VERR_INTERRUPTED);
    RTTESTI_CHECK_RC(SUPSemEventClose(pSession, hEvent), VINF_OBJECT_DESTROYED);


    RTTestSub(hTest, "MRE Interruptibility");
    RTTESTI_CHECK_RC(SUPSemEventMultiCreate(pSession, &hEventMulti), VINF_SUCCESS);
    g_cMillies = RT_INDEFINITE_WAIT;
    hThread = NIL_RTTHREAD;
    RTTESTI_CHECK_RC(RTThreadCreate(&hThread, tstSupSemInterruptibleMRE, (void *)hEventMulti, 0, RTTHREADTYPE_TIMER, RTTHREADFLAGS_WAITABLE, "IntMRE"), VINF_SUCCESS);
    RTTESTI_CHECK_RC(RTThreadUserWait(hThread, 60*1000), VINF_SUCCESS);
    RTThreadSleep(120);
    RTThreadPoke(hThread);
    rcThread = VINF_SUCCESS;
    RTTESTI_CHECK_RC(RTThreadWait(hThread, 60*1000, &rcThread), VINF_SUCCESS);
    RTTESTI_CHECK_RC(rcThread, VERR_INTERRUPTED);
    RTTESTI_CHECK_RC(SUPSemEventMultiClose(pSession, hEventMulti), VINF_OBJECT_DESTROYED);

    RTTESTI_CHECK_RC(SUPSemEventMultiCreate(pSession, &hEventMulti), VINF_SUCCESS);
    g_cMillies = 120*1000;
    hThread = NIL_RTTHREAD;
    RTTESTI_CHECK_RC(RTThreadCreate(&hThread, tstSupSemInterruptibleMRE, (void *)hEventMulti, 0, RTTHREADTYPE_TIMER, RTTHREADFLAGS_WAITABLE, "IntMRE"), VINF_SUCCESS);
    RTTESTI_CHECK_RC(RTThreadUserWait(hThread, 60*1000), VINF_SUCCESS);
    RTThreadSleep(120);
    RTThreadPoke(hThread);
    rcThread = VINF_SUCCESS;
    RTTESTI_CHECK_RC(RTThreadWait(hThread, 60*1000, &rcThread), VINF_SUCCESS);
    RTTESTI_CHECK_RC(rcThread, VERR_INTERRUPTED);
    RTTESTI_CHECK_RC(SUPSemEventMultiClose(pSession, hEventMulti), VINF_OBJECT_DESTROYED);

    /*
     * Fork test.
     * Spawn a thread waiting for an event, then spawn a new child process (of
     * ourselves) and make sure that this does not alter the intended behaviour
     * of our event semaphore implementation (see @bugref{5090}).
     */
    RTTestSub(hTest, "SRE Process Spawn");
    hThread = NIL_RTTHREAD;
    g_cMillies = 120*1000;
    RTTESTI_CHECK_RC(SUPSemEventCreate(pSession, &hEvent), VINF_SUCCESS);
    RTTESTI_CHECK_RC(RTThreadCreate(&hThread, tstSupSemInterruptibleSRE, (void *)hEvent, 0, RTTHREADTYPE_TIMER, RTTHREADFLAGS_WAITABLE, "IntSRE"), VINF_SUCCESS);

    const char *apszArgs[3] = { argv[0], "child", NULL };
    RTPROCESS Process = NIL_RTPROCESS;
    RTThreadSleep(250);
    RTTESTI_CHECK_RC(RTProcCreate(apszArgs[0], apszArgs, RTENV_DEFAULT, 0, &Process), VINF_SUCCESS);

    RTThreadSleep(250);
    RTTESTI_CHECK_RC(SUPSemEventSignal(pSession, hEvent), VINF_SUCCESS);

    rcThread = VERR_GENERAL_FAILURE;
    RTTESTI_CHECK_RC(RTThreadWait(hThread, 120*1000, &rcThread), VINF_SUCCESS);
    RTTESTI_CHECK_RC(rcThread, VINF_SUCCESS);
    RTTESTI_CHECK_RC(SUPSemEventClose(pSession, hEvent), VINF_OBJECT_DESTROYED);


    RTTestSub(hTest, "MRE Process Spawn");
    hThread = NIL_RTTHREAD;
    g_cMillies = 120*1000;
    RTTESTI_CHECK_RC(SUPSemEventMultiCreate(pSession, &hEvent), VINF_SUCCESS);
    RTTESTI_CHECK_RC(RTThreadCreate(&hThread, tstSupSemInterruptibleMRE, (void *)hEvent, 0, RTTHREADTYPE_TIMER, RTTHREADFLAGS_WAITABLE, "IntSRE"), VINF_SUCCESS);

    RTTHREAD hThread2 = NIL_RTTHREAD;
    RTTESTI_CHECK_RC(RTThreadCreate(&hThread2, tstSupSemInterruptibleMRE, (void *)hEvent, 0, RTTHREADTYPE_TIMER, RTTHREADFLAGS_WAITABLE, "IntSRE"), VINF_SUCCESS);

    Process = NIL_RTPROCESS;
    RTThreadSleep(250);
    RTTESTI_CHECK_RC(RTProcCreate(apszArgs[0], apszArgs, RTENV_DEFAULT, 0, &Process), VINF_SUCCESS);

    RTThreadSleep(250);
    RTTESTI_CHECK_RC(SUPSemEventMultiSignal(pSession, hEvent), VINF_SUCCESS);

    rcThread = VERR_GENERAL_FAILURE;
    RTTESTI_CHECK_RC(RTThreadWait(hThread, 120*1000, &rcThread), VINF_SUCCESS);
    RTTESTI_CHECK_RC(rcThread, VINF_SUCCESS);

    int rcThread2 = VERR_GENERAL_FAILURE;
    RTTESTI_CHECK_RC(RTThreadWait(hThread2, 120*1000, &rcThread2), VINF_SUCCESS);
    RTTESTI_CHECK_RC(rcThread2, VINF_SUCCESS);

    RTTESTI_CHECK_RC(SUPSemEventMultiClose(pSession, hEvent), VINF_OBJECT_DESTROYED);

#endif /* !OS2 && !WINDOWS */

    {

#define LOOP_COUNT 20
        static unsigned const s_acMsIntervals[] = { 0, 1, 2, 3, 4, 8, 10, 16, 32 };
        if (RTTestErrorCount(hTest) == 0)
        {
            RTTestSub(hTest, "SRE Timeout Accuracy (ms)");
            RTTESTI_CHECK_RC(SUPSemEventCreate(pSession, &hEvent), VINF_SUCCESS);

            uint32_t cInterrupted = 0;
            for (unsigned i = 0; i < RT_ELEMENTS(s_acMsIntervals); i++)
            {
                uint64_t cMs        = s_acMsIntervals[i];
                uint64_t cNsMinSys  = UINT64_MAX;
                uint64_t cNsMin     = UINT64_MAX;
                uint64_t cNsTotalSys= 0;
                uint64_t cNsTotal   = 0;
                unsigned cLoops     = 0;
                while (cLoops < LOOP_COUNT)
                {
                    uint64_t u64StartSys = RTTimeSystemNanoTS();
                    uint64_t u64Start    = RTTimeNanoTS();
                    int rcX = SUPSemEventWaitNoResume(pSession, hEvent, cMs);
                    uint64_t cNsElapsedSys = RTTimeSystemNanoTS() - u64StartSys;
                    uint64_t cNsElapsed    = RTTimeNanoTS()       - u64Start;

                    if (rcX == VERR_INTERRUPTED)
                    {
                        cInterrupted++;
                        continue; /* retry */
                    }
                    if (rcX != VERR_TIMEOUT)
                        RTTestFailed(hTest, "%Rrc cLoops=%u cMs=%u", rcX, cLoops, cMs);

                    if (cNsElapsedSys < cNsMinSys)
                        cNsMinSys = cNsElapsedSys;
                    if (cNsElapsed < cNsMin)
                        cNsMin = cNsElapsed;
                    cNsTotalSys += cNsElapsedSys;
                    cNsTotal    += cNsElapsed;
                    cLoops++;
                }
                if (fSys)
                {
                    RTTestValueF(hTest, cNsMinSys, RTTESTUNIT_NS,            "%u ms min (clock=sys)", cMs);
                    RTTestValueF(hTest, cNsTotalSys / cLoops, RTTESTUNIT_NS, "%u ms avg (clock=sys)", cMs);
                }
                if (fGip)
                {
                    RTTestValueF(hTest, cNsMin, RTTESTUNIT_NS,               "%u ms min (clock=gip)", cMs);
                    RTTestValueF(hTest, cNsTotal / cLoops, RTTESTUNIT_NS,    "%u ms avg (clock=gip)", cMs);
                }
            }

            RTTESTI_CHECK_RC(SUPSemEventClose(pSession, hEvent), VINF_OBJECT_DESTROYED);
            RTTestValueF(hTest, cInterrupted, RTTESTUNIT_OCCURRENCES, "VERR_INTERRUPTED returned");
        }

        if (RTTestErrorCount(hTest) == 0)
        {
            RTTestSub(hTest, "MRE Timeout Accuracy (ms)");
            RTTESTI_CHECK_RC(SUPSemEventMultiCreate(pSession, &hEvent), VINF_SUCCESS);

            uint32_t cInterrupted = 0;
            for (unsigned i = 0; i < RT_ELEMENTS(s_acMsIntervals); i++)
            {
                uint64_t cMs        = s_acMsIntervals[i];
                uint64_t cNsMinSys  = UINT64_MAX;
                uint64_t cNsMin     = UINT64_MAX;
                uint64_t cNsTotalSys= 0;
                uint64_t cNsTotal   = 0;
                unsigned cLoops     = 0;
                while (cLoops < LOOP_COUNT)
                {
                    uint64_t u64StartSys = RTTimeSystemNanoTS();
                    uint64_t u64Start    = RTTimeNanoTS();
                    int rcX = SUPSemEventMultiWaitNoResume(pSession, hEvent, cMs);
                    uint64_t cNsElapsedSys = RTTimeSystemNanoTS() - u64StartSys;
                    uint64_t cNsElapsed    = RTTimeNanoTS()       - u64Start;

                    if (rcX == VERR_INTERRUPTED)
                    {
                        cInterrupted++;
                        continue; /* retry */
                    }
                    if (rcX != VERR_TIMEOUT)
                        RTTestFailed(hTest, "%Rrc cLoops=%u cMs=%u", rcX, cLoops, cMs);

                    if (cNsElapsedSys < cNsMinSys)
                        cNsMinSys = cNsElapsedSys;
                    if (cNsElapsed < cNsMin)
                        cNsMin = cNsElapsed;
                    cNsTotalSys += cNsElapsedSys;
                    cNsTotal    += cNsElapsed;
                    cLoops++;
                }
                if (fSys)
                {
                    RTTestValueF(hTest, cNsMinSys, RTTESTUNIT_NS,            "%u ms min (clock=sys)", cMs);
                    RTTestValueF(hTest, cNsTotalSys / cLoops, RTTESTUNIT_NS, "%u ms avg (clock=sys)", cMs);
                }
                if (fGip)
                {
                    RTTestValueF(hTest, cNsMin, RTTESTUNIT_NS,               "%u ms min (clock=gip)", cMs);
                    RTTestValueF(hTest, cNsTotal / cLoops, RTTESTUNIT_NS,    "%u ms avg (clock=gip)", cMs);
                }
            }

            RTTESTI_CHECK_RC(SUPSemEventMultiClose(pSession, hEvent), VINF_OBJECT_DESTROYED);
            RTTestValueF(hTest, cInterrupted, RTTESTUNIT_OCCURRENCES, "VERR_INTERRUPTED returned");
        }
    }

    {
        static uint32_t const s_acNsIntervals[] =
        {
            0, 1000, 5000, 15000, 30000, 50000, 100000, 250000, 500000, 750000, 900000, 1500000, 2200000
        };

        if (RTTestErrorCount(hTest) == 0)
        {
            RTTestSub(hTest, "SUPSemEventWaitNsRelIntr Accuracy");
            RTTestValueF(hTest, SUPSemEventGetResolution(pSession), RTTESTUNIT_NS, "SRE resolution");
            RTTESTI_CHECK_RC(SUPSemEventCreate(pSession, &hEvent), VINF_SUCCESS);

            uint32_t cInterrupted = 0;
            for (unsigned i = 0; i < RT_ELEMENTS(s_acNsIntervals); i++)
            {
                uint64_t cNs        = s_acNsIntervals[i];
                uint64_t cNsMinSys  = UINT64_MAX;
                uint64_t cNsMin     = UINT64_MAX;
                uint64_t cNsTotalSys= 0;
                uint64_t cNsTotal   = 0;
                unsigned cLoops     = 0;
                while (cLoops < LOOP_COUNT)
                {
                    uint64_t u64StartSys = RTTimeSystemNanoTS();
                    uint64_t u64Start    = RTTimeNanoTS();
                    int rcX = SUPSemEventWaitNsRelIntr(pSession, hEvent, cNs);
                    uint64_t cNsElapsedSys = RTTimeSystemNanoTS() - u64StartSys;
                    uint64_t cNsElapsed    = RTTimeNanoTS()       - u64Start;

                    if (rcX == VERR_INTERRUPTED)
                    {
                        cInterrupted++;
                        continue; /* retry */
                    }
                    if (rcX != VERR_TIMEOUT)
                        RTTestFailed(hTest, "%Rrc cLoops=%u cNs=%u", rcX, cLoops, cNs);

                    if (cNsElapsedSys < cNsMinSys)
                        cNsMinSys = cNsElapsedSys;
                    if (cNsElapsed < cNsMin)
                        cNsMin = cNsElapsed;
                    cNsTotalSys += cNsElapsedSys;
                    cNsTotal    += cNsElapsed;
                    cLoops++;
                }
                if (fSys)
                {
                    RTTestValueF(hTest, cNsMinSys, RTTESTUNIT_NS,            "%'u ns min (clock=sys)", cNs);
                    RTTestValueF(hTest, cNsTotalSys / cLoops, RTTESTUNIT_NS, "%'u ns avg (clock=sys)", cNs);
                }
                if (fGip)
                {
                    RTTestValueF(hTest, cNsMin, RTTESTUNIT_NS,               "%'u ns min (clock=gip)", cNs);
                    RTTestValueF(hTest, cNsTotal / cLoops, RTTESTUNIT_NS,    "%'u ns avg (clock=gip)", cNs);
                }
            }

            RTTESTI_CHECK_RC(SUPSemEventClose(pSession, hEvent), VINF_OBJECT_DESTROYED);
            RTTestValueF(hTest, cInterrupted, RTTESTUNIT_OCCURRENCES, "VERR_INTERRUPTED returned");
        }

        if (RTTestErrorCount(hTest) == 0)
        {
            RTTestSub(hTest, "SUPSemEventMultiWaitNsRelIntr Accuracy");
            RTTestValueF(hTest, SUPSemEventMultiGetResolution(pSession), RTTESTUNIT_NS, "MRE resolution");
            RTTESTI_CHECK_RC(SUPSemEventMultiCreate(pSession, &hEvent), VINF_SUCCESS);

            uint32_t cInterrupted = 0;
            for (unsigned i = 0; i < RT_ELEMENTS(s_acNsIntervals); i++)
            {
                uint64_t cNs        = s_acNsIntervals[i];
                uint64_t cNsMinSys  = UINT64_MAX;
                uint64_t cNsMin     = UINT64_MAX;
                uint64_t cNsTotalSys= 0;
                uint64_t cNsTotal   = 0;
                unsigned cLoops     = 0;
                while (cLoops < LOOP_COUNT)
                {
                    uint64_t u64StartSys = RTTimeSystemNanoTS();
                    uint64_t u64Start    = RTTimeNanoTS();
                    int rcX = SUPSemEventMultiWaitNsRelIntr(pSession, hEvent, cNs);
                    uint64_t cNsElapsedSys = RTTimeSystemNanoTS() - u64StartSys;
                    uint64_t cNsElapsed    = RTTimeNanoTS()       - u64Start;

                    if (rcX == VERR_INTERRUPTED)
                    {
                        cInterrupted++;
                        continue; /* retry */
                    }
                    if (rcX != VERR_TIMEOUT)
                        RTTestFailed(hTest, "%Rrc cLoops=%u cNs=%u", rcX, cLoops, cNs);

                    if (cNsElapsedSys < cNsMinSys)
                        cNsMinSys = cNsElapsedSys;
                    if (cNsElapsed < cNsMin)
                        cNsMin = cNsElapsed;
                    cNsTotalSys += cNsElapsedSys;
                    cNsTotal    += cNsElapsed;
                    cLoops++;
                }
                if (fSys)
                {
                    RTTestValueF(hTest, cNsMinSys, RTTESTUNIT_NS,            "%'u ns min (clock=sys)", cNs);
                    RTTestValueF(hTest, cNsTotalSys / cLoops, RTTESTUNIT_NS, "%'u ns avg (clock=sys)", cNs);
                }
                if (fGip)
                {
                    RTTestValueF(hTest, cNsMin, RTTESTUNIT_NS,               "%'u ns min (clock=gip)", cNs);
                    RTTestValueF(hTest, cNsTotal / cLoops, RTTESTUNIT_NS,    "%'u ns avg (clock=gip)", cNs);
                }
            }

            RTTESTI_CHECK_RC(SUPSemEventMultiClose(pSession, hEvent), VINF_OBJECT_DESTROYED);
            RTTestValueF(hTest, cInterrupted, RTTESTUNIT_OCCURRENCES, "VERR_INTERRUPTED returned");
        }

        if (RTTestErrorCount(hTest) == 0)
        {
            RTTestSub(hTest, "SUPSemEventWaitNsAbsIntr Accuracy");
            RTTestValueF(hTest, SUPSemEventGetResolution(pSession), RTTESTUNIT_NS, "MRE resolution");
            RTTESTI_CHECK_RC(SUPSemEventCreate(pSession, &hEvent), VINF_SUCCESS);

            uint32_t cInterrupted = 0;
            for (unsigned i = 0; i < RT_ELEMENTS(s_acNsIntervals); i++)
            {
                uint64_t cNs        = s_acNsIntervals[i];
                uint64_t cNsMinSys  = UINT64_MAX;
                uint64_t cNsMin     = UINT64_MAX;
                uint64_t cNsTotalSys= 0;
                uint64_t cNsTotal   = 0;
                unsigned cLoops     = 0;
                while (cLoops < LOOP_COUNT)
                {
                    uint64_t u64StartSys   = RTTimeSystemNanoTS();
                    uint64_t u64Start      = RTTimeNanoTS();
                    uint64_t uAbsDeadline  = (fGip ? u64Start : u64StartSys) + cNs;
                    int rcX = SUPSemEventWaitNsAbsIntr(pSession, hEvent, uAbsDeadline);
                    uint64_t cNsElapsedSys = RTTimeSystemNanoTS() - u64StartSys;
                    uint64_t cNsElapsed    = RTTimeNanoTS()       - u64Start;

                    if (rcX == VERR_INTERRUPTED)
                    {
                        cInterrupted++;
                        continue; /* retry */
                    }
                    if (rcX != VERR_TIMEOUT)
                        RTTestFailed(hTest, "%Rrc cLoops=%u cNs=%u", rcX, cLoops, cNs);

                    if (cNsElapsedSys < cNsMinSys)
                        cNsMinSys = cNsElapsedSys;
                    if (cNsElapsed < cNsMin)
                        cNsMin = cNsElapsed;
                    cNsTotalSys += cNsElapsedSys;
                    cNsTotal    += cNsElapsed;
                    cLoops++;
                }
                if (fSys)
                {
                    RTTestValueF(hTest, cNsMinSys, RTTESTUNIT_NS,            "%'u ns min (clock=sys)", cNs);
                    RTTestValueF(hTest, cNsTotalSys / cLoops, RTTESTUNIT_NS, "%'u ns avg (clock=sys)", cNs);
                }
                if (fGip)
                {
                    RTTestValueF(hTest, cNsMin, RTTESTUNIT_NS,               "%'u ns min (clock=gip)", cNs);
                    RTTestValueF(hTest, cNsTotal / cLoops, RTTESTUNIT_NS,    "%'u ns avg (clock=gip)", cNs);
                }
            }

            RTTESTI_CHECK_RC(SUPSemEventClose(pSession, hEvent), VINF_OBJECT_DESTROYED);
            RTTestValueF(hTest, cInterrupted, RTTESTUNIT_OCCURRENCES, "VERR_INTERRUPTED returned");
        }


        if (RTTestErrorCount(hTest) == 0)
        {
            RTTestSub(hTest, "SUPSemEventMultiWaitNsAbsIntr Accuracy");
            RTTestValueF(hTest, SUPSemEventMultiGetResolution(pSession), RTTESTUNIT_NS, "MRE resolution");
            RTTESTI_CHECK_RC(SUPSemEventMultiCreate(pSession, &hEvent), VINF_SUCCESS);

            uint32_t cInterrupted = 0;
            for (unsigned i = 0; i < RT_ELEMENTS(s_acNsIntervals); i++)
            {
                uint64_t cNs        = s_acNsIntervals[i];
                uint64_t cNsMinSys  = UINT64_MAX;
                uint64_t cNsMin     = UINT64_MAX;
                uint64_t cNsTotalSys= 0;
                uint64_t cNsTotal   = 0;
                unsigned cLoops     = 0;
                while (cLoops < LOOP_COUNT)
                {
                    uint64_t u64StartSys   = RTTimeSystemNanoTS();
                    uint64_t u64Start      = RTTimeNanoTS();
                    uint64_t uAbsDeadline  = (fGip ? u64Start : u64StartSys) + cNs;
                    int rcX = SUPSemEventMultiWaitNsAbsIntr(pSession, hEvent, uAbsDeadline);
                    uint64_t cNsElapsedSys = RTTimeSystemNanoTS() - u64StartSys;
                    uint64_t cNsElapsed    = RTTimeNanoTS()       - u64Start;

                    if (rcX == VERR_INTERRUPTED)
                    {
                        cInterrupted++;
                        continue; /* retry */
                    }
                    if (rcX != VERR_TIMEOUT)
                        RTTestFailed(hTest, "%Rrc cLoops=%u cNs=%u", rcX, cLoops, cNs);

                    if (cNsElapsedSys < cNsMinSys)
                        cNsMinSys = cNsElapsedSys;
                    if (cNsElapsed < cNsMin)
                        cNsMin = cNsElapsed;
                    cNsTotalSys += cNsElapsedSys;
                    cNsTotal    += cNsElapsed;
                    cLoops++;
                }
                if (fSys)
                {
                    RTTestValueF(hTest, cNsMinSys, RTTESTUNIT_NS,            "%'u ns min (clock=sys)", cNs);
                    RTTestValueF(hTest, cNsTotalSys / cLoops, RTTESTUNIT_NS, "%'u ns avg (clock=sys)", cNs);
                }
                if (fGip)
                {
                    RTTestValueF(hTest, cNsMin, RTTESTUNIT_NS,               "%'u ns min (clock=gip)", cNs);
                    RTTestValueF(hTest, cNsTotal / cLoops, RTTESTUNIT_NS,    "%'u ns avg (clock=gip)", cNs);
                }
            }

            RTTESTI_CHECK_RC(SUPSemEventMultiClose(pSession, hEvent), VINF_OBJECT_DESTROYED);
            RTTestValueF(hTest, cInterrupted, RTTESTUNIT_OCCURRENCES, "VERR_INTERRUPTED returned");
        }

    }


    /*
     * Done.
     */
    return RTTestSummaryAndDestroy(hTest);
}
コード例 #26
0
int main (int argc, char **argv)
{
#ifndef VBOX
    RTPrintf("tstSup: SKIPPED\n");
    return 0;
#else
    /*
     * Init.
     */
    RTTEST hTest;
    int rc = RTTestInitAndCreate("tstRTR0DbgKrnlInfo", &hTest);
    if (rc)
        return rc;
    RTTestBanner(hTest);

    uint8_t *pbPage = (uint8_t *)RTTestGuardedAllocTail(hTest, PAGE_SIZE);
    if (!pbPage)
    {
        RTTestFailed(hTest, "RTTestGuardedAllocTail failed with rc=%Rrc\n", rc);
        return RTTestSummaryAndDestroy(hTest);
    }

    PSUPDRVSESSION pSession;
    rc = SUPR3Init(&pSession);
    if (RT_FAILURE(rc))
    {
        RTTestFailed(hTest, "SUPR3Init failed with rc=%Rrc\n", rc);
        return RTTestSummaryAndDestroy(hTest);
    }

    char szPath[RTPATH_MAX];
    rc = RTPathExecDir(szPath, sizeof(szPath));
    if (RT_SUCCESS(rc))
        rc = RTPathAppend(szPath, sizeof(szPath), "tstRTR0DbgKrnlInfo.r0");
    if (RT_FAILURE(rc))
    {
        RTTestFailed(hTest, "Failed constructing .r0 filename (rc=%Rrc)", rc);
        return RTTestSummaryAndDestroy(hTest);
    }

    void *pvImageBase;
    rc = SUPR3LoadServiceModule(szPath, "tstRTR0DbgKrnlInfo",
                                "TSTR0DbgKrnlInfoSrvReqHandler",
                                &pvImageBase);
    if (RT_FAILURE(rc))
    {
        RTTestFailed(hTest, "SUPR3LoadServiceModule(%s,,,) failed with rc=%Rrc\n", szPath, rc);
        return RTTestSummaryAndDestroy(hTest);
    }

    /* test request */
    struct
    {
        SUPR0SERVICEREQHDR  Hdr;
        char                szMsg[256];
    } Req;

    /*
     * Sanity checks.
     */
    RTTestSub(hTest, "Sanity");
    Req.Hdr.u32Magic = SUPR0SERVICEREQHDR_MAGIC;
    Req.Hdr.cbReq = sizeof(Req);
    Req.szMsg[0] = '\0';
    RTTESTI_CHECK_RC(rc = SUPR3CallR0Service("tstRTR0DbgKrnlInfo", sizeof("tstRTR0DbgKrnlInfo") - 1,
                                             TSTRTR0DBGKRNLINFO_SANITY_OK, 0, &Req.Hdr), VINF_SUCCESS);
    if (RT_FAILURE(rc))
        return RTTestSummaryAndDestroy(hTest);
    RTTESTI_CHECK_MSG(Req.szMsg[0] == '\0', ("%s", Req.szMsg));
    if (Req.szMsg[0] != '\0')
        return RTTestSummaryAndDestroy(hTest);

    Req.Hdr.u32Magic = SUPR0SERVICEREQHDR_MAGIC;
    Req.Hdr.cbReq = sizeof(Req);
    Req.szMsg[0] = '\0';
    RTTESTI_CHECK_RC(rc = SUPR3CallR0Service("tstRTR0DbgKrnlInfo", sizeof("tstRTR0DbgKrnlInfo") - 1,
                                             TSTRTR0DBGKRNLINFO_SANITY_FAILURE, 0, &Req.Hdr), VINF_SUCCESS);
    if (RT_FAILURE(rc))
        return RTTestSummaryAndDestroy(hTest);
    RTTESTI_CHECK_MSG(!strncmp(Req.szMsg, RT_STR_TUPLE("!42failure42")), ("%s", Req.szMsg));
    if (strncmp(Req.szMsg, RT_STR_TUPLE("!42failure42")))
        return RTTestSummaryAndDestroy(hTest);

    /*
     * Basic tests, bail out on failure.
     */
    RTTestSub(hTest, "Basics");
    Req.Hdr.u32Magic = SUPR0SERVICEREQHDR_MAGIC;
    Req.Hdr.cbReq = sizeof(Req);
    Req.szMsg[0] = '\0';
    RTTESTI_CHECK_RC(rc = SUPR3CallR0Service("tstRTR0DbgKrnlInfo", sizeof("tstRTR0DbgKrnlInfo") - 1,
                                             TSTRTR0DBGKRNLINFO_BASIC, 0, &Req.Hdr), VINF_SUCCESS);
    if (RT_FAILURE(rc))
        return RTTestSummaryAndDestroy(hTest);
    if (Req.szMsg[0] == '!')
    {
        RTTestIFailed("%s", &Req.szMsg[1]);
        return RTTestSummaryAndDestroy(hTest);
    }
    if (Req.szMsg[0])
        RTTestIPrintf(RTTESTLVL_ALWAYS, "%s", Req.szMsg);

    /*
     * Done.
     */
    return RTTestSummaryAndDestroy(hTest);
#endif
}
コード例 #27
0
ファイル: tstSupTscDelta.cpp プロジェクト: jeppeter/vbox
int main(int argc, char **argv)
{
    RTTEST hTest;
    RTEXITCODE rcExit = RTTestInitExAndCreate(argc, &argv, 0 /*fRtInit*/, "tstSupTscDelta", &hTest);
    if (rcExit != RTEXITCODE_SUCCESS)
        return rcExit;

    /*
     * Parse args
     */
    static const RTGETOPTDEF g_aOptions[] =
    {
        { "--iterations",       'i', RTGETOPT_REQ_INT32 },
        { "--delay",            'd', RTGETOPT_REQ_INT32 },
    };

    uint32_t cIterations = 0; /* Currently 0 so that it doesn't upset testing. */
    uint32_t cMsSleepBetweenIterations = 10;

    int           ch;
    RTGETOPTUNION ValueUnion;
    RTGETOPTSTATE GetState;
    RTGetOptInit(&GetState, argc, argv, g_aOptions, RT_ELEMENTS(g_aOptions), 1, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
    while ((ch = RTGetOpt(&GetState, &ValueUnion)))
    {
        switch (ch)
        {
        case 'd':
            cMsSleepBetweenIterations = ValueUnion.u32;
            break;
        case 'i':
            cIterations = ValueUnion.u32;
            break;

        default:
            return RTGetOptPrintError(ch, &ValueUnion);
        }
    }
    if (!cIterations)
        return RTTestSkipAndDestroy(hTest, "Nothing to do. The --iterations argument is 0 or not given.");

    /*
     * Init
     */
    PSUPDRVSESSION pSession = NIL_RTR0PTR;
    int rc = SUPR3Init(&pSession);
    if (RT_SUCCESS(rc))
    {
        PSUPGLOBALINFOPAGE pGip = g_pSUPGlobalInfoPage;
        if (pGip)
        {
            if (pGip->enmUseTscDelta < SUPGIPUSETSCDELTA_PRACTICALLY_ZERO)
                return RTTestSkipAndDestroy(hTest, "No deltas to play with: enmUseTscDelta=%d\n", pGip->enmUseTscDelta);

            /*
             * Init stats.
             */
            struct
            {
                int64_t iLowest;
                int64_t iHighest;
                int64_t iTotal;
                uint64_t uAbsMin;
                uint64_t uAbsMax;
                uint64_t uAbsTotal;
            } aCpuStats[RTCPUSET_MAX_CPUS];
            RT_ZERO(aCpuStats);
            for (uint32_t i = 0; i < pGip->cCpus; i++)
            {
                aCpuStats[i].iLowest  = INT64_MAX;
                aCpuStats[i].iHighest = INT64_MIN;
                aCpuStats[i].uAbsMin  = UINT64_MAX;
            }

            /*
             * Do the work.
             */
            for (uint32_t iIteration = 0; ; iIteration++)
            {
                /*
                 * Display the current deltas and gather statistics.
                 */
                RTPrintf("tstSupTscDelta: Iteration #%u results:", iIteration);
                for (uint32_t iCpu = 0; iCpu < pGip->cCpus; iCpu++)
                {
                    int64_t iTscDelta = pGip->aCPUs[iCpu].i64TSCDelta;

                    /* print */
                    if ((iCpu % 4) == 0)
                        RTPrintf("\ntstSupTscDelta:");
                    if (pGip->aCPUs[iCpu].enmState != SUPGIPCPUSTATE_ONLINE)
                        RTPrintf("  %02x: offline     ", iCpu);
                    else if (iTscDelta != INT64_MAX)
                        RTPrintf("  %02x: %-12lld", iCpu, iTscDelta);
                    else
                        RTPrintf("  %02x: INT64_MAX   ", iCpu);

                    /* stats */
                    if (   iTscDelta != INT64_MAX
                            && pGip->aCPUs[iCpu].enmState == SUPGIPCPUSTATE_ONLINE)
                    {
                        if (aCpuStats[iCpu].iLowest > iTscDelta)
                            aCpuStats[iCpu].iLowest = iTscDelta;
                        if (aCpuStats[iCpu].iHighest < iTscDelta)
                            aCpuStats[iCpu].iHighest = iTscDelta;
                        aCpuStats[iCpu].iTotal += iTscDelta;

                        uint64_t uAbsTscDelta = iTscDelta >= 0 ? (uint64_t)iTscDelta : (uint64_t)-iTscDelta;
                        if (aCpuStats[iCpu].uAbsMin > uAbsTscDelta)
                            aCpuStats[iCpu].uAbsMin = uAbsTscDelta;
                        if (aCpuStats[iCpu].uAbsMax < uAbsTscDelta)
                            aCpuStats[iCpu].uAbsMax = uAbsTscDelta;
                        aCpuStats[iCpu].uAbsTotal += uAbsTscDelta;
                    }
                }
                if (((pGip->cCpus - 1) % 4) != 0)
                    RTPrintf("\n");

                /*
                 * Done?
                 */
                if (iIteration + 1 >= cIterations)
                    break;

                /*
                 * Force a new measurement.
                 */
                RTThreadSleep(cMsSleepBetweenIterations);
                for (uint32_t iCpu = 0; iCpu < pGip->cCpus; iCpu++)
                    if (pGip->aCPUs[iCpu].enmState == SUPGIPCPUSTATE_ONLINE)
                    {
                        rc = SUPR3TscDeltaMeasure(pGip->aCPUs[iCpu].idCpu, false /*fAsync*/, true /*fForce*/, 64, 16 /*ms*/);
                        if (RT_FAILURE(rc))
                            RTTestFailed(hTest, "SUPR3TscDeltaMeasure failed on %#x: %Rrc", pGip->aCPUs[iCpu].idCpu, rc);
                    }
            }

            /*
             * Display statistics that we've gathered.
             */
            RTPrintf("tstSupTscDelta: Results:\n");
            int64_t  iLowest  = INT64_MAX;
            int64_t  iHighest = INT64_MIN;
            int64_t  iTotal   = 0;
            uint32_t cTotal   = 0;
            for (uint32_t iCpu = 0; iCpu < pGip->cCpus; iCpu++)
            {
                if (pGip->aCPUs[iCpu].enmState != SUPGIPCPUSTATE_ONLINE)
                    RTPrintf("tstSupTscDelta:  %02x: offline\n", iCpu);
                else
                {
                    RTPrintf("tstSupTscDelta:  %02x: lowest=%-12lld  highest=%-12lld  average=%-12lld  spread=%-12lld\n",
                             iCpu,
                             aCpuStats[iCpu].iLowest,
                             aCpuStats[iCpu].iHighest,
                             aCpuStats[iCpu].iTotal / cIterations,
                             aCpuStats[iCpu].iHighest - aCpuStats[iCpu].iLowest);
                    RTPrintf(  "tstSupTscDelta:      absmin=%-12llu   absmax=%-12llu   absavg=%-12llu  idCpu=%#4x  idApic=%#4x\n",
                               aCpuStats[iCpu].uAbsMin,
                               aCpuStats[iCpu].uAbsMax,
                               aCpuStats[iCpu].uAbsTotal / cIterations,
                               pGip->aCPUs[iCpu].idCpu,
                               pGip->aCPUs[iCpu].idApic);
                    if (iLowest > aCpuStats[iCpu].iLowest)
                        iLowest = aCpuStats[iCpu].iLowest;
                    if (iHighest < aCpuStats[iCpu].iHighest)
                        iHighest = aCpuStats[iCpu].iHighest;
                    iTotal += aCpuStats[iCpu].iHighest;
                    cTotal += cIterations;
                }
            }
            RTPrintf("tstSupTscDelta: all: lowest=%-12lld  highest=%-12lld  average=%-12lld  spread=%-12lld\n",
                     iLowest, iHighest, iTotal / cTotal, iHighest - iLowest);
        }
        else
            RTTestFailed(hTest, "g_pSUPGlobalInfoPage is NULL");

        SUPR3Term(false /*fForced*/);
    }
    else
        RTTestFailed(hTest, "SUPR3Init failed: %Rrc", rc);
    return RTTestSummaryAndDestroy(hTest);
}
コード例 #28
0
ファイル: tstRTTime.cpp プロジェクト: mcenirm/vbox
int main()
{
    /*
     * Init.
     */
    RTTEST hTest;
    RTEXITCODE rcExit = RTTestInitExAndCreate(0, NULL, RTR3INIT_FLAGS_SUPLIB, "tstRTTime", &hTest);
    if (rcExit != RTEXITCODE_SUCCESS)
        return rcExit;
    RTTestBanner(hTest);

    /*
     * RTNanoTimeTS() shall never return something which
     * is less or equal to the return of the previous call.
     */

    RTTimeSystemNanoTS(); RTTimeNanoTS(); RTThreadYield();
    uint64_t u64RTStartTS = RTTimeNanoTS();
    uint64_t u64OSStartTS = RTTimeSystemNanoTS();

    uint32_t i;
    uint64_t u64Prev = RTTimeNanoTS();
    for (i = 0; i < 100*_1M; i++)
    {
        uint64_t u64 = RTTimeNanoTS();
        if (u64 <= u64Prev)
        {
            /** @todo wrapping detection. */
            RTTestFailed(hTest, "i=%#010x u64=%#llx u64Prev=%#llx (1)\n", i, u64, u64Prev);
            if (RTTestErrorCount(hTest) >= 256)
                break;
            RTThreadYield();
            u64 = RTTimeNanoTS();
        }
        else if (u64 - u64Prev > 1000000000 /* 1sec */)
        {
            RTTestFailed(hTest, "i=%#010x u64=%#llx u64Prev=%#llx delta=%lld\n", i, u64, u64Prev, u64 - u64Prev);
            if (RTTestErrorCount(hTest) >= 256)
                break;
            RTThreadYield();
            u64 = RTTimeNanoTS();
        }
        if (!(i & (_1M*2 - 1)))
        {
            RTTestPrintf(hTest, RTTESTLVL_INFO, "i=%#010x u64=%#llx u64Prev=%#llx delta=%lld\n", i, u64, u64Prev, u64 - u64Prev);
            RTThreadYield();
            u64 = RTTimeNanoTS();
        }
        u64Prev = u64;
    }

    RTTimeSystemNanoTS(); RTTimeNanoTS(); RTThreadYield();
    uint64_t u64RTElapsedTS = RTTimeNanoTS();
    uint64_t u64OSElapsedTS = RTTimeSystemNanoTS();
    u64RTElapsedTS -= u64RTStartTS;
    u64OSElapsedTS -= u64OSStartTS;
    int64_t i64Diff = u64OSElapsedTS >= u64RTElapsedTS ? u64OSElapsedTS - u64RTElapsedTS : u64RTElapsedTS - u64OSElapsedTS;
    if (i64Diff > (int64_t)(u64OSElapsedTS / 1000))
        RTTestFailed(hTest, "total time differs too much! u64OSElapsedTS=%#llx u64RTElapsedTS=%#llx delta=%lld\n",
                     u64OSElapsedTS, u64RTElapsedTS, u64OSElapsedTS - u64RTElapsedTS);
    else
    {
        if (u64OSElapsedTS >= u64RTElapsedTS)
            RTTestValue(hTest, "Total time delta", u64OSElapsedTS - u64RTElapsedTS, RTTESTUNIT_NS);
        else
            RTTestValue(hTest, "Total time delta", u64RTElapsedTS - u64OSElapsedTS, RTTESTUNIT_NS);
        RTTestPrintf(hTest, RTTESTLVL_INFO, "total time difference: u64OSElapsedTS=%#llx u64RTElapsedTS=%#llx delta=%lld\n",
                     u64OSElapsedTS, u64RTElapsedTS, u64OSElapsedTS - u64RTElapsedTS);
    }

#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86) /** @todo This isn't really x86 or AMD64 specific... */
    RTTestValue(hTest, "RTTimeDbgSteps",        RTTimeDbgSteps(),                           RTTESTUNIT_OCCURRENCES);
    RTTestValue(hTest, "RTTimeDbgSteps pp",     ((uint64_t)RTTimeDbgSteps() * 1000) / i,    RTTESTUNIT_PP1K);
    RTTestValue(hTest, "RTTimeDbgExpired",      RTTimeDbgExpired(),                         RTTESTUNIT_OCCURRENCES);
    RTTestValue(hTest, "RTTimeDbgExpired pp",   ((uint64_t)RTTimeDbgExpired() * 1000) / i,  RTTESTUNIT_PP1K);
    RTTestValue(hTest, "RTTimeDbgBad",          RTTimeDbgBad(),                             RTTESTUNIT_OCCURRENCES);
    RTTestValue(hTest, "RTTimeDbgBad pp",       ((uint64_t)RTTimeDbgBad() * 1000) / i,      RTTESTUNIT_PP1K);
    RTTestValue(hTest, "RTTimeDbgRaces",        RTTimeDbgRaces(),                           RTTESTUNIT_OCCURRENCES);
    RTTestValue(hTest, "RTTimeDbgRaces pp",     ((uint64_t)RTTimeDbgRaces() * 1000) / i,    RTTESTUNIT_PP1K);
#endif

    return RTTestSummaryAndDestroy(hTest);
}
コード例 #29
0
ファイル: tstVMM.cpp プロジェクト: svn2github/virtualbox
/**
 * Entry point.
 */
extern "C" DECLEXPORT(int) TrustedMain(int argc, char **argv, char **envp)
{
    RT_NOREF1(envp);

    /*
     * Init runtime and the test environment.
     */
    RTTEST hTest;
    RTEXITCODE rcExit = RTTestInitExAndCreate(argc, &argv, RTR3INIT_FLAGS_SUPLIB, "tstVMM", &hTest);
    if (rcExit != RTEXITCODE_SUCCESS)
        return rcExit;

    /*
     * Parse arguments.
     */
    static const RTGETOPTDEF s_aOptions[] =
    {
        { "--cpus",          'c', RTGETOPT_REQ_UINT8 },
        { "--test",          't', RTGETOPT_REQ_STRING },
        { "--stat",          's', RTGETOPT_REQ_NOTHING },
    };
    enum
    {
        kTstVMMTest_VMM,  kTstVMMTest_TM, kTstVMMTest_MSRs, kTstVMMTest_KnownMSRs, kTstVMMTest_MSRExperiments
    } enmTestOpt = kTstVMMTest_VMM;

    int ch;
    RTGETOPTUNION ValueUnion;
    RTGETOPTSTATE GetState;
    RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, 0);
    while ((ch = RTGetOpt(&GetState, &ValueUnion)))
    {
        switch (ch)
        {
            case 'c':
                g_cCpus = ValueUnion.u8;
                break;

            case 't':
                if (!strcmp("vmm", ValueUnion.psz))
                    enmTestOpt = kTstVMMTest_VMM;
                else if (!strcmp("tm", ValueUnion.psz))
                    enmTestOpt = kTstVMMTest_TM;
                else if (!strcmp("msr", ValueUnion.psz) || !strcmp("msrs", ValueUnion.psz))
                    enmTestOpt = kTstVMMTest_MSRs;
                else if (!strcmp("known-msr", ValueUnion.psz) || !strcmp("known-msrs", ValueUnion.psz))
                    enmTestOpt = kTstVMMTest_KnownMSRs;
                else if (!strcmp("msr-experiments", ValueUnion.psz))
                    enmTestOpt = kTstVMMTest_MSRExperiments;
                else
                {
                    RTPrintf("tstVMM: unknown test: '%s'\n", ValueUnion.psz);
                    return 1;
                }
                break;

            case 's':
                g_fStat = true;
                break;

            case 'h':
                RTPrintf("usage: tstVMM [--cpus|-c cpus] [-s] [--test <vmm|tm|msrs|known-msrs>]\n");
                return 1;

            case 'V':
                RTPrintf("$Revision$\n");
                return 0;

            default:
                return RTGetOptPrintError(ch, &ValueUnion);
        }
    }

    /*
     * Create the test VM.
     */
    RTPrintf(TESTCASE ": Initializing...\n");
    PVM pVM;
    PUVM pUVM;
    int rc = VMR3Create(g_cCpus, NULL, NULL, NULL, tstVMMConfigConstructor, NULL, &pVM, &pUVM);
    if (RT_SUCCESS(rc))
    {
        PDMR3LdrEnumModules(pVM, tstVMMLdrEnum, NULL);
        RTStrmFlush(g_pStdOut);
        RTThreadSleep(256);

        /*
         * Do the requested testing.
         */
        switch (enmTestOpt)
        {
            case kTstVMMTest_VMM:
            {
                RTTestSub(hTest, "VMM");
                rc = VMR3ReqCallWaitU(pUVM, VMCPUID_ANY, (PFNRT)VMMDoTest, 1, pVM);
                if (RT_FAILURE(rc))
                    RTTestFailed(hTest, "VMMDoTest failed: rc=%Rrc\n", rc);
                if (g_fStat)
                    STAMR3Dump(pUVM, "*");
                break;
            }

            case kTstVMMTest_TM:
            {
                RTTestSub(hTest, "TM");
                for (VMCPUID idCpu = 1; idCpu < g_cCpus; idCpu++)
                {
                    rc = VMR3ReqCallNoWaitU(pUVM, idCpu, (PFNRT)tstTMWorker, 2, pVM, hTest);
                    if (RT_FAILURE(rc))
                        RTTestFailed(hTest, "VMR3ReqCall failed: rc=%Rrc\n", rc);
                }

                rc = VMR3ReqCallWaitU(pUVM, 0 /*idDstCpu*/, (PFNRT)tstTMWorker, 2, pVM, hTest);
                if (RT_FAILURE(rc))
                    RTTestFailed(hTest, "VMMDoTest failed: rc=%Rrc\n", rc);
                if (g_fStat)
                    STAMR3Dump(pUVM, "*");
                break;
            }

            case kTstVMMTest_MSRs:
            {
                RTTestSub(hTest, "MSRs");
                if (g_cCpus == 1)
                {
                    rc = VMR3ReqCallWaitU(pUVM, 0 /*idDstCpu*/, (PFNRT)VMMDoBruteForceMsrs, 1, pVM);
                    if (RT_FAILURE(rc))
                        RTTestFailed(hTest, "VMMDoBruteForceMsrs failed: rc=%Rrc\n", rc);
                }
                else
                    RTTestFailed(hTest, "The MSR test can only be run with one VCpu!\n");
                break;
            }

            case kTstVMMTest_KnownMSRs:
            {
                RTTestSub(hTest, "Known MSRs");
                if (g_cCpus == 1)
                {
                    rc = VMR3ReqCallWaitU(pUVM, 0 /*idDstCpu*/, (PFNRT)VMMDoKnownMsrs, 1, pVM);
                    if (RT_FAILURE(rc))
                        RTTestFailed(hTest, "VMMDoKnownMsrs failed: rc=%Rrc\n", rc);
                }
                else
                    RTTestFailed(hTest, "The MSR test can only be run with one VCpu!\n");
                break;
            }

            case kTstVMMTest_MSRExperiments:
            {
                RTTestSub(hTest, "MSR Experiments");
                if (g_cCpus == 1)
                {
                    rc = VMR3ReqCallWaitU(pUVM, 0 /*idDstCpu*/, (PFNRT)VMMDoMsrExperiments, 1, pVM);
                    if (RT_FAILURE(rc))
                        RTTestFailed(hTest, "VMMDoMsrExperiments failed: rc=%Rrc\n", rc);
                }
                else
                    RTTestFailed(hTest, "The MSR test can only be run with one VCpu!\n");
                break;
            }

        }

        /*
         * Cleanup.
         */
        rc = VMR3PowerOff(pUVM);
        if (RT_FAILURE(rc))
            RTTestFailed(hTest, "VMR3PowerOff failed: rc=%Rrc\n", rc);
        rc = VMR3Destroy(pUVM);
        if (RT_FAILURE(rc))
            RTTestFailed(hTest, "VMR3Destroy failed: rc=%Rrc\n", rc);
        VMR3ReleaseUVM(pUVM);
    }
    else
        RTTestFailed(hTest, "VMR3Create failed: rc=%Rrc\n", rc);

    return RTTestSummaryAndDestroy(hTest);
}