/**
 * Does a multi-threading list test. Several list additions, reading, replacing
 * and erasing are done simultaneous.
 *
 */
static void test2()
{
    RTTestISubF("MT test with 6 threads (%u tests per thread).", MTTESTITEMS);

    int                         rc;
    MTTESTLISTTYPE<MTTESTTYPE>  testList;
    RTTHREAD                    ahThreads[6];
    static PFNRTTHREAD          apfnThreads[6] =
    {
        MtTest1ThreadProc, MtTest2ThreadProc, MtTest3ThreadProc, MtTest4ThreadProc, MtTest5ThreadProc, MtTest6ThreadProc
    };

    for (unsigned i = 0; i < RT_ELEMENTS(ahThreads); i++)
    {
        RTTESTI_CHECK_RC_RETV(RTThreadCreateF(&ahThreads[i], apfnThreads[i], &testList, 0,
                                              RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "mttest%u", i), VINF_SUCCESS);
    }

    uint64_t tsMsDeadline = RTTimeMilliTS() + 60000;
    for (unsigned i = 0; i < RT_ELEMENTS(ahThreads); i++)
    {
        uint64_t tsNow = RTTimeMilliTS();
        uint32_t cWait = tsNow > tsMsDeadline ? 5000 : tsMsDeadline - tsNow;
        RTTESTI_CHECK_RC(RTThreadWait(ahThreads[i], tsNow, NULL), VINF_SUCCESS);
    }

    RTTESTI_CHECK_RETV(testList.size() == MTTESTITEMS * 2);
    for (size_t i = 0; i < testList.size(); ++i)
    {
        uint32_t a = testList.at(i);
        RTTESTI_CHECK(a == 0x0 || a == 0xFFFFFFFF || a == 0xF0F0F0F0 || a == 0xFF00FF00);
    }
}
static void tstRTCreateProcEx5(const char *pszUser, const char *pszPassword)
{
    RTTestISubF("As user \"%s\" with password \"%s\"", pszUser, pszPassword);

    const char * apszArgs[3] =
    {
        "test", /* user name */
        "--testcase-child-5",
        NULL
    };

    RTPROCESS hProc;

    /* Test for invalid logons. */
    RTTESTI_CHECK_RC_RETV(RTProcCreateEx(g_szExecName, apszArgs, RTENV_DEFAULT, 0 /*fFlags*/, NULL,
                                         NULL, NULL, "non-existing-user", "wrong-password", &hProc), VERR_AUTHENTICATION_FAILURE);
    /* Test for invalid application. */
    RTTESTI_CHECK_RC_RETV(RTProcCreateEx("non-existing-app", apszArgs, RTENV_DEFAULT, 0 /*fFlags*/, NULL,
                                         NULL, NULL, NULL, NULL, &hProc), VERR_FILE_NOT_FOUND);
    /* Test a (hopefully) valid user/password logon (given by parameters of this function). */
    RTTESTI_CHECK_RC_RETV(RTProcCreateEx(g_szExecName, apszArgs, RTENV_DEFAULT, 0 /*fFlags*/, NULL,
                                         NULL, NULL, pszUser, pszPassword, &hProc), VINF_SUCCESS);
    RTPROCSTATUS ProcStatus = { -1, RTPROCEXITREASON_ABEND };
    RTTESTI_CHECK_RC(RTProcWait(hProc, RTPROCWAIT_FLAGS_BLOCK, &ProcStatus), VINF_SUCCESS);

    if (ProcStatus.enmReason != RTPROCEXITREASON_NORMAL || ProcStatus.iStatus != 0)
        RTTestIFailed("enmReason=%d iStatus=%d", ProcStatus.enmReason, ProcStatus.iStatus);
    else
        RTTestIPassed(NULL);
}
Ejemplo n.º 3
0
/**
 * Time constrained test with and unlimited  N threads.
 */
