VirtualBox

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

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

ValidationKit/tdUsb1: Disable a few tests for super speed as they fail currently, need investigation (looks like a bug on the USB/IP gadget side)

  • Property svn:eol-style set to LF
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 22.0 KB
Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3# $Id: tdUsb1.py 60885 2016-05-09 09:16:02Z 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: 60885 $"
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 'adaris': {
67 'Low': ('usbtest.de.oracle.com', None),
68 'Full': ('usbtest.de.oracle.com', None),
69 'High': ('usbtest.de.oracle.com', None),
70 'Super': ('usbtest.de.oracle.com', None)
71 },
72 };
73
74 # Mappings of USB controllers to supported USB device speeds.
75 kdUsbSpeedMappings = {
76 'OHCI': ['Low', 'Full'],
77 'EHCI': ['High'],
78 'XHCI': ['Low', 'Full', 'High', 'Super']
79 };
80
81 # Tests currently disabled because they fail, need investigation.
82 kdUsbTestsDisabled = {
83 'Low': [],
84 'Full': [],
85 'High': [],
86 'Super': [4, 6, 10, 11, 18, 20, 24]
87 };
88
89 def __init__(self):
90 vbox.TestDriver.__init__(self);
91 self.asRsrcs = None;
92 self.asTestVMsDef = ['tst-arch'];
93 self.asTestVMs = self.asTestVMsDef;
94 self.asSkipVMs = [];
95 self.asVirtModesDef = ['hwvirt', 'hwvirt-np', 'raw'];
96 self.asVirtModes = self.asVirtModesDef;
97 self.acCpusDef = [1, 2,];
98 self.acCpus = self.acCpusDef;
99 self.asUsbCtrlsDef = ['OHCI', 'EHCI', 'XHCI'];
100 self.asUsbCtrls = self.asUsbCtrlsDef;
101 self.asUsbSpeedDef = ['Low', 'Full', 'High', 'Super'];
102 self.asUsbSpeed = self.asUsbSpeedDef;
103 self.asUsbTestsDef = ['Compliance', 'Reattach'];
104 self.asUsbTests = self.asUsbTestsDef;
105 self.cUsbReattachCyclesDef = 100;
106 self.cUsbReattachCycles = self.cUsbReattachCyclesDef;
107 self.sHostname = socket.gethostname().lower();
108 self.sGadgetHostnameDef = 'usbtest.de.oracle.com';
109 self.uGadgetPortDef = None;
110
111 #
112 # Overridden methods.
113 #
114 def showUsage(self):
115 rc = vbox.TestDriver.showUsage(self);
116 reporter.log('');
117 reporter.log('tdUsb1 Options:');
118 reporter.log(' --virt-modes <m1[:m2[:]]');
119 reporter.log(' Default: %s' % (':'.join(self.asVirtModesDef)));
120 reporter.log(' --cpu-counts <c1[:c2[:]]');
121 reporter.log(' Default: %s' % (':'.join(str(c) for c in self.acCpusDef)));
122 reporter.log(' --test-vms <vm1[:vm2[:...]]>');
123 reporter.log(' Test the specified VMs in the given order. Use this to change');
124 reporter.log(' the execution order or limit the choice of VMs');
125 reporter.log(' Default: %s (all)' % (':'.join(self.asTestVMsDef)));
126 reporter.log(' --skip-vms <vm1[:vm2[:...]]>');
127 reporter.log(' Skip the specified VMs when testing.');
128 reporter.log(' --usb-ctrls <u1[:u2[:]]');
129 reporter.log(' Default: %s' % (':'.join(str(c) for c in self.asUsbCtrlsDef)));
130 reporter.log(' --usb-speed <s1[:s2[:]]');
131 reporter.log(' Default: %s' % (':'.join(str(c) for c in self.asUsbSpeedDef)));
132 reporter.log(' --usb-tests <s1[:s2[:]]');
133 reporter.log(' Default: %s' % (':'.join(str(c) for c in self.asUsbTestsDef)));
134 reporter.log(' --usb-reattach-cycles <cycles>');
135 reporter.log(' Default: %s' % (self.cUsbReattachCyclesDef));
136 reporter.log(' --hostname: <hostname>');
137 reporter.log(' Default: %s' % (self.sHostname));
138 reporter.log(' --default-gadget-host <hostname>');
139 reporter.log(' Default: %s' % (self.sGadgetHostnameDef));
140 reporter.log(' --default-gadget-port <port>');
141 reporter.log(' Default: %s' % (6042));
142 return rc;
143
144 def parseOption(self, asArgs, iArg): # pylint: disable=R0912,R0915
145 if asArgs[iArg] == '--virt-modes':
146 iArg += 1;
147 if iArg >= len(asArgs): raise base.InvalidOption('The "--virt-modes" takes a colon separated list of modes');
148 self.asVirtModes = asArgs[iArg].split(':');
149 for s in self.asVirtModes:
150 if s not in self.asVirtModesDef:
151 raise base.InvalidOption('The "--virt-modes" value "%s" is not valid; valid values are: %s' \
152 % (s, ' '.join(self.asVirtModesDef)));
153 elif asArgs[iArg] == '--cpu-counts':
154 iArg += 1;
155 if iArg >= len(asArgs): raise base.InvalidOption('The "--cpu-counts" takes a colon separated list of cpu counts');
156 self.acCpus = [];
157 for s in asArgs[iArg].split(':'):
158 try: c = int(s);
159 except: raise base.InvalidOption('The "--cpu-counts" value "%s" is not an integer' % (s,));
160 if c <= 0: raise base.InvalidOption('The "--cpu-counts" value "%s" is zero or negative' % (s,));
161 self.acCpus.append(c);
162 elif asArgs[iArg] == '--test-vms':
163 iArg += 1;
164 if iArg >= len(asArgs): raise base.InvalidOption('The "--test-vms" takes colon separated list');
165 self.asTestVMs = asArgs[iArg].split(':');
166 for s in self.asTestVMs:
167 if s not in self.asTestVMsDef:
168 raise base.InvalidOption('The "--test-vms" value "%s" is not valid; valid values are: %s' \
169 % (s, ' '.join(self.asTestVMsDef)));
170 elif asArgs[iArg] == '--skip-vms':
171 iArg += 1;
172 if iArg >= len(asArgs): raise base.InvalidOption('The "--skip-vms" takes colon separated list');
173 self.asSkipVMs = asArgs[iArg].split(':');
174 for s in self.asSkipVMs:
175 if s not in self.asTestVMsDef:
176 reporter.log('warning: The "--test-vms" value "%s" does not specify any of our test VMs.' % (s));
177 elif asArgs[iArg] == '--usb-ctrls':
178 iArg += 1;
179 if iArg >= len(asArgs): raise base.InvalidOption('The "--usb-ctrls" takes a colon separated list of USB controllers');
180 self.asUsbCtrls = asArgs[iArg].split(':');
181 for s in self.asUsbCtrls:
182 if s not in self.asUsbCtrlsDef:
183 reporter.log('warning: The "--usb-ctrls" value "%s" is not a valid USB controller.' % (s));
184 elif asArgs[iArg] == '--usb-speed':
185 iArg += 1;
186 if iArg >= len(asArgs): raise base.InvalidOption('The "--usb-speed" takes a colon separated list of USB speeds');
187 self.asUsbSpeed = asArgs[iArg].split(':');
188 for s in self.asUsbSpeed:
189 if s not in self.asUsbSpeedDef:
190 reporter.log('warning: The "--usb-speed" value "%s" is not a valid USB speed.' % (s));
191 elif asArgs[iArg] == '--usb-tests':
192 iArg += 1;
193 if iArg >= len(asArgs): raise base.InvalidOption('The "--usb-tests" takes a colon separated list of USB tests');
194 self.asUsbTests = asArgs[iArg].split(':');
195 for s in self.asUsbTests:
196 if s not in self.asUsbTestsDef:
197 reporter.log('warning: The "--usb-tests" value "%s" is not a valid USB test.' % (s));
198 elif asArgs[iArg] == '--usb-reattach-cycles':
199 iArg += 1;
200 if iArg >= len(asArgs): raise base.InvalidOption('The "--usb-reattach-cycles" takes cycle count');
201 try: self.cUsbReattachCycles = int(asArgs[iArg]);
202 except: raise base.InvalidOption('The "--usb-reattach-cycles" value "%s" is not an integer' \
203 % (asArgs[iArg],));
204 if self.cUsbReattachCycles <= 0:
205 raise base.InvalidOption('The "--usb-reattach-cycles" value "%s" is zero or negative.' \
206 % (self.cUsbReattachCycles,));
207 elif asArgs[iArg] == '--hostname':
208 iArg += 1;
209 if iArg >= len(asArgs): raise base.InvalidOption('The "--hostname" takes a hostname');
210 self.sHostname = asArgs[iArg];
211 elif asArgs[iArg] == '--default-gadget-host':
212 iArg += 1;
213 if iArg >= len(asArgs): raise base.InvalidOption('The "--default-gadget-host" takes a hostname');
214 self.sGadgetHostnameDef = asArgs[iArg];
215 elif asArgs[iArg] == '--default-gadget-port':
216 iArg += 1;
217 if iArg >= len(asArgs): raise base.InvalidOption('The "--default-gadget-port" takes port number');
218 try: self.uGadgetPortDef = int(asArgs[iArg]);
219 except: raise base.InvalidOption('The "--default-gadget-port" value "%s" is not an integer' \
220 % (asArgs[iArg],));
221 if self.uGadgetPortDef <= 0:
222 raise base.InvalidOption('The "--default-gadget-port" value "%s" is zero or negative.' \
223 % (self.uGadgetPortDef,));
224 else:
225 return vbox.TestDriver.parseOption(self, asArgs, iArg);
226 return iArg + 1;
227
228 def completeOptions(self):
229 # Remove skipped VMs from the test list.
230 for sVM in self.asSkipVMs:
231 try: self.asTestVMs.remove(sVM);
232 except: pass;
233
234 return vbox.TestDriver.completeOptions(self);
235
236 def getResourceSet(self):
237 # Construct the resource list the first time it's queried.
238 if self.asRsrcs is None:
239 self.asRsrcs = [];
240
241 if 'tst-arch' in self.asTestVMs:
242 self.asRsrcs.append('4.2/usb/tst-arch.vdi');
243
244 return self.asRsrcs;
245
246 def actionConfig(self):
247
248 # Some stupid trickery to guess the location of the iso. ## fixme - testsuite unzip ++
249 sVBoxValidationKit_iso = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../VBoxValidationKit.iso'));
250 if not os.path.isfile(sVBoxValidationKit_iso):
251 sVBoxValidationKit_iso = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../VBoxTestSuite.iso'));
252 if not os.path.isfile(sVBoxValidationKit_iso):
253 sVBoxValidationKit_iso = '/mnt/ramdisk/vbox/svn/trunk/validationkit/VBoxValidationKit.iso';
254 if not os.path.isfile(sVBoxValidationKit_iso):
255 sVBoxValidationKit_iso = '/mnt/ramdisk/vbox/svn/trunk/testsuite/VBoxTestSuite.iso';
256 if not os.path.isfile(sVBoxValidationKit_iso):
257 sCur = os.getcwd();
258 for i in range(0, 10):
259 sVBoxValidationKit_iso = os.path.join(sCur, 'validationkit/VBoxValidationKit.iso');
260 if os.path.isfile(sVBoxValidationKit_iso):
261 break;
262 sVBoxValidationKit_iso = os.path.join(sCur, 'testsuite/VBoxTestSuite.iso');
263 if os.path.isfile(sVBoxValidationKit_iso):
264 break;
265 sCur = os.path.abspath(os.path.join(sCur, '..'));
266 if i is None: pass; # shut up pychecker/pylint.
267 if not os.path.isfile(sVBoxValidationKit_iso):
268 sVBoxValidationKit_iso = '/home/bird/validationkit/VBoxValidationKit.iso';
269 if not os.path.isfile(sVBoxValidationKit_iso):
270 sVBoxValidationKit_iso = '/home/bird/testsuite/VBoxTestSuite.iso';
271
272 # Make sure vboxapi has been imported so we can use the constants.
273 if not self.importVBoxApi():
274 return False;
275
276 #
277 # Configure the VMs we're going to use.
278 #
279
280 # Linux VMs
281 if 'tst-arch' in self.asTestVMs:
282 oVM = self.createTestVM('tst-arch', 1, '4.2/usb/tst-arch.vdi', sKind = 'ArchLinux_64', fIoApic = True, \
283 eNic0AttachType = vboxcon.NetworkAttachmentType_NAT, \
284 sDvdImage = sVBoxValidationKit_iso);
285 if oVM is None:
286 return False;
287
288 return True;
289
290 def actionExecute(self):
291 """
292 Execute the testcase.
293 """
294 fRc = self.testUsb();
295 return fRc;
296
297 def getGadgetParams(self, sHostname, sSpeed):
298 """
299 Returns the gadget hostname and port from the
300 given hostname the test is running on and device speed we want to test.
301 """
302 kdGadgetsConfigured = self.kdGadgetParams.get(sHostname);
303 if kdGadgetsConfigured is not None:
304 return kdGadgetsConfigured.get(sSpeed);
305
306 return (self.sGadgetHostnameDef, self.uGadgetPortDef);
307
308 #
309 # Test execution helpers.
310 #
311 def testUsbCompliance(self, oSession, oTxsSession, sUsbCtrl, sSpeed):
312 """
313 Test VirtualBoxs USB stack in a VM.
314 """
315 # Get configured USB test devices from hostname we are running on
316 sGadgetHost, uGadgetPort = self.getGadgetParams(self.sHostname, sSpeed);
317
318 oUsbGadget = usbgadget.UsbGadget();
319 reporter.log('Connecting to UTS: ' + sGadgetHost);
320 fRc = oUsbGadget.connectTo(30 * 1000, sGadgetHost, uPort = uGadgetPort);
321 if fRc is True:
322 reporter.log('Connect succeeded');
323 self.oVBox.host.addUSBDeviceSource('USBIP', sGadgetHost, sGadgetHost + (':%s' % oUsbGadget.getUsbIpPort()), [], []);
324
325 fSuperSpeed = False;
326 if sSpeed == 'Super':
327 fSuperSpeed = True;
328
329 # Create test device gadget and a filter to attach the device automatically.
330 fRc = oUsbGadget.impersonate(usbgadget.g_ksGadgetImpersonationTest, fSuperSpeed);
331 if fRc is True:
332 iBusId, _ = oUsbGadget.getGadgetBusAndDevId();
333 fRc = oSession.addUsbDeviceFilter('Compliance device', sVendorId = '0525', sProductId = 'a4a0', \
334 sPort = format(iBusId, 'x'));
335 if fRc is True:
336
337 # Wait a moment to let the USB device appear
338 self.sleep(3);
339
340 tupCmdLine = ('UsbTest', );
341 # Exclude a few tests which hang and cause a timeout, need investigation.
342 lstTestsExclude = self.kdUsbTestsDisabled.get(sSpeed);
343 for iTestExclude in lstTestsExclude:
344 tupCmdLine = tupCmdLine + ('--exclude', str(iTestExclude));
345
346 fRc = self.txsRunTest(oTxsSession, 'UsbTest', 3600 * 1000, \
347 '${CDROM}/${OS/ARCH}/UsbTest${EXESUFF}', tupCmdLine);
348 if not fRc:
349 reporter.testFailure('Running USB test utility failed');
350 else:
351 reporter.testFailure('Failed to impersonate test device');
352
353 oUsbGadget.disconnectFrom();
354 else:
355 reporter.testFailure('Failed to create USB device filter');
356
357 self.oVBox.host.removeUSBDeviceSource(sGadgetHost);
358 else:
359 reporter.testFailure('Failed to connect to USB gadget');
360
361 return fRc;
362
363 def testUsbReattach(self, oSession, oTxsSession, sUsbCtrl, sSpeed): # pylint: disable=W0613
364 """
365 Tests that rapid connect/disconnect cycles work.
366 """
367 # Get configured USB test devices from hostname we are running on
368 sGadgetHost, uGadgetPort = self.getGadgetParams(self.sHostname, sSpeed);
369
370 oUsbGadget = usbgadget.UsbGadget();
371 reporter.log('Connecting to UTS: ' + sGadgetHost);
372 fRc = oUsbGadget.connectTo(30 * 1000, sGadgetHost, uPort = uGadgetPort);
373 if fRc is True:
374 self.oVBox.host.addUSBDeviceSource('USBIP', sGadgetHost, sGadgetHost + (':%s' % oUsbGadget.getUsbIpPort()), [], []);
375
376 fSuperSpeed = False;
377 if sSpeed == 'Super':
378 fSuperSpeed = True;
379
380 # Create test device gadget and a filter to attach the device automatically.
381 fRc = oUsbGadget.impersonate(usbgadget.g_ksGadgetImpersonationTest, fSuperSpeed);
382 if fRc is True:
383 iBusId, _ = oUsbGadget.getGadgetBusAndDevId();
384 fRc = oSession.addUsbDeviceFilter('Compliance device', sVendorId = '0525', sProductId = 'a4a0', \
385 sPort = str(iBusId));
386 if fRc is True:
387
388 # Wait a moment to let the USB device appear
389 self.sleep(3);
390
391 # Do a rapid disconnect reconnect cycle. Wait a second before disconnecting
392 # again or it will happen so fast that the VM can't attach the new device.
393 # @todo: Get rid of the constant wait and use an event to get notified when
394 # the device was attached.
395 for iCycle in xrange (0, self.cUsbReattachCycles):
396 fRc = oUsbGadget.disconnectUsb();
397 fRc = fRc and oUsbGadget.connectUsb();
398 if not fRc:
399 reporter.testFailure('Reattach cycle %s failed on the gadget device' % (iCycle));
400 break;
401 self.sleep(1);
402
403 else:
404 reporter.testFailure('Failed to impersonate test device');
405
406 oUsbGadget.disconnectFrom();
407 else:
408 reporter.testFailure('Failed to connect to USB gadget');
409 else:
410 reporter.testFailure('Failed to create USB device filter');
411
412 return fRc;
413
414 def testUsbOneCfg(self, sVmName, sUsbCtrl, sSpeed, sUsbTest):
415 """
416 Runs the specified VM thru one specified test.
417
418 Returns a success indicator on the general test execution. This is not
419 the actual test result.
420 """
421 oVM = self.getVmByName(sVmName);
422
423 # Reconfigure the VM
424 fRc = True;
425 oSession = self.openSession(oVM);
426 if oSession is not None:
427 fRc = fRc and oSession.enableVirtEx(True);
428 fRc = fRc and oSession.enableNestedPaging(True);
429
430 # Make sure controllers are disabled initially.
431 fRc = fRc and oSession.enableUsbOhci(False);
432 fRc = fRc and oSession.enableUsbEhci(False);
433 fRc = fRc and oSession.enableUsbXhci(False);
434
435 if sUsbCtrl == 'OHCI':
436 fRc = fRc and oSession.enableUsbOhci(True);
437 elif sUsbCtrl == 'EHCI':
438 fRc = fRc and oSession.enableUsbEhci(True);
439 elif sUsbCtrl == 'XHCI':
440 fRc = fRc and oSession.enableUsbXhci(True);
441 fRc = fRc and oSession.saveSettings();
442 fRc = oSession.close() and fRc and True; # pychecker hack.
443 oSession = None;
444 else:
445 fRc = False;
446
447 # Start up.
448 if fRc is True:
449 self.logVmInfo(oVM);
450 oSession, oTxsSession = self.startVmAndConnectToTxsViaTcp(sVmName, fCdWait = False, fNatForwardingForTxs = False);
451 if oSession is not None:
452 self.addTask(oSession);
453
454 # Fudge factor - Allow the guest to finish starting up.
455 self.sleep(5);
456
457 if sUsbTest == 'Compliance':
458 fRc = self.testUsbCompliance(oSession, oTxsSession, sUsbCtrl, sSpeed);
459 elif sUsbTest == 'Reattach':
460 fRc = self.testUsbReattach(oSession, oTxsSession, sUsbCtrl, sSpeed);
461
462 # cleanup.
463 self.removeTask(oTxsSession);
464 self.terminateVmBySession(oSession)
465 else:
466 fRc = False;
467 return fRc;
468
469 def testUsbForOneVM(self, sVmName):
470 """
471 Runs one VM thru the various configurations.
472 """
473 reporter.testStart(sVmName);
474 for sUsbCtrl in self.asUsbCtrls:
475 reporter.testStart(sUsbCtrl)
476 for sUsbSpeed in self.asUsbSpeed:
477 asSupportedSpeeds = self.kdUsbSpeedMappings.get(sUsbCtrl);
478 if sUsbSpeed in asSupportedSpeeds:
479 reporter.testStart(sUsbSpeed)
480 for sUsbTest in self.asUsbTests:
481 reporter.testStart(sUsbTest)
482 fRc = self.testUsbOneCfg(sVmName, sUsbCtrl, sUsbSpeed, sUsbTest);
483 reporter.testDone();
484 reporter.testDone();
485 reporter.testDone();
486 reporter.testDone();
487 return fRc;
488
489 def testUsb(self):
490 """
491 Executes USB test.
492 """
493
494 reporter.log("Running on host: " + self.sHostname);
495
496 # Loop thru the test VMs.
497 for sVM in self.asTestVMs:
498 # run test on the VM.
499 fRc = self.testUsbForOneVM(sVM);
500
501 return fRc;
502
503
504
505if __name__ == '__main__':
506 sys.exit(tdUsbBenchmark().main(sys.argv));
507
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