VirtualBox

source: vbox/trunk/src/VBox/HostServices/SharedClipboard/testcase/tstClipboardServiceHost.cpp@ 75500

Last change on this file since 75500 was 75500, checked in by vboxsync, 6 years ago

VMMDev,Main,HostServices: More profiling of HGCM guest call processing.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.6 KB
Line 
1/* $Id: tstClipboardServiceHost.cpp 75500 2018-11-16 01:24:39Z vboxsync $ */
2/** @file
3 * Shared Clipboard host service test case.
4 */
5
6/*
7 * Copyright (C) 2011-2017 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#include "../VBoxClipboard.h"
19
20#include <VBox/HostServices/VBoxClipboardSvc.h>
21
22#include <iprt/assert.h>
23#include <iprt/string.h>
24#include <iprt/test.h>
25
26extern "C" DECLCALLBACK(DECLEXPORT(int)) VBoxHGCMSvcLoad (VBOXHGCMSVCFNTABLE *ptable);
27
28static VBOXCLIPBOARDCLIENTDATA g_Client;
29static VBOXHGCMSVCHELPERS g_Helpers = { NULL };
30
31/** Simple call handle structure for the guest call completion callback */
32struct VBOXHGCMCALLHANDLE_TYPEDEF
33{
34 /** Where to store the result code */
35 int32_t rc;
36};
37
38/** Call completion callback for guest calls. */
39static DECLCALLBACK(void) callComplete(VBOXHGCMCALLHANDLE callHandle, int32_t rc)
40{
41 callHandle->rc = rc;
42}
43
44static int setupTable(VBOXHGCMSVCFNTABLE *pTable)
45{
46 pTable->cbSize = sizeof(*pTable);
47 pTable->u32Version = VBOX_HGCM_SVC_VERSION;
48 g_Helpers.pfnCallComplete = callComplete;
49 pTable->pHelpers = &g_Helpers;
50 return VBoxHGCMSvcLoad(pTable);
51}
52
53static void testSetMode(void)
54{
55 struct VBOXHGCMSVCPARM parms[2];
56 VBOXHGCMSVCFNTABLE table;
57 uint32_t u32Mode;
58 int rc;
59
60 RTTestISub("Testing HOST_FN_SET_MODE");
61 rc = setupTable(&table);
62 RTTESTI_CHECK_MSG_RETV(RT_SUCCESS(rc), ("rc=%Rrc\n", rc));
63 /* Reset global variable which doesn't reset itself. */
64 parms[0].setUInt32(VBOX_SHARED_CLIPBOARD_MODE_OFF);
65 rc = table.pfnHostCall(NULL, VBOX_SHARED_CLIPBOARD_HOST_FN_SET_MODE,
66 1, parms);
67 RTTESTI_CHECK_RC_OK(rc);
68 u32Mode = TestClipSvcGetMode();
69 RTTESTI_CHECK_MSG(u32Mode == VBOX_SHARED_CLIPBOARD_MODE_OFF,
70 ("u32Mode=%u\n", (unsigned) u32Mode));
71 rc = table.pfnHostCall(NULL, VBOX_SHARED_CLIPBOARD_HOST_FN_SET_MODE,
72 0, parms);
73 RTTESTI_CHECK_RC(rc, VERR_INVALID_PARAMETER);
74 rc = table.pfnHostCall(NULL, VBOX_SHARED_CLIPBOARD_HOST_FN_SET_MODE,
75 2, parms);
76 RTTESTI_CHECK_RC(rc, VERR_INVALID_PARAMETER);
77 parms[0].setUInt64(99);
78 rc = table.pfnHostCall(NULL, VBOX_SHARED_CLIPBOARD_HOST_FN_SET_MODE,
79 1, parms);
80 RTTESTI_CHECK_RC(rc, VERR_INVALID_PARAMETER);
81 parms[0].setUInt32(VBOX_SHARED_CLIPBOARD_MODE_HOST_TO_GUEST);
82 rc = table.pfnHostCall(NULL, VBOX_SHARED_CLIPBOARD_HOST_FN_SET_MODE,
83 1, parms);
84 RTTESTI_CHECK_RC_OK(rc);
85 u32Mode = TestClipSvcGetMode();
86 RTTESTI_CHECK_MSG(u32Mode == VBOX_SHARED_CLIPBOARD_MODE_HOST_TO_GUEST,
87 ("u32Mode=%u\n", (unsigned) u32Mode));
88 parms[0].setUInt32(99);
89 rc = table.pfnHostCall(NULL, VBOX_SHARED_CLIPBOARD_HOST_FN_SET_MODE,
90 1, parms);
91 RTTESTI_CHECK_RC_OK(rc);
92 u32Mode = TestClipSvcGetMode();
93 RTTESTI_CHECK_MSG(u32Mode == VBOX_SHARED_CLIPBOARD_MODE_OFF,
94 ("u32Mode=%u\n", (unsigned) u32Mode));
95 table.pfnUnload(NULL);
96}
97
98static void testGetHostMsg(void)
99{
100 struct VBOXHGCMSVCPARM parms[2];
101 VBOXHGCMSVCFNTABLE table;
102 VBOXHGCMCALLHANDLE_TYPEDEF call;
103 int rc;
104
105 RTTestISub("Setting up VBOX_SHARED_CLIPBOARD_FN_GET_HOST_MSG test");
106 rc = setupTable(&table);
107 RTTESTI_CHECK_MSG_RETV(RT_SUCCESS(rc), ("rc=%Rrc\n", rc));
108 /* Unless we are bidirectional the host message requests will be dropped. */
109 parms[0].setUInt32(VBOX_SHARED_CLIPBOARD_MODE_BIDIRECTIONAL);
110 rc = table.pfnHostCall(NULL, VBOX_SHARED_CLIPBOARD_HOST_FN_SET_MODE,
111 1, parms);
112 RTTESTI_CHECK_RC_OK(rc);
113
114 RTTestISub("Testing FN_GET_HOST_MSG, one format, waiting guest call.");
115 RT_ZERO(g_Client);
116 parms[0].setUInt32(0);
117 parms[1].setUInt32(0);
118 call.rc = VERR_TRY_AGAIN;
119 table.pfnCall(NULL, &call, 1 /* clientId */, &g_Client, VBOX_SHARED_CLIPBOARD_FN_GET_HOST_MSG,
120 2, parms, 0);
121 RTTESTI_CHECK_RC(call.rc, VERR_TRY_AGAIN); /* This should get updated only when the guest call completes. */
122 vboxSvcClipboardReportMsg (&g_Client, VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA,
123 VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT);
124 RTTESTI_CHECK(parms[0].u.uint32 == VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA);
125 RTTESTI_CHECK(parms[1].u.uint32 == VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT);
126 RTTESTI_CHECK_RC_OK(call.rc);
127 call.rc = VERR_TRY_AGAIN;
128 table.pfnCall(NULL, &call, 1 /* clientId */, &g_Client, VBOX_SHARED_CLIPBOARD_FN_GET_HOST_MSG,
129 2, parms, 0);
130 RTTESTI_CHECK_RC(call.rc, VERR_TRY_AGAIN); /* This call should not complete yet. */
131
132 RTTestISub("Testing FN_GET_HOST_MSG, one format, no waiting guest calls.");
133 RT_ZERO(g_Client);
134 vboxSvcClipboardReportMsg (&g_Client, VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA,
135 VBOX_SHARED_CLIPBOARD_FMT_HTML);
136 parms[0].setUInt32(0);
137 parms[1].setUInt32(0);
138 call.rc = VERR_TRY_AGAIN;
139 table.pfnCall(NULL, &call, 1 /* clientId */, &g_Client, VBOX_SHARED_CLIPBOARD_FN_GET_HOST_MSG,
140 2, parms, 0);
141 RTTESTI_CHECK(parms[0].u.uint32 == VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA);
142 RTTESTI_CHECK(parms[1].u.uint32 == VBOX_SHARED_CLIPBOARD_FMT_HTML);
143 RTTESTI_CHECK_RC_OK(call.rc);
144 call.rc = VERR_TRY_AGAIN;
145 table.pfnCall(NULL, &call, 1 /* clientId */, &g_Client, VBOX_SHARED_CLIPBOARD_FN_GET_HOST_MSG,
146 2, parms, 0);
147 RTTESTI_CHECK_RC(call.rc, VERR_TRY_AGAIN); /* This call should not complete yet. */
148
149 RTTestISub("Testing FN_GET_HOST_MSG, two formats, waiting guest call.");
150 RT_ZERO(g_Client);
151 parms[0].setUInt32(0);
152 parms[1].setUInt32(0);
153 call.rc = VERR_TRY_AGAIN;
154 table.pfnCall(NULL, &call, 1 /* clientId */, &g_Client, VBOX_SHARED_CLIPBOARD_FN_GET_HOST_MSG,
155 2, parms, 0);
156 RTTESTI_CHECK_RC(call.rc, VERR_TRY_AGAIN); /* This should get updated only when the guest call completes. */
157 vboxSvcClipboardReportMsg (&g_Client, VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA,
158 VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT | VBOX_SHARED_CLIPBOARD_FMT_HTML);
159 RTTESTI_CHECK(parms[0].u.uint32 == VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA);
160 RTTESTI_CHECK(parms[1].u.uint32 == VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT);
161 RTTESTI_CHECK_RC_OK(call.rc);
162 call.rc = VERR_TRY_AGAIN;
163 table.pfnCall(NULL, &call, 1 /* clientId */, &g_Client, VBOX_SHARED_CLIPBOARD_FN_GET_HOST_MSG,
164 2, parms, 0);
165 RTTESTI_CHECK(parms[0].u.uint32 == VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA);
166 RTTESTI_CHECK(parms[1].u.uint32 == VBOX_SHARED_CLIPBOARD_FMT_HTML);
167 RTTESTI_CHECK_RC_OK(call.rc);
168 call.rc = VERR_TRY_AGAIN;
169 table.pfnCall(NULL, &call, 1 /* clientId */, &g_Client, VBOX_SHARED_CLIPBOARD_FN_GET_HOST_MSG,
170 2, parms, 0);
171 RTTESTI_CHECK_RC(call.rc, VERR_TRY_AGAIN); /* This call should not complete yet. */
172
173 RTTestISub("Testing FN_GET_HOST_MSG, two formats, no waiting guest calls.");
174 RT_ZERO(g_Client);
175 vboxSvcClipboardReportMsg (&g_Client, VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA,
176 VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT | VBOX_SHARED_CLIPBOARD_FMT_HTML);
177 parms[0].setUInt32(0);
178 parms[1].setUInt32(0);
179 call.rc = VERR_TRY_AGAIN;
180 table.pfnCall(NULL, &call, 1 /* clientId */, &g_Client, VBOX_SHARED_CLIPBOARD_FN_GET_HOST_MSG,
181 2, parms, 0);
182 RTTESTI_CHECK(parms[0].u.uint32 == VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA);
183 RTTESTI_CHECK(parms[1].u.uint32 == VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT);
184 RTTESTI_CHECK_RC_OK(call.rc);
185 call.rc = VERR_TRY_AGAIN;
186 table.pfnCall(NULL, &call, 1 /* clientId */, &g_Client, VBOX_SHARED_CLIPBOARD_FN_GET_HOST_MSG,
187 2, parms, 0);
188 RTTESTI_CHECK(parms[0].u.uint32 == VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA);
189 RTTESTI_CHECK(parms[1].u.uint32 == VBOX_SHARED_CLIPBOARD_FMT_HTML);
190 RTTESTI_CHECK_RC_OK(call.rc);
191 call.rc = VERR_TRY_AGAIN;
192 table.pfnCall(NULL, &call, 1 /* clientId */, &g_Client, VBOX_SHARED_CLIPBOARD_FN_GET_HOST_MSG,
193 2, parms, 0);
194 RTTESTI_CHECK_RC(call.rc, VERR_TRY_AGAIN); /* This call should not complete yet. */
195 table.pfnUnload(NULL);
196}
197
198static void testSetHeadless(void)
199{
200 struct VBOXHGCMSVCPARM parms[2];
201 VBOXHGCMSVCFNTABLE table;
202 bool fHeadless;
203 int rc;
204
205 RTTestISub("Testing HOST_FN_SET_HEADLESS");
206 rc = setupTable(&table);
207 RTTESTI_CHECK_MSG_RETV(RT_SUCCESS(rc), ("rc=%Rrc\n", rc));
208 /* Reset global variable which doesn't reset itself. */
209 parms[0].setUInt32(false);
210 rc = table.pfnHostCall(NULL, VBOX_SHARED_CLIPBOARD_HOST_FN_SET_HEADLESS,
211 1, parms);
212 RTTESTI_CHECK_RC_OK(rc);
213 fHeadless = vboxSvcClipboardGetHeadless();
214 RTTESTI_CHECK_MSG(fHeadless == false, ("fHeadless=%RTbool\n", fHeadless));
215 rc = table.pfnHostCall(NULL, VBOX_SHARED_CLIPBOARD_HOST_FN_SET_HEADLESS,
216 0, parms);
217 RTTESTI_CHECK_RC(rc, VERR_INVALID_PARAMETER);
218 rc = table.pfnHostCall(NULL, VBOX_SHARED_CLIPBOARD_HOST_FN_SET_HEADLESS,
219 2, parms);
220 RTTESTI_CHECK_RC(rc, VERR_INVALID_PARAMETER);
221 parms[0].setUInt64(99);
222 rc = table.pfnHostCall(NULL, VBOX_SHARED_CLIPBOARD_HOST_FN_SET_HEADLESS,
223 1, parms);
224 RTTESTI_CHECK_RC(rc, VERR_INVALID_PARAMETER);
225 parms[0].setUInt32(true);
226 rc = table.pfnHostCall(NULL, VBOX_SHARED_CLIPBOARD_HOST_FN_SET_HEADLESS,
227 1, parms);
228 RTTESTI_CHECK_RC_OK(rc);
229 fHeadless = vboxSvcClipboardGetHeadless();
230 RTTESTI_CHECK_MSG(fHeadless == true, ("fHeadless=%RTbool\n", fHeadless));
231 parms[0].setUInt32(99);
232 rc = table.pfnHostCall(NULL, VBOX_SHARED_CLIPBOARD_HOST_FN_SET_HEADLESS,
233 1, parms);
234 RTTESTI_CHECK_RC_OK(rc);
235 fHeadless = vboxSvcClipboardGetHeadless();
236 RTTESTI_CHECK_MSG(fHeadless == true, ("fHeadless=%RTbool\n", fHeadless));
237 table.pfnUnload(NULL);
238}
239
240static void testHostCall(void)
241{
242 testSetMode();
243 testSetHeadless();
244}
245
246
247int main(int argc, char *argv[])
248{
249 /*
250 * Init the runtime, test and say hello.
251 */
252 const char *pcszExecName;
253 NOREF(argc);
254 pcszExecName = strrchr(argv[0], '/');
255 pcszExecName = pcszExecName ? pcszExecName + 1 : argv[0];
256 RTTEST hTest;
257 RTEXITCODE rcExit = RTTestInitAndCreate(pcszExecName, &hTest);
258 if (rcExit != RTEXITCODE_SUCCESS)
259 return rcExit;
260 RTTestBanner(hTest);
261
262 /*
263 * Run the tests.
264 */
265 testHostCall();
266 testGetHostMsg();
267
268 /*
269 * Summary
270 */
271 return RTTestSummaryAndDestroy(hTest);
272}
273
274int vboxClipboardInit() { return VINF_SUCCESS; }
275void vboxClipboardDestroy() {}
276void vboxClipboardDisconnect(_VBOXCLIPBOARDCLIENTDATA*) { AssertFailed(); }
277int vboxClipboardConnect(_VBOXCLIPBOARDCLIENTDATA*, bool)
278{ AssertFailed(); return VERR_WRONG_ORDER; }
279void vboxClipboardFormatAnnounce(_VBOXCLIPBOARDCLIENTDATA*, unsigned int)
280{ AssertFailed(); }
281int vboxClipboardReadData(_VBOXCLIPBOARDCLIENTDATA*, unsigned int, void*, unsigned int, unsigned int*)
282{ AssertFailed(); return VERR_WRONG_ORDER; }
283void vboxClipboardWriteData(_VBOXCLIPBOARDCLIENTDATA*, void*, unsigned int, unsigned int) { AssertFailed(); }
284int vboxClipboardSync(_VBOXCLIPBOARDCLIENTDATA*)
285{ AssertFailed(); return VERR_WRONG_ORDER; }
Note: See TracBrowser for help on using the repository browser.

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