VirtualBox

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

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

VaildationKit/storage: Don't test raw mode for tst-storage as it is a 64-bit VM

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