- Timestamp:
- Jan 11, 2024 8:45:36 AM (13 months ago)
- Location:
- trunk/src/VBox/GuestHost/SharedClipboard/testcase
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/GuestHost/SharedClipboard/testcase/Makefile.kmk
r100685 r102830 83 83 tstClipboardHttpServer_DEFS += VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS_HTTP 84 84 endif 85 86 if1of ($(KBUILD_TARGET), linux solaris) 87 # Derived executable which also includes X11 dependencies. Might not run on pure server installations where X isn't installed. 88 PROGRAMS += tstClipboardHttpServerX11 89 tstClipboardHttpServerX11_TEMPLATE = VBoxR3TstExe 90 tstClipboardHttpServerX11_EXTENDS = tstClipboardHttpServer 91 tstClipboardHttpServerX11_EXTENDS_BY = appending 92 tstClipboardHttpServerX11_NAME = tstClipboardHttpServerX11 93 tstClipboardHttpServerX11_DEFS += TESTCASE_WITH_X11 94 tstClipboardHttpServerX11_SOURCES += \ 95 ../clipboard-x11.cpp 96 tstClipboardHttpServerX11_LIBS += \ 97 Xt \ 98 X11 99 endif 85 100 endif 86 101 -
trunk/src/VBox/GuestHost/SharedClipboard/testcase/tstClipboardHttpServer.cpp
r102472 r102830 33 33 #include <iprt/message.h> 34 34 #include <iprt/path.h> 35 #include <iprt/process.h> 35 36 #include <iprt/rand.h> 37 #include <iprt/stream.h> 36 38 #include <iprt/string.h> 37 39 #include <iprt/test.h> 40 #include <iprt/utf16.h> 41 42 #ifdef TESTCASE_WITH_X11 43 #include <VBox/GuestHost/SharedClipboard-x11.h> 44 #endif 38 45 39 46 #include <VBox/GuestHost/SharedClipboard-transfers.h> … … 48 55 /** Shutdown indicator. */ 49 56 static bool g_fShutdown = false; 50 /** Manual mode indicator; allows manual testing w/ other HTTP clients. */57 /** Manual mode indicator; allows manual (i.e. interactive) testing w/ other HTTP clients or desktop environments. */ 51 58 static bool g_fManual = false; 59 #ifdef TESTCASE_WITH_X11 60 /** Puts the URL on the X11 clipboard. Only works with manual mode. */ 61 static bool g_fX11 = false; 62 #endif 52 63 53 64 /** Test files to handle + download. … … 76 87 }; 77 88 78 /* Worker thread for the HTTP server. */79 static DECLCALLBACK(int) tstSrvWorker(RTTHREAD hThread, void *pvUser)80 {81 RT_NOREF(pvUser);82 83 int rc = RTThreadUserSignal(hThread);84 AssertRCReturn(rc, rc);85 86 uint64_t const msStartTS = RTTimeMilliTS();87 while (RTTimeMilliTS() - msStartTS < g_msRuntime)88 {89 if (g_fShutdown)90 break;91 RTThreadSleep(100); /* Wait a little. */92 }93 94 return RTTimeMilliTS() - msStartTS <= g_msRuntime ? VINF_SUCCESS : VERR_TIMEOUT;95 }96 89 97 90 static void tstCreateTransferSingle(RTTEST hTest, PSHCLTRANSFERCTX pTransferCtx, PSHCLHTTPSERVER pSrv, … … 107 100 } 108 101 102 /** 103 * Run a manual (i.e. interacive) test. 104 * 105 * This will keep the HTTP server running, so that the file(s) can be downloaded manually. 106 */ 107 static void tstManual(RTTEST hTest, PSHCLTRANSFERCTX pTransferCtx, PSHCLHTTPSERVER pHttpSrv) 108 { 109 char *pszUrls = NULL; 110 111 uint32_t const cTx = ShClTransferCtxGetTotalTransfers(pTransferCtx); 112 if (!cTx) 113 { 114 RTTestFailed(hTest, "Must specify at least one file to serve!\n"); 115 return; 116 } 117 118 for (uint32_t i = 0; i < cTx; i++) 119 { 120 PSHCLTRANSFER pTx = ShClTransferCtxGetTransferByIndex(pTransferCtx, i); 121 122 uint16_t const uId = ShClTransferGetID(pTx); 123 char *pszUrl = ShClTransferHttpServerGetUrlA(pHttpSrv, uId, 0 /* Entry index */); 124 RTTEST_CHECK(hTest, pszUrl != NULL); 125 RTTestPrintf(hTest, RTTESTLVL_ALWAYS, "URL #%02RU32: %s\n", i, pszUrl); 126 RTStrAPrintf(&pszUrls, "%s", pszUrl); 127 if (i > 0) 128 RTStrAPrintf(&pszUrls, "\n"); 129 RTStrFree(pszUrl); 130 } 131 132 #ifdef TESTCASE_WITH_X11 133 SHCLX11CTX X11Ctx; 134 SHCLEVENTSOURCE EventSource; 135 136 if (g_fX11) 137 { 138 RTTestPrintf(hTest, RTTESTLVL_ALWAYS, "Copied URLs to X11 clipboard\n"); 139 140 SHCLCALLBACKS Callbacks; 141 RT_ZERO(Callbacks); 142 RTTEST_CHECK_RC_OK(hTest, ShClX11Init(&X11Ctx, &Callbacks, NULL /* pParent */, false /* fHeadless */)); 143 RTTEST_CHECK_RC_OK(hTest, ShClX11ThreadStart(&X11Ctx, false /* fGrab */)); 144 RTTEST_CHECK_RC_OK(hTest, ShClEventSourceCreate(&EventSource, 0)); 145 RTTEST_CHECK_RC_OK(hTest, ShClX11WriteDataToX11(&X11Ctx, &EventSource, RT_MS_30SEC, 146 VBOX_SHCL_FMT_UNICODETEXT | VBOX_SHCL_FMT_URI_LIST, 147 pszUrls, RTStrNLen(pszUrls, RTSTR_MAX), NULL /* pcbWritten */)); 148 } 149 #endif 150 151 RTThreadSleep(g_msRuntime); 152 153 #ifdef TESTCASE_WITH_X11 154 if (g_fX11) 155 { 156 RTTEST_CHECK_RC_OK(hTest, ShClEventSourceDestroy(&EventSource)); 157 ShClX11ThreadStop(&X11Ctx); 158 ShClX11Destroy(&X11Ctx); 159 } 160 #endif 161 162 RTStrFree(pszUrls); 163 } 164 165 static RTEXITCODE tstUsage(PRTSTREAM pStrm) 166 { 167 RTStrmPrintf(pStrm, "Tests for the clipboard HTTP server.\n\n"); 168 169 RTStrmPrintf(pStrm, "Usage: %s [options] [file 1] ... [file N]\n", RTProcShortName()); 170 RTStrmPrintf(pStrm, 171 "\n" 172 "Options:\n" 173 " -h, -?, --help\n" 174 " Displays help.\n" 175 " -m, --manual\n" 176 " Enables manual (i.e. interactive) testing the HTTP server.\n" 177 " -p, --port\n" 178 " Sets the HTTP server port.\n" 179 " -v, --verbose\n" 180 " Increases verbosity.\n" 181 #ifdef TESTCASE_WITH_X11 182 " -X, --x11\n" 183 " Copies the HTTP URLs to the X11 clipboard(s). Implies manual testing.\n" 184 #endif 185 ); 186 187 return RTEXITCODE_SUCCESS; 188 } 189 109 190 int main(int argc, char *argv[]) 110 191 { … … 116 197 if (rcExit != RTEXITCODE_SUCCESS) 117 198 return rcExit; 118 RTTestBanner(hTest);119 199 120 200 /* … … 123 203 static const RTGETOPTDEF aOpts[] = 124 204 { 125 { "-- port", 'p', RTGETOPT_REQ_UINT16},205 { "--help", 'h', RTGETOPT_REQ_NOTHING }, 126 206 { "--manual", 'm', RTGETOPT_REQ_NOTHING }, 127 207 { "--max-time", 't', RTGETOPT_REQ_UINT32 }, 128 { "--verbose", 'v', RTGETOPT_REQ_NOTHING } 208 { "--port", 'p', RTGETOPT_REQ_UINT16 }, 209 { "--verbose", 'v', RTGETOPT_REQ_NOTHING }, 210 { "--x11", 'X', RTGETOPT_REQ_NOTHING } 129 211 }; 130 212 … … 141 223 switch (ch) 142 224 { 225 case 'h': 226 return tstUsage(g_pStdErr); 227 143 228 case 'p': 144 229 uPort = ValueUnion.u16; … … 157 242 break; 158 243 244 #ifdef TESTCASE_WITH_X11 245 case 'X': 246 g_fX11 = true; 247 break; 248 #endif 159 249 case VINF_GETOPT_NOT_OPTION: 160 250 continue; … … 164 254 } 165 255 } 256 257 RTTestBanner(hTest); 258 259 #ifdef TESTCASE_WITH_X11 260 /* Enable manual mode if X11 was selected. Pure convenience. */ 261 if (g_fX11 && !g_fManual) 262 g_fManual = true; 263 #endif 166 264 167 265 /* … … 227 325 RTTEST_CHECK(hTest, pszSrvAddr != NULL); 228 326 RTTestPrintf(hTest, RTTESTLVL_ALWAYS, "HTTP server running: %s (for %RU32ms) ...\n", pszSrvAddr, g_msRuntime); 229 RT MemFree(pszSrvAddr);327 RTStrFree(pszSrvAddr); 230 328 pszSrvAddr = NULL; 231 329 … … 307 405 if (RTTestErrorCount(hTest) == 0) 308 406 { 309 /* Create thread for our HTTP server. */ 310 RTTHREAD hThread; 311 rc = RTThreadCreate(&hThread, tstSrvWorker, NULL, 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, 312 "tstClpHttpSrv"); 313 RTTEST_CHECK_RC_OK(hTest, rc); 314 if (RT_SUCCESS(rc)) 315 { 316 rc = RTThreadUserWait(hThread, RT_MS_30SEC); 317 RTTEST_CHECK_RC_OK(hTest, rc); 318 } 319 320 if (RT_SUCCESS(rc)) 321 { 322 if (g_fManual) 407 if (g_fManual) 408 { 409 tstManual(hTest, &TxCtx, &HttpSrv); 410 } 411 else /* Download all files to a temp file using our HTTP client. */ 412 { 413 RTHTTP hClient; 414 rc = RTHttpCreate(&hClient); 415 if (RT_SUCCESS(rc)) 323 416 { 324 uint32_t const cTx = ShClTransferCtxGetTotalTransfers(&TxCtx);325 for ( uint32_t i = 0; i < cTx; i++)417 char szURL[RTPATH_MAX]; 418 for (size_t i = 0; i < RT_ELEMENTS(g_aTests); i++) 326 419 { 327 420 PSHCLTRANSFER pTx = ShClTransferCtxGetTransferByIndex(&TxCtx, i); 328 329 uint16_t const uID = ShClTransferGetID(pTx); 330 char *pszURL = ShClTransferHttpServerGetUrlA(&HttpSrv, uID, 0 /* Entry index */); 331 RTTEST_CHECK(hTest, pszURL != NULL); 332 RTTestPrintf(hTest, RTTESTLVL_ALWAYS, "URL #%02RU32: %s\n", i, pszURL); 333 RTStrFree(pszURL); 421 char *pszUrlBase = ShClTransferHttpServerGetUrlA(&HttpSrv, ShClTransferGetID(pTx), UINT64_MAX); 422 423 RTTEST_CHECK(hTest, RTStrPrintf2(szURL, sizeof(szURL), "%s/%s", pszUrlBase, g_aTests[i].pszUrl)); 424 425 RTStrFree(pszUrlBase); 426 427 /* Download to destination file. */ 428 char szDstFile[RTPATH_MAX]; 429 RTTEST_CHECK_RC_OK(hTest, RTPathTemp(szDstFile, sizeof(szDstFile))); 430 RTTEST_CHECK_RC_OK(hTest, RTPathAppend(szDstFile, sizeof(szDstFile), "tstClipboardHttpServer-XXXXXX")); 431 RTTEST_CHECK_RC_OK(hTest, RTFileCreateTemp(szDstFile, 0600)); 432 RTTestPrintf(hTest, RTTESTLVL_ALWAYS, "Downloading '%s' -> '%s'\n", szURL, szDstFile); 433 RTTEST_CHECK_RC_OK(hTest, RTHttpGetFile(hClient, szURL, szDstFile)); 434 435 /* Compare files. */ 436 char szSrcFile[RTPATH_MAX]; 437 RTTEST_CHECK (hTest, RTStrPrintf(szSrcFile, sizeof(szSrcFile), szTempDir)); 438 RTTEST_CHECK_RC_OK(hTest, RTPathAppend(szSrcFile, sizeof(szSrcFile), g_aTests[i].pszFileName)); 439 RTTestPrintf(hTest, RTTESTLVL_ALWAYS, "Comparing files '%s' vs. '%s'\n", szSrcFile, szDstFile); 440 RTTEST_CHECK_RC_OK(hTest, RTFileCompare(szSrcFile, szDstFile)); 441 442 RTTEST_CHECK_RC_OK(hTest, RTFileDelete(szDstFile)); 334 443 } 444 445 RTTEST_CHECK_RC_OK(hTest, RTHttpDestroy(hClient)); 335 446 } 336 else /* Download all files to a temp file using our HTTP client. */ 337 { 338 RTHTTP hClient; 339 rc = RTHttpCreate(&hClient); 340 if (RT_SUCCESS(rc)) 341 { 342 char szURL[RTPATH_MAX]; 343 for (size_t i = 0; i < RT_ELEMENTS(g_aTests); i++) 344 { 345 PSHCLTRANSFER pTx = ShClTransferCtxGetTransferByIndex(&TxCtx, i); 346 char *pszUrlBase = ShClTransferHttpServerGetUrlA(&HttpSrv, ShClTransferGetID(pTx), UINT64_MAX); 347 348 RTTEST_CHECK(hTest, RTStrPrintf2(szURL, sizeof(szURL), "%s/%s", pszUrlBase, g_aTests[i].pszUrl)); 349 350 RTStrFree(pszUrlBase); 351 352 /* Download to destination file. */ 353 char szDstFile[RTPATH_MAX]; 354 RTTEST_CHECK_RC_OK(hTest, RTPathTemp(szDstFile, sizeof(szDstFile))); 355 RTTEST_CHECK_RC_OK(hTest, RTPathAppend(szDstFile, sizeof(szDstFile), "tstClipboardHttpServer-XXXXXX")); 356 RTTEST_CHECK_RC_OK(hTest, RTFileCreateTemp(szDstFile, 0600)); 357 RTTestPrintf(hTest, RTTESTLVL_ALWAYS, "Downloading '%s' -> '%s'\n", szURL, szDstFile); 358 RTTEST_CHECK_RC_OK(hTest, RTHttpGetFile(hClient, szURL, szDstFile)); 359 360 /* Compare files. */ 361 char szSrcFile[RTPATH_MAX]; 362 RTTEST_CHECK (hTest, RTStrPrintf(szSrcFile, sizeof(szSrcFile), szTempDir)); 363 RTTEST_CHECK_RC_OK(hTest, RTPathAppend(szSrcFile, sizeof(szSrcFile), g_aTests[i].pszFileName)); 364 RTTestPrintf(hTest, RTTESTLVL_ALWAYS, "Comparing files '%s' vs. '%s'\n", szSrcFile, szDstFile); 365 RTTEST_CHECK_RC_OK(hTest, RTFileCompare(szSrcFile, szDstFile)); 366 367 RTTEST_CHECK_RC_OK(hTest, RTFileDelete(szDstFile)); 368 } 369 370 RTTEST_CHECK_RC_OK(hTest, RTHttpDestroy(hClient)); 371 } 372 373 /* This is supposed to run unattended, so shutdown automatically. */ 374 ASMAtomicXchgBool(&g_fShutdown, true); /* Set shutdown indicator. */ 375 } 376 } 377 378 int rcThread; 379 RTTEST_CHECK_RC_OK(hTest, RTThreadWait(hThread, g_msRuntime, &rcThread)); 380 RTTEST_CHECK_RC_OK(hTest, rcThread); 381 382 RTTEST_CHECK_RC_OK(hTest, ShClTransferHttpServerDestroy(&HttpSrv)); 383 ShClTransferCtxDestroy(&TxCtx); 384 } 447 448 /* This is supposed to run unattended, so shutdown automatically. */ 449 ASMAtomicXchgBool(&g_fShutdown, true); /* Set shutdown indicator. */ 450 } 451 } 452 453 RTTEST_CHECK_RC_OK(hTest, ShClTransferHttpServerDestroy(&HttpSrv)); 454 ShClTransferCtxDestroy(&TxCtx); 385 455 386 456 /* … … 401 471 return RTTestSummaryAndDestroy(hTest); 402 472 } 403
Note:
See TracChangeset
for help on using the changeset viewer.