VirtualBox

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

Last change on this file since 54118 was 54118, checked in by vboxsync, 10 years ago

ValidationKit/USB: Updates for the automated USB testing system

  • Property svn:eol-style set to LF
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 15.2 KB
Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3# $Id: tdUsb1.py 54118 2015-02-09 20:21:45Z vboxsync $
4
5"""
6VirtualBox Validation Kit - USB testcase and benchmark.
7"""
8
9__copyright__ = \
10"""
11Copyright (C) 2014 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: 54118 $"
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
51from usbgadget import 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', 'BeagleBoneBlack'),
69 'Full': ('beaglebone', 'BeagleBoneBlack'),
70 'High': ('beaglebone', 'BeagleBoneBlack'),
71 'Super': ('odroidxu3', 'ODroid-XU3')
72 },
73 };
74
75 # Mappings of USB controllers to supported USB device speeds.
76 kdUsbSpeedMappings = {
77 'OHCI': ['Low', 'Full'],
78 'EHCI': ['High'],
79 'XHCI': ['Low', 'Full', 'High', 'Super']
80 };
81
82 def __init__(self):
83 vbox.TestDriver.__init__(self);
84 self.asRsrcs = None;
85 self.oGuestToGuestVM = None;
86 self.oGuestToGuestSess = None;
87 self.oGuestToGuestTxs = None;
88 self.asTestVMsDef = ['tst-arch'];
89 self.asTestVMs = self.asTestVMsDef;
90 self.asSkipVMs = [];
91 self.asVirtModesDef = ['hwvirt', 'hwvirt-np', 'raw'];
92 self.asVirtModes = self.asVirtModesDef;
93 self.acCpusDef = [1, 2,];
94 self.acCpus = self.acCpusDef;
95 self.asUsbCtrlsDef = ['OHCI', 'EHCI', 'XHCI'];
96 self.asUsbCtrls = self.asUsbCtrlsDef;
97 self.asUsbSpeedDef = ['Low', 'Full', 'High', 'Super'];
98 self.asUsbSpeed = self.asUsbSpeedDef;
99 self.sHostname = socket.gethostname().lower();
100
101 #
102 # Overridden methods.
103 #
104 def showUsage(self):
105 rc = vbox.TestDriver.showUsage(self);
106 reporter.log('');
107 reporter.log('tdStorageBenchmark1 Options:');
108 reporter.log(' --virt-modes <m1[:m2[:]]');
109 reporter.log(' Default: %s' % (':'.join(self.asVirtModesDef)));
110 reporter.log(' --cpu-counts <c1[:c2[:]]');
111 reporter.log(' Default: %s' % (':'.join(str(c) for c in self.acCpusDef)));
112 reporter.log(' --test-vms <vm1[:vm2[:...]]>');
113 reporter.log(' Test the specified VMs in the given order. Use this to change');
114 reporter.log(' the execution order or limit the choice of VMs');
115 reporter.log(' Default: %s (all)' % (':'.join(self.asTestVMsDef)));
116 reporter.log(' --skip-vms <vm1[:vm2[:...]]>');
117 reporter.log(' Skip the specified VMs when testing.');
118 reporter.log(' --usb-ctrls <u1[:u2[:]]');
119 reporter.log(' Default: %s' % (':'.join(str(c) for c in self.asUsbCtrlsDef)));
120 reporter.log(' --usb-speed <s1[:s2[:]]');
121 reporter.log(' Default: %s' % (':'.join(str(c) for c in self.asUsbSpeedDef)));
122 return rc;
123
124 def parseOption(self, asArgs, iArg): # pylint: disable=R0912,R0915
125 if asArgs[iArg] == '--virt-modes':
126 iArg += 1;
127 if iArg >= len(asArgs): raise base.InvalidOption('The "--virt-modes" takes a colon separated list of modes');
128 self.asVirtModes = asArgs[iArg].split(':');
129 for s in self.asVirtModes:
130 if s not in self.asVirtModesDef:
131 raise base.InvalidOption('The "--virt-modes" value "%s" is not valid; valid values are: %s' \
132 % (s, ' '.join(self.asVirtModesDef)));
133 elif asArgs[iArg] == '--cpu-counts':
134 iArg += 1;
135 if iArg >= len(asArgs): raise base.InvalidOption('The "--cpu-counts" takes a colon separated list of cpu counts');
136 self.acCpus = [];
137 for s in asArgs[iArg].split(':'):
138 try: c = int(s);
139 except: raise base.InvalidOption('The "--cpu-counts" value "%s" is not an integer' % (s,));
140 if c <= 0: raise base.InvalidOption('The "--cpu-counts" value "%s" is zero or negative' % (s,));
141 self.acCpus.append(c);
142 elif asArgs[iArg] == '--test-vms':
143 iArg += 1;
144 if iArg >= len(asArgs): raise base.InvalidOption('The "--test-vms" takes colon separated list');
145 self.asTestVMs = asArgs[iArg].split(':');
146 for s in self.asTestVMs:
147 if s not in self.asTestVMsDef:
148 raise base.InvalidOption('The "--test-vms" value "%s" is not valid; valid values are: %s' \
149 % (s, ' '.join(self.asTestVMsDef)));
150 elif asArgs[iArg] == '--skip-vms':
151 iArg += 1;
152 if iArg >= len(asArgs): raise base.InvalidOption('The "--skip-vms" takes colon separated list');
153 self.asSkipVMs = asArgs[iArg].split(':');
154 for s in self.asSkipVMs:
155 if s not in self.asTestVMsDef:
156 reporter.log('warning: The "--test-vms" value "%s" does not specify any of our test VMs.' % (s));
157 elif asArgs[iArg] == '--usb-ctrls':
158 iArg += 1;
159 if iArg >= len(asArgs): raise base.InvalidOption('The "--usb-ctrls" takes a colon separated list of USB controllers');
160 self.asUsbCtrls = asArgs[iArg].split(':');
161 for s in self.asUsbCtrls:
162 if s not in self.asUsbCtrlsDef:
163 reporter.log('warning: The "--usb-ctrls" value "%s" is not a valid USB controller.' % (s));
164 elif asArgs[iArg] == '--usb-speed':
165 iArg += 1;
166 if iArg >= len(asArgs): raise base.InvalidOption('The "--usb-speed" takes a colon separated list of USB speeds');
167 self.asUsbSpeed = asArgs[iArg].split(':');
168 for s in self.asUsbSpeed:
169 if s not in self.asUsbSpeedDef:
170 reporter.log('warning: The "--usb-speed" value "%s" is not a valid USB speed.' % (s));
171 else:
172 return vbox.TestDriver.parseOption(self, asArgs, iArg);
173 return iArg + 1;
174
175 def completeOptions(self):
176 # Remove skipped VMs from the test list.
177 for sVM in self.asSkipVMs:
178 try: self.asTestVMs.remove(sVM);
179 except: pass;
180
181 return vbox.TestDriver.completeOptions(self);
182
183 def getResourceSet(self):
184 # Construct the resource list the first time it's queried.
185 if self.asRsrcs is None:
186 self.asRsrcs = [];
187
188 if 'tst-arch' in self.asTestVMs:
189 self.asRsrcs.append('4.2/usb/tst-arch.vdi');
190
191 return self.asRsrcs;
192
193 def actionConfig(self):
194
195 # Some stupid trickery to guess the location of the iso. ## fixme - testsuite unzip ++
196 sVBoxValidationKit_iso = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../VBoxValidationKit.iso'));
197 if not os.path.isfile(sVBoxValidationKit_iso):
198 sVBoxValidationKit_iso = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../VBoxTestSuite.iso'));
199 if not os.path.isfile(sVBoxValidationKit_iso):
200 sVBoxValidationKit_iso = '/mnt/ramdisk/vbox/svn/trunk/validationkit/VBoxValidationKit.iso';
201 if not os.path.isfile(sVBoxValidationKit_iso):
202 sVBoxValidationKit_iso = '/mnt/ramdisk/vbox/svn/trunk/testsuite/VBoxTestSuite.iso';
203 if not os.path.isfile(sVBoxValidationKit_iso):
204 sCur = os.getcwd();
205 for i in range(0, 10):
206 sVBoxValidationKit_iso = os.path.join(sCur, 'validationkit/VBoxValidationKit.iso');
207 if os.path.isfile(sVBoxValidationKit_iso):
208 break;
209 sVBoxValidationKit_iso = os.path.join(sCur, 'testsuite/VBoxTestSuite.iso');
210 if os.path.isfile(sVBoxValidationKit_iso):
211 break;
212 sCur = os.path.abspath(os.path.join(sCur, '..'));
213 if i is None: pass; # shut up pychecker/pylint.
214 if not os.path.isfile(sVBoxValidationKit_iso):
215 sVBoxValidationKit_iso = '/home/bird/validationkit/VBoxValidationKit.iso';
216 if not os.path.isfile(sVBoxValidationKit_iso):
217 sVBoxValidationKit_iso = '/home/bird/testsuite/VBoxTestSuite.iso';
218
219 # Make sure vboxapi has been imported so we can use the constants.
220 if not self.importVBoxApi():
221 return False;
222
223 #
224 # Configure the VMs we're going to use.
225 #
226
227 # Linux VMs
228 if 'tst-arch' in self.asTestVMs:
229 oVM = self.createTestVM('tst-arch', 1, '4.2/usb/tst-arch.vdi', sKind = 'ArchLinux_64', fIoApic = True, \
230 eNic0AttachType = vboxcon.NetworkAttachmentType_NAT, \
231 sDvdImage = sVBoxValidationKit_iso);
232 if oVM is None:
233 return False;
234
235 return True;
236
237 def actionExecute(self):
238 """
239 Execute the testcase.
240 """
241 fRc = self.testUsb();
242 return fRc;
243
244 def getGadgetParams(self, sHostname, sSpeed):
245 """
246 Returns the gadget hostname and type from the
247 given hostname the test is running on and device speed we want to test.
248 """
249 kdGadgetsConfigured = self.kdGadgetParams.get(sHostname);
250 if kdGadgetsConfigured is not None:
251 return kdGadgetsConfigured.get(sSpeed);
252
253 return None;
254
255 #
256 # Test execution helpers.
257 #
258 def testUsbCompliance(self, oSession, oTxsSession, sVmName, sSpeed):
259 """
260 Test VirtualBoxs USB stack in a VM.
261 """
262 # Get configured USB test devices from hostname we are running on
263 sGadgetHost, sGadgetType = self.getGadgetParams(self.sHostname, sSpeed);
264
265 # Create device filter
266 fRc = oSession.addUsbDeviceFilter('Compliance device', '0525', 'a4a0');
267 if fRc is True:
268 oUsbGadget = UsbGadget();
269 fRc = oUsbGadget.connectTo(30 * 1000, sGadgetType, sGadgetHost);
270 if fRc is True:
271 fRc = oUsbGadget.impersonate('Test');
272 if fRc is True:
273
274 # Wait a moment to let the USB device appear
275 self.sleep(3);
276
277 fRc = self.txsRunTest(oTxsSession, 'Compliance', 3600 * 1000, \
278 '${CDROM}/${OS/ARCH}/UsbTest${EXESUFF}', ('UsbTest', ));
279
280 else:
281 reporter.testFailure('Failed to impersonate test device');
282
283 oUsbGadget.disconnectFrom();
284 else:
285 reporter.testFailure('Failed to connect to USB gadget');
286 else:
287 reporter.testFailure('Failed to create USB device filter');
288
289 return fRc;
290
291 def testUsbOneCfg(self, sVmName, sUsbCtrl, sSpeed):
292 """
293 Runs the specified VM thru test #1.
294
295 Returns a success indicator on the general test execution. This is not
296 the actual test result.
297 """
298 oVM = self.getVmByName(sVmName);
299
300 # Reconfigure the VM
301 fRc = True;
302 oSession = self.openSession(oVM);
303 if oSession is not None:
304 fRc = fRc and oSession.enableVirtEx(True);
305 fRc = fRc and oSession.enableNestedPaging(True);
306
307 # Make sure controllers are disabled initially.
308 fRc = fRc and oSession.enableUsbOhci(False);
309 fRc = fRc and oSession.enableUsbEhci(False);
310 fRc = fRc and oSession.enableUsbXhci(False);
311
312 if sUsbCtrl == 'OHCI':
313 fRc = fRc and oSession.enableUsbOhci(True);
314 elif sUsbCtrl == 'EHCI':
315 fRc = fRc and oSession.enableUsbEhci(True);
316 elif sUsbCtrl == 'XHCI':
317 fRc = fRc and oSession.enableUsbXhci(True);
318 fRc = fRc and oSession.saveSettings();
319 fRc = oSession.close() and fRc and True; # pychecker hack.
320 oSession = None;
321 else:
322 fRc = False;
323
324 # Start up.
325 if fRc is True:
326 self.logVmInfo(oVM);
327 oSession, oTxsSession = self.startVmAndConnectToTxsViaTcp(sVmName, fCdWait = False, fNatForwardingForTxs = False);
328 if oSession is not None:
329 self.addTask(oSession);
330
331 # Fudge factor - Allow the guest to finish starting up.
332 self.sleep(5);
333
334 fRc = self.testUsbCompliance(oSession, oTxsSession, sVmName, sSpeed);
335
336 # cleanup.
337 self.removeTask(oTxsSession);
338 self.terminateVmBySession(oSession)
339 else:
340 fRc = False;
341 return fRc;
342
343 def testUsbForOneVM(self, sVmName):
344 """
345 Runs one VM thru the various configurations.
346 """
347 reporter.testStart(sVmName);
348 for sUsbCtrl in self.asUsbCtrls:
349 reporter.testStart(sUsbCtrl)
350 for sUsbSpeed in self.asUsbSpeed:
351 asSupportedSpeeds = self.kdUsbSpeedMappings.get(sUsbCtrl);
352 if sUsbSpeed in asSupportedSpeeds:
353 reporter.testStart(sUsbSpeed)
354 fRc = self.testUsbOneCfg(sVmName, sUsbCtrl, sUsbSpeed);
355 reporter.testDone(not fRc);
356 reporter.testDone();
357 reporter.testDone();
358 return fRc;
359
360 def testUsb(self):
361 """
362 Executes USB test.
363 """
364
365 reporter.log("Running on host: " + self.sHostname);
366
367 # Loop thru the test VMs.
368 for sVM in self.asTestVMs:
369 # run test on the VM.
370 if not self.testUsbForOneVM(sVM):
371 fRc = False;
372 else:
373 fRc = True;
374
375 return fRc;
376
377
378
379if __name__ == '__main__':
380 sys.exit(tdUsbBenchmark().main(sys.argv));
381
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