VirtualBox

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

Last change on this file since 65712 was 65483, checked in by vboxsync, 8 years ago

ValidationKit/tdStorageBenchmark1: Add option to log I/O requests for the executed test

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