VirtualBox

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

Last change on this file since 98709 was 98655, checked in by vboxsync, 22 months ago

ValKit: Pylint 2.16.2 adjustments.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 96.4 KB
Line 
1# -*- coding: utf-8 -*-
2# $Id: vboxtestvms.py 98655 2023-02-20 15:05:40Z 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: 98655 $"
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', 'Windows11', 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 Resturns a list of reosurces 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 ):
977 self.oSet = oSet;
978 self.sVmName = sVmName;
979 self.fGrouping = fGrouping;
980 self.sHd = sHd; # Relative to the testrsrc root.
981 self.acCpusSup = acCpusSup;
982 self.asVirtModesSup = asVirtModesSup;
983 self.asParavirtModesSup = asParavirtModesSup;
984 self.asParavirtModesSupOrg = asParavirtModesSup; # HACK ALERT! Trick to make the 'effing random mess not get in the
985 # way of actively selecting virtualization modes.
986 self.sKind = sKind;
987 self.sGuestOsType = None;
988 self.sDvdImage = None; # Relative to the testrsrc root.
989 self.sDvdControllerType = sDvdControllerType;
990 self.fIoApic = fIoApic;
991 self.fNstHwVirt = fNstHwVirt;
992 self.fPae = fPae;
993 self.sNic0AttachType = sNic0AttachType;
994 self.sHddControllerType = sHddControllerType;
995 self.sFloppy = sFloppy; # Relative to the testrsrc root, except when it isn't...
996 self.fVmmDevTestingPart = fVmmDevTestingPart;
997 self.fVmmDevTestingMmio = fVmmDevTestingMmio;
998 self.sFirmwareType = sFirmwareType;
999 self.sChipsetType = sChipsetType;
1000 self.sIommuType = sIommuType;
1001 self.fCom1RawFile = False;
1002
1003 self.fSnapshotRestoreCurrent = False; # Whether to restore execution on the current snapshot.
1004 self.fSkip = False; # All VMs are included in the configured set by default.
1005 self.aInfo = None;
1006 self.sCom1RawFile = None; # Set by createVmInner and getReconfiguredVm if fCom1RawFile is set.
1007 self._guessStuff(fRandomPvPMode);
1008
1009 def _mkCanonicalGuestOSType(self, sType):
1010 """
1011 Convert guest OS type into constant representation.
1012 Raise exception if specified @param sType is unknown.
1013 """
1014 if sType.lower().startswith('darwin'):
1015 return g_ksGuestOsTypeDarwin
1016 if sType.lower().startswith('bsd'):
1017 return g_ksGuestOsTypeFreeBSD
1018 if sType.lower().startswith('dos'):
1019 return g_ksGuestOsTypeDOS
1020 if sType.lower().startswith('linux'):
1021 return g_ksGuestOsTypeLinux
1022 if sType.lower().startswith('os2'):
1023 return g_ksGuestOsTypeOS2
1024 if sType.lower().startswith('solaris'):
1025 return g_ksGuestOsTypeSolaris
1026 if sType.lower().startswith('windows'):
1027 return g_ksGuestOsTypeWindows
1028 raise base.GenError(sWhat="unknown guest OS kind: %s" % str(sType))
1029
1030 def _guessStuff(self, fRandomPvPMode):
1031 """
1032 Used by the constructor to guess stuff.
1033 """
1034
1035 sNm = self.sVmName.lower().strip();
1036 asSplit = sNm.replace('-', ' ').split(' ');
1037
1038 if self.sKind is None:
1039 # From name.
1040 for aInfo in g_aaNameToDetails:
1041 if _intersects(asSplit, aInfo[g_iRegEx]):
1042 self.aInfo = aInfo;
1043 self.sGuestOsType = self._mkCanonicalGuestOSType(aInfo[g_iGuestOsType])
1044 self.sKind = aInfo[g_iKind];
1045 break;
1046 if self.sKind is None:
1047 reporter.fatal('The OS of test VM "%s" cannot be guessed' % (self.sVmName,));
1048
1049 # Check for 64-bit, if required and supported.
1050 if (self.aInfo[g_iFlags] & g_kiArchMask) == g_k32_64 and _intersects(asSplit, ['64', 'amd64']):
1051 self.sKind = self.sKind + '_64';
1052 else:
1053 # Lookup the kind.
1054 for aInfo in g_aaNameToDetails:
1055 if self.sKind == aInfo[g_iKind]:
1056 self.aInfo = aInfo;
1057 break;
1058 if self.aInfo is None:
1059 reporter.fatal('The OS of test VM "%s" with sKind="%s" cannot be guessed' % (self.sVmName, self.sKind));
1060
1061 # Translate sKind into sGuest OS Type.
1062 if self.sGuestOsType is None:
1063 if self.aInfo is not None:
1064 self.sGuestOsType = self._mkCanonicalGuestOSType(self.aInfo[g_iGuestOsType])
1065 elif self.sKind.find("Windows") >= 0:
1066 self.sGuestOsType = g_ksGuestOsTypeWindows
1067 elif self.sKind.find("Linux") >= 0:
1068 self.sGuestOsType = g_ksGuestOsTypeLinux;
1069 elif self.sKind.find("Solaris") >= 0:
1070 self.sGuestOsType = g_ksGuestOsTypeSolaris;
1071 elif self.sKind.find("DOS") >= 0:
1072 self.sGuestOsType = g_ksGuestOsTypeDOS;
1073 else:
1074 reporter.fatal('The OS of test VM "%s", sKind="%s" cannot be guessed' % (self.sVmName, self.sKind));
1075
1076 # Restrict modes and such depending on the OS.
1077 if self.asVirtModesSup is None:
1078 self.asVirtModesSup = list(g_asVirtModes);
1079 if self.sGuestOsType in (g_ksGuestOsTypeOS2, g_ksGuestOsTypeDarwin) \
1080 or self.sKind.find('_64') > 0 \
1081 or (self.aInfo is not None and (self.aInfo[g_iFlags] & g_kiNoRaw)):
1082 self.asVirtModesSup = [sVirtMode for sVirtMode in self.asVirtModesSup if sVirtMode != 'raw'];
1083 # TEMPORARY HACK - START
1084 sHostName = os.environ.get("COMPUTERNAME", None);
1085 if sHostName: sHostName = sHostName.lower();
1086 else: sHostName = socket.getfqdn(); # Horribly slow on windows without IPv6 DNS/whatever.
1087 if sHostName.startswith('testboxpile1'):
1088 self.asVirtModesSup = [sVirtMode for sVirtMode in self.asVirtModesSup if sVirtMode != 'raw'];
1089 # TEMPORARY HACK - END
1090
1091 # Restrict the CPU count depending on the OS and/or percieved SMP readiness.
1092 if self.acCpusSup is None:
1093 if _intersects(asSplit, ['uni']):
1094 self.acCpusSup = [1];
1095 elif self.aInfo is not None:
1096 self.acCpusSup = list(range(self.aInfo[g_iMinCpu], self.aInfo[g_iMaxCpu] + 1));
1097 else:
1098 self.acCpusSup = [1];
1099
1100 # Figure relevant PV modes based on the OS.
1101 if self.asParavirtModesSup is None:
1102 self.asParavirtModesSup = g_kdaParavirtProvidersSupported[self.sGuestOsType];
1103 ## @todo Remove this hack as soon as we've got around to explictly configure test variations
1104 ## on the server side. Client side random is interesting but not the best option.
1105 self.asParavirtModesSupOrg = self.asParavirtModesSup;
1106 if fRandomPvPMode:
1107 random.seed();
1108 self.asParavirtModesSup = (random.choice(self.asParavirtModesSup),);
1109
1110 return True;
1111
1112 def getNonCanonicalGuestOsType(self):
1113 """
1114 Gets the non-canonical OS type (self.sGuestOsType is canonical).
1115 """
1116 return self.aInfo[g_iGuestOsType];
1117
1118 def getMissingResources(self, sTestRsrc):
1119 """
1120 Returns a list of missing resources (paths, stuff) that the VM needs.
1121 """
1122 asRet = [];
1123 for sPath in [ self.sHd, self.sDvdImage, self.sFloppy]:
1124 if sPath is not None:
1125 if not os.path.isabs(sPath):
1126 sPath = os.path.join(sTestRsrc, sPath);
1127 if not os.path.exists(sPath):
1128 asRet.append(sPath);
1129 return asRet;
1130
1131 def skipCreatingVm(self, oTestDrv):
1132 """
1133 Called before VM creation to determine whether the VM should be skipped
1134 due to host incompatibility or something along those lines.
1135
1136 returns True if it should be skipped, False if not.
1137 """
1138 if self.fNstHwVirt and not oTestDrv.hasHostNestedHwVirt():
1139 reporter.log('Ignoring VM %s (Nested hardware-virtualization not support on this host).' % (self.sVmName,));
1140 return True;
1141 return False;
1142
1143 def createVm(self, oTestDrv, eNic0AttachType = None, sDvdImage = None):
1144 """
1145 Creates the VM with defaults and the few tweaks as per the arguments.
1146
1147 Returns same as vbox.TestDriver.createTestVM.
1148 """
1149 if sDvdImage is not None:
1150 sMyDvdImage = sDvdImage;
1151 else:
1152 sMyDvdImage = self.sDvdImage;
1153
1154 if eNic0AttachType is not None:
1155 eMyNic0AttachType = eNic0AttachType;
1156 elif self.sNic0AttachType is None:
1157 eMyNic0AttachType = None;
1158 elif self.sNic0AttachType == 'nat':
1159 eMyNic0AttachType = vboxcon.NetworkAttachmentType_NAT;
1160 elif self.sNic0AttachType == 'bridged':
1161 eMyNic0AttachType = vboxcon.NetworkAttachmentType_Bridged;
1162 else:
1163 assert False, self.sNic0AttachType;
1164
1165 return self.createVmInner(oTestDrv, eMyNic0AttachType, sMyDvdImage);
1166
1167 def _generateRawPortFilename(self, oTestDrv, sInfix, sSuffix):
1168 """ Generates a raw port filename. """
1169 random.seed();
1170 sRandom = ''.join(random.choice(string.ascii_lowercase + string.digits) for _ in range(10));
1171 return os.path.join(oTestDrv.sScratchPath, self.sVmName + sInfix + sRandom + sSuffix);
1172
1173 def createVmInner(self, oTestDrv, eNic0AttachType, sDvdImage):
1174 """
1175 Same as createVm but parameters resolved.
1176
1177 Returns same as vbox.TestDriver.createTestVM.
1178 """
1179 reporter.log2('');
1180 reporter.log2('Calling createTestVM on %s...' % (self.sVmName,))
1181 if self.fCom1RawFile:
1182 self.sCom1RawFile = self._generateRawPortFilename(oTestDrv, '-com1-', '.out');
1183 return oTestDrv.createTestVM(self.sVmName,
1184 1, # iGroup
1185 sHd = self.sHd,
1186 sKind = self.sKind,
1187 fIoApic = self.fIoApic,
1188 fNstHwVirt = self.fNstHwVirt,
1189 fPae = self.fPae,
1190 eNic0AttachType = eNic0AttachType,
1191 sDvdImage = sDvdImage,
1192 sDvdControllerType = self.sDvdControllerType,
1193 sHddControllerType = self.sHddControllerType,
1194 sFloppy = self.sFloppy,
1195 fVmmDevTestingPart = self.fVmmDevTestingPart,
1196 fVmmDevTestingMmio = self.fVmmDevTestingMmio,
1197 sFirmwareType = self.sFirmwareType,
1198 sChipsetType = self.sChipsetType,
1199 sIommuType = self.sIommuType,
1200 sCom1RawFile = self.sCom1RawFile if self.fCom1RawFile else None
1201 );
1202
1203 def getReconfiguredVm(self, oTestDrv, cCpus, sVirtMode, sParavirtMode = None):
1204 """
1205 actionExecute worker that finds and reconfigure a test VM.
1206
1207 Returns (fRc, oVM) where fRc is True, None or False and oVM is a
1208 VBox VM object that is only present when rc is True.
1209 """
1210
1211 fRc = False;
1212 oVM = oTestDrv.getVmByName(self.sVmName);
1213 if oVM is not None:
1214 if self.fSnapshotRestoreCurrent is True:
1215 fRc = True;
1216 else:
1217 fHostSupports64bit = oTestDrv.hasHostLongMode();
1218 if self.is64bitRequired() and not fHostSupports64bit:
1219 fRc = None; # Skip the test.
1220 elif self.isViaIncompatible() and oTestDrv.isHostCpuVia():
1221 fRc = None; # Skip the test.
1222 elif self.isShanghaiIncompatible() and oTestDrv.isHostCpuShanghai():
1223 fRc = None; # Skip the test.
1224 elif self.isP4Incompatible() and oTestDrv.isHostCpuP4():
1225 fRc = None; # Skip the test.
1226 else:
1227 oSession = oTestDrv.openSession(oVM);
1228 if oSession is not None:
1229 fRc = oSession.enableVirtEx(sVirtMode != 'raw');
1230 fRc = fRc and oSession.enableNestedPaging(sVirtMode == 'hwvirt-np');
1231 fRc = fRc and oSession.setCpuCount(cCpus);
1232 if cCpus > 1:
1233 fRc = fRc and oSession.enableIoApic(True);
1234
1235 if sParavirtMode is not None and oSession.fpApiVer >= 5.0:
1236 adParavirtProviders = {
1237 g_ksParavirtProviderNone : vboxcon.ParavirtProvider_None,
1238 g_ksParavirtProviderDefault: vboxcon.ParavirtProvider_Default,
1239 g_ksParavirtProviderLegacy : vboxcon.ParavirtProvider_Legacy,
1240 g_ksParavirtProviderMinimal: vboxcon.ParavirtProvider_Minimal,
1241 g_ksParavirtProviderHyperV : vboxcon.ParavirtProvider_HyperV,
1242 g_ksParavirtProviderKVM : vboxcon.ParavirtProvider_KVM,
1243 };
1244 fRc = fRc and oSession.setParavirtProvider(adParavirtProviders[sParavirtMode]);
1245
1246 fCfg64Bit = self.is64bitRequired() or (self.is64bit() and fHostSupports64bit and sVirtMode != 'raw');
1247 fRc = fRc and oSession.enableLongMode(fCfg64Bit);
1248 if fCfg64Bit: # This is to avoid GUI pedantic warnings in the GUI. Sigh.
1249 oOsType = oSession.getOsType();
1250 if oOsType is not None:
1251 if oOsType.is64Bit and sVirtMode == 'raw':
1252 assert(oOsType.id[-3:] == '_64');
1253 fRc = fRc and oSession.setOsType(oOsType.id[:-3]);
1254 elif not oOsType.is64Bit and sVirtMode != 'raw':
1255 fRc = fRc and oSession.setOsType(oOsType.id + '_64');
1256
1257 # New serial raw file.
1258 if fRc and self.fCom1RawFile:
1259 self.sCom1RawFile = self._generateRawPortFilename(oTestDrv, '-com1-', '.out');
1260 utils.noxcptDeleteFile(self.sCom1RawFile);
1261 fRc = oSession.setupSerialToRawFile(0, self.sCom1RawFile);
1262
1263 # Make life simpler for child classes.
1264 if fRc:
1265 fRc = self._childVmReconfig(oTestDrv, oVM, oSession);
1266
1267 fRc = fRc and oSession.saveSettings();
1268 if not oSession.close():
1269 fRc = False;
1270 if fRc is True:
1271 return (True, oVM);
1272 return (fRc, None);
1273
1274 def _childVmReconfig(self, oTestDrv, oVM, oSession):
1275 """ Hook into getReconfiguredVm() for children. """
1276 _ = oTestDrv; _ = oVM; _ = oSession;
1277 return True;
1278
1279 def getGuestArch(self):
1280 """ Same as util.getHostArch. """
1281 return 'amd64' if self.sKind.find('_64') >= 0 else 'x86';
1282
1283 def getGuestOs(self):
1284 """ Same as util.getHostOs. """
1285 if self.isWindows(): return 'win';
1286 if self.isOS2(): return 'os2';
1287 if self.isLinux(): return 'linux';
1288 reporter.error('getGuestOs does not what to return!');
1289 raise Exception();
1290
1291 def getGuestExeSuff(self):
1292 """ The executable image suffix for the guest. """
1293 if self.isWindows() or self.isOS2():
1294 return '.exe';
1295 return '';
1296
1297 def getGuestOsDotArch(self):
1298 """ Same as util.getHostOsDotArch."""
1299 return self.getGuestOs() + '.' + self.getGuestArch();
1300
1301 def isWindows(self):
1302 """ Checks if it's a Windows VM. """
1303 return self.sGuestOsType == g_ksGuestOsTypeWindows;
1304
1305 def isOS2(self):
1306 """ Checks if it's an OS/2 VM. """
1307 return self.sGuestOsType == g_ksGuestOsTypeOS2;
1308
1309 def isLinux(self):
1310 """ Checks if it's an Linux VM. """
1311 return self.sGuestOsType == g_ksGuestOsTypeLinux;
1312
1313 def is64bit(self):
1314 """ Checks if it's a 64-bit VM. """
1315 return self.sKind.find('_64') >= 0;
1316
1317 def is64bitRequired(self):
1318 """ Check if 64-bit is required or not. """
1319 return (self.aInfo[g_iFlags] & g_k64) != 0;
1320
1321 def isLoggedOntoDesktop(self):
1322 """ Checks if the test VM is logging onto a graphical desktop by default. """
1323 if self.isWindows():
1324 return True;
1325 if self.isOS2():
1326 return True;
1327 if self.sVmName.find('-desktop'):
1328 return True;
1329 return False;
1330
1331 def isViaIncompatible(self):
1332 """
1333 Identifies VMs that doesn't work on VIA.
1334
1335 Returns True if NOT supported on VIA, False if it IS supported.
1336 """
1337 # Oracle linux doesn't like VIA in our experience
1338 if self.aInfo[g_iKind] in ['Oracle', 'Oracle_64']:
1339 return True;
1340 # OS/2: "The system detected an internal processing error at location
1341 # 0168:fff1da1f - 000e:ca1f. 0a8606fd
1342 if self.isOS2():
1343 return True;
1344 # Windows NT4 before SP4 won't work because of cmpxchg8b not being
1345 # detected, leading to a STOP 3e(80,0,0,0).
1346 if self.aInfo[g_iKind] == 'WindowsNT4':
1347 if self.sVmName.find('sp') < 0:
1348 return True; # no service pack.
1349 if self.sVmName.find('sp0') >= 0 \
1350 or self.sVmName.find('sp1') >= 0 \
1351 or self.sVmName.find('sp2') >= 0 \
1352 or self.sVmName.find('sp3') >= 0:
1353 return True;
1354 # XP x64 on a physical VIA box hangs exactly like a VM.
1355 if self.aInfo[g_iKind] in ['WindowsXP_64', 'Windows2003_64']:
1356 return True;
1357 # Vista 64 throws BSOD 0x5D (UNSUPPORTED_PROCESSOR)
1358 if self.aInfo[g_iKind] in ['WindowsVista_64']:
1359 return True;
1360 # Solaris 11 hangs on VIA, tested on a physical box (testboxvqc)
1361 if self.aInfo[g_iKind] in ['Solaris11_64']:
1362 return True;
1363 return False;
1364
1365 def isShanghaiIncompatible(self):
1366 """
1367 Identifies VMs that doesn't work on Shanghai.
1368
1369 Returns True if NOT supported on Shanghai, False if it IS supported.
1370 """
1371 # For now treat it just like VIA, to be adjusted later
1372 return self.isViaIncompatible()
1373
1374 def isP4Incompatible(self):
1375 """
1376 Identifies VMs that doesn't work on Pentium 4 / Pentium D.
1377
1378 Returns True if NOT supported on P4, False if it IS supported.
1379 """
1380 # Stupid 1 kHz timer. Too much for antique CPUs.
1381 if self.sVmName.find('rhel5') >= 0:
1382 return True;
1383 # Due to the boot animation the VM takes forever to boot.
1384 if self.aInfo[g_iKind] == 'Windows2000':
1385 return True;
1386 return False;
1387
1388 def isHostCpuAffectedByUbuntuNewAmdBug(self, oTestDrv):
1389 """
1390 Checks if the host OS is affected by older ubuntu installers being very
1391 picky about which families of AMD CPUs it would run on.
1392
1393 The installer checks for family 15, later 16, later 20, and in 11.10
1394 they remove the family check for AMD CPUs.
1395 """
1396 if not oTestDrv.isHostCpuAmd():
1397 return False;
1398 try:
1399 (uMaxExt, _, _, _) = oTestDrv.oVBox.host.getProcessorCPUIDLeaf(0, 0x80000000, 0);
1400 (uFamilyModel, _, _, _) = oTestDrv.oVBox.host.getProcessorCPUIDLeaf(0, 0x80000001, 0);
1401 except:
1402 reporter.logXcpt();
1403 return False;
1404 if uMaxExt < 0x80000001 or uMaxExt > 0x8000ffff:
1405 return False;
1406
1407 uFamily = (uFamilyModel >> 8) & 0xf
1408 if uFamily == 0xf:
1409 uFamily = ((uFamilyModel >> 20) & 0x7f) + 0xf;
1410 ## @todo Break this down into which old ubuntu release supports exactly
1411 ## which AMD family, if we care.
1412 if uFamily <= 15:
1413 return False;
1414 reporter.log('Skipping "%s" because host CPU is a family %u AMD, which may cause trouble for the guest OS installer.'
1415 % (self.sVmName, uFamily,));
1416 return True;
1417
1418 def getTestUser(self):
1419 """
1420 Gets the primary test user name.
1421 """
1422 if self.isWindows():
1423 return 'Administrator';
1424 return 'vbox';
1425
1426 def getTestUserPassword(self, sUser = None):
1427 """
1428 Gets the password for the primary user (or other specified one).
1429 """
1430 if sUser == 'test':
1431 return '';
1432 if sUser == 'vboxuser': # Default unattended installation user and password.
1433 return 'changeme';
1434 return 'password';
1435
1436 def pathJoin(self, sBase, *asAppend):
1437 """ See common.pathutils.joinEx(). """
1438 return pathutils.joinEx(self.isWindows() or self.isOS2(), sBase, *asAppend);
1439
1440 def pathSep(self):
1441 """ Returns the preferred paths separator for the guest OS. """
1442 return '\\' if self.isWindows() or self.isOS2() else '/';
1443
1444
1445class BootSectorTestVm(TestVm):
1446 """
1447 A Boot Sector Test VM.
1448 """
1449
1450 def __init__(self, oSet, sVmName, sFloppy = None, asVirtModesSup = None, f64BitRequired = False):
1451 self.f64BitRequired = f64BitRequired;
1452 if asVirtModesSup is None:
1453 asVirtModesSup = list(g_asVirtModes);
1454 TestVm.__init__(self, sVmName,
1455 oSet = oSet,
1456 acCpusSup = [1,],
1457 sFloppy = sFloppy,
1458 asVirtModesSup = asVirtModesSup,
1459 fPae = True,
1460 fIoApic = True,
1461 fVmmDevTestingPart = True,
1462 fVmmDevTestingMmio = True,
1463 );
1464
1465 def is64bitRequired(self):
1466 return self.f64BitRequired;
1467
1468
1469class AncientTestVm(TestVm):
1470 """
1471 A ancient Test VM, using the serial port for communicating results.
1472
1473 We're looking for 'PASSED' and 'FAILED' lines in the COM1 output.
1474 """
1475
1476
1477 def __init__(self, # pylint: disable=too-many-arguments
1478 sVmName, # type: str
1479 fGrouping = g_kfGrpAncient | g_kfGrpNoTxs, # type: int
1480 sHd = None, # type: str
1481 sKind = None, # type: str
1482 acCpusSup = None, # type: List[int]
1483 asVirtModesSup = None, # type: List[str]
1484 sNic0AttachType = None, # type: str
1485 sFloppy = None, # type: str
1486 sFirmwareType = 'bios', # type: str
1487 sChipsetType = 'piix3', # type: str
1488 sHddControllerName = 'IDE Controller', # type: str
1489 sDvdControllerName = 'IDE Controller', # type: str
1490 cMBRamMax = None, # type: int
1491 ):
1492 TestVm.__init__(self,
1493 sVmName,
1494 fGrouping = fGrouping,
1495 sHd = sHd,
1496 sKind = sKind,
1497 acCpusSup = [1] if acCpusSup is None else acCpusSup,
1498 asVirtModesSup = asVirtModesSup,
1499 sNic0AttachType = sNic0AttachType,
1500 sFloppy = sFloppy,
1501 sFirmwareType = sFirmwareType,
1502 sChipsetType = sChipsetType,
1503 sHddControllerType = sHddControllerName,
1504 sDvdControllerType = sDvdControllerName,
1505 asParavirtModesSup = (g_ksParavirtProviderNone,)
1506 );
1507 self.fCom1RawFile = True;
1508 self.cMBRamMax= cMBRamMax;
1509
1510
1511 def _childVmReconfig(self, oTestDrv, oVM, oSession):
1512 _ = oVM; _ = oTestDrv;
1513 fRc = True;
1514
1515 # DOS 4.01 doesn't like the default 32MB of memory.
1516 if fRc and self.cMBRamMax is not None:
1517 try:
1518 cMBRam = oSession.o.machine.memorySize;
1519 except:
1520 cMBRam = self.cMBRamMax + 4;
1521 if self.cMBRamMax < cMBRam:
1522 fRc = oSession.setRamSize(self.cMBRamMax);
1523
1524 return fRc;
1525
1526
1527class TestVmSet(object):
1528 """
1529 A set of Test VMs.
1530 """
1531
1532 def __init__(self, oTestVmManager = None, acCpus = None, asVirtModes = None, fIgnoreSkippedVm = False):
1533 self.oTestVmManager = oTestVmManager;
1534 if acCpus is None:
1535 acCpus = [1, 2];
1536 self.acCpusDef = acCpus;
1537 self.acCpus = acCpus;
1538 if asVirtModes is None:
1539 asVirtModes = list(g_asVirtModes);
1540 self.asVirtModesDef = asVirtModes;
1541 self.asVirtModes = asVirtModes;
1542 self.aoTestVms = [] # type: list(BaseTestVm)
1543 self.fIgnoreSkippedVm = fIgnoreSkippedVm;
1544 self.asParavirtModes = None; ##< If None, use the first PV mode of the test VM, otherwise all modes in this list.
1545
1546 def findTestVmByName(self, sVmName):
1547 """
1548 Returns the TestVm object with the given name.
1549 Returns None if not found.
1550 """
1551
1552 # The 'tst-' prefix is optional.
1553 sAltName = sVmName if sVmName.startswith('tst-') else 'tst-' + sVmName;
1554
1555 for oTestVm in self.aoTestVms:
1556 if oTestVm.sVmName in (sVmName, sAltName):
1557 return oTestVm;
1558 return None;
1559
1560 def getAllVmNames(self, sSep = ':'):
1561 """
1562 Returns names of all the test VMs in the set separated by
1563 sSep (defaults to ':').
1564 """
1565 sVmNames = '';
1566 for oTestVm in self.aoTestVms:
1567 sName = oTestVm.sVmName;
1568 if sName.startswith('tst-'):
1569 sName = sName[4:];
1570 if sVmNames == '':
1571 sVmNames = sName;
1572 else:
1573 sVmNames = sVmNames + sSep + sName;
1574 return sVmNames;
1575
1576 def showUsage(self):
1577 """
1578 Invoked by vbox.TestDriver.
1579 """
1580 reporter.log('');
1581 reporter.log('Test VM selection and general config options:');
1582 reporter.log(' --virt-modes <m1[:m2[:...]]>');
1583 reporter.log(' Default: %s' % (':'.join(self.asVirtModesDef)));
1584 reporter.log(' --skip-virt-modes <m1[:m2[:...]]>');
1585 reporter.log(' Use this to avoid hwvirt or hwvirt-np when not supported by the host');
1586 reporter.log(' since we cannot detect it using the main API. Use after --virt-modes.');
1587 reporter.log(' --cpu-counts <c1[:c2[:...]]>');
1588 reporter.log(' Default: %s' % (':'.join(str(c) for c in self.acCpusDef)));
1589 reporter.log(' --test-vms <vm1[:vm2[:...]]>');
1590 reporter.log(' Test the specified VMs in the given order. Use this to change');
1591 reporter.log(' the execution order or limit the choice of VMs');
1592 reporter.log(' Default: %s (all)' % (self.getAllVmNames(),));
1593 reporter.log(' --skip-vms <vm1[:vm2[:...]]>');
1594 reporter.log(' Skip the specified VMs when testing.');
1595 reporter.log(' --skip-win-vms');
1596 reporter.log(' Skips Windows test VMs (accumulative).');
1597 reporter.log(' --skip-non-win-vms');
1598 reporter.log(' Skips non-Windows test VMs (accumulative).');
1599 reporter.log(' --snapshot-restore-current');
1600 reporter.log(' Restores the current snapshot and resumes execution.');
1601 reporter.log(' --paravirt-modes <pv1[:pv2[:...]]>');
1602 reporter.log(' Set of paravirtualized providers (modes) to tests. Intersected with what the test VM supports.');
1603 reporter.log(' Default is the first PV mode the test VMs support, generally same as "legacy".');
1604 reporter.log(' --with-nested-hwvirt-only');
1605 reporter.log(' Test VMs using nested hardware-virtualization only.');
1606 reporter.log(' --without-nested-hwvirt-only');
1607 reporter.log(' Test VMs not using nested hardware-virtualization only.');
1608 ## @todo Add more options for controlling individual VMs.
1609 return True;
1610
1611 def parseOption(self, asArgs, iArg):
1612 """
1613 Parses the set test vm set options (--test-vms and --skip-vms), modifying the set
1614 Invoked by the testdriver method with the same name.
1615
1616 Keyword arguments:
1617 asArgs -- The argument vector.
1618 iArg -- The index of the current argument.
1619
1620 Returns iArg if the option was not recognized and the caller should handle it.
1621 Returns the index of the next argument when something is consumed.
1622
1623 In the event of a syntax error, a InvalidOption or QuietInvalidOption
1624 is thrown.
1625 """
1626
1627 if asArgs[iArg] == '--virt-modes':
1628 iArg += 1;
1629 if iArg >= len(asArgs):
1630 raise base.InvalidOption('The "--virt-modes" takes a colon separated list of modes');
1631
1632 self.asVirtModes = asArgs[iArg].split(':');
1633 for s in self.asVirtModes:
1634 if s not in self.asVirtModesDef:
1635 raise base.InvalidOption('The "--virt-modes" value "%s" is not valid; valid values are: %s' \
1636 % (s, ' '.join(self.asVirtModesDef)));
1637
1638 elif asArgs[iArg] == '--skip-virt-modes':
1639 iArg += 1;
1640 if iArg >= len(asArgs):
1641 raise base.InvalidOption('The "--skip-virt-modes" takes a colon separated list of modes');
1642
1643 for s in asArgs[iArg].split(':'):
1644 if s not in self.asVirtModesDef:
1645 raise base.InvalidOption('The "--virt-modes" value "%s" is not valid; valid values are: %s' \
1646 % (s, ' '.join(self.asVirtModesDef)));
1647 if s in self.asVirtModes:
1648 self.asVirtModes.remove(s);
1649
1650 elif asArgs[iArg] == '--cpu-counts':
1651 iArg += 1;
1652 if iArg >= len(asArgs):
1653 raise base.InvalidOption('The "--cpu-counts" takes a colon separated list of cpu counts');
1654
1655 self.acCpus = [];
1656 for s in asArgs[iArg].split(':'):
1657 try: c = int(s);
1658 except: raise base.InvalidOption('The "--cpu-counts" value "%s" is not an integer' % (s,));
1659 if c <= 0: raise base.InvalidOption('The "--cpu-counts" value "%s" is zero or negative' % (s,));
1660 self.acCpus.append(c);
1661
1662 elif asArgs[iArg] == '--test-vms':
1663 iArg += 1;
1664 if iArg >= len(asArgs):
1665 raise base.InvalidOption('The "--test-vms" takes colon separated list');
1666
1667 for oTestVm in self.aoTestVms:
1668 oTestVm.fSkip = True;
1669
1670 asTestVMs = asArgs[iArg].split(':');
1671 for s in asTestVMs:
1672 oTestVm = self.findTestVmByName(s);
1673 if oTestVm is None:
1674 raise base.InvalidOption('The "--test-vms" value "%s" is not valid; valid values are: %s' \
1675 % (s, self.getAllVmNames(' ')));
1676 oTestVm.fSkip = False;
1677
1678 elif asArgs[iArg] == '--skip-vms':
1679 iArg += 1;
1680 if iArg >= len(asArgs):
1681 raise base.InvalidOption('The "--skip-vms" takes colon separated list');
1682
1683 asTestVMs = asArgs[iArg].split(':');
1684 for s in asTestVMs:
1685 oTestVm = self.findTestVmByName(s);
1686 if oTestVm is None:
1687 reporter.log('warning: The "--test-vms" value "%s" does not specify any of our test VMs.' % (s,));
1688 else:
1689 oTestVm.fSkip = True;
1690
1691 elif asArgs[iArg] == '--skip-win-vms':
1692 asTestVMs = asArgs[iArg].split(':');
1693 for oTestVm in self.aoTestVms:
1694 if oTestVm.isWindows():
1695 oTestVm.fSkip = True;
1696
1697 elif asArgs[iArg] == '--skip-non-win-vms':
1698 asTestVMs = asArgs[iArg].split(':');
1699 for oTestVm in self.aoTestVms:
1700 if not oTestVm.isWindows():
1701 oTestVm.fSkip = True;
1702
1703 elif asArgs[iArg] == '--snapshot-restore-current':
1704 for oTestVm in self.aoTestVms:
1705 if oTestVm.fSkip is False:
1706 oTestVm.fSnapshotRestoreCurrent = True;
1707 reporter.log('VM "%s" will be restored.' % (oTestVm.sVmName));
1708
1709 elif asArgs[iArg] == '--paravirt-modes':
1710 iArg += 1
1711 if iArg >= len(asArgs):
1712 raise base.InvalidOption('The "--paravirt-modes" takes a colon separated list of modes');
1713
1714 self.asParavirtModes = asArgs[iArg].split(':')
1715 for sPvMode in self.asParavirtModes:
1716 if sPvMode not in g_kasParavirtProviders:
1717 raise base.InvalidOption('The "--paravirt-modes" value "%s" is not valid; valid values are: %s'
1718 % (sPvMode, ', '.join(g_kasParavirtProviders),));
1719 if not self.asParavirtModes:
1720 self.asParavirtModes = None;
1721
1722 # HACK ALERT! Reset the random paravirt selection for members.
1723 for oTestVm in self.aoTestVms:
1724 oTestVm.asParavirtModesSup = oTestVm.asParavirtModesSupOrg;
1725
1726 elif asArgs[iArg] == '--with-nested-hwvirt-only':
1727 for oTestVm in self.aoTestVms:
1728 if oTestVm.fNstHwVirt is False:
1729 oTestVm.fSkip = True;
1730
1731 elif asArgs[iArg] == '--without-nested-hwvirt-only':
1732 for oTestVm in self.aoTestVms:
1733 if oTestVm.fNstHwVirt is True:
1734 oTestVm.fSkip = True;
1735
1736 else:
1737 return iArg;
1738 return iArg + 1;
1739
1740 def getResourceSet(self):
1741 """
1742 Called vbox.TestDriver.getResourceSet and returns a list of paths of resources.
1743 """
1744 asResources = [];
1745 for oTestVm in self.aoTestVms:
1746 if not oTestVm.fSkip:
1747 if isinstance(oTestVm, BaseTestVm): # Temporarily...
1748 asResources.extend(oTestVm.getResourceSet());
1749 else:
1750 if oTestVm.sHd is not None:
1751 asResources.append(oTestVm.sHd);
1752 if oTestVm.sDvdImage is not None:
1753 asResources.append(oTestVm.sDvdImage);
1754 return asResources;
1755
1756 def actionConfig(self, oTestDrv, eNic0AttachType = None, sDvdImage = None):
1757 """
1758 For base.TestDriver.actionConfig. Configure the VMs with defaults and
1759 a few tweaks as per arguments.
1760
1761 Returns True if successful.
1762 Returns False if not.
1763 """
1764
1765 for oTestVm in self.aoTestVms:
1766 if oTestVm.fSkip:
1767 continue;
1768 if oTestVm.skipCreatingVm(oTestDrv):
1769 oTestVm.fSkip = True;
1770 continue;
1771
1772 if oTestVm.fSnapshotRestoreCurrent:
1773 # If we want to restore a VM we don't need to create
1774 # the machine anymore -- so just add it to the test VM list.
1775 oVM = oTestDrv.addTestMachine(oTestVm.sVmName);
1776 else:
1777 oVM = oTestVm.createVm(oTestDrv, eNic0AttachType, sDvdImage);
1778 if oVM is None:
1779 return False;
1780
1781 return True;
1782
1783 def _removeUnsupportedVirtModes(self, oTestDrv):
1784 """
1785 Removes unsupported virtualization modes.
1786 """
1787 if 'hwvirt' in self.asVirtModes and not oTestDrv.hasHostHwVirt():
1788 reporter.log('Hardware assisted virtualization is not available on the host, skipping it.');
1789 self.asVirtModes.remove('hwvirt');
1790
1791 if 'hwvirt-np' in self.asVirtModes and not oTestDrv.hasHostNestedPaging():
1792 reporter.log('Nested paging not supported by the host, skipping it.');
1793 self.asVirtModes.remove('hwvirt-np');
1794
1795 if 'raw' in self.asVirtModes and not oTestDrv.hasRawModeSupport():
1796 reporter.log('Raw-mode virtualization is not available in this build (or perhaps for this host), skipping it.');
1797 self.asVirtModes.remove('raw');
1798
1799 return True;
1800
1801 def actionExecute(self, oTestDrv, fnCallback): # pylint: disable=too-many-locals
1802 """
1803 For base.TestDriver.actionExecute. Calls the callback function for
1804 each of the VMs and basic configuration variations (virt-mode and cpu
1805 count).
1806
1807 Returns True if all fnCallback calls returned True, otherwise False.
1808
1809 The callback can return True, False or None. The latter is for when the
1810 test is skipped. (True is for success, False is for failure.)
1811 """
1812
1813 self._removeUnsupportedVirtModes(oTestDrv);
1814 cMaxCpus = oTestDrv.getHostCpuCount();
1815
1816 #
1817 # The test loop.
1818 #
1819 fRc = True;
1820 for oTestVm in self.aoTestVms:
1821 if oTestVm.fSkip and self.fIgnoreSkippedVm:
1822 reporter.log2('Ignoring VM %s (fSkip = True).' % (oTestVm.sVmName,));
1823 continue;
1824 reporter.testStart(oTestVm.sVmName);
1825 if oTestVm.fSkip:
1826 reporter.testDone(fSkipped = True);
1827 continue;
1828
1829 # Intersect the supported modes and the ones being testing.
1830 asVirtModesSup = [sMode for sMode in oTestVm.asVirtModesSup if sMode in self.asVirtModes];
1831
1832 # Ditto for CPUs.
1833 acCpusSup = [cCpus for cCpus in oTestVm.acCpusSup if cCpus in self.acCpus];
1834
1835 # Ditto for paravirtualization modes, except if not specified we got a less obvious default.
1836 if self.asParavirtModes is not None and oTestDrv.fpApiVer >= 5.0:
1837 asParavirtModes = [sPvMode for sPvMode in oTestVm.asParavirtModesSup if sPvMode in self.asParavirtModes];
1838 assert None not in asParavirtModes;
1839 elif oTestDrv.fpApiVer >= 5.0:
1840 asParavirtModes = (oTestVm.asParavirtModesSup[0],);
1841 assert asParavirtModes[0] is not None;
1842 else:
1843 asParavirtModes = (None,);
1844
1845 for cCpus in acCpusSup:
1846 if cCpus == 1:
1847 reporter.testStart('1 cpu');
1848 else:
1849 reporter.testStart('%u cpus' % (cCpus));
1850 if cCpus > cMaxCpus:
1851 reporter.testDone(fSkipped = True);
1852 continue;
1853
1854 cTests = 0;
1855 for sVirtMode in asVirtModesSup:
1856 if sVirtMode == 'raw' and cCpus > 1:
1857 continue;
1858 reporter.testStart('%s' % ( g_dsVirtModeDescs[sVirtMode], ) );
1859 cStartTests = cTests;
1860
1861 for sParavirtMode in asParavirtModes:
1862 if sParavirtMode is not None:
1863 assert oTestDrv.fpApiVer >= 5.0;
1864 reporter.testStart('%s' % ( sParavirtMode, ) );
1865
1866 # Reconfigure the VM.
1867 try:
1868 (rc2, oVM) = oTestVm.getReconfiguredVm(oTestDrv, cCpus, sVirtMode, sParavirtMode = sParavirtMode);
1869 except KeyboardInterrupt:
1870 raise;
1871 except:
1872 reporter.errorXcpt(cFrames = 9);
1873 rc2 = False;
1874 if rc2 is True:
1875 # Do the testing.
1876 try:
1877 rc2 = fnCallback(oVM, oTestVm);
1878 except KeyboardInterrupt:
1879 raise;
1880 except:
1881 reporter.errorXcpt(cFrames = 9);
1882 rc2 = False;
1883 if rc2 is False:
1884 reporter.maybeErr(reporter.testErrorCount() == 0, 'fnCallback failed');
1885 elif rc2 is False:
1886 reporter.log('getReconfiguredVm failed');
1887 if rc2 is False:
1888 fRc = False;
1889
1890 cTests = cTests + (rc2 is not None);
1891 if sParavirtMode is not None:
1892 reporter.testDone(fSkipped = rc2 is None);
1893
1894 reporter.testDone(fSkipped = cTests == cStartTests);
1895
1896 reporter.testDone(fSkipped = cTests == 0);
1897
1898 _, cErrors = reporter.testDone();
1899 if cErrors > 0:
1900 fRc = False;
1901 return fRc;
1902
1903 def enumerateTestVms(self, fnCallback):
1904 """
1905 Enumerates all the 'active' VMs.
1906
1907 Returns True if all fnCallback calls returned True.
1908 Returns False if any returned False.
1909 Returns None immediately if fnCallback returned None.
1910 """
1911 fRc = True;
1912 for oTestVm in self.aoTestVms:
1913 if not oTestVm.fSkip:
1914 fRc2 = fnCallback(oTestVm);
1915 if fRc2 is None:
1916 return fRc2;
1917 fRc = fRc and fRc2;
1918 return fRc;
1919
1920
1921
1922class TestVmManager(object):
1923 """
1924 Test VM manager.
1925 """
1926
1927 ## @name VM grouping flags
1928 ## @{
1929 kfGrpSmoke = g_kfGrpSmoke;
1930 kfGrpStandard = g_kfGrpStandard;
1931 kfGrpStdSmoke = g_kfGrpStdSmoke;
1932 kfGrpWithGAs = g_kfGrpWithGAs;
1933 kfGrpNoTxs = g_kfGrpNoTxs;
1934 kfGrpAncient = g_kfGrpAncient;
1935 kfGrpExotic = g_kfGrpExotic;
1936 ## @}
1937
1938 kaTestVMs = (
1939 # Note: The images in the 6.1 folder all have been pre-configured to allow for Guest Additions installation
1940 # (come with build essentials, kernel headers).
1941 # Linux
1942 TestVm('tst-ubuntu-18_04_3-64', kfGrpStdSmoke, sHd = '6.1/ubuntu-18_04_3-amd64-2.vdi',
1943 sKind = 'Ubuntu_64', acCpusSup = range(1, 33), fIoApic = True,
1944 asParavirtModesSup = [g_ksParavirtProviderKVM,]),
1945 # Note: Deprecated; had SELinux + Screensaver (black screen) enabled.
1946 #TestVm('tst-ol-8_1-64-efi', kfGrpStdSmoke, sHd = '6.1/efi/ol-8_1-efi-amd64.vdi',
1947 # sKind = 'Oracle_64', acCpusSup = range(1, 33), fIoApic = True, sFirmwareType = 'efi',
1948 # asParavirtModesSup = [g_ksParavirtProviderKVM,]),
1949 TestVm('tst-ol-8_1-64-efi', kfGrpStdSmoke, sHd = '6.1/efi/ol-8_1-efi-amd64-2.vdi',
1950 sKind = 'Oracle_64', acCpusSup = range(1, 33), fIoApic = True, sFirmwareType = 'efi',
1951 asParavirtModesSup = [g_ksParavirtProviderKVM,]),
1952 TestVm('tst-ol-6u2-32', kfGrpStdSmoke, sHd = '6.1/ol-6u2-x86.vdi',
1953 sKind = 'Oracle', acCpusSup = range(1, 33), fIoApic = True,
1954 asParavirtModesSup = [g_ksParavirtProviderKVM,]),
1955 TestVm('tst-ubuntu-15_10-64-efi', kfGrpStdSmoke, sHd = '6.1/efi/ubuntu-15_10-efi-amd64-3.vdi',
1956 sKind = 'Ubuntu_64', acCpusSup = range(1, 33), fIoApic = True, sFirmwareType = 'efi',
1957 asParavirtModesSup = [g_ksParavirtProviderKVM,]),
1958 # Note: Deprecated / buggy; use the one in the 6.1 folder.
1959 #TestVm('tst-ubuntu-15_10-64-efi', kfGrpStdSmoke, sHd = '4.2/efi/ubuntu-15_10-efi-amd64.vdi',
1960 # sKind = 'Ubuntu_64', acCpusSup = range(1, 33), fIoApic = True, sFirmwareType = 'efi',
1961 # asParavirtModesSup = [g_ksParavirtProviderKVM,]),
1962 TestVm('tst-rhel5', kfGrpSmoke, sHd = '3.0/tcp/rhel5.vdi',
1963 sKind = 'RedHat', acCpusSup = range(1, 33), fIoApic = True, sNic0AttachType = 'nat'),
1964 TestVm('tst-arch', kfGrpStandard, sHd = '4.2/usb/tst-arch.vdi',
1965 sKind = 'ArchLinux_64', acCpusSup = range(1, 33), fIoApic = True, sNic0AttachType = 'nat'),
1966 # disabled 2019-03-08 klaus - fails all over the place and pollutes the test results
1967 #TestVm('tst-ubuntu-1804-64', kfGrpStdSmoke, sHd = '4.2/ubuntu-1804/t-ubuntu-1804-64.vdi',
1968 # sKind = 'Ubuntu_64', acCpusSup = range(1, 33), fIoApic = True),
1969 TestVm('tst-ol76-64', kfGrpStdSmoke, sHd = '4.2/ol76/t-ol76-64.vdi',
1970 sKind = 'Oracle_64', acCpusSup = range(1, 33), fIoApic = True),
1971 TestVm('tst-ubuntu-20_04-64-amdvi', kfGrpStdSmoke, sHd = '6.1/ubuntu-20_04-64.vdi',
1972 sKind = 'Ubuntu_64', acCpusSup = range(1, 33), fIoApic = True,
1973 asParavirtModesSup = [g_ksParavirtProviderKVM,], sNic0AttachType = 'nat', sChipsetType = 'ich9',
1974 sIommuType = 'amd'),
1975 TestVm('tst-ubuntu-20_04-64-vtd', kfGrpStdSmoke, sHd = '6.1/ubuntu-20_04-64.vdi',
1976 sKind = 'Ubuntu_64', acCpusSup = range(1, 33), fIoApic = True,
1977 asParavirtModesSup = [g_ksParavirtProviderKVM,], sNic0AttachType = 'nat', sChipsetType = 'ich9',
1978 sIommuType = 'intel'),
1979
1980 # Solaris
1981 TestVm('tst-sol10', kfGrpSmoke, sHd = '3.0/tcp/solaris10.vdi',
1982 sKind = 'Solaris', acCpusSup = range(1, 33), fPae = True, sNic0AttachType = 'bridged'),
1983 TestVm('tst-sol10-64', kfGrpSmoke, sHd = '3.0/tcp/solaris10.vdi',
1984 sKind = 'Solaris_64', acCpusSup = range(1, 33), sNic0AttachType = 'bridged'),
1985 TestVm('tst-sol11u1', kfGrpSmoke, sHd = '4.2/nat/sol11u1/t-sol11u1.vdi',
1986 sKind = 'Solaris11_64', acCpusSup = range(1, 33), sNic0AttachType = 'nat', fIoApic = True,
1987 sHddControllerType = 'SATA Controller'),
1988 #TestVm('tst-sol11u1-ich9', kfGrpSmoke, sHd = '4.2/nat/sol11u1/t-sol11u1.vdi',
1989 # sKind = 'Solaris11_64', acCpusSup = range(1, 33), sNic0AttachType = 'nat', fIoApic = True,
1990 # sHddControllerType = 'SATA Controller', sChipsetType = 'ich9'),
1991
1992 # NT 3.x
1993 TestVm('tst-nt310', kfGrpAncient, sHd = '5.2/great-old-ones/t-nt310/t-nt310.vdi',
1994 sKind = 'WindowsNT3x', acCpusSup = [1], sHddControllerType = 'BusLogic SCSI Controller',
1995 sDvdControllerType = 'BusLogic SCSI Controller'),
1996 TestVm('tst-nt350', kfGrpAncient, sHd = '5.2/great-old-ones/t-nt350/t-nt350.vdi',
1997 sKind = 'WindowsNT3x', acCpusSup = [1], sHddControllerType = 'BusLogic SCSI Controller',
1998 sDvdControllerType = 'BusLogic SCSI Controller'),
1999 TestVm('tst-nt351', kfGrpAncient, sHd = '5.2/great-old-ones/t-nt350/t-nt351.vdi',
2000 sKind = 'WindowsNT3x', acCpusSup = [1], sHddControllerType = 'BusLogic SCSI Controller',
2001 sDvdControllerType = 'BusLogic SCSI Controller'),
2002
2003 # NT 4
2004 TestVm('tst-nt4sp1', kfGrpStdSmoke, sHd = '4.2/nat/nt4sp1/t-nt4sp1.vdi',
2005 sKind = 'WindowsNT4', acCpusSup = [1], sNic0AttachType = 'nat'),
2006
2007 TestVm('tst-nt4sp6', kfGrpStdSmoke, sHd = '4.2/nt4sp6/t-nt4sp6.vdi',
2008 sKind = 'WindowsNT4', acCpusSup = range(1, 33)),
2009
2010 # W2K
2011 TestVm('tst-w2ksp4', kfGrpStdSmoke, sHd = '4.2/win2ksp4/t-win2ksp4.vdi',
2012 sKind = 'Windows2000', acCpusSup = range(1, 33)),
2013
2014 # XP
2015 TestVm('tst-xppro', kfGrpStdSmoke, sHd = '4.2/nat/xppro/t-xppro.vdi',
2016 sKind = 'WindowsXP', acCpusSup = range(1, 33), sNic0AttachType = 'nat'),
2017 TestVm('tst-xpsp2', kfGrpStdSmoke, sHd = '4.2/xpsp2/t-winxpsp2.vdi',
2018 sKind = 'WindowsXP', acCpusSup = range(1, 33), fIoApic = True),
2019 TestVm('tst-xpsp2-halaacpi', kfGrpStdSmoke, sHd = '4.2/xpsp2/t-winxp-halaacpi.vdi',
2020 sKind = 'WindowsXP', acCpusSup = range(1, 33), fIoApic = True),
2021 TestVm('tst-xpsp2-halacpi', kfGrpStdSmoke, sHd = '4.2/xpsp2/t-winxp-halacpi.vdi',
2022 sKind = 'WindowsXP', acCpusSup = range(1, 33), fIoApic = True),
2023 TestVm('tst-xpsp2-halapic', kfGrpStdSmoke, sHd = '4.2/xpsp2/t-winxp-halapic.vdi',
2024 sKind = 'WindowsXP', acCpusSup = range(1, 33), fIoApic = True),
2025 TestVm('tst-xpsp2-halmacpi', kfGrpStdSmoke, sHd = '4.2/xpsp2/t-winxp-halmacpi.vdi',
2026 sKind = 'WindowsXP', acCpusSup = range(2, 33), fIoApic = True),
2027 TestVm('tst-xpsp2-halmps', kfGrpStdSmoke, sHd = '4.2/xpsp2/t-winxp-halmps.vdi',
2028 sKind = 'WindowsXP', acCpusSup = range(2, 33), fIoApic = True),
2029
2030 # W2K3
2031 TestVm('tst-win2k3ent', kfGrpSmoke, sHd = '3.0/tcp/win2k3ent-acpi.vdi',
2032 sKind = 'Windows2003', acCpusSup = range(1, 33), fPae = True, sNic0AttachType = 'bridged'),
2033
2034 # W7
2035 TestVm('tst-win7', kfGrpStdSmoke, sHd = '6.1/win7-32/t-win7-32-1.vdi',
2036 sKind = 'Windows7', acCpusSup = range(1, 33), fIoApic = True),
2037 # Note: Deprecated due to activation issues; use t-win7-32-1 instead.
2038 #TestVm('tst-win7', kfGrpStdSmoke, sHd = '6.1/win7-32/t-win7-32.vdi',
2039 # sKind = 'Windows7', acCpusSup = range(1, 33), fIoApic = True),
2040 # Note: Deprecated; use the one in the 6.1 folder.
2041 #TestVm('tst-win7', kfGrpStdSmoke, sHd = '4.2/win7-32/t-win7.vdi',
2042 # sKind = 'Windows7', acCpusSup = range(1, 33), fIoApic = True),
2043
2044 # W8
2045 TestVm('tst-win8-64', kfGrpStdSmoke, sHd = '4.2/win8-64/t-win8-64.vdi',
2046 sKind = 'Windows8_64', acCpusSup = range(1, 33), fIoApic = True),
2047 #TestVm('tst-win8-64-ich9', kfGrpStdSmoke, sHd = '4.2/win8-64/t-win8-64.vdi',
2048 # sKind = 'Windows8_64', acCpusSup = range(1, 33), fIoApic = True, sChipsetType = 'ich9'),
2049
2050 # W10
2051 TestVm('tst-win10-efi', kfGrpStdSmoke, sHd = '4.2/efi/win10-efi-x86.vdi',
2052 sKind = 'Windows10', acCpusSup = range(1, 33), fIoApic = True, sFirmwareType = 'efi'),
2053 TestVm('tst-win10-64-efi', kfGrpStdSmoke, sHd = '4.2/efi/win10-efi-amd64.vdi',
2054 sKind = 'Windows10_64', acCpusSup = range(1, 33), fIoApic = True, sFirmwareType = 'efi'),
2055 #TestVm('tst-win10-64-efi-ich9', kfGrpStdSmoke, sHd = '4.2/efi/win10-efi-amd64.vdi',
2056 # sKind = 'Windows10_64', acCpusSup = range(1, 33), fIoApic = True, sFirmwareType = 'efi', sChipsetType = 'ich9'),
2057
2058 # Nested hardware-virtualization
2059 TestVm('tst-nsthwvirt-ubuntu-64', kfGrpStdSmoke, sHd = '5.3/nat/nsthwvirt-ubuntu64/t-nsthwvirt-ubuntu64.vdi',
2060 sKind = 'Ubuntu_64', acCpusSup = range(1, 2), asVirtModesSup = ['hwvirt-np',], fIoApic = True, fNstHwVirt = True,
2061 sNic0AttachType = 'nat'),
2062
2063 # Audio testing.
2064 TestVm('tst-audio-debian10-64', kfGrpStdSmoke, sHd = '6.1/audio/debian10-amd64-7.vdi',
2065 sKind = 'Debian_64', acCpusSup = range(1, 33), fIoApic = True),
2066
2067 # DOS and Old Windows.
2068 AncientTestVm('tst-dos20', sKind = 'DOS',
2069 sHd = '5.2/great-old-ones/t-dos20/t-dos20.vdi'),
2070 AncientTestVm('tst-dos401-win30me', sKind = 'DOS',
2071 sHd = '5.2/great-old-ones/t-dos401-win30me/t-dos401-win30me.vdi', cMBRamMax = 4),
2072 AncientTestVm('tst-dos401-emm386-win30me', sKind = 'DOS',
2073 sHd = '5.2/great-old-ones/t-dos401-emm386-win30me/t-dos401-emm386-win30me.vdi', cMBRamMax = 4),
2074 AncientTestVm('tst-dos50-win31', sKind = 'DOS',
2075 sHd = '5.2/great-old-ones/t-dos50-win31/t-dos50-win31.vdi'),
2076 AncientTestVm('tst-dos50-emm386-win31', sKind = 'DOS',
2077 sHd = '5.2/great-old-ones/t-dos50-emm386-win31/t-dos50-emm386-win31.vdi'),
2078 AncientTestVm('tst-dos622', sKind = 'DOS',
2079 sHd = '5.2/great-old-ones/t-dos622/t-dos622.vdi'),
2080 AncientTestVm('tst-dos622-emm386', sKind = 'DOS',
2081 sHd = '5.2/great-old-ones/t-dos622-emm386/t-dos622-emm386.vdi'),
2082 AncientTestVm('tst-dos71', sKind = 'DOS',
2083 sHd = '5.2/great-old-ones/t-dos71/t-dos71.vdi'),
2084
2085 #AncientTestVm('tst-dos5-win311a', sKind = 'DOS', sHd = '5.2/great-old-ones/t-dos5-win311a/t-dos5-win311a.vdi'),
2086 );
2087
2088
2089 def __init__(self, sResourcePath):
2090 self.sResourcePath = sResourcePath;
2091
2092 def selectSet(self, fGrouping, sTxsTransport = None, fCheckResources = True):
2093 """
2094 Returns a VM set with the selected VMs.
2095 """
2096 oSet = TestVmSet(oTestVmManager = self);
2097 for oVm in self.kaTestVMs:
2098 if oVm.fGrouping & fGrouping:
2099 if sTxsTransport is None or oVm.sNic0AttachType is None or sTxsTransport == oVm.sNic0AttachType:
2100 if not fCheckResources or not oVm.getMissingResources(self.sResourcePath):
2101 oCopyVm = copy.deepcopy(oVm);
2102 oCopyVm.oSet = oSet;
2103 oSet.aoTestVms.append(oCopyVm);
2104 return oSet;
2105
2106 def getStandardVmSet(self, sTxsTransport):
2107 """
2108 Gets the set of standard test VMs.
2109
2110 This is supposed to do something seriously clever, like searching the
2111 testrsrc tree for usable VMs, but for the moment it's all hard coded. :-)
2112 """
2113 return self.selectSet(self.kfGrpStandard, sTxsTransport)
2114
2115 def getSmokeVmSet(self, sTxsTransport = None):
2116 """Gets a representative set of VMs for smoke testing. """
2117 return self.selectSet(self.kfGrpSmoke, sTxsTransport);
2118
2119 def shutUpPyLint(self):
2120 """ Shut up already! """
2121 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