VirtualBox

source: vbox/trunk/src/VBox/ValidationKit/tests/additions/tdAddBasic1.py@ 103914

Last change on this file since 103914 was 100700, checked in by vboxsync, 17 months ago

ValKit/tdAddGuestCtrl.py: Check if VM needs reboot before installing GAs (pylint fix)

  • Property svn:eol-style set to LF
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 35.3 KB
Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3# $Id: tdAddBasic1.py 100700 2023-07-25 18:37:10Z vboxsync $
4
5"""
6VirtualBox Validation Kit - Additions Basics #1.
7"""
8
9__copyright__ = \
10"""
11Copyright (C) 2010-2023 Oracle and/or its affiliates.
12
13This file is part of VirtualBox base platform packages, as
14available from https://www.virtualbox.org.
15
16This program is free software; you can redistribute it and/or
17modify it under the terms of the GNU General Public License
18as published by the Free Software Foundation, in version 3 of the
19License.
20
21This program is distributed in the hope that it will be useful, but
22WITHOUT ANY WARRANTY; without even the implied warranty of
23MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24General Public License for more details.
25
26You should have received a copy of the GNU General Public License
27along with this program; if not, see <https://www.gnu.org/licenses>.
28
29The contents of this file may alternatively be used under the terms
30of the Common Development and Distribution License Version 1.0
31(CDDL), a copy of it is provided in the "COPYING.CDDL" file included
32in the VirtualBox distribution, in which case the provisions of the
33CDDL are applicable instead of those of the GPL.
34
35You may elect to license modified versions of this file under the
36terms and conditions of either the GPL or the CDDL or both.
37
38SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
39"""
40__version__ = "$Revision: 100700 $"
41
42# Standard Python imports.
43import os;
44import sys;
45import uuid;
46
47# Only the main script needs to modify the path.
48try: __file__ # pylint: disable=used-before-assignment
49except: __file__ = sys.argv[0];
50g_ksValidationKitDir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))));
51sys.path.append(g_ksValidationKitDir);
52
53# Validation Kit imports.
54from testdriver import reporter;
55from testdriver import base;
56from testdriver import vbox;
57from testdriver import vboxcon;
58
59# Sub-test driver imports.
60sys.path.append(os.path.dirname(os.path.abspath(__file__))); # For sub-test drivers.
61from tdAddGuestCtrl import SubTstDrvAddGuestCtrl;
62from tdAddSharedFolders1 import SubTstDrvAddSharedFolders1;
63
64
65class tdAddBasic1(vbox.TestDriver): # pylint: disable=too-many-instance-attributes
66 """
67 Additions Basics #1.
68 """
69 ## @todo
70 # - More of the settings stuff can be and need to be generalized!
71 #
72
73 def __init__(self):
74 vbox.TestDriver.__init__(self);
75 self.oTestVmSet = self.oTestVmManager.getSmokeVmSet('nat');
76 self.asTestsDef = ['install', 'guestprops', 'stdguestprops', 'guestcontrol', 'sharedfolders'];
77 self.asTests = self.asTestsDef;
78 self.asRsrcs = None
79 # The file we're going to use as a beacon to wait if the Guest Additions CD-ROM is ready.
80 self.sFileCdWait = '';
81 # Path pointing to the Guest Additions on the (V)ISO file.
82 self.sGstPathGaPrefix = '';
83
84 # Wether to reboot guest after Guest Additions installation.
85 self.fRebootAfterInstall = True;
86
87 self.addSubTestDriver(SubTstDrvAddGuestCtrl(self));
88 self.addSubTestDriver(SubTstDrvAddSharedFolders1(self));
89
90 #
91 # Overridden methods.
92 #
93 def showUsage(self):
94 """ Shows this driver's command line options. """
95 rc = vbox.TestDriver.showUsage(self);
96 reporter.log('');
97 reporter.log('tdAddBasic1 Options:');
98 reporter.log(' --tests <s1[:s2[:]]>');
99 reporter.log(' Default: %s (all)' % (':'.join(self.asTestsDef)));
100 reporter.log(' --quick');
101 reporter.log(' Same as --virt-modes hwvirt --cpu-counts 1.');
102 reporter.log(' --no-reboot-after-install');
103 reporter.log(' Do not reboot guest after Guest Additions installation.');
104 return rc;
105
106 def parseOption(self, asArgs, iArg): # pylint: disable=too-many-branches,too-many-statements
107 if asArgs[iArg] == '--tests':
108 iArg += 1;
109 if iArg >= len(asArgs): raise base.InvalidOption('The "--tests" takes a colon separated list of tests');
110 self.asTests = asArgs[iArg].split(':');
111 for s in self.asTests:
112 if s not in self.asTestsDef:
113 raise base.InvalidOption('The "--tests" value "%s" is not valid; valid values are: %s'
114 % (s, ' '.join(self.asTestsDef),));
115
116 elif asArgs[iArg] == '--quick':
117 self.parseOption(['--virt-modes', 'hwvirt'], 0);
118 self.parseOption(['--cpu-counts', '1'], 0);
119
120 elif asArgs[iArg] == '--no-reboot-after-install':
121 self.fRebootAfterInstall = False;
122 reporter.log('Guest will not be rebooted after Guest Additions installation, ' +
123 'kernel modules and user services should be reloaded automatically without reboot');
124
125 else:
126 return vbox.TestDriver.parseOption(self, asArgs, iArg);
127 return iArg + 1;
128
129 def getResourceSet(self):
130 if self.asRsrcs is None:
131 self.asRsrcs = []
132 for oSubTstDrv in self.aoSubTstDrvs:
133 self.asRsrcs.extend(oSubTstDrv.asRsrcs)
134 self.asRsrcs.extend(self.oTestVmSet.getResourceSet())
135 return self.asRsrcs
136
137 def actionConfig(self):
138 if not self.importVBoxApi(): # So we can use the constant below.
139 return False;
140
141 eNic0AttachType = vboxcon.NetworkAttachmentType_NAT;
142 sGaIso = self.getGuestAdditionsIso();
143
144 # On 6.0 we merge the GAs with the ValidationKit so we can get at FsPerf.
145 #
146 # Note1: Not possible to do a double import as both images an '/OS2' dir.
147 # So, using same dir as with unattended VISOs for the valkit.
148 #
149 # Note2: We need to make sure that we don't change the location of the
150 # ValidationKit bits of the combined VISO, as this will break TXS' (TestExecService)
151 # automatic updating mechanism (uses hardcoded paths, e.g. "{CDROM}/linux/amd64/TestExecService").
152 #
153 ## @todo Find a solution for testing the automatic Guest Additions updates, which also looks at {CDROM}s root.
154 if self.fpApiVer >= 6.0:
155 sGaViso = os.path.join(self.sScratchPath, 'AdditionsAndValKit.viso');
156 ## @todo encode as bash cmd line:
157 sVisoContent = '--iprt-iso-maker-file-marker-bourne-sh %s ' \
158 '--import-iso \'%s\' ' \
159 '--push-iso \'%s\' ' \
160 '/vboxadditions=/ ' \
161 '--pop ' \
162 % (uuid.uuid4(), self.sVBoxValidationKitIso, sGaIso);
163 reporter.log2('Using VISO combining ValKit and GAs "%s": %s' % (sVisoContent, sGaViso));
164 with open(sGaViso, 'w') as oGaViso: # pylint: disable=unspecified-encoding
165 oGaViso.write(sVisoContent);
166 sGaIso = sGaViso;
167
168 self.sGstPathGaPrefix = 'vboxadditions';
169 else:
170 self.sGstPathGaPrefix = '';
171
172
173 reporter.log2('Path to Guest Additions on ISO is "%s"' % self.sGstPathGaPrefix);
174
175 return self.oTestVmSet.actionConfig(self, eNic0AttachType = eNic0AttachType, sDvdImage = sGaIso);
176
177 def actionExecute(self):
178 return self.oTestVmSet.actionExecute(self, self.testOneCfg);
179
180
181 #
182 # Test execution helpers.
183 #
184
185 def testOneCfg(self, oVM, oTestVm):
186 """
187 Runs the specified VM thru the tests.
188
189 Returns a success indicator on the general test execution. This is not
190 the actual test result.
191 """
192 fRc = False;
193
194 self.logVmInfo(oVM);
195
196 # We skip Linux Guest Additions testing for VBox < 6.1 for now.
197 fVersionIgnored = oTestVm.isLinux() and self.fpApiVer < 6.1;
198
199 if fVersionIgnored:
200 reporter.log('Skipping testing for "%s" because VBox version %s is ignored' % (oTestVm.sKind, self.fpApiVer,));
201 fRc = True;
202 else:
203 reporter.testStart('Waiting for TXS');
204 if oTestVm.isWindows():
205 self.sFileCdWait = ('%s/VBoxWindowsAdditions.exe' % (self.sGstPathGaPrefix,));
206 elif oTestVm.isLinux():
207 self.sFileCdWait = ('%s/VBoxLinuxAdditions.run' % (self.sGstPathGaPrefix,));
208
209 oSession, oTxsSession = self.startVmAndConnectToTxsViaTcp(oTestVm.sVmName, fCdWait = True,
210 cMsCdWait = 5 * 60 * 1000,
211 sFileCdWait = self.sFileCdWait);
212 reporter.testDone();
213
214 if oSession is not None \
215 and oTxsSession is not None:
216 self.addTask(oTxsSession);
217 # Do the testing.
218 fSkip = 'install' not in self.asTests;
219 reporter.testStart('Install');
220 if not fSkip:
221 fRc, oTxsSession = self.testInstallAdditions(oSession, oTxsSession, oTestVm);
222 reporter.testDone(fSkip);
223
224 if not fSkip \
225 and not fRc:
226 reporter.log('Skipping following tests as Guest Additions were not installed successfully');
227 else:
228 fSkip = 'guestprops' not in self.asTests;
229 reporter.testStart('Guest Properties');
230 if not fSkip:
231 fRc = self.testGuestProperties(oSession, oTxsSession, oTestVm) and fRc;
232 reporter.testDone(fSkip);
233
234 fSkip = 'guestcontrol' not in self.asTests;
235 reporter.testStart('Guest Control');
236 if not fSkip:
237 fRc, oTxsSession = self.aoSubTstDrvs[0].testIt(oTestVm, oSession, oTxsSession);
238 reporter.testDone(fSkip);
239
240 fSkip = 'sharedfolders' not in self.asTests;
241 reporter.testStart('Shared Folders');
242 if not fSkip:
243 fRc, oTxsSession = self.aoSubTstDrvs[1].testIt(oTestVm, oSession, oTxsSession);
244 reporter.testDone(fSkip or fRc is None);
245
246 ## @todo Save and restore test.
247
248 ## @todo Reset tests.
249
250 ## @todo Final test: Uninstallation.
251
252 # Download the TxS (Test Execution Service) log. This is not fatal when not being present.
253 if not fRc:
254 self.txsDownloadFiles(oSession, oTxsSession,
255 [ (oTestVm.pathJoin(self.getGuestTempDir(oTestVm), 'vbox-txs-release.log'),
256 'vbox-txs-%s.log' % oTestVm.sVmName) ],
257 fIgnoreErrors = True);
258
259 # Cleanup.
260 self.removeTask(oTxsSession);
261 self.terminateVmBySession(oSession);
262
263 return fRc;
264
265 def testInstallAdditions(self, oSession, oTxsSession, oTestVm):
266 """
267 Tests installing the guest additions
268 """
269 if oTestVm.isWindows():
270 (fRc, oTxsSession) = self.testWindowsInstallAdditions(oSession, oTxsSession, oTestVm);
271 elif oTestVm.isLinux():
272 (fRc, oTxsSession) = self.testLinuxInstallAdditions(oSession, oTxsSession, oTestVm);
273 else:
274 reporter.error('Guest Additions installation not implemented for %s yet! (%s)' %
275 (oTestVm.sKind, oTestVm.sVmName,));
276 fRc = False;
277
278 #
279 # Verify installation of Guest Additions using commmon bits.
280 #
281 if fRc:
282 #
283 # Check if the additions are operational.
284 #
285 try: oGuest = oSession.o.console.guest;
286 except:
287 reporter.errorXcpt('Getting IGuest failed.');
288 return (False, oTxsSession);
289
290 # Wait for the GAs to come up.
291 reporter.testStart('IGuest::additionsRunLevel');
292 fRc = self.testIGuest_additionsRunLevel(oSession, oTxsSession, oTestVm, oGuest);
293 reporter.testDone();
294
295 # Check the additionsVersion attribute. It must not be empty.
296 reporter.testStart('IGuest::additionsVersion');
297 fRc = self.testIGuest_additionsVersion(oGuest) and fRc;
298 reporter.testDone();
299
300 # Check Guest Additions facilities
301 reporter.testStart('IGuest::getFacilityStatus');
302 fRc = self.testIGuest_getFacilityStatus(oTestVm, oGuest) and fRc;
303 reporter.testDone();
304
305 # Do a bit of diagnosis on error.
306 if not fRc:
307 if oTestVm.isLinux():
308 reporter.log('Boot log:');
309 sCmdJournalCtl = oTestVm.pathJoin(self.getGuestSystemDir(oTestVm), 'journalctl');
310 oTxsSession.syncExec(sCmdJournalCtl, (sCmdJournalCtl, '-b'), fIgnoreErrors = True);
311 reporter.log('Loaded processes:');
312 sCmdPs = oTestVm.pathJoin(self.getGuestSystemDir(oTestVm), 'ps');
313 oTxsSession.syncExec(sCmdPs, (sCmdPs, '-a', '-u', '-x'), fIgnoreErrors = True);
314 reporter.log('Kernel messages:');
315 sCmdDmesg = oTestVm.pathJoin(self.getGuestSystemDir(oTestVm), 'dmesg');
316 oTxsSession.syncExec(sCmdDmesg, (sCmdDmesg), fIgnoreErrors = True);
317 reporter.log('Loaded modules:');
318 sCmdLsMod = oTestVm.pathJoin(self.getGuestSystemAdminDir(oTestVm), 'lsmod');
319 oTxsSession.syncExec(sCmdLsMod, (sCmdLsMod), fIgnoreErrors = True);
320 elif oTestVm.isWindows() or oTestVm.isOS2():
321 sShell = self.getGuestSystemShell(oTestVm);
322 sShellOpt = '/C' if oTestVm.isWindows() or oTestVm.isOS2() else '-c';
323 reporter.log('Loaded processes:');
324 oTxsSession.syncExec(sShell, (sShell, sShellOpt, "tasklist.exe", "/FO", "CSV"), fIgnoreErrors = True);
325 reporter.log('Listing autostart entries:');
326 oTxsSession.syncExec(sShell, (sShell, sShellOpt, "wmic.exe", "startup", "get"), fIgnoreErrors = True);
327 reporter.log('Listing autostart entries:');
328 oTxsSession.syncExec(sShell, (sShell, sShellOpt, "dir",
329 oTestVm.pathJoin(self.getGuestSystemDir(oTestVm), 'VBox*')),
330 fIgnoreErrors = True);
331 reporter.log('Downloading logs ...');
332 self.txsDownloadFiles(oSession, oTxsSession,
333 [ ( self.getGuestVBoxTrayClientLogFile(oTestVm),
334 'ga-vboxtrayclient-%s.log' % (oTestVm.sVmName,),),
335 ( "C:\\Documents and Settings\\All Users\\Application Data\\Microsoft\\Dr Watson\\drwtsn32.log",
336 'ga-drwatson-%s.log' % (oTestVm.sVmName,), ),
337 ],
338 fIgnoreErrors = True);
339
340 return (fRc, oTxsSession);
341
342 def getGuestVBoxTrayClientLogFile(self, oTestVm):
343 """ Gets the path on the guest for the (release) log file of VBoxTray / VBoxClient. """
344 if oTestVm.isWindows():
345 return oTestVm.pathJoin(self.getGuestTempDir(oTestVm), 'VBoxTray.log');
346
347 return oTestVm.pathJoin(self.getGuestTempDir(oTestVm), 'VBoxClient.log');
348
349 def setGuestEnvVar(self, oSession, oTxsSession, oTestVm, sName, sValue):
350 """ Sets a system-wide environment variable on the guest. Only supports Windows guests so far. """
351 _ = oSession;
352 if oTestVm.sKind not in ('WindowsNT4', 'Windows2000',):
353 sPathRegExe = oTestVm.pathJoin(self.getGuestSystemDir(oTestVm), 'reg.exe');
354 self.txsRunTest(oTxsSession, ('Set env var \"%s\"' % (sName,)),
355 30 * 1000, sPathRegExe,
356 (sPathRegExe, 'add',
357 '"HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment"', '/v',
358 sName, '/t', 'REG_EXPAND_SZ', '/d', sValue, '/f'));
359
360 def testWindowsInstallAdditions(self, oSession, oTxsSession, oTestVm):
361 """
362 Installs the Windows guest additions using the test execution service.
363 Since this involves rebooting the guest, we will have to create a new TXS session.
364 """
365 if oTestVm.sKind not in ('WindowsNT4', 'Windows2000',):
366 fGuestRequiresReboot = False;
367 sRegExe = oTestVm.pathJoin(self.getGuestSystemDir(oTestVm), 'reg.exe');
368 fGuestRequiresReboot = self.txsRunTest(oTxsSession, 'Check if reboot is required', 30 * 1000,
369 sRegExe,
370 (sRegExe, 'query',
371 '"HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\WindowsUpdate\\Auto Update\\RebootRequired"')); # pylint: disable=line-too-long
372 reporter.log('Status of RebootRequired query is %s' % fGuestRequiresReboot);
373
374 # Set system-wide env vars to enable release logging on some applications.
375 self.setGuestEnvVar(oSession, oTxsSession, oTestVm, 'VBOXTRAY_RELEASE_LOG', 'all.e.l.l2.l3.f');
376 self.setGuestEnvVar(oSession, oTxsSession, oTestVm, 'VBOXTRAY_RELEASE_LOG_FLAGS', 'time thread group append');
377 self.setGuestEnvVar(oSession, oTxsSession, oTestVm, 'VBOXTRAY_RELEASE_LOG_DEST',
378 ('file=%s' % (self.getGuestVBoxTrayClientLogFile(oTestVm),)));
379
380 #
381 # Install the public signing key.
382 #
383 if oTestVm.sKind not in ('WindowsNT4', 'Windows2000', 'WindowsXP', 'Windows2003'):
384 fRc = self.txsRunTest(oTxsSession, 'VBoxCertUtil.exe', 1 * 60 * 1000,
385 '${CDROM}/%s/cert/VBoxCertUtil.exe' % (self.sGstPathGaPrefix,),
386 ('${CDROM}/%s/cert/VBoxCertUtil.exe' % (self.sGstPathGaPrefix,),
387 'add-trusted-publisher',
388 '${CDROM}/%s/cert/vbox-sha1.cer' % (self.sGstPathGaPrefix,)),
389 fCheckSessionStatus = True);
390 if not fRc:
391 reporter.error('Error installing SHA1 certificate');
392 else:
393 fRc = self.txsRunTest(oTxsSession, 'VBoxCertUtil.exe', 1 * 60 * 1000,
394 '${CDROM}/%s/cert/VBoxCertUtil.exe' % (self.sGstPathGaPrefix,),
395 ('${CDROM}/%s/cert/VBoxCertUtil.exe' % (self.sGstPathGaPrefix,),
396 'add-trusted-publisher',
397 '${CDROM}/%s/cert/vbox-sha256.cer' % (self.sGstPathGaPrefix,)),
398 fCheckSessionStatus = True);
399 if not fRc:
400 reporter.error('Error installing SHA256 certificate');
401
402 #
403 # Delete relevant log files.
404 #
405 # Note! On some guests the files in question still can be locked by the OS, so ignore
406 # deletion errors from the guest side (e.g. sharing violations) and just continue.
407 #
408 sWinDir = self.getGuestWinDir(oTestVm);
409 aasLogFiles = [
410 ( oTestVm.pathJoin(sWinDir, 'setupapi.log'), 'ga-setupapi-%s.log' % (oTestVm.sVmName,), ),
411 ( oTestVm.pathJoin(sWinDir, 'setupact.log'), 'ga-setupact-%s.log' % (oTestVm.sVmName,), ),
412 ( oTestVm.pathJoin(sWinDir, 'setuperr.log'), 'ga-setuperr-%s.log' % (oTestVm.sVmName,), ),
413 ];
414
415 # Apply The SetupAPI logging level so that we also get the (most verbose) setupapi.dev.log file.
416 ## @todo !!! HACK ALERT !!! Add the value directly into the testing source image. Later.
417 fHaveSetupApiDevLog = False;
418 if oTestVm.sKind not in ('WindowsNT4', 'Windows2000',):
419 sRegExe = oTestVm.pathJoin(self.getGuestSystemDir(oTestVm), 'reg.exe');
420 fHaveSetupApiDevLog = self.txsRunTest(oTxsSession, 'Enabling setupapi.dev.log', 30 * 1000,
421 sRegExe,
422 (sRegExe, 'add',
423 '"HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Setup"',
424 '/v', 'LogLevel', '/t', 'REG_DWORD', '/d', '0xFF'),
425 fCheckSessionStatus = True);
426
427 for sGstFile, _ in aasLogFiles:
428 self.txsRmFile(oSession, oTxsSession, sGstFile, 10 * 1000, fIgnoreErrors = True);
429
430 # Enable installing the optional auto-logon modules (VBoxGINA/VBoxCredProv).
431 # Also tell the installer to produce the appropriate log files.
432 sExe = '${CDROM}/%s/VBoxWindowsAdditions.exe' % (self.sGstPathGaPrefix,);
433 asArgs = [ sExe, '/S', '/l', '/with_autologon' ];
434
435 # Determine if we need to force installing the legacy timestamp CA to make testing succeed.
436 # Note: Don't force installing when the Guest Additions installer should do this automatically,
437 # i.e, only force it for Windows Server 2016 and up.
438 # Note! This may mess up testing if GA ISO is from before r152467 when the option was added.
439 # Just add a VBox revision check here if we're suddenly keen on testing old stuff.
440 if ( self.fpApiVer >= 6.1
441 and oTestVm.getNonCanonicalGuestOsType() in [ 'Windows2016', 'Windows2019', 'Windows2022', 'Windows11' ]):
442 asArgs.append('/install_timestamp_ca');
443
444 #
445 # Do the actual install.
446 #
447 fRc = self.txsRunTest(oTxsSession, 'VBoxWindowsAdditions.exe', 5 * 60 * 1000, sExe, asArgs, fCheckSessionStatus = True);
448
449 # Add the Windows Guest Additions installer files to the files we want to download
450 # from the guest. Note: There won't be a install_ui.log because of the silent installation.
451 sGuestAddsDir = 'C:\\Program Files\\Oracle\\VirtualBox Guest Additions\\';
452 aasLogFiles.append((sGuestAddsDir + 'install.log', 'ga-install-%s.log' % (oTestVm.sVmName,),));
453 aasLogFiles.append((sGuestAddsDir + 'install_drivers.log', 'ga-install_drivers-%s.log' % (oTestVm.sVmName,),));
454 aasLogFiles.append((oTestVm.pathJoin(self.getGuestWinDir(oTestVm), 'setupapi.log'),
455 'ga-setupapi-%s.log' % (oTestVm.sVmName,),));
456
457 # Note: setupapi.dev.log only is available since Windows 2000.
458 if fHaveSetupApiDevLog:
459 aasLogFiles.append((oTestVm.pathJoin(self.getGuestWinDir(oTestVm), 'setupapi.dev.log'),
460 'ga-setupapi.dev-%s.log' % (oTestVm.sVmName,),));
461
462 #
463 # Download log files.
464 # Ignore errors as all files above might not be present (or in different locations)
465 # on different Windows guests.
466 #
467 self.txsDownloadFiles(oSession, oTxsSession, aasLogFiles, fIgnoreErrors = True);
468
469 #
470 # Reboot the VM and reconnect the TXS session.
471 #
472 if fRc:
473 reporter.testStart('Rebooting guest after Guest Additions installation');
474 (fRc, oTxsSession) = self.txsRebootAndReconnectViaTcp(oSession, oTxsSession, cMsTimeout = 15 * 60 * 1000);
475 if fRc:
476 pass;
477 else:
478 reporter.testFailure('Rebooting and reconnecting to TXS service failed');
479 reporter.testDone();
480 else:
481 reporter.error('Error installing Windows Guest Additions (installer returned with exit code <> 0)')
482
483 return (fRc, oTxsSession);
484
485 def getAdditionsInstallerResult(self, oTxsSession):
486 """
487 Extracts the Guest Additions installer exit code from a run before.
488 Assumes that nothing else has been run on the same TXS session in the meantime.
489 """
490 iRc = 0;
491 (_, sOpcode, abPayload) = oTxsSession.getLastReply();
492 if sOpcode.startswith('PROC NOK '): # Extract process rc
493 iRc = abPayload[0]; # ASSUMES 8-bit rc for now.
494 ## @todo Parse more statuses here.
495 return iRc;
496
497 def testLinuxInstallAdditions(self, oSession, oTxsSession, oTestVm):
498 #
499 # The actual install.
500 # Also tell the installer to produce the appropriate log files.
501
502 # Deploy signing keys into guest if VM has Secure Boot enabled.
503 if oTestVm.fSecureBoot:
504 reporter.log('Deploying Secure Boot signing keys to the guest');
505 fRc = self.txsMkDirPath(oSession, oTxsSession, '/var/lib/shim-signed/mok');
506 if fRc:
507 fRc = self.txsUploadFile(oSession, oTxsSession,
508 self.getFullResourceName(oTestVm.sUefiMokPathPrefix) + '.der',
509 '/var/lib/shim-signed/mok/MOK.der')
510 if fRc:
511 fRc = self.txsUploadFile(oSession, oTxsSession,
512 self.getFullResourceName(oTestVm.sUefiMokPathPrefix) + '.priv',
513 '/var/lib/shim-signed/mok/MOK.priv')
514 if fRc and oTxsSession.isSuccess():
515 pass
516 else:
517 reporter.testFailure('Unable to deploy Secure Boot signing keys to the guest');
518
519 # Construct arguments for installer.
520 asArgs = [ self.getGuestSystemShell(oTestVm), '${CDROM}/%s/VBoxLinuxAdditions.run' % self.sGstPathGaPrefix ];
521
522 # Make sure to add "--nox11" to the makeself wrapper in order to not getting any blocking xterm window spawned.
523 asArgs.extend( [ '--nox11' ] );
524
525 # Ugly kludge to make tst-rhel5 (or any other borked test VM) work which (accidentally?) have old(er) Guest Additions
526 # version pre-installed.
527 #
528 # This forces our installer (inside the makeself wrapper, hence the "--") to install, regardless of whether there already
529 # are any (older) Guest Additions installed already.
530 fForceInstallation = False;
531 if oTestVm.sVmName == "tst-rhel5":
532 fForceInstallation = True;
533
534 if fForceInstallation:
535 asArgs.extend( [ "--", "--force" ] );
536
537 fRc = self.txsRunTest(oTxsSession, 'VBoxLinuxAdditions.run', 30 * 60 * 1000,
538 self.getGuestSystemShell(oTestVm), asArgs);
539 if fRc and oTxsSession.isSuccess():
540 reporter.log('Installation completed');
541 else:
542 # Guest Additions installer which requires guest reboot after installation might return
543 # special exit code which can indicate that all was installed, but kernel modules were
544 # not rebooted. Handle this case here.
545 if self.fRebootAfterInstall:
546 iRc = self.getAdditionsInstallerResult(oTxsSession);
547 # Check for rc == 0 just for completeness.
548 if iRc in (0, 2): # Can happen if the GA installer has detected older VBox kernel modules running
549 # and needs a reboot.
550 reporter.log('Guest has old(er) VBox kernel modules still running; requires a reboot');
551 fRc = True;
552
553 if not fRc:
554 reporter.error('Installing Linux Additions failed (isSuccess=%s, lastReply=%s, see log file for details)'
555 % (oTxsSession.isSuccess(), oTxsSession.getLastReply()));
556
557 #
558 # Download log files.
559 # Ignore errors as all files above might not be present for whatever reason.
560 #
561 self.txsDownloadFiles(oSession, oTxsSession,
562 [ ('/var/log/vboxadd-install.log', 'vboxadd-install-%s.log' % oTestVm.sVmName),
563 ('/var/log/vboxadd-setup.log', 'vboxadd-setup-%s.log' % oTestVm.sVmName),
564 ('/var/log/vboxadd-uninstall.log', 'vboxadd-uninstall-%s.log' % oTestVm.sVmName), ],
565 fIgnoreErrors = True);
566
567 # Do the final reboot to get the just installed Guest Additions up and running.
568 if fRc:
569 if self.fRebootAfterInstall:
570 reporter.testStart('Rebooting guest after Guest Additions installation');
571 (fRc, oTxsSession) = self.txsRebootAndReconnectViaTcp(oSession, oTxsSession, cMsTimeout = 15 * 60 * 1000);
572 if not fRc:
573 reporter.testFailure('Rebooting and reconnecting to TXS service failed');
574 else:
575 reporter.log('Skipping guest reboot after Guest Additions installation as requested');
576 fRc = self.txsRunTest(oTxsSession, 'Check Guest Additions kernel modules status', 5 * 60 * 1000,
577 self.getGuestSystemShell(oTestVm),
578 (self.getGuestSystemShell(oTestVm),
579 '/sbin/rcvboxadd', 'status-kernel'));
580 if fRc and oTxsSession.isSuccess():
581 fRc = self.txsRunTest(oTxsSession, 'Check Guest Additions user services status', 5 * 60 * 1000,
582 self.getGuestSystemShell(oTestVm),
583 (self.getGuestSystemShell(oTestVm),
584 '/sbin/rcvboxadd', 'status-user'));
585 if fRc and oTxsSession.isSuccess():
586 pass;
587 else:
588 fRc = False;
589 reporter.testFailure('User services were not reloaded');
590 else:
591 fRc = False;
592 reporter.testFailure('Kernel modules were not reloaded');
593 if fRc:
594 reporter.testDone();
595
596 return (fRc, oTxsSession);
597
598 def testIGuest_additionsRunLevel(self, oSession, oTxsSession, oTestVm, oGuest):
599 """
600 Do run level tests.
601
602 Returns success status.
603 """
604
605 _ = oGuest;
606
607 if oTestVm.isWindows():
608 if oTestVm.isLoggedOntoDesktop():
609 eExpectedRunLevel = vboxcon.AdditionsRunLevelType_Desktop;
610 else:
611 eExpectedRunLevel = vboxcon.AdditionsRunLevelType_Userland;
612 else:
613 ## @todo VBoxClient does not have facility statuses implemented yet.
614 eExpectedRunLevel = vboxcon.AdditionsRunLevelType_Userland;
615
616 # Give the guest some time to build Guest Additions on system boot if needed.
617 fRc = self.waitForGAs(oSession, cMsTimeout = 15 * 60 * 1000, aenmWaitForRunLevels = [ eExpectedRunLevel ]);
618
619 # Try to detect the display server running on the guest OS.
620 # This might fail on pure server guest OSes (no X, no Wayland).
621 if fRc \
622 and oTestVm.isLinux():
623 ## @todo Fudge factor -- Wait for the desktop env to come up.
624 # Remove once facility statuses are implemented within VBoxClient.
625 reporter.log('Waiting 30s for the desktop environment to come up before checking for the display server ...');
626 self.sleep(30);
627 if self.fpApiVer >= 7.1 and self.uRevision >= 157189:
628 sVBoxClient = oTestVm.pathJoin(self.getGuestSystemDir(oTestVm, '/usr'), 'VBoxClient');
629 fRc = fRc and self.txsRunTest(oTxsSession, 'Check display server detection', 5 * 60 * 1000,
630 sVBoxClient, (sVBoxClient, '-v', '-v', '--session-detect'));
631 return fRc;
632
633 def testIGuest_additionsVersion(self, oGuest):
634 """
635 Returns False if no version string could be obtained, otherwise True
636 even though errors are logged.
637 """
638 try:
639 sVer = oGuest.additionsVersion;
640 except:
641 reporter.errorXcpt('Getting the additions version failed.');
642 return False;
643 reporter.log('IGuest::additionsVersion="%s"' % (sVer,));
644
645 if sVer.strip() == '':
646 reporter.error('IGuest::additionsVersion is empty.');
647 return False;
648
649 if sVer != sVer.strip():
650 reporter.error('IGuest::additionsVersion is contains spaces: "%s".' % (sVer,));
651
652 asBits = sVer.split('.');
653 if len(asBits) < 3:
654 reporter.error('IGuest::additionsVersion does not contain at least tree dot separated fields: "%s" (%d).'
655 % (sVer, len(asBits)));
656
657 ## @todo verify the format.
658 return True;
659
660 def checkFacilityStatus(self, oGuest, eFacilityType, sDesc, fMustSucceed = True):
661 """
662 Prints the current status of a Guest Additions facility.
663
664 Return success status.
665 """
666
667 fRc = True;
668
669 try:
670 eStatus, tsLastUpdatedMs = oGuest.getFacilityStatus(eFacilityType);
671 except:
672 if fMustSucceed:
673 reporter.errorXcpt('Getting facility status for "%s" failed' % (sDesc,));
674 fRc = False;
675 else:
676 if eStatus == vboxcon.AdditionsFacilityStatus_Inactive:
677 sStatus = "INACTIVE";
678 elif eStatus == vboxcon.AdditionsFacilityStatus_Paused:
679 sStatus = "PAUSED";
680 elif eStatus == vboxcon.AdditionsFacilityStatus_PreInit:
681 sStatus = "PREINIT";
682 elif eStatus == vboxcon.AdditionsFacilityStatus_Init:
683 sStatus = "INIT";
684 elif eStatus == vboxcon.AdditionsFacilityStatus_Active:
685 sStatus = "ACTIVE";
686 elif eStatus == vboxcon.AdditionsFacilityStatus_Terminating:
687 sStatus = "TERMINATING";
688 fRc = not fMustSucceed;
689 elif eStatus == vboxcon.AdditionsFacilityStatus_Terminated:
690 sStatus = "TERMINATED";
691 fRc = not fMustSucceed;
692 elif eStatus == vboxcon.AdditionsFacilityStatus_Failed:
693 sStatus = "FAILED";
694 fRc = not fMustSucceed;
695 elif eStatus == vboxcon.AdditionsFacilityStatus_Unknown:
696 sStatus = "UNKNOWN";
697 fRc = not fMustSucceed;
698 else:
699 sStatus = "???";
700 fRc = not fMustSucceed;
701
702 reporter.log('Guest Additions facility "%s": %s (last updated: %sms)' % (sDesc, sStatus, str(tsLastUpdatedMs)));
703 if fMustSucceed \
704 and not fRc:
705 reporter.error('Guest Additions facility "%s" did not report expected status (is "%s")' % (sDesc, sStatus));
706
707 return fRc;
708
709 def testIGuest_getFacilityStatus(self, oTestVm, oGuest):
710 """
711 Checks Guest Additions facilities for their status.
712
713 Returns success status.
714 """
715
716 reporter.testStart('Status VBoxGuest Driver');
717 fRc = self.checkFacilityStatus(oGuest, vboxcon.AdditionsFacilityType_VBoxGuestDriver, "VBoxGuest Driver");
718 reporter.testDone();
719
720 reporter.testStart('Status VBoxService');
721 fRc = self.checkFacilityStatus(oGuest, vboxcon.AdditionsFacilityType_VBoxService, "VBoxService") and fRc;
722 reporter.testDone();
723
724 if oTestVm.isWindows():
725 if oTestVm.isLoggedOntoDesktop():
726 ## @todo VBoxClient does not have facility statuses implemented yet.
727 reporter.testStart('Status VBoxTray / VBoxClient');
728 fRc = self.checkFacilityStatus(oGuest, vboxcon.AdditionsFacilityType_VBoxTrayClient,
729 "VBoxTray / VBoxClient") and fRc;
730 reporter.testDone();
731 ## @todo Add more.
732
733 return fRc;
734
735 def testGuestProperties(self, oSession, oTxsSession, oTestVm):
736 """
737 Test guest properties.
738 """
739 _ = oSession; _ = oTxsSession; _ = oTestVm;
740 return True;
741
742if __name__ == '__main__':
743 sys.exit(tdAddBasic1().main(sys.argv));
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