VirtualBox

source: vbox/trunk/src/VBox/ValidationKit/tests/storage/tdStorageBenchmark1.py@ 62268

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

ValidationKit/tdStorageBenchmark1: Fix test closing when skipping the test with BusLogic controllers

  • Property svn:eol-style set to LF
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 30.2 KB
Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3# $Id: tdStorageBenchmark1.py 62268 2016-07-15 08:50:52Z vboxsync $
4
5"""
6VirtualBox Validation Kit - Storage benchmark.
7"""
8
9__copyright__ = \
10"""
11Copyright (C) 2012-2015 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: 62268 $"
31
32
33# Standard Python imports.
34import os;
35import socket;
36import sys;
37import StringIO;
38
39# Only the main script needs to modify the path.
40try: __file__
41except: __file__ = sys.argv[0];
42g_ksValidationKitDir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))));
43sys.path.append(g_ksValidationKitDir);
44
45# Validation Kit imports.
46from common import constants;
47from common import utils;
48from testdriver import reporter;
49from testdriver import base;
50from testdriver import vbox;
51from testdriver import vboxcon;
52
53import remoteexecutor;
54import storagecfg;
55
56def _ControllerTypeToName(eControllerType):
57 """ Translate a controller type to a name. """
58 if eControllerType == vboxcon.StorageControllerType_PIIX3 or eControllerType == vboxcon.StorageControllerType_PIIX4:
59 sType = "IDE Controller";
60 elif eControllerType == vboxcon.StorageControllerType_IntelAhci:
61 sType = "SATA Controller";
62 elif eControllerType == vboxcon.StorageControllerType_LsiLogicSas:
63 sType = "SAS Controller";
64 elif eControllerType == vboxcon.StorageControllerType_LsiLogic or eControllerType == vboxcon.StorageControllerType_BusLogic:
65 sType = "SCSI Controller";
66 elif eControllerType == vboxcon.StorageControllerType_NVMe:
67 sType = "NVMe Controller";
68 else:
69 sType = "Storage Controller";
70 return sType;
71
72class FioTest(object):
73 """
74 Flexible I/O tester testcase.
75 """
76
77 kdHostIoEngine = {
78 'solaris': ('solarisaio', False),
79 'linux': ('libaio', True)
80 };
81
82 def __init__(self, oExecutor, dCfg = None):
83 self.oExecutor = oExecutor;
84 self.sCfgFileId = None;
85 self.dCfg = dCfg;
86
87 def prepare(self, cMsTimeout = 30000):
88 """ Prepares the testcase """
89
90 sTargetOs = self.dCfg.get('TargetOs', 'linux');
91 sIoEngine, fDirectIo = self.kdHostIoEngine.get(sTargetOs);
92 if sIoEngine is None:
93 return False;
94
95 cfgBuf = StringIO.StringIO();
96 cfgBuf.write('[global]\n');
97 cfgBuf.write('bs=' + self.dCfg.get('RecordSize', '4k') + '\n');
98 cfgBuf.write('ioengine=' + sIoEngine + '\n');
99 cfgBuf.write('iodepth=' + self.dCfg.get('QueueDepth', '32') + '\n');
100 cfgBuf.write('size=' + self.dCfg.get('TestsetSize', '2g') + '\n');
101 if fDirectIo:
102 cfgBuf.write('direct=1\n');
103 else:
104 cfgBuf.write('direct=0\n');
105 cfgBuf.write('directory=' + self.dCfg.get('FilePath', '/mnt') + '\n');
106
107 cfgBuf.write('[seq-write]\n');
108 cfgBuf.write('rw=write\n');
109 cfgBuf.write('stonewall\n');
110
111 cfgBuf.write('[rand-write]\n');
112 cfgBuf.write('rw=randwrite\n');
113 cfgBuf.write('stonewall\n');
114
115 cfgBuf.write('[seq-read]\n');
116 cfgBuf.write('rw=read\n');
117 cfgBuf.write('stonewall\n');
118
119 cfgBuf.write('[rand-read]\n');
120 cfgBuf.write('rw=randread\n');
121 cfgBuf.write('stonewall\n');
122
123 self.sCfgFileId = self.oExecutor.copyString(cfgBuf.getvalue(), 'aio-test', cMsTimeout);
124 return self.sCfgFileId is not None;
125
126 def run(self, cMsTimeout = 30000):
127 """ Runs the testcase """
128 _ = cMsTimeout
129 fRc, sOutput = self.oExecutor.execBinary('fio', (self.sCfgFileId,));
130 # @todo: Parse output.
131 _ = sOutput;
132 return fRc;
133
134 def cleanup(self):
135 """ Cleans up any leftovers from the testcase. """
136
137 def reportResult(self):
138 """
139 Reports the test results to the test manager.
140 """
141 return True;
142
143class IozoneTest(object):
144 """
145 I/O zone testcase.
146 """
147 def __init__(self, oExecutor, dCfg = None):
148 self.oExecutor = oExecutor;
149 self.sResult = None;
150 self.lstTests = [ ('initial writers', 'FirstWrite'),
151 ('rewriters', 'Rewrite'),
152 ('re-readers', 'ReRead'),
153 ('stride readers', 'StrideRead'),
154 ('reverse readers', 'ReverseRead'),
155 ('random readers', 'RandomRead'),
156 ('mixed workload', 'MixedWorkload'),
157 ('random writers', 'RandomWrite'),
158 ('pwrite writers', 'PWrite'),
159 ('pread readers', 'PRead'),
160 ('fwriters', 'FWrite'),
161 ('freaders', 'FRead'),
162 ('readers', 'FirstRead')];
163 self.sRecordSize = dCfg.get('RecordSize', '4k');
164 self.sTestsetSize = dCfg.get('TestsetSize', '2g');
165 self.sQueueDepth = dCfg.get('QueueDepth', '32');
166 self.sFilePath = dCfg.get('FilePath', '/mnt/iozone');
167 self.fDirectIo = True;
168
169 sTargetOs = dCfg.get('TargetOs');
170 if sTargetOs == 'solaris':
171 self.fDirectIo = False;
172
173 def prepare(self, cMsTimeout = 30000):
174 """ Prepares the testcase """
175 _ = cMsTimeout;
176 return True; # Nothing to do.
177
178 def run(self, cMsTimeout = 30000):
179 """ Runs the testcase """
180 tupArgs = ('-r', self.sRecordSize, '-s', self.sTestsetSize, \
181 '-t', '1', '-T', '-F', self.sFilePath + '/iozone.tmp');
182 if self.fDirectIo:
183 tupArgs += ('-I',);
184 fRc, sOutput = self.oExecutor.execBinary('iozone', tupArgs);
185 if fRc:
186 self.sResult = sOutput;
187
188 _ = cMsTimeout;
189 return fRc;
190
191 def cleanup(self):
192 """ Cleans up any leftovers from the testcase. """
193 return True;
194
195 def reportResult(self):
196 """
197 Reports the test results to the test manager.
198 """
199
200 fRc = True;
201 if self.sResult is not None:
202 try:
203 asLines = self.sResult.splitlines();
204 for sLine in asLines:
205 sLine = sLine.strip();
206 if sLine.startswith('Children') is True:
207 # Extract the value
208 idxValue = sLine.rfind('=');
209 if idxValue is -1:
210 raise Exception('IozoneTest: Invalid state');
211
212 idxValue += 1;
213 while sLine[idxValue] == ' ':
214 idxValue += 1;
215
216 # Get the reported value, cut off after the decimal point
217 # it is not supported by the testmanager yet and is not really
218 # relevant anyway.
219 idxValueEnd = idxValue;
220 while sLine[idxValueEnd].isdigit():
221 idxValueEnd += 1;
222
223 for sNeedle, sTestVal in self.lstTests:
224 if sLine.rfind(sNeedle) is not -1:
225 reporter.testValue(sTestVal, sLine[idxValue:idxValueEnd],
226 constants.valueunit.g_asNames[constants.valueunit.KILOBYTES_PER_SEC]);
227 break;
228 except:
229 fRc = False;
230 else:
231 fRc = False;
232
233 return fRc;
234
235
236class tdStorageBenchmark(vbox.TestDriver): # pylint: disable=R0902
237 """
238 Storage benchmark.
239 """
240
241 # Global storage configs for the testbox
242 kdStorageCfgs = {
243 'testboxstor1.de.oracle.com': r'c[3-9]t\dd0\Z',
244 'adaris': [ '/dev/sda' ]
245 };
246
247 def __init__(self):
248 vbox.TestDriver.__init__(self);
249 self.asRsrcs = None;
250 self.oGuestToGuestVM = None;
251 self.oGuestToGuestSess = None;
252 self.oGuestToGuestTxs = None;
253 self.asTestVMsDef = ['tst-storage'];
254 self.asTestVMs = self.asTestVMsDef;
255 self.asSkipVMs = [];
256 self.asVirtModesDef = ['hwvirt', 'hwvirt-np', 'raw',]
257 self.asVirtModes = self.asVirtModesDef
258 self.acCpusDef = [1, 2,]
259 self.acCpus = self.acCpusDef;
260 self.asStorageCtrlsDef = ['AHCI', 'IDE', 'LsiLogicSAS', 'LsiLogic', 'BusLogic', 'NVMe'];
261 self.asStorageCtrls = self.asStorageCtrlsDef;
262 self.asDiskFormatsDef = ['VDI', 'VMDK', 'VHD', 'QED', 'Parallels', 'QCOW', 'iSCSI'];
263 self.asDiskFormats = self.asDiskFormatsDef;
264 self.asTestsDef = ['iozone', 'fio'];
265 self.asTests = self.asTestsDef;
266 self.asIscsiTargetsDef = [ ]; # @todo: Configure one target for basic iSCSI testing
267 self.asIscsiTargets = self.asIscsiTargetsDef;
268 self.fTestHost = False;
269 self.fUseScratch = False;
270 self.oStorCfg = None;
271
272 #
273 # Overridden methods.
274 #
275 def showUsage(self):
276 rc = vbox.TestDriver.showUsage(self);
277 reporter.log('');
278 reporter.log('tdStorageBenchmark1 Options:');
279 reporter.log(' --virt-modes <m1[:m2[:]]');
280 reporter.log(' Default: %s' % (':'.join(self.asVirtModesDef)));
281 reporter.log(' --cpu-counts <c1[:c2[:]]');
282 reporter.log(' Default: %s' % (':'.join(str(c) for c in self.acCpusDef)));
283 reporter.log(' --storage-ctrls <type1[:type2[:...]]>');
284 reporter.log(' Default: %s' % (':'.join(self.asStorageCtrls)));
285 reporter.log(' --disk-formats <type1[:type2[:...]]>');
286 reporter.log(' Default: %s' % (':'.join(self.asDiskFormats)));
287 reporter.log(' --iscsi-targets <target1[:target2[:...]]>');
288 reporter.log(' Default: %s' % (':'.join(self.asIscsiTargets)));
289 reporter.log(' --tests <test1[:test2[:...]]>');
290 reporter.log(' Default: %s' % (':'.join(self.asTests)));
291 reporter.log(' --test-vms <vm1[:vm2[:...]]>');
292 reporter.log(' Test the specified VMs in the given order. Use this to change');
293 reporter.log(' the execution order or limit the choice of VMs');
294 reporter.log(' Default: %s (all)' % (':'.join(self.asTestVMsDef)));
295 reporter.log(' --skip-vms <vm1[:vm2[:...]]>');
296 reporter.log(' Skip the specified VMs when testing.');
297 reporter.log(' --test-host');
298 reporter.log(' Do all configured tests on the host first and report the results');
299 reporter.log(' to get a baseline');
300 reporter.log(' --use-scratch');
301 reporter.log(' Use the scratch directory for testing instead of setting up');
302 reporter.log(' fresh volumes on dedicated disks (for development)');
303 return rc;
304
305 def parseOption(self, asArgs, iArg): # pylint: disable=R0912,R0915
306 if asArgs[iArg] == '--virt-modes':
307 iArg += 1;
308 if iArg >= len(asArgs): raise base.InvalidOption('The "--virt-modes" takes a colon separated list of modes');
309 self.asVirtModes = asArgs[iArg].split(':');
310 for s in self.asVirtModes:
311 if s not in self.asVirtModesDef:
312 raise base.InvalidOption('The "--virt-modes" value "%s" is not valid; valid values are: %s' \
313 % (s, ' '.join(self.asVirtModesDef)));
314 elif asArgs[iArg] == '--cpu-counts':
315 iArg += 1;
316 if iArg >= len(asArgs): raise base.InvalidOption('The "--cpu-counts" takes a colon separated list of cpu counts');
317 self.acCpus = [];
318 for s in asArgs[iArg].split(':'):
319 try: c = int(s);
320 except: raise base.InvalidOption('The "--cpu-counts" value "%s" is not an integer' % (s,));
321 if c <= 0: raise base.InvalidOption('The "--cpu-counts" value "%s" is zero or negative' % (s,));
322 self.acCpus.append(c);
323 elif asArgs[iArg] == '--storage-ctrls':
324 iArg += 1;
325 if iArg >= len(asArgs):
326 raise base.InvalidOption('The "--storage-ctrls" takes a colon separated list of Storage controller types');
327 self.asStorageCtrls = asArgs[iArg].split(':');
328 elif asArgs[iArg] == '--disk-formats':
329 iArg += 1;
330 if iArg >= len(asArgs): raise base.InvalidOption('The "--disk-formats" takes a colon separated list of disk formats');
331 self.asDiskFormats = asArgs[iArg].split(':');
332 elif asArgs[iArg] == '--iscsi-targets':
333 iArg += 1;
334 if iArg >= len(asArgs):
335 raise base.InvalidOption('The "--iscsi-targets" takes a colon separated list of iscsi targets');
336 self.asIscsiTargets = asArgs[iArg].split(':');
337 elif asArgs[iArg] == '--tests':
338 iArg += 1;
339 if iArg >= len(asArgs): raise base.InvalidOption('The "--tests" takes a colon separated list of disk formats');
340 self.asTests = asArgs[iArg].split(':');
341 elif asArgs[iArg] == '--test-vms':
342 iArg += 1;
343 if iArg >= len(asArgs): raise base.InvalidOption('The "--test-vms" takes colon separated list');
344 self.asTestVMs = asArgs[iArg].split(':');
345 for s in self.asTestVMs:
346 if s not in self.asTestVMsDef:
347 raise base.InvalidOption('The "--test-vms" value "%s" is not valid; valid values are: %s' \
348 % (s, ' '.join(self.asTestVMsDef)));
349 elif asArgs[iArg] == '--skip-vms':
350 iArg += 1;
351 if iArg >= len(asArgs): raise base.InvalidOption('The "--skip-vms" takes colon separated list');
352 self.asSkipVMs = asArgs[iArg].split(':');
353 for s in self.asSkipVMs:
354 if s not in self.asTestVMsDef:
355 reporter.log('warning: The "--test-vms" value "%s" does not specify any of our test VMs.' % (s));
356 elif asArgs[iArg] == '--test-host':
357 self.fTestHost = True;
358 elif asArgs[iArg] == '--use-scratch':
359 self.fUseScratch = True;
360 else:
361 return vbox.TestDriver.parseOption(self, asArgs, iArg);
362 return iArg + 1;
363
364 def completeOptions(self):
365 # Remove skipped VMs from the test list.
366 for sVM in self.asSkipVMs:
367 try: self.asTestVMs.remove(sVM);
368 except: pass;
369
370 return vbox.TestDriver.completeOptions(self);
371
372 def getResourceSet(self):
373 # Construct the resource list the first time it's queried.
374 if self.asRsrcs is None:
375 self.asRsrcs = [];
376 if 'tst-storage' in self.asTestVMs:
377 self.asRsrcs.append('5.0/storage/tst-storage.vdi');
378
379 return self.asRsrcs;
380
381 def actionConfig(self):
382
383 # Make sure vboxapi has been imported so we can use the constants.
384 if not self.importVBoxApi():
385 return False;
386
387 #
388 # Configure the VMs we're going to use.
389 #
390
391 # Linux VMs
392 if 'tst-storage' in self.asTestVMs:
393 oVM = self.createTestVM('tst-storage', 1, '5.0/storage/tst-storage.vdi', sKind = 'ArchLinux_64', fIoApic = True, \
394 eNic0AttachType = vboxcon.NetworkAttachmentType_NAT, \
395 eNic0Type = vboxcon.NetworkAdapterType_Am79C973);
396 if oVM is None:
397 return False;
398
399 return True;
400
401 def actionExecute(self):
402 """
403 Execute the testcase.
404 """
405 fRc = self.test1();
406 return fRc;
407
408
409 #
410 # Test execution helpers.
411 #
412
413 def prepareStorage(self, oStorCfg):
414 """
415 Prepares the host storage for disk images or direct testing on the host.
416 """
417 # Create a basic pool with the default configuration.
418 sMountPoint = None;
419 fRc, sPoolId = oStorCfg.createStoragePool();
420 if fRc:
421 fRc, sMountPoint = oStorCfg.createVolume(sPoolId);
422 if not fRc:
423 sMountPoint = None;
424 oStorCfg.cleanup();
425
426 return sMountPoint;
427
428 def cleanupStorage(self, oStorCfg):
429 """
430 Cleans up any created storage space for a test.
431 """
432 return oStorCfg.cleanup();
433
434 def getGuestDisk(self, oSession, oTxsSession, eStorageController):
435 """
436 Gets the path of the disk in the guest to use for testing.
437 """
438 lstDisks = None;
439
440 # The naming scheme for NVMe is different and we don't have
441 # to query the guest for unformatted disks here because the disk with the OS
442 # is not attached to a NVMe controller.
443 if eStorageController == vboxcon.StorageControllerType_NVMe:
444 lstDisks = [ '/dev/nvme0n1' ];
445 else:
446 # Find a unformatted disk (no partition).
447 # @todo: This is a hack because LIST and STAT are not yet implemented
448 # in TXS (get to this eventually)
449 lstBlkDev = [ '/dev/sda', '/dev/sdb' ];
450 for sBlkDev in lstBlkDev:
451 fRc = oTxsSession.syncExec('/usr/bin/ls', ('ls', sBlkDev + '1'));
452 if not fRc:
453 lstDisks = [ sBlkDev ];
454 break;
455
456 _ = oSession;
457 return lstDisks;
458
459 def testBenchmark(self, sTargetOs, sBenchmark, sMountpoint, oExecutor):
460 """
461 Runs the given benchmark on the test host.
462 """
463 # Create a basic config
464 dCfg = {
465 'RecordSize': '64k',
466 'TestsetSize': '100m',
467 'QueueDepth': '32',
468 'FilePath': sMountpoint,
469 'TargetOs': sTargetOs
470 };
471
472 oTst = None;
473 if sBenchmark == 'iozone':
474 oTst = IozoneTest(oExecutor, dCfg);
475 elif sBenchmark == 'fio':
476 oTst = FioTest(oExecutor, dCfg); # pylint: disable=R0204
477
478 if oTst is not None:
479 reporter.testStart(sBenchmark);
480 fRc = oTst.prepare();
481 if fRc:
482 fRc = oTst.run();
483 if fRc:
484 fRc = oTst.reportResult();
485 else:
486 reporter.testFailure('Running the testcase failed');
487 else:
488 reporter.testFailure('Preparing the testcase failed');
489
490 oTst.cleanup();
491 reporter.testDone();
492
493 return fRc;
494
495 def testBenchmarks(self, sTargetOs, sMountPoint, oExecutor):
496 """
497 Runs all the configured benchmarks on the target.
498 """
499 for sTest in self.asTests:
500 self.testBenchmark(sTargetOs, sTest, sMountPoint, oExecutor);
501
502 def test1OneCfg(self, sVmName, eStorageController, sDiskFormat, sDiskPath, cCpus, fHwVirt, fNestedPaging):
503 """
504 Runs the specified VM thru test #1.
505
506 Returns a success indicator on the general test execution. This is not
507 the actual test result.
508 """
509 oVM = self.getVmByName(sVmName);
510
511 # Reconfigure the VM
512 fRc = True;
513 oSession = self.openSession(oVM);
514 if oSession is not None:
515 # Attach HD
516 fRc = oSession.ensureControllerAttached(_ControllerTypeToName(eStorageController));
517 fRc = fRc and oSession.setStorageControllerType(eStorageController, _ControllerTypeToName(eStorageController));
518
519 iDevice = 0;
520 if eStorageController == vboxcon.StorageControllerType_PIIX3 or \
521 eStorageController == vboxcon.StorageControllerType_PIIX4:
522 iDevice = 1; # Master is for the OS.
523
524 if sDiskFormat == "iSCSI":
525 listNames = [];
526 listValues = [];
527 listValues = sDiskPath.split('|');
528 listNames.append('TargetAddress');
529 listNames.append('TargetName');
530 listNames.append('LUN');
531
532 if self.fpApiVer >= 5.0:
533 oHd = oSession.oVBox.createMedium(sDiskFormat, sDiskPath, vboxcon.AccessMode_ReadWrite, \
534 vboxcon.DeviceType_HardDisk);
535 else:
536 oHd = oSession.oVBox.createHardDisk(sDiskFormat, sDiskPath);
537 oHd.type = vboxcon.MediumType_Normal;
538 oHd.setProperties(listNames, listValues);
539
540 # Attach it.
541 if fRc is True:
542 try:
543 if oSession.fpApiVer >= 4.0:
544 oSession.o.machine.attachDevice(_ControllerTypeToName(eStorageController), \
545 0, iDevice, vboxcon.DeviceType_HardDisk, oHd);
546 else:
547 oSession.o.machine.attachDevice(_ControllerTypeToName(eStorageController), \
548 0, iDevice, vboxcon.DeviceType_HardDisk, oHd.id);
549 except:
550 reporter.errorXcpt('attachDevice("%s",%s,%s,HardDisk,"%s") failed on "%s"' \
551 % (_ControllerTypeToName(eStorageController), 1, 0, oHd.id, oSession.sName) );
552 fRc = False;
553 else:
554 reporter.log('attached "%s" to %s' % (sDiskPath, oSession.sName));
555 else:
556 fRc = fRc and oSession.createAndAttachHd(sDiskPath, sDiskFormat, _ControllerTypeToName(eStorageController), \
557 cb = 300*1024*1024*1024, iPort = 0, iDevice = iDevice, \
558 fImmutable = False);
559 fRc = fRc and oSession.enableVirtEx(fHwVirt);
560 fRc = fRc and oSession.enableNestedPaging(fNestedPaging);
561 fRc = fRc and oSession.setCpuCount(cCpus);
562 fRc = fRc and oSession.saveSettings();
563 fRc = oSession.close() and fRc and True; # pychecker hack.
564 oSession = None;
565 else:
566 fRc = False;
567
568 # Start up.
569 if fRc is True:
570 self.logVmInfo(oVM);
571 oSession, oTxsSession = self.startVmAndConnectToTxsViaTcp(sVmName, fCdWait = False, fNatForwardingForTxs = True);
572 if oSession is not None:
573 self.addTask(oSession);
574
575 # Fudge factor - Allow the guest to finish starting up.
576 self.sleep(5);
577
578 # Prepare the storage on the guest
579 lstBinaryPaths = ['/bin', '/sbin', '/usr/bin', '/usr/sbin' ];
580 oExecVm = remoteexecutor.RemoteExecutor(oTxsSession, lstBinaryPaths, '${SCRATCH}');
581 oStorCfgVm = storagecfg.StorageCfg(oExecVm, 'linux', self.getGuestDisk(oSession, oTxsSession, \
582 eStorageController));
583
584 sMountPoint = self.prepareStorage(oStorCfgVm);
585 if sMountPoint is not None:
586 self.testBenchmarks('linux', sMountPoint, oExecVm);
587 self.cleanupStorage(oStorCfgVm);
588 else:
589 reporter.testFailure('Failed to prepare storage for the guest benchmark');
590
591 # cleanup.
592 self.removeTask(oTxsSession);
593 self.terminateVmBySession(oSession)
594 else:
595 fRc = False;
596
597 # Remove disk
598 oSession = self.openSession(oVM);
599 if oSession is not None:
600 try:
601 oSession.o.machine.detachDevice(_ControllerTypeToName(eStorageController), 0, iDevice);
602
603 # Remove storage controller if it is not an IDE controller.
604 if eStorageController is not vboxcon.StorageControllerType_PIIX3 \
605 and eStorageController is not vboxcon.StorageControllerType_PIIX4:
606 oSession.o.machine.removeStorageController(_ControllerTypeToName(eStorageController));
607
608 oSession.saveSettings();
609 self.oVBox.deleteHdByLocation(sDiskPath);
610 oSession.saveSettings();
611 oSession.close();
612 oSession = None;
613 except:
614 reporter.errorXcpt('failed to detach/delete disk %s from storage controller' % (sDiskPath));
615 else:
616 fRc = False;
617
618 return fRc;
619
620 def testBenchmarkOneVM(self, sVmName):
621 """
622 Runs one VM thru the various benchmark configurations.
623 """
624 reporter.testStart(sVmName);
625 fRc = True;
626 for sStorageCtrl in self.asStorageCtrls:
627 reporter.testStart(sStorageCtrl);
628
629 if sStorageCtrl == 'AHCI':
630 eStorageCtrl = vboxcon.StorageControllerType_IntelAhci;
631 elif sStorageCtrl == 'IDE':
632 eStorageCtrl = vboxcon.StorageControllerType_PIIX4;
633 elif sStorageCtrl == 'LsiLogicSAS':
634 eStorageCtrl = vboxcon.StorageControllerType_LsiLogicSas;
635 elif sStorageCtrl == 'LsiLogic':
636 eStorageCtrl = vboxcon.StorageControllerType_LsiLogic;
637 elif sStorageCtrl == 'BusLogic':
638 if sVmName == 'tst-storage': # Broken for 64bit Linux
639 reporter.testDone(True);
640 continue;
641 eStorageCtrl = vboxcon.StorageControllerType_BusLogic;
642 elif sStorageCtrl == 'NVMe':
643 eStorageCtrl = vboxcon.StorageControllerType_NVMe;
644 else:
645 eStorageCtrl = None;
646
647 for sDiskFormat in self.asDiskFormats:
648 reporter.testStart('%s' % (sDiskFormat));
649
650 if sDiskFormat == "iSCSI":
651 asPaths = self.asIscsiTargets;
652 else:
653 if self.fUseScratch:
654 asPaths = [ self.sScratchPath ];
655 else:
656 # Create a new default storage config on the host
657 sMountPoint = self.prepareStorage(self.oStorCfg);
658 if sMountPoint is not None:
659 # Create a directory where every normal user can write to.
660 self.oStorCfg.mkDirOnVolume(sMountPoint, 'test', 0777);
661 asPaths = [ sMountPoint + '/test' ];
662 else:
663 asPaths = [];
664 fRc = False;
665 reporter.testFailure('Failed to prepare storage for VM');
666
667 for sPath in asPaths:
668 reporter.testStart('%s' % (sPath));
669
670 if sDiskFormat == "iSCSI":
671 sPath = sPath;
672 else:
673 sPath = sPath + "/test.disk";
674
675 for cCpus in self.acCpus:
676 if cCpus == 1: reporter.testStart('1 cpu');
677 else: reporter.testStart('%u cpus' % (cCpus));
678
679 for sVirtMode in self.asVirtModes:
680 if sVirtMode == 'raw' and (cCpus > 1 or sVmName == 'tst-storage'):
681 continue;
682 hsVirtModeDesc = {};
683 hsVirtModeDesc['raw'] = 'Raw-mode';
684 hsVirtModeDesc['hwvirt'] = 'HwVirt';
685 hsVirtModeDesc['hwvirt-np'] = 'NestedPaging';
686 reporter.testStart(hsVirtModeDesc[sVirtMode]);
687
688 fHwVirt = sVirtMode != 'raw';
689 fNestedPaging = sVirtMode == 'hwvirt-np';
690 fRc = self.test1OneCfg(sVmName, eStorageCtrl, sDiskFormat, sPath, \
691 cCpus, fHwVirt, fNestedPaging) and fRc and True; # pychecker hack.
692 reporter.testDone();
693
694 reporter.testDone();
695 reporter.testDone();
696
697 # Cleanup storage area
698 if sDiskFormat != 'iSCSI' and not self.fUseScratch:
699 self.cleanupStorage(self.oStorCfg);
700
701 reporter.testDone();
702 reporter.testDone();
703 reporter.testDone();
704 return fRc;
705
706 def test1(self):
707 """
708 Executes test #1.
709 """
710
711 fRc = True;
712 oDiskCfg = self.kdStorageCfgs.get(socket.gethostname().lower());
713
714 # Test the host first if requested
715 if oDiskCfg is not None:
716 lstBinaryPaths = ['/bin', '/sbin', '/usr/bin', '/usr/sbin', \
717 '/opt/csw/bin', '/usr/ccs/bin', '/usr/sfw/bin'];
718 oExecutor = remoteexecutor.RemoteExecutor(None, lstBinaryPaths, self.sScratchPath);
719 self.oStorCfg = storagecfg.StorageCfg(oExecutor, utils.getHostOs(), oDiskCfg);
720
721 if self.fTestHost:
722 reporter.testStart('Host');
723 if self.fUseScratch:
724 sMountPoint = self.sScratchPath;
725 else:
726 sMountPoint = self.prepareStorage(self.oStorCfg);
727 if sMountPoint is not None:
728 fRc = self.testBenchmarks(utils.getHostOs(), sMountPoint, oExecutor);
729 self.cleanupStorage(self.oStorCfg);
730 else:
731 reporter.testFailure('Failed to prepare host storage');
732 reporter.testDone();
733
734 if fRc:
735 # Loop thru the test VMs.
736 for sVM in self.asTestVMs:
737 # run test on the VM.
738 if not self.testBenchmarkOneVM(sVM):
739 fRc = False;
740 else:
741 fRc = True;
742 else:
743 fRc = False;
744
745 return fRc;
746
747if __name__ == '__main__':
748 sys.exit(tdStorageBenchmark().main(sys.argv));
749
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