VirtualBox

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

Last change on this file since 103068 was 103047, checked in by vboxsync, 16 months ago

ValidationKit/vboxtestvms.py: Add an OL 9.2 amd64 and arm64 smoketest VM for comparison [pylint fix]

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

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette