Changeset 97272 in vbox for trunk/src/VBox/HostServices
- Timestamp:
- Oct 24, 2022 7:56:53 AM (2 years ago)
- Location:
- trunk/src/VBox/HostServices/SharedClipboard/testcase
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostServices/SharedClipboard/testcase/Makefile.kmk
r96407 r97272 31 31 if defined(VBOX_WITH_TESTCASES) && !defined(VBOX_ONLY_ADDITIONS) && !defined(VBOX_ONLY_SDK) 32 32 33 if 0 34 # 35 # Testcase which mocks HGCM to also test the VbglR3-side of Shared Clipboard. 36 # 37 # Goal is to use and test as much guest side code as possible as a self-contained 38 # binary on the host here. 39 # 40 # Note: No #ifdef TESTCASE hacks or similar allowed, has to run 41 # without #ifdef modifications to the core code! 42 # 43 PROGRAMS += tstClipboardMockHGCM 44 tstClipboardMockHGCM_TEMPLATE = VBOXR3TSTEXE 45 tstClipboardMockHGCM_DEFS = VBOX_WITH_HGCM VBOX_WITH_SHARED_CLIPBOARD 46 tstClipboardMockHGCM_SOURCES = \ 47 ../VBoxSharedClipboardSvc.cpp \ 48 $(PATH_ROOT)/src/VBox/GuestHost/SharedClipboard/clipboard-common.cpp \ 49 $(PATH_ROOT)/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR3LibClipboard.cpp \ 50 $(PATH_ROOT)/src/VBox/HostServices/common/message.cpp \ 51 tstClipboardMockHGCM.cpp 52 tstClipboardMockHGCM_LIBS = $(LIB_RUNTIME) 33 # 34 # Testcase which mocks HGCM to also test the VbglR3-side of Shared Clipboard. 35 # 36 # Goal is to use and test as much guest side code as possible as a self-contained 37 # binary on the host here. 38 # 39 # Note: No #ifdef TESTCASE hacks or similar allowed, has to run 40 # without #ifdef modifications to the core code! 41 # 42 PROGRAMS.linux += tstClipboardMockHGCM 43 tstClipboardMockHGCM_TEMPLATE = VBOXR3TSTEXE 44 tstClipboardMockHGCM_DEFS = VBOX_WITH_HGCM VBOX_WITH_SHARED_CLIPBOARD 45 tstClipboardMockHGCM_SOURCES = \ 46 ../VBoxSharedClipboardSvc.cpp \ 47 $(PATH_ROOT)/src/VBox/GuestHost/SharedClipboard/clipboard-common.cpp \ 48 $(PATH_ROOT)/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR3LibClipboard.cpp \ 49 $(PATH_ROOT)/src/VBox/HostServices/common/message.cpp \ 50 tstClipboardMockHGCM.cpp 51 tstClipboardMockHGCM_LIBS = $(LIB_RUNTIME) 53 52 54 55 56 57 58 59 60 61 62 63 53 if1of ($(KBUILD_TARGET), linux) 54 tstClipboardMockHGCM_SOURCES.linux += \ 55 $(PATH_ROOT)/src/VBox/GuestHost/SharedClipboard/clipboard-x11.cpp \ 56 ../VBoxSharedClipboardSvc-x11.cpp 57 tstClipboardMockHGCM_LIBPATH = \ 58 $(VBOX_LIBPATH_X11) 59 tstClipboardMockHGCM_LIBS += \ 60 Xt \ 61 X11 62 endif 64 63 65 66 64 tstClipboardMockHGCM_SOURCES.darwin += ../VBoxSharedClipboardSvc-darwin.cpp 65 tstClipboardMockHGCM_SOURCES.win += ../VBoxSharedClipboardSvc-win.cpp 67 66 68 67 tstClipboardMockHGCM_CLEAN = $(tstClipboardMockHGCM_0_OUTDIR)/tstClipboardMockHGCM.run 69 68 70 if defined(VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS) 71 tstClipboardMockHGCM_DEFS += VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS 72 tstClipboardMockHGCM_SOURCES += \ 73 ../VBoxSharedClipboardSvc-transfers.cpp \ 74 $(PATH_ROOT)/src/VBox/GuestHost/SharedClipboard/clipboard-transfers.cpp 75 endif 76 endif 69 if defined(VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS) 70 tstClipboardMockHGCM_DEFS += VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS 71 tstClipboardMockHGCM_SOURCES += \ 72 ../VBoxSharedClipboardSvc-transfers.cpp \ 73 $(PATH_ROOT)/src/VBox/GuestHost/SharedClipboard/clipboard-transfers.cpp 74 endif 75 76 if 0 # Enable this if you want automatic runs after compilation. 77 $$(tstClipboardMockHGCM_0_OUTDIR)/tstClipboardMockHGCM.run: $$(tstClipboardMockHGCM_1_STAGE_TARGET) 78 export VBOX_LOG_DEST=nofile; $(tstClipboardMockHGCM_1_STAGE_TARGET) quiet 79 $(QUIET)$(APPEND) -t "$@" "done" 80 OTHERS += $(tstClipboardMockHGCM_0_OUTDIR)/tstClipboardMockHGCM.run 81 endif 77 82 78 83 # -
trunk/src/VBox/HostServices/SharedClipboard/testcase/tstClipboardMockHGCM.cpp
r96407 r97272 35 35 36 36 #include <VBox/GuestHost/HGCMMock.h> 37 #include <VBox/GuestHost/HGCMMockUtils.h> 37 38 38 39 #include <iprt/assert.h> … … 50 51 *********************************************************************************************************************************/ 51 52 static RTTEST g_hTest; 52 static SHCLCLIENT g_Client;53 53 54 54 … … 56 56 * Shared Clipboard testing * 57 57 *********************************************************************************************************************************/ 58 struct TESTDESC;58 struct CLIPBOARDTESTDESC; 59 59 /** Pointer to a test description. */ 60 typedef TESTDESC *PTESTDESC; 61 62 struct TESTPARMS; 63 /** Pointer to a test parameter structure. */ 64 typedef TESTPARMS *PTESTPARMS; 65 66 struct TESTCTX; 60 typedef CLIPBOARDTESTDESC *PTESTDESC; 61 62 struct CLIPBOARDTESTCTX; 67 63 /** Pointer to a test context. */ 68 typedef TESTCTX *PTESTCTX;64 typedef CLIPBOARDTESTCTX *PCLIPBOARDTESTCTX; 69 65 70 66 /** Pointer a test descriptor. */ 71 typedef TESTDESC *PTESTDESC;72 73 typedef DECLCALLBACKTYPE(int, FNTESTSETUP,(P TESTPARMS pTstParms, void **ppvCtx));74 /** Pointer to a ntest setup callback. */67 typedef CLIPBOARDTESTDESC *PTESTDESC; 68 69 typedef DECLCALLBACKTYPE(int, FNTESTSETUP,(PCLIPBOARDTESTCTX pTstCtx, void **ppvCtx)); 70 /** Pointer to a test setup callback. */ 75 71 typedef FNTESTSETUP *PFNTESTSETUP; 76 72 77 typedef DECLCALLBACKTYPE(int, FNTESTEXEC,(P TESTPARMS pTstParms, void *pvCtx));78 /** Pointer to a ntest exec callback. */73 typedef DECLCALLBACKTYPE(int, FNTESTEXEC,(PCLIPBOARDTESTCTX pTstCtx, void *pvCtx)); 74 /** Pointer to a test exec callback. */ 79 75 typedef FNTESTEXEC *PFNTESTEXEC; 80 76 81 typedef DECLCALLBACKTYPE(int, FNTESTGSTTHREAD,(PTESTCTX pCtx, void *pvCtx)); 82 /** Pointer to an test guest thread callback. */ 83 typedef FNTESTGSTTHREAD *PFNTESTGSTTHREAD; 84 85 typedef DECLCALLBACKTYPE(int, FNTESTDESTROY,(PTESTPARMS pTstParms, void *pvCtx)); 86 /** Pointer to an test destroy callback. */ 77 typedef DECLCALLBACKTYPE(int, FNTESTDESTROY,(PCLIPBOARDTESTCTX pTstCtx, void *pvCtx)); 78 /** Pointer to a test destroy callback. */ 87 79 typedef FNTESTDESTROY *PFNTESTDESTROY; 88 80 89 typedef struct TESTTASK 90 { 91 RTSEMEVENT hEvent; 92 int rcCompleted; 93 int rcExpected; 81 82 /** 83 * Structure for keeping a clipboard test task. 84 */ 85 typedef struct CLIPBOARDTESTTASK 86 { 94 87 SHCLFORMATS enmFmtHst; 95 88 SHCLFORMATS enmFmtGst; 96 /** For chunked reads / writes. */89 /** For testing chunked reads / writes. */ 97 90 size_t cbChunk; 91 /** Data buffer to read / write for this task. 92 * Can be NULL if not needed. */ 93 void *pvData; 94 /** Size (in bytes) of \a pvData. */ 98 95 size_t cbData; 99 void *pvData; 100 } TESTTASK; 101 typedef TESTTASK *PTESTTASK; 96 /** Number of bytes read / written from / to \a pvData. */ 97 size_t cbProcessed; 98 } CLIPBOARDTESTTASK; 99 typedef CLIPBOARDTESTTASK *PCLIPBOARDTESTTASK; 102 100 103 101 /** 104 * Structure for keeping a test context.102 * Structure for keeping a clipboard test context. 105 103 */ 106 typedef struct TESTCTX 107 { 108 PTSTHGCMMOCKSVC pSvc; 109 /** Currently we only support one task at a time. */ 110 TESTTASK Task; 111 struct 112 { 113 RTTHREAD hThread; 114 VBGLR3SHCLCMDCTX CmdCtx; 115 volatile bool fShutdown; 116 PFNTESTGSTTHREAD pfnThread; 117 } Guest; 118 struct 119 { 120 RTTHREAD hThread; 121 volatile bool fShutdown; 122 } Host; 123 } TESTCTX; 124 125 /** The one and only test context. */ 126 TESTCTX g_TstCtx; 104 typedef struct CLIPBOARDTESTCTX 105 { 106 /** The HGCM Mock utils context. */ 107 TSTHGCMUTILSCTX HGCM; 108 /** Clipboard-specific task data. */ 109 CLIPBOARDTESTTASK Task; 110 } CLIPBOARDTESTCTX; 111 112 /** The one and only clipboard test context. One at a time. */ 113 CLIPBOARDTESTCTX g_TstCtx; 127 114 128 115 /** 129 * Test parameters.116 * Structure for keeping a clipboard test description. 130 117 */ 131 typedef struct TESTPARMS 132 { 133 /** Pointer to test context to use. */ 134 PTESTCTX pTstCtx; 135 } TESTPARMS; 136 137 typedef struct TESTDESC 118 typedef struct CLIPBOARDTESTDESC 138 119 { 139 120 /** The setup callback. */ … … 143 124 /** The destruction callback. */ 144 125 PFNTESTDESTROY pfnDestroy; 145 } TESTDESC;126 } CLIPBOARDTESTDESC; 146 127 147 128 typedef struct SHCLCONTEXT … … 150 131 151 132 152 #if 0 153 static void tstBackendWriteData(HGCMCLIENTID idClient, SHCLFORMAT uFormat, void *pvData, size_t cbData) 154 { 155 ShClBackendSetClipboardData(&s_tstHgcmClient[idClient].Client, uFormat, pvData, cbData); 156 } 157 158 /** Adds a host data read request message to the client's message queue. */ 159 static int tstSvcMockRequestDataFromGuest(uint32_t idClient, SHCLFORMATS fFormats, PSHCLEVENT *ppEvent) 160 { 161 AssertPtrReturn(ppEvent, VERR_INVALID_POINTER); 162 163 int rc = ShClSvcGuestDataRequest(&s_tstHgcmClient[idClient].Client, fFormats, ppEvent); 164 RTTESTI_CHECK_RC_OK_RET(rc, rc); 165 166 return rc; 167 } 168 #endif 169 170 static int tstSetModeRc(PTSTHGCMMOCKSVC pSvc, uint32_t uMode, int rc) 133 static int tstSetModeRc(PTSTHGCMMOCKSVC pSvc, uint32_t uMode, int rcExpected) 171 134 { 172 135 VBOXHGCMSVCPARM aParms[2]; 173 136 HGCMSvcSetU32(&aParms[0], uMode); 174 137 int rc2 = TstHgcmMockSvcHostCall(pSvc, NULL, VBOX_SHCL_HOST_FN_SET_MODE, 1, aParms); 175 RTTESTI_CHECK_MSG_RET(rc == rc2, ("Expected %Rrc, got %Rrc\n", rc, rc2), rc2); 176 uint32_t const uModeRet = ShClSvcGetMode(); 177 RTTESTI_CHECK_MSG_RET(uMode == uModeRet, ("Expected mode %RU32, got %RU32\n", uMode, uModeRet), VERR_WRONG_TYPE); 138 RTTESTI_CHECK_MSG_RET(rcExpected == rc2, ("Expected %Rrc, got %Rrc\n", rcExpected, rc2), rc2); 139 if (RT_SUCCESS(rcExpected)) 140 { 141 uint32_t const uModeRet = ShClSvcGetMode(); 142 RTTESTI_CHECK_MSG_RET(uMode == uModeRet, ("Expected mode %RU32, got %RU32\n", uMode, uModeRet), VERR_WRONG_TYPE); 143 } 178 144 return rc2; 179 145 } 180 146 181 static int tst SetMode(PTSTHGCMMOCKSVC pSvc, uint32_t uMode)147 static int tstClipboardSetMode(PTSTHGCMMOCKSVC pSvc, uint32_t uMode) 182 148 { 183 149 return tstSetModeRc(pSvc, uMode, VINF_SUCCESS); 184 150 } 185 151 186 static bool tst GetMode(PTSTHGCMMOCKSVC pSvc, uint32_t uModeExpected)152 static bool tstClipboardGetMode(PTSTHGCMMOCKSVC pSvc, uint32_t uModeExpected) 187 153 { 188 154 RT_NOREF(pSvc); … … 218 184 RTTESTI_CHECK_RC(rc, VERR_INVALID_PARAMETER); 219 185 220 tst SetMode(pSvc, VBOX_SHCL_MODE_HOST_TO_GUEST);186 tstClipboardSetMode(pSvc, VBOX_SHCL_MODE_HOST_TO_GUEST); 221 187 tstSetModeRc(pSvc, 99, VERR_NOT_SUPPORTED); 222 tst GetMode(pSvc, VBOX_SHCL_MODE_OFF);188 tstClipboardGetMode(pSvc, VBOX_SHCL_MODE_OFF); 223 189 } 224 190 … … 252 218 } 253 219 #endif /* VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS */ 254 255 /* Does testing of VBOX_SHCL_GUEST_FN_MSG_OLD_GET_WAIT, needed for providing compatibility to older Guest Additions clients. */256 static void testHostGetMsgOld(void)257 {258 RTTestISub("Setting up VBOX_SHCL_GUEST_FN_MSG_OLD_GET_WAIT test");259 260 PTSTHGCMMOCKSVC pSvc = TstHgcmMockSvcInst();261 262 VBOXHGCMSVCPARM parms[2];263 RT_ZERO(parms);264 265 /* Unless we are bidirectional the host message requests will be dropped. */266 HGCMSvcSetU32(&parms[0], VBOX_SHCL_MODE_BIDIRECTIONAL);267 int rc = pSvc->fnTable.pfnHostCall(NULL, VBOX_SHCL_HOST_FN_SET_MODE, 1, parms);268 RTTESTI_CHECK_RC_OK(rc);269 270 RTTestISub("Testing one format, waiting guest u.Call.");271 RT_ZERO(g_Client);272 VBOXHGCMCALLHANDLE_TYPEDEF call;273 rc = VERR_IPE_UNINITIALIZED_STATUS;274 pSvc->fnTable.pfnConnect(NULL, 1 /* clientId */, &g_Client, 0, 0);275 276 HGCMSvcSetU32(&parms[0], 0);277 HGCMSvcSetU32(&parms[1], 0);278 pSvc->fnTable.pfnCall(NULL, &call, 1 /* clientId */, &g_Client, VBOX_SHCL_GUEST_FN_MSG_OLD_GET_WAIT, 2, parms, 0);279 RTTESTI_CHECK_RC_OK(rc);280 281 //testMsgAddReadData(&g_Client, VBOX_SHCL_FMT_UNICODETEXT);282 RTTESTI_CHECK(parms[0].u.uint32 == VBOX_SHCL_HOST_MSG_READ_DATA);283 RTTESTI_CHECK(parms[1].u.uint32 == VBOX_SHCL_FMT_UNICODETEXT);284 #if 0285 RTTESTI_CHECK_RC_OK(u.Call.rc);286 u.Call.rc = VERR_IPE_UNINITIALIZED_STATUS;287 s_tstHgcmSrv.fnTable.pfnCall(NULL, &call, 1 /* clientId */, &g_Client, VBOX_SHCL_GUEST_FN_MSG_OLD_GET_WAIT, 2, parms, 0);288 RTTESTI_CHECK_RC(u.Call.rc, VINF_SUCCESS);289 s_tstHgcmSrv.fnTable.pfnDisconnect(NULL, 1 /* clientId */, &g_Client);290 291 RTTestISub("Testing one format, no waiting guest calls.");292 RT_ZERO(g_Client);293 s_tstHgcmSrv.fnTable.pfnConnect(NULL, 1 /* clientId */, &g_Client, 0, 0);294 testMsgAddReadData(&g_Client, VBOX_SHCL_FMT_HTML);295 HGCMSvcSetU32(&parms[0], 0);296 HGCMSvcSetU32(&parms[1], 0);297 u.Call.rc = VERR_IPE_UNINITIALIZED_STATUS;298 s_tstHgcmSrv.fnTable.pfnCall(NULL, &call, 1 /* clientId */, &g_Client, VBOX_SHCL_GUEST_FN_MSG_OLD_GET_WAIT, 2, parms, 0);299 RTTESTI_CHECK(parms[0].u.uint32 == VBOX_SHCL_HOST_MSG_READ_DATA);300 RTTESTI_CHECK(parms[1].u.uint32 == VBOX_SHCL_FMT_HTML);301 RTTESTI_CHECK_RC_OK(u.Call.rc);302 u.Call.rc = VERR_IPE_UNINITIALIZED_STATUS;303 s_tstHgcmSrv.fnTable.pfnCall(NULL, &call, 1 /* clientId */, &g_Client, VBOX_SHCL_GUEST_FN_MSG_OLD_GET_WAIT, 2, parms, 0);304 RTTESTI_CHECK_RC(u.Call.rc, VINF_SUCCESS);305 s_tstHgcmSrv.fnTable.pfnDisconnect(NULL, 1 /* clientId */, &g_Client);306 307 RTTestISub("Testing two formats, waiting guest u.Call.");308 RT_ZERO(g_Client);309 s_tstHgcmSrv.fnTable.pfnConnect(NULL, 1 /* clientId */, &g_Client, 0, 0);310 HGCMSvcSetU32(&parms[0], 0);311 HGCMSvcSetU32(&parms[1], 0);312 u.Call.rc = VERR_IPE_UNINITIALIZED_STATUS;313 s_tstHgcmSrv.fnTable.pfnCall(NULL, &call, 1 /* clientId */, &g_Client, VBOX_SHCL_GUEST_FN_MSG_OLD_GET_WAIT, 2, parms, 0);314 RTTESTI_CHECK_RC(u.Call.rc, VERR_IPE_UNINITIALIZED_STATUS); /* This should get updated only when the guest call completes. */315 testMsgAddReadData(&g_Client, VBOX_SHCL_FMT_UNICODETEXT | VBOX_SHCL_FMT_HTML);316 RTTESTI_CHECK(parms[0].u.uint32 == VBOX_SHCL_HOST_MSG_READ_DATA);317 RTTESTI_CHECK(parms[1].u.uint32 == VBOX_SHCL_FMT_UNICODETEXT);318 RTTESTI_CHECK_RC_OK(u.Call.rc);319 u.Call.rc = VERR_IPE_UNINITIALIZED_STATUS;320 s_tstHgcmSrv.fnTable.pfnCall(NULL, &call, 1 /* clientId */, &g_Client, VBOX_SHCL_GUEST_FN_MSG_OLD_GET_WAIT, 2, parms, 0);321 RTTESTI_CHECK(parms[0].u.uint32 == VBOX_SHCL_HOST_MSG_READ_DATA);322 RTTESTI_CHECK(parms[1].u.uint32 == VBOX_SHCL_FMT_HTML);323 RTTESTI_CHECK_RC_OK(u.Call.rc);324 u.Call.rc = VERR_IPE_UNINITIALIZED_STATUS;325 s_tstHgcmSrv.fnTable.pfnCall(NULL, &call, 1 /* clientId */, &g_Client, VBOX_SHCL_GUEST_FN_MSG_OLD_GET_WAIT, 2, parms, 0);326 RTTESTI_CHECK_RC(u.Call.rc, VERR_IPE_UNINITIALIZED_STATUS); /* This call should not complete yet. */327 s_tstHgcmSrv.fnTable.pfnDisconnect(NULL, 1 /* clientId */, &g_Client);328 329 RTTestISub("Testing two formats, no waiting guest calls.");330 RT_ZERO(g_Client);331 s_tstHgcmSrv.fnTable.pfnConnect(NULL, 1 /* clientId */, &g_Client, 0, 0);332 testMsgAddReadData(&g_Client, VBOX_SHCL_FMT_UNICODETEXT | VBOX_SHCL_FMT_HTML);333 HGCMSvcSetU32(&parms[0], 0);334 HGCMSvcSetU32(&parms[1], 0);335 u.Call.rc = VERR_IPE_UNINITIALIZED_STATUS;336 s_tstHgcmSrv.fnTable.pfnCall(NULL, &call, 1 /* clientId */, &g_Client, VBOX_SHCL_GUEST_FN_MSG_OLD_GET_WAIT, 2, parms, 0);337 RTTESTI_CHECK(parms[0].u.uint32 == VBOX_SHCL_HOST_MSG_READ_DATA);338 RTTESTI_CHECK(parms[1].u.uint32 == VBOX_SHCL_FMT_UNICODETEXT);339 RTTESTI_CHECK_RC_OK(u.Call.rc);340 u.Call.rc = VERR_IPE_UNINITIALIZED_STATUS;341 s_tstHgcmSrv.fnTable.pfnCall(NULL, &call, 1 /* clientId */, &g_Client, VBOX_SHCL_GUEST_FN_MSG_OLD_GET_WAIT, 2, parms, 0);342 RTTESTI_CHECK(parms[0].u.uint32 == VBOX_SHCL_HOST_MSG_READ_DATA);343 RTTESTI_CHECK(parms[1].u.uint32 == VBOX_SHCL_FMT_HTML);344 RTTESTI_CHECK_RC_OK(u.Call.rc);345 u.Call.rc = VERR_IPE_UNINITIALIZED_STATUS;346 s_tstHgcmSrv.fnTable.pfnCall(NULL, &call, 1 /* clientId */, &g_Client, VBOX_SHCL_GUEST_FN_MSG_OLD_GET_WAIT, 2, parms, 0);347 RTTESTI_CHECK_RC(u.Call.rc, VERR_IPE_UNINITIALIZED_STATUS); /* This call should not complete yet. */348 #endif349 pSvc->fnTable.pfnDisconnect(NULL, 1 /* clientId */, &g_Client);350 }351 220 352 221 static void testGuestSimple(void) … … 400 269 * Access allowed tests. 401 270 */ 402 tst SetMode(pSvc, VBOX_SHCL_MODE_BIDIRECTIONAL);271 tstClipboardSetMode(pSvc, VBOX_SHCL_MODE_BIDIRECTIONAL); 403 272 404 273 /* Try writing data without reporting formats before. */ … … 416 285 } 417 286 418 static void testGuestWrite(void) 419 { 420 RTTestISub("Testing client (guest) API - Writing"); 421 } 422 423 #if 0 424 /** 425 * Generate a random codepoint for simple UTF-16 encoding. 426 */ 287 static RTUTF16 tstGetRandUtf8(void) 288 { 289 return RTRandU32Ex(0x20, 0x7A); 290 } 291 292 static char *tstGenerateUtf8StringA(uint32_t uCch) 293 { 294 char * pszRand = (char *)RTMemAlloc(uCch + 1); 295 for (uint32_t i = 0; i < uCch; i++) 296 pszRand[i] = tstGetRandUtf8(); 297 pszRand[uCch] = 0; 298 return pszRand; 299 } 300 301 #if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2) 427 302 static RTUTF16 tstGetRandUtf16(void) 428 303 { … … 443 318 return pwszRand; 444 319 } 445 #endif 446 447 #if 0 448 static void testGuestRead(void) 449 { 450 RTTestISub("Testing client (guest) API - Reading"); 451 452 /* Preparations. */ 453 tstSetMode(VBOX_SHCL_MODE_BIDIRECTIONAL); 454 455 VBGLR3SHCLCMDCTX Ctx; 456 RTTESTI_CHECK_RC_OK(VbglR3ClipboardConnectEx(&Ctx, VBOX_SHCL_GF_0_CONTEXT_ID)); 457 RTThreadSleep(500); /** @todo BUGBUG -- Seems to be a startup race when querying the initial clipboard formats. */ 458 459 uint8_t abData[_4K]; uint32_t cbData; uint32_t cbRead; 460 461 /* Issue a host request that we want to read clipboard data from the guest. */ 462 PSHCLEVENT pEvent; 463 tstSvcMockRequestDataFromGuest(Ctx.idClient, VBOX_SHCL_FMT_UNICODETEXT, &pEvent); 464 465 /* Write guest clipboard data to the host side. */ 466 RTTESTI_CHECK_RC_OK(VbglR3ClipboardReportFormats(Ctx.idClient, VBOX_SHCL_FMT_UNICODETEXT)); 467 cbData = RTRandU32Ex(1, sizeof(abData)); 468 PRTUTF16 pwszStr = tstGenerateUtf16String(cbData); 469 RTTESTI_CHECK_RC_OK(VbglR3ClipboardWriteDataEx(&Ctx, VBOX_SHCL_FMT_UNICODETEXT, pwszStr, cbData)); 470 RTMemFree(pwszStr); 471 472 PSHCLEVENTPAYLOAD pPayload; 473 int rc = ShClEventWait(pEvent, RT_MS_30SEC, &pPayload); 474 if (RT_SUCCESS(rc)) 475 { 476 477 } 478 ShClEventRelease(pEvent); 479 pEvent = NULL; 480 481 482 /* Read clipboard data from the host back to the guest side. */ 483 /* Note: Also could return VINF_BUFFER_OVERFLOW, so check for VINF_SUCCESS explicitly here. */ 484 RTTESTI_CHECK_RC(VbglR3ClipboardReadDataEx(&Ctx, VBOX_SHCL_FMT_UNICODETEXT, 485 abData, sizeof(abData), &cbRead), VINF_SUCCESS); 486 RTTESTI_CHECK(cbRead == cbData); 487 488 RTPrintf("Data (%RU32): %ls\n", cbRead, (PCRTUTF16)abData); 489 490 /* Tear down. */ 491 RTTESTI_CHECK_RC_OK(VbglR3ClipboardDisconnectEx(&Ctx)); 492 } 493 #endif 494 495 static DECLCALLBACK(int) tstGuestThread(RTTHREAD hThread, void *pvUser) 496 { 497 RT_NOREF(hThread); 498 PTESTCTX pCtx = (PTESTCTX)pvUser; 499 AssertPtr(pCtx); 500 501 RTThreadUserSignal(hThread); 502 503 if (pCtx->Guest.pfnThread) 504 return pCtx->Guest.pfnThread(pCtx, NULL); 505 506 return VINF_SUCCESS; 507 } 508 509 static DECLCALLBACK(int) tstHostThread(RTTHREAD hThread, void *pvUser) 510 { 511 RT_NOREF(hThread); 512 PTESTCTX pCtx = (PTESTCTX)pvUser; 513 AssertPtr(pCtx); 514 515 int rc = VINF_SUCCESS; 516 517 RTThreadUserSignal(hThread); 518 519 for (;;) 520 { 521 RTThreadSleep(100); 522 523 if (ASMAtomicReadBool(&pCtx->Host.fShutdown)) 524 break; 525 } 526 527 return rc; 528 } 320 #endif /* RT_OS_WINDOWS) || RT_OS_OS2 */ 529 321 530 322 static void testSetHeadless(void) … … 568 360 } 569 361 570 static int tstGuestStart(PTESTCTX pTstCtx, PFNTESTGSTTHREAD pFnThread) 571 { 572 pTstCtx->Guest.pfnThread = pFnThread; 573 574 int rc = RTThreadCreate(&pTstCtx->Guest.hThread, tstGuestThread, pTstCtx, 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, 575 "tstShClGst"); 576 if (RT_SUCCESS(rc)) 577 rc = RTThreadUserWait(pTstCtx->Guest.hThread, RT_MS_30SEC); 578 579 return rc; 580 } 581 582 static int tstGuestStop(PTESTCTX pTstCtx) 583 { 584 ASMAtomicWriteBool(&pTstCtx->Guest.fShutdown, true); 585 586 int rcThread; 587 int rc = RTThreadWait(pTstCtx->Guest.hThread, RT_MS_30SEC, &rcThread); 588 if (RT_SUCCESS(rc)) 589 rc = rcThread; 590 if (RT_FAILURE(rc)) 591 RTTestFailed(g_hTest, "Shutting down guest thread failed with %Rrc\n", rc); 592 593 pTstCtx->Guest.hThread = NIL_RTTHREAD; 594 595 return rc; 596 } 597 598 static int tstHostStart(PTESTCTX pTstCtx) 599 { 600 int rc = RTThreadCreate(&pTstCtx->Host.hThread, tstHostThread, pTstCtx, 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, 601 "tstShClHst"); 602 if (RT_SUCCESS(rc)) 603 rc = RTThreadUserWait(pTstCtx->Host.hThread, RT_MS_30SEC); 604 605 return rc; 606 } 607 608 static int tstHostStop(PTESTCTX pTstCtx) 609 { 610 ASMAtomicWriteBool(&pTstCtx->Host.fShutdown, true); 611 612 int rcThread; 613 int rc = RTThreadWait(pTstCtx->Host.hThread, RT_MS_30SEC, &rcThread); 614 if (RT_SUCCESS(rc)) 615 rc = rcThread; 616 if (RT_FAILURE(rc)) 617 RTTestFailed(g_hTest, "Shutting down host thread failed with %Rrc\n", rc); 618 619 pTstCtx->Host.hThread = NIL_RTTHREAD; 620 621 return rc; 622 } 623 362 363 /********************************************************************************************************************************* 364 * Test: Guest reading from host * 365 ********************************************************************************************************************************/ 624 366 #if defined(RT_OS_LINUX) 625 static DECLCALLBACK(int) tstShClUserMockReportFormatsCallback(PSHCLCONTEXT pCtx, uint32_t fFormats, void *pvUser) 367 /* Called from SHCLX11 thread. */ 368 static DECLCALLBACK(int) tstTestReadFromHost_ReportFormatsCallback(PSHCLCONTEXT pCtx, uint32_t fFormats, void *pvUser) 626 369 { 627 370 RT_NOREF(pCtx, fFormats, pvUser); 628 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "tstShClUserMockReportFormatsCallback: fFormats=%#x\n", fFormats); 371 372 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "tstTestReadFromHost_SvcReportFormatsCallback: fFormats=%#x\n", fFormats); 629 373 return VINF_SUCCESS; 630 374 } 631 375 632 /* 633 static DECLCALLBACK(int) tstTestReadFromHost_RequestDataFromSourceCallback(PSHCLCONTEXT pCtx, SHCLFORMAT uFmt, void **ppv, uint32_t *pcb, void *pvUser) 634 { 635 RT_NOREF(pCtx, uFmt, ppv, pvUser); 636 637 PTESTTASK pTask = &TaskRead; 638 639 uint8_t *pvData = (uint8_t *)RTMemDup(pTask->pvData, pTask->cbData); 640 641 *ppv = pvData; 642 *pcb = pTask->cbData; 643 644 return VINF_SUCCESS; 645 } 646 */ 647 648 #if 0 649 static DECLCALLBACK(int) tstShClUserMockSendDataCallback(PSHCLCONTEXT pCtx, void *pv, uint32_t cb, void *pvUser) 650 { 651 RT_NOREF(pCtx, pv, cb, pvUser); 652 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "tstShClUserMockSendDataCallback\n"); 653 654 PTESTTASK pTask = &TaskRead; 655 656 memcpy(pv, pTask->pvData, RT_MIN(pTask->cbData, cb)); 657 658 return VINF_SUCCESS; 659 } 660 #endif 661 662 static DECLCALLBACK(int) tstShClUserMockOnGetDataCallback(PSHCLCONTEXT pCtx, SHCLFORMAT uFmt, void **ppv, size_t *pcb, void *pvUser) 376 /* Called by the backend, e.g. for X11 in the SHCLX11 thread. */ 377 static DECLCALLBACK(int) tstTestReadFromHost_OnClipboardReadCallback(PSHCLCONTEXT pCtx, 378 SHCLFORMAT uFmt, void **ppv, size_t *pcb, void *pvUser) 663 379 { 664 380 RT_NOREF(pCtx, uFmt, pvUser); 665 381 666 PTESTTASK pTask = &g_TstCtx.Task; 667 668 uint8_t *pvData = pTask->cbData ? (uint8_t *)RTMemDup(pTask->pvData, pTask->cbData) : NULL; 669 size_t cbData = pTask->cbData; 382 PCLIPBOARDTESTTASK pTask = (PCLIPBOARDTESTTASK)TstHGCMUtilsTaskGetCurrent(&g_TstCtx.HGCM)->pvUser; 383 384 void *pvData = NULL; 385 size_t cbData = pTask->cbData - pTask->cbProcessed; 386 if (cbData) 387 { 388 pvData = RTMemDup((uint8_t *)pTask->pvData + pTask->cbProcessed, cbData); 389 AssertPtr(pvData); 390 } 391 392 RTTestPrintf(g_hTest, RTTESTLVL_DEBUG, "Host reporting back %RU32 bytes of data\n", cbData); 670 393 671 394 *ppv = pvData; … … 685 408 typedef TSTUSERMOCK *PTSTUSERMOCK; 686 409 687 static void tst ShClUserMockInit(PTSTUSERMOCK pUsrMock, const char *pszName)410 static void tstTestReadFromHost_MockInit(PTSTUSERMOCK pUsrMock, const char *pszName) 688 411 { 689 412 #if defined(RT_OS_LINUX) 690 413 SHCLCALLBACKS Callbacks; 691 414 RT_ZERO(Callbacks); 692 Callbacks.pfnReportFormats = tst ShClUserMockReportFormatsCallback;693 Callbacks.pfnOnClipboardRead = tst ShClUserMockOnGetDataCallback;415 Callbacks.pfnReportFormats = tstTestReadFromHost_ReportFormatsCallback; 416 Callbacks.pfnOnClipboardRead = tstTestReadFromHost_OnClipboardReadCallback; 694 417 695 418 pUsrMock->pCtx = (PSHCLCONTEXT)RTMemAllocZ(sizeof(SHCLCONTEXT)); … … 701 424 RTThreadSleep(500); 702 425 #else 703 RT_NOREF(pUsrMock );426 RT_NOREF(pUsrMock, pszName); 704 427 #endif /* RT_OS_LINUX */ 705 428 } 706 429 707 static void tst ShClUserMockDestroy(PTSTUSERMOCK pUsrMock)430 static void tstTestReadFromHost_MockDestroy(PTSTUSERMOCK pUsrMock) 708 431 { 709 432 #if defined(RT_OS_LINUX) … … 716 439 } 717 440 718 static int tstTaskGuestRead(PTESTCTX pCtx, PTESTTASK pTask) 719 { 720 size_t cbReadTotal = 0; 721 size_t cbToRead = pTask->cbData; 722 441 static int tstTestReadFromHost_DoIt(PCLIPBOARDTESTCTX pCtx, PCLIPBOARDTESTTASK pTask) 442 { 443 size_t cbDst = RT_MAX(_64K, pTask->cbData); 444 uint8_t *pabDst = (uint8_t *)RTMemAllocZ(cbDst); 445 AssertPtrReturn(pabDst, VERR_NO_MEMORY); 446 447 AssertPtr(pTask->pvData); /* Racing condition with host thread? */ 448 Assert(pTask->cbChunk); /* Buggy test? */ 449 Assert(pTask->cbChunk <= pTask->cbData); /* Ditto. */ 450 451 size_t cbToRead = pTask->cbData; 723 452 switch (pTask->enmFmtGst) 724 453 { … … 731 460 } 732 461 733 size_t cbDst = _64K; 734 uint8_t *pabDst = (uint8_t *)RTMemAllocZ(cbDst); 735 AssertPtrReturn(pabDst, VERR_NO_MEMORY); 736 737 Assert(pTask->cbChunk); /* Buggy test? */ 738 Assert(pTask->cbChunk <= pTask->cbData); /* Ditto. */ 739 740 uint8_t *pabSrc = (uint8_t *)pTask->pvData; 741 742 do 462 PVBGLR3SHCLCMDCTX pCmdCtx = &pCtx->HGCM.Guest.CmdCtx; 463 464 /* Do random chunked reads. */ 465 uint32_t const cChunkedReads = RTRandU32Ex(1, 16); 466 RTTestPrintf(g_hTest, RTTESTLVL_DEBUG, "%RU32 chunked reads\n", cChunkedReads); 467 for (uint32_t i = 0; i < cChunkedReads; i++) 743 468 { 744 469 /* Note! VbglR3ClipboardReadData() currently does not support chunked reads! 745 470 * It in turn returns VINF_BUFFER_OVERFLOW when the supplied buffer was too small. */ 746 uint32_t const cbChunk = cbDst; 747 uint32_t const cbExpected = cbToRead; 748 749 uint32_t cbRead = 0; 750 RTTEST_CHECK_RC(g_hTest, VbglR3ClipboardReadData(pCtx->Guest.CmdCtx.idClient, 751 pTask->enmFmtGst, pabDst, cbChunk, &cbRead), pTask->rcExpected); 752 RTTEST_CHECK_MSG(g_hTest, cbRead == cbExpected, (g_hTest, "Read %RU32 bytes, expected %RU32\n", cbRead, cbExpected)); 753 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Guest side received %RU32 bytes\n", cbRead); 754 cbReadTotal += cbRead; 755 Assert(cbReadTotal <= cbToRead); 756 757 } while (cbReadTotal < cbToRead); 471 472 uint32_t cbChunk = RTRandU32Ex(1, pTask->cbData / cChunkedReads); 473 uint32_t cbRead = 0; 474 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Guest trying to read %RU32 bytes\n", cbChunk); 475 int vrc2 = VbglR3ClipboardReadData(pCmdCtx->idClient, pTask->enmFmtGst, pabDst, cbChunk, &cbRead); 476 if ( vrc2 == VINF_SUCCESS 477 && cbRead == 0) /* No data there yet? */ 478 { 479 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "No data (yet) from host\n"); 480 RTThreadSleep(10); 481 continue; 482 } 483 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Trying reading host clipboard data with a %RU32 buffer -> %Rrc (%RU32)\n", cbChunk, vrc2, cbRead); 484 RTTEST_CHECK_MSG(g_hTest, vrc2 == VINF_BUFFER_OVERFLOW, (g_hTest, "Got %Rrc, expected VINF_BUFFER_OVERFLOW\n", vrc2)); 485 } 486 487 /* Last read: Read the data with a buffer big enough. This must succeed. */ 488 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Reading full data (%zu)\n", pTask->cbData); 489 uint32_t cbRead = 0; 490 int vrc2 = VbglR3ClipboardReadData(pCmdCtx->idClient, pTask->enmFmtGst, pabDst, cbDst, &cbRead); 491 RTTEST_CHECK_MSG(g_hTest, vrc2 == VINF_SUCCESS, (g_hTest, "Got %Rrc, expected VINF_SUCCESS\n", vrc2)); 492 RTTEST_CHECK_MSG(g_hTest, cbRead == cbToRead, (g_hTest, "Read %RU32 bytes, expected %zu\n", cbRead, cbToRead)); 758 493 759 494 if (pTask->enmFmtGst == VBOX_SHCL_FMT_UNICODETEXT) 495 RTTEST_CHECK_MSG(g_hTest, RTUtf16ValidateEncoding((PRTUTF16)pabDst) == VINF_SUCCESS, (g_hTest, "Read data is not valid UTF-16\n")); 496 if (cbRead == cbToRead) 760 497 { 761 RTTEST_CHECK_RC_OK(g_hTest, RTUtf16ValidateEncoding((PRTUTF16)pabDst)); 498 PRTUTF16 pwszSrc; 499 RTTEST_CHECK(g_hTest, RT_SUCCESS(RTStrToUtf16((const char *)pTask->pvData, &pwszSrc))); 500 RTTEST_CHECK_MSG(g_hTest, memcmp(pwszSrc, pabDst, cbRead) == 0, (g_hTest, "Read data does not match host data\n")); 501 RTUtf16Free(pwszSrc); 762 502 } 763 else 764 RTTEST_CHECK(g_hTest, memcmp(pabSrc, pabDst, RT_MIN(pTask->cbData, cbDst) == 0));503 504 RTTestPrintf(g_hTest, RTTESTLVL_DEBUG, "Read data from host:\n%.*Rhxd\n", cbRead, pabDst); 765 505 766 506 RTMemFree(pabDst); … … 769 509 } 770 510 771 static void tstTaskInit(PTESTTASK pTask) 772 { 773 RTSemEventCreate(&pTask->hEvent); 774 } 775 776 static void tstTaskDestroy(PTESTTASK pTask) 777 { 778 RTSemEventDestroy(pTask->hEvent); 779 } 780 781 static void tstTaskWait(PTESTTASK pTask, RTMSINTERVAL msTimeout) 782 { 783 RTTEST_CHECK_RC_OK(g_hTest, RTSemEventWait(pTask->hEvent, msTimeout)); 784 RTTEST_CHECK_RC(g_hTest, pTask->rcCompleted, pTask->rcExpected); 785 } 786 787 static void tstTaskSignal(PTESTTASK pTask, int rc) 788 { 789 pTask->rcCompleted = rc; 790 RTTEST_CHECK_RC_OK(g_hTest, RTSemEventSignal(pTask->hEvent)); 791 } 792 793 static DECLCALLBACK(int) tstTestReadFromHostThreadGuest(PTESTCTX pCtx, void *pvCtx) 794 { 795 RT_NOREF(pvCtx); 796 797 RTThreadSleep(5000); 798 RT_BREAKPOINT(); 511 static DECLCALLBACK(int) tstTestReadFromHost_ThreadGuest(PTSTHGCMUTILSCTX pCtx, void *pvCtx) 512 { 513 RTThreadSleep(1000); /* Fudge; wait until the host has prepared the data for the clipboard. */ 799 514 800 515 RT_ZERO(pCtx->Guest.CmdCtx); 801 516 RTTEST_CHECK_RC_OK(g_hTest, VbglR3ClipboardConnectEx(&pCtx->Guest.CmdCtx, VBOX_SHCL_GF_0_CONTEXT_ID)); 802 517 803 #if 1 804 PTESTTASK pTask = &pCtx->Task; 805 tstTaskGuestRead(pCtx, pTask); 806 tstTaskSignal(pTask, VINF_SUCCESS); 518 RTThreadSleep(1000); /* Fudge; wait until the host has prepared the data for the clipboard. */ 519 520 PCLIPBOARDTESTCTX pTstCtx = (PCLIPBOARDTESTCTX)pvCtx; 521 AssertPtr(pTstCtx); 522 PCLIPBOARDTESTTASK pTstTask = (PCLIPBOARDTESTTASK)pCtx->Task.pvUser; 523 AssertPtr(pTstTask); 524 tstTestReadFromHost_DoIt(pTstCtx, pTstTask); 525 526 /* Signal that the task ended. */ 527 TstHGCMUtilsTaskSignal(&pCtx->Task, VINF_SUCCESS); 528 529 RTTEST_CHECK_RC_OK(g_hTest, VbglR3ClipboardDisconnectEx(&pCtx->Guest.CmdCtx)); 530 531 return VINF_SUCCESS; 532 } 533 534 static DECLCALLBACK(int) tstTestReadFromHost_ClientConnectedCallback(PTSTHGCMUTILSCTX pCtx, PTSTHGCMMOCKCLIENT pClient, 535 void *pvUser) 536 { 537 RT_NOREF(pCtx, pClient); 538 539 PCLIPBOARDTESTCTX pTstCtx = (PCLIPBOARDTESTCTX)pvUser; 540 AssertPtr(pTstCtx); RT_NOREF(pTstCtx); 541 542 RTTestPrintf(g_hTest, RTTESTLVL_DEBUG, "Client %RU32 connected\n", pClient->idClient); 543 return VINF_SUCCESS; 544 } 545 546 static DECLCALLBACK(int) tstTestReadFromHostSetup(PCLIPBOARDTESTCTX pTstCtx, void **ppvCtx) 547 { 548 RT_NOREF(ppvCtx); 549 550 /* Initialize the Shared Clipboard backend callbacks. */ 551 PSHCLBACKEND pBackend = ShClSvcGetBackend(); 552 553 SHCLCALLBACKS ShClCallbacks; 554 RT_ZERO(ShClCallbacks); 555 ShClCallbacks.pfnReportFormats = tstTestReadFromHost_ReportFormatsCallback; 556 ShClCallbacks.pfnOnClipboardRead = tstTestReadFromHost_OnClipboardReadCallback; 557 ShClBackendSetCallbacks(pBackend, &ShClCallbacks); 558 559 /* Set the right clipboard mode, so that the guest can read from the host. */ 560 tstClipboardSetMode(TstHgcmMockSvcInst(), VBOX_SHCL_MODE_BIDIRECTIONAL); 561 562 /* Start the host thread first, so that the guest thread can connect to it later. */ 563 TSTHGCMUTILSHOSTCALLBACKS HostCallbacks; 564 RT_ZERO(HostCallbacks); 565 HostCallbacks.pfnOnClientConnected = tstTestReadFromHost_ClientConnectedCallback; 566 TstHGCMUtilsHostThreadStart(&pTstCtx->HGCM, &HostCallbacks, pTstCtx /* pvUser */); 567 568 PCLIPBOARDTESTTASK pTask = &pTstCtx->Task; 569 AssertPtr(pTask); 570 pTask->enmFmtGst = VBOX_SHCL_FMT_UNICODETEXT; 571 pTask->enmFmtHst = pTask->enmFmtGst; 572 pTask->cbChunk = RTRandU32Ex(1, 512); 573 pTask->cbData = RT_ALIGN_32(pTask->cbChunk * RTRandU32Ex(1, 16), 2); 574 Assert(pTask->cbData % sizeof(RTUTF16) == 0); 575 #if !defined(RT_OS_WINDOWS) && !defined(RT_OS_OS2) 576 pTask->pvData = tstGenerateUtf8StringA(pTask->cbData); 577 pTask->cbData++; /* Add terminating zero. */ 578 #else 579 pTask->pvData = tstGenerateUtf16StringA(pTask->cbData / sizeof(RTUTF16)); 580 pTask->cbData += sizeof(RTUTF16); /* Add terminating zero. */ 807 581 #endif 808 809 #if 0 810 for (;;) 811 { 812 PVBGLR3CLIPBOARDEVENT pEvent = (PVBGLR3CLIPBOARDEVENT)RTMemAllocZ(sizeof(VBGLR3CLIPBOARDEVENT)); 813 AssertPtrBreakStmt(pEvent, rc = VERR_NO_MEMORY); 814 815 uint32_t idMsg = 0; 816 uint32_t cParms = 0; 817 RTTEST_CHECK_RC_OK(g_hTest, VbglR3ClipboardMsgPeekWait(&pCtx->Guest.CmdCtx, &idMsg, &cParms, NULL /* pidRestoreCheck */)); 818 RTTEST_CHECK_RC_OK(g_hTest, VbglR3ClipboardEventGetNext(idMsg, cParms, &pCtx->Guest.CmdCtx, pEvent)); 819 820 if (pEvent) 821 { 822 VbglR3ClipboardEventFree(pEvent); 823 pEvent = NULL; 824 } 825 826 if (ASMAtomicReadBool(&pCtx->Guest.fShutdown)) 827 break; 828 829 RTThreadSleep(100); 830 } 831 #endif 832 833 RTTEST_CHECK_RC_OK(g_hTest, VbglR3ClipboardDisconnectEx(&pCtx->Guest.CmdCtx)); 834 582 pTask->cbProcessed = 0; 583 584 RTTestPrintf(g_hTest, RTTESTLVL_DEBUG, "Host data (%RU32):\n%.*Rhxd\n", pTask->cbData, pTask->cbData, pTask->pvData); 835 585 return VINF_SUCCESS; 836 586 } 837 587 838 static DECLCALLBACK(int) tstTestReadFromHostExec(PTESTPARMS pTstParms, void *pvCtx) 839 { 840 RT_NOREF(pvCtx, pTstParms); 841 842 PTESTTASK pTask = &pTstParms->pTstCtx->Task; 843 844 pTask->enmFmtGst = VBOX_SHCL_FMT_UNICODETEXT; 845 pTask->enmFmtHst = pTask->enmFmtGst; 846 pTask->pvData = RTStrAPrintf2("foo!"); 847 pTask->cbData = strlen((char *)pTask->pvData) + 1; 848 pTask->cbChunk = pTask->cbData; 849 850 PTSTHGCMMOCKSVC pSvc = TstHgcmMockSvcInst(); 851 PTSTHGCMMOCKCLIENT pMockClient = TstHgcmMockSvcWaitForConnect(pSvc); 852 853 AssertPtrReturn(pMockClient, VERR_INVALID_POINTER); 588 static DECLCALLBACK(int) tstTestReadFromHostExec(PCLIPBOARDTESTCTX pTstCtx, void *pvCtx) 589 { 590 RT_NOREF(pvCtx); 591 592 TstHGCMUtilsGuestThreadStart(&pTstCtx->HGCM, tstTestReadFromHost_ThreadGuest, pTstCtx); 593 594 PTSTHGCMUTILSTASK pTask = (PTSTHGCMUTILSTASK)TstHGCMUtilsTaskGetCurrent(&pTstCtx->HGCM); 854 595 855 596 bool fUseMock = false; 856 597 TSTUSERMOCK UsrMock; 857 598 if (fUseMock) 858 tstShClUserMockInit(&UsrMock, "tstX11Hst"); 859 860 RTThreadSleep(RT_MS_1SEC * 4); 861 862 #if 1 863 PSHCLBACKEND pBackend = ShClSvcGetBackend(); 864 865 ShClBackendReportFormats(pBackend, (PSHCLCLIENT)pMockClient->pvClient, pTask->enmFmtHst); 866 tstTaskWait(pTask, RT_MS_30SEC); 867 #endif 868 869 RTThreadSleep(RT_MS_30SEC); 870 871 //PSHCLCLIENT pClient = &pMockClient->Client; 872 873 #if 1 874 if (1) 875 { 876 //RTTEST_CHECK_RC_OK(g_hTest, ShClBackendMockSetData(pBackend, pTask->enmFmt, pwszStr, cbData)); 877 //RTMemFree(pwszStr); 878 } 879 #endif 599 tstTestReadFromHost_MockInit(&UsrMock, "tstX11Hst"); 600 601 /* Wait until the task has been finished. */ 602 TstHGCMUtilsTaskWait(pTask, RT_MS_30SEC); 880 603 881 604 if (fUseMock) 882 tst ShClUserMockDestroy(&UsrMock);605 tstTestReadFromHost_MockDestroy(&UsrMock); 883 606 884 607 return VINF_SUCCESS; 885 608 } 886 609 887 static DECLCALLBACK(int) tstTestReadFromHostSetup(PTESTPARMS pTstParms, void **ppvCtx) 888 { 889 RT_NOREF(ppvCtx); 890 891 PTESTCTX pCtx = pTstParms->pTstCtx; 892 893 tstHostStart(pCtx); 894 895 PSHCLBACKEND pBackend = ShClSvcGetBackend(); 896 897 SHCLCALLBACKS Callbacks; 898 RT_ZERO(Callbacks); 899 Callbacks.pfnReportFormats = tstShClUserMockReportFormatsCallback; 900 //Callbacks.pfnOnRequestDataFromSource = tstTestReadFromHost_RequestDataFromSourceCallback; 901 Callbacks.pfnOnClipboardRead = tstShClUserMockOnGetDataCallback; 902 ShClBackendSetCallbacks(pBackend, &Callbacks); 903 904 tstGuestStart(pCtx, tstTestReadFromHostThreadGuest); 905 906 RTThreadSleep(1000); 907 908 tstSetMode(pCtx->pSvc, VBOX_SHCL_MODE_BIDIRECTIONAL); 909 910 return VINF_SUCCESS; 911 } 912 913 static DECLCALLBACK(int) tstTestReadFromHostDestroy(PTESTPARMS pTstParms, void *pvCtx) 610 static DECLCALLBACK(int) tstTestReadFromHostDestroy(PCLIPBOARDTESTCTX pTstCtx, void *pvCtx) 914 611 { 915 612 RT_NOREF(pvCtx); 916 613 917 int rc = VINF_SUCCESS; 918 919 tstGuestStop(pTstParms->pTstCtx); 920 tstHostStop(pTstParms->pTstCtx); 921 922 return rc; 923 } 614 int vrc = TstHGCMUtilsGuestThreadStop(&pTstCtx->HGCM); 615 AssertRC(vrc); 616 vrc = TstHGCMUtilsHostThreadStop(&pTstCtx->HGCM); 617 AssertRC(vrc); 618 619 return vrc; 620 } 621 622 623 /********************************************************************************************************************************* 624 * Main * 625 ********************************************************************************************************************************/ 924 626 925 627 /** Test definition table. */ 926 TESTDESC g_aTests[] = 927 { 628 CLIPBOARDTESTDESC g_aTests[] = 629 { 630 /* Tests guest reading clipboard data from the host. */ 928 631 { tstTestReadFromHostSetup, tstTestReadFromHostExec, tstTestReadFromHostDestroy } 929 632 }; … … 931 634 unsigned g_cTests = RT_ELEMENTS(g_aTests); 932 635 933 static int tstOne(PTSTHGCMMOCKSVC pSvc, PTESTDESC pTstDesc) 934 { 935 PTESTCTX pTstCtx = &g_TstCtx; 936 937 TESTPARMS TstParms; 938 RT_ZERO(TstParms); 939 940 pTstCtx->pSvc = pSvc; 941 TstParms.pTstCtx = pTstCtx; 636 static int tstOne(PTESTDESC pTstDesc) 637 { 638 PCLIPBOARDTESTCTX pTstCtx = &g_TstCtx; 942 639 943 640 void *pvCtx; 944 int rc = pTstDesc->pfnSetup( &TstParms, &pvCtx);641 int rc = pTstDesc->pfnSetup(pTstCtx, &pvCtx); 945 642 if (RT_SUCCESS(rc)) 946 643 { 947 rc = pTstDesc->pfnExec( &TstParms, pvCtx);948 949 int rc2 = pTstDesc->pfnDestroy( &TstParms, pvCtx);644 rc = pTstDesc->pfnExec(pTstCtx, pvCtx); 645 646 int rc2 = pTstDesc->pfnDestroy(pTstCtx, pvCtx); 950 647 if (RT_SUCCESS(rc)) 951 648 rc = rc2; … … 969 666 RTTestBanner(g_hTest); 970 667 668 #ifndef DEBUG_andy 971 669 /* Don't let assertions in the host service panic (core dump) the test cases. */ 972 670 RTAssertSetMayPanic(false); 973 974 PTSTHGCMMOCKSVC pSvc = TstHgcmMockSvcInst(); 975 671 #endif 672 673 PTSTHGCMMOCKSVC const pSvc = TstHgcmMockSvcInst(); 976 674 TstHgcmMockSvcCreate(pSvc, sizeof(SHCLCLIENT)); 977 675 TstHgcmMockSvcStart(pSvc); … … 980 678 * Run the tests. 981 679 */ 982 if ( 1)680 if (0) 983 681 { 984 682 testGuestSimple(); 985 testGuestWrite();986 683 testHostCall(); 987 testHostGetMsgOld();988 684 } 989 685 990 686 RT_ZERO(g_TstCtx); 991 tstTaskInit(&g_TstCtx.Task); 687 688 PTSTHGCMUTILSCTX pCtx = &g_TstCtx.HGCM; 689 TstHGCMUtilsCtxInit(pCtx, pSvc); 690 691 PTSTHGCMUTILSTASK pTask = (PTSTHGCMUTILSTASK)TstHGCMUtilsTaskGetCurrent(pCtx); 692 TstHGCMUtilsTaskInit(pTask); 693 pTask->pvUser = &g_TstCtx.Task; 694 992 695 for (unsigned i = 0; i < RT_ELEMENTS(g_aTests); i++) 993 tstOne(pSvc, &g_aTests[i]); 994 tstTaskDestroy(&g_TstCtx.Task); 696 tstOne(&g_aTests[i]); 697 698 TstHGCMUtilsTaskDestroy(pTask); 995 699 996 700 TstHgcmMockSvcStop(pSvc); … … 1002 706 return RTTestSummaryAndDestroy(g_hTest); 1003 707 } 708
Note:
See TracChangeset
for help on using the changeset viewer.