VirtualBox

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

Last change on this file since 94126 was 94126, checked in by vboxsync, 3 years ago

ValKit/testdriver: pylint 2.9.6 adjustments (mostly about using 'with' statements).

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