VirtualBox

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

Last change on this file since 102108 was 102108, checked in by vboxsync, 13 months ago

ValidationKit: Fix for 7.1 API changes, bugref:10507

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