VirtualBox

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

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

ValidationKit: bugref:10318 Enable smoke test for Hyper-V enabled Windows 10 Pro guest.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 109.5 KB
Line 
1# -*- coding: utf-8 -*-
2# $Id: vboxtestvms.py 103702 2024-03-06 13:37:56Z vboxsync $
3
4"""
5VirtualBox Test VMs
6"""
7
8__copyright__ = \
9"""
10Copyright (C) 2010-2023 Oracle and/or its affiliates.
11
12This file is part of VirtualBox base platform packages, as
13available from https://www.virtualbox.org.
14
15This program is free software; you can redistribute it and/or
16modify it under the terms of the GNU General Public License
17as published by the Free Software Foundation, in version 3 of the
18License.
19
20This program is distributed in the hope that it will be useful, but
21WITHOUT ANY WARRANTY; without even the implied warranty of
22MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23General Public License for more details.
24
25You should have received a copy of the GNU General Public License
26along with this program; if not, see <https://www.gnu.org/licenses>.
27
28The contents of this file may alternatively be used under the terms
29of the Common Development and Distribution License Version 1.0
30(CDDL), a copy of it is provided in the "COPYING.CDDL" file included
31in the VirtualBox distribution, in which case the provisions of the
32CDDL are applicable instead of those of the GPL.
33
34You may elect to license modified versions of this file under the
35terms and conditions of either the GPL or the CDDL or both.
36
37SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
38"""
39__version__ = "$Revision: 103702 $"
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 aenmExecEngines = oTestDrv.oVBox.systemProperties.getExecutionEnginesForVmCpuArchitecture(enmCpuArch);
1900
1901 if 'raw' in asVirtModesWanted and not oTestDrv.hasRawModeSupport():
1902 reporter.log('Raw-mode virtualization is not available in this build (or perhaps for this host), skipping it.');
1903 asVirtModesWanted.remove('raw');
1904
1905 if 'hwvirt' in asVirtModesWanted and not vboxcon.VMExecutionEngine_HwVirt in aenmExecEngines:
1906 reporter.log('Hardware assisted virtualization is not available on the host, skipping it.');
1907 asVirtModesWanted.remove('hwvirt');
1908
1909 if 'hwvirt-np' in asVirtModesWanted and ( not vboxcon.VMExecutionEngine_HwVirt in aenmExecEngines \
1910 or not oTestDrv.hasHostNestedPaging()):
1911 reporter.log('Nested paging not supported by the host, skipping it.');
1912 asVirtModesWanted.remove('hwvirt-np');
1913
1914 if 'native-api' in asVirtModesWanted and not vboxcon.VMExecutionEngine_NativeApi in aenmExecEngines:
1915 reporter.log('Native API (aka NEM) virtualization is not available in this build (or perhaps for this host) and VM CPU architecture, skipping it.');
1916 asVirtModesWanted.remove('native-api');
1917
1918 if 'interpreter' in asVirtModesWanted and not vboxcon.VMExecutionEngine_Interpreter in aenmExecEngines:
1919 reporter.log('IEM interpreter is not available in this build (or perhaps for this host) and VM CPU architecture, skipping it.');
1920 asVirtModesWanted.remove('interpreter');
1921
1922 if 'recompiler' in asVirtModesWanted and not vboxcon.VMExecutionEngine_Recompiler in aenmExecEngines:
1923 reporter.log('IEM recompiler is not available in this build (or perhaps for this host) and VM CPU architecture, skipping it.');
1924 asVirtModesWanted.remove('recompiler');
1925 except:
1926 reporter.errorXcpt('failed to query supported execution engines for "%s"' % (oVm.sVmName, ));
1927 asVirtModesWanted = [];
1928 else:
1929 if 'native-api' in asVirtModesWanted:
1930 asVirtModesWanted.remove('native-api');
1931 if 'interpreter' in asVirtModesWanted:
1932 asVirtModesWanted.remove('interpreter');
1933 if 'recompiler' in asVirtModesWanted:
1934 asVirtModesWanted.remove('recompiler');
1935
1936 if 'hwvirt' in asVirtModesWanted and not oTestDrv.hasHostHwVirt():
1937 reporter.log('Hardware assisted virtualization is not available on the host, skipping it.');
1938 asVirtModesWanted.remove('hwvirt');
1939
1940 # r=aeichner: For 7.0 there is no native API mode to set but NEM gets picked by default on macOS.
1941 # But because the darwin testboxes don't report the hwvirt or hwvirt-np capability anymore (see @bugref{10592})
1942 # this results in no virt mode being supported and all the VMs getting skipped (but the test marked as
1943 # succeeded anyway). In order to keep the default behavior we keep at least hwvirt-np on macOS which will
1944 # make use of NEM automatically and testing with 7.0 continues working.
1945 if 'hwvirt-np' in asVirtModesWanted and not oTestDrv.hasHostNestedPaging() and utils.getHostOs() != 'darwin':
1946 reporter.log('Nested paging not supported by the host, skipping it.');
1947 asVirtModesWanted.remove('hwvirt-np');
1948
1949 if 'raw' in asVirtModesWanted and not oTestDrv.hasRawModeSupport():
1950 reporter.log('Raw-mode virtualization is not available in this build (or perhaps for this host), skipping it.');
1951 asVirtModesWanted.remove('raw');
1952
1953 # pylint: enable=line-too-long
1954 return asVirtModesWanted;
1955
1956 def actionExecute(self, oTestDrv, fnCallback): # pylint: disable=too-many-locals
1957 """
1958 For base.TestDriver.actionExecute. Calls the callback function for
1959 each of the VMs and basic configuration variations (virt-mode and cpu
1960 count).
1961
1962 Returns True if all fnCallback calls returned True, otherwise False.
1963
1964 The callback can return True, False or None. The latter is for when the
1965 test is skipped. (True is for success, False is for failure.)
1966 """
1967
1968 cMaxCpus = oTestDrv.getHostCpuCount();
1969
1970 #
1971 # The test loop.
1972 #
1973 fRc = True;
1974 for oTestVm in self.aoTestVms:
1975 if oTestVm.fSkip and self.fIgnoreSkippedVm:
1976 reporter.log2('Ignoring VM %s (fSkip = True).' % (oTestVm.sVmName,));
1977 continue;
1978 reporter.testStart(oTestVm.sVmName);
1979 if oTestVm.fSkip:
1980 reporter.testDone(fSkipped = True);
1981 continue;
1982
1983 # Intersect the supported modes and the ones being testing.
1984 asVirtModesSup = [sMode for sMode in oTestVm.asVirtModesSup if sMode in self.asVirtModes];
1985
1986 # Filter out what the host doesn't support.
1987 asVirtModesSup = self._removeUnsupportedVirtModes(oTestDrv, oTestVm, asVirtModesSup);
1988
1989 # Ditto for CPUs.
1990 acCpusSup = [cCpus for cCpus in oTestVm.acCpusSup if cCpus in self.acCpus];
1991
1992 # Ditto for paravirtualization modes, except if not specified we got a less obvious default.
1993 if self.asParavirtModes is not None and oTestDrv.fpApiVer >= 5.0:
1994 asParavirtModes = [sPvMode for sPvMode in oTestVm.asParavirtModesSup if sPvMode in self.asParavirtModes];
1995 assert None not in asParavirtModes;
1996 elif oTestDrv.fpApiVer >= 5.0:
1997 asParavirtModes = (oTestVm.asParavirtModesSup[0],);
1998 assert asParavirtModes[0] is not None;
1999 else:
2000 asParavirtModes = (None,);
2001
2002 for cCpus in acCpusSup:
2003 if cCpus == 1:
2004 reporter.testStart('1 cpu');
2005 else:
2006 reporter.testStart('%u cpus' % (cCpus));
2007 if cCpus > cMaxCpus:
2008 reporter.testDone(fSkipped = True);
2009 continue;
2010
2011 cTests = 0;
2012 for sVirtMode in asVirtModesSup:
2013 if sVirtMode == 'raw' and cCpus > 1:
2014 continue;
2015 reporter.testStart('%s' % ( g_dsVirtModeDescs[sVirtMode], ) );
2016 cStartTests = cTests;
2017
2018 for sParavirtMode in asParavirtModes:
2019 if sParavirtMode is not None:
2020 assert oTestDrv.fpApiVer >= 5.0;
2021 reporter.testStart('%s' % ( sParavirtMode, ) );
2022
2023 # Reconfigure the VM.
2024 try:
2025 (rc2, oVM) = oTestVm.getReconfiguredVm(oTestDrv, cCpus, sVirtMode, sParavirtMode = sParavirtMode);
2026 except KeyboardInterrupt:
2027 raise;
2028 except:
2029 reporter.errorXcpt(cFrames = 9);
2030 rc2 = False;
2031 if rc2 is True:
2032 # Do the testing.
2033 try:
2034 rc2 = fnCallback(oVM, oTestVm);
2035 except KeyboardInterrupt:
2036 raise;
2037 except:
2038 reporter.errorXcpt(cFrames = 9);
2039 rc2 = False;
2040 if rc2 is False:
2041 reporter.maybeErr(reporter.testErrorCount() == 0, 'fnCallback failed');
2042 elif rc2 is False:
2043 reporter.log('getReconfiguredVm failed');
2044 if rc2 is False:
2045 fRc = False;
2046
2047 cTests = cTests + (rc2 is not None);
2048 if sParavirtMode is not None:
2049 reporter.testDone(fSkipped = rc2 is None);
2050
2051 reporter.testDone(fSkipped = cTests == cStartTests);
2052
2053 reporter.testDone(fSkipped = cTests == 0);
2054
2055 _, cErrors = reporter.testDone();
2056 if cErrors > 0:
2057 fRc = False;
2058 return fRc;
2059
2060 def enumerateTestVms(self, fnCallback):
2061 """
2062 Enumerates all the 'active' VMs.
2063
2064 Returns True if all fnCallback calls returned True.
2065 Returns False if any returned False.
2066 Returns None immediately if fnCallback returned None.
2067 """
2068 fRc = True;
2069 for oTestVm in self.aoTestVms:
2070 if not oTestVm.fSkip:
2071 fRc2 = fnCallback(oTestVm);
2072 if fRc2 is None:
2073 return fRc2;
2074 fRc = fRc and fRc2;
2075 return fRc;
2076
2077
2078
2079class TestVmManager(object):
2080 """
2081 Test VM manager.
2082 """
2083
2084 ## @name VM grouping flags
2085 ## @{
2086 kfGrpSmoke = g_kfGrpSmoke;
2087 kfGrpStandard = g_kfGrpStandard;
2088 kfGrpStdSmoke = g_kfGrpStdSmoke;
2089 kfGrpWithGAs = g_kfGrpWithGAs;
2090 kfGrpNoTxs = g_kfGrpNoTxs;
2091 kfGrpAncient = g_kfGrpAncient;
2092 kfGrpExotic = g_kfGrpExotic;
2093 ## @}
2094
2095 kaTestVMs = (
2096 # Note: The images in the 6.1 folder all have been pre-configured to allow for Guest Additions installation
2097 # (come with build essentials, kernel headers).
2098 # Linux
2099 TestVm('tst-ubuntu-18_04_3-64', kfGrpStdSmoke, sHd = '6.1/ubuntu-18_04_3-amd64-2.vdi',
2100 sKind = 'Ubuntu_64', acCpusSup = range(1, 33), fIoApic = True,
2101 asParavirtModesSup = [g_ksParavirtProviderKVM,]),
2102 # Note: Deprecated; had SELinux + Screensaver (black screen) enabled.
2103 #TestVm('tst-ol-8_1-64-efi', kfGrpStdSmoke, sHd = '6.1/efi/ol-8_1-efi-amd64.vdi',
2104 # sKind = 'Oracle_64', acCpusSup = range(1, 33), fIoApic = True, sFirmwareType = 'efi',
2105 # asParavirtModesSup = [g_ksParavirtProviderKVM,]),
2106 TestVm('tst-ol-8_1-64-efi', kfGrpStdSmoke, sHd = '6.1/efi/ol-8_1-efi-amd64-2.vdi',
2107 sKind = 'Oracle_64', acCpusSup = range(1, 33), fIoApic = True, sFirmwareType = 'efi',
2108 asParavirtModesSup = [g_ksParavirtProviderKVM,]),
2109 TestVm('tst-ol-8_1-64-efi-sb', kfGrpStdSmoke, sHd = '6.1/efi/ol-8_1-efi-amd64-2.vdi',
2110 sKind = 'Oracle_64', acCpusSup = range(1, 33), fIoApic = True, sFirmwareType = 'efi',
2111 asParavirtModesSup = [g_ksParavirtProviderKVM,], fSecureBoot = True, sUefiMokPathPrefix = '7.0/mok/vbox-test-MOK'),
2112 TestVm('tst-ol-6u10-32', kfGrpStdSmoke, sHd = '7.1/ol-6u10-x86.vdi',
2113 sKind = 'Oracle', acCpusSup = range(1, 33), fIoApic = True,
2114 asParavirtModesSup = [g_ksParavirtProviderKVM,]),
2115 TestVm('tst-ol-9_2-amd64', kfGrpStdSmoke, sHd = '7.1/smoketests/ol-9_2-amd64-txs.vdi',
2116 sKind = 'Oracle_64', acCpusSup = range(1, 33), fIoApic = True,
2117 asParavirtModesSup = [g_ksParavirtProviderKVM,], sHddControllerType='SATA Controller',
2118 sDvdControllerType = 'SATA Controller', sGraphicsControllerType = 'VMSVGA'),
2119 # Note: Don't use this image for VBoxService / Guest Control-related tests anymore;
2120 # The distro has a buggy dbus implementation, which crashes often in some dbus watcher functions when being
2121 # invoked by pm_sm_authenticate(). Also, the distro's repositories can't be used either easily anymore due to old
2122 # certificates and/or authentication methods. However, newer versions, such as OL6u9 or u10 should work fine.
2123 #TestVm('tst-ol-6u2-32', kfGrpStdSmoke, sHd = '6.1/ol-6u2-x86.vdi',
2124 # sKind = 'Oracle', acCpusSup = range(1, 33), fIoApic = True,
2125 # asParavirtModesSup = [g_ksParavirtProviderKVM,]),
2126 TestVm('tst-ubuntu-15_10-64-efi', kfGrpStdSmoke, sHd = '6.1/efi/ubuntu-15_10-efi-amd64-3.vdi',
2127 sKind = 'Ubuntu_64', acCpusSup = range(1, 33), fIoApic = True, sFirmwareType = 'efi',
2128 asParavirtModesSup = [g_ksParavirtProviderKVM,]),
2129 # Note: Temporary disabled. Probably too old distro for Secure Boot experiments, insmod fails to
2130 # insert guest modules with ENOPKG (Package not Installed).
2131 #TestVm('tst-ubuntu-15_10-64-efi-sb', kfGrpStdSmoke, sHd = '6.1/efi/ubuntu-15_10-efi-amd64-3.vdi',
2132 # sKind = 'Ubuntu_64', acCpusSup = range(1, 33), fIoApic = True, sFirmwareType = 'efi',
2133 # asParavirtModesSup = [g_ksParavirtProviderKVM,], fSecureBoot = True,
2134 # sUefiMokPathPrefix = '7.0/mok/vbox-test-MOK'),
2135 # Note: Deprecated / buggy; use the one in the 6.1 folder.
2136 #TestVm('tst-ubuntu-15_10-64-efi', kfGrpStdSmoke, sHd = '4.2/efi/ubuntu-15_10-efi-amd64.vdi',
2137 # sKind = 'Ubuntu_64', acCpusSup = range(1, 33), fIoApic = True, sFirmwareType = 'efi',
2138 # asParavirtModesSup = [g_ksParavirtProviderKVM,]),
2139 # Note: Has ancient Guest Additions 3.0.14 installed already.
2140 TestVm('tst-rhel5', kfGrpSmoke, sHd = '3.0/tcp/rhel5.vdi',
2141 sKind = 'RedHat', acCpusSup = range(1, 33), fIoApic = True, sNic0AttachType = 'nat'),
2142 TestVm('tst-arch', kfGrpStandard, sHd = '4.2/usb/tst-arch.vdi',
2143 sKind = 'ArchLinux_64', acCpusSup = range(1, 33), fIoApic = True, sNic0AttachType = 'nat'),
2144 # disabled 2019-03-08 klaus - fails all over the place and pollutes the test results
2145 #TestVm('tst-ubuntu-1804-64', kfGrpStdSmoke, sHd = '4.2/ubuntu-1804/t-ubuntu-1804-64.vdi',
2146 # sKind = 'Ubuntu_64', acCpusSup = range(1, 33), fIoApic = True),
2147 TestVm('tst-ol76-64', kfGrpStdSmoke, sHd = '4.2/ol76/t-ol76-64.vdi',
2148 sKind = 'Oracle_64', acCpusSup = range(1, 33), fIoApic = True),
2149 TestVm('tst-ubuntu-20_04-64-amdvi', kfGrpStdSmoke, sHd = '6.1/ubuntu-20_04-64-updated_by_ksenia.vdi',
2150 sKind = 'Ubuntu_64', acCpusSup = range(1, 33), fIoApic = True,
2151 asParavirtModesSup = [g_ksParavirtProviderKVM,], sNic0AttachType = 'nat', sChipsetType = 'ich9',
2152 sIommuType = 'amd'),
2153 TestVm('tst-ubuntu-20_04-64-vtd', kfGrpStdSmoke, sHd = '6.1/ubuntu-20_04-64-updated_by_ksenia.vdi',
2154 sKind = 'Ubuntu_64', acCpusSup = range(1, 33), fIoApic = True,
2155 asParavirtModesSup = [g_ksParavirtProviderKVM,], sNic0AttachType = 'nat', sChipsetType = 'ich9',
2156 sIommuType = 'intel'),
2157
2158 # Solaris
2159 TestVm('tst-sol10', kfGrpSmoke, sHd = '3.0/tcp/solaris10.vdi',
2160 sKind = 'Solaris', acCpusSup = range(1, 33), fPae = True, sNic0AttachType = 'bridged'),
2161 TestVm('tst-sol10-64', kfGrpSmoke, sHd = '3.0/tcp/solaris10.vdi',
2162 sKind = 'Solaris_64', acCpusSup = range(1, 33), sNic0AttachType = 'bridged'),
2163 TestVm('tst-sol11u1', kfGrpSmoke, sHd = '4.2/nat/sol11u1/t-sol11u1.vdi',
2164 sKind = 'Solaris11_64', acCpusSup = range(1, 33), sNic0AttachType = 'nat', fIoApic = True,
2165 sHddControllerType = 'SATA Controller'),
2166 #TestVm('tst-sol11u1-ich9', kfGrpSmoke, sHd = '4.2/nat/sol11u1/t-sol11u1.vdi',
2167 # sKind = 'Solaris11_64', acCpusSup = range(1, 33), sNic0AttachType = 'nat', fIoApic = True,
2168 # sHddControllerType = 'SATA Controller', sChipsetType = 'ich9'),
2169
2170 # NT 3.x
2171 TestVm('tst-nt310', kfGrpAncient, sHd = '5.2/great-old-ones/t-nt310/t-nt310.vdi',
2172 sKind = 'WindowsNT3x', acCpusSup = [1], sHddControllerType = 'BusLogic SCSI Controller',
2173 sDvdControllerType = 'BusLogic SCSI Controller'),
2174 TestVm('tst-nt350', kfGrpAncient, sHd = '5.2/great-old-ones/t-nt350/t-nt350.vdi',
2175 sKind = 'WindowsNT3x', acCpusSup = [1], sHddControllerType = 'BusLogic SCSI Controller',
2176 sDvdControllerType = 'BusLogic SCSI Controller'),
2177 TestVm('tst-nt351', kfGrpAncient, sHd = '5.2/great-old-ones/t-nt350/t-nt351.vdi',
2178 sKind = 'WindowsNT3x', acCpusSup = [1], sHddControllerType = 'BusLogic SCSI Controller',
2179 sDvdControllerType = 'BusLogic SCSI Controller'),
2180
2181 # NT 4
2182 TestVm('tst-nt4sp1', kfGrpStdSmoke, sHd = '4.2/nat/nt4sp1/t-nt4sp1.vdi',
2183 sKind = 'WindowsNT4', acCpusSup = [1], sNic0AttachType = 'nat'),
2184
2185 TestVm('tst-nt4sp6', kfGrpStdSmoke, sHd = '4.2/nt4sp6/t-nt4sp6.vdi',
2186 sKind = 'WindowsNT4', acCpusSup = range(1, 33)),
2187
2188 # W2K
2189 TestVm('tst-w2ksp4', kfGrpStdSmoke, sHd = '4.2/win2ksp4/t-win2ksp4.vdi',
2190 sKind = 'Windows2000', acCpusSup = range(1, 33)),
2191
2192 # XP
2193 TestVm('tst-xppro', kfGrpStdSmoke, sHd = '4.2/nat/xppro/t-xppro.vdi',
2194 sKind = 'WindowsXP', acCpusSup = range(1, 33), sNic0AttachType = 'nat'),
2195 TestVm('tst-xpsp2', kfGrpStdSmoke, sHd = '4.2/xpsp2/t-winxpsp2.vdi',
2196 sKind = 'WindowsXP', acCpusSup = range(1, 33), fIoApic = True),
2197 TestVm('tst-xpsp2-halaacpi', kfGrpStdSmoke, sHd = '4.2/xpsp2/t-winxp-halaacpi.vdi',
2198 sKind = 'WindowsXP', acCpusSup = range(1, 33), fIoApic = True),
2199 TestVm('tst-xpsp2-halacpi', kfGrpStdSmoke, sHd = '4.2/xpsp2/t-winxp-halacpi.vdi',
2200 sKind = 'WindowsXP', acCpusSup = range(1, 33), fIoApic = True),
2201 TestVm('tst-xpsp2-halapic', kfGrpStdSmoke, sHd = '4.2/xpsp2/t-winxp-halapic.vdi',
2202 sKind = 'WindowsXP', acCpusSup = range(1, 33), fIoApic = True),
2203 TestVm('tst-xpsp2-halmacpi', kfGrpStdSmoke, sHd = '4.2/xpsp2/t-winxp-halmacpi.vdi',
2204 sKind = 'WindowsXP', acCpusSup = range(2, 33), fIoApic = True),
2205 TestVm('tst-xpsp2-halmps', kfGrpStdSmoke, sHd = '4.2/xpsp2/t-winxp-halmps.vdi',
2206 sKind = 'WindowsXP', acCpusSup = range(2, 33), fIoApic = True),
2207
2208 # W2K3
2209 TestVm('tst-win2k3ent', kfGrpSmoke, sHd = '3.0/tcp/win2k3ent-acpi.vdi',
2210 sKind = 'Windows2003', acCpusSup = range(1, 33), fPae = True, sNic0AttachType = 'bridged'),
2211
2212 # W7
2213 TestVm('tst-win7', kfGrpStdSmoke, sHd = '6.1/win7-32/t-win7-32-1.vdi',
2214 sKind = 'Windows7', acCpusSup = range(1, 33), fIoApic = True),
2215 TestVm('tst-win7-64', kfGrpStdSmoke, sHd = '7.0/win7-64/win7-64.vdi',
2216 sKind = 'Windows7_64', acCpusSup = range(1, 33), fIoApic = True,
2217 sHddControllerType = 'SATA Controller'),
2218 # Note: Deprecated due to activation issues; use t-win7-32-1 instead.
2219 #TestVm('tst-win7', kfGrpStdSmoke, sHd = '6.1/win7-32/t-win7-32.vdi',
2220 # sKind = 'Windows7', acCpusSup = range(1, 33), fIoApic = True),
2221 # Note: Deprecated; use the one in the 6.1 folder.
2222 #TestVm('tst-win7', kfGrpStdSmoke, sHd = '4.2/win7-32/t-win7.vdi',
2223 # sKind = 'Windows7', acCpusSup = range(1, 33), fIoApic = True),
2224
2225 # W8
2226 TestVm('tst-win8-64', kfGrpStdSmoke, sHd = '4.2/win8-64/t-win8-64-active-admin-acc.vdi',
2227 sKind = 'Windows8_64', acCpusSup = range(1, 33), fIoApic = True),
2228 #TestVm('tst-win8-64-ich9', kfGrpStdSmoke, sHd = '4.2/win8-64/t-win8-64.vdi',
2229 # sKind = 'Windows8_64', acCpusSup = range(1, 33), fIoApic = True, sChipsetType = 'ich9'),
2230
2231 # W10
2232 TestVm('tst-win10-efi', kfGrpStdSmoke, sHd = '4.2/efi/win10-efi-x86-edited2.vdi',
2233 sKind = 'Windows10', acCpusSup = range(1, 33), fIoApic = True, sFirmwareType = 'efi'),
2234 TestVm('tst-win10-64-efi', kfGrpStdSmoke, sHd = '4.2/efi/t-win10-64-efi-2.vdi',
2235 sKind = 'Windows10_64', acCpusSup = range(1, 33), fIoApic = True, sFirmwareType = 'efi'),
2236 #TestVm('tst-win10-64-efi-ich9', kfGrpStdSmoke, sHd = '4.2/efi/win10-efi-amd64.vdi',
2237 # sKind = 'Windows10_64', acCpusSup = range(1, 33), fIoApic = True, sFirmwareType = 'efi', sChipsetType = 'ich9'),
2238
2239 # W11
2240 TestVm('tst-win11-64-efi', kfGrpStdSmoke, sHd = '7.0/win11/t-win11-64-efi-2.vdi',
2241 sKind = 'Windows11_64', acCpusSup = range(1, 33), fIoApic = True, sFirmwareType = 'efi',
2242 sHddControllerType = 'SATA Controller', sDvdControllerType = 'SATA Controller',
2243 sGraphicsControllerType = 'VBoxSVGA', asVirtModesSup = ['hwvirt-np',] ),
2244
2245 # Nested hardware-virtualization
2246 TestVm('tst-nsthwvirt-ubuntu-64', kfGrpStdSmoke, sHd = '5.3/nat/nsthwvirt-ubuntu64/t-nsthwvirt-ubuntu64.vdi',
2247 sKind = 'Ubuntu_64', acCpusSup = range(1, 2), asVirtModesSup = ['hwvirt-np',], fIoApic = True, fNstHwVirt = True,
2248 sNic0AttachType = 'nat'),
2249 TestVm('tst-nsthwvirt-win10-hv-64', kfGrpStdSmoke, sHd = '7.1/smoketests/t-nsthwvirt-win10-hv-64.vdi',
2250 sKind = 'Windows10_64', acCpusSup = range(1, 2), asVirtModesSup = ['hwvirt-np',], fIoApic = True,
2251 fNstHwVirt = True, sNic0AttachType = 'nat', asParavirtModesSup = [g_ksParavirtProviderNone,]),
2252
2253 # Audio testing.
2254 TestVm('tst-audio-debian10-64', kfGrpStdSmoke, sHd = '6.1/audio/debian10-amd64-7.vdi',
2255 sKind = 'Debian_64', acCpusSup = range(1, 33), fIoApic = True),
2256
2257 # DOS and Old Windows.
2258 AncientTestVm('tst-dos20', sKind = 'DOS',
2259 sHd = '5.2/great-old-ones/t-dos20/t-dos20.vdi'),
2260 AncientTestVm('tst-dos401-win30me', sKind = 'DOS',
2261 sHd = '5.2/great-old-ones/t-dos401-win30me/t-dos401-win30me.vdi', cMBRamMax = 4),
2262 AncientTestVm('tst-dos401-emm386-win30me', sKind = 'DOS',
2263 sHd = '5.2/great-old-ones/t-dos401-emm386-win30me/t-dos401-emm386-win30me.vdi', cMBRamMax = 4),
2264 AncientTestVm('tst-dos50-win31', sKind = 'DOS',
2265 sHd = '5.2/great-old-ones/t-dos50-win31/t-dos50-win31.vdi'),
2266 AncientTestVm('tst-dos50-emm386-win31', sKind = 'DOS',
2267 sHd = '5.2/great-old-ones/t-dos50-emm386-win31/t-dos50-emm386-win31.vdi'),
2268 AncientTestVm('tst-dos622', sKind = 'DOS',
2269 sHd = '5.2/great-old-ones/t-dos622/t-dos622.vdi'),
2270 AncientTestVm('tst-dos622-emm386', sKind = 'DOS',
2271 sHd = '5.2/great-old-ones/t-dos622-emm386/t-dos622-emm386.vdi'),
2272 AncientTestVm('tst-dos71', sKind = 'DOS',
2273 sHd = '5.2/great-old-ones/t-dos71/t-dos71.vdi'),
2274
2275 #AncientTestVm('tst-dos5-win311a', sKind = 'DOS', sHd = '5.2/great-old-ones/t-dos5-win311a/t-dos5-win311a.vdi'),
2276
2277 #
2278 # ARM
2279 #
2280 TestVm('tst-ol-9_2-arm64', kfGrpStdSmoke, sHd = '7.1/smoketests/ol-9_2-arm64-txs.vdi',
2281 sKind = 'Oracle_arm64', acCpusSup = range(1, 33), sChipsetType = 'armv8virtual', \
2282 sHddControllerType='VirtIO SCSI Controller', sDvdControllerType = 'SATA Controller', \
2283 sGraphicsControllerType = 'QemuRamFb', sPlatformArchitecture = 'ARM'),
2284 );
2285
2286
2287 def __init__(self, sResourcePath):
2288 self.sResourcePath = sResourcePath;
2289
2290 def selectSet(self, fGrouping, sTxsTransport = None, fCheckResources = True):
2291 """
2292 Returns a VM set with the selected VMs.
2293 """
2294 oSet = TestVmSet(oTestVmManager = self);
2295 for oVm in self.kaTestVMs:
2296 if oVm.fGrouping & fGrouping:
2297 if sTxsTransport is None or oVm.sNic0AttachType is None or sTxsTransport == oVm.sNic0AttachType:
2298 if not fCheckResources or not oVm.getMissingResources(self.sResourcePath):
2299 oCopyVm = copy.deepcopy(oVm);
2300 oCopyVm.oSet = oSet;
2301 oSet.aoTestVms.append(oCopyVm);
2302 return oSet;
2303
2304 def getStandardVmSet(self, sTxsTransport):
2305 """
2306 Gets the set of standard test VMs.
2307
2308 This is supposed to do something seriously clever, like searching the
2309 testrsrc tree for usable VMs, but for the moment it's all hard coded. :-)
2310 """
2311 return self.selectSet(self.kfGrpStandard, sTxsTransport)
2312
2313 def getSmokeVmSet(self, sTxsTransport = None):
2314 """Gets a representative set of VMs for smoke testing. """
2315 return self.selectSet(self.kfGrpSmoke, sTxsTransport);
2316
2317 def shutUpPyLint(self):
2318 """ Shut up already! """
2319 return self.sResourcePath;
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use