VirtualBox

Changeset 89541 in vbox for trunk/src/VBox/ValidationKit


Ignore:
Timestamp:
Jun 7, 2021 9:26:07 AM (4 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
144899
Message:

Audio/ValKit: More code for completely self-contained (self) testing. bugref:10008

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/ValidationKit/utils/audio/vkat.cpp

    r89525 r89541  
    182182    /** Audio testing mode. */
    183183    AUDIOTESTMODE           enmMode;
     184    /** Whether self test mode is active or not. */
     185    bool                    fSelftest;
    184186    /** Output path for storing the test environment's final test files. */
    185187    char                    szTag[AUDIOTEST_TAG_MAX];
     
    211213        struct
    212214        {
    213             ATSCLIENT       Client;
     215            /** Client connected to the ATS on the guest side. */
     216            ATSCLIENT       AtsClGuest;
     217            /** Client connected to the ATS on the Validation Kit. */
     218            ATSCLIENT       AtsClValKit;
    214219        } Host;
    215220    } u;
     
    303308enum
    304309{
    305     VKAT_SELFTEST_OPT_ATS_HOST = 900
     310    VKAT_SELFTEST_OPT_ATS_GUEST_ADDR = 900,
     311    VKAT_SELFTEST_OPT_ATS_GUEST_PORT,
     312    VKAT_SELFTEST_OPT_ATS_VALKIT_ADDR,
     313    VKAT_SELFTEST_OPT_ATS_VALKIT_PORT
    306314};
    307315
     
    493501                RTThreadSleep(pTstEnv->cMsSchedulingHint);
    494502
    495                 RTTestPrintf(g_hTest, RTTESTLVL_DEBUG,  "Written %RU32 bytes\n", cbWritten);
    496 
    497503                Assert(cbToWrite >= cbWritten);
    498504                cbToWrite -= cbWritten;
     
    564570                RTThreadSleep(pTstEnv->cMsSchedulingHint);
    565571
    566                 RTTestPrintf(g_hTest, RTTESTLVL_DEBUG,  "Read %RU32 bytes\n", cbRead);
    567 
    568572                Assert(cbToRead >= cbRead);
    569573                cbToRead -= cbRead;
     
    595599    PAUDIOTESTENV   pTstEnv = pCtx->pTstEnv;
    596600
    597     RTTestPrintf(g_hTest, RTTESTLVL_DEBUG, "Beginning test set '%s'\n", pszTag);
    598 
    599     return AudioTestSetCreate(&pTstEnv->Set, pTstEnv->szPathTemp, pszTag);
     601    char szTag[AUDIOTEST_TAG_MAX];
     602    int rc = RTStrPrintf2(szTag, sizeof(szTag), "%s-guest", pszTag);
     603    AssertRCReturn(rc, rc);
     604
     605    RTTestPrintf(g_hTest, RTTESTLVL_DEBUG, "Beginning test set '%s'\n", szTag);
     606
     607    return AudioTestSetCreate(&pTstEnv->Set, pTstEnv->szPathTemp, szTag);
    600608}
    601609
     
    708716 * @param   pDrvReg             Audio driver to use.
    709717 * @param   fWithDrvAudio       Whether to include DrvAudio in the stack or not.
    710  * @param   pszTag              Tag name to use. If NULL, a generated UUID will be used.
    711718 * @param   pszTcpAddr          TCP/IP address to connect to.
     719 *                              If NULL, localhost (127.0.0.1) will be used.
    712720 * @param   uTcpPort            TCP/IP port to connect to.
     721 *                              If 0, ATS_DEFAULT_PORT will be used.
    713722 */
    714723static int audioTestEnvInit(PAUDIOTESTENV pTstEnv,
    715                             PCPDMDRVREG pDrvReg, bool fWithDrvAudio, const char *pszTag,
     724                            PCPDMDRVREG pDrvReg, bool fWithDrvAudio,
    716725                            const char *pszTcpAddr, uint32_t uTcpPort)
    717726{
    718727    RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Test mode is '%s'\n", pTstEnv->enmMode == AUDIOTESTMODE_HOST ? "host" : "guest");
    719     RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Using tag '%s'\n", pszTag);
     728    RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Using tag '%s'\n", pTstEnv->szTag);
    720729    RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Output directory is '%s'\n", pTstEnv->szPathOut);
    721730    RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Temp directory is '%s'\n", pTstEnv->szPathTemp);
     
    730739
    731740    /* Only the guest mode needs initializing the driver stack. */
    732     const bool fUseDriverStack = pTstEnv->enmMode == AUDIOTESTMODE_GUEST;
     741    const bool fUseDriverStack =    pTstEnv->enmMode == AUDIOTESTMODE_GUEST
     742                                 /* The self test mode drives the ValKit audio driver locally,
     743                                  * so also use the driver stack here. */
     744                                 || pTstEnv->fSelftest;
    733745    if (fUseDriverStack)
    734746    {
     
    772784        Callbacks.pvUser          = &Ctx;
    773785
    774         RTTestPrintf(g_hTest, RTTESTLVL_DEBUG, "Starting ATS ...\n");
    775         rc = AudioTestSvcInit(&pTstEnv->u.Guest.Srv, &Callbacks);
     786        RTTestPrintf(g_hTest, RTTESTLVL_DEBUG, "Starting guest ATS at %s:%RU32...\n", pszTcpAddr, uTcpPort);
     787        rc = AudioTestSvcInit(&pTstEnv->u.Guest.Srv, pszTcpAddr, uTcpPort, &Callbacks);
    776788        if (RT_SUCCESS(rc))
    777789            rc = AudioTestSvcStart(&pTstEnv->u.Guest.Srv);
     
    785797    else /* Host mode */
    786798    {
    787         RTTestPrintf(g_hTest, RTTESTLVL_DEBUG, "Connecting to ATS at %s:%RU32 ...\n", pszTcpAddr, uTcpPort);
    788 
    789         rc = AudioTestSvcClientConnect(&pTstEnv->u.Host.Client, pszTcpAddr, uTcpPort);
     799        RTTestPrintf(g_hTest, RTTESTLVL_DEBUG, "Connecting to guest ATS at %s:%RU32 ...\n",
     800                     (pszTcpAddr && *pszTcpAddr) ? pszTcpAddr : "127.0.0.1", uTcpPort ? uTcpPort : ATS_TCP_DEFAULT_PORT);
     801
     802        rc = AudioTestSvcClientConnect(&pTstEnv->u.Host.AtsClGuest, pszTcpAddr, uTcpPort);
    790803        if (RT_FAILURE(rc))
    791804        {
     
    850863    AudioTestSetDestroy(&pTstEnv->Set);
    851864
     865    if (RT_FAILURE(rc))
     866        RTTestFailed(g_hTest, "Test set prologue failed with %Rrc\n", rc);
     867
    852868    return rc;
    853869}
     
    892908static int audioTestDevicesEnumerateAndCheck(PAUDIOTESTENV pTstEnv, const char *pszDev, PPDMAUDIOHOSTDEV *ppDev)
    893909{
     910#ifdef DEBUG_andy
     911    return VINF_SUCCESS;
     912#endif
     913
    894914    RTTestSubF(g_hTest, "Enumerating audio devices and checking for device '%s'", pszDev ? pszDev : "<Default>");
    895915
     
    11071127            Cfg.Props = pTstParms->Props;
    11081128
    1109             rc = AudioTestSvcClientTonePlay(&pTstEnv->u.Host.Client, &pTstParms->TestTone);
     1129            rc = AudioTestSvcClientTonePlay(&pTstEnv->u.Host.AtsClGuest, &pTstParms->TestTone);
    11101130            if (RT_SUCCESS(rc))
    11111131            {
     
    11381158static DECLCALLBACK(int) audioTestRecordToneSetup(PAUDIOTESTENV pTstEnv, PAUDIOTESTDESC pTstDesc, PAUDIOTESTPARMS pTstParmsAcq, void **ppvCtx)
    11391159{
    1140     RT_NOREF(pTstEnv, pTstDesc, ppvCtx);
     1160    RT_NOREF(pTstDesc, ppvCtx);
    11411161
    11421162    pTstParmsAcq->enmType     = AUDIOTESTTYPE_TESTTONE_RECORD;
     
    11521172    pTstParmsAcq->idxCurrent  = 0;
    11531173
    1154     return VINF_SUCCESS;
     1174    /* Connect to the Validation Kit audio driver ATS. */
     1175    int rc = AudioTestSvcClientConnect(&pTstEnv->u.Host.AtsClValKit,
     1176                                       "127.0.0.1" /** @todo Make this dynamic. */, ATS_TCP_DEFAULT_PORT);
     1177    if (RT_SUCCESS(rc))
     1178    {
     1179        char szTag[AUDIOTEST_TAG_MAX];
     1180        rc = RTStrPrintf2(szTag, sizeof(szTag), "%s-valkit", pTstEnv->szTag);
     1181        if (RT_SUCCESS(rc))
     1182            rc = AudioTestSvcClientTestSetBegin(&pTstEnv->u.Host.AtsClValKit, szTag);
     1183    }
     1184
     1185    return rc;
    11551186}
    11561187
     
    11671198    {
    11681199        pTstParms->TestTone.Props      = pTstParms->Props;
    1169         pTstParms->TestTone.msDuration = RTRandU32Ex(50 /* ms */, RT_MS_10SEC); /** @todo Record even longer? */
    1170 
     1200#ifdef DEBUG_andy
     1201        pTstParms->TestTone.msDuration = RTRandU32Ex(50 /* ms */, 2000);
     1202#else
     1203        pTstParms->TestTone.msDuration = RTRandU32Ex(50 /* ms */, RT_MS_30SEC); /** @todo Record even longer? */
     1204#endif
    11711205        PAUDIOTESTENTRY pTst;
    11721206        rc = AudioTestSetTestBegin(&pTstEnv->Set, "Recording test tone", pTstParms, &pTst);
    11731207        if (RT_SUCCESS(rc))
    11741208        {
    1175             rc = AudioTestSvcClientToneRecord(&pTstEnv->u.Host.Client, &pTstParms->TestTone);
     1209            /*
     1210             * 1. Arm the ValKit ATS with the recording parameters.
     1211             */
     1212            rc = AudioTestSvcClientTonePlay(&pTstEnv->u.Host.AtsClValKit, &pTstParms->TestTone);
    11761213            if (RT_SUCCESS(rc))
    11771214            {
    1178                 AudioTestSetTestDone(pTst);
     1215                /*
     1216                 * 2. Tell the guest ATS to start recording.
     1217                 */
     1218                rc = AudioTestSvcClientToneRecord(&pTstEnv->u.Host.AtsClGuest, &pTstParms->TestTone);
     1219                if (RT_SUCCESS(rc))
     1220                {
     1221                    AudioTestSetTestDone(pTst);
     1222                }
     1223                else
     1224                    AudioTestSetTestFailed(pTst, rc, "Recording test tone failed");
    11791225            }
    1180             else
    1181                 AudioTestSetTestFailed(pTst, rc, "Recording test tone failed");
    11821226        }
    11831227
     
    11941238static DECLCALLBACK(int) audioTestRecordToneDestroy(PAUDIOTESTENV pTstEnv, void *pvCtx)
    11951239{
    1196     RT_NOREF(pTstEnv, pvCtx);
    1197 
    1198     return VINF_SUCCESS;
     1240    RT_NOREF(pvCtx);
     1241
     1242    char szTag[AUDIOTEST_TAG_MAX];
     1243    int rc = RTStrPrintf2(szTag, sizeof(szTag), "%s-valkit", pTstEnv->szTag);
     1244    if (RT_SUCCESS(rc))
     1245        rc = AudioTestSvcClientTestSetEnd(&pTstEnv->u.Host.AtsClValKit, szTag);
     1246
     1247    int rc2 = AudioTestSvcClientClose(&pTstEnv->u.Host.AtsClValKit);
     1248    if (RT_SUCCESS(rc))
     1249        rc = rc2;
     1250
     1251    return rc;
    11991252}
    12001253
     
    12451298        if (RT_FAILURE(rc))
    12461299        {
    1247             RTTestFailed(g_hTest, "Test setup failed\n");
     1300            RTTestFailed(g_hTest, "Test setup failed with %Rrc\n", rc);
    12481301            return rc;
    12491302        }
     
    12591312    AssertPtr(pTstDesc->pfnExec);
    12601313    rc = pTstDesc->pfnExec(pTstEnv, pvCtx, &TstParms);
     1314    if (RT_FAILURE(rc))
     1315        RTTestFailed(g_hTest, "Test failed with %Rrc\n", rc);
    12611316
    12621317    RTTestSubDone(g_hTest);
     
    12691324
    12701325        if (RT_FAILURE(rc2))
    1271             RTTestFailed(g_hTest, "Test destruction failed\n");
     1326            RTTestFailed(g_hTest, "Test destruction failed with %Rrc\n", rc2);
    12721327    }
    12731328
     
    12921347    if (pTstEnv->enmMode == AUDIOTESTMODE_GUEST)
    12931348    {
    1294         RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "ATS running\n");
    1295 
    1296         while (!g_fTerminate) /** @todo Implement signal handling. */
    1297         {
     1349        RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Guest ATS running\n");
     1350
     1351        while (!g_fTerminate)
    12981352            RTThreadSleep(100);
    1299         }
    1300 
    1301         RTTestPrintf(g_hTest, RTTESTLVL_DEBUG, "Shutting down ATS ...\n");
     1353
     1354        RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Shutting down guest ATS ...\n");
    13021355
    13031356        int rc2 = AudioTestSvcShutdown(&pTstEnv->u.Guest.Srv);
    13041357        if (RT_SUCCESS(rc))
    13051358            rc = rc2;
     1359
     1360        RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Guest ATS shutdown complete\n");
    13061361    }
    13071362    else if (pTstEnv->enmMode == AUDIOTESTMODE_HOST)
    13081363    {
     1364        /* Generate tag for the host side. */
     1365        char szTag[AUDIOTEST_TAG_MAX];
     1366        rc = RTStrPrintf2(szTag, sizeof(szTag), "%s-host", pTstEnv->szTag);
     1367        AssertRCReturn(rc, rc);
     1368
    13091369        /* We have one single test set for all executed tests for now. */
    1310         rc = AudioTestSetCreate(&pTstEnv->Set, pTstEnv->szPathTemp, pTstEnv->szTag);
     1370        rc = AudioTestSetCreate(&pTstEnv->Set, pTstEnv->szPathTemp, szTag);
    13111371        if (RT_SUCCESS(rc))
    13121372        {
    1313             /* Copy back the (eventually generated) tag to the test environment. */
    1314             rc = RTStrCopy(pTstEnv->szTag, sizeof(pTstEnv->szTag), AudioTestSetGetTag(&pTstEnv->Set));
    1315             AssertRC(rc);
    1316 
    1317             rc = AudioTestSvcClientTestSetBegin(&pTstEnv->u.Host.Client, pTstEnv->szTag);
     1373            rc = AudioTestSvcClientTestSetBegin(&pTstEnv->u.Host.AtsClGuest, pTstEnv->szTag);
    13181374            if (RT_SUCCESS(rc))
    13191375            {
     
    13271383                    if (!g_aTests[i].fExcluded)
    13281384                        uSeq++;
     1385
     1386                    if (g_fTerminate)
     1387                        break;
    13291388                }
    13301389
    1331                 int rc2 = AudioTestSvcClientTestSetEnd(&pTstEnv->u.Host.Client, pTstEnv->szTag);
     1390                int rc2 = AudioTestSvcClientTestSetEnd(&pTstEnv->u.Host.AtsClGuest, pTstEnv->szTag);
    13321391                if (RT_SUCCESS(rc))
    13331392                    rc = rc2;
     
    15091568        /* Use the default port is none is specified. */
    15101569        if (!uTcpPort)
    1511             uTcpPort = ATS_DEFAULT_PORT;
     1570            uTcpPort = ATS_TCP_DEFAULT_PORT;
    15121571
    15131572        if (!pszTcpAddr)
     
    15161575
    15171576    /* For now all tests have the same test environment. */
    1518     rc = audioTestEnvInit(&TstEnv, pDrvReg, fWithDrvAudio, pszTag, pszTcpAddr, uTcpPort);
     1577    rc = audioTestEnvInit(&TstEnv, pDrvReg, fWithDrvAudio, pszTcpAddr, uTcpPort);
    15191578    if (RT_SUCCESS(rc))
    15201579    {
     
    15261585
    15271586    if (RT_FAILURE(rc)) /* Let us know that something went wrong in case we forgot to mention it. */
    1528         RTTestFailed(g_hTest, "Tested failed with %Rrc\n", rc);
     1587        RTTestFailed(g_hTest, "Testing failed with %Rrc\n", rc);
    15291588
    15301589    /*
     
    24812540*********************************************************************************************************************************/
    24822541
     2542/** @todo Move this (all?) commands into separate files -- this file is too big already. */
     2543
    24832544/**
    24842545 * Command line parameters for self-test mode.
     
    24862547static const RTGETOPTDEF g_aCmdSelftestOptions[] =
    24872548{
    2488     { "--ats-host",         VKAT_SELFTEST_OPT_ATS_HOST,   RTGETOPT_REQ_STRING },
    2489     { "--backend",          'b',                          RTGETOPT_REQ_STRING  },
    2490     { "--with-drv-audio",   'd',                          RTGETOPT_REQ_NOTHING },
     2549    { "--ats-guest-addr",   VKAT_SELFTEST_OPT_ATS_GUEST_ADDR,   RTGETOPT_REQ_STRING  },
     2550    { "--ats-guest-port",   VKAT_SELFTEST_OPT_ATS_GUEST_PORT,   RTGETOPT_REQ_UINT32  },
     2551    { "--ats-valkit-addr",  VKAT_SELFTEST_OPT_ATS_GUEST_ADDR,   RTGETOPT_REQ_STRING  },
     2552    { "--ats-valkit-port",  VKAT_SELFTEST_OPT_ATS_GUEST_PORT,   RTGETOPT_REQ_UINT32  },
     2553    { "--exclude-all",      'a',                                RTGETOPT_REQ_NOTHING },
     2554    { "--backend",          'b',                                RTGETOPT_REQ_STRING  },
     2555    { "--with-drv-audio",   'd',                                RTGETOPT_REQ_NOTHING },
     2556    { "--exclude",          'e',                                RTGETOPT_REQ_UINT32  },
     2557    { "--include",          'i',                                RTGETOPT_REQ_UINT32  }
    24912558};
    24922559
     
    25032570
    25042571/**
    2505  * Tests the Audio Test Service (ATS).
     2572 * Structure for keeping a VKAT self test context.
     2573 */
     2574typedef struct SELFTESTCTX
     2575{
     2576    /** Common tag for guest and host side. */
     2577    char             szTag[AUDIOTEST_TAG_MAX];
     2578    /** Whether to use DrvAudio in the driver stack or not. */
     2579    bool             fWithDrvAudio;
     2580    struct
     2581    {
     2582        AUDIOTESTENV TstEnv;
     2583        /** Audio driver to use.
     2584         *  Defaults to the platform's default driver. */
     2585        PCPDMDRVREG  pDrvReg;
     2586    } Guest;
     2587    struct
     2588    {
     2589        AUDIOTESTENV TstEnv;
     2590        /** Address of the guest ATS instance.
     2591         *  Defaults to localhost (127.0.0.1) if not set. */
     2592        char         szGuestAtsAddr[64];
     2593        /** Port of the guest ATS instance.
     2594         *  Defaults to ATS_DEFAULT_PORT if not set. */
     2595        uint32_t     uGuestAtsPort;
     2596        /** Address of the Validation Kit audio driver ATS instance.
     2597         *  Defaults to localhost (127.0.0.1) if not set. */
     2598        char         szValKitAtsAddr[64];
     2599        /** Port of the Validation Kit audio driver ATS instance.
     2600         *  Defaults to ATS_ALT_PORT if not set. */
     2601        uint32_t     uValKitAtsPort;
     2602    } Host;
     2603} SELFTESTCTX;
     2604/** Pointer to a VKAT self test context. */
     2605typedef SELFTESTCTX *PSELFTESTCTX;
     2606
     2607static DECLCALLBACK(int) audioTestSelftestGuestAtsThread(RTTHREAD hThread, void *pvUser)
     2608{
     2609    RT_NOREF(hThread);
     2610    PSELFTESTCTX pCtx = (PSELFTESTCTX)pvUser;
     2611
     2612    AUDIOTESTPARMS TstCust;
     2613    audioTestParmsInit(&TstCust);
     2614
     2615    PAUDIOTESTENV pTstEnv = &pCtx->Guest.TstEnv;
     2616
     2617    /* Flag the environment for self test mode. */
     2618    pTstEnv->fSelftest = true;
     2619
     2620    /* Generate tag for guest side. */
     2621    int rc = RTStrCopy(pTstEnv->szTag, sizeof(pTstEnv->szTag), pCtx->szTag);
     2622    AssertRCReturn(rc, rc);
     2623
     2624    rc = AudioTestPathCreateTemp(pTstEnv->szPathTemp, sizeof(pTstEnv->szPathTemp), "selftest-guest");
     2625    AssertRCReturn(rc, rc);
     2626
     2627    rc = AudioTestPathCreateTemp(pTstEnv->szPathOut, sizeof(pTstEnv->szPathOut), "selftest-out");
     2628    AssertRCReturn(rc, rc);
     2629
     2630    pTstEnv->enmMode = AUDIOTESTMODE_GUEST;
     2631
     2632    /** @todo Make this customizable. */
     2633    PDMAudioPropsInit(&TstCust.TestTone.Props,
     2634                      2 /* 16-bit */, true  /* fSigned */, 2 /* cChannels */, 44100 /* uHz */);
     2635
     2636    /* Use ATS_ALT_PORT, as on ATS_DEFAULT_PORT the
     2637     * Validation Kit audio driver ATS already is running on ATS_DEFAULT_PORT. */
     2638    rc = audioTestEnvInit(pTstEnv, pCtx->Guest.pDrvReg, pCtx->fWithDrvAudio,
     2639                          "127.0.0.1", ATS_TCP_ALT_PORT);
     2640    if (RT_SUCCESS(rc))
     2641    {
     2642        RTThreadUserSignal(hThread);
     2643
     2644        audioTestWorker(pTstEnv, &TstCust);
     2645        audioTestEnvDestroy(pTstEnv);
     2646    }
     2647
     2648    audioTestParmsDestroy(&TstCust);
     2649
     2650    return rc;
     2651}
     2652
     2653/**
     2654 * Main function for performing the self test.
    25062655 *
    25072656 * @returns VBox status code.
    2508  * @param   pDrvReg             Backend driver to use.
    2509  * @param   pszAdr              Address of ATS server to connect to.
    2510  *                              If NULL, an own (local) ATS server will be created.
    2511  */
    2512 static int audioTestDoSelftestAts(PCPDMDRVREG pDrvReg, const char *pszAdr)
    2513 {
    2514     AUDIOTESTENV TstEnv;
    2515     int rc = audioTestDriverStackInit(&TstEnv.DrvStack, pDrvReg, true /* fWithDrvAudio */);
     2657 * @param   pCtx                Self test context to use.
     2658 */
     2659static int audioTestDoSelftest(PSELFTESTCTX pCtx)
     2660{
     2661    RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS,  "Running self test ...\n");
     2662
     2663    /*
     2664     * The self-test does the following:
     2665     * - 1. Creates an ATS instance to emulate the guest mode ("--mode guest")
     2666     *      at port 6042 (ATS_ALT_PORT).
     2667     * - 2. Uses the Validation Kit audio backend, which in turn creates an ATS instance
     2668     *      at port 6052 (ATS_DEFAULT_PORT).
     2669     * - 3. Executes a complete test run locally (e.g. without any guest (VM) involved).
     2670     */
     2671
     2672    AUDIOTESTPARMS TstCust;
     2673    audioTestParmsInit(&TstCust);
     2674
     2675    /* Generate a common tag for guest and host side. */
     2676    int rc = AudioTestGenTag(pCtx->szTag, sizeof(pCtx->szTag));
     2677    AssertRCReturn(rc, rc);
     2678
     2679    PAUDIOTESTENV pTstEnv = &pCtx->Host.TstEnv;
     2680
     2681    /* Flag the environment for self test mode. */
     2682    pTstEnv->fSelftest = true;
     2683
     2684    /* Generate tag for host side. */
     2685    rc = RTStrCopy(pTstEnv->szTag, sizeof(pTstEnv->szTag), pCtx->szTag);
     2686    AssertRCReturn(rc, rc);
     2687
     2688    rc = AudioTestPathCreateTemp(pTstEnv->szPathTemp, sizeof(pTstEnv->szPathTemp), "selftest-host");
     2689    AssertRCReturn(rc, rc);
     2690
     2691    rc = AudioTestPathCreateTemp(pTstEnv->szPathOut, sizeof(pTstEnv->szPathOut), "selftest-out");
     2692    AssertRCReturn(rc, rc);
     2693
     2694    /*
     2695     * Step 1.
     2696     * Creates a separate thread for the guest ATS.
     2697     */
     2698    RTTHREAD hThreadGstAts;
     2699    rc = RTThreadCreate(&hThreadGstAts, audioTestSelftestGuestAtsThread, pCtx, 0, RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE,
     2700                        "VKATGstAts");
    25162701    if (RT_SUCCESS(rc))
    25172702    {
    2518         /** @todo Make stream parameters configurable. */
    2519         PDMAUDIOPCMPROPS  Props;
    2520         PDMAudioPropsInit(&Props, 16 /* bit */ / 8, true /* fSigned */, 2 /* Channels */, 44100 /* Hz */);
    2521 
    2522         PDMAUDIOSTREAMCFG CfgAcq;
    2523         PPDMAUDIOSTREAM   pStream = NULL;
    2524         rc = audioTestDriverStackStreamCreateOutput(&TstEnv.DrvStack, &Props,
    2525                                                     UINT32_MAX /* cMsBufferSize */,
    2526                                                     UINT32_MAX /* cMsPreBuffer */,
    2527                                                     UINT32_MAX /* cMsSchedulingHint */, &pStream, &CfgAcq);
     2703        rc = RTThreadUserWait(hThreadGstAts, RT_MS_30SEC);
    25282704        if (RT_SUCCESS(rc))
    25292705        {
    2530             rc = audioTestDriverStackStreamEnable(&TstEnv.DrvStack, pStream);
     2706            /*
     2707             * Steps 2 + 3.
     2708             */
     2709            pTstEnv->enmMode = AUDIOTESTMODE_HOST;
     2710
     2711            if (!pCtx->Host.uGuestAtsPort)
     2712                pCtx->Host.uGuestAtsPort = ATS_TCP_ALT_PORT;
     2713
     2714            rc = audioTestEnvInit(pTstEnv, &g_DrvHostValidationKitAudio, true /* fWithDrvAudio */,
     2715                                  pCtx->Host.szGuestAtsAddr, pCtx->Host.uGuestAtsPort);
    25312716            if (RT_SUCCESS(rc))
    25322717            {
    2533                 ATSCALLBACKCTX Ctx;
    2534                 Ctx.pTstEnv = &TstEnv;
    2535 
    2536                 ATSCALLBACKS Callbacks;
    2537                 Callbacks.pfnTonePlay = audioTestSvcTonePlayCallback;
    2538                 Callbacks.pvUser      = &Ctx;
    2539 
    2540                 /* Start an own ATS instance if no address to connect was specified. */
    2541                 ATSSERVER Srv;
    2542                 if (pszAdr == NULL)
    2543                 {
    2544                     RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Starting ATS ...\n");
    2545 
    2546                     rc = AudioTestSvcInit(&Srv, &Callbacks);
    2547                     if (RT_SUCCESS(rc))
    2548                         rc = AudioTestSvcStart(&Srv);
    2549                 }
    2550                 else
    2551                     RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Connecting to ATS at '%s' ...\n", pszAdr);
    2552 
    2553                 if (RT_SUCCESS(rc))
    2554                 {
    2555                     ATSCLIENT Conn;
    2556                     rc = AudioTestSvcClientConnect(&Conn, NULL, 0);
    2557                     if (RT_SUCCESS(rc))
    2558                     {
    2559                         RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Connected to ATS, testing ...\n");
    2560 
    2561                         /* Do the bare minimum here to get a test tone out. */
    2562                         AUDIOTESTTONEPARMS ToneParms;
    2563                         RT_ZERO(ToneParms);
    2564                         ToneParms.msDuration = RTRandU32Ex(250, 1000 * 5);
    2565                         memcpy(&ToneParms.Props, &CfgAcq.Props, sizeof(PDMAUDIOPCMPROPS));
    2566 
    2567                         rc = AudioTestSvcClientTonePlay(&Conn, &ToneParms);
    2568 
    2569                         int rc2 = AudioTestSvcClientClose(&Conn);
    2570                         if (RT_SUCCESS(rc))
    2571                             rc = rc2;
    2572                     }
    2573                     else
    2574                         RTTestFailed(g_hTest, "Connecting to ATS failed, rc=%Rrc\n", rc);
    2575 
    2576                     int rc2 = AudioTestSvcShutdown(&Srv);
    2577                     if (RT_SUCCESS(rc))
    2578                         rc = rc2;
    2579                 }
    2580 
    2581                 if (pszAdr == NULL)
    2582                 {
    2583                     RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Shutting down ATS ...\n");
    2584 
    2585                     int rc2 = AudioTestSvcDestroy(&Srv);
    2586                         if (RT_SUCCESS(rc))
    2587                             rc = rc2;
    2588                 }
     2718                audioTestWorker(pTstEnv, &TstCust);
     2719                audioTestEnvDestroy(pTstEnv);
    25892720            }
    25902721        }
    25912722    }
    25922723
     2724    audioTestParmsDestroy(&TstCust);
     2725
     2726    /*
     2727     * Shutting down.
     2728     */
     2729    RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS,  "Shutting down self test\n");
     2730
     2731    ASMAtomicWriteBool(&g_fTerminate, true);
     2732
     2733    int rcThread;
     2734    int rc2 = RTThreadWait(hThreadGstAts, RT_MS_30SEC, &rcThread);
     2735    if (RT_SUCCESS(rc2))
     2736        rc2 = rcThread;
     2737    if (RT_FAILURE(rc2))
     2738        RTTestFailed(g_hTest, "Shutting down self test failed with %Rrc\n", rc2);
     2739
     2740    if (RT_SUCCESS(rc))
     2741        rc = rc2;
     2742
    25932743    if (RT_FAILURE(rc))
    2594         RTTestFailed(g_hTest, "Testing ATS failed with %Rrc\n", rc);
    2595 
    2596     return rc;
    2597 }
    2598 
    2599 /**
    2600  * Main function for performing the self-tests.
    2601  *
    2602  * @returns VBox status code.
    2603  * @param   pDrvReg             Backend driver to use.
    2604  * @param   pszAtsAdr           Address of ATS server to connect to.
    2605  *                              If NULL, an own (local) ATS server will be created.
    2606  */
    2607 static int audioTestDoSelftest(PCPDMDRVREG pDrvReg, const char *pszAtsAdr)
    2608 {
    2609     int rc = audioTestDoSelftestAts(pDrvReg, pszAtsAdr);
    2610     if (RT_FAILURE(rc))
    2611         RTTestFailed(g_hTest, "Self-test failed with: %Rrc", rc);
     2744        RTTestFailed(g_hTest, "Self test failed with %Rrc\n", rc);
    26122745
    26132746    return rc;
     
    26222755static DECLCALLBACK(RTEXITCODE) audioTestCmdSelftestHandler(PRTGETOPTSTATE pGetState)
    26232756{
    2624     /* Option values: */
    2625     PCPDMDRVREG pDrvReg           = g_aBackends[0].pDrvReg;
    2626     bool        fWithDrvAudio     = false;
    2627     const char *pszAtsAddr        = NULL;
     2757    SELFTESTCTX Ctx;
     2758    RT_ZERO(Ctx);
     2759
     2760    /* Go with the platform's default bakcend if nothing else is specified. */
     2761    Ctx.Guest.pDrvReg = g_aBackends[0].pDrvReg;
    26282762
    26292763    /* Argument processing loop: */
     
    26342768        switch (rc)
    26352769        {
    2636             case VKAT_SELFTEST_OPT_ATS_HOST:
    2637                 pszAtsAddr = ValueUnion.psz;
     2770            case VKAT_SELFTEST_OPT_ATS_GUEST_ADDR:
     2771                rc = RTStrCopy(Ctx.Host.szGuestAtsAddr, sizeof(Ctx.Host.szGuestAtsAddr), ValueUnion.psz);
     2772                break;
     2773
     2774            case VKAT_SELFTEST_OPT_ATS_GUEST_PORT:
     2775                Ctx.Host.uGuestAtsPort = ValueUnion.u32;
     2776                break;
     2777
     2778            case VKAT_SELFTEST_OPT_ATS_VALKIT_ADDR:
     2779                rc = RTStrCopy(Ctx.Host.szValKitAtsAddr, sizeof(Ctx.Host.szValKitAtsAddr), ValueUnion.psz);
     2780                break;
     2781
     2782            case VKAT_SELFTEST_OPT_ATS_VALKIT_PORT:
     2783                Ctx.Host.uValKitAtsPort = ValueUnion.u32;
     2784                break;
     2785
     2786            case 'a':
     2787                for (unsigned i = 0; i < RT_ELEMENTS(g_aTests); i++)
     2788                    g_aTests[i].fExcluded = true;
    26382789                break;
    26392790
    26402791            case 'b':
    2641                 pDrvReg = audioTestFindBackendOpt(ValueUnion.psz);
    2642                 if (pDrvReg == NULL)
     2792            {
     2793                Ctx.Guest.pDrvReg = audioTestFindBackendOpt(ValueUnion.psz);
     2794                if (Ctx.Guest.pDrvReg == NULL)
    26432795                    return RTEXITCODE_SYNTAX;
    26442796                break;
     2797            }
    26452798
    26462799            case 'd':
    2647                 fWithDrvAudio = true;
     2800                Ctx.fWithDrvAudio = true;
     2801                break;
     2802
     2803            case 'e':
     2804                if (ValueUnion.u32 >= RT_ELEMENTS(g_aTests))
     2805                    return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Invalid test number %u passed to --exclude", ValueUnion.u32);
     2806                g_aTests[ValueUnion.u32].fExcluded = true;
     2807                break;
     2808
     2809            case 'i':
     2810                if (ValueUnion.u32 >= RT_ELEMENTS(g_aTests))
     2811                    return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Invalid test number %u passed to --include", ValueUnion.u32);
     2812                g_aTests[ValueUnion.u32].fExcluded = false;
    26482813                break;
    26492814
     
    26552820    }
    26562821
    2657     audioTestDoSelftest(pDrvReg, pszAtsAddr);
     2822    /*
     2823     * Start testing.
     2824     */
     2825    RTTestBanner(g_hTest);
     2826
     2827    int rc2 = audioTestDoSelftest(&Ctx);
     2828    if (RT_FAILURE(rc2))
     2829        RTTestFailed(g_hTest, "Self test failed with rc=%Rrc", rc2);
    26582830
    26592831    /*
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