VirtualBox

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

最後變更 在這個檔案從102100是 101702,由 vboxsync 提交於 17 月 前

ValidationKit/tdGuestOsUnattendedInst1: Add OracleLinux 9 arm64 to the list of unattended install testcases, bugref:10542

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

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