VirtualBox

Changeset 27649 in vbox for trunk/src/VBox/Runtime


Ignore:
Timestamp:
Mar 23, 2010 10:43:29 PM (15 years ago)
Author:
vboxsync
Message:

RTTest: Added RTTest*Value* for reporting simple benchmark result. Implemented the test pipe + file.

Location:
trunk/src/VBox/Runtime/r3
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r3/test.cpp

    r26683 r27649  
    3939#include <iprt/env.h>
    4040#include <iprt/err.h>
     41#include <iprt/file.h>
    4142#include <iprt/initterm.h>
    4243#include <iprt/mem.h>
    4344#include <iprt/once.h>
    4445#include <iprt/param.h>
     46#include <iprt/pipe.h>
    4547#include <iprt/string.h>
    4648#include <iprt/stream.h>
     
    104106
    105107
    106     /** Critical section seralizing access to the members following it. */
     108    /** Critical section serializing access to the members following it. */
    107109    RTCRITSECT          Lock;
    108110
     
    124126    uint32_t            cSubTestsFailed;
    125127
     128    /** Set if XML output is enabled. */
     129    bool                fXmlEnabled;
     130    enum {
     131        kXmlPos_ValueStart,
     132        kXmlPos_Value,
     133        kXmlPos_ElementEnd
     134    }                   eXmlState;
     135    /** Test pipe for the XML output stream going to the server. */
     136    RTPIPE              hXmlPipe;
     137    /** File where the XML output stream might be directed.  */
     138    RTFILE              hXmlFile;
     139    /** The number of XML elements on the stack. */
     140    size_t              cXmlElements;
     141    /** XML element stack. */
     142    const char         *apszXmlElements[10];
    126143} RTTESTINT;
    127144/** Pointer to a test instance. */
     
    167184*******************************************************************************/
    168185static void rtTestGuardedFreeOne(PRTTESTGUARDEDMEM pMem);
    169 static int rtTestPrintf(PRTTESTINT pTest, const char *pszFormat, ...);
     186static int  rtTestPrintf(PRTTESTINT pTest, const char *pszFormat, ...);
     187static void rtTestXmlStart(PRTTESTINT pTest, const char *pszTest);
     188static void rtTestXmlElemV(PRTTESTINT pTest, const char *pszTag, const char *pszAttrFmt, va_list va);
     189static void rtTestXmlElem(PRTTESTINT pTest, const char *pszTag, const char *pszAttrFmt, ...);
     190static void rtTestXmlElemStartV(PRTTESTINT pTest, const char *pszTag, const char *pszAttrFmt, va_list va);
     191static void rtTestXmlElemStart(PRTTESTINT pTest, const char *pszTag, const char *pszAttrFmt, ...);
     192static void rtTestXmlElemValueV(PRTTESTINT pTest, const char *pszFormat, va_list va);
     193static void rtTestXmlElemValue(PRTTESTINT pTest, const char *pszFormat, ...);
     194static void rtTestXmlElemEnd(PRTTESTINT pTest, const char *pszTag);
     195static void rtTestXmlEnd(PRTTESTINT pTest);
    170196
    171197
     
    236262    pTest->cSubTestsFailed  = 0;
    237263
     264    pTest->fXmlEnabled      = false;
     265    pTest->eXmlState        = RTTESTINT::kXmlPos_ElementEnd;
     266    pTest->hXmlPipe         = NIL_RTPIPE;
     267    pTest->hXmlFile         = NIL_RTFILE;
     268    pTest->cXmlElements     = 0;
     269
    238270    rc = RTCritSectInit(&pTest->Lock);
    239271    if (RT_SUCCESS(rc))
     
    242274        if (RT_SUCCESS(rc))
    243275        {
    244 
    245276            /*
    246277             * Associate it with our TLS entry unless there is already
     
    252283            {
    253284                /*
    254                  * Finally, pick up overrides from the environment.
     285                 * Pick up overrides from the environment.
    255286                 */
    256                 char szMaxLevel[80];
    257                 rc = RTEnvGetEx(RTENV_DEFAULT, "IPRT_TEST_MAX_LEVEL", szMaxLevel, sizeof(szMaxLevel), NULL);
     287                char szEnvVal[RTPATH_MAX];
     288                rc = RTEnvGetEx(RTENV_DEFAULT, "IPRT_TEST_MAX_LEVEL", szEnvVal, sizeof(szEnvVal), NULL);
    258289                if (RT_SUCCESS(rc))
    259290                {
    260                     char *pszMaxLevel = RTStrStrip(szMaxLevel);
     291                    char *pszMaxLevel = RTStrStrip(szEnvVal);
    261292                    if (!strcmp(pszMaxLevel, "all"))
    262293                        pTest->enmMaxLevel = RTTESTLVL_DEBUG;
     
    273304                }
    274305
     306                /*
     307                 * Any test driver we are connected or should connect to?
     308                 */
     309                rc = RTEnvGetEx(RTENV_DEFAULT, "IPRT_TEST_PIPE", szEnvVal, sizeof(szEnvVal), NULL);
     310                if (RT_SUCCESS(rc))
     311                {
     312                    RTHCINTPTR  hNative = -1;
     313#if ARCH_BITS == 64
     314                    rc =  RTStrToInt64Full(szEnvVal, 0, &hNative);
     315#else
     316                    rc =  RTStrToInt32Full(szEnvVal, 0, &hNative);
     317#endif
     318                    if (RT_SUCCESS(rc))
     319                    {
     320                        rc = RTPipeFromNative(&pTest->hXmlPipe, hNative, RTPIPE_N_WRITE);
     321                        if (RT_SUCCESS(rc))
     322                            pTest->fXmlEnabled = true;
     323                        else
     324                        {
     325                            RTStrmPrintf(g_pStdErr, "%s: test pipe error: RTPipeFromNative(,\"%s\",WRITE) -> %Rrc\n", pszTest, szEnvVal, rc);
     326                            pTest->hXmlPipe = NIL_RTPIPE;
     327                        }
     328                    }
     329                    else
     330                        RTStrmPrintf(g_pStdErr, "%s: test pipe error: RTStrToInt32Full(\"%s\") -> %Rrc\n", pszTest, szEnvVal, rc);
     331                }
     332                else if (rc != VERR_ENV_VAR_NOT_FOUND)
     333                    RTStrmPrintf(g_pStdErr, "%s: test pipe error: RTEnvGetEx(IPRT_TEST_PIPE) -> %Rrc\n", pszTest, rc);
     334
     335                /*
     336                 * Any test file we should write the test report to?
     337                 */
     338                rc = RTEnvGetEx(RTENV_DEFAULT, "IPRT_TEST_FILE", szEnvVal, sizeof(szEnvVal), NULL);
     339                if (RT_SUCCESS(rc))
     340                {
     341                    rc = RTFileOpen(&pTest->hXmlFile, szEnvVal, RTFILE_O_WRITE | RTFILE_O_DENY_WRITE | RTFILE_O_CREATE_REPLACE);
     342                    if (RT_SUCCESS(rc))
     343                        pTest->fXmlEnabled = true;
     344                    else
     345                    {
     346                        RTStrmPrintf(g_pStdErr, "%s: test file error: RTFileOpen(,\"%s\",) -> %Rrc\n", pszTest, szEnvVal, rc);
     347                        pTest->hXmlFile = NIL_RTFILE;
     348                    }
     349                }
     350                else if (rc != VERR_ENV_VAR_NOT_FOUND)
     351                    RTStrmPrintf(g_pStdErr, "%s: test file error: RTEnvGetEx(IPRT_TEST_FILE) -> %Rrc\n", pszTest, rc);
     352
     353
     354                /*
     355                 * Tell the test driver that we're up.
     356                 */
     357                rtTestXmlStart(pTest, pszTest);
     358
    275359                *phTest = pTest;
    276360                return VINF_SUCCESS;
     
    294378    if (RT_FAILURE(rc))
    295379    {
    296         RTStrmPrintf(g_pStdErr, "%s: fatal error: RTR3Init failed with rc=%Rrc\n",  pszTest, rc);
     380        RTStrmPrintf(g_pStdErr, "%s: fatal error: RTR3Init failed with rc=%Rrc\n", pszTest, rc);
    297381        return RTEXITCODE_INIT;
    298382    }
     
    300384    if (RT_FAILURE(rc))
    301385    {
    302         RTStrmPrintf(g_pStdErr, "%s: fatal error: RTTestCreate failed with rc=%Rrc\n",  pszTest, rc);
     386        RTStrmPrintf(g_pStdErr, "%s: fatal error: RTTestCreate failed with rc=%Rrc\n", pszTest, rc);
    303387        return RTEXITCODE_INIT;
    304388    }
     
    324408
    325409    /*
    326      * Make sure we end with a new line.
     410     * Make sure we end with a new line and have finished up the XML.
    327411     */
    328412    if (!pTest->fNewLine)
    329413        rtTestPrintf(pTest, "\n");
     414    rtTestXmlEnd(pTest);
    330415
    331416    /*
     
    550635
    551636/**
     637 * Outputs the formatted XML.
     638 *
     639 * @param   pTest               The test instance.
     640 * @param   pszFormat           The format string.
     641 * @param   va                  The format arguments.
     642 */
     643static void rtTestXmlOutputV(PRTTESTINT pTest, const char *pszFormat, va_list va)
     644{
     645    if (pTest->fXmlEnabled)
     646    {
     647        char *pszStr;
     648        ssize_t cchStr = RTStrAPrintfV(&pszStr, pszFormat, va);
     649        if (pszStr)
     650        {
     651            if (pTest->hXmlPipe != NIL_RTPIPE)
     652                RTPipeWriteBlocking(pTest->hXmlPipe, pszStr, cchStr,  NULL);
     653            if (pTest->hXmlFile != NIL_RTFILE)
     654                RTFileWrite(pTest->hXmlFile, pszStr, cchStr, NULL);
     655            RTStrFree(pszStr);
     656        }
     657    }
     658}
     659
     660
     661/**
     662 * Outputs the formatted XML.
     663 *
     664 * @param   pTest               The test instance.
     665 * @param   pszFormat           The format string.
     666 * @param   ...                 The format arguments.
     667 */
     668static void rtTestXmlOutput(PRTTESTINT pTest, const char *pszFormat, ...)
     669{
     670    va_list va;
     671    va_start(va, pszFormat);
     672    rtTestXmlOutputV(pTest, pszFormat, va);
     673    va_end(va);
     674}
     675
     676
     677/**
     678 * Starts the XML stream.
     679 *
     680 * @param   pTest               The test instance.
     681 * @param   pszTest             The test name.
     682 */
     683static void rtTestXmlStart(PRTTESTINT pTest, const char *pszTest)
     684{
     685    pTest->cXmlElements = 0;
     686    if (pTest->fXmlEnabled)
     687    {
     688        rtTestXmlOutput(pTest, "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
     689        pTest->eXmlState = RTTESTINT::kXmlPos_ElementEnd;
     690        rtTestXmlElemStart(pTest, "Test", "name=%RMas", pszTest);
     691    }
     692}
     693
     694/**
     695 * Emit an XML element that doesn't have any value and instead ends immediately.
     696 *
     697 * The caller must own the instance lock.
     698 *
     699 * @param   pTest               The test instance.
     700 * @param   pszTag              The element tag.
     701 * @param   pszAttrFmt          The element attributes as a format string. Use
     702 *                              NULL if none.
     703 * @param   va                  Format string arguments.
     704 */
     705static void rtTestXmlElemV(PRTTESTINT pTest, const char *pszTag, const char *pszAttrFmt, va_list va)
     706{
     707    if (pTest->fXmlEnabled)
     708    {
     709        RTTIMESPEC  TimeSpec;
     710        RTTIME      Time;
     711        char        szTS[80];
     712        RTTimeToString(RTTimeExplode(&Time, RTTimeNow(&TimeSpec)), szTS, sizeof(szTS));
     713
     714        if (pTest->eXmlState != RTTESTINT::kXmlPos_ElementEnd)
     715            rtTestXmlOutput(pTest, "\n");
     716
     717        if (!pszAttrFmt || !*pszAttrFmt)
     718            rtTestXmlOutput(pTest, "%*s<%s timestamp=%RMas/>\n",
     719                            pTest->cXmlElements * 2, "", pszTag, szTS);
     720        else
     721        {
     722            va_list va2;
     723            va_copy(va2, va);
     724            rtTestXmlOutput(pTest, "%*s<%s timestamp=%RMas %N/>\n",
     725                            pTest->cXmlElements * 2, "", pszTag, szTS, pszAttrFmt, &va2);
     726            va_end(va2);
     727        }
     728        pTest->eXmlState = RTTESTINT::kXmlPos_ElementEnd;
     729    }
     730}
     731
     732/**
     733 * Wrapper around rtTestXmlElemV.
     734 */
     735static void rtTestXmlElem(PRTTESTINT pTest, const char *pszTag, const char *pszAttrFmt, ...)
     736{
     737    va_list va;
     738    va_start(va, pszAttrFmt);
     739    rtTestXmlElemV(pTest, pszTag, pszAttrFmt, va);
     740    va_end(va);
     741}
     742
     743
     744/**
     745 * Starts a new XML element.
     746 *
     747 * The caller must own the instance lock.
     748 *
     749 * @param   pTest               The test instance.
     750 * @param   pszTag              The element tag.
     751 * @param   pszAttrFmt          The element attributes as a format string. Use
     752 *                              NULL if none.
     753 * @param   va                  Format string arguments.
     754 */
     755static void rtTestXmlElemStartV(PRTTESTINT pTest, const char *pszTag, const char *pszAttrFmt, va_list va)
     756{
     757    /* Push it onto the stack. */
     758    size_t i = pTest->cXmlElements;
     759    AssertReturnVoid(i < RT_ELEMENTS(pTest->apszXmlElements));
     760    pTest->apszXmlElements[i] = pszTag;
     761    pTest->cXmlElements       = i + 1;
     762
     763    if (pTest->fXmlEnabled)
     764    {
     765        RTTIMESPEC  TimeSpec;
     766        RTTIME      Time;
     767        char        szTS[80];
     768        RTTimeToString(RTTimeExplode(&Time, RTTimeNow(&TimeSpec)), szTS, sizeof(szTS));
     769
     770        if (pTest->eXmlState != RTTESTINT::kXmlPos_ElementEnd)
     771            rtTestXmlOutput(pTest, "\n");
     772
     773        if (!pszAttrFmt || !*pszAttrFmt)
     774            rtTestXmlOutput(pTest, "%*s<%s timestamp=%RMas>",
     775                            i * 2, "", pszTag, szTS);
     776        else
     777        {
     778            va_list va2;
     779            va_copy(va2, va);
     780            rtTestXmlOutput(pTest, "%*s<%s timestamp=%RMas %N>",
     781                            i * 2, "", pszTag, szTS, pszAttrFmt, &va2);
     782            va_end(va2);
     783        }
     784        pTest->eXmlState = RTTESTINT::kXmlPos_ValueStart;
     785    }
     786}
     787
     788
     789/**
     790 * Wrapper around rtTestXmlElemStartV.
     791 */
     792static void rtTestXmlElemStart(PRTTESTINT pTest, const char *pszTag, const char *pszAttrFmt, ...)
     793{
     794    va_list va;
     795    va_start(va, pszAttrFmt);
     796    rtTestXmlElemStartV(pTest, pszTag, pszAttrFmt, va);
     797    va_end(va);
     798}
     799
     800
     801/**
     802 * Writes an element value, or a part of one, taking care of all the escaping.
     803 *
     804 * The caller must own the instance lock.
     805 *
     806 * @param   pTest               The test instance.
     807 * @param   pszFormat           The value format string.
     808 * @param   va                  The format arguments.
     809 */
     810static void rtTestXmlElemValueV(PRTTESTINT pTest, const char *pszFormat, va_list va)
     811{
     812    if (pTest->fXmlEnabled)
     813    {
     814        char *pszValue;
     815        RTStrAPrintfV(&pszValue, pszFormat, va);
     816        if (pszValue)
     817        {
     818            rtTestXmlOutput(pTest, "%RMes", pszValue);
     819            RTStrFree(pszValue);
     820        }
     821        pTest->eXmlState = RTTESTINT::kXmlPos_Value;
     822    }
     823}
     824
     825
     826/**
     827 * Wrapper around rtTestXmlElemValueV.
     828 */
     829static void rtTestXmlElemValue(PRTTESTINT pTest, const char *pszFormat, ...)
     830{
     831    va_list va;
     832    va_start(va, pszFormat);
     833    rtTestXmlElemValueV(pTest, pszFormat, va);
     834    va_end(va);
     835}
     836
     837
     838/**
     839 * Ends the current element.
     840 *
     841 * The caller must own the instance lock.
     842 *
     843 * @param   pTest               The test instance.
     844 * @param   pszTag              The tag we're ending (chiefly for sanity
     845 *                              checking).
     846 */
     847static void rtTestXmlElemEnd(PRTTESTINT pTest, const char *pszTag)
     848{
     849    /* pop the element */
     850    size_t i = pTest->cXmlElements;
     851    AssertReturnVoid(i > 0);
     852    i--;
     853    AssertReturnVoid(!strcmp(pszTag, pTest->apszXmlElements[i]));
     854    pTest->cXmlElements = i;
     855
     856    /* Do the closing. */
     857    if (pTest->fXmlEnabled)
     858    {
     859        if (pTest->eXmlState == RTTESTINT::kXmlPos_ValueStart)
     860            rtTestXmlOutput(pTest, "\n%*s</%s>\n", i * 2, "", pszTag);
     861        else if (pTest->eXmlState == RTTESTINT::kXmlPos_ElementEnd)
     862            rtTestXmlOutput(pTest, "%*s</%s>\n", i * 2, "", pszTag);
     863        else
     864            rtTestXmlOutput(pTest, "</%s>\n", pszTag);
     865        pTest->eXmlState = RTTESTINT::kXmlPos_ElementEnd;
     866    }
     867}
     868
     869
     870/**
     871 * Ends the XML stream, closing all open elements.
     872 *
     873 * The caller must own the instance lock.
     874 *
     875 * @param   pTest               The test instance.
     876 */
     877static void rtTestXmlEnd(PRTTESTINT pTest)
     878{
     879    if (pTest->fXmlEnabled)
     880    {
     881        /*
     882         * Close all the elements and add the final TestEnd one to get a
     883         * final timestamp and some certainty that the XML is valid.
     884         */
     885        size_t i = pTest->cXmlElements;
     886        AssertReturnVoid(i > 0);
     887        while (i-- > 1)
     888        {
     889            const char *pszTag = pTest->apszXmlElements[pTest->cXmlElements];
     890            if (pTest->eXmlState == RTTESTINT::kXmlPos_ValueStart)
     891                rtTestXmlOutput(pTest, "\n%*s</%s>\n", i * 2, "", pszTag);
     892            else if (pTest->eXmlState == RTTESTINT::kXmlPos_ElementEnd)
     893                rtTestXmlOutput(pTest, "%*s</%s>\n", i * 2, "", pszTag);
     894            else
     895                rtTestXmlOutput(pTest, "</%s>\n", pszTag);
     896            pTest->eXmlState = RTTESTINT::kXmlPos_ElementEnd;
     897        }
     898        rtTestXmlElem(pTest, "End", "SubTests=\"%u\" SubTestsFailed=\"%u\" errors=\"%u\"",
     899                      pTest->cSubTests, pTest->cSubTestsFailed, pTest->cErrors);
     900        rtTestXmlOutput(pTest, "</Test>\n");
     901
     902        /*
     903         * Close the XML outputs.
     904         */
     905        if (pTest->hXmlPipe != NIL_RTPIPE)
     906        {
     907            RTPipeClose(pTest->hXmlPipe);
     908            pTest->hXmlPipe = NIL_RTPIPE;
     909        }
     910        if (pTest->hXmlFile != NIL_RTFILE)
     911        {
     912            RTFileClose(pTest->hXmlFile);
     913            pTest->hXmlFile = NIL_RTFILE;
     914        }
     915        pTest->fXmlEnabled = false;
     916        pTest->eXmlState = RTTESTINT::kXmlPos_ElementEnd;
     917    }
     918    pTest->cXmlElements = 0;
     919}
     920
     921/**
    552922 * Output callback.
    553923 *
     
    7641134        uint32_t cErrors = ASMAtomicUoReadU32(&pTest->cErrors) - pTest->cSubTestAtErrors;
    7651135        if (!cErrors)
     1136        {
     1137            rtTestXmlElem(pTest, "Passed", NULL);
     1138            rtTestXmlElemEnd(pTest, "SubTest");
    7661139            cch += RTTestPrintfNl(pTest, RTTESTLVL_SUB_TEST, "%-50s: PASSED\n", pTest->pszSubTest);
     1140        }
    7671141        else
    7681142        {
    7691143            pTest->cSubTestsFailed++;
     1144            rtTestXmlElem(pTest, "Failed", "errors=\"%u\"", cErrors);
     1145            rtTestXmlElemEnd(pTest, "SubTest");
    7701146            cch += RTTestPrintfNl(pTest, RTTESTLVL_SUB_TEST, "%-50s: FAILED (%u errors)\n",
    7711147                                  pTest->pszSubTest, cErrors);
     
    9021278        cch = RTTestPrintfNl(hTest, RTTESTLVL_DEBUG, "debug: Starting sub-test '%s'\n", pszSubTest);
    9031279
     1280    rtTestXmlElemStart(pTest, "SubTest", "name=%RMas", pszSubTest);
     1281
    9041282    RTCritSectLeave(&pTest->Lock);
    9051283
     
    10321410
    10331411/**
     1412 * Gets the unit name.
     1413 *
     1414 * @returns Unit name.
     1415 * @param   enmUnit             The unit.
     1416 */
     1417static const char *rtTestUnitName(RTTESTUNIT enmUnit)
     1418{
     1419    switch (enmUnit)
     1420    {
     1421        case RTTESTUNIT_PCT:                    return "%";
     1422        case RTTESTUNIT_BYTES:                  return "bytes";
     1423        case RTTESTUNIT_BYTES_PER_SEC:          return "bytes/s";
     1424        case RTTESTUNIT_KILOBYTES:              return "KB";
     1425        case RTTESTUNIT_KILOBYTES_PER_SEC:      return "KB/s";
     1426        case RTTESTUNIT_MEGABYTES:              return "MB";
     1427        case RTTESTUNIT_MEGABYTES_PER_SEC:      return "MB/s";
     1428        case RTTESTUNIT_PACKETS:                return "packets";
     1429        case RTTESTUNIT_PACKETS_PER_SEC:        return "packets/s";
     1430        case RTTESTUNIT_FRAMES:                 return "frames";
     1431        case RTTESTUNIT_FRAMES_PER_SEC:         return "frames/";
     1432        case RTTESTUNIT_OCCURRENCES:            return "occurences";
     1433        case RTTESTUNIT_OCCURRENCES_PER_SEC:    return "occurences/s";
     1434        case RTTESTUNIT_ROUND_TRIP:             return "roundtrips";
     1435        case RTTESTUNIT_CALLS:                  return "calls";
     1436        case RTTESTUNIT_CALLS_PER_SEC:          return "calls/s";
     1437        case RTTESTUNIT_SECS:                   return "s";
     1438        case RTTESTUNIT_MS:                     return "ms";
     1439        case RTTESTUNIT_NS:                     return "ns";
     1440        case RTTESTUNIT_NS_PER_CALL:            return "ns/call";
     1441        case RTTESTUNIT_NS_PER_FRAME:           return "ns/frame";
     1442        case RTTESTUNIT_NS_PER_OCCURRENCE:      return "ns/occurences";
     1443        case RTTESTUNIT_NS_PER_PACKET:          return "ns/packet";
     1444        case RTTESTUNIT_NS_PER_ROUND_TRIP:      return "ns/roundtrips";
     1445
     1446        /* No default so gcc helps us keep this up to date. */
     1447        case RTTESTUNIT_INVALID:
     1448        case RTTESTUNIT_END:
     1449            break;
     1450    }
     1451    AssertMsgFailed(("%d\n", enmUnit));
     1452    return "unknown";
     1453}
     1454
     1455
     1456RTR3DECL(int) RTTestValue(RTTEST hTest, const char *pszName, uint64_t u64Value, RTTESTUNIT enmUnit)
     1457{
     1458    PRTTESTINT pTest = hTest;
     1459    RTTEST_GET_VALID_RETURN(pTest);
     1460
     1461    const char *pszUnit = rtTestUnitName(enmUnit);
     1462
     1463    RTCritSectEnter(&pTest->Lock);
     1464    rtTestXmlElemStart(pTest, "Value", "name=%RMas unit=%RMas", pszName, pszUnit);
     1465    rtTestXmlElemValue(pTest, "%llu", u64Value);
     1466    rtTestXmlElemEnd(pTest, "Value");
     1467    RTCritSectLeave(&pTest->Lock);
     1468
     1469    RTCritSectEnter(&pTest->OutputLock);
     1470    rtTestPrintf(pTest, "  %-48s: %'12llu %s\n", pszName, u64Value, pszUnit);
     1471    RTCritSectLeave(&pTest->OutputLock);
     1472
     1473    return VINF_SUCCESS;
     1474}
     1475
     1476
     1477RTR3DECL(int) RTTestValueF(RTTEST hTest, uint64_t u64Value, RTTESTUNIT enmUnit, const char *pszNameFmt, ...)
     1478{
     1479    va_list va;
     1480    va_start(va, pszNameFmt);
     1481    int rc = RTTestValueV(hTest, u64Value, enmUnit, pszNameFmt, va);
     1482    va_end(va);
     1483    return rc;
     1484}
     1485
     1486
     1487RTR3DECL(int) RTTestValueV(RTTEST hTest, uint64_t u64Value, RTTESTUNIT enmUnit, const char *pszNameFmt, va_list va)
     1488{
     1489    char *pszName;
     1490    RTStrAPrintfV(&pszName, pszNameFmt, va);
     1491    if (!pszName)
     1492        return VERR_NO_MEMORY;
     1493    int rc = RTTestValue(hTest, pszName, u64Value, enmUnit);
     1494    RTStrFree(pszName);
     1495    return rc;
     1496}
     1497
     1498
     1499/**
    10341500 * Increments the error counter.
    10351501 *
  • trunk/src/VBox/Runtime/r3/testi.cpp

    r25517 r27649  
    9797
    9898
     99RTR3DECL(int) RTTestIValue(const char *pszName, uint64_t u64Value, RTTESTUNIT enmUnit)
     100{
     101    return RTTestValue(NIL_RTTEST, pszName, u64Value, enmUnit);
     102}
     103
     104
     105RTR3DECL(int) RTTestIValueF(uint64_t u64Value, RTTESTUNIT enmUnit, const char *pszNameFmt, ...)
     106{
     107    va_list va;
     108    va_start(va, pszNameFmt);
     109    int rc = RTTestValueV(NIL_RTTEST, u64Value, enmUnit, pszNameFmt, va);
     110    va_end(va);
     111    return rc;
     112}
     113
     114
     115RTR3DECL(int) RTTestIValueV(uint64_t u64Value, RTTESTUNIT enmUnit, const char *pszNameFmt, va_list va)
     116{
     117    return RTTestValueV(NIL_RTTEST, u64Value, enmUnit, pszNameFmt, va);
     118}
     119
     120
    99121RTR3DECL(int) RTTestIErrorInc(void)
    100122{
     
    125147
    126148
     149RTR3DECL(int) RTTestIFailedRcV(int rcRet, const char *pszFormat, va_list va)
     150{
     151    RTTestFailedV(NIL_RTTEST, pszFormat, va);
     152    return rcRet;
     153}
     154
     155
     156RTR3DECL(int) RTTestIFailedRc(int rcRet, const char *pszFormat, ...)
     157{
     158    va_list va;
     159    va_start(va, pszFormat);
     160    RTTestFailedV(NIL_RTTEST, pszFormat, va);
     161    va_end(va);
     162    return rcRet;
     163}
     164
     165
    127166RTR3DECL(int) RTTestIFailureDetailsV(const char *pszFormat, va_list va)
    128167{
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette