VirtualBox

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

最後變更 在這個檔案從66244是 66244,由 vboxsync 提交於 8 年 前

ValidationKit/tests/storage: Implement option to use a ramdisk for backing the disk images

  • 屬性 svn:eol-style 設為 LF
  • 屬性 svn:executable 設為 *
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 51.7 KB
 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3# $Id: tdStorageBenchmark1.py 66244 2017-03-24 12:14:06Z vboxsync $
4
5"""
6VirtualBox Validation Kit - Storage benchmark.
7"""
8
9__copyright__ = \
10"""
11Copyright (C) 2012-2017 Oracle Corporation
12
13This file is part of VirtualBox Open Source Edition (OSE), as
14available from http://www.alldomusa.eu.org. This file is free software;
15you can redistribute it and/or modify it under the terms of the GNU
16General Public License (GPL) as published by the Free Software
17Foundation, in version 2 as it comes in the "COPYING" file of the
18VirtualBox OSE distribution. VirtualBox OSE is distributed in the
19hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
20
21The contents of this file may alternatively be used under the terms
22of the Common Development and Distribution License Version 1.0
23(CDDL) only, as it comes in the "COPYING.CDDL" file of the
24VirtualBox OSE distribution, in which case the provisions of the
25CDDL are applicable instead of those of the GPL.
26
27You may elect to license modified versions of this file under the
28terms and conditions of either the GPL or the CDDL or both.
29"""
30__version__ = "$Revision: 66244 $"
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 self.sError = None;
87 self.sResult = None;
88
89 def prepare(self, cMsTimeout = 30000):
90 """ Prepares the testcase """
91
92 sTargetOs = self.dCfg.get('TargetOs', 'linux');
93 sIoEngine, fDirectIo = self.kdHostIoEngine.get(sTargetOs);
94 if sIoEngine is None:
95 return False;
96
97 cfgBuf = StringIO.StringIO();
98 cfgBuf.write('[global]\n');
99 cfgBuf.write('bs=' + self.dCfg.get('RecordSize', '4k') + '\n');
100 cfgBuf.write('ioengine=' + sIoEngine + '\n');
101 cfgBuf.write('iodepth=' + self.dCfg.get('QueueDepth', '32') + '\n');
102 cfgBuf.write('size=' + self.dCfg.get('TestsetSize', '2g') + '\n');
103 if fDirectIo:
104 cfgBuf.write('direct=1\n');
105 else:
106 cfgBuf.write('direct=0\n');
107 cfgBuf.write('directory=' + self.dCfg.get('FilePath', '/mnt') + '\n');
108
109 cfgBuf.write('[seq-write]\n');
110 cfgBuf.write('rw=write\n');
111 cfgBuf.write('stonewall\n');
112
113 cfgBuf.write('[rand-write]\n');
114 cfgBuf.write('rw=randwrite\n');
115 cfgBuf.write('stonewall\n');
116
117 cfgBuf.write('[seq-read]\n');
118 cfgBuf.write('rw=read\n');
119 cfgBuf.write('stonewall\n');
120
121 cfgBuf.write('[rand-read]\n');
122 cfgBuf.write('rw=randread\n');
123 cfgBuf.write('stonewall\n');
124
125 self.sCfgFileId = self.oExecutor.copyString(cfgBuf.getvalue(), 'aio-test', cMsTimeout);
126 return self.sCfgFileId is not None;
127
128 def run(self, cMsTimeout = 30000):
129 """ Runs the testcase """
130 _ = cMsTimeout
131 fRc, sOutput, sError = self.oExecutor.execBinary('fio', (self.sCfgFileId,), cMsTimeout = cMsTimeout);
132 if fRc:
133 self.sResult = sOutput;
134 else:
135 self.sError = ('Binary: fio\n' +
136 '\nOutput:\n\n' +
137 sOutput +
138 '\nError:\n\n' +
139 sError);
140 return fRc;
141
142 def cleanup(self):
143 """ Cleans up any leftovers from the testcase. """
144
145 def reportResult(self):
146 """
147 Reports the test results to the test manager.
148 """
149 return True;
150
151 def getErrorReport(self):
152 """
153 Returns the error report in case the testcase failed.
154 """
155 return self.sError;
156
157class IozoneTest(object):
158 """
159 I/O zone testcase.
160 """
161 def __init__(self, oExecutor, dCfg = None):
162 self.oExecutor = oExecutor;
163 self.sResult = None;
164 self.sError = None;
165 self.lstTests = [ ('initial writers', 'FirstWrite'),
166 ('rewriters', 'Rewrite'),
167 ('re-readers', 'ReRead'),
168 ('stride readers', 'StrideRead'),
169 ('reverse readers', 'ReverseRead'),
170 ('random readers', 'RandomRead'),
171 ('mixed workload', 'MixedWorkload'),
172 ('random writers', 'RandomWrite'),
173 ('pwrite writers', 'PWrite'),
174 ('pread readers', 'PRead'),
175 ('fwriters', 'FWrite'),
176 ('freaders', 'FRead'),
177 ('readers', 'FirstRead')];
178 self.sRecordSize = dCfg.get('RecordSize', '4k');
179 self.sTestsetSize = dCfg.get('TestsetSize', '2g');
180 self.sQueueDepth = dCfg.get('QueueDepth', '32');
181 self.sFilePath = dCfg.get('FilePath', '/mnt/iozone');
182 self.fDirectIo = True;
183
184 sTargetOs = dCfg.get('TargetOs');
185 if sTargetOs == 'solaris':
186 self.fDirectIo = False;
187
188 def prepare(self, cMsTimeout = 30000):
189 """ Prepares the testcase """
190 _ = cMsTimeout;
191 return True; # Nothing to do.
192
193 def run(self, cMsTimeout = 30000):
194 """ Runs the testcase """
195 tupArgs = ('-r', self.sRecordSize, '-s', self.sTestsetSize, \
196 '-t', '1', '-T', '-F', self.sFilePath + '/iozone.tmp');
197 if self.fDirectIo:
198 tupArgs += ('-I',);
199 fRc, sOutput, sError = self.oExecutor.execBinary('iozone', tupArgs, cMsTimeout = cMsTimeout);
200 if fRc:
201 self.sResult = sOutput;
202 else:
203 self.sError = ('Binary: iozone\n' +
204 '\nOutput:\n\n' +
205 sOutput +
206 '\nError:\n\n' +
207 sError);
208
209 _ = cMsTimeout;
210 return fRc;
211
212 def cleanup(self):
213 """ Cleans up any leftovers from the testcase. """
214 return True;
215
216 def reportResult(self):
217 """
218 Reports the test results to the test manager.
219 """
220
221 fRc = True;
222 if self.sResult is not None:
223 try:
224 asLines = self.sResult.splitlines();
225 for sLine in asLines:
226 sLine = sLine.strip();
227 if sLine.startswith('Children') is True:
228 # Extract the value
229 idxValue = sLine.rfind('=');
230 if idxValue == -1:
231 raise Exception('IozoneTest: Invalid state');
232
233 idxValue += 1;
234 while sLine[idxValue] == ' ':
235 idxValue += 1;
236
237 # Get the reported value, cut off after the decimal point
238 # it is not supported by the testmanager yet and is not really
239 # relevant anyway.
240 idxValueEnd = idxValue;
241 while sLine[idxValueEnd].isdigit():
242 idxValueEnd += 1;
243
244 for sNeedle, sTestVal in self.lstTests:
245 if sLine.rfind(sNeedle) != -1:
246 reporter.testValue(sTestVal, sLine[idxValue:idxValueEnd],
247 constants.valueunit.g_asNames[constants.valueunit.KILOBYTES_PER_SEC]);
248 break;
249 except:
250 fRc = False;
251 else:
252 fRc = False;
253
254 return fRc;
255
256 def getErrorReport(self):
257 """
258 Returns the error report in case the testcase failed.
259 """
260 return self.sError;
261
262class StorTestCfgMgr(object):
263 """
264 Manages the different testcases.
265 """
266
267 def __init__(self, aasTestLvls, aasTestsBlacklist, fnIsCfgSupported = None):
268 self.aasTestsBlacklist = aasTestsBlacklist;
269 self.at3TestLvls = [];
270 self.iTestLvl = 0;
271 self.fnIsCfgSupported = fnIsCfgSupported;
272 for asTestLvl in aasTestLvls:
273 if isinstance(asTestLvl, tuple):
274 asTestLvl, fnTestFmt = asTestLvl;
275 self.at3TestLvls.append((0, fnTestFmt, asTestLvl));
276 else:
277 self.at3TestLvls.append((0, None, asTestLvl));
278
279 self.at3TestLvls.reverse();
280
281 # Get the first non blacklisted test.
282 asTestCfg = self.getCurrentTestCfg();
283 while asTestCfg and self.isTestCfgBlacklisted(asTestCfg):
284 asTestCfg = self.advanceTestCfg();
285
286 iLvl = 0;
287 for sCfg in asTestCfg:
288 reporter.testStart('%s' % (self.getTestIdString(sCfg, iLvl)));
289 iLvl += 1;
290
291 def __del__(self):
292 # Make sure the tests are marked as done.
293 while self.iTestLvl < len(self.at3TestLvls):
294 reporter.testDone();
295 self.iTestLvl += 1;
296
297 def getTestIdString(self, oCfg, iLvl):
298 """
299 Returns a potentially formatted string for the test name.
300 """
301
302 # The order of the test levels is reversed so get the level starting
303 # from the end.
304 _, fnTestFmt, _ = self.at3TestLvls[len(self.at3TestLvls) - 1 - iLvl];
305 if fnTestFmt is not None:
306 return fnTestFmt(oCfg);
307 return oCfg;
308
309 def isTestCfgBlacklisted(self, asTestCfg):
310 """
311 Returns whether the given test config is black listed.
312 """
313 fBlacklisted = False;
314
315 for asTestBlacklist in self.aasTestsBlacklist:
316 iLvl = 0;
317 fBlacklisted = True;
318 while iLvl < len(asTestBlacklist) and iLvl < len(asTestCfg):
319 if asTestBlacklist[iLvl] != asTestCfg[iLvl] and asTestBlacklist[iLvl] != '*':
320 fBlacklisted = False;
321 break;
322
323 iLvl += 1;
324
325 if not fBlacklisted and self.fnIsCfgSupported is not None:
326 fBlacklisted = not self.fnIsCfgSupported(asTestCfg);
327
328 return fBlacklisted;
329
330 def advanceTestCfg(self):
331 """
332 Advances to the next test config and returns it as an
333 array of strings or an empty config if there is no test left anymore.
334 """
335 iTestCfg, fnTestFmt, asTestCfg = self.at3TestLvls[self.iTestLvl];
336 iTestCfg += 1;
337 self.at3TestLvls[self.iTestLvl] = (iTestCfg, fnTestFmt, asTestCfg);
338 while iTestCfg == len(asTestCfg) and self.iTestLvl < len(self.at3TestLvls):
339 self.at3TestLvls[self.iTestLvl] = (0, fnTestFmt, asTestCfg);
340 self.iTestLvl += 1;
341 if self.iTestLvl < len(self.at3TestLvls):
342 iTestCfg, fnTestFmt, asTestCfg = self.at3TestLvls[self.iTestLvl];
343 iTestCfg += 1;
344 self.at3TestLvls[self.iTestLvl] = (iTestCfg, fnTestFmt, asTestCfg);
345 if iTestCfg < len(asTestCfg):
346 self.iTestLvl = 0;
347 break;
348 else:
349 break; # We reached the end of our tests.
350
351 return self.getCurrentTestCfg();
352
353 def getCurrentTestCfg(self):
354 """
355 Returns the current not black listed test config as an array of strings.
356 """
357 asTestCfg = [];
358
359 if self.iTestLvl < len(self.at3TestLvls):
360 for t3TestLvl in self.at3TestLvls:
361 iTestCfg, _, asTestLvl = t3TestLvl;
362 asTestCfg.append(asTestLvl[iTestCfg]);
363
364 asTestCfg.reverse()
365
366 return asTestCfg;
367
368 def getNextTestCfg(self, fSkippedLast = False):
369 """
370 Returns the next not blacklisted test config or an empty list if
371 there is no test left.
372 """
373 asTestCfgCur = self.getCurrentTestCfg();
374
375 asTestCfg = self.advanceTestCfg();
376 while asTestCfg and self.isTestCfgBlacklisted(asTestCfg):
377 asTestCfg = self.advanceTestCfg();
378
379 # Compare the current and next config and close the approriate test
380 # categories.
381 reporter.testDone(fSkippedLast);
382 if asTestCfg:
383 idxSame = 0;
384 while asTestCfgCur[idxSame] == asTestCfg[idxSame]:
385 idxSame += 1;
386
387 for i in range(idxSame, len(asTestCfg) - 1):
388 reporter.testDone();
389
390 for i in range(idxSame, len(asTestCfg)):
391 reporter.testStart('%s' % (self.getTestIdString(asTestCfg[i], i)));
392
393 else:
394 # No more tests, mark all tests as done
395 for i in range(0, len(asTestCfgCur) - 1):
396 reporter.testDone();
397
398 return asTestCfg;
399
400class tdStorageBenchmark(vbox.TestDriver): # pylint: disable=R0902
401 """
402 Storage benchmark.
403 """
404
405 # Global storage configs for the testbox
406 kdStorageCfgs = {
407 'testboxstor1.de.oracle.com': r'c[3-9]t\dd0\Z',
408 'adaris': [ '/dev/sda' ]
409 };
410
411 # Available test sets.
412 kdTestSets = {
413 # Mostly for developing and debugging the testcase.
414 'Fast': {
415 'RecordSize': '64k',
416 'TestsetSize': '100m',
417 'QueueDepth': '32',
418 'DiskSizeGb': 2
419 },
420 # For quick functionality tests where benchmark results are not required.
421 'Functionality': {
422 'RecordSize': '64k',
423 'TestsetSize': '2g',
424 'QueueDepth': '32',
425 'DiskSizeGb': 10
426 },
427 # For benchmarking the I/O stack.
428 'Benchmark': {
429 'RecordSize': '64k',
430 'TestsetSize': '20g',
431 'QueueDepth': '32',
432 'DiskSizeGb': 30
433 },
434 # For stress testing which takes a lot of time.
435 'Stress': {
436 'RecordSize': '64k',
437 'TestsetSize': '2t',
438 'QueueDepth': '32',
439 'DiskSizeGb': 10000
440 },
441 };
442
443 # Dictionary mapping the virtualization mode mnemonics to a little less cryptic
444 # strings used in test descriptions.
445 kdVirtModeDescs = {
446 'raw' : 'Raw-mode',
447 'hwvirt' : 'HwVirt',
448 'hwvirt-np' : 'NestedPaging'
449 };
450
451 kdHostIoCacheDescs = {
452 'default' : 'HostCacheDef',
453 'hostiocache' : 'HostCacheOn',
454 'no-hostiocache' : 'HostCacheOff'
455 };
456
457 # Array indexes for the test configs.
458 kiVmName = 0;
459 kiStorageCtrl = 1;
460 kiHostIoCache = 2;
461 kiDiskFmt = 3;
462 kiDiskVar = 4;
463 kiCpuCount = 5;
464 kiVirtMode = 6;
465 kiIoTest = 7;
466 kiTestSet = 8;
467
468 def __init__(self):
469 vbox.TestDriver.__init__(self);
470 self.asRsrcs = None;
471 self.asTestVMsDef = ['tst-storage', 'tst-storage32'];
472 self.asTestVMs = self.asTestVMsDef;
473 self.asSkipVMs = [];
474 self.asVirtModesDef = ['hwvirt', 'hwvirt-np', 'raw',]
475 self.asVirtModes = self.asVirtModesDef;
476 self.acCpusDef = [1, 2];
477 self.acCpus = self.acCpusDef;
478 self.asStorageCtrlsDef = ['AHCI', 'IDE', 'LsiLogicSAS', 'LsiLogic', 'BusLogic', 'NVMe'];
479 self.asStorageCtrls = self.asStorageCtrlsDef;
480 self.asHostIoCacheDef = ['default', 'hostiocache', 'no-hostiocache'];
481 self.asHostIoCache = self.asHostIoCacheDef;
482 self.asDiskFormatsDef = ['VDI', 'VMDK', 'VHD', 'QED', 'Parallels', 'QCOW', 'iSCSI'];
483 self.asDiskFormats = self.asDiskFormatsDef;
484 self.asDiskVariantsDef = ['Dynamic', 'Fixed', 'DynamicSplit2G', 'FixedSplit2G', 'Network'];
485 self.asDiskVariants = self.asDiskVariantsDef;
486 self.asTestsDef = ['iozone', 'fio'];
487 self.asTests = self.asTestsDef;
488 self.asTestSetsDef = ['Fast', 'Functionality', 'Benchmark', 'Stress'];
489 self.asTestSets = self.asTestSetsDef;
490 self.asIscsiTargetsDef = [ ]; # @todo: Configure one target for basic iSCSI testing
491 self.asIscsiTargets = self.asIscsiTargetsDef;
492 self.cDiffLvlsDef = 0;
493 self.cDiffLvls = self.cDiffLvlsDef;
494 self.fTestHost = False;
495 self.fUseScratch = False;
496 self.fRecreateStorCfg = True;
497 self.fReportBenchmarkResults = True;
498 self.oStorCfg = None;
499 self.sIoLogPathDef = self.sScratchPath;
500 self.sIoLogPath = self.sIoLogPathDef;
501 self.fIoLog = False;
502 self.fUseRamDiskDef = False;
503 self.fUseRamDisk = self.fUseRamDiskDef;
504
505 #
506 # Overridden methods.
507 #
508 def showUsage(self):
509 rc = vbox.TestDriver.showUsage(self);
510 reporter.log('');
511 reporter.log('tdStorageBenchmark1 Options:');
512 reporter.log(' --virt-modes <m1[:m2[:]]');
513 reporter.log(' Default: %s' % (':'.join(self.asVirtModesDef)));
514 reporter.log(' --cpu-counts <c1[:c2[:]]');
515 reporter.log(' Default: %s' % (':'.join(str(c) for c in self.acCpusDef)));
516 reporter.log(' --storage-ctrls <type1[:type2[:...]]>');
517 reporter.log(' Default: %s' % (':'.join(self.asStorageCtrlsDef)));
518 reporter.log(' --host-io-cache <setting1[:setting2[:...]]>');
519 reporter.log(' Default: %s' % (':'.join(self.asHostIoCacheDef)));
520 reporter.log(' --disk-formats <type1[:type2[:...]]>');
521 reporter.log(' Default: %s' % (':'.join(self.asDiskFormatsDef)));
522 reporter.log(' --disk-variants <variant1[:variant2[:...]]>');
523 reporter.log(' Default: %s' % (':'.join(self.asDiskVariantsDef)));
524 reporter.log(' --iscsi-targets <target1[:target2[:...]]>');
525 reporter.log(' Default: %s' % (':'.join(self.asIscsiTargetsDef)));
526 reporter.log(' --tests <test1[:test2[:...]]>');
527 reporter.log(' Default: %s' % (':'.join(self.asTestsDef)));
528 reporter.log(' --test-sets <set1[:set2[:...]]>');
529 reporter.log(' Default: %s' % (':'.join(self.asTestSetsDef)));
530 reporter.log(' --diff-levels <number of diffs>');
531 reporter.log(' Default: %s' % (self.cDiffLvlsDef));
532 reporter.log(' --test-vms <vm1[:vm2[:...]]>');
533 reporter.log(' Test the specified VMs in the given order. Use this to change');
534 reporter.log(' the execution order or limit the choice of VMs');
535 reporter.log(' Default: %s (all)' % (':'.join(self.asTestVMsDef)));
536 reporter.log(' --skip-vms <vm1[:vm2[:...]]>');
537 reporter.log(' Skip the specified VMs when testing.');
538 reporter.log(' --test-host');
539 reporter.log(' Do all configured tests on the host first and report the results');
540 reporter.log(' to get a baseline');
541 reporter.log(' --use-scratch');
542 reporter.log(' Use the scratch directory for testing instead of setting up');
543 reporter.log(' fresh volumes on dedicated disks (for development)');
544 reporter.log(' --always-wipe-storage-cfg');
545 reporter.log(' Recreate the host storage config before each test');
546 reporter.log(' --dont-wipe-storage-cfg');
547 reporter.log(' Don\'t recreate the host storage config before each test');
548 reporter.log(' --report-benchmark-results');
549 reporter.log(' Report all benchmark results');
550 reporter.log(' --dont-report-benchmark-results');
551 reporter.log(' Don\'t report any benchmark results');
552 reporter.log(' --io-log-path <path>');
553 reporter.log(' Default: %s' % (self.sIoLogPathDef));
554 reporter.log(' --enable-io-log');
555 reporter.log(' Whether to enable I/O logging for each test');
556 reporter.log(' --use-ramdisk');
557 reporter.log(' Default: %s' % (self.fUseRamDiskDef));
558 return rc;
559
560 def parseOption(self, asArgs, iArg): # pylint: disable=R0912,R0915
561 if asArgs[iArg] == '--virt-modes':
562 iArg += 1;
563 if iArg >= len(asArgs): raise base.InvalidOption('The "--virt-modes" takes a colon separated list of modes');
564 self.asVirtModes = asArgs[iArg].split(':');
565 for s in self.asVirtModes:
566 if s not in self.asVirtModesDef:
567 raise base.InvalidOption('The "--virt-modes" value "%s" is not valid; valid values are: %s' \
568 % (s, ' '.join(self.asVirtModesDef)));
569 elif asArgs[iArg] == '--cpu-counts':
570 iArg += 1;
571 if iArg >= len(asArgs): raise base.InvalidOption('The "--cpu-counts" takes a colon separated list of cpu counts');
572 self.acCpus = [];
573 for s in asArgs[iArg].split(':'):
574 try: c = int(s);
575 except: raise base.InvalidOption('The "--cpu-counts" value "%s" is not an integer' % (s,));
576 if c <= 0: raise base.InvalidOption('The "--cpu-counts" value "%s" is zero or negative' % (s,));
577 self.acCpus.append(c);
578 elif asArgs[iArg] == '--storage-ctrls':
579 iArg += 1;
580 if iArg >= len(asArgs):
581 raise base.InvalidOption('The "--storage-ctrls" takes a colon separated list of Storage controller types');
582 self.asStorageCtrls = asArgs[iArg].split(':');
583 elif asArgs[iArg] == '--host-io-cache':
584 iArg += 1;
585 if iArg >= len(asArgs):
586 raise base.InvalidOption('The "--host-io-cache" takes a colon separated list of I/O cache settings');
587 self.asHostIoCache = asArgs[iArg].split(':');
588 elif asArgs[iArg] == '--disk-formats':
589 iArg += 1;
590 if iArg >= len(asArgs): raise base.InvalidOption('The "--disk-formats" takes a colon separated list of disk formats');
591 self.asDiskFormats = asArgs[iArg].split(':');
592 elif asArgs[iArg] == '--disk-variants':
593 iArg += 1;
594 if iArg >= len(asArgs):
595 raise base.InvalidOption('The "--disk-variants" takes a colon separated list of disk variants');
596 self.asDiskVariants = asArgs[iArg].split(':');
597 elif asArgs[iArg] == '--iscsi-targets':
598 iArg += 1;
599 if iArg >= len(asArgs):
600 raise base.InvalidOption('The "--iscsi-targets" takes a colon separated list of iscsi targets');
601 self.asIscsiTargets = asArgs[iArg].split(':');
602 elif asArgs[iArg] == '--tests':
603 iArg += 1;
604 if iArg >= len(asArgs): raise base.InvalidOption('The "--tests" takes a colon separated list of tests to run');
605 self.asTests = asArgs[iArg].split(':');
606 elif asArgs[iArg] == '--test-sets':
607 iArg += 1;
608 if iArg >= len(asArgs): raise base.InvalidOption('The "--test-sets" takes a colon separated list of test sets');
609 self.asTestSets = asArgs[iArg].split(':');
610 elif asArgs[iArg] == '--diff-levels':
611 iArg += 1;
612 if iArg >= len(asArgs): raise base.InvalidOption('The "--diff-levels" takes an integer');
613 try: self.cDiffLvls = int(asArgs[iArg]);
614 except: raise base.InvalidOption('The "--diff-levels" value "%s" is not an integer' % (asArgs[iArg],));
615 elif asArgs[iArg] == '--test-vms':
616 iArg += 1;
617 if iArg >= len(asArgs): raise base.InvalidOption('The "--test-vms" takes colon separated list');
618 self.asTestVMs = asArgs[iArg].split(':');
619 for s in self.asTestVMs:
620 if s not in self.asTestVMsDef:
621 raise base.InvalidOption('The "--test-vms" value "%s" is not valid; valid values are: %s' \
622 % (s, ' '.join(self.asTestVMsDef)));
623 elif asArgs[iArg] == '--skip-vms':
624 iArg += 1;
625 if iArg >= len(asArgs): raise base.InvalidOption('The "--skip-vms" takes colon separated list');
626 self.asSkipVMs = asArgs[iArg].split(':');
627 for s in self.asSkipVMs:
628 if s not in self.asTestVMsDef:
629 reporter.log('warning: The "--test-vms" value "%s" does not specify any of our test VMs.' % (s));
630 elif asArgs[iArg] == '--test-host':
631 self.fTestHost = True;
632 elif asArgs[iArg] == '--use-scratch':
633 self.fUseScratch = True;
634 elif asArgs[iArg] == '--always-wipe-storage-cfg':
635 self.fRecreateStorCfg = True;
636 elif asArgs[iArg] == '--dont-wipe-storage-cfg':
637 self.fRecreateStorCfg = False;
638 elif asArgs[iArg] == '--report-benchmark-results':
639 self.fReportBenchmarkResults = True;
640 elif asArgs[iArg] == '--dont-report-benchmark-results':
641 self.fReportBenchmarkResults = False;
642 elif asArgs[iArg] == '--io-log-path':
643 if iArg >= len(asArgs): raise base.InvalidOption('The "--io-log-path" takes a path argument');
644 self.sIoLogPath = asArgs[iArg];
645 elif asArgs[iArg] == '--enable-io-log':
646 self.fIoLog = True;
647 elif asArgs[iArg] == '--use-ramdisk':
648 self.fUseRamDisk = True;
649 else:
650 return vbox.TestDriver.parseOption(self, asArgs, iArg);
651 return iArg + 1;
652
653 def completeOptions(self):
654 # Remove skipped VMs from the test list.
655 for sVM in self.asSkipVMs:
656 try: self.asTestVMs.remove(sVM);
657 except: pass;
658
659 return vbox.TestDriver.completeOptions(self);
660
661 def getResourceSet(self):
662 # Construct the resource list the first time it's queried.
663 if self.asRsrcs is None:
664 self.asRsrcs = [];
665 if 'tst-storage' in self.asTestVMs:
666 self.asRsrcs.append('5.0/storage/tst-storage.vdi');
667 if 'tst-storage32' in self.asTestVMs:
668 self.asRsrcs.append('5.0/storage/tst-storage32.vdi');
669
670 return self.asRsrcs;
671
672 def actionConfig(self):
673
674 # Make sure vboxapi has been imported so we can use the constants.
675 if not self.importVBoxApi():
676 return False;
677
678 #
679 # Configure the VMs we're going to use.
680 #
681
682 # Linux VMs
683 if 'tst-storage' in self.asTestVMs:
684 oVM = self.createTestVM('tst-storage', 1, '5.0/storage/tst-storage.vdi', sKind = 'ArchLinux_64', fIoApic = True, \
685 eNic0AttachType = vboxcon.NetworkAttachmentType_NAT, \
686 eNic0Type = vboxcon.NetworkAdapterType_Am79C973);
687 if oVM is None:
688 return False;
689
690 if 'tst-storage32' in self.asTestVMs:
691 oVM = self.createTestVM('tst-storage32', 1, '5.0/storage/tst-storage32.vdi', sKind = 'ArchLinux', fIoApic = True, \
692 eNic0AttachType = vboxcon.NetworkAttachmentType_NAT, \
693 eNic0Type = vboxcon.NetworkAdapterType_Am79C973);
694 if oVM is None:
695 return False;
696
697 return True;
698
699 def actionExecute(self):
700 """
701 Execute the testcase.
702 """
703 fRc = self.test1();
704 return fRc;
705
706
707 #
708 # Test execution helpers.
709 #
710
711 def prepareStorage(self, oStorCfg, fRamDisk = False, cbPool = None):
712 """
713 Prepares the host storage for disk images or direct testing on the host.
714 """
715 # Create a basic pool with the default configuration.
716 sMountPoint = None;
717 fRc, sPoolId = oStorCfg.createStoragePool(cbPool = cbPool, fRamDisk = fRamDisk);
718 if fRc:
719 fRc, sMountPoint = oStorCfg.createVolume(sPoolId);
720 if not fRc:
721 sMountPoint = None;
722 oStorCfg.cleanup();
723
724 return sMountPoint;
725
726 def cleanupStorage(self, oStorCfg):
727 """
728 Cleans up any created storage space for a test.
729 """
730 return oStorCfg.cleanup();
731
732 def getGuestDisk(self, oSession, oTxsSession, eStorageController):
733 """
734 Gets the path of the disk in the guest to use for testing.
735 """
736 lstDisks = None;
737
738 # The naming scheme for NVMe is different and we don't have
739 # to query the guest for unformatted disks here because the disk with the OS
740 # is not attached to a NVMe controller.
741 if eStorageController == vboxcon.StorageControllerType_NVMe:
742 lstDisks = [ '/dev/nvme0n1' ];
743 else:
744 # Find a unformatted disk (no partition).
745 # @todo: This is a hack because LIST and STAT are not yet implemented
746 # in TXS (get to this eventually)
747 lstBlkDev = [ '/dev/sda', '/dev/sdb' ];
748 for sBlkDev in lstBlkDev:
749 fRc = oTxsSession.syncExec('/usr/bin/ls', ('ls', sBlkDev + '1'));
750 if not fRc:
751 lstDisks = [ sBlkDev ];
752 break;
753
754 _ = oSession;
755 return lstDisks;
756
757 def getDiskFormatVariantsForTesting(self, sDiskFmt, asVariants):
758 """
759 Returns a list of disk variants for testing supported by the given
760 disk format and selected for testing.
761 """
762 lstDskFmts = self.oVBoxMgr.getArray(self.oVBox.systemProperties, 'mediumFormats');
763 for oDskFmt in lstDskFmts:
764 if oDskFmt.id == sDiskFmt:
765 lstDskVariants = [];
766 lstCaps = self.oVBoxMgr.getArray(oDskFmt, 'capabilities');
767
768 if vboxcon.MediumFormatCapabilities_CreateDynamic in lstCaps \
769 and 'Dynamic' in asVariants:
770 lstDskVariants.append('Dynamic');
771
772 if vboxcon.MediumFormatCapabilities_CreateFixed in lstCaps \
773 and 'Fixed' in asVariants:
774 lstDskVariants.append('Fixed');
775
776 if vboxcon.MediumFormatCapabilities_CreateSplit2G in lstCaps \
777 and vboxcon.MediumFormatCapabilities_CreateDynamic in lstCaps \
778 and 'DynamicSplit2G' in asVariants:
779 lstDskVariants.append('DynamicSplit2G');
780
781 if vboxcon.MediumFormatCapabilities_CreateSplit2G in lstCaps \
782 and vboxcon.MediumFormatCapabilities_CreateFixed in lstCaps \
783 and 'FixedSplit2G' in asVariants:
784 lstDskVariants.append('FixedSplit2G');
785
786 if vboxcon.MediumFormatCapabilities_TcpNetworking in lstCaps \
787 and 'Network' in asVariants:
788 lstDskVariants.append('Network'); # Solely for iSCSI to get a non empty list
789
790 return lstDskVariants;
791
792 return [];
793
794 def convDiskToMediumVariant(self, sDiskVariant):
795 """
796 Returns a tuple of medium variant flags matching the given disk variant.
797 """
798 tMediumVariant = None;
799 if sDiskVariant == 'Dynamic':
800 tMediumVariant = (vboxcon.MediumVariant_Standard, );
801 elif sDiskVariant == 'Fixed':
802 tMediumVariant = (vboxcon.MediumVariant_Fixed, );
803 elif sDiskVariant == 'DynamicSplit2G':
804 tMediumVariant = (vboxcon.MediumVariant_Standard, vboxcon.MediumVariant_VmdkSplit2G);
805 elif sDiskVariant == 'FixedSplit2G':
806 tMediumVariant = (vboxcon.MediumVariant_Fixed, vboxcon.MediumVariant_VmdkSplit2G);
807
808 return tMediumVariant;
809
810 def getStorageCtrlFromName(self, sStorageCtrl):
811 """
812 Resolves the storage controller string to the matching constant.
813 """
814 eStorageCtrl = None;
815
816 if sStorageCtrl == 'AHCI':
817 eStorageCtrl = vboxcon.StorageControllerType_IntelAhci;
818 elif sStorageCtrl == 'IDE':
819 eStorageCtrl = vboxcon.StorageControllerType_PIIX4;
820 elif sStorageCtrl == 'LsiLogicSAS':
821 eStorageCtrl = vboxcon.StorageControllerType_LsiLogicSas;
822 elif sStorageCtrl == 'LsiLogic':
823 eStorageCtrl = vboxcon.StorageControllerType_LsiLogic;
824 elif sStorageCtrl == 'BusLogic':
825 eStorageCtrl = vboxcon.StorageControllerType_BusLogic;
826 elif sStorageCtrl == 'NVMe':
827 eStorageCtrl = vboxcon.StorageControllerType_NVMe;
828
829 return eStorageCtrl;
830
831 def getStorageDriverFromEnum(self, eStorageCtrl, fHardDisk):
832 """
833 Returns the appropriate driver name for the given storage controller
834 and a flag whether the driver has the generic SCSI driver attached.
835 """
836 if eStorageCtrl == vboxcon.StorageControllerType_IntelAhci:
837 if fHardDisk:
838 return ('ahci', False);
839 return ('ahci', True);
840 if eStorageCtrl == vboxcon.StorageControllerType_PIIX4:
841 return ('piix3ide', False);
842 if eStorageCtrl == vboxcon.StorageControllerType_LsiLogicSas:
843 return ('lsilogicsas', True);
844 if eStorageCtrl == vboxcon.StorageControllerType_LsiLogic:
845 return ('lsilogicscsi', True);
846 if eStorageCtrl == vboxcon.StorageControllerType_BusLogic:
847 return ('buslogic', True);
848 if eStorageCtrl == vboxcon.StorageControllerType_NVMe:
849 return ('nvme', False);
850
851 return ('<invalid>', False);
852
853 def isTestCfgSupported(self, asTestCfg):
854 """
855 Returns whether a specific test config is supported.
856 """
857
858 # Check whether the disk variant is supported by the selected format.
859 asVariants = self.getDiskFormatVariantsForTesting(asTestCfg[self.kiDiskFmt], [ asTestCfg[self.kiDiskVar] ]);
860 if not asVariants:
861 return False;
862
863 # For iSCSI check whether we have targets configured.
864 if asTestCfg[self.kiDiskFmt] == 'iSCSI' and not self.asIscsiTargets:
865 return False;
866
867 # Check for virt mode, CPU count and selected VM.
868 if asTestCfg[self.kiVirtMode] == 'raw' \
869 and (asTestCfg[self.kiCpuCount] > 1 or asTestCfg[self.kiVmName] == 'tst-storage'):
870 return False;
871
872 # IDE does not support the no host I/O cache setting
873 if asTestCfg[self.kiHostIoCache] == 'no-hostiocache' \
874 and asTestCfg[self.kiStorageCtrl] == 'IDE':
875 return False;
876
877 return True;
878
879 def fnFormatCpuString(self, cCpus):
880 """
881 Formats the CPU count to be readable.
882 """
883 if cCpus == 1:
884 return '1 cpu';
885 return '%u cpus' % (cCpus);
886
887 def fnFormatVirtMode(self, sVirtMode):
888 """
889 Formats the virtualization mode to be a little less cryptic for use in test
890 descriptions.
891 """
892 return self.kdVirtModeDescs[sVirtMode];
893
894 def fnFormatHostIoCache(self, sHostIoCache):
895 """
896 Formats the host I/O cache mode to be a little less cryptic for use in test
897 descriptions.
898 """
899 return self.kdHostIoCacheDescs[sHostIoCache];
900
901 def testBenchmark(self, sTargetOs, sBenchmark, sMountpoint, oExecutor, dTestSet, \
902 cMsTimeout = 3600000):
903 """
904 Runs the given benchmark on the test host.
905 """
906
907 dTestSet['FilePath'] = sMountpoint;
908 dTestSet['TargetOs'] = sTargetOs;
909
910 oTst = None;
911 if sBenchmark == 'iozone':
912 oTst = IozoneTest(oExecutor, dTestSet);
913 elif sBenchmark == 'fio':
914 oTst = FioTest(oExecutor, dTestSet); # pylint: disable=R0204
915
916 if oTst is not None:
917 fRc = oTst.prepare();
918 if fRc:
919 fRc = oTst.run(cMsTimeout);
920 if fRc:
921 if self.fReportBenchmarkResults:
922 fRc = oTst.reportResult();
923 else:
924 reporter.testFailure('Running the testcase failed');
925 reporter.addLogString(oTst.getErrorReport(), sBenchmark + '.log',
926 'log/release/client', 'Benchmark raw output');
927 else:
928 reporter.testFailure('Preparing the testcase failed');
929
930 oTst.cleanup();
931
932 return fRc;
933
934 def createHd(self, oSession, sDiskFormat, sDiskVariant, iDiffLvl, oHdParent, \
935 sDiskPath, cbDisk):
936 """
937 Creates a new disk with the given parameters returning the medium object
938 on success.
939 """
940
941 oHd = None;
942 if sDiskFormat == "iSCSI" and iDiffLvl == 0:
943 listNames = [];
944 listValues = [];
945 listValues = self.asIscsiTargets[0].split('|');
946 listNames.append('TargetAddress');
947 listNames.append('TargetName');
948 listNames.append('LUN');
949
950 if self.fpApiVer >= 5.0:
951 oHd = oSession.oVBox.createMedium(sDiskFormat, sDiskPath, vboxcon.AccessMode_ReadWrite, \
952 vboxcon.DeviceType_HardDisk);
953 else:
954 oHd = oSession.oVBox.createHardDisk(sDiskFormat, sDiskPath);
955 oHd.type = vboxcon.MediumType_Normal;
956 oHd.setProperties(listNames, listValues);
957 else:
958 if iDiffLvl == 0:
959 tMediumVariant = self.convDiskToMediumVariant(sDiskVariant);
960 oHd = oSession.createBaseHd(sDiskPath + '/base.disk', sDiskFormat, cbDisk, \
961 cMsTimeout = 3600 * 1000, tMediumVariant = tMediumVariant);
962 else:
963 sDiskPath = sDiskPath + '/diff_%u.disk' % (iDiffLvl);
964 oHd = oSession.createDiffHd(oHdParent, sDiskPath, None);
965
966 return oHd;
967
968 def testOneCfg(self, sVmName, eStorageController, sHostIoCache, sDiskFormat, # pylint: disable=R0913,R0914,R0915
969 sDiskVariant, sDiskPath, cCpus, sIoTest, sVirtMode, sTestSet):
970 """
971 Runs the specified VM thru test #1.
972
973 Returns a success indicator on the general test execution. This is not
974 the actual test result.
975 """
976 oVM = self.getVmByName(sVmName);
977
978 dTestSet = self.kdTestSets.get(sTestSet);
979 cbDisk = dTestSet.get('DiskSizeGb') * 1024*1024*1024;
980 fHwVirt = sVirtMode != 'raw';
981 fNestedPaging = sVirtMode == 'hwvirt-np';
982
983 fRc = True;
984 if sDiskFormat == 'iSCSI':
985 sDiskPath = self.asIscsiTargets[0];
986 elif self.fUseScratch:
987 sDiskPath = self.sScratchPath;
988 else:
989 # If requested recreate the storage space to start with a clean config
990 # for benchmarks
991 if self.fRecreateStorCfg:
992 sMountPoint = self.prepareStorage(self.oStorCfg, self.fUseRamDisk, cbDisk);
993 if sMountPoint is not None:
994 # Create a directory where every normal user can write to.
995 self.oStorCfg.mkDirOnVolume(sMountPoint, 'test', 0777);
996 sDiskPath = sMountPoint + '/test';
997 else:
998 fRc = False;
999 reporter.testFailure('Failed to prepare storage for VM');
1000
1001 if not fRc:
1002 return fRc;
1003
1004 lstDisks = []; # List of disks we have to delete afterwards.
1005
1006 for iDiffLvl in range(self.cDiffLvls + 1):
1007 sIoLogFile = None;
1008
1009 if iDiffLvl == 0:
1010 reporter.testStart('Base');
1011 else:
1012 reporter.testStart('Diff %u' % (iDiffLvl));
1013
1014 # Reconfigure the VM
1015 oSession = self.openSession(oVM);
1016 if oSession is not None:
1017 # Attach HD
1018 fRc = oSession.ensureControllerAttached(_ControllerTypeToName(eStorageController));
1019 fRc = fRc and oSession.setStorageControllerType(eStorageController, _ControllerTypeToName(eStorageController));
1020
1021 if sHostIoCache == 'hostiocache':
1022 fRc = fRc and oSession.setStorageControllerHostIoCache(_ControllerTypeToName(eStorageController), True);
1023 elif sHostIoCache == 'no-hostiocache':
1024 fRc = fRc and oSession.setStorageControllerHostIoCache(_ControllerTypeToName(eStorageController), False);
1025
1026 iDevice = 0;
1027 if eStorageController == vboxcon.StorageControllerType_PIIX3 or \
1028 eStorageController == vboxcon.StorageControllerType_PIIX4:
1029 iDevice = 1; # Master is for the OS.
1030
1031 oHdParent = None;
1032 if iDiffLvl > 0:
1033 oHdParent = lstDisks[0];
1034 oHd = self.createHd(oSession, sDiskFormat, sDiskVariant, iDiffLvl, oHdParent, sDiskPath, cbDisk);
1035 if oHd is not None:
1036 lstDisks.insert(0, oHd);
1037 try:
1038 if oSession.fpApiVer >= 4.0:
1039 oSession.o.machine.attachDevice(_ControllerTypeToName(eStorageController), \
1040 0, iDevice, vboxcon.DeviceType_HardDisk, oHd);
1041 else:
1042 oSession.o.machine.attachDevice(_ControllerTypeToName(eStorageController), \
1043 0, iDevice, vboxcon.DeviceType_HardDisk, oHd.id);
1044 except:
1045 reporter.errorXcpt('attachDevice("%s",%s,%s,HardDisk,"%s") failed on "%s"' \
1046 % (_ControllerTypeToName(eStorageController), 1, 0, oHd.id, oSession.sName) );
1047 fRc = False;
1048 else:
1049 reporter.log('attached "%s" to %s' % (sDiskPath, oSession.sName));
1050 else:
1051 fRc = False;
1052
1053 # Set up the I/O logging config if enabled
1054 if fRc and self.fIoLog:
1055 try:
1056 oSession.o.machine.setExtraData('VBoxInternal2/EnableDiskIntegrityDriver', '1');
1057
1058 iLun = 0;
1059 if eStorageController == vboxcon.StorageControllerType_PIIX3 or \
1060 eStorageController == vboxcon.StorageControllerType_PIIX4:
1061 iLun = 1
1062 sDrv, fDrvScsi = self.getStorageDriverFromEnum(eStorageController, True);
1063 if fDrvScsi:
1064 sCfgmPath = 'VBoxInternal/Devices/%s/0/LUN#%u/AttachedDriver/Config' % (sDrv, iLun);
1065 else:
1066 sCfgmPath = 'VBoxInternal/Devices/%s/0/LUN#%u/Config' % (sDrv, iLun);
1067
1068 sIoLogFile = '%s/%s.iolog' % (self.sIoLogPath, sDrv);
1069 print sCfgmPath;
1070 print sIoLogFile;
1071 oSession.o.machine.setExtraData('%s/IoLog' % (sCfgmPath,), sIoLogFile);
1072 except:
1073 reporter.logXcpt();
1074
1075 fRc = fRc and oSession.enableVirtEx(fHwVirt);
1076 fRc = fRc and oSession.enableNestedPaging(fNestedPaging);
1077 fRc = fRc and oSession.setCpuCount(cCpus);
1078 fRc = fRc and oSession.saveSettings();
1079 fRc = oSession.close() and fRc and True; # pychecker hack.
1080 oSession = None;
1081 else:
1082 fRc = False;
1083
1084 # Start up.
1085 if fRc is True:
1086 self.logVmInfo(oVM);
1087 oSession, oTxsSession = self.startVmAndConnectToTxsViaTcp(sVmName, fCdWait = False, fNatForwardingForTxs = True);
1088 if oSession is not None:
1089 self.addTask(oSession);
1090
1091 # Fudge factor - Allow the guest to finish starting up.
1092 self.sleep(5);
1093
1094 # Prepare the storage on the guest
1095 lstBinaryPaths = ['/bin', '/sbin', '/usr/bin', '/usr/sbin' ];
1096 oExecVm = remoteexecutor.RemoteExecutor(oTxsSession, lstBinaryPaths, '${SCRATCH}');
1097 oStorCfgVm = storagecfg.StorageCfg(oExecVm, 'linux', self.getGuestDisk(oSession, oTxsSession, \
1098 eStorageController));
1099
1100 sMountPoint = self.prepareStorage(oStorCfgVm);
1101 if sMountPoint is not None:
1102 self.testBenchmark('linux', sIoTest, sMountPoint, oExecVm, dTestSet, \
1103 cMsTimeout = 3 * 3600 * 1000); # 3 hours max (Benchmark and QED takes a lot of time)
1104 self.cleanupStorage(oStorCfgVm);
1105 else:
1106 reporter.testFailure('Failed to prepare storage for the guest benchmark');
1107
1108 # cleanup.
1109 self.removeTask(oTxsSession);
1110 self.terminateVmBySession(oSession);
1111
1112 # Add the I/O log if it exists and the test failed
1113 if reporter.testErrorCount() > 0 \
1114 and sIoLogFile is not None \
1115 and os.path.exists(sIoLogFile):
1116 reporter.addLogFile(sIoLogFile, 'misc/other', 'I/O log');
1117 os.remove(sIoLogFile);
1118
1119 else:
1120 fRc = False;
1121
1122 # Remove disk
1123 oSession = self.openSession(oVM);
1124 if oSession is not None:
1125 try:
1126 oSession.o.machine.detachDevice(_ControllerTypeToName(eStorageController), 0, iDevice);
1127
1128 # Remove storage controller if it is not an IDE controller.
1129 if eStorageController is not vboxcon.StorageControllerType_PIIX3 \
1130 and eStorageController is not vboxcon.StorageControllerType_PIIX4:
1131 oSession.o.machine.removeStorageController(_ControllerTypeToName(eStorageController));
1132
1133 oSession.saveSettings();
1134 oSession.saveSettings();
1135 oSession.close();
1136 oSession = None;
1137 except:
1138 reporter.errorXcpt('failed to detach/delete disk %s from storage controller' % (sDiskPath));
1139 else:
1140 fRc = False;
1141
1142 reporter.testDone();
1143
1144 # Delete all disks
1145 for oHd in lstDisks:
1146 self.oVBox.deleteHdByMedium(oHd);
1147
1148 # Cleanup storage area
1149 if sDiskFormat != 'iSCSI' and not self.fUseScratch and self.fRecreateStorCfg:
1150 self.cleanupStorage(self.oStorCfg);
1151
1152 return fRc;
1153
1154 def testStorage(self, sDiskPath = None):
1155 """
1156 Runs the storage testcase through the selected configurations
1157 """
1158
1159 aasTestCfgs = [];
1160 aasTestCfgs.insert(self.kiVmName, self.asTestVMs);
1161 aasTestCfgs.insert(self.kiStorageCtrl, self.asStorageCtrls);
1162 aasTestCfgs.insert(self.kiHostIoCache, (self.asHostIoCache, self.fnFormatHostIoCache));
1163 aasTestCfgs.insert(self.kiDiskFmt, self.asDiskFormats);
1164 aasTestCfgs.insert(self.kiDiskVar, self.asDiskVariants);
1165 aasTestCfgs.insert(self.kiCpuCount, (self.acCpus, self.fnFormatCpuString));
1166 aasTestCfgs.insert(self.kiVirtMode, (self.asVirtModes, self.fnFormatVirtMode));
1167 aasTestCfgs.insert(self.kiIoTest, self.asTests);
1168 aasTestCfgs.insert(self.kiTestSet, self.asTestSets);
1169
1170 aasTestsBlacklist = [];
1171 aasTestsBlacklist.append(['tst-storage', 'BusLogic']); # 64bit Linux is broken with BusLogic
1172
1173 oTstCfgMgr = StorTestCfgMgr(aasTestCfgs, aasTestsBlacklist, self.isTestCfgSupported);
1174
1175 fRc = True;
1176 asTestCfg = oTstCfgMgr.getCurrentTestCfg();
1177 while asTestCfg:
1178 fRc = self.testOneCfg(asTestCfg[self.kiVmName], self.getStorageCtrlFromName(asTestCfg[self.kiStorageCtrl]), \
1179 asTestCfg[self.kiHostIoCache], asTestCfg[self.kiDiskFmt], asTestCfg[self.kiDiskVar],
1180 sDiskPath, asTestCfg[self.kiCpuCount], asTestCfg[self.kiIoTest], \
1181 asTestCfg[self.kiVirtMode], asTestCfg[self.kiTestSet]) and fRc and True; # pychecker hack.
1182
1183 asTestCfg = oTstCfgMgr.getNextTestCfg();
1184
1185 return fRc;
1186
1187 def test1(self):
1188 """
1189 Executes test #1.
1190 """
1191
1192 fRc = True;
1193 oDiskCfg = self.kdStorageCfgs.get(socket.gethostname().lower());
1194
1195 # Test the host first if requested
1196 if oDiskCfg is not None or self.fUseScratch:
1197 lstBinaryPaths = ['/bin', '/sbin', '/usr/bin', '/usr/sbin', \
1198 '/opt/csw/bin', '/usr/ccs/bin', '/usr/sfw/bin'];
1199 oExecutor = remoteexecutor.RemoteExecutor(None, lstBinaryPaths, self.sScratchPath);
1200 if not self.fUseScratch:
1201 self.oStorCfg = storagecfg.StorageCfg(oExecutor, utils.getHostOs(), oDiskCfg);
1202
1203 # Try to cleanup any leftovers from a previous run first.
1204 fRc = self.oStorCfg.cleanupLeftovers();
1205 if not fRc:
1206 reporter.error('Failed to cleanup any leftovers from a previous run');
1207
1208 if self.fTestHost:
1209 reporter.testStart('Host');
1210 if self.fUseScratch:
1211 sMountPoint = self.sScratchPath;
1212 else:
1213 sMountPoint = self.prepareStorage(self.oStorCfg);
1214 if sMountPoint is not None:
1215 for sIoTest in self.asTests:
1216 reporter.testStart(sIoTest);
1217 for sTestSet in self.asTestSets:
1218 reporter.testStart(sTestSet);
1219 dTestSet = self.kdTestSets.get(sTestSet);
1220 self.testBenchmark(utils.getHostOs(), sIoTest, sMountPoint, oExecutor, dTestSet);
1221 reporter.testDone();
1222 reporter.testDone();
1223 self.cleanupStorage(self.oStorCfg);
1224 else:
1225 reporter.testFailure('Failed to prepare host storage');
1226 fRc = False;
1227 reporter.testDone();
1228 else:
1229 # Create the storage space first if it is not done before every test.
1230 sMountPoint = None;
1231 if self.fUseScratch:
1232 sMountPoint = self.sScratchPath;
1233 elif not self.fRecreateStorCfg:
1234 reporter.testStart('Create host storage');
1235 sMountPoint = self.prepareStorage(self.oStorCfg);
1236 if sMountPoint is None:
1237 reporter.testFailure('Failed to prepare host storage');
1238 fRc = False;
1239 self.oStorCfg.mkDirOnVolume(sMountPoint, 'test', 0777);
1240 sMountPoint = sMountPoint + '/test';
1241 reporter.testDone();
1242
1243 if fRc:
1244 # Run the storage tests.
1245 if not self.testStorage(sMountPoint):
1246 fRc = False;
1247
1248 if not self.fRecreateStorCfg and not self.fUseScratch:
1249 self.cleanupStorage(self.oStorCfg);
1250 else:
1251 fRc = False;
1252
1253 return fRc;
1254
1255if __name__ == '__main__':
1256 sys.exit(tdStorageBenchmark().main(sys.argv));
1257
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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