VirtualBox

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

Last change on this file since 57984 was 56923, checked in by vboxsync, 9 years ago

vboxtestvms.py: Don't try use raw-mode windows 8.0 and higher, they require SYSENTER which we must disable (see bug 1757).

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