static void tst3(uint32_t cThreads, uint32_t cbObject, int iMethod, uint32_t cSecs)
{
    RTTestISubF("Benchmark - %u threads, %u bytes, %u secs, %s", cThreads, cbObject, cSecs,
                iMethod == 0 ? "RTMemCache"
                : "RTMemAlloc");

    /*
     * Create a cache with unlimited space, a start semaphore and line up
     * the threads.
     */
    RTTESTI_CHECK_RC_RETV(RTMemCacheCreate(&g_hMemCache, cbObject, 0 /*cbAlignment*/, UINT32_MAX, NULL, NULL, NULL, 0 /*fFlags*/), VINF_SUCCESS);

    RTSEMEVENTMULTI hEvt;
    RTTESTI_CHECK_RC_OK_RETV(RTSemEventMultiCreate(&hEvt));

    TST3THREAD aThreads[64];
    RTTESTI_CHECK_RETV(cThreads < RT_ELEMENTS(aThreads));

    ASMAtomicWriteBool(&g_fTst3Stop, false);
    for (uint32_t i = 0; i < cThreads; i++)
    {
        aThreads[i].hThread     = NIL_RTTHREAD;
        aThreads[i].cIterations = 0;
        aThreads[i].fUseCache   = iMethod == 0;
        aThreads[i].cbObject    = cbObject;
        aThreads[i].hEvt        = hEvt;
        RTTESTI_CHECK_RC_OK_RETV(RTThreadCreateF(&aThreads[i].hThread, tst3Thread, &aThreads[i], 0,
                                                 RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "tst3-%u", i));
    }

    /*
     * Start the race.
     */
    RTTimeNanoTS(); /* warmup */

    uint64_t uStartTS = RTTimeNanoTS();
    RTTESTI_CHECK_RC_OK_RETV(RTSemEventMultiSignal(hEvt));
    RTThreadSleep(cSecs * 1000);
    ASMAtomicWriteBool(&g_fTst3Stop, true);
    for (uint32_t i = 0; i < cThreads; i++)
        RTTESTI_CHECK_RC_OK_RETV(RTThreadWait(aThreads[i].hThread, 60*1000, NULL));
    uint64_t cElapsedNS = RTTimeNanoTS() - uStartTS;

    /*
     * Sum up the counts.
     */
    uint64_t cIterations = 0;
    for (uint32_t i = 0; i < cThreads; i++)
        cIterations += aThreads[i].cIterations;

    RTTestIPrintf(RTTESTLVL_ALWAYS, "%'8u iterations per second, %'llu ns on avg\n",
                  (unsigned)((long double)cIterations * 1000000000.0 / cElapsedNS),
                  cElapsedNS / cIterations);

    /* clean up */
    RTTESTI_CHECK_RC(RTMemCacheDestroy(g_hMemCache), VINF_SUCCESS);
    RTTESTI_CHECK_RC_OK(RTSemEventMultiDestroy(hEvt));
}
static void tst1(size_t cTest, size_t cchDigits, char chSep)
{
    RTTestISubF("tst #%u (digits: %u; sep: %c)", cTest, cchDigits, chSep ? chSep : ' ');

    /* We try to create max possible + one. */
    size_t cTimes = 1;
    for (size_t i = 0; i < cchDigits; ++i)
        cTimes *= 10;

    /* Allocate the result array. */
    char **papszNames = (char **)RTMemTmpAllocZ(cTimes * sizeof(char *));
    RTTESTI_CHECK_RETV(papszNames != NULL);

    int rc = VERR_INTERNAL_ERROR;
    /* The test loop. */
    size_t i;
    for (i = 0; i < cTimes; i++)
    {
        char szName[RTPATH_MAX];
        RTTESTI_CHECK_RC(rc = RTPathAppend(strcpy(szName, g_szTempPath), sizeof(szName), "RTDirCreateUniqueNumbered"), VINF_SUCCESS);
        if (RT_FAILURE(rc))
            break;

        RTTESTI_CHECK_RC(rc = RTDirCreateUniqueNumbered(szName, sizeof(szName), 0700, cchDigits, chSep), VINF_SUCCESS);
        if (RT_FAILURE(rc))
        {
            RTTestIFailed("RTDirCreateUniqueNumbered(%s) call #%u -> %Rrc\n", szName, i, rc);
            break;
        }

        RTTESTI_CHECK(papszNames[i] = RTStrDup(szName));
        if (!papszNames[i])
            break;

        RTTestIPrintf(RTTESTLVL_DEBUG, "%s\n", papszNames[i]);
    }

    /* Try to create one more, which shouldn't be possible. */
    if (RT_SUCCESS(rc))
    {
        char szName[RTPATH_MAX];
        RTTESTI_CHECK_RC(rc = RTPathAppend(strcpy(szName, g_szTempPath), sizeof(szName), "RTDirCreateUniqueNumbered"), VINF_SUCCESS);
        if (RT_SUCCESS(rc))
            RTTESTI_CHECK_RC(rc = RTDirCreateUniqueNumbered(szName, sizeof(szName), 0700, cchDigits, chSep), VERR_ALREADY_EXISTS);
    }

    /* cleanup */
    while (i-- > 0)
    {
        RTTESTI_CHECK_RC(RTDirRemove(papszNames[i]), VINF_SUCCESS);
        RTStrFree(papszNames[i]);
    }
    RTMemTmpFree(papszNames);
}
Ejemplo n.º 5
0
/**
 * Does a multi-threading list test. Several list additions, reading, replacing
 * and erasing are done simultaneous.
 *
 */
