VirtualBox

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

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

ValidationKit/storage: Hack to work around changes in block device naming during bootup (sometimes sda is the test disk and sdb the root volume)

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

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette