VirtualBox

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

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

ValidationKit/usb/tdUsb1: Enable all super-speed tests again, the gadget side is fixed now

  • 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 60898 2016-05-09 14:53:47Z 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: 60898 $"
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': []
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 _ = sUsbCtrl;
362 return fRc;
363
364 def testUsbReattach(self, oSession, oTxsSession, sUsbCtrl, sSpeed): # pylint: disable=W0613
365 """
366 Tests that rapid connect/disconnect cycles work.
367 """
368 # Get configured USB test devices from hostname we are running on
369 sGadgetHost, uGadgetPort = self.getGadgetParams(self.sHostname, sSpeed);
370
371 oUsbGadget = usbgadget.UsbGadget();
372 reporter.log('Connecting to UTS: ' + sGadgetHost);
373 fRc = oUsbGadget.connectTo(30 * 1000, sGadgetHost, uPort = uGadgetPort);
374 if fRc is True:
375 self.oVBox.host.addUSBDeviceSource('USBIP', sGadgetHost, sGadgetHost + (':%s' % oUsbGadget.getUsbIpPort()), [], []);
376
377 fSuperSpeed = False;
378 if sSpeed == 'Super':
379 fSuperSpeed = True;
380
381 # Create test device gadget and a filter to attach the device automatically.
382 fRc = oUsbGadget.impersonate(usbgadget.g_ksGadgetImpersonationTest, fSuperSpeed);
383 if fRc is True:
384 iBusId, _ = oUsbGadget.getGadgetBusAndDevId();
385 fRc = oSession.addUsbDeviceFilter('Compliance device', sVendorId = '0525', sProductId = 'a4a0', \
386 sPort = str(iBusId));
387 if fRc is True:
388
389 # Wait a moment to let the USB device appear
390 self.sleep(3);
391
392 # Do a rapid disconnect reconnect cycle. Wait a second before disconnecting
393 # again or it will happen so fast that the VM can't attach the new device.
394 # @todo: Get rid of the constant wait and use an event to get notified when
395 # the device was attached.
396 for iCycle in xrange (0, self.cUsbReattachCycles):
397 fRc = oUsbGadget.disconnectUsb();
398 fRc = fRc and oUsbGadget.connectUsb();
399 if not fRc:
400 reporter.testFailure('Reattach cycle %s failed on the gadget device' % (iCycle));
401 break;
402 self.sleep(1);
403
404 else:
405 reporter.testFailure('Failed to impersonate test device');
406
407 oUsbGadget.disconnectFrom();
408 else:
409 reporter.testFailure('Failed to connect to USB gadget');
410 else:
411 reporter.testFailure('Failed to create USB device filter');
412
413 return fRc;
414
415 def testUsbOneCfg(self, sVmName, sUsbCtrl, sSpeed, sUsbTest):
416 """
417 Runs the specified VM thru one specified test.
418
419 Returns a success indicator on the general test execution. This is not
420 the actual test result.
421 """
422 oVM = self.getVmByName(sVmName);
423
424 # Reconfigure the VM
425 fRc = True;
426 oSession = self.openSession(oVM);
427 if oSession is not None:
428 fRc = fRc and oSession.enableVirtEx(True);
429 fRc = fRc and oSession.enableNestedPaging(True);
430
431 # Make sure controllers are disabled initially.
432 fRc = fRc and oSession.enableUsbOhci(False);
433 fRc = fRc and oSession.enableUsbEhci(False);
434 fRc = fRc and oSession.enableUsbXhci(False);
435
436 if sUsbCtrl == 'OHCI':
437 fRc = fRc and oSession.enableUsbOhci(True);
438 elif sUsbCtrl == 'EHCI':
439 fRc = fRc and oSession.enableUsbEhci(True);
440 elif sUsbCtrl == 'XHCI':
441 fRc = fRc and oSession.enableUsbXhci(True);
442 fRc = fRc and oSession.saveSettings();
443 fRc = oSession.close() and fRc and True; # pychecker hack.
444 oSession = None;
445 else:
446 fRc = False;
447
448 # Start up.
449 if fRc is True:
450 self.logVmInfo(oVM);
451 oSession, oTxsSession = self.startVmAndConnectToTxsViaTcp(sVmName, fCdWait = False, fNatForwardingForTxs = False);
452 if oSession is not None:
453 self.addTask(oSession);
454
455 # Fudge factor - Allow the guest to finish starting up.
456 self.sleep(5);
457
458 if sUsbTest == 'Compliance':
459 fRc = self.testUsbCompliance(oSession, oTxsSession, sUsbCtrl, sSpeed);
460 elif sUsbTest == 'Reattach':
461 fRc = self.testUsbReattach(oSession, oTxsSession, sUsbCtrl, sSpeed);
462
463 # cleanup.
464 self.removeTask(oTxsSession);
465 self.terminateVmBySession(oSession)
466 else:
467 fRc = False;
468 return fRc;
469
470 def testUsbForOneVM(self, sVmName):
471 """
472 Runs one VM thru the various configurations.
473 """
474 reporter.testStart(sVmName);
475 for sUsbCtrl in self.asUsbCtrls:
476 reporter.testStart(sUsbCtrl)
477 for sUsbSpeed in self.asUsbSpeed:
478 asSupportedSpeeds = self.kdUsbSpeedMappings.get(sUsbCtrl);
479 if sUsbSpeed in asSupportedSpeeds:
480 reporter.testStart(sUsbSpeed)
481 for sUsbTest in self.asUsbTests:
482 reporter.testStart(sUsbTest)
483 fRc = self.testUsbOneCfg(sVmName, sUsbCtrl, sUsbSpeed, sUsbTest);
484 reporter.testDone();
485 reporter.testDone();
486 reporter.testDone();
487 reporter.testDone();
488 return fRc;
489
490 def testUsb(self):
491 """
492 Executes USB test.
493 """
494
495 reporter.log("Running on host: " + self.sHostname);
496
497 # Loop thru the test VMs.
498 for sVM in self.asTestVMs:
499 # run test on the VM.
500 fRc = self.testUsbForOneVM(sVM);
501
502 return fRc;
503
504
505
506if __name__ == '__main__':
507 sys.exit(tdUsbBenchmark().main(sys.argv));
508
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