VirtualBox

source: vbox/trunk/src/VBox/Main/testcase/tstUSBProxyLinux.cpp@ 36996

Last change on this file since 36996 was 36996, checked in by vboxsync, 14 years ago

Main/linux/usb: additional tests, drop a couple of silly ones

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.7 KB
Line 
1/* $Id: tstUSBProxyLinux.cpp 36996 2011-05-06 23:09:23Z vboxsync $ */
2/** @file
3 * USBProxyServiceLinux test case.
4 */
5
6/*
7 * Copyright (C) 2011 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.215389.xyz. 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/******************************************************************************
19* Header Files *
20******************************************************************************/
21
22#include "USBProxyService.h"
23#include "USBGetDevices.h"
24
25#include <VBox/err.h>
26#include <iprt/assert.h>
27#include <iprt/env.h>
28#include <iprt/string.h>
29#include <iprt/test.h>
30
31/*** BEGIN STUBS ***/
32
33USBProxyService::USBProxyService(Host*) {}
34USBProxyService::~USBProxyService() {}
35HRESULT USBProxyService::init() { return S_OK; }
36int USBProxyService::start() { return VINF_SUCCESS; }
37int USBProxyService::stop() { return VINF_SUCCESS; }
38RWLockHandle *USBProxyService::lockHandle() const { return NULL; }
39void *USBProxyService::insertFilter(USBFILTER const*) { return NULL; }
40void USBProxyService::removeFilter(void*) {}
41int USBProxyService::captureDevice(HostUSBDevice*) { return VINF_SUCCESS; }
42void USBProxyService::captureDeviceCompleted(HostUSBDevice*, bool) {}
43void USBProxyService::detachingDevice(HostUSBDevice*) {}
44int USBProxyService::releaseDevice(HostUSBDevice*) { return VINF_SUCCESS; }
45void USBProxyService::releaseDeviceCompleted(HostUSBDevice*, bool) {}
46void USBProxyService::serviceThreadInit() {}
47void USBProxyService::serviceThreadTerm() {}
48int USBProxyService::wait(unsigned int) { return VINF_SUCCESS; }
49int USBProxyService::interruptWait() { return VINF_SUCCESS; }
50PUSBDEVICE USBProxyService::getDevices() { return NULL; }
51void USBProxyService::deviceAdded(ComObjPtr<HostUSBDevice> &aDevice, SessionMachinesList &llOpenedMachines, PUSBDEVICE aUSBDevice) {}
52void USBProxyService::deviceRemoved(ComObjPtr<HostUSBDevice> &aDevice) {}
53void USBProxyService::deviceChanged(ComObjPtr<HostUSBDevice> &aDevice, SessionMachinesList*, SessionMachine*) {}
54bool USBProxyService::updateDeviceState(HostUSBDevice*, USBDEVICE*, bool*, SessionMachine**) { return true; }
55bool USBProxyService::updateDeviceStateFake(HostUSBDevice*, USBDEVICE*, bool*, SessionMachine**) { return true; }
56bool USBProxyService::isActive() { return true; }
57
58VBoxMainHotplugWaiter::VBoxMainHotplugWaiter(char const*) {}
59
60com::Utf8Str HostUSBDevice::getName()
61{
62 return Utf8Str();
63}
64
65int USBProxyService::getLastError(void)
66{
67 return mLastError;
68}
69
70void SysFreeString(BSTR bstr)
71{
72 Assert(0);
73}
74
75static struct
76{
77 const char *pcszEnvUsb;
78 const char *pcszEnvUsbRoot;
79 const char *pcszDevicesRoot;
80 bool fDevicesAccessible;
81 const char *pcszUsbfsRoot;
82 bool fUsbfsAccessible;
83 int rcMethodInit;
84 const char *pcszDevicesRootExpected;
85 bool fUsingUsbfsExpected;
86 int rcExpected;
87} s_testEnvironment[] =
88{
89 /* "sysfs" and root in the environment */
90 { "sysfs", "/dev/bus/usb", NULL, false, NULL, false, VINF_SUCCESS, "/dev/bus/usb", false, VINF_SUCCESS },
91 /* "sysfs" and root in the environment, method-specific init failed */
92 { "sysfs", "/dev/bus/usb", NULL, false, NULL, false, VERR_NO_MEMORY, "/dev/bus/usb", false, VERR_NO_MEMORY },
93 /* "sysfs" and bad root in the environment (should succeed as we don't do checks if the user specifies everything) */
94 { "sysfs", "/dev/bus/usb", "/dev/usbvbox", false, "/proc/usb/bus", false, VINF_SUCCESS, "/dev/bus/usb", false, VINF_SUCCESS },
95 /* "sysfs" and bad root in the environment, method-specific init failed */
96 { "sysfs", "/dev/bus/usb", "/dev/usbvbox", false, "/proc/usb/bus", false, VERR_NO_MEMORY, "/dev/bus/usb", false, VERR_NO_MEMORY },
97 /* "sysfs" and no root in the environment */
98 { "sysfs", NULL, "/dev/vboxusb", true, NULL, false, VINF_SUCCESS, "/dev/vboxusb", false, VINF_SUCCESS },
99 /* "usbfs" and root in the environment */
100 { "usbfs", "/dev/bus/usb", NULL, false, NULL, false, VINF_SUCCESS, "/dev/bus/usb", true, VINF_SUCCESS },
101 /* "usbfs" and root in the environment, method-specific init failed */
102 { "usbfs", "/dev/bus/usb", NULL, false, NULL, false, VERR_NO_MEMORY, "/dev/bus/usb", true, VERR_NO_MEMORY },
103 /* "usbfs" and bad root in the environment (should succeed as we don't do checks if the user specifies everything) */
104 { "usbfs", "/dev/bus/usb", "/dev/usbvbox", false, "/proc/usb/bus", false, VINF_SUCCESS, "/dev/bus/usb", true, VINF_SUCCESS },
105 /* "usbfs" and bad root in the environment, method-specific init failed */
106 { "usbfs", "/dev/bus/usb", "/dev/usbvbox", false, "/proc/usb/bus", false, VERR_NO_MEMORY, "/dev/bus/usb", true, VERR_NO_MEMORY },
107 /* "usbfs" and no root in the environment */
108 { "usbfs", NULL, NULL, false, "/proc/bus/usb", true, VINF_SUCCESS, "/proc/bus/usb", true, VINF_SUCCESS },
109 /* invalid method in the environment, sysfs available */
110 { "invalid", "/dev/bus/usb", "/dev/vboxusb", true, NULL, false, VINF_SUCCESS, "/dev/vboxusb", false, VINF_SUCCESS },
111 /* invalid method in the environment, usbfs available */
112 { "invalid", "/dev/bus/usb", NULL, true, "/proc/bus/usb", true, VINF_SUCCESS, "/proc/bus/usb", true, VINF_SUCCESS },
113 /* invalid method in the environment, sysfs inaccessible */
114 { "invalid", "/dev/bus/usb", "/dev/vboxusb", false, NULL, false, VINF_SUCCESS, "", true, VERR_VUSB_USB_DEVICE_PERMISSION },
115 /* invalid method in the environment, usbfs inaccessible */
116 { "invalid", "/dev/bus/usb", NULL, false, "/proc/bus/usb", false, VINF_SUCCESS, "", true, VERR_VUSB_USBFS_PERMISSION },
117 /* No environment, sysfs and usbfs available but without access permissions. */
118 { NULL, NULL, "/dev/vboxusb", false, "/proc/bus/usb", false, VERR_NO_MEMORY, "", true, VERR_VUSB_USB_DEVICE_PERMISSION },
119 /* No environment, sysfs and usbfs available, access permissions for sysfs. */
120 { NULL, NULL, "/dev/vboxusb", true, "/proc/bus/usb", false, VINF_SUCCESS, "/dev/vboxusb", false, VINF_SUCCESS },
121 /* No environment, sysfs and usbfs available, access permissions for usbfs. */
122 { NULL, NULL, "/dev/vboxusb", false, "/proc/bus/usb", true, VINF_SUCCESS, "/proc/bus/usb", true, VINF_SUCCESS },
123 /* No environment, sysfs available but without access permissions. */
124 { NULL, NULL, "/dev/vboxusb", false, NULL, false, VERR_NO_MEMORY, "", true, VERR_VUSB_USB_DEVICE_PERMISSION },
125 /* No environment, sysfs available with access permissions, method-specific init failed. */
126 { NULL, NULL, "/dev/vboxusb", true, NULL, false, VERR_NO_MEMORY, "/dev/vboxusb", false, VERR_NO_MEMORY },
127 /* No environment, usbfs available but without access permissions. */
128 { NULL, NULL, NULL, false, "/proc/bus/usb", false, VERR_NO_MEMORY, "", true, VERR_VUSB_USBFS_PERMISSION },
129 /* No environment, usbfs available with access permissions, method-specific
130 * init failed. */
131 { NULL, NULL, NULL, false, "/proc/bus/usb", true, VERR_NO_MEMORY, "/proc/bus/usb", true, VERR_NO_MEMORY }
132};
133
134static void testInit(RTTEST hTest)
135{
136 RTTestSub(hTest, "Testing USBProxyServiceLinux initialisation");
137 for (unsigned i = 0; i < RT_ELEMENTS(s_testEnvironment); ++i)
138 {
139 USBProxyServiceLinux test(NULL);
140 test.testSetEnv(s_testEnvironment[i].pcszEnvUsb,
141 s_testEnvironment[i].pcszEnvUsbRoot);
142 test.testSetupInit(s_testEnvironment[i].pcszUsbfsRoot,
143 s_testEnvironment[i].fUsbfsAccessible,
144 s_testEnvironment[i].pcszDevicesRoot,
145 s_testEnvironment[i].fDevicesAccessible,
146 s_testEnvironment[i].rcMethodInit);
147 HRESULT hrc = test.init();
148 RTTESTI_CHECK_MSG(hrc == S_OK,
149 ("init() returned 0x%x (test index %i)!\n", hrc, i));
150 int rc = test.getLastError();
151 RTTESTI_CHECK_MSG(rc == s_testEnvironment[i].rcExpected,
152 ("getLastError() returned %Rrc (test index %i) instead of %Rrc!\n",
153 rc, i, s_testEnvironment[i].rcExpected));
154 const char *pcszDevicesRoot = test.testGetDevicesRoot();
155 RTTESTI_CHECK_MSG(!RTStrCmp(pcszDevicesRoot,
156 s_testEnvironment[i].pcszDevicesRootExpected),
157 ("testGetDevicesRoot() returned %s (test index %i) instead of %s!\n",
158 pcszDevicesRoot, i,
159 s_testEnvironment[i].pcszDevicesRootExpected));
160 bool fUsingUsbfs = test.testGetUsingUsbfs();
161 RTTESTI_CHECK_MSG( fUsingUsbfs
162 == s_testEnvironment[i].fUsingUsbfsExpected,
163 ("testGetUsingUsbfs() returned %RTbool (test index %i) instead of %RTbool!\n",
164 fUsingUsbfs, i,
165 s_testEnvironment[i].fUsingUsbfsExpected));
166 }
167}
168
169static struct
170{
171 const char *pacszDeviceAddresses[16];
172 const char *pacszAccessibleFiles[16];
173 const char *pcszRoot;
174 bool fIsDeviceNodes;
175 bool fAvailableExpected;
176} s_testCheckDeviceRoot[] =
177{
178 /* /dev/vboxusb accessible -> device nodes method available */
179 { { NULL }, { "/dev/vboxusb" }, "/dev/vboxusb", true, true },
180 /* /dev/vboxusb present but not accessible -> device nodes method not
181 * available */
182 { { NULL }, { NULL }, "/dev/vboxusb", true, false },
183 /* /proc/bus/usb available but empty -> usbfs method available (we can't
184 * really check in this case) */
185 { { NULL }, { NULL }, "/proc/bus/usb", false, true },
186 /* /proc/bus/usb available, one inaccessible device -> usbfs method not
187 * available */
188 { { "/proc/bus/usb/001/001" }, { NULL }, "/proc/bus/usb", false, false },
189 /* /proc/bus/usb available, one device of two inaccessible -> usbfs method
190 * not available */
191 { { "/proc/bus/usb/001/001", "/proc/bus/usb/002/002" },
192 { "/proc/bus/usb/001/001" }, "/proc/bus/usb", false, false },
193 /* /proc/bus/usb available, two accessible devices -> usbfs method
194 * available */
195 { { "/proc/bus/usb/001/001", "/proc/bus/usb/002/002" },
196 { "/proc/bus/usb/001/001", "/proc/bus/usb/002/002" },
197 "/proc/bus/usb", false, true }
198};
199
200static void testCheckDeviceRoot(RTTEST hTest)
201{
202 RTTestSub(hTest, "Testing the USBProxyLinuxCheckDeviceRoot API");
203 for (unsigned i = 0; i < RT_ELEMENTS(s_testCheckDeviceRoot); ++i)
204 {
205 TestUSBSetAvailableUsbfsDevices(s_testCheckDeviceRoot[i]
206 .pacszDeviceAddresses);
207 TestUSBSetAccessibleFiles(s_testCheckDeviceRoot[i]
208 .pacszAccessibleFiles);
209 bool fAvailable = USBProxyLinuxCheckDeviceRoot
210 (s_testCheckDeviceRoot[i].pcszRoot,
211 s_testCheckDeviceRoot[i].fIsDeviceNodes);
212 RTTESTI_CHECK_MSG( fAvailable
213 == s_testCheckDeviceRoot[i].fAvailableExpected,
214 ("USBProxyLinuxCheckDeviceRoot() returned %RTbool (test index %i) instead of %RTbool!\n",
215 fAvailable, i,
216 s_testCheckDeviceRoot[i].fAvailableExpected));
217 }
218}
219
220int main(void)
221{
222 /*
223 * Init the runtime, test and say hello.
224 */
225 RTTEST hTest;
226 RTEXITCODE rcExit = RTTestInitAndCreate("tstUSBProxyLinux", &hTest);
227 if (rcExit != RTEXITCODE_SUCCESS)
228 return rcExit;
229 RTTestBanner(hTest);
230
231 /*
232 * Run the tests.
233 */
234 testInit(hTest);
235 testCheckDeviceRoot(hTest);
236
237 /*
238 * Summary
239 */
240 return RTTestSummaryAndDestroy(hTest);
241}
Note: See TracBrowser for help on using the repository browser.

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