VirtualBox

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

Last change on this file was 106061, checked in by vboxsync, 3 months ago

Copyright year updates by scm.

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