VirtualBox

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

Last change on this file since 95935 was 95935, checked in by vboxsync, 2 years ago

Validation Kit/vboxtestvms.py: Added couple more Windows server variants which were missing before, also Windows 11.

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