VirtualBox

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

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

ValidationKit/storage: Fixes in general and add support for NVMe controllers

  • Property svn:eol-style set to LF
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 28.9 KB
Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3# $Id: tdStorageBenchmark1.py 62190 2016-07-12 12:31:05Z 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: 62190 $"
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 testBenchmark(self, sTargetOs, sBenchmark, sMountpoint, oExecutor):
429 """
430 Runs the given benchmark on the test host.
431 """
432 # Create a basic config
433 dCfg = {
434 'RecordSize': '64k',
435 'TestsetSize': '100m',
436 'QueueDepth': '32',
437 'FilePath': sMountpoint,
438 'TargetOs': sTargetOs
439 };
440
441 oTst = None;
442 if sBenchmark == 'iozone':
443 oTst = IozoneTest(oExecutor, dCfg);
444 elif sBenchmark == 'fio':
445 oTst = FioTest(oExecutor, dCfg); # pylint: disable=R0204
446
447 if oTst is not None:
448 reporter.testStart(sBenchmark);
449 fRc = oTst.prepare();
450 if fRc:
451 fRc = oTst.run();
452 if fRc:
453 fRc = oTst.reportResult();
454 else:
455 reporter.testFailure('Running the testcase failed');
456 else:
457 reporter.testFailure('Preparing the testcase failed');
458
459 oTst.cleanup();
460 reporter.testDone();
461
462 return fRc;
463
464 def testBenchmarks(self, sTargetOs, sMountPoint, oExecutor):
465 """
466 Runs all the configured benchmarks on the target.
467 """
468 for sTest in self.asTests:
469 self.testBenchmark(sTargetOs, sTest, sMountPoint, oExecutor);
470
471 def test1OneCfg(self, sVmName, eStorageController, sDiskFormat, sDiskPath, cCpus, fHwVirt, fNestedPaging):
472 """
473 Runs the specified VM thru test #1.
474
475 Returns a success indicator on the general test execution. This is not
476 the actual test result.
477 """
478 oVM = self.getVmByName(sVmName);
479
480 # Reconfigure the VM
481 fRc = True;
482 oSession = self.openSession(oVM);
483 if oSession is not None:
484 # Attach HD
485 fRc = oSession.ensureControllerAttached(_ControllerTypeToName(eStorageController));
486 fRc = fRc and oSession.setStorageControllerType(eStorageController, _ControllerTypeToName(eStorageController));
487
488 iDevice = 0;
489 if eStorageController == vboxcon.StorageControllerType_PIIX3 or \
490 eStorageController == vboxcon.StorageControllerType_PIIX4:
491 iDevice = 1; # Master is for the OS.
492
493 if sDiskFormat == "iSCSI":
494 listNames = [];
495 listValues = [];
496 listValues = sDiskPath.split('|');
497 listNames.append('TargetAddress');
498 listNames.append('TargetName');
499 listNames.append('LUN');
500
501 if self.fpApiVer >= 5.0:
502 oHd = oSession.oVBox.createMedium(sDiskFormat, sDiskPath, vboxcon.AccessMode_ReadWrite, \
503 vboxcon.DeviceType_HardDisk);
504 else:
505 oHd = oSession.oVBox.createHardDisk(sDiskFormat, sDiskPath);
506 oHd.type = vboxcon.MediumType_Normal;
507 oHd.setProperties(listNames, listValues);
508
509 # Attach it.
510 if fRc is True:
511 try:
512 if oSession.fpApiVer >= 4.0:
513 oSession.o.machine.attachDevice(_ControllerTypeToName(eStorageController), \
514 0, iDevice, vboxcon.DeviceType_HardDisk, oHd);
515 else:
516 oSession.o.machine.attachDevice(_ControllerTypeToName(eStorageController), \
517 0, iDevice, vboxcon.DeviceType_HardDisk, oHd.id);
518 except:
519 reporter.errorXcpt('attachDevice("%s",%s,%s,HardDisk,"%s") failed on "%s"' \
520 % (_ControllerTypeToName(eStorageController), 1, 0, oHd.id, oSession.sName) );
521 fRc = False;
522 else:
523 reporter.log('attached "%s" to %s' % (sDiskPath, oSession.sName));
524 else:
525 fRc = fRc and oSession.createAndAttachHd(sDiskPath, sDiskFormat, _ControllerTypeToName(eStorageController), \
526 cb = 300*1024*1024*1024, iPort = 0, iDevice = iDevice, \
527 fImmutable = False);
528 fRc = fRc and oSession.enableVirtEx(fHwVirt);
529 fRc = fRc and oSession.enableNestedPaging(fNestedPaging);
530 fRc = fRc and oSession.setCpuCount(cCpus);
531 fRc = fRc and oSession.saveSettings();
532 fRc = oSession.close() and fRc and True; # pychecker hack.
533 oSession = None;
534 else:
535 fRc = False;
536
537 # Start up.
538 if fRc is True:
539 self.logVmInfo(oVM);
540 oSession, oTxsSession = self.startVmAndConnectToTxsViaTcp(sVmName, fCdWait = False, fNatForwardingForTxs = True);
541 if oSession is not None:
542 self.addTask(oSession);
543
544 # Fudge factor - Allow the guest to finish starting up.
545 self.sleep(5);
546
547 # Prepare the storage on the guest
548 lstBinaryPaths = ['/bin', '/sbin', '/usr/bin', '/usr/sbin' ];
549 oExecVm = remoteexecutor.RemoteExecutor(oTxsSession, lstBinaryPaths, '${SCRATCH}');
550 lstDisks = [ '/dev/sdb' ];
551 # The naming scheme for NVMe is different.
552 if eStorageController == vboxcon.StorageControllerType_NVMe:
553 lstDisks = [ '/dev/nvme0n1' ];
554 oStorCfgVm = storagecfg.StorageCfg(oExecVm, 'linux', lstDisks);
555
556 sMountPoint = self.prepareStorage(oStorCfgVm);
557 if sMountPoint is not None:
558 self.testBenchmarks('linux', sMountPoint, oExecVm);
559 self.cleanupStorage(oStorCfgVm);
560 else:
561 reporter.testFailure('Failed to prepare storage for the guest benchmark');
562
563 # cleanup.
564 self.removeTask(oTxsSession);
565 self.terminateVmBySession(oSession)
566
567 # Remove disk
568 oSession = self.openSession(oVM);
569 if oSession is not None:
570 try:
571 oSession.o.machine.detachDevice(_ControllerTypeToName(eStorageController), 0, iDevice);
572
573 # Remove storage controller if it is not an IDE controller.
574 if eStorageController is not vboxcon.StorageControllerType_PIIX3 \
575 and eStorageController is not vboxcon.StorageControllerType_PIIX4:
576 oSession.o.machine.removeStorageController(_ControllerTypeToName(eStorageController));
577
578 oSession.saveSettings();
579 self.oVBox.deleteHdByLocation(sDiskPath);
580 oSession.saveSettings();
581 oSession.close();
582 oSession = None;
583 except:
584 reporter.errorXcpt('failed to detach/delete disk %s from storage controller' % (sDiskPath));
585 else:
586 fRc = False;
587 else:
588 fRc = False;
589 return fRc;
590
591 def testBenchmarkOneVM(self, sVmName):
592 """
593 Runs one VM thru the various benchmark configurations.
594 """
595 reporter.testStart(sVmName);
596 fRc = True;
597 for sStorageCtrl in self.asStorageCtrls:
598 reporter.testStart(sStorageCtrl);
599
600 if sStorageCtrl == 'AHCI':
601 eStorageCtrl = vboxcon.StorageControllerType_IntelAhci;
602 elif sStorageCtrl == 'IDE':
603 eStorageCtrl = vboxcon.StorageControllerType_PIIX4;
604 elif sStorageCtrl == 'LsiLogicSAS':
605 eStorageCtrl = vboxcon.StorageControllerType_LsiLogicSas;
606 elif sStorageCtrl == 'LsiLogic':
607 eStorageCtrl = vboxcon.StorageControllerType_LsiLogic;
608 elif sStorageCtrl == 'BusLogic':
609 eStorageCtrl = vboxcon.StorageControllerType_BusLogic;
610 elif sStorageCtrl == 'NVMe':
611 eStorageCtrl = vboxcon.StorageControllerType_NVMe;
612 else:
613 eStorageCtrl = None;
614
615 for sDiskFormat in self.asDiskFormats:
616 reporter.testStart('%s' % (sDiskFormat));
617
618 if sDiskFormat == "iSCSI":
619 asPaths = self.asIscsiTargets;
620 else:
621 if self.fUseScratch:
622 asPaths = [ self.sScratchPath ];
623 else:
624 # Create a new default storage config on the host
625 sMountPoint = self.prepareStorage(self.oStorCfg);
626 if sMountPoint is not None:
627 # Create a directory where every normal user can write to.
628 self.oStorCfg.mkDirOnVolume(sMountPoint, 'test', 0777);
629 asPaths = [ sMountPoint + '/test' ];
630 else:
631 asPaths = [];
632 fRc = False;
633 reporter.testFailure('Failed to prepare storage for VM');
634
635 for sPath in asPaths:
636 reporter.testStart('%s' % (sPath));
637
638 if sDiskFormat == "iSCSI":
639 sPath = sPath;
640 else:
641 sPath = sPath + "/test.disk";
642
643 for cCpus in self.acCpus:
644 if cCpus == 1: reporter.testStart('1 cpu');
645 else: reporter.testStart('%u cpus' % (cCpus));
646
647 for sVirtMode in self.asVirtModes:
648 if sVirtMode == 'raw' and cCpus > 1:
649 continue;
650 hsVirtModeDesc = {};
651 hsVirtModeDesc['raw'] = 'Raw-mode';
652 hsVirtModeDesc['hwvirt'] = 'HwVirt';
653 hsVirtModeDesc['hwvirt-np'] = 'NestedPaging';
654 reporter.testStart(hsVirtModeDesc[sVirtMode]);
655
656 fHwVirt = sVirtMode != 'raw';
657 fNestedPaging = sVirtMode == 'hwvirt-np';
658 fRc = self.test1OneCfg(sVmName, eStorageCtrl, sDiskFormat, sPath, \
659 cCpus, fHwVirt, fNestedPaging) and fRc and True; # pychecker hack.
660 reporter.testDone();
661
662 reporter.testDone();
663 reporter.testDone();
664
665 # Cleanup storage area
666 if sDiskFormat != 'iSCSI' and not self.fUseScratch:
667 self.cleanupStorage(self.oStorCfg);
668
669 reporter.testDone();
670 reporter.testDone();
671 reporter.testDone();
672 return fRc;
673
674 def test1(self):
675 """
676 Executes test #1.
677 """
678
679 fRc = True;
680 oDiskCfg = self.kdStorageCfgs.get(socket.gethostname().lower());
681
682 # Test the host first if requested
683 if oDiskCfg is not None:
684 lstBinaryPaths = ['/bin', '/sbin', '/usr/bin', '/usr/sbin', \
685 '/opt/csw/bin', '/usr/ccs/bin', '/usr/sfw/bin'];
686 oExecutor = remoteexecutor.RemoteExecutor(None, lstBinaryPaths, self.sScratchPath);
687 self.oStorCfg = storagecfg.StorageCfg(oExecutor, utils.getHostOs(), oDiskCfg);
688
689 if self.fTestHost:
690 reporter.testStart('Host');
691 if self.fUseScratch:
692 sMountPoint = self.sScratchPath;
693 else:
694 sMountPoint = self.prepareStorage(self.oStorCfg);
695 if sMountPoint is not None:
696 fRc = self.testBenchmarks(utils.getHostOs(), sMountPoint, oExecutor);
697 self.cleanupStorage(self.oStorCfg);
698 else:
699 reporter.testFailure('Failed to prepare host storage');
700 reporter.testDone();
701
702 if fRc:
703 # Loop thru the test VMs.
704 for sVM in self.asTestVMs:
705 # run test on the VM.
706 if not self.testBenchmarkOneVM(sVM):
707 fRc = False;
708 else:
709 fRc = True;
710 else:
711 fRc = False;
712
713 return fRc;
714
715if __name__ == '__main__':
716 sys.exit(tdStorageBenchmark().main(sys.argv));
717
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