VirtualBox

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

Last change on this file since 101007 was 101007, checked in by vboxsync, 18 months ago

ValKit: Use VBoxSVGA adapter on Windows 11 guests (instead of default VBoxVGA adapter)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 99.4 KB
Line 
1# -*- coding: utf-8 -*-
2# $Id: vboxtestvms.py 101007 2023-09-04 16:07:04Z vboxsync $
3
4"""
5VirtualBox Test VMs
6"""
7
8__copyright__ = \
9"""
10Copyright (C) 2010-2023 Oracle and/or its affiliates.
11
12This file is part of VirtualBox base platform packages, as
13available from https://www.virtualbox.org.
14
15This program is free software; you can redistribute it and/or
16modify it under the terms of the GNU General Public License
17as published by the Free Software Foundation, in version 3 of the
18License.
19
20This program is distributed in the hope that it will be useful, but
21WITHOUT ANY WARRANTY; without even the implied warranty of
22MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23General Public License for more details.
24
25You should have received a copy of the GNU General Public License
26along with this program; if not, see <https://www.gnu.org/licenses>.
27
28The contents of this file may alternatively be used under the terms
29of the Common Development and Distribution License Version 1.0
30(CDDL), a copy of it is provided in the "COPYING.CDDL" file included
31in the VirtualBox distribution, in which case the provisions of the
32CDDL are applicable instead of those of the GPL.
33
34You may elect to license modified versions of this file under the
35terms and conditions of either the GPL or the CDDL or both.
36
37SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
38"""
39__version__ = "$Revision: 101007 $"
40
41# Standard Python imports.
42import copy;
43import os;
44import re;
45import random;
46import socket;
47import string;
48import uuid;
49
50# Validation Kit imports.
51from common import pathutils;
52from common import utils;
53from testdriver import base;
54from testdriver import reporter;
55from testdriver import vboxcon;
56
57
58# All virtualization modes.
59g_asVirtModes = ['hwvirt', 'hwvirt-np', 'raw',];
60# All virtualization modes except for raw-mode.
61g_asVirtModesNoRaw = ['hwvirt', 'hwvirt-np',];
62# Dictionary mapping the virtualization mode mnemonics to a little less cryptic
63# strings used in test descriptions.
64g_dsVirtModeDescs = {
65 'raw' : 'Raw-mode',
66 'hwvirt' : 'HwVirt',
67 'hwvirt-np' : 'NestedPaging'
68};
69
70## @name VM grouping flags
71## @{
72g_kfGrpSmoke = 0x0001; ##< Smoke test VM.
73g_kfGrpStandard = 0x0002; ##< Standard test VM.
74g_kfGrpStdSmoke = g_kfGrpSmoke | g_kfGrpStandard; ##< shorthand.
75g_kfGrpWithGAs = 0x0004; ##< The VM has guest additions installed.
76g_kfGrpNoTxs = 0x0008; ##< The VM lacks test execution service.
77g_kfGrpAncient = 0x1000; ##< Ancient OS.
78g_kfGrpExotic = 0x2000; ##< Exotic OS.
79## @}
80
81
82## @name Flags.
83## @{
84g_k32 = 32; # pylint: disable=invalid-name
85g_k64 = 64; # pylint: disable=invalid-name
86g_k32_64 = 96; # pylint: disable=invalid-name
87g_kiArchMask = 96;
88g_kiNoRaw = 128; ##< No raw mode.
89## @}
90
91# Array indexes.
92g_iGuestOsType = 0;
93g_iKind = 1;
94g_iFlags = 2;
95g_iMinCpu = 3;
96g_iMaxCpu = 4;
97g_iRegEx = 5;
98
99# Table translating from VM name core to a more detailed guest info.
100# pylint: disable=line-too-long
101## @todo what's the difference between the first two columns again?
102g_aaNameToDetails = \
103[
104 [ 'WindowsNT3x', 'WindowsNT3x', g_k32, 1, 32, ['nt3', 'nt3[0-9]*']], # max cpus??
105 [ 'WindowsNT4', 'WindowsNT4', g_k32, 1, 32, ['nt4', 'nt4sp[0-9]']], # max cpus??
106 [ 'Windows2000', 'Windows2000', g_k32, 1, 32, ['w2k', 'w2ksp[0-9]', 'win2k', 'win2ksp[0-9]']], # max cpus??
107 [ 'WindowsXP', 'WindowsXP', g_k32, 1, 32, ['xp', 'xpsp[0-9]']],
108 [ 'WindowsXP_64', 'WindowsXP_64', g_k64, 1, 32, ['xp64', 'xp64sp[0-9]']],
109 [ 'Windows2003', 'Windows2003', g_k32, 1, 32, ['w2k3', 'w2k3sp[0-9]', 'win2k3', 'win2k3sp[0-9]']],
110 [ 'WindowsVista', 'WindowsVista', g_k32, 1, 32, ['vista', 'vistasp[0-9]']],
111 [ 'WindowsVista_64','WindowsVista_64', g_k64, 1, 64, ['vista-64', 'vistasp[0-9]-64',]], # max cpus/cores??
112 [ 'Windows2008', 'Windows2008', g_k32, 1, 64, ['w2k8', 'w2k8sp[0-9]', 'win2k8', 'win2k8sp[0-9]']], # max cpus/cores??
113 [ 'Windows2008_64', 'Windows2008_64', g_k64, 1, 64, ['w2k8r2', 'w2k8r2sp[0-9]', 'win2k8r2', 'win2k8r2sp[0-9]']], # max cpus/cores??
114 [ 'Windows7', 'Windows7', g_k32, 1, 32, ['w7', 'w7sp[0-9]', 'win7',]], # max cpus/cores??
115 [ 'Windows7_64', 'Windows7_64', g_k64, 1, 64, ['w7-64', 'w7sp[0-9]-64', 'win7-64',]], # max cpus/cores??
116 [ 'Windows2012', 'Windows2012', g_k64, 1, 64, ['w2k12', 'w2k12sp[0-9]', 'win2k12', 'win2k12sp[0-9]',]], # max cpus/cores??
117 [ 'Windows8', 'Windows8', g_k32 | g_kiNoRaw, 1, 32, ['w8', 'w8sp[0-9]', 'win8',]], # max cpus/cores??
118 [ 'Windows8_64', 'Windows8_64', g_k64, 1, 64, ['w8-64', 'w8sp[0-9]-64', 'win8-64',]], # max cpus/cores??
119 [ 'Windows81', 'Windows81', g_k32 | g_kiNoRaw, 1, 32, ['w81', 'w81sp[0-9]', 'win81',]], # max cpus/cores??
120 [ 'Windows81_64', 'Windows81_64', g_k64, 1, 64, ['w81-64', 'w81sp[0-9]-64', 'win81-64',]], # max cpus/cores??
121 [ 'Windows10', 'Windows10', g_k32 | g_kiNoRaw, 1, 32, ['w10', 'w10sp[0-9]', 'win10',]], # max cpus/cores??
122 [ 'Windows10_64', 'Windows10_64', g_k64, 1, 64, ['w10-64', 'w10sp[0-9]-64', 'win10-64',]], # max cpus/cores??
123 [ 'Windows2016', 'Windows2016', g_k64, 1, 64, ['w2k16', 'w2k16sp[0-9]', 'win2k16', 'win2k16sp[0-9]',]], # max cpus/cores??
124 [ 'Windows2019', 'Windows2019', g_k64, 1, 64, ['w2k19', 'w2k19sp[0-9]', 'win2k19', 'win2k19sp[0-9]',]], # max cpus/cores??
125 [ 'Windows2022', 'Windows2022', g_k64, 1, 64, ['w2k22', 'w2k22sp[0-9]', 'win2k22', 'win2k22sp[0-9]',]], # max cpus/cores??
126 [ 'Windows11_64', 'Windows11_64', g_k64, 2, 64, ['w11', 'w11-64', 'w11sp[0-9]-64', 'win11', 'win11-64',]], # max cpus/cores??
127 [ 'Linux', 'Debian', g_k32, 1, 256, ['deb[0-9]*', 'debian[0-9]*', ]],
128 [ 'Linux_64', 'Debian_64', g_k64, 1, 256, ['deb[0-9]*-64', 'debian[0-9]*-64', ]],
129 [ 'Linux', 'RedHat', g_k32, 1, 256, ['rhel', 'rhel[0-9]', 'rhel[0-9]u[0-9]']],
130 [ 'Linux', 'Fedora', g_k32, 1, 256, ['fedora', 'fedora[0-9]*', ]],
131 [ 'Linux_64', 'Fedora_64', g_k64, 1, 256, ['fedora-64', 'fedora[0-9]*-64', ]],
132 [ 'Linux', 'Oracle', g_k32, 1, 256, ['ols[0-9]*', 'oel[0-9]*', ]],
133 [ 'Linux_64', 'Oracle_64', g_k64, 1, 256, ['ols[0-9]*-64', 'oel[0-9]*-64', ]],
134 [ 'Linux', 'OpenSUSE', g_k32, 1, 256, ['opensuse[0-9]*', 'suse[0-9]*', ]],
135 [ 'Linux_64', 'OpenSUSE_64', g_k64, 1, 256, ['opensuse[0-9]*-64', 'suse[0-9]*-64', ]],
136 [ 'Linux', 'Ubuntu', g_k32, 1, 256, ['ubuntu[0-9]*', ]],
137 [ 'Linux_64', 'Ubuntu_64', g_k64, 1, 256, ['ubuntu[0-9]*-64', ]],
138 [ 'Linux', 'ArchLinux', g_k32, 1, 256, ['arch[0-9]*', ]],
139 [ 'Linux_64', 'ArchLinux_64', g_k64, 1, 256, ['arch[0-9]*-64', ]],
140 [ 'OS2Warp45', 'OS2Warp45', g_k32 | g_kiNoRaw, 1, 1, ['os2.*', 'acp.*','mcp.*', ]], # smp does busy spinning and unattended installer only does UNI at the momen.
141 [ 'Solaris', 'Solaris', g_k32, 1, 256, ['sol10', 'sol10u[0-9]']],
142 [ 'Solaris_64', 'Solaris_64', g_k64, 1, 256, ['sol10-64', 'sol10u-64[0-9]']],
143 [ 'Solaris_64', 'Solaris11_64', g_k64, 1, 256, ['sol11u1']],
144 [ 'BSD', 'FreeBSD_64', g_k32_64, 1, 1, ['bs-.*']], # boot sectors, wanted 64-bit type.
145 [ 'DOS', 'DOS', g_k32, 1, 1, ['bs-.*']],
146];
147
148
149## @name Guest OS type string constants.
150## @{
151g_ksGuestOsTypeDarwin = 'darwin';
152g_ksGuestOsTypeDOS = 'dos';
153g_ksGuestOsTypeFreeBSD = 'freebsd';
154g_ksGuestOsTypeLinux = 'linux';
155g_ksGuestOsTypeOS2 = 'os2';
156g_ksGuestOsTypeSolaris = 'solaris';
157g_ksGuestOsTypeWindows = 'windows';
158## @}
159
160## @name String constants for paravirtualization providers.
161## @{
162g_ksParavirtProviderNone = 'none';
163g_ksParavirtProviderDefault = 'default';
164g_ksParavirtProviderLegacy = 'legacy';
165g_ksParavirtProviderMinimal = 'minimal';
166g_ksParavirtProviderHyperV = 'hyperv';
167g_ksParavirtProviderKVM = 'kvm';
168## @}
169
170## Valid paravirtualization providers.
171g_kasParavirtProviders = ( g_ksParavirtProviderNone, g_ksParavirtProviderDefault, g_ksParavirtProviderLegacy,
172 g_ksParavirtProviderMinimal, g_ksParavirtProviderHyperV, g_ksParavirtProviderKVM );
173
174# Mapping for support of paravirtualisation providers per guest OS.
175#g_kdaParavirtProvidersSupported = {
176# g_ksGuestOsTypeDarwin : ( g_ksParavirtProviderMinimal, ),
177# g_ksGuestOsTypeFreeBSD : ( g_ksParavirtProviderNone, g_ksParavirtProviderMinimal, ),
178# g_ksGuestOsTypeLinux : ( g_ksParavirtProviderNone, g_ksParavirtProviderMinimal, g_ksParavirtProviderHyperV, g_ksParavirtProviderKVM),
179# g_ksGuestOsTypeOS2 : ( g_ksParavirtProviderNone, ),
180# g_ksGuestOsTypeSolaris : ( g_ksParavirtProviderNone, ),
181# g_ksGuestOsTypeWindows : ( g_ksParavirtProviderNone, g_ksParavirtProviderMinimal, g_ksParavirtProviderHyperV, )
182#}
183# Temporary tweak:
184# since for the most guests g_ksParavirtProviderNone is almost the same as g_ksParavirtProviderMinimal,
185# g_ksParavirtProviderMinimal is removed from the list in order to get maximum number of unique choices
186# during independent test runs when paravirt provider is taken randomly.
187g_kdaParavirtProvidersSupported = {
188 g_ksGuestOsTypeDarwin : ( g_ksParavirtProviderMinimal, ),
189 g_ksGuestOsTypeDOS : ( g_ksParavirtProviderNone, ),
190 g_ksGuestOsTypeFreeBSD : ( g_ksParavirtProviderNone, ),
191 g_ksGuestOsTypeLinux : ( g_ksParavirtProviderNone, g_ksParavirtProviderHyperV, g_ksParavirtProviderKVM),
192 g_ksGuestOsTypeOS2 : ( g_ksParavirtProviderNone, ),
193 g_ksGuestOsTypeSolaris : ( g_ksParavirtProviderNone, ),
194 g_ksGuestOsTypeWindows : ( g_ksParavirtProviderNone, g_ksParavirtProviderHyperV, )
195}
196
197
198# pylint: enable=line-too-long
199
200def _intersects(asSet1, asSet2):
201 """
202 Checks if any of the strings in set 1 matches any of the regular
203 expressions in set 2.
204 """
205 for sStr1 in asSet1:
206 for sRx2 in asSet2:
207 if re.match(sStr1, sRx2 + '$'):
208 return True;
209 return False;
210
211
212
213class BaseTestVm(object):
214 """
215 Base class for Test VMs.
216 """
217
218 def __init__(self, # pylint: disable=too-many-arguments
219 sVmName, # type: str
220 fGrouping = 0, # type: int
221 oSet = None, # type: TestVmSet
222 sKind = None, # type: str
223 acCpusSup = None, # type: List[int]
224 asVirtModesSup = None, # type: List[str]
225 asParavirtModesSup = None, # type: List[str]
226 fRandomPvPModeCrap = False, # type: bool
227 fVmmDevTestingPart = None, # type: bool
228 fVmmDevTestingMmio = False, # type: bool
229 iGroup = 1, # type: int
230 ):
231 self.oSet = oSet # type: TestVmSet
232 self.sVmName = sVmName;
233 self.iGroup = iGroup; # Startup group (for MAC address uniqueness and non-NAT networking).
234 self.fGrouping = fGrouping;
235 self.sKind = sKind; # API Guest OS type.
236 self.acCpusSup = acCpusSup;
237 self.asVirtModesSup = asVirtModesSup;
238 self.asParavirtModesSup = asParavirtModesSup;
239 self.asParavirtModesSupOrg = asParavirtModesSup; # HACK ALERT! Trick to make the 'effing random mess not get in the
240 # way of actively selecting virtualization modes.
241
242 self.fSkip = False; # All VMs are included in the configured set by default.
243 self.fSnapshotRestoreCurrent = False; # Whether to restore execution on the current snapshot.
244
245 # VMMDev and serial (TXS++) settings:
246 self.fVmmDevTestingPart = fVmmDevTestingPart;
247 self.fVmmDevTestingMmio = fVmmDevTestingMmio;
248 self.fCom1RawFile = False;
249
250 # Cached stuff (use getters):
251 self.__sCom1RawFile = None; # Set by createVmInner and getReconfiguredVm if fCom1RawFile is set.
252 self.__tHddCtrlPortDev = (None, None, None); # The HDD controller, port and device.
253 self.__tDvdCtrlPortDev = (None, None, None); # The DVD controller, port and device.
254 self.__cbHdd = -1; # The recommended HDD size.
255
256 # Derived stuff:
257 self.aInfo = None;
258 self.sGuestOsType = None; # ksGuestOsTypeXxxx value, API GuestOS Type is in the sKind member.
259 ## @todo rename sGuestOsType
260 self._guessStuff(fRandomPvPModeCrap);
261
262 def _mkCanonicalGuestOSType(self, sType):
263 """
264 Convert guest OS type into constant representation.
265 Raise exception if specified @param sType is unknown.
266 """
267 if sType.lower().startswith('darwin'):
268 return g_ksGuestOsTypeDarwin
269 if sType.lower().startswith('bsd'):
270 return g_ksGuestOsTypeFreeBSD
271 if sType.lower().startswith('dos'):
272 return g_ksGuestOsTypeDOS
273 if sType.lower().startswith('linux'):
274 return g_ksGuestOsTypeLinux
275 if sType.lower().startswith('os2'):
276 return g_ksGuestOsTypeOS2
277 if sType.lower().startswith('solaris'):
278 return g_ksGuestOsTypeSolaris
279 if sType.lower().startswith('windows'):
280 return g_ksGuestOsTypeWindows
281 raise base.GenError(sWhat="unknown guest OS kind: %s" % str(sType))
282
283 def _guessStuff(self, fRandomPvPModeCrap):
284 """
285 Used by the constructor to guess stuff.
286 """
287
288 sNm = self.sVmName.lower().strip();
289 asSplit = sNm.replace('-', ' ').split(' ');
290
291 if self.sKind is None:
292 # From name.
293 for aInfo in g_aaNameToDetails:
294 if _intersects(asSplit, aInfo[g_iRegEx]):
295 self.aInfo = aInfo;
296 self.sGuestOsType = self._mkCanonicalGuestOSType(aInfo[g_iGuestOsType])
297 self.sKind = aInfo[g_iKind];
298 break;
299 if self.sKind is None:
300 reporter.fatal('The OS of test VM "%s" cannot be guessed' % (self.sVmName,));
301
302 # Check for 64-bit, if required and supported.
303 if (self.aInfo[g_iFlags] & g_kiArchMask) == g_k32_64 and _intersects(asSplit, ['64', 'amd64']):
304 self.sKind = self.sKind + '_64';
305 else:
306 # Lookup the kind.
307 for aInfo in g_aaNameToDetails:
308 if self.sKind == aInfo[g_iKind]:
309 self.aInfo = aInfo;
310 break;
311 if self.aInfo is None:
312 reporter.fatal('The OS of test VM "%s" with sKind="%s" cannot be guessed' % (self.sVmName, self.sKind));
313
314 # Translate sKind into sGuest OS Type.
315 if self.sGuestOsType is None:
316 if self.aInfo is not None:
317 self.sGuestOsType = self._mkCanonicalGuestOSType(self.aInfo[g_iGuestOsType])
318 elif self.sKind.find("Windows") >= 0:
319 self.sGuestOsType = g_ksGuestOsTypeWindows
320 elif self.sKind.find("Linux") >= 0:
321 self.sGuestOsType = g_ksGuestOsTypeLinux;
322 elif self.sKind.find("Solaris") >= 0:
323 self.sGuestOsType = g_ksGuestOsTypeSolaris;
324 elif self.sKind.find("DOS") >= 0:
325 self.sGuestOsType = g_ksGuestOsTypeDOS;
326 else:
327 reporter.fatal('The OS of test VM "%s", sKind="%s" cannot be guessed' % (self.sVmName, self.sKind));
328
329 # Restrict modes and such depending on the OS.
330 if self.asVirtModesSup is None:
331 self.asVirtModesSup = list(g_asVirtModes);
332 if self.sGuestOsType in (g_ksGuestOsTypeOS2, g_ksGuestOsTypeDarwin) \
333 or self.sKind.find('_64') > 0 \
334 or (self.aInfo is not None and (self.aInfo[g_iFlags] & g_kiNoRaw)):
335 self.asVirtModesSup = [sVirtMode for sVirtMode in self.asVirtModesSup if sVirtMode != 'raw'];
336 # TEMPORARY HACK - START
337 sHostName = os.environ.get("COMPUTERNAME", None);
338 if sHostName: sHostName = sHostName.lower();
339 else: sHostName = socket.getfqdn(); # Horribly slow on windows without IPv6 DNS/whatever.
340 if sHostName.startswith('testboxpile1'):
341 self.asVirtModesSup = [sVirtMode for sVirtMode in self.asVirtModesSup if sVirtMode != 'raw'];
342 # TEMPORARY HACK - END
343
344 # Restrict the CPU count depending on the OS and/or percieved SMP readiness.
345 if self.acCpusSup is None:
346 if _intersects(asSplit, ['uni']):
347 self.acCpusSup = [1];
348 elif self.aInfo is not None:
349 self.acCpusSup = list(range(self.aInfo[g_iMinCpu], self.aInfo[g_iMaxCpu] + 1));
350 else:
351 self.acCpusSup = [1];
352
353 # Figure relevant PV modes based on the OS.
354 if self.asParavirtModesSup is None:
355 self.asParavirtModesSup = g_kdaParavirtProvidersSupported[self.sGuestOsType];
356 ## @todo Remove this hack as soon as we've got around to explictly configure test variations
357 ## on the server side. Client side random is interesting but not the best option.
358 self.asParavirtModesSupOrg = self.asParavirtModesSup;
359 if fRandomPvPModeCrap:
360 random.seed();
361 self.asParavirtModesSup = (random.choice(self.asParavirtModesSup),);
362
363 return True;
364
365 def _generateRawPortFilename(self, oTestDrv, sInfix, sSuffix):
366 """ Generates a raw port filename. """
367 random.seed();
368 sRandom = ''.join(random.choice(string.ascii_lowercase + string.digits) for _ in range(10));
369 return os.path.join(oTestDrv.sScratchPath, self.sVmName + sInfix + sRandom + sSuffix);
370
371 def _createVmPre(self, oTestDrv, eNic0AttachType, sDvdImage):
372 """
373 Prepares for creating the VM.
374
375 Returns True / False.
376 """
377 _ = eNic0AttachType; _ = sDvdImage;
378 if self.fCom1RawFile:
379 self.__sCom1RawFile = self._generateRawPortFilename(oTestDrv, '-com1-', '.out');
380 return True;
381
382 def _createVmDoIt(self, oTestDrv, eNic0AttachType, sDvdImage):
383 """
384 Creates the VM.
385
386 The default implementation creates a VM with defaults, no disks created or attached.
387
388 Returns Wrapped VM object on success, None on failure.
389 """
390 return oTestDrv.createTestVmWithDefaults(self.sVmName,
391 iGroup = self.iGroup,
392 sKind = self.sKind,
393 eNic0AttachType = eNic0AttachType,
394 sDvdImage = sDvdImage,
395 fVmmDevTestingPart = self.fVmmDevTestingPart,
396 fVmmDevTestingMmio = self.fVmmDevTestingMmio,
397 sCom1RawFile = self.__sCom1RawFile if self.fCom1RawFile else None
398 );
399
400 def _createVmPost(self, oTestDrv, oVM, eNic0AttachType, sDvdImage): # type: (base.testdriver, Any, int, str) -> Any
401 """
402 Returns same oVM on success, None on failure (createVm cleans up).
403 """
404 _ = oTestDrv; _ = eNic0AttachType; _ = sDvdImage;
405 return oVM;
406
407 def _skipVmTest(self, oTestDrv, oVM):
408 """
409 Called by getReconfiguredVm to figure out whether to skip the VM or not.
410
411 Returns True if the VM should be skipped, False otherwise.
412 """
413 _ = oVM;
414 fHostSupports64bit = oTestDrv.hasHostLongMode();
415 if self.is64bitRequired() and not fHostSupports64bit:
416 reporter.log('Skipping 64-bit VM on non-64 capable host.');
417 elif self.isViaIncompatible() and oTestDrv.isHostCpuVia():
418 reporter.log('Skipping VIA incompatible VM.');
419 elif self.isShanghaiIncompatible() and oTestDrv.isHostCpuShanghai():
420 reporter.log('Skipping Shanghai (Zhaoxin) incompatible VM.');
421 elif self.isP4Incompatible() and oTestDrv.isHostCpuP4():
422 reporter.log('Skipping P4 incompatible VM.');
423 else:
424 return False;
425 return True;
426
427
428 def _childVmReconfig(self, oTestDrv, oVM, oSession):
429 """
430 Hook into getReconfiguredVm() for children.
431 """
432 _ = oTestDrv; _ = oVM; _ = oSession;
433 return True;
434
435 def _storageCtrlAndBusToName(self, oVBoxMgr, oVM, eCtrl, eBus):
436 """
437 Resolves the storage controller name given type and bus.
438
439 Returns String on success, None on failure w/ errors logged.
440 """
441 try:
442 aoControllers = oVBoxMgr.getArray(oVM, 'storageControllers');
443 except:
444 reporter.errorXcpt();
445 return None;
446 asSummary = [];
447 for oController in aoControllers:
448 try:
449 eCurCtrl = oController.controllerType;
450 eCurBus = oController.bus;
451 sName = oController.name;
452 except:
453 reporter.errorXcpt();
454 return None;
455 if eCurCtrl == eCtrl and eCurBus == eBus:
456 return sName;
457 asSummary.append('%s-%s-%s' % (eCurCtrl, eCurBus, sName,));
458 reporter.error('Unable to find controller of type %s and bus %s (searched: %s)' % (eCtrl, eBus, ', '.join(asSummary),));
459 return None;
460
461
462 #
463 # Public interface.
464 #
465
466 def getResourceSet(self):
467 """
468 Returns a list of resources that the VM needs.
469 """
470 return [];
471
472 def getMissingResources(self, sResourcePath):
473 """
474 Returns a list of missing resources (paths, stuff) that the VM needs.
475 """
476 asRet = [];
477 asResources = self.getResourceSet();
478 for sPath in asResources:
479 if not os.path.isabs(sPath):
480 sPath = os.path.join(sResourcePath, sPath);
481 if not os.path.exists(sPath):
482 asRet.append(sPath);
483 return asRet;
484
485 def skipCreatingVm(self, oTestDrv):
486 """
487 Called before VM creation to determine whether the VM should be skipped
488 due to host incompatibility or something along those lines.
489
490 returns True if it should be skipped, False if not. Caller updates fSkip.
491
492 See also _skipVmTest().
493 """
494 _ = oTestDrv;
495 return False;
496
497
498 def createVm(self, oTestDrv, eNic0AttachType = None, sDvdImage = None):
499 """
500 Creates the VM with defaults and the few tweaks as per the arguments.
501
502 Returns same as vbox.TestDriver.createTestVM.
503 """
504 reporter.log2('');
505 reporter.log2('Creating %s...' % (self.sVmName,))
506 oVM = None;
507 fRc = self._createVmPre(oTestDrv, eNic0AttachType, sDvdImage);
508 if fRc is True:
509 oVM = self._createVmDoIt(oTestDrv, eNic0AttachType, sDvdImage);
510 if oVM:
511 oVM = self._createVmPost(oTestDrv, oVM, eNic0AttachType, sDvdImage);
512 return oVM;
513
514 def getReconfiguredVm(self, oTestDrv, cCpus, sVirtMode, sParavirtMode = None):
515 """
516 actionExecute worker that finds and reconfigure a test VM.
517
518 Returns (fRc, oVM) where fRc is True, None or False and oVM is a
519 VBox VM object that is only present when rc is True.
520 """
521
522 fRc = False;
523 oVM = oTestDrv.getVmByName(self.sVmName);
524 if oVM is not None:
525 if self.fSnapshotRestoreCurrent is True:
526 fRc = True;
527 else:
528 fHostSupports64bit = oTestDrv.hasHostLongMode();
529 if self._skipVmTest(oTestDrv, oVM):
530 fRc = None; # Skip the test.
531 else:
532 oSession = oTestDrv.openSession(oVM);
533 if oSession is not None:
534 fRc = oSession.enableVirtEx(sVirtMode != 'raw');
535 fRc = fRc and oSession.enableNestedPaging(sVirtMode == 'hwvirt-np');
536 fRc = fRc and oSession.setCpuCount(cCpus);
537 if cCpus > 1:
538 fRc = fRc and oSession.enableIoApic(True);
539
540 if sParavirtMode is not None and oSession.fpApiVer >= 5.0:
541 adParavirtProviders = {
542 g_ksParavirtProviderNone : vboxcon.ParavirtProvider_None,
543 g_ksParavirtProviderDefault: vboxcon.ParavirtProvider_Default,
544 g_ksParavirtProviderLegacy : vboxcon.ParavirtProvider_Legacy,
545 g_ksParavirtProviderMinimal: vboxcon.ParavirtProvider_Minimal,
546 g_ksParavirtProviderHyperV : vboxcon.ParavirtProvider_HyperV,
547 g_ksParavirtProviderKVM : vboxcon.ParavirtProvider_KVM,
548 };
549 fRc = fRc and oSession.setParavirtProvider(adParavirtProviders[sParavirtMode]);
550
551 fCfg64Bit = self.is64bitRequired() or (self.is64bit() and fHostSupports64bit and sVirtMode != 'raw');
552 fRc = fRc and oSession.enableLongMode(fCfg64Bit);
553 if fCfg64Bit: # This is to avoid GUI pedantic warnings in the GUI. Sigh.
554 oOsType = oSession.getOsType();
555 if oOsType is not None:
556 if oOsType.is64Bit and sVirtMode == 'raw':
557 assert(oOsType.id[-3:] == '_64');
558 fRc = fRc and oSession.setOsType(oOsType.id[:-3]);
559 elif not oOsType.is64Bit and sVirtMode != 'raw':
560 fRc = fRc and oSession.setOsType(oOsType.id + '_64');
561
562 # New serial raw file.
563 if fRc and self.fCom1RawFile:
564 self.__sCom1RawFile = self._generateRawPortFilename(oTestDrv, '-com1-', '.out');
565 utils.noxcptDeleteFile(self.__sCom1RawFile);
566 fRc = oSession.setupSerialToRawFile(0, self.__sCom1RawFile);
567
568 # Make life simpler for child classes.
569 if fRc:
570 fRc = self._childVmReconfig(oTestDrv, oVM, oSession);
571
572 fRc = fRc and oSession.saveSettings();
573 if not oSession.close():
574 fRc = False;
575 if fRc is True:
576 return (True, oVM);
577 return (fRc, None);
578
579 def getNonCanonicalGuestOsType(self):
580 """
581 Gets the non-canonical OS type (self.sGuestOsType is canonical).
582 """
583 return self.sKind; #self.aInfo[g_iGuestOsType];
584
585 def getGuestArch(self):
586 """ Same as util.getHostArch. """
587 return 'amd64' if self.sKind.find('_64') >= 0 else 'x86';
588
589 def getGuestOs(self):
590 """ Same as util.getHostOs. """
591 if self.isWindows(): return 'win';
592 if self.isOS2(): return 'os2';
593 if self.isLinux(): return 'linux';
594 reporter.error('getGuestOs does not what to return!');
595 raise Exception();
596
597 def getGuestOsDotArch(self):
598 """ Same as util.getHostOsDotArch. """
599 return self.getGuestOs() + '.' + self.getGuestArch();
600
601 def getGuestExeSuff(self):
602 """ The executable image suffix for the guest. """
603 if self.isWindows() or self.isOS2():
604 return '.exe';
605 return '';
606
607 def isWindows(self):
608 """ Checks if it's a Windows VM. """
609 return self.sGuestOsType == g_ksGuestOsTypeWindows;
610
611 def isOS2(self):
612 """ Checks if it's an OS/2 VM. """
613 return self.sGuestOsType == g_ksGuestOsTypeOS2;
614
615 def isLinux(self):
616 """ Checks if it's an Linux VM. """
617 return self.sGuestOsType == g_ksGuestOsTypeLinux;
618
619 def is64bit(self):
620 """ Checks if it's a 64-bit VM. """
621 return self.sKind.find('_64') >= 0;
622
623 def is64bitRequired(self):
624 """ Check if 64-bit is required or not. """
625 return (self.aInfo[g_iFlags] & g_k64) != 0;
626
627 def isLoggedOntoDesktop(self):
628 """ Checks if the test VM is logging onto a graphical desktop by default. """
629 if self.isWindows():
630 return True;
631 if self.isOS2():
632 return True;
633 if self.sVmName.find('-desktop'):
634 return True;
635 return False;
636
637 def isViaIncompatible(self):
638 """
639 Identifies VMs that doesn't work on VIA.
640
641 Returns True if NOT supported on VIA, False if it IS supported.
642 """
643 # Oracle linux doesn't like VIA in our experience
644 if self.aInfo[g_iKind] in ['Oracle', 'Oracle_64']:
645 return True;
646 # OS/2: "The system detected an internal processing error at location
647 # 0168:fff1da1f - 000e:ca1f. 0a8606fd
648 if self.isOS2():
649 return True;
650 # Windows NT4 before SP4 won't work because of cmpxchg8b not being
651 # detected, leading to a STOP 3e(80,0,0,0).
652 if self.aInfo[g_iKind] == 'WindowsNT4':
653 if self.sVmName.find('sp') < 0:
654 return True; # no service pack.
655 if self.sVmName.find('sp0') >= 0 \
656 or self.sVmName.find('sp1') >= 0 \
657 or self.sVmName.find('sp2') >= 0 \
658 or self.sVmName.find('sp3') >= 0:
659 return True;
660 # XP x64 on a physical VIA box hangs exactly like a VM.
661 if self.aInfo[g_iKind] in ['WindowsXP_64', 'Windows2003_64']:
662 return True;
663 # Vista 64 throws BSOD 0x5D (UNSUPPORTED_PROCESSOR)
664 if self.aInfo[g_iKind] in ['WindowsVista_64']:
665 return True;
666 # Solaris 11 hangs on VIA, tested on a physical box (testboxvqc)
667 if self.aInfo[g_iKind] in ['Solaris11_64']:
668 return True;
669 return False;
670
671 def isShanghaiIncompatible(self):
672 """
673 Identifies VMs that doesn't work on Shanghai.
674
675 Returns True if NOT supported on Shanghai, False if it IS supported.
676 """
677 # For now treat it just like VIA, to be adjusted later
678 return self.isViaIncompatible()
679
680 def isP4Incompatible(self):
681 """
682 Identifies VMs that doesn't work on Pentium 4 / Pentium D.
683
684 Returns True if NOT supported on P4, False if it IS supported.
685 """
686 # Stupid 1 kHz timer. Too much for antique CPUs.
687 if self.sVmName.find('rhel5') >= 0:
688 return True;
689 # Due to the boot animation the VM takes forever to boot.
690 if self.aInfo[g_iKind] == 'Windows2000':
691 return True;
692 return False;
693
694 def isHostCpuAffectedByUbuntuNewAmdBug(self, oTestDrv):
695 """
696 Checks if the host OS is affected by older ubuntu installers being very
697 picky about which families of AMD CPUs it would run on.
698
699 The installer checks for family 15, later 16, later 20, and in 11.10
700 they remove the family check for AMD CPUs.
701 """
702 if not oTestDrv.isHostCpuAmd():
703 return False;
704 try:
705 (uMaxExt, _, _, _) = oTestDrv.oVBox.host.getProcessorCPUIDLeaf(0, 0x80000000, 0);
706 (uFamilyModel, _, _, _) = oTestDrv.oVBox.host.getProcessorCPUIDLeaf(0, 0x80000001, 0);
707 except:
708 reporter.logXcpt();
709 return False;
710 if uMaxExt < 0x80000001 or uMaxExt > 0x8000ffff:
711 return False;
712
713 uFamily = (uFamilyModel >> 8) & 0xf
714 if uFamily == 0xf:
715 uFamily = ((uFamilyModel >> 20) & 0x7f) + 0xf;
716 ## @todo Break this down into which old ubuntu release supports exactly
717 ## which AMD family, if we care.
718 if uFamily <= 15:
719 return False;
720 reporter.log('Skipping "%s" because host CPU is a family %u AMD, which may cause trouble for the guest OS installer.'
721 % (self.sVmName, uFamily,));
722 return True;
723
724 def getTestUser(self):
725 """
726 Gets the primary test user name.
727 """
728 if self.isWindows():
729 return 'Administrator';
730 return 'vbox';
731
732 def getTestUserPassword(self, sUser = None):
733 """
734 Gets the password for the primary user (or other specified one).
735 """
736 if sUser == 'test':
737 return '';
738 if sUser == 'vboxuser': # Default unattended installation user and password.
739 return 'changeme';
740 return 'password';
741
742 def getCom1RawFile(self, oVM):
743 """
744 Gets the name of the COM1 raw file.
745
746 Returns string, None on failure or if not active.
747
748 Note! Do not access __sCom1RawFile directly as it will not be set unless the
749 'config' action was executed in the same run.
750 """
751 if self.fCom1RawFile:
752 # Retrieve it from the IMachine object and cache the result if needed:
753 if self.__sCom1RawFile is None:
754 try:
755 oPort = oVM.machine.getSerialPort(0);
756 except:
757 reporter.errorXcpt('failed to get serial port #0');
758 else:
759 try:
760 self.__sCom1RawFile = oPort.path;
761 except:
762 reporter.errorXcpt('failed to get the "path" property on serial port #0');
763 return self.__sCom1RawFile;
764
765 reporter.error('getCom1RawFile called when fCom1RawFile is False');
766 return None;
767
768 def getIGuestOSType(self, oVBoxWrapped):
769 """
770 Gets the IGuestOSType object corresponding to self.sKind.
771
772 Returns object on success, None on failure (logged as error).
773 """
774 try:
775 return oVBoxWrapped.o.getGuestOSType(self.sKind);
776 except:
777 reporter.errorXcpt('sVmName=%s sKind=%s' % (self.sVmName, self.sKind,));
778 return None;
779
780 def getRecommendedHddSize(self, oVBoxWrapped):
781 """
782 Gets the recommended HDD size from the IGuestOSType matching self.sKind.
783
784 Returns size in bytes on success, -1 on failure.
785 """
786 if self.__cbHdd < 0:
787 oGuestOSType = self.getIGuestOSType(oVBoxWrapped);
788 if oGuestOSType:
789 try:
790 self.__cbHdd = oGuestOSType.recommendedHDD;
791 except:
792 reporter.errorXcpt();
793 return -1;
794 return self.__cbHdd;
795
796 def getHddAddress(self, oVM, oVBoxWrapped):
797 """
798 Gets the HDD attachment address.
799
800 Returns (sController, iPort, iDevice) on success; (None, None, None) on failure.
801
802 Note! Do not access the cached value directly!
803 """
804 # Cached already?
805 if self.__tHddCtrlPortDev[0] is not None:
806 return self.__tHddCtrlPortDev;
807
808 # First look for HDs attached to the VM:
809 try:
810 aoAttachments = oVBoxWrapped.oVBoxMgr.getArray(oVM, 'mediumAttachments')
811 except:
812 reporter.errorXcpt();
813 else:
814 for oAtt in aoAttachments:
815 try:
816 sCtrl = oAtt.controller
817 iPort = oAtt.port;
818 iDev = oAtt.device;
819 eType = oAtt.type;
820 except:
821 reporter.errorXcpt();
822 return self.__tHddCtrlPortDev;
823 if eType == vboxcon.DeviceType_HardDisk:
824 self.__tHddCtrlPortDev = (sCtrl, iPort, iDev);
825 reporter.log2('getHddAddress: %s, %s, %s' % self.__tHddCtrlPortDev);
826 return self.__tHddCtrlPortDev;
827
828 # Then consult IGuestOSType:
829 oGuestOSType = self.getIGuestOSType(oVBoxWrapped);
830 if oGuestOSType:
831 try:
832 eCtrl = oGuestOSType.recommendedHDStorageController;
833 eBus = oGuestOSType.recommendedHDStorageBus;
834 except:
835 reporter.errorXcpt();
836 else:
837 # ASSUMES port 0, device 0.
838 self.__tHddCtrlPortDev = (self._storageCtrlAndBusToName(oVBoxWrapped.oVBoxMgr, oVM, eCtrl, eBus), 0, 0);
839 reporter.log2('getHddAddress: %s, %s, %s [IGuestOSType]' % self.__tHddCtrlPortDev);
840 return self.__tHddCtrlPortDev;
841
842 def getDvdAddress(self, oVM, oVBoxWrapped):
843 """
844 Gets the DVD attachment address.
845
846 Returns (sController, iPort, iDevice) on success; (None, None, None) on failure.
847
848 Note! Do not access the cached value directly!
849 """
850 # Cached already?
851 if self.__tDvdCtrlPortDev[0] is not None:
852 return self.__tDvdCtrlPortDev;
853
854 # First look for DVD attached to the VM:
855 try:
856 aoAttachments = oVBoxWrapped.oVBoxMgr.getArray(oVM, 'mediumAttachments')
857 except:
858 reporter.errorXcpt();
859 else:
860 for oAtt in aoAttachments:
861 try:
862 sCtrl = oAtt.controller
863 iPort = oAtt.port;
864 iDev = oAtt.device;
865 eType = oAtt.type;
866 except:
867 reporter.errorXcpt();
868 return self.__tDvdCtrlPortDev;
869 if eType == vboxcon.DeviceType_DVD:
870 self.__tDvdCtrlPortDev = (sCtrl, iPort, iDev);
871 reporter.log2('getDvdAddress: %s, %s, %s' % self.__tDvdCtrlPortDev);
872 return self.__tDvdCtrlPortDev;
873
874 # Then consult IGuestOSType:
875 oGuestOSType = self.getIGuestOSType(oVBoxWrapped);
876 if oGuestOSType:
877 try:
878 eCtrl = oGuestOSType.recommendedDVDStorageController;
879 eBus = oGuestOSType.recommendedDVDStorageBus;
880 except:
881 reporter.errorXcpt();
882 else:
883 # ASSUMES port 1, device 0.
884 self.__tDvdCtrlPortDev = (self._storageCtrlAndBusToName(oVBoxWrapped.oVBoxMgr, oVM, eCtrl, eBus), 1, 0);
885 reporter.log2('getDvdAddress: %s, %s, %s [IGuestOSType]' % self.__tDvdCtrlPortDev);
886 return self.__tDvdCtrlPortDev;
887
888 def recreateRecommendedHdd(self, oVM, oTestDrv, sHddPath = None):
889 """
890 Detaches and delete any current hard disk and then ensures that a new
891 one with the recommended size is created and attached to the recommended
892 controller/port/device.
893
894 Returns True/False (errors logged).
895 """
896 # Generate a name if none was given:
897 if not sHddPath:
898 try:
899 sHddPath = oVM.settingsFilePath;
900 except:
901 return reporter.errorXcpt();
902 sHddPath = os.path.join(os.path.dirname(sHddPath), '%s-%s.vdi' % (self.sVmName, uuid.uuid4(),));
903
904 fRc = False;
905
906 # Get the hard disk specs first:
907 cbHdd = self.getRecommendedHddSize(oTestDrv.oVBox);
908 tHddAddress = self.getHddAddress(oVM, oTestDrv.oVBox);
909 assert len(tHddAddress) == 3;
910 if tHddAddress[0] and cbHdd > 0:
911 # Open an session so we can make changes:
912 oSession = oTestDrv.openSession(oVM);
913 if oSession is not None:
914 # Detach the old disk (this will succeed with oOldHd set to None the first time around).
915 (fRc, oOldHd) = oSession.detachHd(tHddAddress[0], tHddAddress[1], tHddAddress[2]);
916 if fRc:
917 # Create a new disk and attach it.
918 fRc = oSession.createAndAttachHd(sHddPath,
919 cb = cbHdd,
920 sController = tHddAddress[0],
921 iPort = tHddAddress[1],
922 iDevice = tHddAddress[2],
923 fImmutable = False);
924 if fRc:
925 # Save the changes.
926 fRc = oSession.saveSettings();
927
928 # Delete the old HD:
929 if fRc and oOldHd is not None:
930 fRc = fRc and oTestDrv.oVBox.deleteHdByMedium(oOldHd);
931 fRc = fRc and oSession.saveSettings(); # Necessary for media reg??
932 else:
933 oSession.discardSettings();
934 fRc = oSession.close() and fRc;
935 return fRc;
936
937 def pathJoin(self, sBase, *asAppend):
938 """ See common.pathutils.joinEx(). """
939 return pathutils.joinEx(self.isWindows() or self.isOS2(), sBase, *asAppend);
940
941 def pathSep(self):
942 """ Returns the preferred paths separator for the guest OS. """
943 return '\\' if self.isWindows() or self.isOS2() else '/';
944
945
946## @todo Inherit from BaseTestVm
947class TestVm(object):
948 """
949 A Test VM - name + VDI/whatever.
950
951 This is just a data object.
952 """
953
954 def __init__(self, # pylint: disable=too-many-arguments
955 sVmName, # type: str
956 fGrouping = 0, # type: int
957 oSet = None, # type: TestVmSet
958 sHd = None, # type: str
959 sKind = None, # type: str
960 acCpusSup = None, # type: List[int]
961 asVirtModesSup = None, # type: List[str]
962 fIoApic = None, # type: bool
963 fNstHwVirt = False, # type: bool
964 fPae = None, # type: bool
965 sNic0AttachType = None, # type: str
966 sFloppy = None, # type: str
967 fVmmDevTestingPart = None, # type: bool
968 fVmmDevTestingMmio = False, # type: bool
969 asParavirtModesSup = None, # type: List[str]
970 fRandomPvPMode = False, # type: bool
971 sFirmwareType = 'bios', # type: str
972 sChipsetType = 'piix3', # type: str
973 sIommuType = 'none', # type: str
974 sHddControllerType = 'IDE Controller', # type: str
975 sDvdControllerType = 'IDE Controller', # type: str
976 sGraphicsControllerType = None, # type: str
977 fSecureBoot = False, # type: bool
978 sUefiMokPathPrefix = None # type: str
979 ):
980 self.oSet = oSet;
981 self.sVmName = sVmName;
982 self.fGrouping = fGrouping;
983 self.sHd = sHd; # Relative to the testrsrc root.
984 self.acCpusSup = acCpusSup;
985 self.asVirtModesSup = asVirtModesSup;
986 self.asParavirtModesSup = asParavirtModesSup;
987 self.asParavirtModesSupOrg = asParavirtModesSup; # HACK ALERT! Trick to make the 'effing random mess not get in the
988 # way of actively selecting virtualization modes.
989 self.sKind = sKind;
990 self.sGuestOsType = None;
991 self.sDvdImage = None; # Relative to the testrsrc root.
992 self.sDvdControllerType = sDvdControllerType;
993 self.sGraphicsControllerType = sGraphicsControllerType;
994 self.fIoApic = fIoApic;
995 self.fNstHwVirt = fNstHwVirt;
996 self.fPae = fPae;
997 self.sNic0AttachType = sNic0AttachType;
998 self.sHddControllerType = sHddControllerType;
999 self.sFloppy = sFloppy; # Relative to the testrsrc root, except when it isn't...
1000 self.fVmmDevTestingPart = fVmmDevTestingPart;
1001 self.fVmmDevTestingMmio = fVmmDevTestingMmio;
1002 self.sFirmwareType = sFirmwareType;
1003 self.sChipsetType = sChipsetType;
1004 self.sIommuType = sIommuType;
1005 self.fCom1RawFile = False;
1006
1007 self.fSecureBoot = fSecureBoot;
1008 self.sUefiMokPathPrefix = sUefiMokPathPrefix;
1009
1010 self.fSnapshotRestoreCurrent = False; # Whether to restore execution on the current snapshot.
1011 self.fSkip = False; # All VMs are included in the configured set by default.
1012 self.aInfo = None;
1013 self.sCom1RawFile = None; # Set by createVmInner and getReconfiguredVm if fCom1RawFile is set.
1014 self._guessStuff(fRandomPvPMode);
1015
1016 def _mkCanonicalGuestOSType(self, sType):
1017 """
1018 Convert guest OS type into constant representation.
1019 Raise exception if specified @param sType is unknown.
1020 """
1021 if sType.lower().startswith('darwin'):
1022 return g_ksGuestOsTypeDarwin
1023 if sType.lower().startswith('bsd'):
1024 return g_ksGuestOsTypeFreeBSD
1025 if sType.lower().startswith('dos'):
1026 return g_ksGuestOsTypeDOS
1027 if sType.lower().startswith('linux'):
1028 return g_ksGuestOsTypeLinux
1029 if sType.lower().startswith('os2'):
1030 return g_ksGuestOsTypeOS2
1031 if sType.lower().startswith('solaris'):
1032 return g_ksGuestOsTypeSolaris
1033 if sType.lower().startswith('windows'):
1034 return g_ksGuestOsTypeWindows
1035 raise base.GenError(sWhat="unknown guest OS kind: %s" % str(sType))
1036
1037 def _guessStuff(self, fRandomPvPMode):
1038 """
1039 Used by the constructor to guess stuff.
1040 """
1041
1042 sNm = self.sVmName.lower().strip();
1043 asSplit = sNm.replace('-', ' ').split(' ');
1044
1045 if self.sKind is None:
1046 # From name.
1047 for aInfo in g_aaNameToDetails:
1048 if _intersects(asSplit, aInfo[g_iRegEx]):
1049 self.aInfo = aInfo;
1050 self.sGuestOsType = self._mkCanonicalGuestOSType(aInfo[g_iGuestOsType])
1051 self.sKind = aInfo[g_iKind];
1052 break;
1053 if self.sKind is None:
1054 reporter.fatal('The OS of test VM "%s" cannot be guessed' % (self.sVmName,));
1055
1056 # Check for 64-bit, if required and supported.
1057 if (self.aInfo[g_iFlags] & g_kiArchMask) == g_k32_64 and _intersects(asSplit, ['64', 'amd64']):
1058 self.sKind = self.sKind + '_64';
1059 else:
1060 # Lookup the kind.
1061 for aInfo in g_aaNameToDetails:
1062 if self.sKind == aInfo[g_iKind]:
1063 self.aInfo = aInfo;
1064 break;
1065 if self.aInfo is None:
1066 reporter.fatal('The OS of test VM "%s" with sKind="%s" cannot be guessed' % (self.sVmName, self.sKind));
1067
1068 # Translate sKind into sGuest OS Type.
1069 if self.sGuestOsType is None:
1070 if self.aInfo is not None:
1071 self.sGuestOsType = self._mkCanonicalGuestOSType(self.aInfo[g_iGuestOsType])
1072 elif self.sKind.find("Windows") >= 0:
1073 self.sGuestOsType = g_ksGuestOsTypeWindows
1074 elif self.sKind.find("Linux") >= 0:
1075 self.sGuestOsType = g_ksGuestOsTypeLinux;
1076 elif self.sKind.find("Solaris") >= 0:
1077 self.sGuestOsType = g_ksGuestOsTypeSolaris;
1078 elif self.sKind.find("DOS") >= 0:
1079 self.sGuestOsType = g_ksGuestOsTypeDOS;
1080 else:
1081 reporter.fatal('The OS of test VM "%s", sKind="%s" cannot be guessed' % (self.sVmName, self.sKind));
1082
1083 # Restrict modes and such depending on the OS.
1084 if self.asVirtModesSup is None:
1085 self.asVirtModesSup = list(g_asVirtModes);
1086 if self.sGuestOsType in (g_ksGuestOsTypeOS2, g_ksGuestOsTypeDarwin) \
1087 or self.sKind.find('_64') > 0 \
1088 or (self.aInfo is not None and (self.aInfo[g_iFlags] & g_kiNoRaw)):
1089 self.asVirtModesSup = [sVirtMode for sVirtMode in self.asVirtModesSup if sVirtMode != 'raw'];
1090 # TEMPORARY HACK - START
1091 sHostName = os.environ.get("COMPUTERNAME", None);
1092 if sHostName: sHostName = sHostName.lower();
1093 else: sHostName = socket.getfqdn(); # Horribly slow on windows without IPv6 DNS/whatever.
1094 if sHostName.startswith('testboxpile1'):
1095 self.asVirtModesSup = [sVirtMode for sVirtMode in self.asVirtModesSup if sVirtMode != 'raw'];
1096 # TEMPORARY HACK - END
1097
1098 # Restrict the CPU count depending on the OS and/or percieved SMP readiness.
1099 if self.acCpusSup is None:
1100 if _intersects(asSplit, ['uni']):
1101 self.acCpusSup = [1];
1102 elif self.aInfo is not None:
1103 self.acCpusSup = list(range(self.aInfo[g_iMinCpu], self.aInfo[g_iMaxCpu] + 1));
1104 else:
1105 self.acCpusSup = [1];
1106
1107 # Figure relevant PV modes based on the OS.
1108 if self.asParavirtModesSup is None:
1109 self.asParavirtModesSup = g_kdaParavirtProvidersSupported[self.sGuestOsType];
1110 ## @todo Remove this hack as soon as we've got around to explictly configure test variations
1111 ## on the server side. Client side random is interesting but not the best option.
1112 self.asParavirtModesSupOrg = self.asParavirtModesSup;
1113 if fRandomPvPMode:
1114 random.seed();
1115 self.asParavirtModesSup = (random.choice(self.asParavirtModesSup),);
1116
1117 return True;
1118
1119 def getNonCanonicalGuestOsType(self):
1120 """
1121 Gets the non-canonical OS type (self.sGuestOsType is canonical).
1122 """
1123 return self.aInfo[g_iGuestOsType];
1124
1125 def getMissingResources(self, sTestRsrc):
1126 """
1127 Returns a list of missing resources (paths, stuff) that the VM needs.
1128 """
1129 asRet = [];
1130 for sPath in [ self.sHd, self.sDvdImage, self.sFloppy]:
1131 if sPath is not None:
1132 if not os.path.isabs(sPath):
1133 sPath = os.path.join(sTestRsrc, sPath);
1134 if not os.path.exists(sPath):
1135 asRet.append(sPath);
1136 return asRet;
1137
1138 def skipCreatingVm(self, oTestDrv):
1139 """
1140 Called before VM creation to determine whether the VM should be skipped
1141 due to host incompatibility or something along those lines.
1142
1143 returns True if it should be skipped, False if not.
1144 """
1145 if self.fNstHwVirt and not oTestDrv.hasHostNestedHwVirt():
1146 reporter.log('Ignoring VM %s (Nested hardware-virtualization not support on this host).' % (self.sVmName,));
1147 return True;
1148 return False;
1149
1150 def createVm(self, oTestDrv, eNic0AttachType = None, sDvdImage = None):
1151 """
1152 Creates the VM with defaults and the few tweaks as per the arguments.
1153
1154 Returns same as vbox.TestDriver.createTestVM.
1155 """
1156 if sDvdImage is not None:
1157 sMyDvdImage = sDvdImage;
1158 else:
1159 sMyDvdImage = self.sDvdImage;
1160
1161 if eNic0AttachType is not None:
1162 eMyNic0AttachType = eNic0AttachType;
1163 elif self.sNic0AttachType is None:
1164 eMyNic0AttachType = None;
1165 elif self.sNic0AttachType == 'nat':
1166 eMyNic0AttachType = vboxcon.NetworkAttachmentType_NAT;
1167 elif self.sNic0AttachType == 'bridged':
1168 eMyNic0AttachType = vboxcon.NetworkAttachmentType_Bridged;
1169 else:
1170 assert False, self.sNic0AttachType;
1171
1172 return self.createVmInner(oTestDrv, eMyNic0AttachType, sMyDvdImage);
1173
1174 def _generateRawPortFilename(self, oTestDrv, sInfix, sSuffix):
1175 """ Generates a raw port filename. """
1176 random.seed();
1177 sRandom = ''.join(random.choice(string.ascii_lowercase + string.digits) for _ in range(10));
1178 return os.path.join(oTestDrv.sScratchPath, self.sVmName + sInfix + sRandom + sSuffix);
1179
1180 def createVmInner(self, oTestDrv, eNic0AttachType, sDvdImage):
1181 """
1182 Same as createVm but parameters resolved.
1183
1184 Returns same as vbox.TestDriver.createTestVM.
1185 """
1186 reporter.log2('');
1187 reporter.log2('Calling createTestVM on %s...' % (self.sVmName,))
1188 if self.fCom1RawFile:
1189 self.sCom1RawFile = self._generateRawPortFilename(oTestDrv, '-com1-', '.out');
1190 return oTestDrv.createTestVM(self.sVmName,
1191 1, # iGroup
1192 sHd = self.sHd,
1193 sKind = self.sKind,
1194 fIoApic = self.fIoApic,
1195 fNstHwVirt = self.fNstHwVirt,
1196 fPae = self.fPae,
1197 eNic0AttachType = eNic0AttachType,
1198 sDvdImage = sDvdImage,
1199 sDvdControllerType = self.sDvdControllerType,
1200 sHddControllerType = self.sHddControllerType,
1201 sFloppy = self.sFloppy,
1202 fVmmDevTestingPart = self.fVmmDevTestingPart,
1203 fVmmDevTestingMmio = self.fVmmDevTestingMmio,
1204 sFirmwareType = self.sFirmwareType,
1205 sChipsetType = self.sChipsetType,
1206 sIommuType = self.sIommuType,
1207 sCom1RawFile = self.sCom1RawFile if self.fCom1RawFile else None,
1208 fSecureBoot = self.fSecureBoot,
1209 sUefiMokPathPrefix = self.sUefiMokPathPrefix,
1210 eGraphicsControllerType = vboxcon.GraphicsControllerType_VBoxSVGA if self.sGraphicsControllerType == 'VBoxSVGA' else None
1211 );
1212
1213 def getReconfiguredVm(self, oTestDrv, cCpus, sVirtMode, sParavirtMode = None):
1214 """
1215 actionExecute worker that finds and reconfigure a test VM.
1216
1217 Returns (fRc, oVM) where fRc is True, None or False and oVM is a
1218 VBox VM object that is only present when rc is True.
1219 """
1220
1221 fRc = False;
1222 oVM = oTestDrv.getVmByName(self.sVmName);
1223 if oVM is not None:
1224 if self.fSnapshotRestoreCurrent is True:
1225 fRc = True;
1226 else:
1227 fHostSupports64bit = oTestDrv.hasHostLongMode();
1228 if self.is64bitRequired() and not fHostSupports64bit:
1229 fRc = None; # Skip the test.
1230 elif self.isViaIncompatible() and oTestDrv.isHostCpuVia():
1231 fRc = None; # Skip the test.
1232 elif self.isShanghaiIncompatible() and oTestDrv.isHostCpuShanghai():
1233 fRc = None; # Skip the test.
1234 elif self.isP4Incompatible() and oTestDrv.isHostCpuP4():
1235 fRc = None; # Skip the test.
1236 else:
1237 oSession = oTestDrv.openSession(oVM);
1238 if oSession is not None:
1239 fRc = oSession.enableVirtEx(sVirtMode != 'raw');
1240 fRc = fRc and oSession.enableNestedPaging(sVirtMode == 'hwvirt-np');
1241 fRc = fRc and oSession.setCpuCount(cCpus);
1242 if cCpus > 1:
1243 fRc = fRc and oSession.enableIoApic(True);
1244
1245 if sParavirtMode is not None and oSession.fpApiVer >= 5.0:
1246 adParavirtProviders = {
1247 g_ksParavirtProviderNone : vboxcon.ParavirtProvider_None,
1248 g_ksParavirtProviderDefault: vboxcon.ParavirtProvider_Default,
1249 g_ksParavirtProviderLegacy : vboxcon.ParavirtProvider_Legacy,
1250 g_ksParavirtProviderMinimal: vboxcon.ParavirtProvider_Minimal,
1251 g_ksParavirtProviderHyperV : vboxcon.ParavirtProvider_HyperV,
1252 g_ksParavirtProviderKVM : vboxcon.ParavirtProvider_KVM,
1253 };
1254 fRc = fRc and oSession.setParavirtProvider(adParavirtProviders[sParavirtMode]);
1255
1256 fCfg64Bit = self.is64bitRequired() or (self.is64bit() and fHostSupports64bit and sVirtMode != 'raw');
1257 fRc = fRc and oSession.enableLongMode(fCfg64Bit);
1258 if fCfg64Bit: # This is to avoid GUI pedantic warnings in the GUI. Sigh.
1259 oOsType = oSession.getOsType();
1260 if oOsType is not None:
1261 if oOsType.is64Bit and sVirtMode == 'raw':
1262 assert(oOsType.id[-3:] == '_64');
1263 fRc = fRc and oSession.setOsType(oOsType.id[:-3]);
1264 elif not oOsType.is64Bit and sVirtMode != 'raw':
1265 fRc = fRc and oSession.setOsType(oOsType.id + '_64');
1266
1267 # New serial raw file.
1268 if fRc and self.fCom1RawFile:
1269 self.sCom1RawFile = self._generateRawPortFilename(oTestDrv, '-com1-', '.out');
1270 utils.noxcptDeleteFile(self.sCom1RawFile);
1271 fRc = oSession.setupSerialToRawFile(0, self.sCom1RawFile);
1272
1273 # Make life simpler for child classes.
1274 if fRc:
1275 fRc = self._childVmReconfig(oTestDrv, oVM, oSession);
1276
1277 fRc = fRc and oSession.saveSettings();
1278 if not oSession.close():
1279 fRc = False;
1280 if fRc is True:
1281 return (True, oVM);
1282 return (fRc, None);
1283
1284 def _childVmReconfig(self, oTestDrv, oVM, oSession):
1285 """ Hook into getReconfiguredVm() for children. """
1286 _ = oTestDrv; _ = oVM; _ = oSession;
1287 return True;
1288
1289 def getGuestArch(self):
1290 """ Same as util.getHostArch. """
1291 return 'amd64' if self.sKind.find('_64') >= 0 else 'x86';
1292
1293 def getGuestOs(self):
1294 """ Same as util.getHostOs. """
1295 if self.isWindows(): return 'win';
1296 if self.isOS2(): return 'os2';
1297 if self.isLinux(): return 'linux';
1298 reporter.error('getGuestOs does not what to return!');
1299 raise Exception();
1300
1301 def getGuestExeSuff(self):
1302 """ The executable image suffix for the guest. """
1303 if self.isWindows() or self.isOS2():
1304 return '.exe';
1305 return '';
1306
1307 def getGuestOsDotArch(self):
1308 """ Same as util.getHostOsDotArch."""
1309 return self.getGuestOs() + '.' + self.getGuestArch();
1310
1311 def isWindows(self):
1312 """ Checks if it's a Windows VM. """
1313 return self.sGuestOsType == g_ksGuestOsTypeWindows;
1314
1315 def isOS2(self):
1316 """ Checks if it's an OS/2 VM. """
1317 return self.sGuestOsType == g_ksGuestOsTypeOS2;
1318
1319 def isLinux(self):
1320 """ Checks if it's an Linux VM. """
1321 return self.sGuestOsType == g_ksGuestOsTypeLinux;
1322
1323 def is64bit(self):
1324 """ Checks if it's a 64-bit VM. """
1325 return self.sKind.find('_64') >= 0;
1326
1327 def is64bitRequired(self):
1328 """ Check if 64-bit is required or not. """
1329 return (self.aInfo[g_iFlags] & g_k64) != 0;
1330
1331 def isLoggedOntoDesktop(self):
1332 """ Checks if the test VM is logging onto a graphical desktop by default. """
1333 if self.isWindows():
1334 return True;
1335 if self.isOS2():
1336 return True;
1337 if self.sVmName.find('-desktop'):
1338 return True;
1339 return False;
1340
1341 def isViaIncompatible(self):
1342 """
1343 Identifies VMs that doesn't work on VIA.
1344
1345 Returns True if NOT supported on VIA, False if it IS supported.
1346 """
1347 # Oracle linux doesn't like VIA in our experience
1348 if self.aInfo[g_iKind] in ['Oracle', 'Oracle_64']:
1349 return True;
1350 # OS/2: "The system detected an internal processing error at location
1351 # 0168:fff1da1f - 000e:ca1f. 0a8606fd
1352 if self.isOS2():
1353 return True;
1354 # Windows NT4 before SP4 won't work because of cmpxchg8b not being
1355 # detected, leading to a STOP 3e(80,0,0,0).
1356 if self.aInfo[g_iKind] == 'WindowsNT4':
1357 if self.sVmName.find('sp') < 0:
1358 return True; # no service pack.
1359 if self.sVmName.find('sp0') >= 0 \
1360 or self.sVmName.find('sp1') >= 0 \
1361 or self.sVmName.find('sp2') >= 0 \
1362 or self.sVmName.find('sp3') >= 0:
1363 return True;
1364 # XP x64 on a physical VIA box hangs exactly like a VM.
1365 if self.aInfo[g_iKind] in ['WindowsXP_64', 'Windows2003_64']:
1366 return True;
1367 # Vista 64 throws BSOD 0x5D (UNSUPPORTED_PROCESSOR)
1368 if self.aInfo[g_iKind] in ['WindowsVista_64']:
1369 return True;
1370 # Solaris 11 hangs on VIA, tested on a physical box (testboxvqc)
1371 if self.aInfo[g_iKind] in ['Solaris11_64']:
1372 return True;
1373 return False;
1374
1375 def isShanghaiIncompatible(self):
1376 """
1377 Identifies VMs that doesn't work on Shanghai.
1378
1379 Returns True if NOT supported on Shanghai, False if it IS supported.
1380 """
1381 # For now treat it just like VIA, to be adjusted later
1382 return self.isViaIncompatible()
1383
1384 def isP4Incompatible(self):
1385 """
1386 Identifies VMs that doesn't work on Pentium 4 / Pentium D.
1387
1388 Returns True if NOT supported on P4, False if it IS supported.
1389 """
1390 # Stupid 1 kHz timer. Too much for antique CPUs.
1391 if self.sVmName.find('rhel5') >= 0:
1392 return True;
1393 # Due to the boot animation the VM takes forever to boot.
1394 if self.aInfo[g_iKind] == 'Windows2000':
1395 return True;
1396 return False;
1397
1398 def isHostCpuAffectedByUbuntuNewAmdBug(self, oTestDrv):
1399 """
1400 Checks if the host OS is affected by older ubuntu installers being very
1401 picky about which families of AMD CPUs it would run on.
1402
1403 The installer checks for family 15, later 16, later 20, and in 11.10
1404 they remove the family check for AMD CPUs.
1405 """
1406 if not oTestDrv.isHostCpuAmd():
1407 return False;
1408 try:
1409 (uMaxExt, _, _, _) = oTestDrv.oVBox.host.getProcessorCPUIDLeaf(0, 0x80000000, 0);
1410 (uFamilyModel, _, _, _) = oTestDrv.oVBox.host.getProcessorCPUIDLeaf(0, 0x80000001, 0);
1411 except:
1412 reporter.logXcpt();
1413 return False;
1414 if uMaxExt < 0x80000001 or uMaxExt > 0x8000ffff:
1415 return False;
1416
1417 uFamily = (uFamilyModel >> 8) & 0xf
1418 if uFamily == 0xf:
1419 uFamily = ((uFamilyModel >> 20) & 0x7f) + 0xf;
1420 ## @todo Break this down into which old ubuntu release supports exactly
1421 ## which AMD family, if we care.
1422 if uFamily <= 15:
1423 return False;
1424 reporter.log('Skipping "%s" because host CPU is a family %u AMD, which may cause trouble for the guest OS installer.'
1425 % (self.sVmName, uFamily,));
1426 return True;
1427
1428 def getTestUser(self):
1429 """
1430 Gets the primary test user name.
1431 """
1432 if self.isWindows():
1433 return 'Administrator';
1434 return 'vbox';
1435
1436 def getTestUserPassword(self, sUser = None):
1437 """
1438 Gets the password for the primary user (or other specified one).
1439 """
1440 if sUser == 'test':
1441 return '';
1442 if sUser == 'vboxuser': # Default unattended installation user and password.
1443 return 'changeme';
1444 return 'password';
1445
1446 def pathJoin(self, sBase, *asAppend):
1447 """ See common.pathutils.joinEx(). """
1448 return pathutils.joinEx(self.isWindows() or self.isOS2(), sBase, *asAppend);
1449
1450 def pathSep(self):
1451 """ Returns the preferred paths separator for the guest OS. """
1452 return '\\' if self.isWindows() or self.isOS2() else '/';
1453
1454
1455class BootSectorTestVm(TestVm):
1456 """
1457 A Boot Sector Test VM.
1458 """
1459
1460 def __init__(self, oSet, sVmName, sFloppy = None, asVirtModesSup = None, f64BitRequired = False):
1461 self.f64BitRequired = f64BitRequired;
1462 if asVirtModesSup is None:
1463 asVirtModesSup = list(g_asVirtModes);
1464 TestVm.__init__(self, sVmName,
1465 oSet = oSet,
1466 acCpusSup = [1,],
1467 sFloppy = sFloppy,
1468 asVirtModesSup = asVirtModesSup,
1469 fPae = True,
1470 fIoApic = True,
1471 fVmmDevTestingPart = True,
1472 fVmmDevTestingMmio = True,
1473 );
1474
1475 def is64bitRequired(self):
1476 return self.f64BitRequired;
1477
1478
1479class AncientTestVm(TestVm):
1480 """
1481 A ancient Test VM, using the serial port for communicating results.
1482
1483 We're looking for 'PASSED' and 'FAILED' lines in the COM1 output.
1484 """
1485
1486
1487 def __init__(self, # pylint: disable=too-many-arguments
1488 sVmName, # type: str
1489 fGrouping = g_kfGrpAncient | g_kfGrpNoTxs, # type: int
1490 sHd = None, # type: str
1491 sKind = None, # type: str
1492 acCpusSup = None, # type: List[int]
1493 asVirtModesSup = None, # type: List[str]
1494 sNic0AttachType = None, # type: str
1495 sFloppy = None, # type: str
1496 sFirmwareType = 'bios', # type: str
1497 sChipsetType = 'piix3', # type: str
1498 sHddControllerName = 'IDE Controller', # type: str
1499 sDvdControllerName = 'IDE Controller', # type: str
1500 cMBRamMax = None, # type: int
1501 sGraphicsControllerType = None # type: str
1502 ):
1503 TestVm.__init__(self,
1504 sVmName,
1505 fGrouping = fGrouping,
1506 sHd = sHd,
1507 sKind = sKind,
1508 acCpusSup = [1] if acCpusSup is None else acCpusSup,
1509 asVirtModesSup = asVirtModesSup,
1510 sNic0AttachType = sNic0AttachType,
1511 sFloppy = sFloppy,
1512 sFirmwareType = sFirmwareType,
1513 sChipsetType = sChipsetType,
1514 sHddControllerType = sHddControllerName,
1515 sDvdControllerType = sDvdControllerName,
1516 asParavirtModesSup = (g_ksParavirtProviderNone,),
1517 sGraphicsControllerType = sGraphicsControllerType
1518 );
1519 self.fCom1RawFile = True;
1520 self.cMBRamMax= cMBRamMax;
1521
1522
1523 def _childVmReconfig(self, oTestDrv, oVM, oSession):
1524 _ = oVM; _ = oTestDrv;
1525 fRc = True;
1526
1527 # DOS 4.01 doesn't like the default 32MB of memory.
1528 if fRc and self.cMBRamMax is not None:
1529 try:
1530 cMBRam = oSession.o.machine.memorySize;
1531 except:
1532 cMBRam = self.cMBRamMax + 4;
1533 if self.cMBRamMax < cMBRam:
1534 fRc = oSession.setRamSize(self.cMBRamMax);
1535
1536 return fRc;
1537
1538
1539class TestVmSet(object):
1540 """
1541 A set of Test VMs.
1542 """
1543
1544 def __init__(self, oTestVmManager = None, acCpus = None, asVirtModes = None, fIgnoreSkippedVm = False):
1545 self.oTestVmManager = oTestVmManager;
1546 if acCpus is None:
1547 acCpus = [1, 2];
1548 self.acCpusDef = acCpus;
1549 self.acCpus = acCpus;
1550 if asVirtModes is None:
1551 asVirtModes = list(g_asVirtModes);
1552 self.asVirtModesDef = asVirtModes;
1553 self.asVirtModes = asVirtModes;
1554 self.aoTestVms = [] # type: list(BaseTestVm)
1555 self.fIgnoreSkippedVm = fIgnoreSkippedVm;
1556 self.asParavirtModes = None; ##< If None, use the first PV mode of the test VM, otherwise all modes in this list.
1557
1558 def findTestVmByName(self, sVmName):
1559 """
1560 Returns the TestVm object with the given name.
1561 Returns None if not found.
1562 """
1563
1564 # The 'tst-' prefix is optional.
1565 sAltName = sVmName if sVmName.startswith('tst-') else 'tst-' + sVmName;
1566
1567 for oTestVm in self.aoTestVms:
1568 if oTestVm.sVmName in (sVmName, sAltName):
1569 return oTestVm;
1570 return None;
1571
1572 def getAllVmNames(self, sSep = ':'):
1573 """
1574 Returns names of all the test VMs in the set separated by
1575 sSep (defaults to ':').
1576 """
1577 sVmNames = '';
1578 for oTestVm in self.aoTestVms:
1579 sName = oTestVm.sVmName;
1580 if sName.startswith('tst-'):
1581 sName = sName[4:];
1582 if sVmNames == '':
1583 sVmNames = sName;
1584 else:
1585 sVmNames = sVmNames + sSep + sName;
1586 return sVmNames;
1587
1588 def showUsage(self):
1589 """
1590 Invoked by vbox.TestDriver.
1591 """
1592 reporter.log('');
1593 reporter.log('Test VM selection and general config options:');
1594 reporter.log(' --virt-modes <m1[:m2[:...]]>');
1595 reporter.log(' Default: %s' % (':'.join(self.asVirtModesDef)));
1596 reporter.log(' --skip-virt-modes <m1[:m2[:...]]>');
1597 reporter.log(' Use this to avoid hwvirt or hwvirt-np when not supported by the host');
1598 reporter.log(' since we cannot detect it using the main API. Use after --virt-modes.');
1599 reporter.log(' --cpu-counts <c1[:c2[:...]]>');
1600 reporter.log(' Default: %s' % (':'.join(str(c) for c in self.acCpusDef)));
1601 reporter.log(' --test-vms <vm1[:vm2[:...]]>');
1602 reporter.log(' Test the specified VMs in the given order. Use this to change');
1603 reporter.log(' the execution order or limit the choice of VMs');
1604 reporter.log(' Default: %s (all)' % (self.getAllVmNames(),));
1605 reporter.log(' --skip-vms <vm1[:vm2[:...]]>');
1606 reporter.log(' Skip the specified VMs when testing.');
1607 reporter.log(' --skip-win-vms');
1608 reporter.log(' Skips Windows test VMs (accumulative).');
1609 reporter.log(' --skip-non-win-vms');
1610 reporter.log(' Skips non-Windows test VMs (accumulative).');
1611 reporter.log(' --snapshot-restore-current');
1612 reporter.log(' Restores the current snapshot and resumes execution.');
1613 reporter.log(' --paravirt-modes <pv1[:pv2[:...]]>');
1614 reporter.log(' Set of paravirtualized providers (modes) to tests. Intersected with what the test VM supports.');
1615 reporter.log(' Default is the first PV mode the test VMs support, generally same as "legacy".');
1616 reporter.log(' --with-nested-hwvirt-only');
1617 reporter.log(' Test VMs using nested hardware-virtualization only.');
1618 reporter.log(' --without-nested-hwvirt-only');
1619 reporter.log(' Test VMs not using nested hardware-virtualization only.');
1620 ## @todo Add more options for controlling individual VMs.
1621 return True;
1622
1623 def parseOption(self, asArgs, iArg):
1624 """
1625 Parses the set test vm set options (--test-vms and --skip-vms), modifying the set
1626 Invoked by the testdriver method with the same name.
1627
1628 Keyword arguments:
1629 asArgs -- The argument vector.
1630 iArg -- The index of the current argument.
1631
1632 Returns iArg if the option was not recognized and the caller should handle it.
1633 Returns the index of the next argument when something is consumed.
1634
1635 In the event of a syntax error, a InvalidOption or QuietInvalidOption
1636 is thrown.
1637 """
1638
1639 if asArgs[iArg] == '--virt-modes':
1640 iArg += 1;
1641 if iArg >= len(asArgs):
1642 raise base.InvalidOption('The "--virt-modes" takes a colon separated list of modes');
1643
1644 self.asVirtModes = asArgs[iArg].split(':');
1645 for s in self.asVirtModes:
1646 if s not in self.asVirtModesDef:
1647 raise base.InvalidOption('The "--virt-modes" value "%s" is not valid; valid values are: %s' \
1648 % (s, ' '.join(self.asVirtModesDef)));
1649
1650 elif asArgs[iArg] == '--skip-virt-modes':
1651 iArg += 1;
1652 if iArg >= len(asArgs):
1653 raise base.InvalidOption('The "--skip-virt-modes" takes a colon separated list of modes');
1654
1655 for s in asArgs[iArg].split(':'):
1656 if s not in self.asVirtModesDef:
1657 raise base.InvalidOption('The "--virt-modes" value "%s" is not valid; valid values are: %s' \
1658 % (s, ' '.join(self.asVirtModesDef)));
1659 if s in self.asVirtModes:
1660 self.asVirtModes.remove(s);
1661
1662 elif asArgs[iArg] == '--cpu-counts':
1663 iArg += 1;
1664 if iArg >= len(asArgs):
1665 raise base.InvalidOption('The "--cpu-counts" takes a colon separated list of cpu counts');
1666
1667 self.acCpus = [];
1668 for s in asArgs[iArg].split(':'):
1669 try: c = int(s);
1670 except: raise base.InvalidOption('The "--cpu-counts" value "%s" is not an integer' % (s,));
1671 if c <= 0: raise base.InvalidOption('The "--cpu-counts" value "%s" is zero or negative' % (s,));
1672 self.acCpus.append(c);
1673
1674 elif asArgs[iArg] == '--test-vms':
1675 iArg += 1;
1676 if iArg >= len(asArgs):
1677 raise base.InvalidOption('The "--test-vms" takes colon separated list');
1678
1679 for oTestVm in self.aoTestVms:
1680 oTestVm.fSkip = True;
1681
1682 asTestVMs = asArgs[iArg].split(':');
1683 for s in asTestVMs:
1684 oTestVm = self.findTestVmByName(s);
1685 if oTestVm is None:
1686 raise base.InvalidOption('The "--test-vms" value "%s" is not valid; valid values are: %s' \
1687 % (s, self.getAllVmNames(' ')));
1688 oTestVm.fSkip = False;
1689
1690 elif asArgs[iArg] == '--skip-vms':
1691 iArg += 1;
1692 if iArg >= len(asArgs):
1693 raise base.InvalidOption('The "--skip-vms" takes colon separated list');
1694
1695 asTestVMs = asArgs[iArg].split(':');
1696 for s in asTestVMs:
1697 oTestVm = self.findTestVmByName(s);
1698 if oTestVm is None:
1699 reporter.log('warning: The "--test-vms" value "%s" does not specify any of our test VMs.' % (s,));
1700 else:
1701 oTestVm.fSkip = True;
1702
1703 elif asArgs[iArg] == '--skip-win-vms':
1704 asTestVMs = asArgs[iArg].split(':');
1705 for oTestVm in self.aoTestVms:
1706 if oTestVm.isWindows():
1707 oTestVm.fSkip = True;
1708
1709 elif asArgs[iArg] == '--skip-non-win-vms':
1710 asTestVMs = asArgs[iArg].split(':');
1711 for oTestVm in self.aoTestVms:
1712 if not oTestVm.isWindows():
1713 oTestVm.fSkip = True;
1714
1715 elif asArgs[iArg] == '--snapshot-restore-current':
1716 for oTestVm in self.aoTestVms:
1717 if oTestVm.fSkip is False:
1718 oTestVm.fSnapshotRestoreCurrent = True;
1719 reporter.log('VM "%s" will be restored.' % (oTestVm.sVmName));
1720
1721 elif asArgs[iArg] == '--paravirt-modes':
1722 iArg += 1
1723 if iArg >= len(asArgs):
1724 raise base.InvalidOption('The "--paravirt-modes" takes a colon separated list of modes');
1725
1726 self.asParavirtModes = asArgs[iArg].split(':')
1727 for sPvMode in self.asParavirtModes:
1728 if sPvMode not in g_kasParavirtProviders:
1729 raise base.InvalidOption('The "--paravirt-modes" value "%s" is not valid; valid values are: %s'
1730 % (sPvMode, ', '.join(g_kasParavirtProviders),));
1731 if not self.asParavirtModes:
1732 self.asParavirtModes = None;
1733
1734 # HACK ALERT! Reset the random paravirt selection for members.
1735 for oTestVm in self.aoTestVms:
1736 oTestVm.asParavirtModesSup = oTestVm.asParavirtModesSupOrg;
1737
1738 elif asArgs[iArg] == '--with-nested-hwvirt-only':
1739 for oTestVm in self.aoTestVms:
1740 if oTestVm.fNstHwVirt is False:
1741 oTestVm.fSkip = True;
1742
1743 elif asArgs[iArg] == '--without-nested-hwvirt-only':
1744 for oTestVm in self.aoTestVms:
1745 if oTestVm.fNstHwVirt is True:
1746 oTestVm.fSkip = True;
1747
1748 else:
1749 return iArg;
1750 return iArg + 1;
1751
1752 def getResourceSet(self):
1753 """
1754 Called vbox.TestDriver.getResourceSet and returns a list of paths of resources.
1755 """
1756 asResources = [];
1757 for oTestVm in self.aoTestVms:
1758 if not oTestVm.fSkip:
1759 if isinstance(oTestVm, BaseTestVm): # Temporarily...
1760 asResources.extend(oTestVm.getResourceSet());
1761 else:
1762 if oTestVm.sHd is not None:
1763 asResources.append(oTestVm.sHd);
1764 if oTestVm.sDvdImage is not None:
1765 asResources.append(oTestVm.sDvdImage);
1766 return asResources;
1767
1768 def actionConfig(self, oTestDrv, eNic0AttachType = None, sDvdImage = None):
1769 """
1770 For base.TestDriver.actionConfig. Configure the VMs with defaults and
1771 a few tweaks as per arguments.
1772
1773 Returns True if successful.
1774 Returns False if not.
1775 """
1776
1777 for oTestVm in self.aoTestVms:
1778 if oTestVm.fSkip:
1779 continue;
1780 if oTestVm.skipCreatingVm(oTestDrv):
1781 oTestVm.fSkip = True;
1782 continue;
1783
1784 if oTestVm.fSnapshotRestoreCurrent:
1785 # If we want to restore a VM we don't need to create
1786 # the machine anymore -- so just add it to the test VM list.
1787 oVM = oTestDrv.addTestMachine(oTestVm.sVmName);
1788 else:
1789 oVM = oTestVm.createVm(oTestDrv, eNic0AttachType, sDvdImage);
1790 if oVM is None:
1791 return False;
1792
1793 return True;
1794
1795 def _removeUnsupportedVirtModes(self, oTestDrv):
1796 """
1797 Removes unsupported virtualization modes.
1798 """
1799 if 'hwvirt' in self.asVirtModes and not oTestDrv.hasHostHwVirt():
1800 reporter.log('Hardware assisted virtualization is not available on the host, skipping it.');
1801 self.asVirtModes.remove('hwvirt');
1802
1803 if 'hwvirt-np' in self.asVirtModes and not oTestDrv.hasHostNestedPaging():
1804 reporter.log('Nested paging not supported by the host, skipping it.');
1805 self.asVirtModes.remove('hwvirt-np');
1806
1807 if 'raw' in self.asVirtModes and not oTestDrv.hasRawModeSupport():
1808 reporter.log('Raw-mode virtualization is not available in this build (or perhaps for this host), skipping it.');
1809 self.asVirtModes.remove('raw');
1810
1811 return True;
1812
1813 def actionExecute(self, oTestDrv, fnCallback): # pylint: disable=too-many-locals
1814 """
1815 For base.TestDriver.actionExecute. Calls the callback function for
1816 each of the VMs and basic configuration variations (virt-mode and cpu
1817 count).
1818
1819 Returns True if all fnCallback calls returned True, otherwise False.
1820
1821 The callback can return True, False or None. The latter is for when the
1822 test is skipped. (True is for success, False is for failure.)
1823 """
1824
1825 self._removeUnsupportedVirtModes(oTestDrv);
1826 cMaxCpus = oTestDrv.getHostCpuCount();
1827
1828 #
1829 # The test loop.
1830 #
1831 fRc = True;
1832 for oTestVm in self.aoTestVms:
1833 if oTestVm.fSkip and self.fIgnoreSkippedVm:
1834 reporter.log2('Ignoring VM %s (fSkip = True).' % (oTestVm.sVmName,));
1835 continue;
1836 reporter.testStart(oTestVm.sVmName);
1837 if oTestVm.fSkip:
1838 reporter.testDone(fSkipped = True);
1839 continue;
1840
1841 # Intersect the supported modes and the ones being testing.
1842 asVirtModesSup = [sMode for sMode in oTestVm.asVirtModesSup if sMode in self.asVirtModes];
1843
1844 # Ditto for CPUs.
1845 acCpusSup = [cCpus for cCpus in oTestVm.acCpusSup if cCpus in self.acCpus];
1846
1847 # Ditto for paravirtualization modes, except if not specified we got a less obvious default.
1848 if self.asParavirtModes is not None and oTestDrv.fpApiVer >= 5.0:
1849 asParavirtModes = [sPvMode for sPvMode in oTestVm.asParavirtModesSup if sPvMode in self.asParavirtModes];
1850 assert None not in asParavirtModes;
1851 elif oTestDrv.fpApiVer >= 5.0:
1852 asParavirtModes = (oTestVm.asParavirtModesSup[0],);
1853 assert asParavirtModes[0] is not None;
1854 else:
1855 asParavirtModes = (None,);
1856
1857 for cCpus in acCpusSup:
1858 if cCpus == 1:
1859 reporter.testStart('1 cpu');
1860 else:
1861 reporter.testStart('%u cpus' % (cCpus));
1862 if cCpus > cMaxCpus:
1863 reporter.testDone(fSkipped = True);
1864 continue;
1865
1866 cTests = 0;
1867 for sVirtMode in asVirtModesSup:
1868 if sVirtMode == 'raw' and cCpus > 1:
1869 continue;
1870 reporter.testStart('%s' % ( g_dsVirtModeDescs[sVirtMode], ) );
1871 cStartTests = cTests;
1872
1873 for sParavirtMode in asParavirtModes:
1874 if sParavirtMode is not None:
1875 assert oTestDrv.fpApiVer >= 5.0;
1876 reporter.testStart('%s' % ( sParavirtMode, ) );
1877
1878 # Reconfigure the VM.
1879 try:
1880 (rc2, oVM) = oTestVm.getReconfiguredVm(oTestDrv, cCpus, sVirtMode, sParavirtMode = sParavirtMode);
1881 except KeyboardInterrupt:
1882 raise;
1883 except:
1884 reporter.errorXcpt(cFrames = 9);
1885 rc2 = False;
1886 if rc2 is True:
1887 # Do the testing.
1888 try:
1889 rc2 = fnCallback(oVM, oTestVm);
1890 except KeyboardInterrupt:
1891 raise;
1892 except:
1893 reporter.errorXcpt(cFrames = 9);
1894 rc2 = False;
1895 if rc2 is False:
1896 reporter.maybeErr(reporter.testErrorCount() == 0, 'fnCallback failed');
1897 elif rc2 is False:
1898 reporter.log('getReconfiguredVm failed');
1899 if rc2 is False:
1900 fRc = False;
1901
1902 cTests = cTests + (rc2 is not None);
1903 if sParavirtMode is not None:
1904 reporter.testDone(fSkipped = rc2 is None);
1905
1906 reporter.testDone(fSkipped = cTests == cStartTests);
1907
1908 reporter.testDone(fSkipped = cTests == 0);
1909
1910 _, cErrors = reporter.testDone();
1911 if cErrors > 0:
1912 fRc = False;
1913 return fRc;
1914
1915 def enumerateTestVms(self, fnCallback):
1916 """
1917 Enumerates all the 'active' VMs.
1918
1919 Returns True if all fnCallback calls returned True.
1920 Returns False if any returned False.
1921 Returns None immediately if fnCallback returned None.
1922 """
1923 fRc = True;
1924 for oTestVm in self.aoTestVms:
1925 if not oTestVm.fSkip:
1926 fRc2 = fnCallback(oTestVm);
1927 if fRc2 is None:
1928 return fRc2;
1929 fRc = fRc and fRc2;
1930 return fRc;
1931
1932
1933
1934class TestVmManager(object):
1935 """
1936 Test VM manager.
1937 """
1938
1939 ## @name VM grouping flags
1940 ## @{
1941 kfGrpSmoke = g_kfGrpSmoke;
1942 kfGrpStandard = g_kfGrpStandard;
1943 kfGrpStdSmoke = g_kfGrpStdSmoke;
1944 kfGrpWithGAs = g_kfGrpWithGAs;
1945 kfGrpNoTxs = g_kfGrpNoTxs;
1946 kfGrpAncient = g_kfGrpAncient;
1947 kfGrpExotic = g_kfGrpExotic;
1948 ## @}
1949
1950 kaTestVMs = (
1951 # Note: The images in the 6.1 folder all have been pre-configured to allow for Guest Additions installation
1952 # (come with build essentials, kernel headers).
1953 # Linux
1954 TestVm('tst-ubuntu-18_04_3-64', kfGrpStdSmoke, sHd = '6.1/ubuntu-18_04_3-amd64-2.vdi',
1955 sKind = 'Ubuntu_64', acCpusSup = range(1, 33), fIoApic = True,
1956 asParavirtModesSup = [g_ksParavirtProviderKVM,]),
1957 # Note: Deprecated; had SELinux + Screensaver (black screen) enabled.
1958 #TestVm('tst-ol-8_1-64-efi', kfGrpStdSmoke, sHd = '6.1/efi/ol-8_1-efi-amd64.vdi',
1959 # sKind = 'Oracle_64', acCpusSup = range(1, 33), fIoApic = True, sFirmwareType = 'efi',
1960 # asParavirtModesSup = [g_ksParavirtProviderKVM,]),
1961 TestVm('tst-ol-8_1-64-efi', kfGrpStdSmoke, sHd = '6.1/efi/ol-8_1-efi-amd64-2.vdi',
1962 sKind = 'Oracle_64', acCpusSup = range(1, 33), fIoApic = True, sFirmwareType = 'efi',
1963 asParavirtModesSup = [g_ksParavirtProviderKVM,]),
1964 TestVm('tst-ol-8_1-64-efi-sb', kfGrpStdSmoke, sHd = '6.1/efi/ol-8_1-efi-amd64-2.vdi',
1965 sKind = 'Oracle_64', acCpusSup = range(1, 33), fIoApic = True, sFirmwareType = 'efi',
1966 asParavirtModesSup = [g_ksParavirtProviderKVM,], fSecureBoot = True, sUefiMokPathPrefix = '7.0/mok/vbox-test-MOK'),
1967 TestVm('tst-ol-6u10-32', kfGrpStdSmoke, sHd = '7.1/ol-6u10-x86.vdi',
1968 sKind = 'Oracle', acCpusSup = range(1, 33), fIoApic = True,
1969 asParavirtModesSup = [g_ksParavirtProviderKVM,]),
1970 # Note: Don't use this image for VBoxService / Guest Control-related tests anymore;
1971 # The distro has a buggy dbus implementation, which crashes often in some dbus watcher functions when being
1972 # invoked by pm_sm_authenticate(). Also, the distro's repositories can't be used either easily anymore due to old
1973 # certificates and/or authentication methods. However, newer versions, such as OL6u9 or u10 should work fine.
1974 #TestVm('tst-ol-6u2-32', kfGrpStdSmoke, sHd = '6.1/ol-6u2-x86.vdi',
1975 # sKind = 'Oracle', acCpusSup = range(1, 33), fIoApic = True,
1976 # asParavirtModesSup = [g_ksParavirtProviderKVM,]),
1977 TestVm('tst-ubuntu-15_10-64-efi', kfGrpStdSmoke, sHd = '6.1/efi/ubuntu-15_10-efi-amd64-3.vdi',
1978 sKind = 'Ubuntu_64', acCpusSup = range(1, 33), fIoApic = True, sFirmwareType = 'efi',
1979 asParavirtModesSup = [g_ksParavirtProviderKVM,]),
1980 # Note: Temporary disabled. Probably too old distro for Secure Boot experiments, insmod fails to
1981 # insert guest modules with ENOPKG (Package not Installed).
1982 #TestVm('tst-ubuntu-15_10-64-efi-sb', kfGrpStdSmoke, sHd = '6.1/efi/ubuntu-15_10-efi-amd64-3.vdi',
1983 # sKind = 'Ubuntu_64', acCpusSup = range(1, 33), fIoApic = True, sFirmwareType = 'efi',
1984 # asParavirtModesSup = [g_ksParavirtProviderKVM,], fSecureBoot = True,
1985 # sUefiMokPathPrefix = '7.0/mok/vbox-test-MOK'),
1986 # Note: Deprecated / buggy; use the one in the 6.1 folder.
1987 #TestVm('tst-ubuntu-15_10-64-efi', kfGrpStdSmoke, sHd = '4.2/efi/ubuntu-15_10-efi-amd64.vdi',
1988 # sKind = 'Ubuntu_64', acCpusSup = range(1, 33), fIoApic = True, sFirmwareType = 'efi',
1989 # asParavirtModesSup = [g_ksParavirtProviderKVM,]),
1990 # Note: Has ancient Guest Additions 3.0.14 installed already.
1991 TestVm('tst-rhel5', kfGrpSmoke, sHd = '3.0/tcp/rhel5.vdi',
1992 sKind = 'RedHat', acCpusSup = range(1, 33), fIoApic = True, sNic0AttachType = 'nat'),
1993 TestVm('tst-arch', kfGrpStandard, sHd = '4.2/usb/tst-arch.vdi',
1994 sKind = 'ArchLinux_64', acCpusSup = range(1, 33), fIoApic = True, sNic0AttachType = 'nat'),
1995 # disabled 2019-03-08 klaus - fails all over the place and pollutes the test results
1996 #TestVm('tst-ubuntu-1804-64', kfGrpStdSmoke, sHd = '4.2/ubuntu-1804/t-ubuntu-1804-64.vdi',
1997 # sKind = 'Ubuntu_64', acCpusSup = range(1, 33), fIoApic = True),
1998 TestVm('tst-ol76-64', kfGrpStdSmoke, sHd = '4.2/ol76/t-ol76-64.vdi',
1999 sKind = 'Oracle_64', acCpusSup = range(1, 33), fIoApic = True),
2000 TestVm('tst-ubuntu-20_04-64-amdvi', kfGrpStdSmoke, sHd = '6.1/ubuntu-20_04-64-updated_by_ksenia.vdi',
2001 sKind = 'Ubuntu_64', acCpusSup = range(1, 33), fIoApic = True,
2002 asParavirtModesSup = [g_ksParavirtProviderKVM,], sNic0AttachType = 'nat', sChipsetType = 'ich9',
2003 sIommuType = 'amd'),
2004 TestVm('tst-ubuntu-20_04-64-vtd', kfGrpStdSmoke, sHd = '6.1/ubuntu-20_04-64-updated_by_ksenia.vdi',
2005 sKind = 'Ubuntu_64', acCpusSup = range(1, 33), fIoApic = True,
2006 asParavirtModesSup = [g_ksParavirtProviderKVM,], sNic0AttachType = 'nat', sChipsetType = 'ich9',
2007 sIommuType = 'intel'),
2008
2009 # Solaris
2010 TestVm('tst-sol10', kfGrpSmoke, sHd = '3.0/tcp/solaris10.vdi',
2011 sKind = 'Solaris', acCpusSup = range(1, 33), fPae = True, sNic0AttachType = 'bridged'),
2012 TestVm('tst-sol10-64', kfGrpSmoke, sHd = '3.0/tcp/solaris10.vdi',
2013 sKind = 'Solaris_64', acCpusSup = range(1, 33), sNic0AttachType = 'bridged'),
2014 TestVm('tst-sol11u1', kfGrpSmoke, sHd = '4.2/nat/sol11u1/t-sol11u1.vdi',
2015 sKind = 'Solaris11_64', acCpusSup = range(1, 33), sNic0AttachType = 'nat', fIoApic = True,
2016 sHddControllerType = 'SATA Controller'),
2017 #TestVm('tst-sol11u1-ich9', kfGrpSmoke, sHd = '4.2/nat/sol11u1/t-sol11u1.vdi',
2018 # sKind = 'Solaris11_64', acCpusSup = range(1, 33), sNic0AttachType = 'nat', fIoApic = True,
2019 # sHddControllerType = 'SATA Controller', sChipsetType = 'ich9'),
2020
2021 # NT 3.x
2022 TestVm('tst-nt310', kfGrpAncient, sHd = '5.2/great-old-ones/t-nt310/t-nt310.vdi',
2023 sKind = 'WindowsNT3x', acCpusSup = [1], sHddControllerType = 'BusLogic SCSI Controller',
2024 sDvdControllerType = 'BusLogic SCSI Controller'),
2025 TestVm('tst-nt350', kfGrpAncient, sHd = '5.2/great-old-ones/t-nt350/t-nt350.vdi',
2026 sKind = 'WindowsNT3x', acCpusSup = [1], sHddControllerType = 'BusLogic SCSI Controller',
2027 sDvdControllerType = 'BusLogic SCSI Controller'),
2028 TestVm('tst-nt351', kfGrpAncient, sHd = '5.2/great-old-ones/t-nt350/t-nt351.vdi',
2029 sKind = 'WindowsNT3x', acCpusSup = [1], sHddControllerType = 'BusLogic SCSI Controller',
2030 sDvdControllerType = 'BusLogic SCSI Controller'),
2031
2032 # NT 4
2033 TestVm('tst-nt4sp1', kfGrpStdSmoke, sHd = '4.2/nat/nt4sp1/t-nt4sp1.vdi',
2034 sKind = 'WindowsNT4', acCpusSup = [1], sNic0AttachType = 'nat'),
2035
2036 TestVm('tst-nt4sp6', kfGrpStdSmoke, sHd = '4.2/nt4sp6/t-nt4sp6.vdi',
2037 sKind = 'WindowsNT4', acCpusSup = range(1, 33)),
2038
2039 # W2K
2040 TestVm('tst-w2ksp4', kfGrpStdSmoke, sHd = '4.2/win2ksp4/t-win2ksp4.vdi',
2041 sKind = 'Windows2000', acCpusSup = range(1, 33)),
2042
2043 # XP
2044 TestVm('tst-xppro', kfGrpStdSmoke, sHd = '4.2/nat/xppro/t-xppro.vdi',
2045 sKind = 'WindowsXP', acCpusSup = range(1, 33), sNic0AttachType = 'nat'),
2046 TestVm('tst-xpsp2', kfGrpStdSmoke, sHd = '4.2/xpsp2/t-winxpsp2.vdi',
2047 sKind = 'WindowsXP', acCpusSup = range(1, 33), fIoApic = True),
2048 TestVm('tst-xpsp2-halaacpi', kfGrpStdSmoke, sHd = '4.2/xpsp2/t-winxp-halaacpi.vdi',
2049 sKind = 'WindowsXP', acCpusSup = range(1, 33), fIoApic = True),
2050 TestVm('tst-xpsp2-halacpi', kfGrpStdSmoke, sHd = '4.2/xpsp2/t-winxp-halacpi.vdi',
2051 sKind = 'WindowsXP', acCpusSup = range(1, 33), fIoApic = True),
2052 TestVm('tst-xpsp2-halapic', kfGrpStdSmoke, sHd = '4.2/xpsp2/t-winxp-halapic.vdi',
2053 sKind = 'WindowsXP', acCpusSup = range(1, 33), fIoApic = True),
2054 TestVm('tst-xpsp2-halmacpi', kfGrpStdSmoke, sHd = '4.2/xpsp2/t-winxp-halmacpi.vdi',
2055 sKind = 'WindowsXP', acCpusSup = range(2, 33), fIoApic = True),
2056 TestVm('tst-xpsp2-halmps', kfGrpStdSmoke, sHd = '4.2/xpsp2/t-winxp-halmps.vdi',
2057 sKind = 'WindowsXP', acCpusSup = range(2, 33), fIoApic = True),
2058
2059 # W2K3
2060 TestVm('tst-win2k3ent', kfGrpSmoke, sHd = '3.0/tcp/win2k3ent-acpi.vdi',
2061 sKind = 'Windows2003', acCpusSup = range(1, 33), fPae = True, sNic0AttachType = 'bridged'),
2062
2063 # W7
2064 TestVm('tst-win7', kfGrpStdSmoke, sHd = '6.1/win7-32/t-win7-32-1.vdi',
2065 sKind = 'Windows7', acCpusSup = range(1, 33), fIoApic = True),
2066 TestVm('tst-win7-64', kfGrpStdSmoke, sHd = '7.0/win7-64/win7-64.vdi',
2067 sKind = 'Windows7_64', acCpusSup = range(1, 33), fIoApic = True),
2068 # Note: Deprecated due to activation issues; use t-win7-32-1 instead.
2069 #TestVm('tst-win7', kfGrpStdSmoke, sHd = '6.1/win7-32/t-win7-32.vdi',
2070 # sKind = 'Windows7', acCpusSup = range(1, 33), fIoApic = True),
2071 # Note: Deprecated; use the one in the 6.1 folder.
2072 #TestVm('tst-win7', kfGrpStdSmoke, sHd = '4.2/win7-32/t-win7.vdi',
2073 # sKind = 'Windows7', acCpusSup = range(1, 33), fIoApic = True),
2074
2075 # W8
2076 TestVm('tst-win8-64', kfGrpStdSmoke, sHd = '4.2/win8-64/t-win8-64-testmode.vdi',
2077 sKind = 'Windows8_64', acCpusSup = range(1, 33), fIoApic = True),
2078 #TestVm('tst-win8-64-ich9', kfGrpStdSmoke, sHd = '4.2/win8-64/t-win8-64.vdi',
2079 # sKind = 'Windows8_64', acCpusSup = range(1, 33), fIoApic = True, sChipsetType = 'ich9'),
2080
2081 # W10
2082 TestVm('tst-win10-efi', kfGrpStdSmoke, sHd = '4.2/efi/win10-efi-x86-edited2.vdi',
2083 sKind = 'Windows10', acCpusSup = range(1, 33), fIoApic = True, sFirmwareType = 'efi'),
2084 TestVm('tst-win10-64-efi', kfGrpStdSmoke, sHd = '4.2/efi/t-win10-64-efi-2.vdi',
2085 sKind = 'Windows10_64', acCpusSup = range(1, 33), fIoApic = True, sFirmwareType = 'efi'),
2086 #TestVm('tst-win10-64-efi-ich9', kfGrpStdSmoke, sHd = '4.2/efi/win10-efi-amd64.vdi',
2087 # sKind = 'Windows10_64', acCpusSup = range(1, 33), fIoApic = True, sFirmwareType = 'efi', sChipsetType = 'ich9'),
2088
2089 # W11
2090 TestVm('tst-win11-64-efi', kfGrpStdSmoke, sHd = '7.0/win11/t-win11-64-efi-2.vdi',
2091 sKind = 'Windows11_64', acCpusSup = range(1, 33), fIoApic = True, sFirmwareType = 'efi',
2092 sHddControllerType = 'SATA Controller', sDvdControllerType = 'SATA Controller',
2093 sGraphicsControllerType = 'VBoxSVGA'),
2094
2095 # Nested hardware-virtualization
2096 TestVm('tst-nsthwvirt-ubuntu-64', kfGrpStdSmoke, sHd = '5.3/nat/nsthwvirt-ubuntu64/t-nsthwvirt-ubuntu64.vdi',
2097 sKind = 'Ubuntu_64', acCpusSup = range(1, 2), asVirtModesSup = ['hwvirt-np',], fIoApic = True, fNstHwVirt = True,
2098 sNic0AttachType = 'nat'),
2099
2100 # Audio testing.
2101 TestVm('tst-audio-debian10-64', kfGrpStdSmoke, sHd = '6.1/audio/debian10-amd64-7.vdi',
2102 sKind = 'Debian_64', acCpusSup = range(1, 33), fIoApic = True),
2103
2104 # DOS and Old Windows.
2105 AncientTestVm('tst-dos20', sKind = 'DOS',
2106 sHd = '5.2/great-old-ones/t-dos20/t-dos20.vdi'),
2107 AncientTestVm('tst-dos401-win30me', sKind = 'DOS',
2108 sHd = '5.2/great-old-ones/t-dos401-win30me/t-dos401-win30me.vdi', cMBRamMax = 4),
2109 AncientTestVm('tst-dos401-emm386-win30me', sKind = 'DOS',
2110 sHd = '5.2/great-old-ones/t-dos401-emm386-win30me/t-dos401-emm386-win30me.vdi', cMBRamMax = 4),
2111 AncientTestVm('tst-dos50-win31', sKind = 'DOS',
2112 sHd = '5.2/great-old-ones/t-dos50-win31/t-dos50-win31.vdi'),
2113 AncientTestVm('tst-dos50-emm386-win31', sKind = 'DOS',
2114 sHd = '5.2/great-old-ones/t-dos50-emm386-win31/t-dos50-emm386-win31.vdi'),
2115 AncientTestVm('tst-dos622', sKind = 'DOS',
2116 sHd = '5.2/great-old-ones/t-dos622/t-dos622.vdi'),
2117 AncientTestVm('tst-dos622-emm386', sKind = 'DOS',
2118 sHd = '5.2/great-old-ones/t-dos622-emm386/t-dos622-emm386.vdi'),
2119 AncientTestVm('tst-dos71', sKind = 'DOS',
2120 sHd = '5.2/great-old-ones/t-dos71/t-dos71.vdi'),
2121
2122 #AncientTestVm('tst-dos5-win311a', sKind = 'DOS', sHd = '5.2/great-old-ones/t-dos5-win311a/t-dos5-win311a.vdi'),
2123 );
2124
2125
2126 def __init__(self, sResourcePath):
2127 self.sResourcePath = sResourcePath;
2128
2129 def selectSet(self, fGrouping, sTxsTransport = None, fCheckResources = True):
2130 """
2131 Returns a VM set with the selected VMs.
2132 """
2133 oSet = TestVmSet(oTestVmManager = self);
2134 for oVm in self.kaTestVMs:
2135 if oVm.fGrouping & fGrouping:
2136 if sTxsTransport is None or oVm.sNic0AttachType is None or sTxsTransport == oVm.sNic0AttachType:
2137 if not fCheckResources or not oVm.getMissingResources(self.sResourcePath):
2138 oCopyVm = copy.deepcopy(oVm);
2139 oCopyVm.oSet = oSet;
2140 oSet.aoTestVms.append(oCopyVm);
2141 return oSet;
2142
2143 def getStandardVmSet(self, sTxsTransport):
2144 """
2145 Gets the set of standard test VMs.
2146
2147 This is supposed to do something seriously clever, like searching the
2148 testrsrc tree for usable VMs, but for the moment it's all hard coded. :-)
2149 """
2150 return self.selectSet(self.kfGrpStandard, sTxsTransport)
2151
2152 def getSmokeVmSet(self, sTxsTransport = None):
2153 """Gets a representative set of VMs for smoke testing. """
2154 return self.selectSet(self.kfGrpSmoke, sTxsTransport);
2155
2156 def shutUpPyLint(self):
2157 """ Shut up already! """
2158 return self.sResourcePath;
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