VirtualBox

source: vbox/trunk/src/VBox/HostServices/SharedClipboard/testcase/tstClipboardTransfers.cpp@ 100204

最後變更 在這個檔案從100204是 100204,由 vboxsync 提交於 21 月 前

Shared Clipboard: Unified root list entry code to also use the generic list entry code, a lot of updates for the cross OS transfer handling code, more updates for HTTP server transfer handling.

This also changed the handling of how that transfers are being initiated, as we needed to have this for X11: Before, transfers were initiated as soon as on side announced the URI list format -- now we postpone initiating the transfer until the receiving side requests the data as URI list.

bugref:9437

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 13.3 KB
 
1/* $Id: tstClipboardTransfers.cpp 100204 2023-06-19 09:11:37Z vboxsync $ */
2/** @file
3 * Shared Clipboard transfers test case.
4 */
5
6/*
7 * Copyright (C) 2019-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.alldomusa.eu.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28#include "../VBoxSharedClipboardSvc-internal.h"
29
30#include <VBox/HostServices/VBoxClipboardSvc.h>
31
32#include <iprt/assert.h>
33#include <iprt/dir.h>
34#include <iprt/file.h>
35#include <iprt/path.h>
36#include <iprt/string.h>
37#include <iprt/test.h>
38
39
40static int testCreateTempDir(RTTEST hTest, const char *pszTestcase, char *pszTempDir, size_t cbTempDir)
41{
42 char szTempDir[RTPATH_MAX];
43 int rc = RTPathTemp(szTempDir, sizeof(szTempDir));
44 RTTESTI_CHECK_RC_RET(rc, VINF_SUCCESS, rc);
45
46 rc = RTPathAppend(szTempDir, sizeof(szTempDir), "tstClipboardTransfers");
47 RTTESTI_CHECK_RC_RET(rc, VINF_SUCCESS, rc);
48
49 rc = RTDirCreate(szTempDir, 0700, 0);
50 if (rc == VERR_ALREADY_EXISTS)
51 rc = VINF_SUCCESS;
52 RTTESTI_CHECK_RC_RET(rc, VINF_SUCCESS, rc);
53
54 rc = RTPathAppend(szTempDir, sizeof(szTempDir), "XXXXX");
55 RTTESTI_CHECK_RC_RET(rc, VINF_SUCCESS, rc);
56
57 rc = RTDirCreateTemp(szTempDir, 0700);
58 RTTESTI_CHECK_RC_RET(rc, VINF_SUCCESS, rc);
59
60 rc = RTPathJoin(pszTempDir, cbTempDir, szTempDir, pszTestcase);
61 RTTESTI_CHECK_RC_RET(rc, VINF_SUCCESS, rc);
62
63 RTTestPrintf(hTest, RTTESTLVL_DEBUG, "Created temporary directory: %s\n", pszTempDir);
64
65 return rc;
66}
67
68static int testRemoveTempDir(RTTEST hTest)
69{
70 char szTempDir[RTPATH_MAX];
71 int rc = RTPathTemp(szTempDir, sizeof(szTempDir));
72 RTTESTI_CHECK_RC_RET(rc, VINF_SUCCESS, rc);
73
74 rc = RTPathAppend(szTempDir, sizeof(szTempDir), "tstClipboardTransfers");
75 RTTESTI_CHECK_RC_RET(rc, VINF_SUCCESS, rc);
76
77 rc = RTDirRemoveRecursive(szTempDir, RTDIRRMREC_F_CONTENT_AND_DIR);
78 RTTESTI_CHECK_RC_RET(rc, VINF_SUCCESS, rc);
79
80 RTTestPrintf(hTest, RTTESTLVL_DEBUG, "Removed temporary directory: %s\n", szTempDir);
81
82 return rc;
83}
84
85static int testCreateDir(RTTEST hTest, const char *pszPathToCreate)
86{
87 RTTestPrintf(hTest, RTTESTLVL_DEBUG, "Creating directory: %s\n", pszPathToCreate);
88
89 int rc = RTDirCreateFullPath(pszPathToCreate, 0700);
90 if (rc == VERR_ALREADY_EXISTS)
91 rc = VINF_SUCCESS;
92 RTTESTI_CHECK_RC_RET(rc, VINF_SUCCESS, rc);
93
94 return rc;
95}
96
97static int testCreateFile(RTTEST hTest, const char *pszTempDir, const char *pszFileName, uint32_t fOpen, size_t cbSize,
98 char **ppszFilePathAbs)
99{
100 char szFilePath[RTPATH_MAX];
101
102 int rc = RTStrCopy(szFilePath, sizeof(szFilePath), pszTempDir);
103 RTTESTI_CHECK_RC_OK_RET(rc, rc);
104
105 rc = RTPathAppend(szFilePath, sizeof(szFilePath), pszFileName);
106 RTTESTI_CHECK_RC_OK_RET(rc, rc);
107
108 char *pszDirToCreate = RTStrDup(szFilePath);
109 RTTESTI_CHECK_RET(pszDirToCreate, VERR_NO_MEMORY);
110
111 RTPathStripFilename(pszDirToCreate);
112
113 rc = testCreateDir(hTest, pszDirToCreate);
114 RTTESTI_CHECK_RC_OK_RET(rc, rc);
115
116 RTStrFree(pszDirToCreate);
117 pszDirToCreate = NULL;
118
119 if (!fOpen)
120 fOpen = RTFILE_O_OPEN_CREATE | RTFILE_O_WRITE | RTFILE_O_DENY_NONE;
121
122 RTTestPrintf(hTest, RTTESTLVL_DEBUG, "Creating file: %s\n", szFilePath);
123
124 RTFILE hFile;
125 rc = RTFileOpen(&hFile, szFilePath, fOpen);
126 if (RT_SUCCESS(rc))
127 {
128 if (cbSize)
129 {
130 /** @todo Fill in some random stuff. */
131 }
132
133 rc = RTFileClose(hFile);
134 RTTESTI_CHECK_RC_RET(rc, VINF_SUCCESS, rc);
135 }
136
137 if (ppszFilePathAbs)
138 *ppszFilePathAbs = RTStrDup(szFilePath);
139
140 return rc;
141}
142
143typedef struct TESTTRANSFERROOTENTRY
144{
145 TESTTRANSFERROOTENTRY(const RTCString &a_strPath)
146 : strPath(a_strPath) { }
147
148 RTCString strPath;
149} TESTTRANSFERROOTENTRY;
150
151static int testAddRootEntry(RTTEST hTest, const char *pszTempDir,
152 const TESTTRANSFERROOTENTRY &rootEntry, char **ppszRoots)
153{
154 char *pszRoots = NULL;
155
156 const char *pszPath = rootEntry.strPath.c_str();
157
158 char *pszPathAbs;
159 int rc = testCreateFile(hTest, pszTempDir, pszPath, 0, 0, &pszPathAbs);
160 RTTESTI_CHECK_RC_OK_RET(rc, rc);
161
162 rc = RTStrAAppend(&pszRoots, pszPathAbs);
163 RTTESTI_CHECK_RC_OK(rc);
164
165 rc = RTStrAAppend(&pszRoots, "\r\n");
166 RTTESTI_CHECK_RC_OK(rc);
167
168 RTStrFree(pszPathAbs);
169
170 *ppszRoots = pszRoots;
171
172 return rc;
173}
174
175static int testAddRootEntries(RTTEST hTest, const char *pszTempDir,
176 RTCList<TESTTRANSFERROOTENTRY> &lstBase, RTCList<TESTTRANSFERROOTENTRY> lstToExtend,
177 char **ppszRoots)
178{
179 int rc = VINF_SUCCESS;
180
181 char *pszRoots = NULL;
182
183 for (size_t i = 0; i < lstBase.size(); ++i)
184 {
185 char *pszEntry = NULL;
186 rc = testAddRootEntry(hTest, pszTempDir, lstBase.at(i), &pszEntry);
187 RTTESTI_CHECK_RC_OK_BREAK(rc);
188 rc = RTStrAAppend(&pszRoots, pszEntry);
189 RTTESTI_CHECK_RC_OK_BREAK(rc);
190 RTStrFree(pszEntry);
191 }
192
193 for (size_t i = 0; i < lstToExtend.size(); ++i)
194 {
195 char *pszEntry = NULL;
196 rc = testAddRootEntry(hTest, pszTempDir, lstToExtend.at(i), &pszEntry);
197 RTTESTI_CHECK_RC_OK_BREAK(rc);
198 rc = RTStrAAppend(&pszRoots, pszEntry);
199 RTTESTI_CHECK_RC_OK_BREAK(rc);
200 RTStrFree(pszEntry);
201 }
202
203 if (RT_SUCCESS(rc))
204 *ppszRoots = pszRoots;
205
206 return rc;
207}
208
209static void testTransferRootsSetSingle(RTTEST hTest,
210 RTCList<TESTTRANSFERROOTENTRY> &lstBase, RTCList<TESTTRANSFERROOTENTRY> lstToExtend,
211 int rcExpected)
212{
213 PSHCLTRANSFER pTransfer;
214 int rc = ShClTransferCreate(&pTransfer);
215 RTTESTI_CHECK_RC_OK(rc);
216
217 SHCLTXPROVIDER Provider;
218 RTTESTI_CHECK(VBClTransferProviderLocalQueryInterface(&Provider) != NULL);
219 RTTESTI_CHECK_RC_OK(ShClTransferSetProvider(pTransfer, &Provider));
220
221 char szTestTransferRootsSetDir[RTPATH_MAX];
222 rc = testCreateTempDir(hTest, "testTransferRootsSet", szTestTransferRootsSetDir, sizeof(szTestTransferRootsSetDir));
223 RTTESTI_CHECK_RC_OK_RETV(rc);
224
225 /* This is the file we're trying to access (but not supposed to). */
226 rc = testCreateFile(hTest, szTestTransferRootsSetDir, "must-not-access-this", 0, 0, NULL);
227 RTTESTI_CHECK_RC_OK(rc);
228
229 char *pszRoots;
230 rc = testAddRootEntries(hTest, szTestTransferRootsSetDir, lstBase, lstToExtend, &pszRoots);
231 RTTESTI_CHECK_RC_OK_RETV(rc);
232
233 rc = ShClTransferRootsInitFromStringList(pTransfer, pszRoots, strlen(pszRoots) + 1);
234 RTTESTI_CHECK_RC(rc, rcExpected);
235
236 RTStrFree(pszRoots);
237
238 rc = ShClTransferDestroy(pTransfer);
239 RTTESTI_CHECK_RC_OK(rc);
240}
241
242static void testTransferObjOpenSingle(RTTEST hTest,
243 RTCList<TESTTRANSFERROOTENTRY> &lstRoots, const char *pszObjPath, int rcExpected)
244{
245 RT_NOREF(hTest);
246
247 PSHCLTRANSFER pTransfer;
248 int rc = ShClTransferCreate(&pTransfer);
249 RTTESTI_CHECK_RC_OK(rc);
250
251 SHCLTXPROVIDER Provider;
252 VBClTransferProviderLocalQueryInterface(&Provider);
253
254 rc = ShClTransferSetProvider(pTransfer, &Provider);
255 RTTESTI_CHECK_RC_OK(rc);
256
257 rc = ShClTransferInit(pTransfer, SHCLTRANSFERDIR_FROM_REMOTE, SHCLSOURCE_LOCAL);
258 RTTESTI_CHECK_RC_OK(rc);
259
260 char szTestTransferObjOpenDir[RTPATH_MAX];
261 rc = testCreateTempDir(hTest, "testTransferObjOpen", szTestTransferObjOpenDir, sizeof(szTestTransferObjOpenDir));
262 RTTESTI_CHECK_RC_OK_RETV(rc);
263
264 /* This is the file we're trying to access (but not supposed to). */
265 rc = testCreateFile(hTest, szTestTransferObjOpenDir, "file1.txt", 0, 0, NULL);
266 RTTESTI_CHECK_RC_OK(rc);
267
268 RTCList<TESTTRANSFERROOTENTRY> lstToExtendEmpty;
269
270 char *pszRoots;
271 rc = testAddRootEntries(hTest, szTestTransferObjOpenDir, lstRoots, lstToExtendEmpty, &pszRoots);
272 RTTESTI_CHECK_RC_OK_RETV(rc);
273
274 rc = ShClTransferRootsInitFromStringList(pTransfer, pszRoots, strlen(pszRoots) + 1);
275 RTTESTI_CHECK_RC_OK(rc);
276
277 RTStrFree(pszRoots);
278
279 SHCLOBJOPENCREATEPARMS openCreateParms;
280 rc = ShClTransferObjOpenParmsInit(&openCreateParms);
281 RTTESTI_CHECK_RC_OK(rc);
282
283 rc = RTStrCopy(openCreateParms.pszPath, openCreateParms.cbPath, pszObjPath);
284 RTTESTI_CHECK_RC_OK(rc);
285
286 SHCLOBJHANDLE hObj;
287 rc = ShClTransferObjOpen(pTransfer, &openCreateParms, &hObj);
288 RTTESTI_CHECK_RC(rc, rcExpected);
289 if (RT_SUCCESS(rc))
290 {
291 rc = ShClTransferObjClose(pTransfer, hObj);
292 RTTESTI_CHECK_RC_OK(rc);
293 }
294
295 rc = ShClTransferDestroy(pTransfer);
296 RTTESTI_CHECK_RC_OK(rc);
297}
298
299static void testTransferBasics(RTTEST hTest)
300{
301 RT_NOREF(hTest);
302
303 RTTestISub("Testing transfer basics");
304
305 SHCLEVENTSOURCE Source;
306 int rc = ShClEventSourceCreate(&Source, 0);
307 RTTESTI_CHECK_RC_OK(rc);
308 rc = ShClEventSourceDestroy(&Source);
309 RTTESTI_CHECK_RC_OK(rc);
310 PSHCLTRANSFER pTransfer;
311 rc = ShClTransferCreate(&pTransfer);
312 RTTESTI_CHECK_RC_OK(rc);
313 rc = ShClTransferDestroy(pTransfer);
314 RTTESTI_CHECK_RC_OK(rc);
315 rc = ShClTransferDestroy(pTransfer); /* Second time, intentional. */
316 RTTESTI_CHECK_RC_OK(rc);
317
318 PSHCLLIST pList = ShClTransferListAlloc();
319 RTTESTI_CHECK(pList != NULL);
320 rc = ShClTransferCreate(&pTransfer);
321 RTTESTI_CHECK_RC_OK(rc);
322 ShClTransferListFree(pList);
323 pList = NULL;
324 ShClTransferListFree(pList); /* Second time, intentional. */
325
326 SHCLLISTENTRY Entry;
327 RTTESTI_CHECK_RC_OK(ShClTransferListEntryInit(&Entry));
328 ShClTransferListEntryDestroy(&Entry);
329 ShClTransferListEntryDestroy(&Entry); /* Second time, intentional. */
330}
331
332static void testTransferRootsSet(RTTEST hTest)
333{
334 RTTestISub("Testing setting transfer roots");
335
336 /* Define the (valid) transfer root set. */
337 RTCList<TESTTRANSFERROOTENTRY> lstBase;
338 lstBase.append(TESTTRANSFERROOTENTRY("my-transfer-1/file1.txt"));
339 lstBase.append(TESTTRANSFERROOTENTRY("my-transfer-1/dir1/file1.txt"));
340 lstBase.append(TESTTRANSFERROOTENTRY("my-transfer-1/dir1/sub1/file1.txt"));
341 lstBase.append(TESTTRANSFERROOTENTRY("my-transfer-1/dir2/file1.txt"));
342 lstBase.append(TESTTRANSFERROOTENTRY("my-transfer-1/dir2/sub1/file1.txt"));
343
344 RTCList<TESTTRANSFERROOTENTRY> lstBreakout;
345 testTransferRootsSetSingle(hTest, lstBase, lstBreakout, VINF_SUCCESS);
346
347 lstBreakout.clear();
348 lstBase.append(TESTTRANSFERROOTENTRY("../must-not-access-this"));
349 testTransferRootsSetSingle(hTest, lstBase, lstBreakout, VERR_INVALID_PARAMETER);
350
351 lstBreakout.clear();
352 lstBase.append(TESTTRANSFERROOTENTRY("does-not-exist/file1.txt"));
353 testTransferRootsSetSingle(hTest, lstBase, lstBreakout, VERR_INVALID_PARAMETER);
354
355 lstBreakout.clear();
356 lstBase.append(TESTTRANSFERROOTENTRY("my-transfer-1/../must-not-access-this"));
357 testTransferRootsSetSingle(hTest, lstBase, lstBreakout, VERR_INVALID_PARAMETER);
358
359 lstBreakout.clear();
360 lstBase.append(TESTTRANSFERROOTENTRY("my-transfer-1/./../must-not-access-this"));
361 testTransferRootsSetSingle(hTest, lstBase, lstBreakout, VERR_INVALID_PARAMETER);
362
363 lstBreakout.clear();
364 lstBase.append(TESTTRANSFERROOTENTRY("../does-not-exist"));
365 testTransferRootsSetSingle(hTest, lstBase, lstBreakout, VERR_INVALID_PARAMETER);
366}
367
368static void testTransferObjOpen(RTTEST hTest)
369{
370 RTTestISub("Testing setting transfer object open");
371
372 /* Define the (valid) transfer root set. */
373 RTCList<TESTTRANSFERROOTENTRY> lstRoots;
374 lstRoots.append(TESTTRANSFERROOTENTRY("my-transfer-1/file1.txt"));
375 lstRoots.append(TESTTRANSFERROOTENTRY("my-transfer-1/dir1/file1.txt"));
376 lstRoots.append(TESTTRANSFERROOTENTRY("my-transfer-1/dir1/sub1/file1.txt"));
377 lstRoots.append(TESTTRANSFERROOTENTRY("my-transfer-1/dir2/file1.txt"));
378 lstRoots.append(TESTTRANSFERROOTENTRY("my-transfer-1/dir2/sub1/file1.txt"));
379
380 testTransferObjOpenSingle(hTest, lstRoots, "file1.txt", VINF_SUCCESS);
381 testTransferObjOpenSingle(hTest, lstRoots, "does-not-exist.txt", VERR_PATH_NOT_FOUND);
382 testTransferObjOpenSingle(hTest, lstRoots, "dir1/does-not-exist.txt", VERR_PATH_NOT_FOUND);
383 testTransferObjOpenSingle(hTest, lstRoots, "../must-not-access-this.txt", VERR_INVALID_PARAMETER);
384 testTransferObjOpenSingle(hTest, lstRoots, "dir1/../../must-not-access-this.txt", VERR_INVALID_PARAMETER);
385}
386
387int main(int argc, char *argv[])
388{
389 /*
390 * Init the runtime, test and say hello.
391 */
392 const char *pcszExecName;
393 NOREF(argc);
394 pcszExecName = strrchr(argv[0], '/');
395 pcszExecName = pcszExecName ? pcszExecName + 1 : argv[0];
396 RTTEST hTest;
397 RTEXITCODE rcExit = RTTestInitAndCreate(pcszExecName, &hTest);
398 if (rcExit != RTEXITCODE_SUCCESS)
399 return rcExit;
400 RTTestBanner(hTest);
401
402 testTransferBasics(hTest);
403 testTransferRootsSet(hTest);
404 testTransferObjOpen(hTest);
405
406 int rc = testRemoveTempDir(hTest);
407 RTTESTI_CHECK_RC(rc, VINF_SUCCESS);
408
409 /*
410 * Summary
411 */
412 return RTTestSummaryAndDestroy(hTest);
413}
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette