VirtualBox

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

Last change on this file since 55338 was 55084, checked in by vboxsync, 10 years ago

ValidationKit: Replace checks for API version 4.4 with 5.0, 4.4 does not exist anymore. Not strictly necessary as the checks would trigger correctly but it removes a possible source of confusion

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