VirtualBox

Changeset 102830 in vbox for trunk


Ignore:
Timestamp:
Jan 11, 2024 8:45:36 AM (13 months ago)
Author:
vboxsync
Message:

Shared Clipboard/Transfers: Added building a separate X11 binary, so that the X-specific code also can be tested in combination with the transfer code. Only available in manual mode; see syntax help. bugref:9437

Location:
trunk/src/VBox/GuestHost/SharedClipboard/testcase
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/GuestHost/SharedClipboard/testcase/Makefile.kmk

    r100685 r102830  
    8383   tstClipboardHttpServer_DEFS    += VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS_HTTP
    8484  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
    85100 endif
    86101
  • trunk/src/VBox/GuestHost/SharedClipboard/testcase/tstClipboardHttpServer.cpp

    r102472 r102830  
    3333#include <iprt/message.h>
    3434#include <iprt/path.h>
     35#include <iprt/process.h>
    3536#include <iprt/rand.h>
     37#include <iprt/stream.h>
    3638#include <iprt/string.h>
    3739#include <iprt/test.h>
     40#include <iprt/utf16.h>
     41
     42#ifdef TESTCASE_WITH_X11
     43#include <VBox/GuestHost/SharedClipboard-x11.h>
     44#endif
    3845
    3946#include <VBox/GuestHost/SharedClipboard-transfers.h>
     
    4855/** Shutdown indicator. */
    4956static 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. */
    5158static 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
    5263
    5364/** Test files to handle + download.
     
    7687};
    7788
    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 }
    9689
    9790static void tstCreateTransferSingle(RTTEST hTest, PSHCLTRANSFERCTX pTransferCtx, PSHCLHTTPSERVER pSrv,
     
    107100}
    108101
     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 */
     107static 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
     165static 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
    109190int main(int argc, char *argv[])
    110191{
     
    116197    if (rcExit != RTEXITCODE_SUCCESS)
    117198        return rcExit;
    118     RTTestBanner(hTest);
    119199
    120200    /*
     
    123203    static const RTGETOPTDEF aOpts[] =
    124204    {
    125         { "--port",             'p',               RTGETOPT_REQ_UINT16 },
     205        { "--help",             'h',               RTGETOPT_REQ_NOTHING },
    126206        { "--manual",           'm',               RTGETOPT_REQ_NOTHING },
    127207        { "--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 }
    129211    };
    130212
     
    141223        switch (ch)
    142224        {
     225            case 'h':
     226                return tstUsage(g_pStdErr);
     227
    143228            case 'p':
    144229                uPort = ValueUnion.u16;
     
    157242                break;
    158243
     244#ifdef TESTCASE_WITH_X11
     245            case 'X':
     246                g_fX11 = true;
     247                break;
     248#endif
    159249            case VINF_GETOPT_NOT_OPTION:
    160250                continue;
     
    164254        }
    165255    }
     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
    166264
    167265    /*
     
    227325    RTTEST_CHECK(hTest, pszSrvAddr != NULL);
    228326    RTTestPrintf(hTest, RTTESTLVL_ALWAYS, "HTTP server running: %s (for %RU32ms) ...\n", pszSrvAddr, g_msRuntime);
    229     RTMemFree(pszSrvAddr);
     327    RTStrFree(pszSrvAddr);
    230328    pszSrvAddr = NULL;
    231329
     
    307405    if (RTTestErrorCount(hTest) == 0)
    308406    {
    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))
    323416            {
    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++)
    326419                {
    327420                    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));
    334443                }
     444
     445                RTTEST_CHECK_RC_OK(hTest, RTHttpDestroy(hClient));
    335446            }
    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);
    385455
    386456    /*
     
    401471    return RTTestSummaryAndDestroy(hTest);
    402472}
    403 
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