VirtualBox

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

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

ValidationKit: Fixes for arm and 7.1 Main API, bugref:10542 [fix]

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

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