VirtualBox

source: vbox/trunk/src/VBox/ValidationKit/tests/storage/tdStorageStress1.py@ 53938

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

fix OSE

  • Property svn:eol-style set to LF
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 23.1 KB
Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3
4"""
5Storage testcase using xfstests.
6"""
7
8__copyright__ = \
9"""
10Copyright (C) 2012-2014 Oracle Corporation
11
12This file is part of VirtualBox Open Source Edition (OSE), as
13available from http://www.virtualbox.org. This file is free software;
14you can redistribute it and/or modify it under the terms of the GNU
15General Public License (GPL) as published by the Free Software
16Foundation, in version 2 as it comes in the "COPYING" file of the
17VirtualBox OSE distribution. VirtualBox OSE is distributed in the
18hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
19
20The contents of this file may alternatively be used under the terms
21of the Common Development and Distribution License Version 1.0
22(CDDL) only, as it comes in the "COPYING.CDDL" file of the
23VirtualBox OSE distribution, in which case the provisions of the
24CDDL are applicable instead of those of the GPL.
25
26You may elect to license modified versions of this file under the
27terms and conditions of either the GPL or the CDDL or both.
28"""
29__version__ = "$Id: tdStorageStress1.py 52776 2014-09-17 14:51:43Z vboxsync $"
30
31
32# Standard Python imports.
33import os;
34import sys;
35
36# Only the main script needs to modify the path.
37try: __file__
38except: __file__ = sys.argv[0];
39g_ksValidationKitDir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))));
40sys.path.append(g_ksValidationKitDir);
41
42# Validation Kit imports.
43from testdriver import reporter;
44from testdriver import base;
45from testdriver import vbox;
46from testdriver import vboxcon;
47
48def _ControllerTypeToName(eControllerType):
49 """ Translate a controller type to a name. """
50 if eControllerType == vboxcon.StorageControllerType_PIIX3 or eControllerType == vboxcon.StorageControllerType_PIIX4:
51 sType = "IDE Controller";
52 elif eControllerType == vboxcon.StorageControllerType_IntelAhci:
53 sType = "SATA Controller";
54 elif eControllerType == vboxcon.StorageControllerType_LsiLogicSas:
55 sType = "SAS Controller";
56 elif eControllerType == vboxcon.StorageControllerType_LsiLogic or eControllerType == vboxcon.StorageControllerType_BusLogic:
57 sType = "SCSI Controller";
58 else:
59 sType = "Storage Controller";
60 return sType;
61
62class tdStorageStress(vbox.TestDriver): # pylint: disable=R0902
63 """
64 Storage testcase.
65 """
66
67 def __init__(self):
68 vbox.TestDriver.__init__(self);
69 self.asRsrcs = None;
70 self.oGuestToGuestVM = None;
71 self.oGuestToGuestSess = None;
72 self.oGuestToGuestTxs = None;
73 self.asTestVMsDef = ['tst-debian'];
74 self.asTestVMs = self.asTestVMsDef;
75 self.asSkipVMs = [];
76 self.asVirtModesDef = ['hwvirt', 'hwvirt-np', 'raw',]
77 self.asVirtModes = self.asVirtModesDef
78 self.acCpusDef = [1, 2,]
79 self.acCpus = self.acCpusDef;
80 self.asStorageCtrlsDef = ['AHCI', 'IDE', 'LsiLogicSAS', 'LsiLogic', 'BusLogic'];
81 self.asStorageCtrls = self.asStorageCtrlsDef;
82 self.asDiskFormatsDef = ['VDI', 'VMDK', 'VHD', 'QED', 'Parallels', 'QCOW'];
83 self.asDiskFormats = self.asDiskFormatsDef;
84 self.asTestsDef = ['xfstests'];
85 self.asTests = self.asTestsDef;
86 self.asGuestFs = ['xfs', 'ext4', 'btrfs'];
87 self.asGuestFsDef = self.asGuestFs;
88 self.asIscsiTargetsDef = ['aurora|iqn.2011-03.home.aurora:aurora.storagebench|1'];
89 self.asIscsiTargets = self.asIscsiTargetsDef;
90 self.asDirsDef = ['/run/media/alexander/OWCSSD/alexander', \
91 '/run/media/alexander/CrucialSSD/alexander', \
92 '/run/media/alexander/HardDisk/alexander', \
93 '/home/alexander'];
94 self.asDirs = self.asDirsDef;
95
96 #
97 # Overridden methods.
98 #
99 def showUsage(self):
100 rc = vbox.TestDriver.showUsage(self);
101 reporter.log('');
102 reporter.log('tdStorageBenchmark1 Options:');
103 reporter.log(' --virt-modes <m1[:m2[:]]');
104 reporter.log(' Default: %s' % (':'.join(self.asVirtModesDef)));
105 reporter.log(' --cpu-counts <c1[:c2[:]]');
106 reporter.log(' Default: %s' % (':'.join(str(c) for c in self.acCpusDef)));
107 reporter.log(' --storage-ctrls <type1[:type2[:...]]>');
108 reporter.log(' Default: %s' % (':'.join(self.asStorageCtrls)));
109 reporter.log(' --disk-formats <type1[:type2[:...]]>');
110 reporter.log(' Default: %s' % (':'.join(self.asDiskFormats)));
111 reporter.log(' --disk-dirs <path1[:path2[:...]]>');
112 reporter.log(' Default: %s' % (':'.join(self.asDirs)));
113 reporter.log(' --iscsi-targets <target1[:target2[:...]]>');
114 reporter.log(' Default: %s' % (':'.join(self.asIscsiTargets)));
115 reporter.log(' --tests <test1[:test2[:...]]>');
116 reporter.log(' Default: %s' % (':'.join(self.asTests)));
117 reporter.log(' --guest-fs <fs1[:fs2[:...]]>');
118 reporter.log(' Default: %s' % (':'.join(self.asGuestFs)));
119 reporter.log(' --test-vms <vm1[:vm2[:...]]>');
120 reporter.log(' Test the specified VMs in the given order. Use this to change');
121 reporter.log(' the execution order or limit the choice of VMs');
122 reporter.log(' Default: %s (all)' % (':'.join(self.asTestVMsDef)));
123 reporter.log(' --skip-vms <vm1[:vm2[:...]]>');
124 reporter.log(' Skip the specified VMs when testing.');
125 return rc;
126
127 def parseOption(self, asArgs, iArg): # pylint: disable=R0912,R0915
128 if asArgs[iArg] == '--virt-modes':
129 iArg += 1;
130 if iArg >= len(asArgs): raise base.InvalidOption('The "--virt-modes" takes a colon separated list of modes');
131 self.asVirtModes = asArgs[iArg].split(':');
132 for s in self.asVirtModes:
133 if s not in self.asVirtModesDef:
134 raise base.InvalidOption('The "--virt-modes" value "%s" is not valid; valid values are: %s' \
135 % (s, ' '.join(self.asVirtModesDef)));
136 elif asArgs[iArg] == '--cpu-counts':
137 iArg += 1;
138 if iArg >= len(asArgs): raise base.InvalidOption('The "--cpu-counts" takes a colon separated list of cpu counts');
139 self.acCpus = [];
140 for s in asArgs[iArg].split(':'):
141 try: c = int(s);
142 except: raise base.InvalidOption('The "--cpu-counts" value "%s" is not an integer' % (s,));
143 if c <= 0: raise base.InvalidOption('The "--cpu-counts" value "%s" is zero or negative' % (s,));
144 self.acCpus.append(c);
145 elif asArgs[iArg] == '--storage-ctrls':
146 iArg += 1;
147 if iArg >= len(asArgs):
148 raise base.InvalidOption('The "--storage-ctrls" takes a colon separated list of Storage controller types');
149 self.asStorageCtrls = asArgs[iArg].split(':');
150 elif asArgs[iArg] == '--disk-formats':
151 iArg += 1;
152 if iArg >= len(asArgs): raise base.InvalidOption('The "--disk-formats" takes a colon separated list of disk formats');
153 self.asDiskFormats = asArgs[iArg].split(':');
154 elif asArgs[iArg] == '--disk-dirs':
155 iArg += 1;
156 if iArg >= len(asArgs): raise base.InvalidOption('The "--disk-dirs" takes a colon separated list of directories');
157 self.asDirs = asArgs[iArg].split(':');
158 elif asArgs[iArg] == '--iscsi-targets':
159 iArg += 1;
160 if iArg >= len(asArgs):
161 raise base.InvalidOption('The "--iscsi-targets" takes a colon separated list of iscsi targets');
162 self.asIscsiTargets = asArgs[iArg].split(':');
163 elif asArgs[iArg] == '--tests':
164 iArg += 1;
165 if iArg >= len(asArgs): raise base.InvalidOption('The "--tests" takes a colon separated list of disk formats');
166 self.asTests = asArgs[iArg].split(':');
167 elif asArgs[iArg] == '--guest-fs':
168 iArg += 1;
169 if iArg >= len(asArgs):
170 raise base.InvalidOption('The "--guest-fs" takes a colon separated list of filesystem identifiers');
171 self.asGuestFs = asArgs[iArg].split(':');
172 elif asArgs[iArg] == '--test-vms':
173 iArg += 1;
174 if iArg >= len(asArgs): raise base.InvalidOption('The "--test-vms" takes colon separated list');
175 self.asTestVMs = asArgs[iArg].split(':');
176 for s in self.asTestVMs:
177 if s not in self.asTestVMsDef:
178 raise base.InvalidOption('The "--test-vms" value "%s" is not valid; valid values are: %s' \
179 % (s, ' '.join(self.asTestVMsDef)));
180 elif asArgs[iArg] == '--skip-vms':
181 iArg += 1;
182 if iArg >= len(asArgs): raise base.InvalidOption('The "--skip-vms" takes colon separated list');
183 self.asSkipVMs = asArgs[iArg].split(':');
184 for s in self.asSkipVMs:
185 if s not in self.asTestVMsDef:
186 reporter.log('warning: The "--test-vms" value "%s" does not specify any of our test VMs.' % (s));
187 else:
188 return vbox.TestDriver.parseOption(self, asArgs, iArg);
189 return iArg + 1;
190
191 def completeOptions(self):
192 # Remove skipped VMs from the test list.
193 for sVM in self.asSkipVMs:
194 try: self.asTestVMs.remove(sVM);
195 except: pass;
196
197 return vbox.TestDriver.completeOptions(self);
198
199 def getResourceSet(self):
200 # Construct the resource list the first time it's queried.
201 if self.asRsrcs is None:
202 self.asRsrcs = [];
203 if 'tst-debian' in self.asTestVMs:
204 self.asRsrcs.append('4.2/storage/debian.vdi');
205
206 return self.asRsrcs;
207
208 def actionConfig(self):
209 # Some stupid trickery to guess the location of the iso. ## fixme - testsuite unzip ++
210 sVBoxValidationKit_iso = os.path.abspath(os.path.join(os.path.dirname(__file__),
211 '../../VBoxValidationKitStorIo.iso'));
212 if not os.path.isfile(sVBoxValidationKit_iso):
213 sVBoxValidationKit_iso = os.path.abspath(os.path.join(os.path.dirname(__file__),
214 '../../VBoxValidationKitStorIo.iso'));
215 if not os.path.isfile(sVBoxValidationKit_iso):
216 sVBoxValidationKit_iso = '/mnt/ramdisk/vbox/svn/trunk/validationkit/VBoxValidationKitStorIo.iso';
217 if not os.path.isfile(sVBoxValidationKit_iso):
218 sVBoxValidationKit_iso = '/mnt/ramdisk/vbox/svn/trunk/testsuite/VBoxTestSuiteStorIo.iso';
219 if not os.path.isfile(sVBoxValidationKit_iso):
220 sCur = os.getcwd();
221 for i in range(0, 10):
222 sVBoxValidationKit_iso = os.path.join(sCur, 'validationkit/VBoxValidationKitStorIo.iso');
223 if os.path.isfile(sVBoxValidationKit_iso):
224 break;
225 sVBoxValidationKit_iso = os.path.join(sCur, 'testsuite/VBoxTestSuiteStorIo.iso');
226 if os.path.isfile(sVBoxValidationKit_iso):
227 break;
228 sCur = os.path.abspath(os.path.join(sCur, '..'));
229 if i is None: pass; # shut up pychecker/pylint.
230 if not os.path.isfile(sVBoxValidationKit_iso):
231 sVBoxValidationKit_iso = '/mnt/VirtualBox/VBoxValidationKitStorIo.iso';
232 if not os.path.isfile(sVBoxValidationKit_iso):
233 sVBoxValidationKit_iso = '/mnt/VirtualBox/VBoxTestSuiteStorIo.iso';
234
235
236
237 # Make sure vboxapi has been imported so we can use the constants.
238 if not self.importVBoxApi():
239 return False;
240
241 #
242 # Configure the VMs we're going to use.
243 #
244
245 # Linux VMs
246 if 'tst-debian' in self.asTestVMs:
247 oVM = self.createTestVM('tst-debian', 1, '4.2/storage/debian.vdi', sKind = 'Debian_64', fIoApic = True, \
248 eNic0AttachType = vboxcon.NetworkAttachmentType_NAT, \
249 eNic0Type = vboxcon.NetworkAdapterType_Am79C973, \
250 sDvdImage = sVBoxValidationKit_iso);
251 if oVM is None:
252 return False;
253
254 return True;
255
256 def actionExecute(self):
257 """
258 Execute the testcase.
259 """
260 fRc = self.test1();
261 return fRc;
262
263
264 #
265 # Test execution helpers.
266 #
267
268 def test1RunTestProgs(self, oSession, oTxsSession, fRc, sTestName, sGuestFs):
269 """
270 Runs all the test programs on the test machine.
271 """
272 _ = oSession;
273
274 reporter.testStart(sTestName);
275
276 sMkfsCmd = 'mkfs.' + sGuestFs;
277
278 # Prepare test disks, just create filesystem without partition
279 reporter.testStart('Preparation');
280 fRc = fRc and self.txsRunTest(oTxsSession, 'Create FS 1', 60000, \
281 '/sbin/' + sMkfsCmd,
282 (sMkfsCmd, '/dev/sdb'));
283
284 fRc = fRc and self.txsRunTest(oTxsSession, 'Create FS 2', 60000, \
285 '/sbin/' + sMkfsCmd,
286 (sMkfsCmd, '/dev/sdc'));
287
288 # Create test and scratch directory
289 fRc = fRc and self.txsRunTest(oTxsSession, 'Create /mnt/test', 10000, \
290 '/bin/mkdir',
291 ('mkdir', '/mnt/test'));
292
293 fRc = fRc and self.txsRunTest(oTxsSession, 'Create /mnt/scratch', 10000, \
294 '/bin/mkdir',
295 ('mkdir', '/mnt/scratch'));
296
297 # Mount test and scratch directory.
298 fRc = fRc and self.txsRunTest(oTxsSession, 'Mount /mnt/test', 10000, \
299 '/bin/mount',
300 ('mount', '/dev/sdb','/mnt/test'));
301
302 fRc = fRc and self.txsRunTest(oTxsSession, 'Mount /mnt/scratch', 10000, \
303 '/bin/mount',
304 ('mount', '/dev/sdc','/mnt/scratch'));
305
306 fRc = fRc and self.txsRunTest(oTxsSession, 'Copying xfstests', 10000, \
307 '/bin/cp',
308 ('cp', '-r','${CDROM}/${OS.ARCH}/xfstests', '/tmp'));
309
310 reporter.testDone();
311
312 # Run xfstests (this sh + cd crap is required because the cwd for the script must be in the root
313 # of the xfstests directory...)
314 reporter.testStart('xfstests');
315 if fRc and 'xfstests' in self.asTests:
316 fRc = self.txsRunTest(oTxsSession, 'xfstests', 3600000, \
317 '/bin/sh',
318 ('sh', '-c', '(cd /tmp/xfstests && ./check -g auto)'), \
319 ('TEST_DIR=/mnt/test', 'TEST_DEV=/dev/sdb', 'SCRATCH_MNT=/mnt/scratch', 'SCRATCH_DEV=/dev/sdc', \
320 'FSTYP=' + sGuestFs));
321 reporter.testDone();
322 else:
323 reporter.testDone(fSkipped = True);
324
325 reporter.testDone(not fRc);
326 return fRc;
327
328 # pylint: disable=R0913
329
330 def test1OneCfg(self, sVmName, eStorageController, sDiskFormat, sDiskPath1, sDiskPath2, \
331 sGuestFs, cCpus, fHwVirt, fNestedPaging):
332 """
333 Runs the specified VM thru test #1.
334
335 Returns a success indicator on the general test execution. This is not
336 the actual test result.
337 """
338 oVM = self.getVmByName(sVmName);
339
340 # Reconfigure the VM
341 fRc = True;
342 oSession = self.openSession(oVM);
343 if oSession is not None:
344 # Attach HD
345 fRc = oSession.ensureControllerAttached(_ControllerTypeToName(eStorageController));
346 fRc = fRc and oSession.setStorageControllerType(eStorageController, _ControllerTypeToName(eStorageController));
347
348 if sDiskFormat == "iSCSI":
349 listNames = [];
350 listValues = [];
351 listValues = sDiskPath1.split('|');
352 listNames.append('TargetAddress');
353 listNames.append('TargetName');
354 listNames.append('LUN');
355
356 oHd = oSession.oVBox.createHardDisk(sDiskFormat, sDiskPath1);
357 oHd.type = vboxcon.MediumType_Normal;
358 oHd.setProperties(listNames, listValues);
359
360 # Attach it.
361 if fRc is True:
362 try:
363 if oSession.fpApiVer >= 4.0:
364 oSession.o.machine.attachDevice(_ControllerTypeToName(eStorageController), \
365 1, 0, vboxcon.DeviceType_HardDisk, oHd);
366 else:
367 oSession.o.machine.attachDevice(_ControllerTypeToName(eStorageController), \
368 1, 0, vboxcon.DeviceType_HardDisk, oHd.id);
369 except:
370 reporter.errorXcpt('attachDevice("%s",%s,%s,HardDisk,"%s") failed on "%s"' \
371 % (_ControllerTypeToName(eStorageController), 1, 0, oHd.id, oSession.sName) );
372 fRc = False;
373 else:
374 reporter.log('attached "%s" to %s' % (sDiskPath1, oSession.sName));
375 else:
376 fRc = fRc and oSession.createAndAttachHd(sDiskPath1, sDiskFormat, _ControllerTypeToName(eStorageController), \
377 cb = 10*1024*1024*1024, iPort = 1, fImmutable = False);
378 fRc = fRc and oSession.createAndAttachHd(sDiskPath2, sDiskFormat, _ControllerTypeToName(eStorageController), \
379 cb = 10*1024*1024*1024, iPort = 2, fImmutable = False);
380 fRc = fRc and oSession.enableVirtEx(fHwVirt);
381 fRc = fRc and oSession.enableNestedPaging(fNestedPaging);
382 fRc = fRc and oSession.setCpuCount(cCpus);
383 fRc = fRc and oSession.saveSettings();
384 fRc = oSession.close() and fRc and True; # pychecker hack.
385 oSession = None;
386 else:
387 fRc = False;
388
389 # Start up.
390 if fRc is True:
391 self.logVmInfo(oVM);
392 oSession, oTxsSession = self.startVmAndConnectToTxsViaTcp(sVmName, fCdWait = False, fNatForwardingForTxs = True);
393 if oSession is not None:
394 self.addTask(oSession);
395
396 # Fudge factor - Allow the guest to finish starting up.
397 self.sleep(5);
398
399 fRc = self.test1RunTestProgs(oSession, oTxsSession, fRc, 'stress testing', sGuestFs);
400
401 # cleanup.
402 self.removeTask(oTxsSession);
403 self.terminateVmBySession(oSession)
404
405 # Remove disk
406 oSession = self.openSession(oVM);
407 if oSession is not None:
408 try:
409 oSession.o.machine.detachDevice(_ControllerTypeToName(eStorageController), 1, 0);
410 oSession.o.machine.detachDevice(_ControllerTypeToName(eStorageController), 2, 0);
411
412 # Remove storage controller if it is not an IDE controller.
413 if eStorageController is not vboxcon.StorageControllerType_PIIX3 \
414 and eStorageController is not vboxcon.StorageControllerType_PIIX4:
415 oSession.o.machine.removeStorageController(_ControllerTypeToName(eStorageController));
416
417 oSession.saveSettings();
418 oSession.oVBox.deleteHdByLocation(sDiskPath1);
419 oSession.oVBox.deleteHdByLocation(sDiskPath2);
420 oSession.saveSettings();
421 oSession.close();
422 oSession = None;
423 except:
424 reporter.errorXcpt('failed to detach/delete disks %s and %s from storage controller' % \
425 (sDiskPath1, sDiskPath2));
426 else:
427 fRc = False;
428 else:
429 fRc = False;
430 return fRc;
431
432 def test1OneVM(self, sVmName):
433 """
434 Runs one VM thru the various configurations.
435 """
436 reporter.testStart(sVmName);
437 fRc = True;
438 for sStorageCtrl in self.asStorageCtrls:
439 reporter.testStart(sStorageCtrl);
440
441 if sStorageCtrl == 'AHCI':
442 eStorageCtrl = vboxcon.StorageControllerType_IntelAhci;
443 elif sStorageCtrl == 'IDE':
444 eStorageCtrl = vboxcon.StorageControllerType_PIIX4;
445 elif sStorageCtrl == 'LsiLogicSAS':
446 eStorageCtrl = vboxcon.StorageControllerType_LsiLogicSas;
447 elif sStorageCtrl == 'LsiLogic':
448 eStorageCtrl = vboxcon.StorageControllerType_LsiLogic;
449 elif sStorageCtrl == 'BusLogic':
450 eStorageCtrl = vboxcon.StorageControllerType_BusLogic;
451 else:
452 eStorageCtrl = None;
453
454 for sDiskFormat in self.asDiskFormats:
455 reporter.testStart('%s' % (sDiskFormat,));
456
457 asPaths = self.asDirs;
458
459 for sDir in asPaths:
460 reporter.testStart('%s' % (sDir,));
461
462 sPathDisk1 = sDir + "/disk1.disk";
463 sPathDisk2 = sDir + "/disk2.disk";
464
465 for sGuestFs in self.asGuestFs:
466 reporter.testStart('%s' % (sGuestFs,));
467
468 for cCpus in self.acCpus:
469 if cCpus == 1: reporter.testStart('1 cpu');
470 else: reporter.testStart('%u cpus' % (cCpus,));
471
472 for sVirtMode in self.asVirtModes:
473 if sVirtMode == 'raw' and cCpus > 1:
474 continue;
475 hsVirtModeDesc = {};
476 hsVirtModeDesc['raw'] = 'Raw-mode';
477 hsVirtModeDesc['hwvirt'] = 'HwVirt';
478 hsVirtModeDesc['hwvirt-np'] = 'NestedPaging';
479 reporter.testStart(hsVirtModeDesc[sVirtMode]);
480
481 fHwVirt = sVirtMode != 'raw';
482 fNestedPaging = sVirtMode == 'hwvirt-np';
483 fRc = self.test1OneCfg(sVmName, eStorageCtrl, sDiskFormat, sPathDisk1, sPathDisk2, \
484 sGuestFs, cCpus, fHwVirt, fNestedPaging) and fRc and True;
485 reporter.testDone();
486 reporter.testDone();
487 reporter.testDone();
488 reporter.testDone();
489 reporter.testDone();
490 reporter.testDone();
491 reporter.testDone();
492 return fRc;
493
494 def test1(self):
495 """
496 Executes test #1.
497 """
498
499 # Loop thru the test VMs.
500 for sVM in self.asTestVMs:
501 # run test on the VM.
502 if not self.test1OneVM(sVM):
503 fRc = False;
504 else:
505 fRc = True;
506
507 return fRc;
508
509
510
511if __name__ == '__main__':
512 sys.exit(tdStorageStress().main(sys.argv));
513
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