Changeset 89541 in vbox for trunk/src/VBox/ValidationKit
- Timestamp:
- Jun 7, 2021 9:26:07 AM (4 years ago)
- svn:sync-xref-src-repo-rev:
- 144899
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/ValidationKit/utils/audio/vkat.cpp
r89525 r89541 182 182 /** Audio testing mode. */ 183 183 AUDIOTESTMODE enmMode; 184 /** Whether self test mode is active or not. */ 185 bool fSelftest; 184 186 /** Output path for storing the test environment's final test files. */ 185 187 char szTag[AUDIOTEST_TAG_MAX]; … … 211 213 struct 212 214 { 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; 214 219 } Host; 215 220 } u; … … 303 308 enum 304 309 { 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 306 314 }; 307 315 … … 493 501 RTThreadSleep(pTstEnv->cMsSchedulingHint); 494 502 495 RTTestPrintf(g_hTest, RTTESTLVL_DEBUG, "Written %RU32 bytes\n", cbWritten);496 497 503 Assert(cbToWrite >= cbWritten); 498 504 cbToWrite -= cbWritten; … … 564 570 RTThreadSleep(pTstEnv->cMsSchedulingHint); 565 571 566 RTTestPrintf(g_hTest, RTTESTLVL_DEBUG, "Read %RU32 bytes\n", cbRead);567 568 572 Assert(cbToRead >= cbRead); 569 573 cbToRead -= cbRead; … … 595 599 PAUDIOTESTENV pTstEnv = pCtx->pTstEnv; 596 600 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); 600 608 } 601 609 … … 708 716 * @param pDrvReg Audio driver to use. 709 717 * @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.711 718 * @param pszTcpAddr TCP/IP address to connect to. 719 * If NULL, localhost (127.0.0.1) will be used. 712 720 * @param uTcpPort TCP/IP port to connect to. 721 * If 0, ATS_DEFAULT_PORT will be used. 713 722 */ 714 723 static int audioTestEnvInit(PAUDIOTESTENV pTstEnv, 715 PCPDMDRVREG pDrvReg, bool fWithDrvAudio, const char *pszTag,724 PCPDMDRVREG pDrvReg, bool fWithDrvAudio, 716 725 const char *pszTcpAddr, uint32_t uTcpPort) 717 726 { 718 727 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", p szTag);728 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Using tag '%s'\n", pTstEnv->szTag); 720 729 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Output directory is '%s'\n", pTstEnv->szPathOut); 721 730 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Temp directory is '%s'\n", pTstEnv->szPathTemp); … … 730 739 731 740 /* 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; 733 745 if (fUseDriverStack) 734 746 { … … 772 784 Callbacks.pvUser = &Ctx; 773 785 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); 776 788 if (RT_SUCCESS(rc)) 777 789 rc = AudioTestSvcStart(&pTstEnv->u.Guest.Srv); … … 785 797 else /* Host mode */ 786 798 { 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); 790 803 if (RT_FAILURE(rc)) 791 804 { … … 850 863 AudioTestSetDestroy(&pTstEnv->Set); 851 864 865 if (RT_FAILURE(rc)) 866 RTTestFailed(g_hTest, "Test set prologue failed with %Rrc\n", rc); 867 852 868 return rc; 853 869 } … … 892 908 static int audioTestDevicesEnumerateAndCheck(PAUDIOTESTENV pTstEnv, const char *pszDev, PPDMAUDIOHOSTDEV *ppDev) 893 909 { 910 #ifdef DEBUG_andy 911 return VINF_SUCCESS; 912 #endif 913 894 914 RTTestSubF(g_hTest, "Enumerating audio devices and checking for device '%s'", pszDev ? pszDev : "<Default>"); 895 915 … … 1107 1127 Cfg.Props = pTstParms->Props; 1108 1128 1109 rc = AudioTestSvcClientTonePlay(&pTstEnv->u.Host. Client, &pTstParms->TestTone);1129 rc = AudioTestSvcClientTonePlay(&pTstEnv->u.Host.AtsClGuest, &pTstParms->TestTone); 1110 1130 if (RT_SUCCESS(rc)) 1111 1131 { … … 1138 1158 static DECLCALLBACK(int) audioTestRecordToneSetup(PAUDIOTESTENV pTstEnv, PAUDIOTESTDESC pTstDesc, PAUDIOTESTPARMS pTstParmsAcq, void **ppvCtx) 1139 1159 { 1140 RT_NOREF(pTst Env, pTstDesc, ppvCtx);1160 RT_NOREF(pTstDesc, ppvCtx); 1141 1161 1142 1162 pTstParmsAcq->enmType = AUDIOTESTTYPE_TESTTONE_RECORD; … … 1152 1172 pTstParmsAcq->idxCurrent = 0; 1153 1173 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; 1155 1186 } 1156 1187 … … 1167 1198 { 1168 1199 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 1171 1205 PAUDIOTESTENTRY pTst; 1172 1206 rc = AudioTestSetTestBegin(&pTstEnv->Set, "Recording test tone", pTstParms, &pTst); 1173 1207 if (RT_SUCCESS(rc)) 1174 1208 { 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); 1176 1213 if (RT_SUCCESS(rc)) 1177 1214 { 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"); 1179 1225 } 1180 else1181 AudioTestSetTestFailed(pTst, rc, "Recording test tone failed");1182 1226 } 1183 1227 … … 1194 1238 static DECLCALLBACK(int) audioTestRecordToneDestroy(PAUDIOTESTENV pTstEnv, void *pvCtx) 1195 1239 { 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; 1199 1252 } 1200 1253 … … 1245 1298 if (RT_FAILURE(rc)) 1246 1299 { 1247 RTTestFailed(g_hTest, "Test setup failed \n");1300 RTTestFailed(g_hTest, "Test setup failed with %Rrc\n", rc); 1248 1301 return rc; 1249 1302 } … … 1259 1312 AssertPtr(pTstDesc->pfnExec); 1260 1313 rc = pTstDesc->pfnExec(pTstEnv, pvCtx, &TstParms); 1314 if (RT_FAILURE(rc)) 1315 RTTestFailed(g_hTest, "Test failed with %Rrc\n", rc); 1261 1316 1262 1317 RTTestSubDone(g_hTest); … … 1269 1324 1270 1325 if (RT_FAILURE(rc2)) 1271 RTTestFailed(g_hTest, "Test destruction failed \n");1326 RTTestFailed(g_hTest, "Test destruction failed with %Rrc\n", rc2); 1272 1327 } 1273 1328 … … 1292 1347 if (pTstEnv->enmMode == AUDIOTESTMODE_GUEST) 1293 1348 { 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) 1298 1352 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"); 1302 1355 1303 1356 int rc2 = AudioTestSvcShutdown(&pTstEnv->u.Guest.Srv); 1304 1357 if (RT_SUCCESS(rc)) 1305 1358 rc = rc2; 1359 1360 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Guest ATS shutdown complete\n"); 1306 1361 } 1307 1362 else if (pTstEnv->enmMode == AUDIOTESTMODE_HOST) 1308 1363 { 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 1309 1369 /* 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); 1311 1371 if (RT_SUCCESS(rc)) 1312 1372 { 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); 1318 1374 if (RT_SUCCESS(rc)) 1319 1375 { … … 1327 1383 if (!g_aTests[i].fExcluded) 1328 1384 uSeq++; 1385 1386 if (g_fTerminate) 1387 break; 1329 1388 } 1330 1389 1331 int rc2 = AudioTestSvcClientTestSetEnd(&pTstEnv->u.Host. Client, pTstEnv->szTag);1390 int rc2 = AudioTestSvcClientTestSetEnd(&pTstEnv->u.Host.AtsClGuest, pTstEnv->szTag); 1332 1391 if (RT_SUCCESS(rc)) 1333 1392 rc = rc2; … … 1509 1568 /* Use the default port is none is specified. */ 1510 1569 if (!uTcpPort) 1511 uTcpPort = ATS_ DEFAULT_PORT;1570 uTcpPort = ATS_TCP_DEFAULT_PORT; 1512 1571 1513 1572 if (!pszTcpAddr) … … 1516 1575 1517 1576 /* For now all tests have the same test environment. */ 1518 rc = audioTestEnvInit(&TstEnv, pDrvReg, fWithDrvAudio, pszT ag, pszTcpAddr, uTcpPort);1577 rc = audioTestEnvInit(&TstEnv, pDrvReg, fWithDrvAudio, pszTcpAddr, uTcpPort); 1519 1578 if (RT_SUCCESS(rc)) 1520 1579 { … … 1526 1585 1527 1586 if (RT_FAILURE(rc)) /* Let us know that something went wrong in case we forgot to mention it. */ 1528 RTTestFailed(g_hTest, "Test edfailed with %Rrc\n", rc);1587 RTTestFailed(g_hTest, "Testing failed with %Rrc\n", rc); 1529 1588 1530 1589 /* … … 2481 2540 *********************************************************************************************************************************/ 2482 2541 2542 /** @todo Move this (all?) commands into separate files -- this file is too big already. */ 2543 2483 2544 /** 2484 2545 * Command line parameters for self-test mode. … … 2486 2547 static const RTGETOPTDEF g_aCmdSelftestOptions[] = 2487 2548 { 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 } 2491 2558 }; 2492 2559 … … 2503 2570 2504 2571 /** 2505 * Tests the Audio Test Service (ATS). 2572 * Structure for keeping a VKAT self test context. 2573 */ 2574 typedef 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. */ 2605 typedef SELFTESTCTX *PSELFTESTCTX; 2606 2607 static 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. 2506 2655 * 2507 2656 * @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 */ 2659 static 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"); 2516 2701 if (RT_SUCCESS(rc)) 2517 2702 { 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); 2528 2704 if (RT_SUCCESS(rc)) 2529 2705 { 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); 2531 2716 if (RT_SUCCESS(rc)) 2532 2717 { 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); 2589 2720 } 2590 2721 } 2591 2722 } 2592 2723 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 2593 2743 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); 2612 2745 2613 2746 return rc; … … 2622 2755 static DECLCALLBACK(RTEXITCODE) audioTestCmdSelftestHandler(PRTGETOPTSTATE pGetState) 2623 2756 { 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; 2628 2762 2629 2763 /* Argument processing loop: */ … … 2634 2768 switch (rc) 2635 2769 { 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; 2638 2789 break; 2639 2790 2640 2791 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) 2643 2795 return RTEXITCODE_SYNTAX; 2644 2796 break; 2797 } 2645 2798 2646 2799 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; 2648 2813 break; 2649 2814 … … 2655 2820 } 2656 2821 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); 2658 2830 2659 2831 /*
Note:
See TracChangeset
for help on using the changeset viewer.