VirtualBox

source: vbox/trunk/src/VBox/ValidationKit/testdriver/vboxtestvms.py@ 53517

Last change on this file since 53517 was 53136, checked in by vboxsync, 10 years ago

ValidationKit/testdriver: using g_k32_64 is almost always wrong here, otherwise the 32-bit tests are never executed on testboxes which don't support 64-bit guests

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 42.6 KB
Line 
1# -*- coding: utf-8 -*-
2# $Id: vboxtestvms.py 53136 2014-10-23 20:37:48Z vboxsync $
3
4"""
5VirtualBox Test VMs
6"""
7
8__copyright__ = \
9"""
10Copyright (C) 2010-2014 Oracle Corporation
11
12This file is part of VirtualBox Open Source Edition (OSE), as
13available from http://www.virtualbox.org. This file is free software;
14you can redistribute it and/or modify it under the terms of the GNU
15General Public License (GPL) as published by the Free Software
16Foundation, in version 2 as it comes in the "COPYING" file of the
17VirtualBox OSE distribution. VirtualBox OSE is distributed in the
18hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
19
20The contents of this file may alternatively be used under the terms
21of the Common Development and Distribution License Version 1.0
22(CDDL) only, as it comes in the "COPYING.CDDL" file of the
23VirtualBox OSE distribution, in which case the provisions of the
24CDDL are applicable instead of those of the GPL.
25
26You may elect to license modified versions of this file under the
27terms and conditions of either the GPL or the CDDL or both.
28"""
29__version__ = "$Revision: 53136 $"
30
31# Standard Python imports.
32import re
33import random
34
35# Validation Kit imports.
36from testdriver import base;
37from testdriver import reporter;
38from testdriver import vboxcon;
39
40
41# All virtualization modes.
42g_asVirtModes = ['hwvirt', 'hwvirt-np', 'raw',];
43# All virtualization modes except for raw-mode.
44g_asVirtModesNoRaw = ['hwvirt', 'hwvirt-np',];
45# Dictionary mapping the virtualization mode mnemonics to a little less cryptic
46# strings used in test descriptions.
47g_dsVirtModeDescs = {
48 'raw' : 'Raw-mode',
49 'hwvirt' : 'HwVirt',
50 'hwvirt-np' : 'NestedPaging'
51};
52
53# Arch constants.
54g_k32 = 32; # pylint: disable=C0103
55g_k64 = 64; # pylint: disable=C0103
56g_k32_64 = 96; # pylint: disable=C0103
57
58# Array indexes.
59g_iGuestOsType = 0;
60g_iKind = 1;
61g_iArch = 2;
62g_iMinCpu = 3;
63g_iMaxCpu = 4;
64g_iRegEx = 5;
65
66# Table translating from VM name core to a more detailed guest info.
67# pylint: disable=C0301
68g_aaNameToDetails = \
69[
70 [ 'WindowsNT4', 'WindowsNT4', g_k32, 1, 32, ['nt4', 'nt4sp[0-9]']], # max cpus??
71 [ 'Windows2000', 'Windows2000', g_k32, 1, 32, ['w2k', 'w2ksp[0-9]', 'win2k', 'win2ksp[0-9]']], # max cpus??
72 [ 'WindowsXP', 'WindowsXP', g_k32, 1, 32, ['xp', 'xpsp[0-9]']],
73 [ 'WindowsXP_64', 'WindowsXP_64', g_k64, 1, 32, ['xp64', 'xp64sp[0-9]']],
74 [ 'Windows2003', 'Windows2003', g_k32, 1, 32, ['w2k3', 'w2k3sp[0-9]', 'win2k3', 'win2k3sp[0-9]']],
75 [ 'WindowsVista', 'WindowsVista', g_k32, 1, 32, ['vista', 'vistasp[0-9]']],
76 [ 'Windows2008', 'Windows2008', g_k32, 1, 64, ['w2k8', 'w2k8sp[0-9]', 'win2k8', 'win2k8sp[0-9]']], # max cpus/cores??
77 [ 'Windows2008_64', 'Windows2008_64', g_k64, 1, 64, ['w2k8r2', 'w2k8r2sp[0-9]', 'win2k8r2', 'win2k8r2sp[0-9]']], # max cpus/cores??
78 [ 'Windows7', 'Windows7', g_k32, 1, 32, ['w7', 'w7sp[0-9]', 'win7',]], # max cpus/cores??
79 [ 'Windows7_64', 'Windows7_64', g_k64, 1, 64, ['w7-64', 'w7sp[0-9]-64', 'win7-64',]], # max cpus/cores??
80 [ 'Windows8', 'Windows8', g_k32, 1, 32, ['w8', 'w8sp[0-9]', 'win8',]], # max cpus/cores??
81 [ 'Windows8_64', 'Windows8_64', g_k64, 1, 64, ['w8-64', 'w8sp[0-9]-64', 'win8-64',]], # max cpus/cores??
82 [ 'Windows81', 'Windows81', g_k32, 1, 32, ['w81', 'w81sp[0-9]', 'win81',]], # max cpus/cores??
83 [ 'Windows81_64', 'Windows81_64', g_k64, 1, 64, ['w81-64', 'w81sp[0-9]-64', 'win81-64',]], # max cpus/cores??
84 [ 'Linux', 'Debian', g_k32, 1, 256, ['deb[0-9]*', 'debian[0-9]*', ]],
85 [ 'Linux_64', 'Debian_64', g_k64, 1, 256, ['deb[0-9]*-64', 'debian[0-9]*-64', ]],
86 [ 'Linux', 'RedHat', g_k32, 1, 256, ['rhel', 'rhel[0-9]', 'rhel[0-9]u[0-9]']],
87 [ 'Linux', 'Fedora', g_k32, 1, 256, ['fedora', 'fedora[0-9]*', ]],
88 [ 'Linux_64', 'Fedora_64', g_k64, 1, 256, ['fedora-64', 'fedora[0-9]*-64', ]],
89 [ 'Linux', 'Oracle', g_k32, 1, 256, ['ols[0-9]*', 'oel[0-9]*', ]],
90 [ 'Linux_64', 'Oracle_64', g_k64, 1, 256, ['ols[0-9]*-64', 'oel[0-9]*-64', ]],
91 [ 'Linux', 'OpenSUSE', g_k32, 1, 256, ['opensuse[0-9]*', 'suse[0-9]*', ]],
92 [ 'Linux_64', 'OpenSUSE_64', g_k64, 1, 256, ['opensuse[0-9]*-64', 'suse[0-9]*-64', ]],
93 [ 'Linux', 'Ubuntu', g_k32, 1, 256, ['ubuntu[0-9]*', ]],
94 [ 'Linux_64', 'Ubuntu_64', g_k64, 1, 256, ['ubuntu[0-9]*-64', ]],
95 [ 'Solaris', 'Solaris', g_k32, 1, 256, ['sol10', 'sol10u[0-9]']],
96 [ 'Solaris_64', 'Solaris_64', g_k64, 1, 256, ['sol10-64', 'sol10u-64[0-9]']],
97 [ 'Solaris_64', 'Solaris11_64', g_k64, 1, 256, ['sol11u1']],
98 [ 'BSD', 'FreeBSD_64', g_k32_64, 1, 1, ['bs-.*']], # boot sectors, wanted 64-bit type.
99];
100
101# Guest OS type string constants.
102g_ksGuestOsTypeDarwin = 'darwin'
103g_ksGuestOsTypeFreeBSD = 'freebsd'
104g_ksGuestOsTypeLinux = 'linux'
105g_ksGuestOsTypeOS2 = 'os2'
106g_ksGuestOsTypeSolaris = 'solaris'
107g_ksGuestOsTypeWindows = 'windows'
108
109# String constants for hypervisor types.
110g_ksParavirtProviderNone = 'none'
111g_ksParavirtProviderDefault = 'default'
112g_ksParavirtProviderLegacy = 'legacy'
113g_ksParavirtProviderMinimal = 'minimal'
114g_ksParavirtProviderHyperV = 'hyperv'
115
116# Mapping for support of paravirtualisation providers per guest OS.
117#g_kdaParavirtProvidersSupported = {
118# g_ksGuestOsTypeDarwin : ( g_ksParavirtProviderMinimal, ),
119# g_ksGuestOsTypeFreeBSD : ( g_ksParavirtProviderNone, g_ksParavirtProviderMinimal, ),
120# g_ksGuestOsTypeLinux : ( g_ksParavirtProviderNone, g_ksParavirtProviderMinimal, g_ksParavirtProviderHyperV, ),
121# g_ksGuestOsTypeOS2 : ( g_ksParavirtProviderNone, ),
122# g_ksGuestOsTypeSolaris : ( g_ksParavirtProviderNone, ),
123# g_ksGuestOsTypeWindows : ( g_ksParavirtProviderNone, g_ksParavirtProviderMinimal, g_ksParavirtProviderHyperV, )
124#}
125# Temporary tweak:
126# since for the most guests g_ksParavirtProviderNone is almost the same as g_ksParavirtProviderMinimal,
127# g_ksParavirtProviderMinimal is removed from the list in order to get maximum number of unique choices
128# during independent test runs when paravirt provider is taken randomly.
129g_kdaParavirtProvidersSupported = {
130 g_ksGuestOsTypeDarwin : ( g_ksParavirtProviderMinimal, ),
131 g_ksGuestOsTypeFreeBSD : ( g_ksParavirtProviderNone, ),
132 g_ksGuestOsTypeLinux : ( g_ksParavirtProviderNone, g_ksParavirtProviderHyperV, ),
133 g_ksGuestOsTypeOS2 : ( g_ksParavirtProviderNone, ),
134 g_ksGuestOsTypeSolaris : ( g_ksParavirtProviderNone, ),
135 g_ksGuestOsTypeWindows : ( g_ksParavirtProviderNone, g_ksParavirtProviderHyperV, )
136}
137
138
139# pylint: enable=C0301
140
141def _intersects(asSet1, asSet2):
142 """
143 Checks if any of the strings in set 1 matches any of the regular
144 expressions in set 2.
145 """
146 for sStr1 in asSet1:
147 for sRx2 in asSet2:
148 if re.match(sStr1, sRx2 + '$'):
149 return True;
150 return False;
151
152
153class TestVm(object):
154 """
155 A Test VM - name + VDI/whatever.
156
157 This is just a data object.
158 """
159
160 def __init__(self, oSet, sVmName, sHd = None, sKind = None, acCpusSup = None, asVirtModesSup = None, # pylint: disable=R0913
161 fIoApic = None, fPae = None, sNic0AttachType = None, sHddControllerType = 'IDE Controller',
162 sFloppy = None, fVmmDevTestingPart = None, fVmmDevTestingMmio = False, fUseParavirtProvider = False):
163 self.oSet = oSet;
164 self.sVmName = sVmName;
165 self.sHd = sHd; # Relative to the testrsrc root.
166 self.acCpusSup = acCpusSup;
167 self.asVirtModesSup = asVirtModesSup;
168 self.sKind = sKind;
169 self.sGuestOsType = None;
170 self.sDvdImage = None; # Relative to the testrsrc root.
171 self.fIoApic = fIoApic;
172 self.fPae = fPae;
173 self.sNic0AttachType = sNic0AttachType;
174 self.sHddControllerType = sHddControllerType;
175 self.sFloppy = sFloppy; # Relative to the testrsrc root, except when it isn't...
176 self.fVmmDevTestingPart = fVmmDevTestingPart;
177 self.fVmmDevTestingMmio = fVmmDevTestingMmio;
178
179 self.fSnapshotRestoreCurrent = False; # Whether to restore execution on the current snapshot.
180 self.fSkip = False; # All VMs are included in the configured set by default.
181 self.aInfo = None;
182 self._guessStuff();
183
184 # Assign all available paravirt providers for current VM type if fUseParavirtProvider allows to do that.
185 # The list might be overwritten later once --paravirt-modes option is specified.
186 #
187 # Temporary solution: in order to do not overload testboxes, the only one provider is enabled by default (a random one).
188 if fUseParavirtProvider:
189 random.seed()
190 self.asParavirtModes = (random.choice(g_kdaParavirtProvidersSupported[self.sGuestOsType]),)
191 else:
192 self.asParavirtModes = (None,)
193
194 def _mkCanonicalGuestOSType(self, sType):
195 """
196 Convert guest OS type into constant representation.
197 Raise exception if specified @param sType is unknown.
198 """
199 if sType.lower().startswith('darwin'):
200 return g_ksGuestOsTypeDarwin
201 if sType.lower().startswith('bsd'):
202 return g_ksGuestOsTypeFreeBSD
203 if sType.lower().startswith('linux'):
204 return g_ksGuestOsTypeLinux
205 if sType.lower().startswith('os2'):
206 return g_ksGuestOsTypeOS2
207 if sType.lower().startswith('solaris'):
208 return g_ksGuestOsTypeSolaris
209 if sType.lower().startswith('windows'):
210 return g_ksGuestOsTypeWindows
211 raise base.GenError(sWhat="unknown guest OS kind: %s" % str(sType))
212
213 def _guessStuff(self):
214 """
215 Used by the constructor to guess stuff.
216 """
217
218 sNm = self.sVmName.lower().strip();
219 asSplit = sNm.replace('-', ' ').split(' ');
220
221 if self.sKind is None:
222 # From name.
223 for aInfo in g_aaNameToDetails:
224 if _intersects(asSplit, aInfo[g_iRegEx]):
225 self.aInfo = aInfo;
226 self.sGuestOsType = self._mkCanonicalGuestOSType(aInfo[g_iGuestOsType])
227 self.sKind = aInfo[g_iKind];
228 break;
229 if self.sKind is None:
230 reporter.fatal('The OS of test VM "%s" cannot be guessed' % (self.sVmName,));
231
232 # Check for 64-bit, if required and supported.
233 if self.aInfo[g_iArch] == g_k32_64 and _intersects(asSplit, ['64', 'amd64']):
234 self.sKind = self.sKind + '_64';
235 else:
236 # Lookup the kind.
237 for aInfo in g_aaNameToDetails:
238 if self.sKind == aInfo[g_iKind]:
239 self.aInfo = aInfo;
240 break;
241 if self.aInfo is None:
242 reporter.fatal('The OS of test VM "%s" with sKind="%s" cannot be guessed' % (self.sVmName, self.sKind));
243
244 # Translate sKind into sGuest OS Type.
245 if self.sGuestOsType is None:
246 if self.aInfo is not None:
247 self.sGuestOsType = self._mkCanonicalGuestOSType(self.aInfo[g_iGuestOsType])
248 elif self.sKind.find("Windows") >= 0:
249 self.sGuestOsType = g_ksGuestOsTypeWindows
250 elif self.sKind.find("Linux") >= 0:
251 self.sGuestOsType = g_ksGuestOsTypeLinux;
252 elif self.sKind.find("Solaris") >= 0:
253 self.sGuestOsType = g_ksGuestOsTypeSolaris;
254 else:
255 reporter.fatal('The OS of test VM "%s", sKind="%s" cannot be guessed' % (self.sVmName, self.sKind));
256
257 # Restrict modes and such depending on the OS.
258 if self.asVirtModesSup is None:
259 self.asVirtModesSup = list(g_asVirtModes);
260 if self.sGuestOsType in (g_ksGuestOsTypeOS2, g_ksGuestOsTypeDarwin):
261 self.asVirtModesSup = [sVirtMode for sVirtMode in self.asVirtModesSup if sVirtMode != 'raw'];
262 if self.sKind.find('_64') > 0:
263 self.asVirtModesSup = [sVirtMode for sVirtMode in self.asVirtModesSup if sVirtMode != 'raw'];
264
265 # Restrict the CPU count depending on the OS and/or percieved SMP readiness.
266 if self.acCpusSup is None:
267 if _intersects(asSplit, ['uni']):
268 self.acCpusSup = [1];
269 elif self.aInfo is not None:
270 self.acCpusSup = [i for i in range(self.aInfo[g_iMinCpu], self.aInfo[g_iMaxCpu]) ];
271 else:
272 self.acCpusSup = [1];
273
274 return True;
275
276 def getReconfiguredVm(self, oTestDrv, cCpus, sVirtMode, sParavirtMode = None):
277 """
278 actionExecute worker that finds and reconfigure a test VM.
279
280 Returns (fRc, oVM) where fRc is True, None or False and oVM is a
281 VBox VM object that is only present when rc is True.
282 """
283
284 fRc = False;
285 oVM = oTestDrv.getVmByName(self.sVmName);
286 if oVM is not None:
287 if self.fSnapshotRestoreCurrent is True:
288 fRc = True;
289 else:
290 fHostSupports64bit = oTestDrv.hasHostLongMode();
291 if self.is64bitRequired() and not fHostSupports64bit:
292 fRc = None; # Skip the test.
293 elif self.isViaIncompatible() and oTestDrv.isHostCpuVia():
294 fRc = None; # Skip the test.
295 else:
296 oSession = oTestDrv.openSession(oVM);
297 if oSession is not None:
298 fRc = oSession.enableVirtEx(sVirtMode != 'raw');
299 fRc = fRc and oSession.enableNestedPaging(sVirtMode == 'hwvirt-np');
300 fRc = fRc and oSession.setCpuCount(cCpus);
301
302 if oSession.fpApiVer >= 4.4 and sParavirtMode is not None:
303 adParavirtProviders = {
304 g_ksParavirtProviderNone : vboxcon.ParavirtProvider_None,
305 g_ksParavirtProviderDefault: vboxcon.ParavirtProvider_Default,
306 g_ksParavirtProviderLegacy : vboxcon.ParavirtProvider_Legacy,
307 g_ksParavirtProviderMinimal: vboxcon.ParavirtProvider_Minimal,
308 g_ksParavirtProviderHyperV : vboxcon.ParavirtProvider_HyperV,
309 };
310 fRc = fRc and oSession.setParavirtProvider(adParavirtProviders[sParavirtMode]);
311 reporter.log('Set paravirtualization provider [%s].' % sParavirtMode);
312
313 fCfg64Bit = self.is64bitRequired() or (self.is64bit() and fHostSupports64bit and sVirtMode != 'raw');
314 fRc = fRc and oSession.enableLongMode(fCfg64Bit);
315 if fCfg64Bit: # This is to avoid GUI pedantic warnings in the GUI. Sigh.
316 oOsType = oSession.getOsType();
317 if oOsType is not None:
318 if oOsType.is64Bit and sVirtMode == 'raw':
319 assert(oOsType.id[-3:] == '_64');
320 fRc = fRc and oSession.setOsType(oOsType.id[:-3]);
321 elif not oOsType.is64Bit and sVirtMode != 'raw':
322 fRc = fRc and oSession.setOsType(oOsType.id + '_64');
323
324 fRc = fRc and oSession.saveSettings();
325 if not oSession.close():
326 fRc = False;
327 if fRc is True:
328 return (True, oVM);
329 return (fRc, None);
330
331
332 def isWindows(self):
333 """ Checks if it's a Windows VM. """
334 return self.sGuestOsType == g_ksGuestOsTypeWindows;
335
336 def isOS2(self):
337 """ Checks if it's an OS/2 VM. """
338 return self.sGuestOsType == g_ksGuestOsTypeOS2;
339
340 def is64bit(self):
341 """ Checks if it's a 64-bit VM. """
342 return self.sKind.find('_64') >= 0;
343
344 def is64bitRequired(self):
345 """ Check if 64-bit is required or not. """
346 return (self.aInfo[g_iArch] & g_k64) != 0;
347
348 def isLoggedOntoDesktop(self):
349 """ Checks if the test VM is logging onto a graphical desktop by default. """
350 if self.isWindows():
351 return True;
352 if self.isOS2():
353 return True;
354 if self.sVmName.find('-desktop'):
355 return True;
356 return False;
357
358 def isViaIncompatible(self):
359 """
360 Identifies VMs that doesn't work on VIA.
361
362 Returns True if NOT supported on VIA, False if it IS supported.
363 """
364 # Oracle linux doesn't like VIA in our experience
365 if self.aInfo[g_iKind] in ['Oracle', 'Oracle_64']:
366 return True;
367 # OS/2: "The system detected an internal processing error at location
368 # 0168:fff1da1f - 000e:ca1f. 0a8606fd
369 if self.isOS2():
370 return True;
371 # Windows NT4 before SP4 won't work because of cmpxchg8b not being
372 # detected, leading to a STOP 3e(80,0,0,0).
373 if self.aInfo[g_iKind] == 'WindowsNT4':
374 if self.sVmName.find('sp') < 0:
375 return True; # no service pack.
376 if self.sVmName.find('sp0') >= 0 \
377 or self.sVmName.find('sp1') >= 0 \
378 or self.sVmName.find('sp2') >= 0 \
379 or self.sVmName.find('sp3') >= 0:
380 return True;
381 return False;
382
383
384
385class BootSectorTestVm(TestVm):
386 """
387 A Boot Sector Test VM.
388 """
389
390 def __init__(self, oSet, sVmName, sFloppy = None, asVirtModesSup = None, f64BitRequired = False):
391 self.f64BitRequired = f64BitRequired;
392 if asVirtModesSup is None:
393 asVirtModesSup = list(g_asVirtModes);
394 TestVm.__init__(self, oSet, sVmName,
395 acCpusSup = [1,],
396 sFloppy = sFloppy,
397 asVirtModesSup = asVirtModesSup,
398 fPae = True,
399 fIoApic = True,
400 fVmmDevTestingPart = True,
401 fVmmDevTestingMmio = True,
402 );
403
404 def is64bitRequired(self):
405 return self.f64BitRequired;
406
407
408
409class TestVmSet(object):
410 """
411 A set of Test VMs.
412 """
413
414 def __init__(self, oTestVmManager = None, acCpus = None, asVirtModes = None, fIgnoreSkippedVm = False):
415 self.oTestVmManager = oTestVmManager;
416 if acCpus is None:
417 acCpus = [1, 2];
418 self.acCpusDef = acCpus;
419 self.acCpus = acCpus;
420 if asVirtModes is None:
421 asVirtModes = list(g_asVirtModes);
422 self.asVirtModesDef = asVirtModes;
423 self.asVirtModes = asVirtModes;
424 self.aoTestVms = [];
425 self.fIgnoreSkippedVm = fIgnoreSkippedVm;
426 self.asParavirtModes = None
427
428 def findTestVmByName(self, sVmName):
429 """
430 Returns the TestVm object with the given name.
431 Returns None if not found.
432 """
433 for oTestVm in self.aoTestVms:
434 if oTestVm.sVmName == sVmName:
435 return oTestVm;
436 return None;
437
438 def getAllVmNames(self, sSep = ':'):
439 """
440 Returns names of all the test VMs in the set separated by
441 sSep (defaults to ':').
442 """
443 sVmNames = '';
444 for oTestVm in self.aoTestVms:
445 if sVmNames == '':
446 sVmNames = oTestVm.sVmName;
447 else:
448 sVmNames = sVmNames + sSep + oTestVm.sVmName;
449 return sVmNames;
450
451 def showUsage(self):
452 """
453 Invoked by vbox.TestDriver.
454 """
455 reporter.log('');
456 reporter.log('Test VM selection and general config options:');
457 reporter.log(' --virt-modes <m1[:m2[:]]');
458 reporter.log(' Default: %s' % (':'.join(self.asVirtModesDef)));
459 reporter.log(' --skip-virt-modes <m1[:m2[:]]');
460 reporter.log(' Use this to avoid hwvirt or hwvirt-np when not supported by the host');
461 reporter.log(' since we cannot detect it using the main API. Use after --virt-modes.');
462 reporter.log(' --cpu-counts <c1[:c2[:]]');
463 reporter.log(' Default: %s' % (':'.join(str(c) for c in self.acCpusDef)));
464 reporter.log(' --test-vms <vm1[:vm2[:...]]>');
465 reporter.log(' Test the specified VMs in the given order. Use this to change');
466 reporter.log(' the execution order or limit the choice of VMs');
467 reporter.log(' Default: %s (all)' % (self.getAllVmNames(),));
468 reporter.log(' --skip-vms <vm1[:vm2[:...]]>');
469 reporter.log(' Skip the specified VMs when testing.');
470 reporter.log(' --snapshot-restore-current');
471 reporter.log(' Restores the current snapshot and resumes execution.');
472 reporter.log(' --paravirt-modes <m1[:m2[:]]')
473 reporter.log(' Default for OS X guests : %s' % (':'.join(str(m) for m in g_kdaParavirtProvidersSupported[g_ksGuestOsTypeDarwin ]))) # pylint: disable=C0301
474 reporter.log(' Default for FreeBSD guests: %s' % (':'.join(str(m) for m in g_kdaParavirtProvidersSupported[g_ksGuestOsTypeFreeBSD ]))) # pylint: disable=C0301
475 reporter.log(' Default for Linux guests : %s' % (':'.join(str(m) for m in g_kdaParavirtProvidersSupported[g_ksGuestOsTypeLinux ]))) # pylint: disable=C0301
476 reporter.log(' Default for OS/2 guests : %s' % (':'.join(str(m) for m in g_kdaParavirtProvidersSupported[g_ksGuestOsTypeOS2 ]))) # pylint: disable=C0301
477 reporter.log(' Default for Solaris guests: %s' % (':'.join(str(m) for m in g_kdaParavirtProvidersSupported[g_ksGuestOsTypeSolaris ]))) # pylint: disable=C0301
478 reporter.log(' Default for Windows guests: %s' % (':'.join(str(m) for m in g_kdaParavirtProvidersSupported[g_ksGuestOsTypeWindows ]))) # pylint: disable=C0301
479 reporter.log(' NOTE: this option can be applied only in case if VM set contains')
480 reporter.log(' the only one VM because different VMs might not support all')
481 reporter.log(' the specified paravirtualisation providers. If the option not')
482 reporter.log(' specified, default set of paravirtualisation providers assigned')
483 reporter.log(' to VM according to its type.')
484
485 ## @todo Add more options for controlling individual VMs.
486 return True;
487
488 def parseOption(self, asArgs, iArg):
489 """
490 Parses the set test vm set options (--test-vms and --skip-vms), modifying the set
491 Invoked by the testdriver method with the same name.
492
493 Keyword arguments:
494 asArgs -- The argument vector.
495 iArg -- The index of the current argument.
496
497 Returns iArg if the option was not recognized and the caller should handle it.
498 Returns the index of the next argument when something is consumed.
499
500 In the event of a syntax error, a InvalidOption or QuietInvalidOption
501 is thrown.
502 """
503
504 if asArgs[iArg] == '--virt-modes':
505 iArg += 1;
506 if iArg >= len(asArgs):
507 raise base.InvalidOption('The "--virt-modes" takes a colon separated list of modes');
508
509 self.asVirtModes = asArgs[iArg].split(':');
510 for s in self.asVirtModes:
511 if s not in self.asVirtModesDef:
512 raise base.InvalidOption('The "--virt-modes" value "%s" is not valid; valid values are: %s' \
513 % (s, ' '.join(self.asVirtModesDef)));
514
515 elif asArgs[iArg] == '--skip-virt-modes':
516 iArg += 1;
517 if iArg >= len(asArgs):
518 raise base.InvalidOption('The "--skip-virt-modes" takes a colon separated list of modes');
519
520 for s in asArgs[iArg].split(':'):
521 if s not in self.asVirtModesDef:
522 raise base.InvalidOption('The "--virt-modes" value "%s" is not valid; valid values are: %s' \
523 % (s, ' '.join(self.asVirtModesDef)));
524 if s in self.asVirtModes:
525 self.asVirtModes.remove(s);
526
527 elif asArgs[iArg] == '--cpu-counts':
528 iArg += 1;
529 if iArg >= len(asArgs):
530 raise base.InvalidOption('The "--cpu-counts" takes a colon separated list of cpu counts');
531
532 self.acCpus = [];
533 for s in asArgs[iArg].split(':'):
534 try: c = int(s);
535 except: raise base.InvalidOption('The "--cpu-counts" value "%s" is not an integer' % (s,));
536 if c <= 0: raise base.InvalidOption('The "--cpu-counts" value "%s" is zero or negative' % (s,));
537 self.acCpus.append(c);
538
539 elif asArgs[iArg] == '--test-vms':
540 iArg += 1;
541 if iArg >= len(asArgs):
542 raise base.InvalidOption('The "--test-vms" takes colon separated list');
543
544 for oTestVm in self.aoTestVms:
545 oTestVm.fSkip = True;
546
547 asTestVMs = asArgs[iArg].split(':');
548 for s in asTestVMs:
549 oTestVm = self.findTestVmByName(s);
550 if oTestVm is None:
551 raise base.InvalidOption('The "--test-vms" value "%s" is not valid; valid values are: %s' \
552 % (s, self.getAllVmNames(' ')));
553 oTestVm.fSkip = False;
554
555 elif asArgs[iArg] == '--skip-vms':
556 iArg += 1;
557 if iArg >= len(asArgs):
558 raise base.InvalidOption('The "--skip-vms" takes colon separated list');
559
560 asTestVMs = asArgs[iArg].split(':');
561 for s in asTestVMs:
562 oTestVm = self.findTestVmByName(s);
563 if oTestVm is None:
564 reporter.log('warning: The "--test-vms" value "%s" does not specify any of our test VMs.' % (s,));
565 else:
566 oTestVm.fSkip = True;
567
568 elif asArgs[iArg] == '--snapshot-restore-current':
569 for oTestVm in self.aoTestVms:
570 if oTestVm.fSkip is False:
571 oTestVm.fSnapshotRestoreCurrent = True;
572 reporter.log('VM "%s" will be restored.' % (oTestVm.sVmName));
573
574 elif asArgs[iArg] == '--paravirt-modes':
575 iArg += 1
576 if iArg >= len(asArgs):
577 raise base.InvalidOption('The "--paravirt-modes" takes a colon separated list of modes');
578
579 # Check and remember specified paravirtualisation providers list.
580 self.asParavirtModes = asArgs[iArg].split(':')
581
582 for sMode in self.asParavirtModes:
583 if sMode not in (g_ksParavirtProviderNone, g_ksParavirtProviderDefault,
584 g_ksParavirtProviderLegacy, g_ksParavirtProviderMinimal, g_ksParavirtProviderHyperV):
585 raise base.InvalidOption('Bad paravirtualisation provider specified: %s' % sMode);
586
587 else:
588 return iArg;
589 return iArg + 1;
590
591 def getResourceSet(self):
592 """
593 Implements base.TestDriver.getResourceSet
594 """
595 asResources = [];
596 for oTestVm in self.aoTestVms:
597 if not oTestVm.fSkip:
598 if oTestVm.sHd is not None:
599 asResources.append(oTestVm.sHd);
600 if oTestVm.sDvdImage is not None:
601 asResources.append(oTestVm.sDvdImage);
602 return asResources;
603
604 def actionConfig(self, oTestDrv, eNic0AttachType = None, sDvdImage = None):
605 """
606 For base.TestDriver.actionConfig. Configure the VMs with defaults and
607 a few tweaks as per arguments.
608
609 Returns True if successful.
610 Returns False if not.
611 """
612
613 # Check if --paravirt-modes option was specified and it meets requirements.
614 if self.asParavirtModes is not None:
615 iNumberOfActivatedVMs = len([item for item in self.aoTestVms if item.fSkip is not True])
616 if iNumberOfActivatedVMs != 1:
617 raise base.InvalidOption('The --paravirt-modes option assumes that the only one VM '
618 'is activated in test VMs set while %d are active.' % iNumberOfActivatedVMs)
619
620 for oTestVm in self.aoTestVms:
621 if oTestVm.fSkip:
622 continue;
623
624 # At this point we know that if --paravirt-modes option was specified, there is only one VM in set.
625 if self.asParavirtModes is not None:
626 for sMode in self.asParavirtModes:
627 if sMode not in g_kdaParavirtProvidersSupported[oTestVm.sGuestOsType]:
628 raise base.InvalidOption('Paravirtualisation provider "%s" is not supported by current guest OS.' % sMode)
629 # At this point oTestVm' asParavirtModes might be safely overwritten.
630 oTestVm.asParavirtModes = self.asParavirtModes
631
632 if oTestVm.fSnapshotRestoreCurrent:
633 # If we want to restore a VM we don't need to create
634 # the machine anymore -- so just add it to the test VM list.
635 oVM = oTestDrv.addTestMachine(oTestVm.sVmName);
636 else:
637 ## @todo This could possibly be moved to the TestVM object.
638 if sDvdImage is not None:
639 sMyDvdImage = sDvdImage;
640 else:
641 sMyDvdImage = oTestVm.sDvdImage;
642
643 if eNic0AttachType is not None:
644 eMyNic0AttachType = eNic0AttachType;
645 elif oTestVm.sNic0AttachType is None:
646 eMyNic0AttachType = None;
647 elif oTestVm.sNic0AttachType == 'nat':
648 eMyNic0AttachType = vboxcon.NetworkAttachmentType_NAT;
649 elif oTestVm.sNic0AttachType == 'bridged':
650 eMyNic0AttachType = vboxcon.NetworkAttachmentType_Bridged;
651 else:
652 assert False, oTestVm.sNic0AttachType;
653
654 oVM = oTestDrv.createTestVM(oTestVm.sVmName, 1, \
655 sHd = oTestVm.sHd, \
656 sKind = oTestVm.sKind, \
657 fIoApic = oTestVm.fIoApic, \
658 fPae = oTestVm.fPae, \
659 eNic0AttachType = eMyNic0AttachType, \
660 sDvdImage = sMyDvdImage, \
661 sHddControllerType = oTestVm.sHddControllerType,
662 sFloppy = oTestVm.sFloppy,
663 fVmmDevTestingPart = oTestVm.fVmmDevTestingPart,
664 fVmmDevTestingMmio = oTestVm.fVmmDevTestingPart);
665 if oVM is None:
666 return False;
667
668 return True;
669
670 def _removeUnsupportedVirtModes(self, oTestDrv):
671 """
672 Removes unsupported virtualization modes.
673 """
674 if 'hwvirt' in self.asVirtModes and not oTestDrv.hasHostHwVirt():
675 reporter.log('Hardware assisted virtualization is not available on the host, skipping it.');
676 self.asVirtModes.remove('hwvirt');
677
678 if 'hwvirt-np' in self.asVirtModes and not oTestDrv.hasHostNestedPaging():
679 reporter.log('Nested paging not supported by the host, skipping it.');
680 self.asVirtModes.remove('hwvirt-np');
681 return True;
682
683 def actionExecute(self, oTestDrv, fnCallback): # pylint: disable=R0914
684 """
685 For base.TestDriver.actionExecute. Calls the callback function for
686 each of the VMs and basic configuration variations (virt-mode and cpu
687 count).
688
689 Returns True if all fnCallback calls returned True, otherwise False.
690
691 The callback can return True, False or None. The latter is for when the
692 test is skipped. (True is for success, False is for failure.)
693 """
694
695 self._removeUnsupportedVirtModes(oTestDrv);
696 cMaxCpus = oTestDrv.getHostCpuCount();
697
698 #
699 # The test loop.
700 #
701 fRc = True;
702 for oTestVm in self.aoTestVms:
703 if oTestVm.fSkip and self.fIgnoreSkippedVm:
704 reporter.log2('Ignoring VM %s (fSkip = True).' % (oTestVm.sVmName,));
705 continue;
706 reporter.testStart(oTestVm.sVmName);
707 if oTestVm.fSkip:
708 reporter.testDone(fSkipped = True);
709 continue;
710
711 # Intersect the supported modes and the ones being testing.
712 asVirtModesSup = [sMode for sMode in oTestVm.asVirtModesSup if sMode in self.asVirtModes];
713
714 # Ditto for CPUs.
715 acCpusSup = [cCpus for cCpus in oTestVm.acCpusSup if cCpus in self.acCpus];
716
717 for cCpus in acCpusSup:
718 if cCpus == 1:
719 reporter.testStart('1 cpu');
720 else:
721 reporter.testStart('%u cpus' % (cCpus));
722 if cCpus > cMaxCpus:
723 reporter.testDone(fSkipped = True);
724 continue;
725
726 cTests = 0;
727 for sVirtMode in asVirtModesSup:
728 if sVirtMode == 'raw' and cCpus > 1:
729 continue;
730
731 for sParavirtMode in oTestVm.asParavirtModes:
732
733 reporter.testStart("%s/%s" % (g_dsVirtModeDescs[sVirtMode], sParavirtMode if sParavirtMode is not None else "[paravirtualisation provider not set]")); # pylint: disable=C0301
734
735 # Reconfigure the VM.
736 try:
737 (rc2, oVM) = oTestVm.getReconfiguredVm(oTestDrv, cCpus, sVirtMode, sParavirtMode=sParavirtMode);
738 except KeyboardInterrupt:
739 raise;
740 except:
741 reporter.errorXcpt(cFrames = 9);
742 rc2 = False;
743 if rc2 is True:
744 try:
745 rc2 = fnCallback(oVM, oTestVm);
746 except KeyboardInterrupt:
747 raise;
748 except:
749 reporter.errorXcpt(cFrames = 9);
750 rc2 = False;
751 if rc2 is False:
752 reporter.maybeErr(reporter.testErrorCount() == 0, 'fnCallback failed');
753 elif rc2 is False:
754 reporter.log('getReconfiguredVm failed');
755 if rc2 is False:
756 fRc = False;
757
758 cTests = cTests + (rc2 is not None);
759 reporter.testDone(fSkipped = (rc2 is None));
760
761 reporter.testDone(fSkipped = cTests == 0);
762
763 _, cErrors = reporter.testDone();
764 if cErrors > 0:
765 fRc = False;
766 return fRc;
767
768 def enumerateTestVms(self, fnCallback):
769 """
770 Enumerates all the 'active' VMs.
771
772 Returns True if all fnCallback calls returned True.
773 Returns False if any returned False.
774 Returns None immediately if fnCallback returned None.
775 """
776 fRc = True;
777 for oTestVm in self.aoTestVms:
778 if not oTestVm.fSkip:
779 fRc2 = fnCallback(oTestVm);
780 if fRc2 is None:
781 return fRc2;
782 fRc = fRc and fRc2;
783 return fRc;
784
785
786
787class TestVmManager(object):
788 """
789 Test VM manager.
790 """
791
792 def __init__(self, sResourcePath):
793 self.sResourcePath = sResourcePath;
794
795
796 def getStandardVmSet(self, sTxsTransport):
797 """
798 Gets the set of standard test VMs.
799
800 This is supposed to do something seriously clever, like searching the
801 testrsrc tree for usable VMs, but for the moment it's all hard coded. :-)
802 """
803
804 oSet = TestVmSet(oTestVmManager = self);
805
806 oTestVm = TestVm(oSet, 'tst-nt4sp1', sHd = '4.2/' + sTxsTransport + '/nt4sp1/t-nt4sp1.vdi',
807 sKind = 'WindowsNT4', acCpusSup = [1]);
808 oSet.aoTestVms.append(oTestVm);
809
810 oTestVm = TestVm(oSet, 'tst-xppro', sHd = '4.2/' + sTxsTransport + '/xppro/t-xppro.vdi',
811 sKind = 'WindowsXP', acCpusSup = range(1, 33));
812 oSet.aoTestVms.append(oTestVm);
813
814 oTestVm = TestVm(oSet, 'tst-nt4sp6', sHd = '4.2/nt4sp6/t-nt4sp6.vdi',
815 sKind = 'WindowsNT4', acCpusSup = range(1, 33));
816 oSet.aoTestVms.append(oTestVm);
817
818 oTestVm = TestVm(oSet, 'tst-2ksp4', sHd = '4.2/win2ksp4/t-win2ksp4.vdi',
819 sKind = 'Windows2000', acCpusSup = range(1, 33));
820 oSet.aoTestVms.append(oTestVm);
821
822 oTestVm = TestVm(oSet, 'tst-xpsp2', sHd = '4.2/xpsp2/t-winxpsp2.vdi',
823 sKind = 'WindowsXP', acCpusSup = range(1, 33), fIoApic = True);
824 oSet.aoTestVms.append(oTestVm);
825
826 oTestVm = TestVm(oSet, 'tst-xpsp2-halaacpi', sHd = '4.2/xpsp2/t-winxp-halaacpi.vdi',
827 sKind = 'WindowsXP', acCpusSup = range(1, 33), fIoApic = True);
828 oSet.aoTestVms.append(oTestVm);
829
830 oTestVm = TestVm(oSet, 'tst-xpsp2-halacpi', sHd = '4.2/xpsp2/t-winxp-halacpi.vdi',
831 sKind = 'WindowsXP', acCpusSup = range(1, 33), fIoApic = True);
832 oSet.aoTestVms.append(oTestVm);
833
834 oTestVm = TestVm(oSet, 'tst-xpsp2-halapic', sHd = '4.2/xpsp2/t-winxp-halapic.vdi',
835 sKind = 'WindowsXP', acCpusSup = range(1, 33), fIoApic = True);
836 oSet.aoTestVms.append(oTestVm);
837
838 oTestVm = TestVm(oSet, 'tst-xpsp2-halmacpi', sHd = '4.2/xpsp2/t-winxp-halmacpi.vdi',
839 sKind = 'WindowsXP', acCpusSup = range(2, 33), fIoApic = True);
840 oSet.aoTestVms.append(oTestVm);
841
842 oTestVm = TestVm(oSet, 'tst-xpsp2-halmps', sHd = '4.2/xpsp2/t-winxp-halmps.vdi',
843 sKind = 'WindowsXP', acCpusSup = range(2, 33), fIoApic = True);
844 oSet.aoTestVms.append(oTestVm);
845
846 oTestVm = TestVm(oSet, 'tst-win7', sHd = '4.2/win7-32/t-win7.vdi',
847 sKind = 'Windows7', acCpusSup = range(1, 33), fIoApic = True);
848 oSet.aoTestVms.append(oTestVm);
849
850 oTestVm = TestVm(oSet, 'tst-win8', sHd = '4.2/win8-32/t-win8.vdi',
851 sKind = 'Windows8', acCpusSup = range(1, 33), fIoApic = True);
852 oSet.aoTestVms.append(oTestVm);
853
854 return oSet;
855
856 def getSmokeVmSet(self):
857 """
858 Gets a representative set of VMs for smoke testing.
859 """
860
861 oSet = TestVmSet(oTestVmManager = self);
862
863 oTestVm = TestVm(oSet, 'tst-nt4sp1', sHd = '4.2/nat/nt4sp1/t-nt4sp1.vdi',
864 sKind = 'WindowsNT4', acCpusSup = [1], sNic0AttachType = 'nat');
865 oSet.aoTestVms.append(oTestVm);
866
867 oTestVm = TestVm(oSet, 'tst-xppro', sHd = '4.2/nat/xppro/t-xppro.vdi',
868 sKind = 'WindowsXP', acCpusSup = range(1, 33), sNic0AttachType = 'nat');
869 oSet.aoTestVms.append(oTestVm);
870
871 oTestVm = TestVm(oSet, 'tst-rhel5', sHd = '3.0/tcp/rhel5.vdi',
872 sKind = 'RedHat', acCpusSup = range(1, 33), fIoApic = True, sNic0AttachType = 'nat');
873 oSet.aoTestVms.append(oTestVm);
874
875 oTestVm = TestVm(oSet, 'tst-win2k3ent', sHd = '3.0/tcp/win2k3ent-acpi.vdi',
876 sKind = 'Windows2003', acCpusSup = range(1, 33), fPae = True, sNic0AttachType = 'bridged');
877 oSet.aoTestVms.append(oTestVm);
878
879 oTestVm = TestVm(oSet, 'tst-sol10', sHd = '3.0/tcp/solaris10.vdi',
880 sKind = 'Solaris', acCpusSup = range(1, 33), fPae = True, sNic0AttachType = 'bridged');
881 oSet.aoTestVms.append(oTestVm);
882
883 oTestVm = TestVm(oSet, 'tst-sol10-64', sHd = '3.0/tcp/solaris10.vdi',
884 sKind = 'Solaris_64', acCpusSup = range(1, 33), sNic0AttachType = 'bridged');
885 oSet.aoTestVms.append(oTestVm);
886
887 oTestVm = TestVm(oSet, 'tst-sol11u1', sHd = '4.2/nat/sol11u1/t-sol11u1.vdi',
888 sKind = 'Solaris11_64', acCpusSup = range(1, 33), sNic0AttachType = 'nat',
889 fIoApic = True, sHddControllerType = 'SATA Controller');
890 oSet.aoTestVms.append(oTestVm);
891
892 oTestVm = TestVm(oSet, 'tst-nt4sp6', sHd = '4.2/nt4sp6/t-nt4sp6.vdi',
893 sKind = 'WindowsNT4', acCpusSup = range(1, 33));
894 oSet.aoTestVms.append(oTestVm);
895
896 oTestVm = TestVm(oSet, 'tst-2ksp4', sHd = '4.2/win2ksp4/t-win2ksp4.vdi',
897 sKind = 'Windows2000', acCpusSup = range(1, 33));
898 oSet.aoTestVms.append(oTestVm);
899
900 oTestVm = TestVm(oSet, 'tst-xpsp2', sHd = '4.2/xpsp2/t-winxpsp2.vdi',
901 sKind = 'WindowsXP', acCpusSup = range(1, 33), fIoApic = True);
902 oSet.aoTestVms.append(oTestVm);
903
904 oTestVm = TestVm(oSet, 'tst-xpsp2-halaacpi', sHd = '4.2/xpsp2/t-winxp-halaacpi.vdi',
905 sKind = 'WindowsXP', acCpusSup = range(1, 33), fIoApic = True);
906 oSet.aoTestVms.append(oTestVm);
907
908 oTestVm = TestVm(oSet, 'tst-xpsp2-halacpi', sHd = '4.2/xpsp2/t-winxp-halacpi.vdi',
909 sKind = 'WindowsXP', acCpusSup = range(1, 33), fIoApic = True);
910 oSet.aoTestVms.append(oTestVm);
911
912 oTestVm = TestVm(oSet, 'tst-xpsp2-halapic', sHd = '4.2/xpsp2/t-winxp-halapic.vdi',
913 sKind = 'WindowsXP', acCpusSup = range(1, 33), fIoApic = True);
914 oSet.aoTestVms.append(oTestVm);
915
916 oTestVm = TestVm(oSet, 'tst-xpsp2-halmacpi', sHd = '4.2/xpsp2/t-winxp-halmacpi.vdi',
917 sKind = 'WindowsXP', acCpusSup = range(2, 33), fIoApic = True);
918 oSet.aoTestVms.append(oTestVm);
919
920 oTestVm = TestVm(oSet, 'tst-xpsp2-halmps', sHd = '4.2/xpsp2/t-winxp-halmps.vdi',
921 sKind = 'WindowsXP', acCpusSup = range(2, 33), fIoApic = True);
922 oSet.aoTestVms.append(oTestVm);
923
924 oTestVm = TestVm(oSet, 'tst-win7', sHd = '4.2/win7-32/t-win7.vdi',
925 sKind = 'Windows7', acCpusSup = range(1, 33), fIoApic = True);
926 oSet.aoTestVms.append(oTestVm);
927
928 oTestVm = TestVm(oSet, 'tst-win8', sHd = '4.2/win8-32/t-win8.vdi',
929 sKind = 'Windows8', acCpusSup = range(1, 33), fIoApic = True);
930 oSet.aoTestVms.append(oTestVm);
931
932 return oSet;
933
934 def shutUpPyLint(self):
935 """ Shut up already! """
936 return self.sResourcePath;
937
Note: See TracBrowser for help on using the repository browser.

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