VirtualBox

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

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

ValidationKit/tests/tdStorageBenchmark1: Add 32bit variant for the VM to test BusLogic controllers as well

  • Property svn:eol-style set to LF
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 30.7 KB
Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3# $Id: tdStorageBenchmark1.py 62356 2016-07-20 12:52:02Z 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: 62356 $"
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', 'tst-storage32'];
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 if 'tst-storage32' in self.asTestVMs:
379 self.asRsrcs.append('5.0/storage/tst-storage32.vdi');
380
381 return self.asRsrcs;
382
383 def actionConfig(self):
384
385 # Make sure vboxapi has been imported so we can use the constants.
386 if not self.importVBoxApi():
387 return False;
388
389 #
390 # Configure the VMs we're going to use.
391 #
392
393 # Linux VMs
394 if 'tst-storage' in self.asTestVMs:
395 oVM = self.createTestVM('tst-storage', 1, '5.0/storage/tst-storage.vdi', sKind = 'ArchLinux_64', fIoApic = True, \
396 eNic0AttachType = vboxcon.NetworkAttachmentType_NAT, \
397 eNic0Type = vboxcon.NetworkAdapterType_Am79C973);
398 if oVM is None:
399 return False;
400
401 if 'tst-storage32' in self.asTestVMs:
402 oVM = self.createTestVM('tst-storage32', 1, '5.0/storage/tst-storage32.vdi', sKind = 'ArchLinux', fIoApic = True, \
403 eNic0AttachType = vboxcon.NetworkAttachmentType_NAT, \
404 eNic0Type = vboxcon.NetworkAdapterType_Am79C973);
405 if oVM is None:
406 return False;
407
408 return True;
409
410 def actionExecute(self):
411 """
412 Execute the testcase.
413 """
414 fRc = self.test1();
415 return fRc;
416
417
418 #
419 # Test execution helpers.
420 #
421
422 def prepareStorage(self, oStorCfg):
423 """
424 Prepares the host storage for disk images or direct testing on the host.
425 """
426 # Create a basic pool with the default configuration.
427 sMountPoint = None;
428 fRc, sPoolId = oStorCfg.createStoragePool();
429 if fRc:
430 fRc, sMountPoint = oStorCfg.createVolume(sPoolId);
431 if not fRc:
432 sMountPoint = None;
433 oStorCfg.cleanup();
434
435 return sMountPoint;
436
437 def cleanupStorage(self, oStorCfg):
438 """
439 Cleans up any created storage space for a test.
440 """
441 return oStorCfg.cleanup();
442
443 def getGuestDisk(self, oSession, oTxsSession, eStorageController):
444 """
445 Gets the path of the disk in the guest to use for testing.
446 """
447 lstDisks = None;
448
449 # The naming scheme for NVMe is different and we don't have
450 # to query the guest for unformatted disks here because the disk with the OS
451 # is not attached to a NVMe controller.
452 if eStorageController == vboxcon.StorageControllerType_NVMe:
453 lstDisks = [ '/dev/nvme0n1' ];
454 else:
455 # Find a unformatted disk (no partition).
456 # @todo: This is a hack because LIST and STAT are not yet implemented
457 # in TXS (get to this eventually)
458 lstBlkDev = [ '/dev/sda', '/dev/sdb' ];
459 for sBlkDev in lstBlkDev:
460 fRc = oTxsSession.syncExec('/usr/bin/ls', ('ls', sBlkDev + '1'));
461 if not fRc:
462 lstDisks = [ sBlkDev ];
463 break;
464
465 _ = oSession;
466 return lstDisks;
467
468 def testBenchmark(self, sTargetOs, sBenchmark, sMountpoint, oExecutor):
469 """
470 Runs the given benchmark on the test host.
471 """
472 # Create a basic config
473 dCfg = {
474 'RecordSize': '64k',
475 'TestsetSize': '100m',
476 'QueueDepth': '32',
477 'FilePath': sMountpoint,
478 'TargetOs': sTargetOs
479 };
480
481 oTst = None;
482 if sBenchmark == 'iozone':
483 oTst = IozoneTest(oExecutor, dCfg);
484 elif sBenchmark == 'fio':
485 oTst = FioTest(oExecutor, dCfg); # pylint: disable=R0204
486
487 if oTst is not None:
488 reporter.testStart(sBenchmark);
489 fRc = oTst.prepare();
490 if fRc:
491 fRc = oTst.run();
492 if fRc:
493 fRc = oTst.reportResult();
494 else:
495 reporter.testFailure('Running the testcase failed');
496 else:
497 reporter.testFailure('Preparing the testcase failed');
498
499 oTst.cleanup();
500 reporter.testDone();
501
502 return fRc;
503
504 def testBenchmarks(self, sTargetOs, sMountPoint, oExecutor):
505 """
506 Runs all the configured benchmarks on the target.
507 """
508 for sTest in self.asTests:
509 self.testBenchmark(sTargetOs, sTest, sMountPoint, oExecutor);
510
511 def test1OneCfg(self, sVmName, eStorageController, sDiskFormat, sDiskPath, cCpus, fHwVirt, fNestedPaging):
512 """
513 Runs the specified VM thru test #1.
514
515 Returns a success indicator on the general test execution. This is not
516 the actual test result.
517 """
518 oVM = self.getVmByName(sVmName);
519
520 # Reconfigure the VM
521 fRc = True;
522 oSession = self.openSession(oVM);
523 if oSession is not None:
524 # Attach HD
525 fRc = oSession.ensureControllerAttached(_ControllerTypeToName(eStorageController));
526 fRc = fRc and oSession.setStorageControllerType(eStorageController, _ControllerTypeToName(eStorageController));
527
528 iDevice = 0;
529 if eStorageController == vboxcon.StorageControllerType_PIIX3 or \
530 eStorageController == vboxcon.StorageControllerType_PIIX4:
531 iDevice = 1; # Master is for the OS.
532
533 if sDiskFormat == "iSCSI":
534 listNames = [];
535 listValues = [];
536 listValues = sDiskPath.split('|');
537 listNames.append('TargetAddress');
538 listNames.append('TargetName');
539 listNames.append('LUN');
540
541 if self.fpApiVer >= 5.0:
542 oHd = oSession.oVBox.createMedium(sDiskFormat, sDiskPath, vboxcon.AccessMode_ReadWrite, \
543 vboxcon.DeviceType_HardDisk);
544 else:
545 oHd = oSession.oVBox.createHardDisk(sDiskFormat, sDiskPath);
546 oHd.type = vboxcon.MediumType_Normal;
547 oHd.setProperties(listNames, listValues);
548
549 # Attach it.
550 if fRc is True:
551 try:
552 if oSession.fpApiVer >= 4.0:
553 oSession.o.machine.attachDevice(_ControllerTypeToName(eStorageController), \
554 0, iDevice, vboxcon.DeviceType_HardDisk, oHd);
555 else:
556 oSession.o.machine.attachDevice(_ControllerTypeToName(eStorageController), \
557 0, iDevice, vboxcon.DeviceType_HardDisk, oHd.id);
558 except:
559 reporter.errorXcpt('attachDevice("%s",%s,%s,HardDisk,"%s") failed on "%s"' \
560 % (_ControllerTypeToName(eStorageController), 1, 0, oHd.id, oSession.sName) );
561 fRc = False;
562 else:
563 reporter.log('attached "%s" to %s' % (sDiskPath, oSession.sName));
564 else:
565 fRc = fRc and oSession.createAndAttachHd(sDiskPath, sDiskFormat, _ControllerTypeToName(eStorageController), \
566 cb = 300*1024*1024*1024, iPort = 0, iDevice = iDevice, \
567 fImmutable = False);
568 fRc = fRc and oSession.enableVirtEx(fHwVirt);
569 fRc = fRc and oSession.enableNestedPaging(fNestedPaging);
570 fRc = fRc and oSession.setCpuCount(cCpus);
571 fRc = fRc and oSession.saveSettings();
572 fRc = oSession.close() and fRc and True; # pychecker hack.
573 oSession = None;
574 else:
575 fRc = False;
576
577 # Start up.
578 if fRc is True:
579 self.logVmInfo(oVM);
580 oSession, oTxsSession = self.startVmAndConnectToTxsViaTcp(sVmName, fCdWait = False, fNatForwardingForTxs = True);
581 if oSession is not None:
582 self.addTask(oSession);
583
584 # Fudge factor - Allow the guest to finish starting up.
585 self.sleep(5);
586
587 # Prepare the storage on the guest
588 lstBinaryPaths = ['/bin', '/sbin', '/usr/bin', '/usr/sbin' ];
589 oExecVm = remoteexecutor.RemoteExecutor(oTxsSession, lstBinaryPaths, '${SCRATCH}');
590 oStorCfgVm = storagecfg.StorageCfg(oExecVm, 'linux', self.getGuestDisk(oSession, oTxsSession, \
591 eStorageController));
592
593 sMountPoint = self.prepareStorage(oStorCfgVm);
594 if sMountPoint is not None:
595 self.testBenchmarks('linux', sMountPoint, oExecVm);
596 self.cleanupStorage(oStorCfgVm);
597 else:
598 reporter.testFailure('Failed to prepare storage for the guest benchmark');
599
600 # cleanup.
601 self.removeTask(oTxsSession);
602 self.terminateVmBySession(oSession)
603 else:
604 fRc = False;
605
606 # Remove disk
607 oSession = self.openSession(oVM);
608 if oSession is not None:
609 try:
610 oSession.o.machine.detachDevice(_ControllerTypeToName(eStorageController), 0, iDevice);
611
612 # Remove storage controller if it is not an IDE controller.
613 if eStorageController is not vboxcon.StorageControllerType_PIIX3 \
614 and eStorageController is not vboxcon.StorageControllerType_PIIX4:
615 oSession.o.machine.removeStorageController(_ControllerTypeToName(eStorageController));
616
617 oSession.saveSettings();
618 self.oVBox.deleteHdByLocation(sDiskPath);
619 oSession.saveSettings();
620 oSession.close();
621 oSession = None;
622 except:
623 reporter.errorXcpt('failed to detach/delete disk %s from storage controller' % (sDiskPath));
624 else:
625 fRc = False;
626
627 return fRc;
628
629 def testBenchmarkOneVM(self, sVmName):
630 """
631 Runs one VM thru the various benchmark configurations.
632 """
633 reporter.testStart(sVmName);
634 fRc = True;
635 for sStorageCtrl in self.asStorageCtrls:
636 reporter.testStart(sStorageCtrl);
637
638 if sStorageCtrl == 'AHCI':
639 eStorageCtrl = vboxcon.StorageControllerType_IntelAhci;
640 elif sStorageCtrl == 'IDE':
641 eStorageCtrl = vboxcon.StorageControllerType_PIIX4;
642 elif sStorageCtrl == 'LsiLogicSAS':
643 eStorageCtrl = vboxcon.StorageControllerType_LsiLogicSas;
644 elif sStorageCtrl == 'LsiLogic':
645 eStorageCtrl = vboxcon.StorageControllerType_LsiLogic;
646 elif sStorageCtrl == 'BusLogic':
647 if sVmName == 'tst-storage': # Broken for 64bit Linux
648 reporter.testDone(True);
649 continue;
650 eStorageCtrl = vboxcon.StorageControllerType_BusLogic;
651 elif sStorageCtrl == 'NVMe':
652 eStorageCtrl = vboxcon.StorageControllerType_NVMe;
653 else:
654 eStorageCtrl = None;
655
656 for sDiskFormat in self.asDiskFormats:
657 reporter.testStart('%s' % (sDiskFormat));
658
659 if sDiskFormat == "iSCSI":
660 asPaths = self.asIscsiTargets;
661 else:
662 if self.fUseScratch:
663 asPaths = [ self.sScratchPath ];
664 else:
665 # Create a new default storage config on the host
666 sMountPoint = self.prepareStorage(self.oStorCfg);
667 if sMountPoint is not None:
668 # Create a directory where every normal user can write to.
669 self.oStorCfg.mkDirOnVolume(sMountPoint, 'test', 0777);
670 asPaths = [ sMountPoint + '/test' ];
671 else:
672 asPaths = [];
673 fRc = False;
674 reporter.testFailure('Failed to prepare storage for VM');
675
676 for sPath in asPaths:
677 reporter.testStart('%s' % (sPath));
678
679 if sDiskFormat == "iSCSI":
680 sPath = sPath;
681 else:
682 sPath = sPath + "/test.disk";
683
684 for cCpus in self.acCpus:
685 if cCpus == 1: reporter.testStart('1 cpu');
686 else: reporter.testStart('%u cpus' % (cCpus));
687
688 for sVirtMode in self.asVirtModes:
689 if sVirtMode == 'raw' and (cCpus > 1 or sVmName == 'tst-storage'):
690 continue;
691 hsVirtModeDesc = {};
692 hsVirtModeDesc['raw'] = 'Raw-mode';
693 hsVirtModeDesc['hwvirt'] = 'HwVirt';
694 hsVirtModeDesc['hwvirt-np'] = 'NestedPaging';
695 reporter.testStart(hsVirtModeDesc[sVirtMode]);
696
697 fHwVirt = sVirtMode != 'raw';
698 fNestedPaging = sVirtMode == 'hwvirt-np';
699 fRc = self.test1OneCfg(sVmName, eStorageCtrl, sDiskFormat, sPath, \
700 cCpus, fHwVirt, fNestedPaging) and fRc and True; # pychecker hack.
701 reporter.testDone();
702
703 reporter.testDone();
704 reporter.testDone();
705
706 # Cleanup storage area
707 if sDiskFormat != 'iSCSI' and not self.fUseScratch:
708 self.cleanupStorage(self.oStorCfg);
709
710 reporter.testDone();
711 reporter.testDone();
712 reporter.testDone();
713 return fRc;
714
715 def test1(self):
716 """
717 Executes test #1.
718 """
719
720 fRc = True;
721 oDiskCfg = self.kdStorageCfgs.get(socket.gethostname().lower());
722
723 # Test the host first if requested
724 if oDiskCfg is not None:
725 lstBinaryPaths = ['/bin', '/sbin', '/usr/bin', '/usr/sbin', \
726 '/opt/csw/bin', '/usr/ccs/bin', '/usr/sfw/bin'];
727 oExecutor = remoteexecutor.RemoteExecutor(None, lstBinaryPaths, self.sScratchPath);
728 self.oStorCfg = storagecfg.StorageCfg(oExecutor, utils.getHostOs(), oDiskCfg);
729
730 if self.fTestHost:
731 reporter.testStart('Host');
732 if self.fUseScratch:
733 sMountPoint = self.sScratchPath;
734 else:
735 sMountPoint = self.prepareStorage(self.oStorCfg);
736 if sMountPoint is not None:
737 fRc = self.testBenchmarks(utils.getHostOs(), sMountPoint, oExecutor);
738 self.cleanupStorage(self.oStorCfg);
739 else:
740 reporter.testFailure('Failed to prepare host storage');
741 reporter.testDone();
742
743 if fRc:
744 # Loop thru the test VMs.
745 for sVM in self.asTestVMs:
746 # run test on the VM.
747 if not self.testBenchmarkOneVM(sVM):
748 fRc = False;
749 else:
750 fRc = True;
751 else:
752 fRc = False;
753
754 return fRc;
755
756if __name__ == '__main__':
757 sys.exit(tdStorageBenchmark().main(sys.argv));
758
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