VirtualBox

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

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

ValKit: Administrator account unlocked in Windows 10 VM (to pass GA Basic tests)

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