VirtualBox

Changeset 103262 in vbox for trunk/src/VBox/Runtime/r3


Ignore:
Timestamp:
Feb 8, 2024 12:00:32 AM (15 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
161553
Message:

IPRT,VMMDev,Bs3Kit: Added support for sub-sub-tests to better deal with bs3-cpu-generated-1 and others with too many sub-tests for the test manager.

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

Legend:

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

    r103005 r103262  
    122122    PRTTESTGUARDEDMEM   pGuardedMem;
    123123
    124     /** The current sub-test. */
    125     const char         *pszSubTest;
    126     /** The length of the sub-test name. */
    127     size_t              cchSubTest;
    128     /** Whether the current subtest should figure as 'SKIPPED'. */
    129     bool                fSubTestSkipped;
    130     /** Whether we've reported the sub-test result or not. */
    131     bool                fSubTestReported;
    132     /** The start error count of the current subtest. */
    133     uint32_t            cSubTestAtErrors;
    134 
    135     /** The number of sub tests. */
    136     uint32_t            cSubTests;
    137     /** The number of sub tests that failed. */
    138     uint32_t            cSubTestsFailed;
     124    struct RTTESTINTSUBTRACKER
     125    {
     126        /** The current (sub-)sub-test. */
     127        const char         *pszName;
     128        /** The length of the (sub-)sub-test name. */
     129        size_t              cchName;
     130        /** Whether the current (sub-)sub-test should figure as 'SKIPPED'. */
     131        bool                fSkipped;
     132        /** Whether we've reported the (sub-)sub-test result or not. */
     133        bool                fReported;
     134        /** The start error count of the current (sub-)sub-test. */
     135        uint32_t            cErrorsAtStart;
     136        /** The number of (sub-)sub-tests. */
     137        uint32_t            cTests;
     138        /** The number of (sub-)sub-tests that failed. */
     139        uint32_t            cFailedTests;
     140    }
     141    /** sub-test tracker. */
     142                        Sub,
     143    /** sub-sub-test tracker. */
     144                        SubSub;
    139145
    140146    /** Error context message. */
     
    243249
    244250
     251/** RTTestCreateEx helpers.   */
     252DECL_FORCE_INLINE(void) rtTestInitSubTracking(struct RTTESTINT::RTTESTINTSUBTRACKER *pTracker)
     253{
     254    pTracker->pszName        = NULL;
     255    pTracker->cchName        = 0;
     256    pTracker->fSkipped       = false;
     257    pTracker->fReported      = true;
     258    pTracker->cErrorsAtStart = 0;
     259    pTracker->cTests         = 0;
     260    pTracker->cFailedTests   = 0;
     261}
     262
     263
    245264RTR3DECL(int) RTTestCreateEx(const char *pszTest, uint32_t fFlags, RTTESTLVL enmMaxLevel,
    246265                             RTHCINTPTR iNativeTestPipe, const char *pszXmlFile, PRTTEST phTest)
     
    277296    pTest->pGuardedMem      = NULL;
    278297
    279     pTest->pszSubTest       = NULL;
    280     pTest->cchSubTest       = 0;
    281     pTest->fSubTestSkipped  = false;
    282     pTest->fSubTestReported = true;
    283     pTest->cSubTestAtErrors = 0;
    284     pTest->cSubTests        = 0;
    285     pTest->cSubTestsFailed  = 0;
     298    rtTestInitSubTracking(&pTest->Sub);
     299    rtTestInitSubTracking(&pTest->SubSub);
    286300
    287301    pTest->fXmlEnabled      = false;
     
    525539    }
    526540
    527     RTStrFree((char *)pTest->pszSubTest);
    528     pTest->pszSubTest = NULL;
     541    RTStrFree((char *)pTest->SubSub.pszName);
     542    pTest->SubSub.pszName = NULL;
     543    RTStrFree((char *)pTest->Sub.pszName);
     544    pTest->Sub.pszName = NULL;
    529545    RTStrFree((char *)pTest->pszTest);
    530546    pTest->pszTest = NULL;
     
    944960        {
    945961            rtTestXmlElem(pTest, "End", "SubTests=\"%u\" SubTestsFailed=\"%u\" errors=\"%u\"",
    946                           pTest->cSubTests, pTest->cSubTestsFailed, pTest->cErrors);
     962                          pTest->Sub.cTests, pTest->Sub.cFailedTests, pTest->cErrors);
    947963            rtTestXmlOutput(pTest, "</Test>\n");
    948964        }
     
    11201136
    11211137/**
    1122  * Prints the result of a sub-test if necessary.
     1138 * Prints the result of a sub-test or sub-sub-test if necessary.
    11231139 *
    11241140 * @returns Number of chars printed.
    11251141 * @param   pTest       The test instance.
     1142 * @param   pTracker    The sub-test or sub-sub-test tracker.
     1143 * @param   cchIndent   Result indent.
    11261144 * @remarks Caller own the test Lock.
    11271145 */
    1128 static int rtTestSubTestReport(PRTTESTINT pTest)
     1146static int rtTestSubTestReportWorker(PRTTESTINT pTest, struct RTTESTINT::RTTESTINTSUBTRACKER *pTracker, unsigned cchIndent)
    11291147{
    11301148    int cch = 0;
    1131     if (    !pTest->fSubTestReported
    1132         &&  pTest->pszSubTest)
    1133     {
    1134         pTest->fSubTestReported = true;
    1135         uint32_t cErrors = ASMAtomicUoReadU32(&pTest->cErrors) - pTest->cSubTestAtErrors;
     1149    if (   !pTracker->fReported
     1150        && pTracker->pszName)
     1151    {
     1152        unsigned const cchNameWidth = 60 - cchIndent;
     1153        pTracker->fReported = true;
     1154        uint32_t const cErrors = ASMAtomicUoReadU32(&pTest->cErrors) - pTracker->cErrorsAtStart;
    11361155        if (!cErrors)
    11371156        {
    1138             if (!pTest->fSubTestSkipped)
     1157            if (!pTracker->fSkipped)
    11391158            {
    11401159                rtTestXmlElem(pTest, "Passed", NULL);
    11411160                rtTestXmlElemEnd(pTest, "Test");
    1142                 cch += RTTestPrintfNl(pTest, RTTESTLVL_SUB_TEST, "%-60s: PASSED\n", pTest->pszSubTest);
     1161                cch += RTTestPrintfNl(pTest, RTTESTLVL_SUB_TEST, "%*s%-*s: PASSED\n",
     1162                                      cchIndent, "", cchNameWidth, pTracker->pszName);
    11431163            }
    11441164            else
     
    11461166                rtTestXmlElem(pTest, "Skipped", NULL);
    11471167                rtTestXmlElemEnd(pTest, "Test");
    1148                 cch += RTTestPrintfNl(pTest, RTTESTLVL_SUB_TEST, "%-60s: SKIPPED\n", pTest->pszSubTest);
     1168                cch += RTTestPrintfNl(pTest, RTTESTLVL_SUB_TEST, "%*s%-60s: SKIPPED\n",
     1169                                      cchIndent, "", cchNameWidth, pTracker->pszName);
    11491170            }
    11501171        }
    11511172        else
    11521173        {
    1153             pTest->cSubTestsFailed++;
     1174            pTracker->cFailedTests++;
    11541175            rtTestXmlElem(pTest, "Failed", "errors=\"%u\"", cErrors);
    11551176            rtTestXmlElemEnd(pTest, "Test");
    1156             cch += RTTestPrintfNl(pTest, RTTESTLVL_SUB_TEST, "%-60s: FAILED (%u errors)\n",
    1157                                   pTest->pszSubTest, cErrors);
     1177            cch += RTTestPrintfNl(pTest, RTTESTLVL_SUB_TEST, "%*s%-60s: FAILED (%u errors)\n",
     1178                                  cchIndent, "", cchNameWidth, pTracker->pszName, cErrors);
    11581179        }
    11591180    }
     
    11621183
    11631184
    1164 /**
    1165  * RTTestSub and RTTestSubDone worker that cleans up the current (if any)
    1166  * sub test.
     1185/** Worker for rtTestSubSubCleanup and rtTestSubCleanup.  */
     1186static int rtTestSubCleanupWorker(PRTTESTINT pTest, struct RTTESTINT::RTTESTINTSUBTRACKER *pTracker, unsigned cchIndent)
     1187{
     1188    int cch = rtTestSubTestReportWorker(pTest, pTracker, cchIndent);
     1189    RTStrFree((char *)pTracker->pszName);
     1190    pTracker->pszName   = NULL;
     1191    pTracker->fReported = true;
     1192    return cch;
     1193}
     1194
     1195
     1196/**
     1197 * RTTestSubSub and RTTestSubSubDone worker that cleans up the current (if any)
     1198 * sub-sub-test.
    11671199 *
    11681200 * @returns Number of chars printed.
     
    11701202 * @remarks Caller own the test Lock.
    11711203 */
     1204static int rtTestSubSubCleanup(PRTTESTINT pTest)
     1205{
     1206    return rtTestSubCleanupWorker(pTest, &pTest->SubSub, 2);
     1207}
     1208
     1209
     1210/**
     1211 * RTTestSub and RTTestSubDone worker that cleans up the current (if any)
     1212 * sub test.
     1213 *
     1214 * @returns Number of chars printed.
     1215 * @param   pTest       The test instance.
     1216 * @remarks Caller own the test Lock.
     1217 */
    11721218static int rtTestSubCleanup(PRTTESTINT pTest)
    11731219{
    1174     int cch = 0;
    1175     if (pTest->pszSubTest)
    1176     {
    1177         cch += rtTestSubTestReport(pTest);
    1178 
    1179         RTStrFree((char *)pTest->pszSubTest);
    1180         pTest->pszSubTest = NULL;
    1181         pTest->fSubTestReported = true;
    1182     }
     1220    int cch = rtTestSubCleanupWorker(pTest, &pTest->SubSub, 2);
     1221    cch    += rtTestSubCleanupWorker(pTest, &pTest->Sub, 0);
     1222
    11831223    RTStrFree(pTest->pszErrCtx);
    11841224    pTest->pszErrCtx = NULL;
     
    11931233
    11941234    RTCritSectEnter(&pTest->Lock);
    1195     rtTestSubTestReport(pTest);
     1235    rtTestSubTestReportWorker(pTest, &pTest->SubSub, 2);
     1236    rtTestSubTestReportWorker(pTest, &pTest->Sub, 0);
    11961237    RTCritSectLeave(&pTest->Lock);
    11971238
     
    12191260
    12201261    RTCritSectEnter(&pTest->Lock);
    1221     rtTestSubTestReport(pTest);
     1262    rtTestSubTestReportWorker(pTest, &pTest->SubSub, 2);
     1263    rtTestSubTestReportWorker(pTest, &pTest->Sub, 0);
    12221264    RTCritSectLeave(&pTest->Lock);
    12231265
     
    12511293
    12521294
     1295/** Worker for RTTestSub and RTTestSubSub. */
     1296static void rtTestSubNew(PRTTESTINT pTest, struct RTTESTINT::RTTESTINTSUBTRACKER *pTracker, const char *pszName)
     1297{
     1298    pTracker->cTests++;
     1299    pTracker->cErrorsAtStart = ASMAtomicUoReadU32(&pTest->cErrors);
     1300    pTracker->pszName        = RTStrDup(pszName);
     1301    pTracker->cchName        = strlen(pszName);
     1302    AssertMsg(pTracker->cchName < 64 /* See g_kcchMaxTestResultName in testmanager/config.py. */,
     1303              ("cchSubTest=%u: '%s'\n", pTracker->cchName, pTracker->pszName));
     1304    pTracker->fSkipped       = false;
     1305    pTracker->fReported      = false;
     1306}
     1307
     1308
    12531309RTR3DECL(int) RTTestSub(RTTEST hTest, const char *pszSubTest)
    12541310{
     
    12611317    rtTestSubCleanup(pTest);
    12621318
     1319    pTest->SubSub.cTests       = 0;
     1320    pTest->SubSub.cFailedTests = 0;
     1321
    12631322    /* Start new sub test. */
    1264     pTest->cSubTests++;
    1265     pTest->cSubTestAtErrors = ASMAtomicUoReadU32(&pTest->cErrors);
    1266     pTest->pszSubTest = RTStrDup(pszSubTest);
    1267     pTest->cchSubTest = strlen(pszSubTest);
    1268     AssertMsg(pTest->cchSubTest < 64 /* See g_kcchMaxTestResultName in testmanager/config.py. */,
    1269               ("cchSubTest=%u: '%s'\n", pTest->cchSubTest, pTest->pszSubTest));
    1270     pTest->fSubTestSkipped  = false;
    1271     pTest->fSubTestReported = false;
     1323    rtTestSubNew(pTest, &pTest->Sub, pszSubTest);
    12721324
    12731325    int cch = 0;
     
    13261378
    13271379
     1380RTR3DECL(int) RTTestSubSub(RTTEST hTest, const char *pszSubSubTest)
     1381{
     1382    PRTTESTINT pTest = hTest;
     1383    RTTEST_GET_VALID_RETURN_RC(pTest, -1);
     1384    AssertReturn(pTest->Sub.pszName, -1);
     1385    AssertReturn(!pTest->Sub.fReported, -1);
     1386    AssertReturn(!pTest->Sub.fSkipped, -1);
     1387
     1388    RTCritSectEnter(&pTest->Lock);
     1389
     1390    /* Cleanup, reporting if necessary previous sub-sub-test. */
     1391    rtTestSubSubCleanup(pTest);
     1392
     1393    /* Start new sub-sub-test. */
     1394    rtTestSubNew(pTest, &pTest->SubSub, pszSubSubTest);
     1395
     1396    int cch = 0;
     1397    if (pTest->enmMaxLevel >= RTTESTLVL_DEBUG)
     1398        cch = RTTestPrintfNl(hTest, RTTESTLVL_DEBUG, "debug: Starting sub-sub-test '%s'\n", pszSubSubTest);
     1399
     1400    Assert(pTest->fXmlTopTestDone);
     1401    rtTestXmlElemStart(pTest, "Test", "name=%RMas", pszSubSubTest);
     1402
     1403    RTCritSectLeave(&pTest->Lock);
     1404
     1405    return cch;
     1406}
     1407
     1408
     1409RTR3DECL(int) RTTestSubSubF(RTTEST hTest, const char *pszSubSubTestFmt, ...)
     1410{
     1411    va_list va;
     1412    va_start(va, pszSubSubTestFmt);
     1413    int cch = RTTestSubSubV(hTest, pszSubSubTestFmt, va);
     1414    va_end(va);
     1415    return cch;
     1416}
     1417
     1418
     1419RTR3DECL(int) RTTestSubSubV(RTTEST hTest, const char *pszSubSubTestFmt, va_list va)
     1420{
     1421    char *pszSubSubTest;
     1422    RTStrAPrintfV(&pszSubSubTest, pszSubSubTestFmt, va);
     1423    if (pszSubSubTest)
     1424    {
     1425        int cch = RTTestSubSub(hTest, pszSubSubTest);
     1426        RTStrFree(pszSubSubTest);
     1427        return cch;
     1428    }
     1429    return 0;
     1430}
     1431
     1432
     1433RTR3DECL(int) RTTestSubSubDone(RTTEST hTest)
     1434{
     1435    PRTTESTINT pTest = hTest;
     1436    RTTEST_GET_VALID_RETURN_RC(pTest, VERR_INVALID_HANDLE);
     1437
     1438    RTCritSectEnter(&pTest->Lock);
     1439    int cch = rtTestSubSubCleanup(pTest);
     1440    RTCritSectLeave(&pTest->Lock);
     1441
     1442    return cch;
     1443}
     1444
    13281445RTR3DECL(int) RTTestPassedV(RTTEST hTest, const char *pszFormat, va_list va)
    13291446{
     
    13671484    RTTEST_GET_VALID_RETURN_RC(pTest, VERR_INVALID_HANDLE);
    13681485
    1369     pTest->fSubTestSkipped = true;
     1486    if (pTest->SubSub.pszName)
     1487        pTest->SubSub.fSkipped = true;
     1488    else
     1489        pTest->Sub.fSkipped = true;
    13701490
    13711491    int cch = 0;
     
    15331653    RTTEST_GET_VALID_RETURN_RC(pTest, UINT32_MAX);
    15341654
    1535     return ASMAtomicReadU32(&pTest->cErrors) - pTest->cSubTestAtErrors;
     1655    return ASMAtomicReadU32(&pTest->cErrors) - pTest->Sub.cErrorsAtStart;
     1656}
     1657
     1658
     1659RTR3DECL(uint32_t) RTTestSubSubErrorCount(RTTEST hTest)
     1660{
     1661    PRTTESTINT pTest = hTest;
     1662    RTTEST_GET_VALID_RETURN_RC(pTest, UINT32_MAX);
     1663
     1664    return ASMAtomicReadU32(&pTest->cErrors) - pTest->SubSub.cErrorsAtStart;
    15361665}
    15371666
  • trunk/src/VBox/Runtime/r3/testi.cpp

    r98103 r103262  
    8787
    8888
     89RTR3DECL(int) RTTestISubSub(const char *pszSubSubTest)
     90{
     91    return RTTestSubSub(NIL_RTTEST, pszSubSubTest);
     92}
     93
     94
     95RTR3DECL(int) RTTestISubSubF(const char *pszSubSubTestFmt, ...)
     96{
     97    va_list va;
     98    va_start(va, pszSubSubTestFmt);
     99    int cch = RTTestSubSubV(NIL_RTTEST, pszSubSubTestFmt, va);
     100    va_end(va);
     101    return cch;
     102}
     103
     104
     105RTR3DECL(int) RTTestISubSubV(const char *pszSubSubTestFmt, va_list va)
     106{
     107    return RTTestSubSubV(NIL_RTTEST, pszSubSubTestFmt, va);
     108}
     109
     110
     111RTR3DECL(int) RTTestISubSubDone(void)
     112{
     113    return RTTestSubSubDone(NIL_RTTEST);
     114}
     115
     116
    89117RTR3DECL(int) RTTestIPassedV(const char *pszFormat, va_list va)
    90118{
Note: See TracChangeset for help on using the changeset viewer.

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