VirtualBox

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

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

ValidationKit/tests: pylint 2.0.0 fixes.

  • 屬性 svn:eol-style 設為 LF
  • 屬性 svn:executable 設為 *
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 51.3 KB
 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3# $Id: tdStorageBenchmark1.py 65963 2017-03-07 10:30:26Z vboxsync $
4
5"""
6VirtualBox Validation Kit - Storage benchmark.
7"""
8
9__copyright__ = \
10"""
11Copyright (C) 2012-2016 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: 65963 $"
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': 100
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
503 #
504 # Overridden methods.
505 #
506 def showUsage(self):
507 rc = vbox.TestDriver.showUsage(self);
508 reporter.log('');
509 reporter.log('tdStorageBenchmark1 Options:');
510 reporter.log(' --virt-modes <m1[:m2[:]]');
511 reporter.log(' Default: %s' % (':'.join(self.asVirtModesDef)));
512 reporter.log(' --cpu-counts <c1[:c2[:]]');
513 reporter.log(' Default: %s' % (':'.join(str(c) for c in self.acCpusDef)));
514 reporter.log(' --storage-ctrls <type1[:type2[:...]]>');
515 reporter.log(' Default: %s' % (':'.join(self.asStorageCtrlsDef)));
516 reporter.log(' --host-io-cache <setting1[:setting2[:...]]>');
517 reporter.log(' Default: %s' % (':'.join(self.asHostIoCacheDef)));
518 reporter.log(' --disk-formats <type1[:type2[:...]]>');
519 reporter.log(' Default: %s' % (':'.join(self.asDiskFormatsDef)));
520 reporter.log(' --disk-variants <variant1[:variant2[:...]]>');
521 reporter.log(' Default: %s' % (':'.join(self.asDiskVariantsDef)));
522 reporter.log(' --iscsi-targets <target1[:target2[:...]]>');
523 reporter.log(' Default: %s' % (':'.join(self.asIscsiTargetsDef)));
524 reporter.log(' --tests <test1[:test2[:...]]>');
525 reporter.log(' Default: %s' % (':'.join(self.asTestsDef)));
526 reporter.log(' --test-sets <set1[:set2[:...]]>');
527 reporter.log(' Default: %s' % (':'.join(self.asTestSetsDef)));
528 reporter.log(' --diff-levels <number of diffs>');
529 reporter.log(' Default: %s' % (self.cDiffLvlsDef));
530 reporter.log(' --test-vms <vm1[:vm2[:...]]>');
531 reporter.log(' Test the specified VMs in the given order. Use this to change');
532 reporter.log(' the execution order or limit the choice of VMs');
533 reporter.log(' Default: %s (all)' % (':'.join(self.asTestVMsDef)));
534 reporter.log(' --skip-vms <vm1[:vm2[:...]]>');
535 reporter.log(' Skip the specified VMs when testing.');
536 reporter.log(' --test-host');
537 reporter.log(' Do all configured tests on the host first and report the results');
538 reporter.log(' to get a baseline');
539 reporter.log(' --use-scratch');
540 reporter.log(' Use the scratch directory for testing instead of setting up');
541 reporter.log(' fresh volumes on dedicated disks (for development)');
542 reporter.log(' --always-wipe-storage-cfg');
543 reporter.log(' Recreate the host storage config before each test');
544 reporter.log(' --dont-wipe-storage-cfg');
545 reporter.log(' Don\'t recreate the host storage config before each test');
546 reporter.log(' --report-benchmark-results');
547 reporter.log(' Report all benchmark results');
548 reporter.log(' --dont-report-benchmark-results');
549 reporter.log(' Don\'t report any benchmark results');
550 reporter.log(' --io-log-path <path>');
551 reporter.log(' Default: %s' % (self.sIoLogPathDef));
552 reporter.log(' --enable-io-log');
553 reporter.log(' Whether to enable I/O logging for each test');
554 return rc;
555
556 def parseOption(self, asArgs, iArg): # pylint: disable=R0912,R0915
557 if asArgs[iArg] == '--virt-modes':
558 iArg += 1;
559 if iArg >= len(asArgs): raise base.InvalidOption('The "--virt-modes" takes a colon separated list of modes');
560 self.asVirtModes = asArgs[iArg].split(':');
561 for s in self.asVirtModes:
562 if s not in self.asVirtModesDef:
563 raise base.InvalidOption('The "--virt-modes" value "%s" is not valid; valid values are: %s' \
564 % (s, ' '.join(self.asVirtModesDef)));
565 elif asArgs[iArg] == '--cpu-counts':
566 iArg += 1;
567 if iArg >= len(asArgs): raise base.InvalidOption('The "--cpu-counts" takes a colon separated list of cpu counts');
568 self.acCpus = [];
569 for s in asArgs[iArg].split(':'):
570 try: c = int(s);
571 except: raise base.InvalidOption('The "--cpu-counts" value "%s" is not an integer' % (s,));
572 if c <= 0: raise base.InvalidOption('The "--cpu-counts" value "%s" is zero or negative' % (s,));
573 self.acCpus.append(c);
574 elif asArgs[iArg] == '--storage-ctrls':
575 iArg += 1;
576 if iArg >= len(asArgs):
577 raise base.InvalidOption('The "--storage-ctrls" takes a colon separated list of Storage controller types');
578 self.asStorageCtrls = asArgs[iArg].split(':');
579 elif asArgs[iArg] == '--host-io-cache':
580 iArg += 1;
581 if iArg >= len(asArgs):
582 raise base.InvalidOption('The "--host-io-cache" takes a colon separated list of I/O cache settings');
583 self.asHostIoCache = asArgs[iArg].split(':');
584 elif asArgs[iArg] == '--disk-formats':
585 iArg += 1;
586 if iArg >= len(asArgs): raise base.InvalidOption('The "--disk-formats" takes a colon separated list of disk formats');
587 self.asDiskFormats = asArgs[iArg].split(':');
588 elif asArgs[iArg] == '--disk-variants':
589 iArg += 1;
590 if iArg >= len(asArgs):
591 raise base.InvalidOption('The "--disk-variants" takes a colon separated list of disk variants');
592 self.asDiskVariants = asArgs[iArg].split(':');
593 elif asArgs[iArg] == '--iscsi-targets':
594 iArg += 1;
595 if iArg >= len(asArgs):
596 raise base.InvalidOption('The "--iscsi-targets" takes a colon separated list of iscsi targets');
597 self.asIscsiTargets = asArgs[iArg].split(':');
598 elif asArgs[iArg] == '--tests':
599 iArg += 1;
600 if iArg >= len(asArgs): raise base.InvalidOption('The "--tests" takes a colon separated list of tests to run');
601 self.asTests = asArgs[iArg].split(':');
602 elif asArgs[iArg] == '--test-sets':
603 iArg += 1;
604 if iArg >= len(asArgs): raise base.InvalidOption('The "--test-sets" takes a colon separated list of test sets');
605 self.asTestSets = asArgs[iArg].split(':');
606 elif asArgs[iArg] == '--diff-levels':
607 iArg += 1;
608 if iArg >= len(asArgs): raise base.InvalidOption('The "--diff-levels" takes an integer');
609 try: self.cDiffLvls = int(asArgs[iArg]);
610 except: raise base.InvalidOption('The "--diff-levels" value "%s" is not an integer' % (asArgs[iArg],));
611 elif asArgs[iArg] == '--test-vms':
612 iArg += 1;
613 if iArg >= len(asArgs): raise base.InvalidOption('The "--test-vms" takes colon separated list');
614 self.asTestVMs = asArgs[iArg].split(':');
615 for s in self.asTestVMs:
616 if s not in self.asTestVMsDef:
617 raise base.InvalidOption('The "--test-vms" value "%s" is not valid; valid values are: %s' \
618 % (s, ' '.join(self.asTestVMsDef)));
619 elif asArgs[iArg] == '--skip-vms':
620 iArg += 1;
621 if iArg >= len(asArgs): raise base.InvalidOption('The "--skip-vms" takes colon separated list');
622 self.asSkipVMs = asArgs[iArg].split(':');
623 for s in self.asSkipVMs:
624 if s not in self.asTestVMsDef:
625 reporter.log('warning: The "--test-vms" value "%s" does not specify any of our test VMs.' % (s));
626 elif asArgs[iArg] == '--test-host':
627 self.fTestHost = True;
628 elif asArgs[iArg] == '--use-scratch':
629 self.fUseScratch = True;
630 elif asArgs[iArg] == '--always-wipe-storage-cfg':
631 self.fRecreateStorCfg = True;
632 elif asArgs[iArg] == '--dont-wipe-storage-cfg':
633 self.fRecreateStorCfg = False;
634 elif asArgs[iArg] == '--report-benchmark-results':
635 self.fReportBenchmarkResults = True;
636 elif asArgs[iArg] == '--dont-report-benchmark-results':
637 self.fReportBenchmarkResults = False;
638 elif asArgs[iArg] == '--io-log-path':
639 if iArg >= len(asArgs): raise base.InvalidOption('The "--io-log-path" takes a path argument');
640 self.sIoLogPath = asArgs[iArg];
641 elif asArgs[iArg] == '--enable-io-log':
642 self.fIoLog = True;
643 else:
644 return vbox.TestDriver.parseOption(self, asArgs, iArg);
645 return iArg + 1;
646
647 def completeOptions(self):
648 # Remove skipped VMs from the test list.
649 for sVM in self.asSkipVMs:
650 try: self.asTestVMs.remove(sVM);
651 except: pass;
652
653 return vbox.TestDriver.completeOptions(self);
654
655 def getResourceSet(self):
656 # Construct the resource list the first time it's queried.
657 if self.asRsrcs is None:
658 self.asRsrcs = [];
659 if 'tst-storage' in self.asTestVMs:
660 self.asRsrcs.append('5.0/storage/tst-storage.vdi');
661 if 'tst-storage32' in self.asTestVMs:
662 self.asRsrcs.append('5.0/storage/tst-storage32.vdi');
663
664 return self.asRsrcs;
665
666 def actionConfig(self):
667
668 # Make sure vboxapi has been imported so we can use the constants.
669 if not self.importVBoxApi():
670 return False;
671
672 #
673 # Configure the VMs we're going to use.
674 #
675
676 # Linux VMs
677 if 'tst-storage' in self.asTestVMs:
678 oVM = self.createTestVM('tst-storage', 1, '5.0/storage/tst-storage.vdi', sKind = 'ArchLinux_64', fIoApic = True, \
679 eNic0AttachType = vboxcon.NetworkAttachmentType_NAT, \
680 eNic0Type = vboxcon.NetworkAdapterType_Am79C973);
681 if oVM is None:
682 return False;
683
684 if 'tst-storage32' in self.asTestVMs:
685 oVM = self.createTestVM('tst-storage32', 1, '5.0/storage/tst-storage32.vdi', sKind = 'ArchLinux', fIoApic = True, \
686 eNic0AttachType = vboxcon.NetworkAttachmentType_NAT, \
687 eNic0Type = vboxcon.NetworkAdapterType_Am79C973);
688 if oVM is None:
689 return False;
690
691 return True;
692
693 def actionExecute(self):
694 """
695 Execute the testcase.
696 """
697 fRc = self.test1();
698 return fRc;
699
700
701 #
702 # Test execution helpers.
703 #
704
705 def prepareStorage(self, oStorCfg):
706 """
707 Prepares the host storage for disk images or direct testing on the host.
708 """
709 # Create a basic pool with the default configuration.
710 sMountPoint = None;
711 fRc, sPoolId = oStorCfg.createStoragePool();
712 if fRc:
713 fRc, sMountPoint = oStorCfg.createVolume(sPoolId);
714 if not fRc:
715 sMountPoint = None;
716 oStorCfg.cleanup();
717
718 return sMountPoint;
719
720 def cleanupStorage(self, oStorCfg):
721 """
722 Cleans up any created storage space for a test.
723 """
724 return oStorCfg.cleanup();
725
726 def getGuestDisk(self, oSession, oTxsSession, eStorageController):
727 """
728 Gets the path of the disk in the guest to use for testing.
729 """
730 lstDisks = None;
731
732 # The naming scheme for NVMe is different and we don't have
733 # to query the guest for unformatted disks here because the disk with the OS
734 # is not attached to a NVMe controller.
735 if eStorageController == vboxcon.StorageControllerType_NVMe:
736 lstDisks = [ '/dev/nvme0n1' ];
737 else:
738 # Find a unformatted disk (no partition).
739 # @todo: This is a hack because LIST and STAT are not yet implemented
740 # in TXS (get to this eventually)
741 lstBlkDev = [ '/dev/sda', '/dev/sdb' ];
742 for sBlkDev in lstBlkDev:
743 fRc = oTxsSession.syncExec('/usr/bin/ls', ('ls', sBlkDev + '1'));
744 if not fRc:
745 lstDisks = [ sBlkDev ];
746 break;
747
748 _ = oSession;
749 return lstDisks;
750
751 def getDiskFormatVariantsForTesting(self, sDiskFmt, asVariants):
752 """
753 Returns a list of disk variants for testing supported by the given
754 disk format and selected for testing.
755 """
756 lstDskFmts = self.oVBoxMgr.getArray(self.oVBox.systemProperties, 'mediumFormats');
757 for oDskFmt in lstDskFmts:
758 if oDskFmt.id == sDiskFmt:
759 lstDskVariants = [];
760 lstCaps = self.oVBoxMgr.getArray(oDskFmt, 'capabilities');
761
762 if vboxcon.MediumFormatCapabilities_CreateDynamic in lstCaps \
763 and 'Dynamic' in asVariants:
764 lstDskVariants.append('Dynamic');
765
766 if vboxcon.MediumFormatCapabilities_CreateFixed in lstCaps \
767 and 'Fixed' in asVariants:
768 lstDskVariants.append('Fixed');
769
770 if vboxcon.MediumFormatCapabilities_CreateSplit2G in lstCaps \
771 and vboxcon.MediumFormatCapabilities_CreateDynamic in lstCaps \
772 and 'DynamicSplit2G' in asVariants:
773 lstDskVariants.append('DynamicSplit2G');
774
775 if vboxcon.MediumFormatCapabilities_CreateSplit2G in lstCaps \
776 and vboxcon.MediumFormatCapabilities_CreateFixed in lstCaps \
777 and 'FixedSplit2G' in asVariants:
778 lstDskVariants.append('FixedSplit2G');
779
780 if vboxcon.MediumFormatCapabilities_TcpNetworking in lstCaps \
781 and 'Network' in asVariants:
782 lstDskVariants.append('Network'); # Solely for iSCSI to get a non empty list
783
784 return lstDskVariants;
785
786 return [];
787
788 def convDiskToMediumVariant(self, sDiskVariant):
789 """
790 Returns a tuple of medium variant flags matching the given disk variant.
791 """
792 tMediumVariant = None;
793 if sDiskVariant == 'Dynamic':
794 tMediumVariant = (vboxcon.MediumVariant_Standard, );
795 elif sDiskVariant == 'Fixed':
796 tMediumVariant = (vboxcon.MediumVariant_Fixed, );
797 elif sDiskVariant == 'DynamicSplit2G':
798 tMediumVariant = (vboxcon.MediumVariant_Standard, vboxcon.MediumVariant_VmdkSplit2G);
799 elif sDiskVariant == 'FixedSplit2G':
800 tMediumVariant = (vboxcon.MediumVariant_Fixed, vboxcon.MediumVariant_VmdkSplit2G);
801
802 return tMediumVariant;
803
804 def getStorageCtrlFromName(self, sStorageCtrl):
805 """
806 Resolves the storage controller string to the matching constant.
807 """
808 eStorageCtrl = None;
809
810 if sStorageCtrl == 'AHCI':
811 eStorageCtrl = vboxcon.StorageControllerType_IntelAhci;
812 elif sStorageCtrl == 'IDE':
813 eStorageCtrl = vboxcon.StorageControllerType_PIIX4;
814 elif sStorageCtrl == 'LsiLogicSAS':
815 eStorageCtrl = vboxcon.StorageControllerType_LsiLogicSas;
816 elif sStorageCtrl == 'LsiLogic':
817 eStorageCtrl = vboxcon.StorageControllerType_LsiLogic;
818 elif sStorageCtrl == 'BusLogic':
819 eStorageCtrl = vboxcon.StorageControllerType_BusLogic;
820 elif sStorageCtrl == 'NVMe':
821 eStorageCtrl = vboxcon.StorageControllerType_NVMe;
822
823 return eStorageCtrl;
824
825 def getStorageDriverFromEnum(self, eStorageCtrl, fHardDisk):
826 """
827 Returns the appropriate driver name for the given storage controller
828 and a flag whether the driver has the generic SCSI driver attached.
829 """
830 if eStorageCtrl == vboxcon.StorageControllerType_IntelAhci:
831 if fHardDisk:
832 return ('ahci', False);
833 return ('ahci', True);
834 if eStorageCtrl == vboxcon.StorageControllerType_PIIX4:
835 return ('piix3ide', False);
836 if eStorageCtrl == vboxcon.StorageControllerType_LsiLogicSas:
837 return ('lsilogicsas', True);
838 if eStorageCtrl == vboxcon.StorageControllerType_LsiLogic:
839 return ('lsilogicscsi', True);
840 if eStorageCtrl == vboxcon.StorageControllerType_BusLogic:
841 return ('buslogic', True);
842 if eStorageCtrl == vboxcon.StorageControllerType_NVMe:
843 return ('nvme', False);
844
845 return ('<invalid>', False);
846
847 def isTestCfgSupported(self, asTestCfg):
848 """
849 Returns whether a specific test config is supported.
850 """
851
852 # Check whether the disk variant is supported by the selected format.
853 asVariants = self.getDiskFormatVariantsForTesting(asTestCfg[self.kiDiskFmt], [ asTestCfg[self.kiDiskVar] ]);
854 if not asVariants:
855 return False;
856
857 # For iSCSI check whether we have targets configured.
858 if asTestCfg[self.kiDiskFmt] == 'iSCSI' and not self.asIscsiTargets:
859 return False;
860
861 # Check for virt mode, CPU count and selected VM.
862 if asTestCfg[self.kiVirtMode] == 'raw' \
863 and (asTestCfg[self.kiCpuCount] > 1 or asTestCfg[self.kiVmName] == 'tst-storage'):
864 return False;
865
866 # IDE does not support the no host I/O cache setting
867 if asTestCfg[self.kiHostIoCache] == 'no-hostiocache' \
868 and asTestCfg[self.kiStorageCtrl] == 'IDE':
869 return False;
870
871 return True;
872
873 def fnFormatCpuString(self, cCpus):
874 """
875 Formats the CPU count to be readable.
876 """
877 if cCpus == 1:
878 return '1 cpu';
879 return '%u cpus' % (cCpus);
880
881 def fnFormatVirtMode(self, sVirtMode):
882 """
883 Formats the virtualization mode to be a little less cryptic for use in test
884 descriptions.
885 """
886 return self.kdVirtModeDescs[sVirtMode];
887
888 def fnFormatHostIoCache(self, sHostIoCache):
889 """
890 Formats the host I/O cache mode to be a little less cryptic for use in test
891 descriptions.
892 """
893 return self.kdHostIoCacheDescs[sHostIoCache];
894
895 def testBenchmark(self, sTargetOs, sBenchmark, sMountpoint, oExecutor, dTestSet, \
896 cMsTimeout = 3600000):
897 """
898 Runs the given benchmark on the test host.
899 """
900
901 dTestSet['FilePath'] = sMountpoint;
902 dTestSet['TargetOs'] = sTargetOs;
903
904 oTst = None;
905 if sBenchmark == 'iozone':
906 oTst = IozoneTest(oExecutor, dTestSet);
907 elif sBenchmark == 'fio':
908 oTst = FioTest(oExecutor, dTestSet); # pylint: disable=R0204
909
910 if oTst is not None:
911 fRc = oTst.prepare();
912 if fRc:
913 fRc = oTst.run(cMsTimeout);
914 if fRc:
915 if self.fReportBenchmarkResults:
916 fRc = oTst.reportResult();
917 else:
918 reporter.testFailure('Running the testcase failed');
919 reporter.addLogString(oTst.getErrorReport(), sBenchmark + '.log',
920 'log/release/client', 'Benchmark raw output');
921 else:
922 reporter.testFailure('Preparing the testcase failed');
923
924 oTst.cleanup();
925
926 return fRc;
927
928 def createHd(self, oSession, sDiskFormat, sDiskVariant, iDiffLvl, oHdParent, \
929 sDiskPath, cbDisk):
930 """
931 Creates a new disk with the given parameters returning the medium object
932 on success.
933 """
934
935 oHd = None;
936 if sDiskFormat == "iSCSI" and iDiffLvl == 0:
937 listNames = [];
938 listValues = [];
939 listValues = self.asIscsiTargets[0].split('|');
940 listNames.append('TargetAddress');
941 listNames.append('TargetName');
942 listNames.append('LUN');
943
944 if self.fpApiVer >= 5.0:
945 oHd = oSession.oVBox.createMedium(sDiskFormat, sDiskPath, vboxcon.AccessMode_ReadWrite, \
946 vboxcon.DeviceType_HardDisk);
947 else:
948 oHd = oSession.oVBox.createHardDisk(sDiskFormat, sDiskPath);
949 oHd.type = vboxcon.MediumType_Normal;
950 oHd.setProperties(listNames, listValues);
951 else:
952 if iDiffLvl == 0:
953 tMediumVariant = self.convDiskToMediumVariant(sDiskVariant);
954 oHd = oSession.createBaseHd(sDiskPath + '/base.disk', sDiskFormat, cbDisk, \
955 cMsTimeout = 3600 * 1000, tMediumVariant = tMediumVariant);
956 else:
957 sDiskPath = sDiskPath + '/diff_%u.disk' % (iDiffLvl);
958 oHd = oSession.createDiffHd(oHdParent, sDiskPath, None);
959
960 return oHd;
961
962 def testOneCfg(self, sVmName, eStorageController, sHostIoCache, sDiskFormat, # pylint: disable=R0913,R0914,R0915
963 sDiskVariant, sDiskPath, cCpus, sIoTest, sVirtMode, sTestSet):
964 """
965 Runs the specified VM thru test #1.
966
967 Returns a success indicator on the general test execution. This is not
968 the actual test result.
969 """
970 oVM = self.getVmByName(sVmName);
971
972 dTestSet = self.kdTestSets.get(sTestSet);
973 cbDisk = dTestSet.get('DiskSizeGb') * 1024*1024*1024;
974 fHwVirt = sVirtMode != 'raw';
975 fNestedPaging = sVirtMode == 'hwvirt-np';
976
977 fRc = True;
978 if sDiskFormat == 'iSCSI':
979 sDiskPath = self.asIscsiTargets[0];
980 elif self.fUseScratch:
981 sDiskPath = self.sScratchPath;
982 else:
983 # If requested recreate the storage space to start with a clean config
984 # for benchmarks
985 if self.fRecreateStorCfg:
986 sMountPoint = self.prepareStorage(self.oStorCfg);
987 if sMountPoint is not None:
988 # Create a directory where every normal user can write to.
989 self.oStorCfg.mkDirOnVolume(sMountPoint, 'test', 0777);
990 sDiskPath = sMountPoint + '/test';
991 else:
992 fRc = False;
993 reporter.testFailure('Failed to prepare storage for VM');
994
995 if not fRc:
996 return fRc;
997
998 lstDisks = []; # List of disks we have to delete afterwards.
999
1000 for iDiffLvl in range(self.cDiffLvls + 1):
1001 sIoLogFile = None;
1002
1003 if iDiffLvl == 0:
1004 reporter.testStart('Base');
1005 else:
1006 reporter.testStart('Diff %u' % (iDiffLvl));
1007
1008 # Reconfigure the VM
1009 oSession = self.openSession(oVM);
1010 if oSession is not None:
1011 # Attach HD
1012 fRc = oSession.ensureControllerAttached(_ControllerTypeToName(eStorageController));
1013 fRc = fRc and oSession.setStorageControllerType(eStorageController, _ControllerTypeToName(eStorageController));
1014
1015 if sHostIoCache == 'hostiocache':
1016 fRc = fRc and oSession.setStorageControllerHostIoCache(_ControllerTypeToName(eStorageController), True);
1017 elif sHostIoCache == 'no-hostiocache':
1018 fRc = fRc and oSession.setStorageControllerHostIoCache(_ControllerTypeToName(eStorageController), False);
1019
1020 iDevice = 0;
1021 if eStorageController == vboxcon.StorageControllerType_PIIX3 or \
1022 eStorageController == vboxcon.StorageControllerType_PIIX4:
1023 iDevice = 1; # Master is for the OS.
1024
1025 oHdParent = None;
1026 if iDiffLvl > 0:
1027 oHdParent = lstDisks[0];
1028 oHd = self.createHd(oSession, sDiskFormat, sDiskVariant, iDiffLvl, oHdParent, sDiskPath, cbDisk);
1029 if oHd is not None:
1030 lstDisks.insert(0, oHd);
1031 try:
1032 if oSession.fpApiVer >= 4.0:
1033 oSession.o.machine.attachDevice(_ControllerTypeToName(eStorageController), \
1034 0, iDevice, vboxcon.DeviceType_HardDisk, oHd);
1035 else:
1036 oSession.o.machine.attachDevice(_ControllerTypeToName(eStorageController), \
1037 0, iDevice, vboxcon.DeviceType_HardDisk, oHd.id);
1038 except:
1039 reporter.errorXcpt('attachDevice("%s",%s,%s,HardDisk,"%s") failed on "%s"' \
1040 % (_ControllerTypeToName(eStorageController), 1, 0, oHd.id, oSession.sName) );
1041 fRc = False;
1042 else:
1043 reporter.log('attached "%s" to %s' % (sDiskPath, oSession.sName));
1044 else:
1045 fRc = False;
1046
1047 # Set up the I/O logging config if enabled
1048 if fRc and self.fIoLog:
1049 try:
1050 oSession.o.machine.setExtraData('VBoxInternal2/EnableDiskIntegrityDriver', '1');
1051
1052 iLun = 0;
1053 if eStorageController == vboxcon.StorageControllerType_PIIX3 or \
1054 eStorageController == vboxcon.StorageControllerType_PIIX4:
1055 iLun = 1
1056 sDrv, fDrvScsi = self.getStorageDriverFromEnum(eStorageController, True);
1057 if fDrvScsi:
1058 sCfgmPath = 'VBoxInternal/Devices/%s/0/LUN#%u/AttachedDriver/Config' % (sDrv, iLun);
1059 else:
1060 sCfgmPath = 'VBoxInternal/Devices/%s/0/LUN#%u/Config' % (sDrv, iLun);
1061
1062 sIoLogFile = '%s/%s.iolog' % (self.sIoLogPath, sDrv);
1063 print sCfgmPath;
1064 print sIoLogFile;
1065 oSession.o.machine.setExtraData('%s/IoLog' % (sCfgmPath,), sIoLogFile);
1066 except:
1067 reporter.logXcpt();
1068
1069 fRc = fRc and oSession.enableVirtEx(fHwVirt);
1070 fRc = fRc and oSession.enableNestedPaging(fNestedPaging);
1071 fRc = fRc and oSession.setCpuCount(cCpus);
1072 fRc = fRc and oSession.saveSettings();
1073 fRc = oSession.close() and fRc and True; # pychecker hack.
1074 oSession = None;
1075 else:
1076 fRc = False;
1077
1078 # Start up.
1079 if fRc is True:
1080 self.logVmInfo(oVM);
1081 oSession, oTxsSession = self.startVmAndConnectToTxsViaTcp(sVmName, fCdWait = False, fNatForwardingForTxs = True);
1082 if oSession is not None:
1083 self.addTask(oSession);
1084
1085 # Fudge factor - Allow the guest to finish starting up.
1086 self.sleep(5);
1087
1088 # Prepare the storage on the guest
1089 lstBinaryPaths = ['/bin', '/sbin', '/usr/bin', '/usr/sbin' ];
1090 oExecVm = remoteexecutor.RemoteExecutor(oTxsSession, lstBinaryPaths, '${SCRATCH}');
1091 oStorCfgVm = storagecfg.StorageCfg(oExecVm, 'linux', self.getGuestDisk(oSession, oTxsSession, \
1092 eStorageController));
1093
1094 sMountPoint = self.prepareStorage(oStorCfgVm);
1095 if sMountPoint is not None:
1096 self.testBenchmark('linux', sIoTest, sMountPoint, oExecVm, dTestSet, \
1097 cMsTimeout = 3 * 3600 * 1000); # 3 hours max (Benchmark and QED takes a lot of time)
1098 self.cleanupStorage(oStorCfgVm);
1099 else:
1100 reporter.testFailure('Failed to prepare storage for the guest benchmark');
1101
1102 # cleanup.
1103 self.removeTask(oTxsSession);
1104 self.terminateVmBySession(oSession);
1105
1106 # Add the I/O log if it exists and the test failed
1107 if reporter.testErrorCount() > 0 \
1108 and sIoLogFile is not None \
1109 and os.path.exists(sIoLogFile):
1110 reporter.addLogFile(sIoLogFile, 'misc/other', 'I/O log');
1111 os.remove(sIoLogFile);
1112
1113 else:
1114 fRc = False;
1115
1116 # Remove disk
1117 oSession = self.openSession(oVM);
1118 if oSession is not None:
1119 try:
1120 oSession.o.machine.detachDevice(_ControllerTypeToName(eStorageController), 0, iDevice);
1121
1122 # Remove storage controller if it is not an IDE controller.
1123 if eStorageController is not vboxcon.StorageControllerType_PIIX3 \
1124 and eStorageController is not vboxcon.StorageControllerType_PIIX4:
1125 oSession.o.machine.removeStorageController(_ControllerTypeToName(eStorageController));
1126
1127 oSession.saveSettings();
1128 oSession.saveSettings();
1129 oSession.close();
1130 oSession = None;
1131 except:
1132 reporter.errorXcpt('failed to detach/delete disk %s from storage controller' % (sDiskPath));
1133 else:
1134 fRc = False;
1135
1136 reporter.testDone();
1137
1138 # Delete all disks
1139 for oHd in lstDisks:
1140 self.oVBox.deleteHdByMedium(oHd);
1141
1142 # Cleanup storage area
1143 if sDiskFormat != 'iSCSI' and not self.fUseScratch and self.fRecreateStorCfg:
1144 self.cleanupStorage(self.oStorCfg);
1145
1146 return fRc;
1147
1148 def testStorage(self, sDiskPath = None):
1149 """
1150 Runs the storage testcase through the selected configurations
1151 """
1152
1153 aasTestCfgs = [];
1154 aasTestCfgs.insert(self.kiVmName, self.asTestVMs);
1155 aasTestCfgs.insert(self.kiStorageCtrl, self.asStorageCtrls);
1156 aasTestCfgs.insert(self.kiHostIoCache, (self.asHostIoCache, self.fnFormatHostIoCache));
1157 aasTestCfgs.insert(self.kiDiskFmt, self.asDiskFormats);
1158 aasTestCfgs.insert(self.kiDiskVar, self.asDiskVariants);
1159 aasTestCfgs.insert(self.kiCpuCount, (self.acCpus, self.fnFormatCpuString));
1160 aasTestCfgs.insert(self.kiVirtMode, (self.asVirtModes, self.fnFormatVirtMode));
1161 aasTestCfgs.insert(self.kiIoTest, self.asTests);
1162 aasTestCfgs.insert(self.kiTestSet, self.asTestSets);
1163
1164 aasTestsBlacklist = [];
1165 aasTestsBlacklist.append(['tst-storage', 'BusLogic']); # 64bit Linux is broken with BusLogic
1166
1167 oTstCfgMgr = StorTestCfgMgr(aasTestCfgs, aasTestsBlacklist, self.isTestCfgSupported);
1168
1169 fRc = True;
1170 asTestCfg = oTstCfgMgr.getCurrentTestCfg();
1171 while asTestCfg:
1172 fRc = self.testOneCfg(asTestCfg[self.kiVmName], self.getStorageCtrlFromName(asTestCfg[self.kiStorageCtrl]), \
1173 asTestCfg[self.kiHostIoCache], asTestCfg[self.kiDiskFmt], asTestCfg[self.kiDiskVar],
1174 sDiskPath, asTestCfg[self.kiCpuCount], asTestCfg[self.kiIoTest], \
1175 asTestCfg[self.kiVirtMode], asTestCfg[self.kiTestSet]) and fRc and True; # pychecker hack.
1176
1177 asTestCfg = oTstCfgMgr.getNextTestCfg();
1178
1179 return fRc;
1180
1181 def test1(self):
1182 """
1183 Executes test #1.
1184 """
1185
1186 fRc = True;
1187 oDiskCfg = self.kdStorageCfgs.get(socket.gethostname().lower());
1188
1189 # Test the host first if requested
1190 if oDiskCfg is not None or self.fUseScratch:
1191 lstBinaryPaths = ['/bin', '/sbin', '/usr/bin', '/usr/sbin', \
1192 '/opt/csw/bin', '/usr/ccs/bin', '/usr/sfw/bin'];
1193 oExecutor = remoteexecutor.RemoteExecutor(None, lstBinaryPaths, self.sScratchPath);
1194 if not self.fUseScratch:
1195 self.oStorCfg = storagecfg.StorageCfg(oExecutor, utils.getHostOs(), oDiskCfg);
1196
1197 # Try to cleanup any leftovers from a previous run first.
1198 fRc = self.oStorCfg.cleanupLeftovers();
1199 if not fRc:
1200 reporter.error('Failed to cleanup any leftovers from a previous run');
1201
1202 if self.fTestHost:
1203 reporter.testStart('Host');
1204 if self.fUseScratch:
1205 sMountPoint = self.sScratchPath;
1206 else:
1207 sMountPoint = self.prepareStorage(self.oStorCfg);
1208 if sMountPoint is not None:
1209 for sIoTest in self.asTests:
1210 reporter.testStart(sIoTest);
1211 for sTestSet in self.asTestSets:
1212 reporter.testStart(sTestSet);
1213 dTestSet = self.kdTestSets.get(sTestSet);
1214 self.testBenchmark(utils.getHostOs(), sIoTest, sMountPoint, oExecutor, dTestSet);
1215 reporter.testDone();
1216 reporter.testDone();
1217 self.cleanupStorage(self.oStorCfg);
1218 else:
1219 reporter.testFailure('Failed to prepare host storage');
1220 fRc = False;
1221 reporter.testDone();
1222 else:
1223 # Create the storage space first if it is not done before every test.
1224 sMountPoint = None;
1225 if self.fUseScratch:
1226 sMountPoint = self.sScratchPath;
1227 elif not self.fRecreateStorCfg:
1228 reporter.testStart('Create host storage');
1229 sMountPoint = self.prepareStorage(self.oStorCfg);
1230 if sMountPoint is None:
1231 reporter.testFailure('Failed to prepare host storage');
1232 fRc = False;
1233 self.oStorCfg.mkDirOnVolume(sMountPoint, 'test', 0777);
1234 sMountPoint = sMountPoint + '/test';
1235 reporter.testDone();
1236
1237 if fRc:
1238 # Run the storage tests.
1239 if not self.testStorage(sMountPoint):
1240 fRc = False;
1241
1242 if not self.fRecreateStorCfg and not self.fUseScratch:
1243 self.cleanupStorage(self.oStorCfg);
1244 else:
1245 fRc = False;
1246
1247 return fRc;
1248
1249if __name__ == '__main__':
1250 sys.exit(tdStorageBenchmark().main(sys.argv));
1251
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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