VirtualBox

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

Last change on this file since 102966 was 102966, checked in by vboxsync, 11 months ago

ValidationKit/tests/cpu: Add very basic tdCpuIemInstr1.py testcase to run certain bootsector testcases automatically, bugref:10582

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