static void test2()
{
    RTTestISubF("MT test with 6 threads (%u tests per thread).", MTTESTITEMS);

    RTTHREAD hThread1, hThread2, hThread3, hThread4, hThread5, hThread6;
    int rc = VINF_SUCCESS;

    MTTESTLISTTYPE<MTTESTTYPE> testList;
    rc = RTThreadCreate(&hThread1, &mttest1, &testList, 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "mttest1");
    AssertRC(rc);
    rc = RTThreadCreate(&hThread2, &mttest2, &testList, 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "mttest2");
    AssertRC(rc);
    rc = RTThreadCreate(&hThread3, &mttest3, &testList, 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "mttest3");
    AssertRC(rc);
    rc = RTThreadCreate(&hThread4, &mttest4, &testList, 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "mttest4");
    AssertRC(rc);
    rc = RTThreadCreate(&hThread5, &mttest5, &testList, 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "mttest5");
    AssertRC(rc);
    rc = RTThreadCreate(&hThread6, &mttest6, &testList, 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "mttest6");
    AssertRC(rc);

    rc = RTThreadWait(hThread1, RT_INDEFINITE_WAIT, 0);
    AssertRC(rc);
    rc = RTThreadWait(hThread2, RT_INDEFINITE_WAIT, 0);
    AssertRC(rc);
    rc = RTThreadWait(hThread3, RT_INDEFINITE_WAIT, 0);
    AssertRC(rc);
    rc = RTThreadWait(hThread4, RT_INDEFINITE_WAIT, 0);
    AssertRC(rc);
    rc = RTThreadWait(hThread5, RT_INDEFINITE_WAIT, 0);
    AssertRC(rc);
    rc = RTThreadWait(hThread6, RT_INDEFINITE_WAIT, 0);
    AssertRC(rc);

    RTTESTI_CHECK_RETV(testList.size() == MTTESTITEMS * 2);
    for (size_t i = 0; i < testList.size(); ++i)
    {
        uint32_t a = testList.at(i);
        RTTESTI_CHECK(a == 0x0 || a == 0xFFFFFFFF || a == 0xF0F0F0F0 || a == 0xFF00FF00);
    }
}
Ejemplo n.º 6
0
static void testPerformance(const char *pszSub, uint8_t const *pabInstrs, uintptr_t uEndPtr, DISCPUMODE enmDisCpuMode)
{
    RTTestISubF("Performance - %s", pszSub);

    size_t const    cbInstrs = uEndPtr - (uintptr_t)pabInstrs;
    uint64_t        cInstrs  = 0;
    uint64_t        nsStart  = RTTimeNanoTS();
    for (uint32_t i = 0; i < _512K; i++) /* the samples are way to small. :-) */
    {
        for (size_t off = 0; off < cbInstrs; cInstrs++)
        {
            uint32_t    cb = 1;
            DISSTATE    Dis;
            DISInstrWithReader((uintptr_t)&pabInstrs[off], enmDisCpuMode, testReadBytes, NULL, &Dis, &cb);
            off += cb;
        }
    }
    uint64_t cNsElapsed = RTTimeNanoTS() - nsStart;

    RTTestIValueF(cNsElapsed, RTTESTUNIT_NS, "%s-Total", pszSub);
    RTTestIValueF(cNsElapsed / cInstrs, RTTESTUNIT_NS_PER_CALL, "%s-per-instruction", pszSub);
}
Ejemplo n.º 7
0
/** sub test */
static void tst4Sub(uint32_t cThreads)
{
    RTTestISubF("Serialization - %u threads", cThreads);
    RTMEMPOOL hMemPool;
    RTTESTI_CHECK_RC_RETV(RTMemPoolCreate(&hMemPool, "test 2a"), VINF_SUCCESS);
    g_hMemPool4 = hMemPool;

    PRTTHREAD pahThreads = (PRTTHREAD)RTMemPoolAlloc(hMemPool, cThreads * sizeof(RTTHREAD));
    RTTESTI_CHECK(pahThreads);
    if (pahThreads)
    {
        /* start them. */
        for (uint32_t i = 0; i < cThreads; i++)
        {
            int rc = RTThreadCreateF(&pahThreads[i], tst4Thread, (void *)(uintptr_t)i, 0,
                                     RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "tst4-%u/%u", i, cThreads);
            RTTESTI_CHECK_RC_OK(rc);
            if (RT_FAILURE(rc))
                pahThreads[i] = NIL_RTTHREAD;
        }
        RTThreadYield();

        /* kick them off. */
        for (uint32_t i = 0; i < cThreads; i++)
            if (pahThreads[i] != NIL_RTTHREAD)
                RTTESTI_CHECK_RC_OK(RTThreadUserSignal(pahThreads[i]));

        /* wait for them. */
        for (uint32_t i = 0; i < cThreads; i++)
            if (pahThreads[i] != NIL_RTTHREAD)
            {
                int rc = RTThreadWait(pahThreads[i], 2*60*1000, NULL);
                RTTESTI_CHECK_RC_OK(rc);
            }
    }

    RTTESTI_CHECK_RC(RTMemPoolDestroy(hMemPool), VINF_SUCCESS);
}
Ejemplo n.º 8
0
static void doTest(PTSTSTATE pThis, uint32_t cbRecv, uint32_t cbSend)
{

    /*
     * Create an INTNET instance.
     */
    RTTestISub("IntNetR0Init");
    RTTESTI_CHECK_RC_RETV(IntNetR0Init(), VINF_SUCCESS);

    /*
     * Create two interfaces and activate them.
     */
    RTTestISub("Network creation");
    int rc = tstOpenInterfaces(pThis, "test", cbSend, cbRecv);
    if (RT_FAILURE(rc))
        return;
    RTTESTI_CHECK_RC(IntNetR0IfSetActive(pThis->hIf0, g_pSession, true), VINF_SUCCESS);
    RTTESTI_CHECK_RC(IntNetR0IfSetActive(pThis->hIf1, g_pSession, true), VINF_SUCCESS);

    /*
     * Test basic waiting.
     */
    RTTestISub("IntNetR0IfWait");
    RTTESTI_CHECK_RC(IntNetR0IfWait(pThis->hIf0, g_pSession, 1), VERR_TIMEOUT);
    RTTESTI_CHECK_RC(IntNetR0IfWait(pThis->hIf0, g_pSession, 0), VERR_TIMEOUT);
    RTTESTI_CHECK_RC(IntNetR0IfWait(pThis->hIf1, g_pSession, 1), VERR_TIMEOUT);
    RTTESTI_CHECK_RC(IntNetR0IfWait(pThis->hIf1, g_pSession, 0), VERR_TIMEOUT);

    /*
     * Broadcast send and receive.
     * (This establishes the MAC address of the 1st interface.)
     */
    RTTestISub("Broadcast");
    doBroadcastTest(pThis, false /*fHeadGuard*/);
    doBroadcastTest(pThis, true /*fHeadGuard*/);

    /*
     * Unicast send and receive.
     * (This establishes the MAC address of the 2nd interface.)
     */
    RTTestISub("Unicast");
    doUnicastTest(pThis, false /*fHeadGuard*/);
    doUnicastTest(pThis, true /*fHeadGuard*/);

    /*
     * Do the big bi-directional transfer test if the basics worked out.
     */
    if (!RTTestIErrorCount())
    {
        RTTestISubF("bi-directional benchmark, cbSend=%u, cbRecv=%u, cbTransfer=%u",
                    pThis->pBuf0->cbSend, pThis->pBuf0->cbRecv, g_cbTransfer);
        tstBidirectionalTransfer(pThis, 256);

        for (uint32_t cbFrame = 64; cbFrame < cbSend - 64; cbFrame += 8)
        {
            RTTestISubF("bi-directional benchmark, cbSend=%u, cbRecv=%u, cbTransfer=%u, cbFrame=%u",
                        pThis->pBuf0->cbSend, pThis->pBuf0->cbRecv, g_cbTransfer, cbFrame);
            tstBidirectionalTransfer(pThis, cbFrame);
        }
    }

    /*
     * Destroy the service.
     */
    tstCloseInterfaces(pThis);
    IntNetR0Term();
}
static void test1(const char *pcszDesc, T3 paTestData[], size_t cTestItems)
{
    RTTestISubF("%s with size of %u (items=%u)", pcszDesc, sizeof(T1), cTestItems);

    /*
     * Construction
     */

    /* Create a test list */
    L<T1, T2> testList;

    const size_t defCap = L<T1, T2>::kDefaultCapacity;
    RTTESTI_CHECK(testList.isEmpty());
    RTTESTI_CHECK(testList.size()     == 0);
    RTTESTI_CHECK(testList.capacity() == defCap);

    /*
     * Adding
     */

    /* Add the second half of the test data */
    size_t cAdded = 1;

    /* Start adding the second half of our test list */
    for (size_t i = cTestItems / 2; i < cTestItems; ++i, ++cAdded)
    {
        testList.append(paTestData[i]);
        RTTESTI_CHECK_RETV(testList.size()    == cAdded);
        RTTESTI_CHECK(testList.at(0)          == paTestData[cTestItems / 2]);
        RTTESTI_CHECK(testList[0]             == paTestData[cTestItems / 2]);
        RTTESTI_CHECK(testList.first()        == paTestData[cTestItems / 2]);
        RTTESTI_CHECK(testList.at(cAdded - 1) == paTestData[i]);
        RTTESTI_CHECK(testList[cAdded - 1]    == paTestData[i]);
        RTTESTI_CHECK(testList.last()         == paTestData[i]);
    }

    /* Check that all is correctly appended. */
    RTTESTI_CHECK_RETV(testList.size()        == cTestItems / 2);
    RTTESTI_CHECK_RETV(testList.isEmpty()     == false);
    for (size_t i = 0; i < testList.size(); ++i)
        RTTESTI_CHECK(testList.at(i) == paTestData[cTestItems / 2 + i]);

    /* Start prepending the first half of our test list. Iterate reverse to get
     * the correct sorting back. */
    for (size_t i = cTestItems / 2; i > 0; --i, ++cAdded)
    {
        testList.prepend(paTestData[i - 1]);
        RTTESTI_CHECK_RETV(testList.size()    == cAdded);
        RTTESTI_CHECK(testList.at(0)          == paTestData[i - 1]);
        RTTESTI_CHECK(testList[0]             == paTestData[i - 1]);
        RTTESTI_CHECK(testList.first()        == paTestData[i - 1]);
        RTTESTI_CHECK(testList.at(cAdded - 1) == paTestData[cTestItems - 1]);
        RTTESTI_CHECK(testList[cAdded - 1]    == paTestData[cTestItems - 1]);
        RTTESTI_CHECK(testList.last()         == paTestData[cTestItems - 1]);
    }

    /* Check that all is correctly prepended. */
    RTTESTI_CHECK_RETV(testList.size()        == cTestItems);
    RTTESTI_CHECK_RETV(testList.isEmpty()     == false);
    for (size_t i = 0; i < testList.size(); ++i)
        RTTESTI_CHECK(testList.at(i) == paTestData[i]);

    /*
     * Contains
     */
    L<T1, T2> testList2;

    /* Check full list. */
    RTTESTI_CHECK( testList.contains(paTestData[0]));
    RTTESTI_CHECK( testList.contains(paTestData[cTestItems / 2]));
    RTTESTI_CHECK( testList.contains(paTestData[cTestItems - 1]));
    RTTESTI_CHECK(!testList.contains(T1()));
    /* Check empty list. */
    RTTESTI_CHECK(!testList2.contains(paTestData[0]));
    RTTESTI_CHECK(!testList2.contains(paTestData[cTestItems / 2]));
    RTTESTI_CHECK(!testList2.contains(paTestData[cTestItems - 1]));
    RTTESTI_CHECK(!testList2.contains(T1()));

    /*
     * Copy operator
     */
    L<T1, T2> testList3(testList);

    /* Check that all is correctly appended. */
    RTTESTI_CHECK_RETV(testList3.size() == cTestItems);
    for (size_t i = 0; i < testList3.size(); ++i)
        RTTESTI_CHECK(testList3.at(i) == paTestData[i]);

    /*
     * "=" operator
     */
    L<T1, T2> testList4;
    testList4 = testList;

    /* Check that all is correctly appended. */
    RTTESTI_CHECK_RETV(testList4.size() == cTestItems);
    for (size_t i = 0; i < testList4.size(); ++i)
        RTTESTI_CHECK(testList4.at(i) == paTestData[i]);

    /*
     * Append list
     */
    testList3.append(testList4);

    /* Check that all is correctly appended. */
    RTTESTI_CHECK_RETV(testList3.size() == cTestItems * 2);
    for (size_t i = 0; i < testList3.size(); ++i)
        RTTESTI_CHECK(testList3.at(i) == paTestData[i % cTestItems]);

    /*
     * Prepend list
     */
    testList3.prepend(testList4);

    /* Check that all is correctly appended. */
    RTTESTI_CHECK_RETV(testList3.size() == cTestItems * 3);
    for (size_t i = 0; i < testList3.size(); ++i)
        RTTESTI_CHECK(testList3.at(i) == paTestData[i % cTestItems]);

    /*
     * "value" method
     */
    for (size_t i = 0; i < testList3.size(); ++i)
        RTTESTI_CHECK(testList3.value(i)       == paTestData[i % cTestItems]);
    for (size_t i = 0; i < testList3.size(); ++i)
        RTTESTI_CHECK(testList3.value(i, T1()) == paTestData[i % cTestItems]);
    RTTESTI_CHECK(testList3.value(testList3.size() + 1) == T1());       /* Invalid index */
    RTTESTI_CHECK(testList3.value(testList3.size() + 1, T1()) == T1()); /* Invalid index */

    /*
     * operator[] (reading)
     */
    for (size_t i = 0; i < testList.size(); ++i)
        RTTESTI_CHECK(testList[i] == paTestData[i]);

    /*
     * operator[] (writing)
     *
     * Replace with inverted array.
     */
    for (size_t i = 0; i < cTestItems; ++i)
        testList[i] = paTestData[cTestItems - i - 1];
    RTTESTI_CHECK_RETV(testList.size() == cTestItems);
    for (size_t i = 0; i < testList.size(); ++i)
        RTTESTI_CHECK(testList[i] == paTestData[cTestItems - i - 1]);

    /*
     * Replace
     *
     * Replace with inverted array (Must be original array when finished).
     */
    for (size_t i = 0; i < cTestItems; ++i)
        testList.replace(i, paTestData[i]);
    RTTESTI_CHECK_RETV(testList.size() == cTestItems);
    for (size_t i = 0; i < testList.size(); ++i)
        RTTESTI_CHECK(testList[i] == paTestData[i]);

    /*
     * Removing
     */

    /* Remove Range */
    testList3.removeRange(cTestItems, cTestItems * 2);
    RTTESTI_CHECK_RETV(testList3.size() == cTestItems * 2);
    for (size_t i = 0; i < testList3.size(); ++i)
        RTTESTI_CHECK(testList3.at(i) == paTestData[i % cTestItems]);

    /* Remove the first half (reverse) */
    size_t cRemoved = 1;
    for (size_t i = cTestItems / 2; i > 0; --i, ++cRemoved)
    {
        testList.removeAt(i - 1);
        RTTESTI_CHECK_RETV(testList.size() == cTestItems - cRemoved);
    }
    RTTESTI_CHECK_RETV(testList.size() == cTestItems / 2);

    /* Check that all is correctly removed and only the second part of the list
     * is still there. */
    for (size_t i = 0; i < testList.size(); ++i)
        RTTESTI_CHECK(testList.at(i) == paTestData[cTestItems / 2 + i]);

    /*
     * setCapacitiy
     */
    testList.setCapacity(cTestItems * 5);
    RTTESTI_CHECK(testList.capacity()  == cTestItems * 5);
    RTTESTI_CHECK_RETV(testList.size() == cTestItems / 2);

    /* As the capacity just increased, we should still have all entries from
     * the previous list. */
    for (size_t i = 0; i < testList.size(); ++i)
        RTTESTI_CHECK(testList.at(i) == paTestData[cTestItems / 2 + i]);

    /* Decrease the capacity so it will be smaller than the count of items in
     * the list. The list should be shrink automatically, but the remaining
     * items should be still valid. */
    testList.setCapacity(cTestItems / 4);
    RTTESTI_CHECK_RETV(testList.size() == cTestItems / 4);
    RTTESTI_CHECK(testList.capacity()  == cTestItems / 4);
    for (size_t i = 0; i < testList.size(); ++i)
        RTTESTI_CHECK(testList.at(i) == paTestData[cTestItems / 2 + i]);

    /* Clear all */
    testList.clear();
    RTTESTI_CHECK_RETV(testList.isEmpty());
    RTTESTI_CHECK_RETV(testList.size() == 0);
    RTTESTI_CHECK(testList.capacity()  == defCap);


    /* Copy empty lists. */
    L<T1, T2> testList5(testList);
    RTTESTI_CHECK_RETV(testList5.isEmpty());
    RTTESTI_CHECK_RETV(testList5.size() == 0);
    RTTESTI_CHECK(testList5.capacity()  == 0);

    testList5.append(paTestData[0]);
    testList5 = testList;
    RTTESTI_CHECK_RETV(testList5.isEmpty());
    RTTESTI_CHECK_RETV(testList5.size() == 0);
    RTTESTI_CHECK(testList5.capacity()  == 0);

    /*
     * Negative testing.
     */
    bool fMayPanic = RTAssertMayPanic();
    bool fQuiet    = RTAssertAreQuiet();
    RTAssertSetMayPanic(false);
    RTAssertSetQuiet(true);

    L<T1, T2> testList6;
    for (size_t i = 0; i < cTestItems; ++i)
        testList6.insert(i, paTestData[i]);
    RTTESTI_CHECK(testList6.size() == cTestItems);

    /* Insertion beyond the end of the array ends up at the end. */
    size_t cBefore = testList6.size();
    testList6.insert(cBefore + 3, paTestData[0]);
    RTTESTI_CHECK(testList6.size() == cBefore + 1);
    RTTESTI_CHECK(testList6.at(cBefore) == paTestData[0]);

    cBefore = testList6.size();
    L<T1, T2> testList7(testList6);
    testList6.insert(testList6.size() + 42, testList7);
    RTTESTI_CHECK(testList6.size() == cBefore + testList7.size());

    /* Inserting, appending or prepending a list to itself is not supported. */
    cBefore = testList6.size();
    testList6.insert(3, testList6);
    RTTESTI_CHECK(testList6.size() == cBefore);

    cBefore = testList6.size();
    testList6.append(testList6);
    RTTESTI_CHECK(testList6.size() == cBefore);

    cBefore = testList6.size();
    testList6.prepend(testList6);
    RTTESTI_CHECK(testList6.size() == cBefore);

    /* Replace does nothing if the index is bad. */
    cBefore = testList6.size();
    testList6.replace(cBefore, testList6[6]);
    RTTESTI_CHECK(testList6.size() == cBefore);

    cBefore = testList6.size();
    testList6.replace(cBefore + 64, testList6[6]);
    RTTESTI_CHECK(testList6.size() == cBefore);

    /* Indexing beyond the array returns the last element. */
    cBefore = testList6.size();
    RTTESTI_CHECK(testList6[cBefore] == testList6.last());
    RTTESTI_CHECK(testList6[cBefore + 42] == testList6.last());

    RTTESTI_CHECK(&testList6[cBefore]      == &testList6[cBefore - 1]);
    RTTESTI_CHECK(&testList6[cBefore + 42] == &testList6[cBefore - 1]);

    /* removeAt does nothing if the index is bad. */
    cBefore = testList6.size();
    testList6.removeAt(cBefore);
    RTTESTI_CHECK(testList6.size() == cBefore);

    cBefore = testList6.size();
    testList6.removeAt(cBefore + 42);
    RTTESTI_CHECK(testList6.size() == cBefore);

    L<T1, T2> testListEmpty1; RTTESTI_CHECK(!testListEmpty1.size());
    testListEmpty1.removeFirst();
    RTTESTI_CHECK(!testListEmpty1.size());

    testListEmpty1.removeLast();
    RTTESTI_CHECK(!testListEmpty1.size());

    testListEmpty1.removeAt(128);
    RTTESTI_CHECK(!testListEmpty1.size());

    /* removeRange interprets indexes beyond the end as the end of array (asserted). */
    testListEmpty1.removeRange(42, 128);
    RTTESTI_CHECK(!testListEmpty1.size());

    cBefore = testList6.size();
    testList6.removeRange(cBefore, cBefore);
    RTTESTI_CHECK(testList6.size() == cBefore);

    cBefore = testList6.size();
    testList6.removeRange(cBefore + 12, cBefore + 128);
    RTTESTI_CHECK(testList6.size() == cBefore);

    /* If end is less or equal to the start, nothing is done. */
    testListEmpty1.removeRange(128, 0);
    RTTESTI_CHECK(!testListEmpty1.size());

    cBefore = testList6.size();
    testList6.removeRange(cBefore, 0);
    RTTESTI_CHECK(testList6.size() == cBefore);

    cBefore = testList6.size();
    testList6.removeRange(0, 0);
    RTTESTI_CHECK(testList6.size() == cBefore);

    cBefore = testList6.size();
    testList6.removeRange(0, 0);
    RTTESTI_CHECK(testList6.size() == cBefore);

    RTAssertSetQuiet(fQuiet);
    RTAssertSetMayPanic(fMayPanic);
}
Ejemplo n.º 10
0
static void test1(const char *pcszDesc, T3 paTestData[], size_t cTestItems)
{
    RTTestISubF("%s with size of %u (items=%u)", pcszDesc, sizeof(T1), cTestItems);

    /*
     * Construction
     */

    /* Create a test list */
    L<T1, T2> testList;

    const size_t defCap = L<T1, T2>::DefaultCapacity;
    RTTESTI_CHECK(testList.isEmpty());
    RTTESTI_CHECK(testList.size()     == 0);
    RTTESTI_CHECK(testList.capacity() == defCap);

    /*
     * Adding
     */

    /* Add the second half of the test data */
    size_t cAdded = 1;

    /* Start adding the second half of our test list */
    for (size_t i = cTestItems / 2; i < cTestItems; ++i, ++cAdded)
    {
        testList.append(paTestData[i]);
        RTTESTI_CHECK_RETV(testList.size()    == cAdded);
        RTTESTI_CHECK(testList.at(0)          == paTestData[cTestItems / 2]);
        RTTESTI_CHECK(testList[0]             == paTestData[cTestItems / 2]);
        RTTESTI_CHECK(testList.first()        == paTestData[cTestItems / 2]);
        RTTESTI_CHECK(testList.at(cAdded - 1) == paTestData[i]);
        RTTESTI_CHECK(testList[cAdded - 1]    == paTestData[i]);
        RTTESTI_CHECK(testList.last()         == paTestData[i]);
    }

    /* Check that all is correctly appended. */
    RTTESTI_CHECK_RETV(testList.size()        == cTestItems / 2);
    RTTESTI_CHECK_RETV(testList.isEmpty()     == false);
    for (size_t i = 0; i < testList.size(); ++i)
        RTTESTI_CHECK(testList.at(i) == paTestData[cTestItems / 2 + i]);

    /* Start prepending the first half of our test list. Iterate reverse to get
     * the correct sorting back. */
    for (size_t i = cTestItems / 2; i > 0; --i, ++cAdded)
    {
        testList.prepend(paTestData[i - 1]);
        RTTESTI_CHECK_RETV(testList.size()    == cAdded);
        RTTESTI_CHECK(testList.at(0)          == paTestData[i - 1]);
        RTTESTI_CHECK(testList[0]             == paTestData[i - 1]);
        RTTESTI_CHECK(testList.first()        == paTestData[i - 1]);
        RTTESTI_CHECK(testList.at(cAdded - 1) == paTestData[cTestItems - 1]);
        RTTESTI_CHECK(testList[cAdded - 1]    == paTestData[cTestItems - 1]);
        RTTESTI_CHECK(testList.last()         == paTestData[cTestItems - 1]);
    }

    /* Check that all is correctly prepended. */
    RTTESTI_CHECK_RETV(testList.size()        == cTestItems);
    RTTESTI_CHECK_RETV(testList.isEmpty()     == false);
    for (size_t i = 0; i < testList.size(); ++i)
        RTTESTI_CHECK(testList.at(i) == paTestData[i]);

    /*
     * Contains
     */
    L<T1, T2> testList2;

    /* Check full list. */
    RTTESTI_CHECK( testList.contains(paTestData[0]));
    RTTESTI_CHECK( testList.contains(paTestData[cTestItems / 2]));
    RTTESTI_CHECK( testList.contains(paTestData[cTestItems - 1]));
    RTTESTI_CHECK(!testList.contains(T1()));
    /* Check empty list. */
    RTTESTI_CHECK(!testList2.contains(paTestData[0]));
    RTTESTI_CHECK(!testList2.contains(paTestData[cTestItems / 2]));
    RTTESTI_CHECK(!testList2.contains(paTestData[cTestItems - 1]));
    RTTESTI_CHECK(!testList2.contains(T1()));

    /*
     * Copy operator
     */
    L<T1, T2> testList3(testList);

    /* Check that all is correctly appended. */
    RTTESTI_CHECK_RETV(testList3.size() == cTestItems);
    for (size_t i = 0; i < testList3.size(); ++i)
        RTTESTI_CHECK(testList3.at(i) == paTestData[i]);

    /*
     * "=" operator
     */
    L<T1, T2> testList4;
    testList4 = testList;

    /* Check that all is correctly appended. */
    RTTESTI_CHECK_RETV(testList4.size() == cTestItems);
    for (size_t i = 0; i < testList4.size(); ++i)
        RTTESTI_CHECK(testList4.at(i) == paTestData[i]);

    /*
     * Append list
     */
    testList3.append(testList4);

    /* Check that all is correctly appended. */
    RTTESTI_CHECK_RETV(testList3.size() == cTestItems * 2);
    for (size_t i = 0; i < testList3.size(); ++i)
        RTTESTI_CHECK(testList3.at(i) == paTestData[i % cTestItems]);

    /*
     * Prepend list
     */
    testList3.prepend(testList4);

    /* Check that all is correctly appended. */
    RTTESTI_CHECK_RETV(testList3.size() == cTestItems * 3);
    for (size_t i = 0; i < testList3.size(); ++i)
        RTTESTI_CHECK(testList3.at(i) == paTestData[i % cTestItems]);

    /*
     * "value" method
     */
    for (size_t i = 0; i < testList3.size(); ++i)
        RTTESTI_CHECK(testList3.value(i)       == paTestData[i % cTestItems]);
    for (size_t i = 0; i < testList3.size(); ++i)
        RTTESTI_CHECK(testList3.value(i, T1()) == paTestData[i % cTestItems]);
    RTTESTI_CHECK(testList3.value(testList3.size() + 1) == T1());       /* Invalid index */
    RTTESTI_CHECK(testList3.value(testList3.size() + 1, T1()) == T1()); /* Invalid index */

    /*
     * operator[] (reading)
     */
    for (size_t i = 0; i < testList.size(); ++i)
        RTTESTI_CHECK(testList[i] == paTestData[i]);

    /*
     * operator[] (writing)
     *
     * Replace with inverted array.
     */
    for (size_t i = 0; i < cTestItems; ++i)
        testList[i] = paTestData[cTestItems - i - 1];
    RTTESTI_CHECK_RETV(testList.size() == cTestItems);
    for (size_t i = 0; i < testList.size(); ++i)
        RTTESTI_CHECK(testList[i] == paTestData[cTestItems - i - 1]);

    /*
     * Replace
     *
     * Replace with inverted array (Must be original array when finished).
     */
    for (size_t i = 0; i < cTestItems; ++i)
        testList.replace(i, paTestData[i]);
    RTTESTI_CHECK_RETV(testList.size() == cTestItems);
    for (size_t i = 0; i < testList.size(); ++i)
        RTTESTI_CHECK(testList[i] == paTestData[i]);

    /*
     * Removing
     */

    /* Remove Range */
    testList3.removeRange(cTestItems, cTestItems * 2);
    RTTESTI_CHECK_RETV(testList3.size() == cTestItems * 2);
    for (size_t i = 0; i < testList3.size(); ++i)
        RTTESTI_CHECK(testList3.at(i) == paTestData[i % cTestItems]);

    /* Remove the first half (reverse) */
    size_t cRemoved = 1;
    for (size_t i = cTestItems / 2; i > 0; --i, ++cRemoved)
    {
        testList.removeAt(i - 1);
        RTTESTI_CHECK_RETV(testList.size() == cTestItems - cRemoved);
    }
    RTTESTI_CHECK_RETV(testList.size() == cTestItems / 2);

    /* Check that all is correctly removed and only the second part of the list
     * is still there. */
    for (size_t i = 0; i < testList.size(); ++i)
        RTTESTI_CHECK(testList.at(i) == paTestData[cTestItems / 2 + i]);

    /*
     * setCapacitiy
     */
    testList.setCapacity(cTestItems * 5);
    RTTESTI_CHECK(testList.capacity()  == cTestItems * 5);
    RTTESTI_CHECK_RETV(testList.size() == cTestItems / 2);

    /* As the capacity just increased, we should still have all entries from
     * the previous list. */
    for (size_t i = 0; i < testList.size(); ++i)
        RTTESTI_CHECK(testList.at(i) == paTestData[cTestItems / 2 + i]);

    /* Decrease the capacity so it will be smaller than the count of items in
     * the list. The list should be shrink automatically, but the remaining
     * items should be still valid. */
    testList.setCapacity(cTestItems / 4);
    RTTESTI_CHECK_RETV(testList.size() == cTestItems / 4);
    RTTESTI_CHECK(testList.capacity()  == cTestItems / 4);
    for (size_t i = 0; i < testList.size(); ++i)
        RTTESTI_CHECK(testList.at(i) == paTestData[cTestItems / 2 + i]);

    /* Clear all */
    testList.clear();
    RTTESTI_CHECK_RETV(testList.isEmpty());
    RTTESTI_CHECK_RETV(testList.size() == 0);
    RTTESTI_CHECK(testList.capacity()  == defCap);


    /* Copy empty lists. */
    L<T1, T2> testList5(testList);
    RTTESTI_CHECK_RETV(testList5.isEmpty());
    RTTESTI_CHECK_RETV(testList5.size() == 0);
    RTTESTI_CHECK(testList5.capacity()  == 0);

    testList5.append(paTestData[0]);
    testList5 = testList;
    RTTESTI_CHECK_RETV(testList5.isEmpty());
    RTTESTI_CHECK_RETV(testList5.size() == 0);
    RTTESTI_CHECK(testList5.capacity()  == 0);

}