VirtualBox

source: vbox/trunk/src/VBox/ValidationKit/tests/usb/tdUsb1.py@ 59884

Last change on this file since 59884 was 59884, checked in by vboxsync, 9 years ago

ValidationKit/usb: Add a new gadget type using the dummy_hcd module to use gadgets on the machine executing the test

  • Property svn:eol-style set to LF
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 20.3 KB
Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3# $Id: tdUsb1.py 59884 2016-03-01 11:27:30Z vboxsync $
4
5"""
6VirtualBox Validation Kit - USB testcase and benchmark.
7"""
8
9__copyright__ = \
10"""
11Copyright (C) 2014-2016 Oracle Corporation
12
13This file is part of VirtualBox Open Source Edition (OSE), as
14available from http://www.virtualbox.org. This file is free software;
15you can redistribute it and/or modify it under the terms of the GNU
16General Public License (GPL) as published by the Free Software
17Foundation, in version 2 as it comes in the "COPYING" file of the
18VirtualBox OSE distribution. VirtualBox OSE is distributed in the
19hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
20
21The contents of this file may alternatively be used under the terms
22of the Common Development and Distribution License Version 1.0
23(CDDL) only, as it comes in the "COPYING.CDDL" file of the
24VirtualBox OSE distribution, in which case the provisions of the
25CDDL are applicable instead of those of the GPL.
26
27You may elect to license modified versions of this file under the
28terms and conditions of either the GPL or the CDDL or both.
29"""
30__version__ = "$Revision: 59884 $"
31
32
33# Standard Python imports.
34import os;
35import sys;
36import socket;
37
38# Only the main script needs to modify the path.
39try: __file__
40except: __file__ = sys.argv[0];
41g_ksValidationKitDir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))));
42sys.path.append(g_ksValidationKitDir);
43
44# Validation Kit imports.
45from testdriver import reporter;
46from testdriver import base;
47from testdriver import vbox;
48from testdriver import vboxcon;
49
50# USB gadget control import
51import usbgadget;
52
53class tdUsbBenchmark(vbox.TestDriver): # pylint: disable=R0902
54 """
55 USB benchmark.
56 """
57
58 # The available test devices
59 #
60 # The first key is the hostname of the host the test is running on.
61 # It contains a new dictionary with the attached gadgets based on the
62 # USB speed we want to test (Low, Full, High, Super).
63 # The parameters consist of the hostname of the gadget in the network
64 # and the hardware type.
65 kdGadgetParams = {
66 # The following is for local testing and not for the test lab.
67 'adaris': {
68 'Low': ('beaglebone', usbgadget.g_ksGadgetTypeBeaglebone),
69 'Full': ('beaglebone', usbgadget.g_ksGadgetTypeBeaglebone),
70 'High': ('beaglebone', usbgadget.g_ksGadgetTypeBeaglebone),
71 'Super': ('odroidxu3', usbgadget.g_ksGadgetTypeODroidXu3)
72 },
73 'archusb': {
74 'Low': ('beaglebone', usbgadget.g_ksGadgetTypeBeaglebone),
75 'Full': ('beaglebone', usbgadget.g_ksGadgetTypeBeaglebone),
76 'High': ('beaglebone', usbgadget.g_ksGadgetTypeBeaglebone),
77 'Super': ('odroidxu3', usbgadget.g_ksGadgetTypeODroidXu3)
78 },
79 };
80
81 # Mappings of USB controllers to supported USB device speeds.
82 kdUsbSpeedMappings = {
83 'OHCI': ['Low', 'Full'],
84 'EHCI': ['High'],
85 'XHCI': ['Low', 'Full', 'High', 'Super']
86 };
87
88 def __init__(self):
89 vbox.TestDriver.__init__(self);
90 self.asRsrcs = None;
91 self.asTestVMsDef = ['tst-arch'];
92 self.asTestVMs = self.asTestVMsDef;
93 self.asSkipVMs = [];
94 self.asVirtModesDef = ['hwvirt', 'hwvirt-np', 'raw'];
95 self.asVirtModes = self.asVirtModesDef;
96 self.acCpusDef = [1, 2,];
97 self.acCpus = self.acCpusDef;
98 self.asUsbCtrlsDef = ['OHCI', 'EHCI', 'XHCI'];
99 self.asUsbCtrls = self.asUsbCtrlsDef;
100 self.asUsbSpeedDef = ['Low', 'Full', 'High', 'Super'];
101 self.asUsbSpeed = self.asUsbSpeedDef;
102 self.asUsbTestsDef = ['Compliance', 'Reattach'];
103 self.asUsbTests = self.asUsbTestsDef;
104 self.cUsbReattachCyclesDef = 100;
105 self.cUsbReattachCycles = self.cUsbReattachCyclesDef;
106 self.sHostname = socket.gethostname().lower();
107 self.fUseTxs = True;
108
109 #
110 # Overridden methods.
111 #
112 def showUsage(self):
113 rc = vbox.TestDriver.showUsage(self);
114 reporter.log('');
115 reporter.log('tdUsb1 Options:');
116 reporter.log(' --virt-modes <m1[:m2[:]]');
117 reporter.log(' Default: %s' % (':'.join(self.asVirtModesDef)));
118 reporter.log(' --cpu-counts <c1[:c2[:]]');
119 reporter.log(' Default: %s' % (':'.join(str(c) for c in self.acCpusDef)));
120 reporter.log(' --test-vms <vm1[:vm2[:...]]>');
121 reporter.log(' Test the specified VMs in the given order. Use this to change');
122 reporter.log(' the execution order or limit the choice of VMs');
123 reporter.log(' Default: %s (all)' % (':'.join(self.asTestVMsDef)));
124 reporter.log(' --skip-vms <vm1[:vm2[:...]]>');
125 reporter.log(' Skip the specified VMs when testing.');
126 reporter.log(' --usb-ctrls <u1[:u2[:]]');
127 reporter.log(' Default: %s' % (':'.join(str(c) for c in self.asUsbCtrlsDef)));
128 reporter.log(' --usb-speed <s1[:s2[:]]');
129 reporter.log(' Default: %s' % (':'.join(str(c) for c in self.asUsbSpeedDef)));
130 reporter.log(' --usb-tests <s1[:s2[:]]');
131 reporter.log(' Default: %s' % (':'.join(str(c) for c in self.asUsbTestsDef)));
132 reporter.log(' --usb-reattach-cycles <cycles>');
133 reporter.log(' Default: %s' % (self.cUsbReattachCyclesDef));
134 reporter.log(' --local');
135 reporter.log(' Don\'t use TXS for communication with the gadget but do everything');
136 reporter.log(' on this host');
137 return rc;
138
139 def parseOption(self, asArgs, iArg): # pylint: disable=R0912,R0915
140 if asArgs[iArg] == '--virt-modes':
141 iArg += 1;
142 if iArg >= len(asArgs): raise base.InvalidOption('The "--virt-modes" takes a colon separated list of modes');
143 self.asVirtModes = asArgs[iArg].split(':');
144 for s in self.asVirtModes:
145 if s not in self.asVirtModesDef:
146 raise base.InvalidOption('The "--virt-modes" value "%s" is not valid; valid values are: %s' \
147 % (s, ' '.join(self.asVirtModesDef)));
148 elif asArgs[iArg] == '--cpu-counts':
149 iArg += 1;
150 if iArg >= len(asArgs): raise base.InvalidOption('The "--cpu-counts" takes a colon separated list of cpu counts');
151 self.acCpus = [];
152 for s in asArgs[iArg].split(':'):
153 try: c = int(s);
154 except: raise base.InvalidOption('The "--cpu-counts" value "%s" is not an integer' % (s,));
155 if c <= 0: raise base.InvalidOption('The "--cpu-counts" value "%s" is zero or negative' % (s,));
156 self.acCpus.append(c);
157 elif asArgs[iArg] == '--test-vms':
158 iArg += 1;
159 if iArg >= len(asArgs): raise base.InvalidOption('The "--test-vms" takes colon separated list');
160 self.asTestVMs = asArgs[iArg].split(':');
161 for s in self.asTestVMs:
162 if s not in self.asTestVMsDef:
163 raise base.InvalidOption('The "--test-vms" value "%s" is not valid; valid values are: %s' \
164 % (s, ' '.join(self.asTestVMsDef)));
165 elif asArgs[iArg] == '--skip-vms':
166 iArg += 1;
167 if iArg >= len(asArgs): raise base.InvalidOption('The "--skip-vms" takes colon separated list');
168 self.asSkipVMs = asArgs[iArg].split(':');
169 for s in self.asSkipVMs:
170 if s not in self.asTestVMsDef:
171 reporter.log('warning: The "--test-vms" value "%s" does not specify any of our test VMs.' % (s));
172 elif asArgs[iArg] == '--usb-ctrls':
173 iArg += 1;
174 if iArg >= len(asArgs): raise base.InvalidOption('The "--usb-ctrls" takes a colon separated list of USB controllers');
175 self.asUsbCtrls = asArgs[iArg].split(':');
176 for s in self.asUsbCtrls:
177 if s not in self.asUsbCtrlsDef:
178 reporter.log('warning: The "--usb-ctrls" value "%s" is not a valid USB controller.' % (s));
179 elif asArgs[iArg] == '--usb-speed':
180 iArg += 1;
181 if iArg >= len(asArgs): raise base.InvalidOption('The "--usb-speed" takes a colon separated list of USB speeds');
182 self.asUsbSpeed = asArgs[iArg].split(':');
183 for s in self.asUsbSpeed:
184 if s not in self.asUsbSpeedDef:
185 reporter.log('warning: The "--usb-speed" value "%s" is not a valid USB speed.' % (s));
186 elif asArgs[iArg] == '--usb-tests':
187 iArg += 1;
188 if iArg >= len(asArgs): raise base.InvalidOption('The "--usb-tests" takes a colon separated list of USB tests');
189 self.asUsbTests = asArgs[iArg].split(':');
190 for s in self.asUsbTests:
191 if s not in self.asUsbTestsDef:
192 reporter.log('warning: The "--usb-tests" value "%s" is not a valid USB test.' % (s));
193 elif asArgs[iArg] == '--usb-reattach-cycles':
194 iArg += 1;
195 if iArg >= len(asArgs): raise base.InvalidOption('The "--usb-reattach-cycles" takes cycle count');
196 try: self.cUsbReattachCycles = int(asArgs[iArg]);
197 except: raise base.InvalidOption('The "--usb-reattach-cycles" value "%s" is not an integer' \
198 % (asArgs[iArg],));
199 if self.cUsbReattachCycles <= 0:
200 raise base.InvalidOption('The "--usb-reattach-cycles" value "%s" is zero or negative.' \
201 % (self.cUsbReattachCycles,));
202 elif asArgs[iArg] == '--local':
203 self.fUseTxs = False;
204 else:
205 return vbox.TestDriver.parseOption(self, asArgs, iArg);
206 return iArg + 1;
207
208 def completeOptions(self):
209 # Remove skipped VMs from the test list.
210 for sVM in self.asSkipVMs:
211 try: self.asTestVMs.remove(sVM);
212 except: pass;
213
214 return vbox.TestDriver.completeOptions(self);
215
216 def getResourceSet(self):
217 # Construct the resource list the first time it's queried.
218 if self.asRsrcs is None:
219 self.asRsrcs = [];
220
221 if 'tst-arch' in self.asTestVMs:
222 self.asRsrcs.append('4.2/usb/tst-arch.vdi');
223
224 return self.asRsrcs;
225
226 def actionConfig(self):
227
228 # Some stupid trickery to guess the location of the iso. ## fixme - testsuite unzip ++
229 sVBoxValidationKit_iso = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../VBoxValidationKit.iso'));
230 if not os.path.isfile(sVBoxValidationKit_iso):
231 sVBoxValidationKit_iso = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../VBoxTestSuite.iso'));
232 if not os.path.isfile(sVBoxValidationKit_iso):
233 sVBoxValidationKit_iso = '/mnt/ramdisk/vbox/svn/trunk/validationkit/VBoxValidationKit.iso';
234 if not os.path.isfile(sVBoxValidationKit_iso):
235 sVBoxValidationKit_iso = '/mnt/ramdisk/vbox/svn/trunk/testsuite/VBoxTestSuite.iso';
236 if not os.path.isfile(sVBoxValidationKit_iso):
237 sCur = os.getcwd();
238 for i in range(0, 10):
239 sVBoxValidationKit_iso = os.path.join(sCur, 'validationkit/VBoxValidationKit.iso');
240 if os.path.isfile(sVBoxValidationKit_iso):
241 break;
242 sVBoxValidationKit_iso = os.path.join(sCur, 'testsuite/VBoxTestSuite.iso');
243 if os.path.isfile(sVBoxValidationKit_iso):
244 break;
245 sCur = os.path.abspath(os.path.join(sCur, '..'));
246 if i is None: pass; # shut up pychecker/pylint.
247 if not os.path.isfile(sVBoxValidationKit_iso):
248 sVBoxValidationKit_iso = '/home/bird/validationkit/VBoxValidationKit.iso';
249 if not os.path.isfile(sVBoxValidationKit_iso):
250 sVBoxValidationKit_iso = '/home/bird/testsuite/VBoxTestSuite.iso';
251
252 # Make sure vboxapi has been imported so we can use the constants.
253 if not self.importVBoxApi():
254 return False;
255
256 #
257 # Configure the VMs we're going to use.
258 #
259
260 # Linux VMs
261 if 'tst-arch' in self.asTestVMs:
262 oVM = self.createTestVM('tst-arch', 1, '4.2/usb/tst-arch.vdi', sKind = 'ArchLinux_64', fIoApic = True, \
263 eNic0AttachType = vboxcon.NetworkAttachmentType_NAT, \
264 sDvdImage = sVBoxValidationKit_iso);
265 if oVM is None:
266 return False;
267
268 return True;
269
270 def actionExecute(self):
271 """
272 Execute the testcase.
273 """
274 fRc = self.testUsb();
275 return fRc;
276
277 def getGadgetParams(self, sHostname, sSpeed):
278 """
279 Returns the gadget hostname and type from the
280 given hostname the test is running on and device speed we want to test.
281 """
282 kdGadgetsConfigured = self.kdGadgetParams.get(sHostname);
283 if kdGadgetsConfigured is not None:
284 return kdGadgetsConfigured.get(sSpeed);
285
286 return (None, None);
287
288 #
289 # Test execution helpers.
290 #
291 def testUsbCompliance(self, oSession, oTxsSession, sUsbCtrl, sSpeed):
292 """
293 Test VirtualBoxs USB stack in a VM.
294 """
295 # Get configured USB test devices from hostname we are running on
296 if self.fUseTxs is True:
297 sGadgetHost, sGadgetType = self.getGadgetParams(self.sHostname, sSpeed);
298 else:
299 sGadgetHost = 'dummy';
300 sGadgetType = usbgadget.g_ksGadgetTypeDummyHcd;
301
302 # Create device filter
303 fRc = oSession.addUsbDeviceFilter('Compliance device', '0525', 'a4a0');
304 if fRc is True:
305 oUsbGadget = usbgadget.UsbGadget();
306 reporter.log('Connecting to gadget: ' + sGadgetType);
307 fRc = oUsbGadget.connectTo(30 * 1000, sGadgetType, self.fUseTxs, sGadgetHost);
308 if fRc is True:
309 reporter.log('Connect succeeded');
310 fRc = oUsbGadget.impersonate(usbgadget.g_ksGadgetImpersonationTest);
311 if fRc is True:
312
313 # Wait a moment to let the USB device appear
314 self.sleep(3);
315
316 tupCmdLine = ('UsbTest', );
317 # Exclude a few tests which hang and cause a timeout, need investigation.
318 if sUsbCtrl is 'XHCI':
319 tupCmdLine = tupCmdLine + ('--exclude', '10', '--exclude', '24');
320
321 fRc = self.txsRunTest(oTxsSession, 'UsbTest', 3600 * 1000, \
322 '${CDROM}/${OS/ARCH}/UsbTest${EXESUFF}', tupCmdLine);
323 if not fRc:
324 reporter.testFailure('Running USB test utility failed');
325
326 else:
327 reporter.testFailure('Failed to impersonate test device');
328
329 oUsbGadget.disconnectFrom();
330 else:
331 reporter.testFailure('Failed to connect to USB gadget');
332 else:
333 reporter.testFailure('Failed to create USB device filter');
334
335 return fRc;
336
337 def testUsbReattach(self, oSession, oTxsSession, sUsbCtrl, sSpeed): # pylint: disable=W0613
338 """
339 Tests that rapid connect/disconnect cycles work.
340 """
341 # Get configured USB test devices from hostname we are running on
342 if self.fUseTxs is True:
343 sGadgetHost, sGadgetType = self.getGadgetParams(self.sHostname, sSpeed);
344 else:
345 sGadgetHost = 'dummy';
346 sGadgetType = usbgadget.g_ksGadgetTypeDummyHcd;
347
348 # Create device filter
349 fRc = oSession.addUsbDeviceFilter('Compliance device', '0525', 'a4a0');
350 if fRc is True:
351 oUsbGadget = usbgadget.UsbGadget();
352 reporter.log('Connecting to gadget: ' + sGadgetType);
353 fRc = oUsbGadget.connectTo(30 * 1000, sGadgetType, self.fUseTxs, sGadgetHost);
354 if fRc is True:
355 reporter.log('Connect succeeded');
356 fRc = oUsbGadget.impersonate(usbgadget.g_ksGadgetImpersonationTest);
357 if fRc is True:
358
359 self.sleep(1);
360
361 # Do a rapid disconnect reconnect cycle. Wait a second before disconnecting
362 # again or it will happen so fast that the VM can't attach the new device.
363 # @todo: Get rid of the constant wait and use an event to get notified when
364 # the device was attached.
365 for iCycle in xrange (0, self.cUsbReattachCycles):
366 fRc = oUsbGadget.disconnectUsb();
367 fRc = fRc and oUsbGadget.connectUsb();
368 if not fRc:
369 reporter.testFailure('Reattach cycle %s failed on the gadget device' % (iCycle));
370 break;
371 self.sleep(1);
372
373 else:
374 reporter.testFailure('Failed to impersonate test device');
375
376 oUsbGadget.disconnectFrom();
377 else:
378 reporter.testFailure('Failed to connect to USB gadget');
379 else:
380 reporter.testFailure('Failed to create USB device filter');
381
382 return fRc;
383
384 def testUsbOneCfg(self, sVmName, sUsbCtrl, sSpeed, sUsbTest):
385 """
386 Runs the specified VM thru one specified test.
387
388 Returns a success indicator on the general test execution. This is not
389 the actual test result.
390 """
391 oVM = self.getVmByName(sVmName);
392
393 # Reconfigure the VM
394 fRc = True;
395 oSession = self.openSession(oVM);
396 if oSession is not None:
397 fRc = fRc and oSession.enableVirtEx(True);
398 fRc = fRc and oSession.enableNestedPaging(True);
399
400 # Make sure controllers are disabled initially.
401 fRc = fRc and oSession.enableUsbOhci(False);
402 fRc = fRc and oSession.enableUsbEhci(False);
403 fRc = fRc and oSession.enableUsbXhci(False);
404
405 if sUsbCtrl == 'OHCI':
406 fRc = fRc and oSession.enableUsbOhci(True);
407 elif sUsbCtrl == 'EHCI':
408 fRc = fRc and oSession.enableUsbEhci(True);
409 elif sUsbCtrl == 'XHCI':
410 fRc = fRc and oSession.enableUsbXhci(True);
411 fRc = fRc and oSession.saveSettings();
412 fRc = oSession.close() and fRc and True; # pychecker hack.
413 oSession = None;
414 else:
415 fRc = False;
416
417 # Start up.
418 if fRc is True:
419 self.logVmInfo(oVM);
420 oSession, oTxsSession = self.startVmAndConnectToTxsViaTcp(sVmName, fCdWait = False, fNatForwardingForTxs = False);
421 if oSession is not None:
422 self.addTask(oSession);
423
424 # Fudge factor - Allow the guest to finish starting up.
425 self.sleep(5);
426
427 if sUsbTest == 'Compliance':
428 fRc = self.testUsbCompliance(oSession, oTxsSession, sUsbCtrl, sSpeed);
429 elif sUsbTest == 'Reattach':
430 fRc = self.testUsbReattach(oSession, oTxsSession, sUsbCtrl, sSpeed);
431
432 # cleanup.
433 self.removeTask(oTxsSession);
434 self.terminateVmBySession(oSession)
435 else:
436 fRc = False;
437 return fRc;
438
439 def testUsbForOneVM(self, sVmName):
440 """
441 Runs one VM thru the various configurations.
442 """
443 reporter.testStart(sVmName);
444 for sUsbCtrl in self.asUsbCtrls:
445 reporter.testStart(sUsbCtrl)
446 for sUsbSpeed in self.asUsbSpeed:
447 asSupportedSpeeds = self.kdUsbSpeedMappings.get(sUsbCtrl);
448 if sUsbSpeed in asSupportedSpeeds:
449 reporter.testStart(sUsbSpeed)
450 for sUsbTest in self.asUsbTests:
451 reporter.testStart(sUsbTest)
452 fRc = self.testUsbOneCfg(sVmName, sUsbCtrl, sUsbSpeed, sUsbTest);
453 reporter.testDone();
454 reporter.testDone();
455 reporter.testDone();
456 reporter.testDone();
457 return fRc;
458
459 def testUsb(self):
460 """
461 Executes USB test.
462 """
463
464 reporter.log("Running on host: " + self.sHostname);
465
466 # Loop thru the test VMs.
467 for sVM in self.asTestVMs:
468 # run test on the VM.
469 fRc = self.testUsbForOneVM(sVM);
470
471 return fRc;
472
473
474
475if __name__ == '__main__':
476 sys.exit(tdUsbBenchmark().main(sys.argv));
477
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