VirtualBox

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

Last change on this file since 84597 was 84597, checked in by vboxsync, 5 years ago

ValKit/tdAddBasci1.py+vbox.py: Refactored txsDownloadFiles to get rid of path style issues and be a little more flexible wrt. filenames and stuff.

  • Property svn:eol-style set to LF
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 28.9 KB
Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3# $Id: tdAddBasic1.py 84597 2020-05-28 16:03:23Z vboxsync $
4
5"""
6VirtualBox Validation Kit - Additions Basics #1.
7"""
8
9__copyright__ = \
10"""
11Copyright (C) 2010-2020 Oracle Corporation
12
13This file is part of VirtualBox Open Source Edition (OSE), as
14available from http://www.virtualbox.org. This file is free software;
15you can redistribute it and/or modify it under the terms of the GNU
16General Public License (GPL) as published by the Free Software
17Foundation, in version 2 as it comes in the "COPYING" file of the
18VirtualBox OSE distribution. VirtualBox OSE is distributed in the
19hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
20
21The contents of this file may alternatively be used under the terms
22of the Common Development and Distribution License Version 1.0
23(CDDL) only, as it comes in the "COPYING.CDDL" file of the
24VirtualBox OSE distribution, in which case the provisions of the
25CDDL are applicable instead of those of the GPL.
26
27You may elect to license modified versions of this file under the
28terms and conditions of either the GPL or the CDDL or both.
29"""
30__version__ = "$Revision: 84597 $"
31
32# Standard Python imports.
33import os;
34import sys;
35import uuid;
36if sys.version_info[0] >= 3:
37 from io import StringIO as StringIO; # pylint: disable=import-error,no-name-in-module,useless-import-alias
38else:
39 from StringIO import StringIO as StringIO; # pylint: disable=import-error,no-name-in-module,useless-import-alias
40
41# Only the main script needs to modify the path.
42try: __file__
43except: __file__ = sys.argv[0];
44g_ksValidationKitDir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))));
45sys.path.append(g_ksValidationKitDir);
46
47# Validation Kit imports.
48from testdriver import reporter;
49from testdriver import base;
50from testdriver import vbox;
51from testdriver import vboxcon;
52
53# Sub-test driver imports.
54sys.path.append(os.path.dirname(os.path.abspath(__file__))); # For sub-test drivers.
55from tdAddGuestCtrl import SubTstDrvAddGuestCtrl;
56from tdAddSharedFolders1 import SubTstDrvAddSharedFolders1;
57
58
59
60class tdAddBasicConsoleCallbacks(vbox.ConsoleEventHandlerBase):
61 """
62 For catching the Guest Additions change state events.
63 """
64 def __init__(self, dArgs):
65 oTstDrv = dArgs['oTstDrv'];
66 oVBoxMgr = dArgs['oVBoxMgr']; _ = oVBoxMgr;
67 oGuest = dArgs['oGuest'];
68
69 vbox.ConsoleEventHandlerBase.__init__(self, dArgs, 'tdAddBasic1');
70 self.oTstDrv = oTstDrv;
71 self.oGuest = oGuest;
72
73 def handleEvent(self, oEvt):
74 try:
75 oEvtBase = self.oVBoxMgr.queryInterface(oEvt, 'IEvent');
76 eType = oEvtBase.type;
77 except:
78 reporter.logXcpt();
79 return None;
80 if eType == vboxcon.VBoxEventType_OnAdditionsStateChanged:
81 return self.onAdditionsStateChanged();
82 return None;
83
84 def onAdditionsStateChanged(self):
85 reporter.log('onAdditionsStateChange');
86 self.oTstDrv.fGAStatusCallbackFired = True;
87 self.oTstDrv.eGAStatusCallbackRunlevel = self.oGuest.additionsRunLevel;
88 self.oVBoxMgr.interruptWaitEvents();
89 return None;
90
91class tdAddBasic1(vbox.TestDriver): # pylint: disable=too-many-instance-attributes
92 """
93 Additions Basics #1.
94 """
95 ## @todo
96 # - More of the settings stuff can be and need to be generalized!
97 #
98
99 def __init__(self):
100 vbox.TestDriver.__init__(self);
101 self.oTestVmSet = self.oTestVmManager.getSmokeVmSet('nat');
102 self.asTestsDef = ['install', 'guestprops', 'stdguestprops', 'guestcontrol', 'sharedfolders'];
103 self.asTests = self.asTestsDef;
104 self.asRsrcs = None
105 # The file we're going to use as a beacon to wait if the Guest Additions CD-ROM is ready.
106 self.sFileCdWait = '';
107
108 self.addSubTestDriver(SubTstDrvAddGuestCtrl(self));
109 self.addSubTestDriver(SubTstDrvAddSharedFolders1(self));
110
111 self.fGAStatusCallbackFired = False;
112 self.eGAStatusCallbackRunlevel = 0;
113
114 #
115 # Overridden methods.
116 #
117 def showUsage(self):
118 rc = vbox.TestDriver.showUsage(self);
119 reporter.log('');
120 reporter.log('tdAddBasic1 Options:');
121 reporter.log(' --tests <s1[:s2[:]]>');
122 reporter.log(' Default: %s (all)' % (':'.join(self.asTestsDef)));
123 reporter.log(' --quick');
124 reporter.log(' Same as --virt-modes hwvirt --cpu-counts 1.');
125 return rc;
126
127 def parseOption(self, asArgs, iArg): # pylint: disable=too-many-branches,too-many-statements
128 if asArgs[iArg] == '--tests':
129 iArg += 1;
130 if iArg >= len(asArgs): raise base.InvalidOption('The "--tests" takes a colon separated list of tests');
131 self.asTests = asArgs[iArg].split(':');
132 for s in self.asTests:
133 if s not in self.asTestsDef:
134 raise base.InvalidOption('The "--tests" value "%s" is not valid; valid values are: %s'
135 % (s, ' '.join(self.asTestsDef),));
136
137 elif asArgs[iArg] == '--quick':
138 self.parseOption(['--virt-modes', 'hwvirt'], 0);
139 self.parseOption(['--cpu-counts', '1'], 0);
140
141 else:
142 return vbox.TestDriver.parseOption(self, asArgs, iArg);
143 return iArg + 1;
144
145 def getResourceSet(self):
146 if self.asRsrcs is None:
147 self.asRsrcs = []
148 for oSubTstDrv in self.aoSubTstDrvs:
149 self.asRsrcs.extend(oSubTstDrv.asRsrcs)
150 self.asRsrcs.extend(self.oTestVmSet.getResourceSet())
151 return self.asRsrcs
152
153 def actionConfig(self):
154 if not self.importVBoxApi(): # So we can use the constant below.
155 return False;
156
157 eNic0AttachType = vboxcon.NetworkAttachmentType_NAT;
158 sGaIso = self.getGuestAdditionsIso();
159
160 # On 6.0 we merge the GAs with the ValidationKit so we can get at FsPerf.
161 # Note! Not possible to do a dboule import as both images an '/OS2' dir.
162 # So, using same dir as with unattended VISOs for the valkit.
163 if self.fpApiVer >= 6.0 and 'sharedfolders' in self.asTests:
164 sGaViso = os.path.join(self.sScratchPath, 'AdditionsAndValKit.viso');
165 ## @todo encode as bash cmd line:
166 sVisoContent = '--iprt-iso-maker-file-marker-bourne-sh %s ' \
167 '--import-iso \'%s\' ' \
168 '--push-iso \'%s\' ' \
169 '/vboxvalidationkit=/ ' \
170 '--pop ' \
171 % (uuid.uuid4(), sGaIso, self.sVBoxValidationKitIso);
172 reporter.log2('Using VISO combining GAs and ValKit "%s": %s' % (sGaViso, sVisoContent));
173 oGaViso = open(sGaViso, 'w');
174 oGaViso.write(sVisoContent);
175 oGaViso.close();
176 sGaIso = sGaViso;
177
178 return self.oTestVmSet.actionConfig(self, eNic0AttachType = eNic0AttachType, sDvdImage = sGaIso);
179
180 def actionExecute(self):
181 return self.oTestVmSet.actionExecute(self, self.testOneCfg);
182
183
184 #
185 # Test execution helpers.
186 #
187
188 def testOneCfg(self, oVM, oTestVm):
189 """
190 Runs the specified VM thru the tests.
191
192 Returns a success indicator on the general test execution. This is not
193 the actual test result.
194 """
195 # HACK ALERT! HORRIBLE MESS THAT SHOULDN'T BE HERE!
196 aasLogFiles = [ ];
197 if oTestVm.isLinux():
198 reporter.testStart('Enabling udev logging ...');
199 oSession, oTxsSession = self.startVmAndConnectToTxsViaTcp(oTestVm.sVmName, fCdWait = False);
200 reporter.testDone();
201 if oTxsSession:
202 oTxsSession.syncExec("sed", ("sed", "-i", "'s/.*udev_log.*/udev_log=\"debug\"/'", "/etc/udev/udev.conf"),
203 fIgnoreErrors = True);
204
205 sUDevMonitorLog = '/tmp/udev_monitor.log';
206 aasLogFiles.append((sUDevMonitorLog, 'guest-udev_monitor-%s.log' % (oTestVm.sVmName,),));
207
208 reporter.testStart('Enabling udev monitoring ...');
209 sUdevSvc = StringIO();
210 sUdevSvc.write('[Unit]\n');
211 sUdevSvc.write('Description=udev Monitoring\n');
212 sUdevSvc.write('DefaultDependencies=no\n');
213 sUdevSvc.write('Wants=systemd-udevd.service\n');
214 sUdevSvc.write('After=systemd-udevd-control.socket systemd-udevd-kernel.socket\n');
215 sUdevSvc.write('Before=sysinit.target systemd-udev-trigger.service\n');
216 sUdevSvc.write('[Service]\n');
217 sUdevSvc.write('Type=simple\n');
218 sUdevSvc.write('ExecStart=/usr/bin/sh -c "/usr/sbin/udevadm monitor --udev --env > ' + sUDevMonitorLog + '\n');
219 sUdevSvc.write('[Install]\n');
220 sUdevSvc.write('WantedBy=sysinit.target');
221 oTxsSession.syncUploadString(sUdevSvc.getvalue(), '/etc/systemd/system/systemd-udev-monitor.service', 0o644,
222 fIgnoreErrors = True);
223 oTxsSession.syncExec("systemctl", ("systemctl", "enable", "systemd-udev-monitor.service"), fIgnoreErrors = True);
224 reporter.testDone();
225 # HACK ALERT - END.
226
227 fRc = False;
228
229 self.logVmInfo(oVM);
230
231 if oTestVm.isWindows():
232 self.sFileCdWait = 'VBoxWindowsAdditions.exe';
233 elif oTestVm.isLinux():
234 self.sFileCdWait = 'VBoxLinuxAdditions.run';
235
236 reporter.testStart('Waiting for TXS + CD (%s)' % (self.sFileCdWait,));
237 if oTestVm.isLinux():
238 fRc, oTxsSession = self.txsRebootAndReconnectViaTcp(oSession, oTxsSession, fCdWait = True,
239 cMsCdWait = 5 * 60 * 1000,
240 sFileCdWait = self.sFileCdWait);
241 else:
242 oSession, oTxsSession = self.startVmAndConnectToTxsViaTcp(oTestVm.sVmName, fCdWait = True,
243 cMsCdWait = 5 * 60 * 1000,
244 sFileCdWait = self.sFileCdWait);
245 reporter.testDone();
246
247 # More HACK ALERT stuff.
248 if aasLogFiles and oTxsSession:
249 self.txsDownloadFiles(oSession, oTxsSession, aasLogFiles, fIgnoreErrors = True);
250
251 if oSession is not None:
252 self.addTask(oTxsSession);
253 # Do the testing.
254 fSkip = 'install' not in self.asTests;
255 reporter.testStart('Install');
256 if not fSkip:
257 fRc, oTxsSession = self.testInstallAdditions(oSession, oTxsSession, oTestVm);
258 reporter.testDone(fSkip);
259
260 if not fSkip \
261 and not fRc:
262 reporter.log('Skipping following tests as Guest Additions were not installed successfully');
263 else:
264 fSkip = 'guestprops' not in self.asTests;
265 reporter.testStart('Guest Properties');
266 if not fSkip:
267 fRc = self.testGuestProperties(oSession, oTxsSession, oTestVm) and fRc;
268 reporter.testDone(fSkip);
269
270 fSkip = 'guestcontrol' not in self.asTests;
271 reporter.testStart('Guest Control');
272 if not fSkip:
273 fRc, oTxsSession = self.aoSubTstDrvs[0].testIt(oTestVm, oSession, oTxsSession);
274 reporter.testDone(fSkip);
275
276 fSkip = 'sharedfolders' not in self.asTests and self.fpApiVer >= 6.0;
277 reporter.testStart('Shared Folders');
278 if not fSkip:
279 fRc, oTxsSession = self.aoSubTstDrvs[1].testIt(oTestVm, oSession, oTxsSession);
280 reporter.testDone(fSkip or fRc is None);
281
282 ## @todo Save and restore test.
283
284 ## @todo Reset tests.
285
286 ## @todo Final test: Uninstallation.
287
288 # Cleanup.
289 self.removeTask(oTxsSession);
290 self.terminateVmBySession(oSession)
291 return fRc;
292
293 def waitForGuestAdditionsRunLevel(self, oSession, oGuest, cMsTimeout, eRunLevel):
294 """
295 Waits for the Guest Additions to reach a specific run level.
296
297 Returns success status.
298 """
299 # No need to wait as we already reached the run level?
300 eRunLevelCur = oGuest.additionsRunLevel;
301 if eRunLevelCur == eRunLevel:
302 reporter.log('Already reached run level %s' % eRunLevel);
303 return True;
304
305 reporter.log('Waiting for Guest Additions to reach run level %s with %dms (current: %s) ...' %
306 (eRunLevel, cMsTimeout, eRunLevelCur));
307
308 oConsoleCallbacks = oSession.registerDerivedEventHandler(tdAddBasicConsoleCallbacks, \
309 {'oTstDrv':self, 'oGuest':oGuest, });
310 fRc = False;
311 if oConsoleCallbacks is not None:
312 tsStart = base.timestampMilli();
313 while base.timestampMilli() - tsStart < cMsTimeout:
314 self.sleep(1); # Do some busy waiting.
315 if self.fGAStatusCallbackFired:
316 reporter.log('Reached new run level %s after %dms' %
317 (self.eGAStatusCallbackRunlevel, base.timestampMilli() - tsStart));
318 if eRunLevel == self.eGAStatusCallbackRunlevel:
319 fRc = True;
320 break;
321 self.fGAStatusCallbackFired = False;
322 if fRc:
323 reporter.log('Final Guest Additions run level reached after %dms' % (base.timestampMilli() - tsStart));
324 else:
325 reporter.error('Guest Additions run level not reached');
326
327 # cleanup.
328 oConsoleCallbacks.unregister();
329 else:
330 reporter.error('Registering derived event handler failed');
331
332 if not fRc:
333 reporter.log('Waiting for Guest Additions to reach run level %s failed' % (eRunLevel));
334 return fRc;
335
336 def testInstallAdditions(self, oSession, oTxsSession, oTestVm):
337 """
338 Tests installing the guest additions
339 """
340 if oTestVm.isWindows():
341 (fRc, oTxsSession) = self.testWindowsInstallAdditions(oSession, oTxsSession, oTestVm);
342 elif oTestVm.isLinux():
343 (fRc, oTxsSession) = self.testLinuxInstallAdditions(oSession, oTxsSession, oTestVm);
344 else:
345 reporter.error('Guest Additions installation not implemented for %s yet! (%s)' %
346 (oTestVm.sKind, oTestVm.sVmName,));
347 fRc = False;
348
349 #
350 # Verify installation of Guest Additions using commmon bits.
351 #
352 if fRc:
353 #
354 # Check if the additions are operational.
355 #
356 try: oGuest = oSession.o.console.guest;
357 except:
358 reporter.errorXcpt('Getting IGuest failed.');
359 return (False, oTxsSession);
360
361 # Wait for the GAs to come up.
362 reporter.testStart('IGuest::additionsRunLevel');
363 fRc = self.testIGuest_additionsRunLevel(oSession, oTestVm, oGuest);
364 reporter.testDone();
365
366 # Check the additionsVersion attribute. It must not be empty.
367 reporter.testStart('IGuest::additionsVersion');
368 fRc = self.testIGuest_additionsVersion(oGuest) and fRc;
369 reporter.testDone();
370
371 # Check Guest Additions facilities
372 reporter.testStart('IGuest::getFacilityStatus');
373 fRc = self.testIGuest_getFacilityStatus(oTestVm, oGuest) and fRc;
374 reporter.testDone();
375
376 # Do a bit of diagnosis on error.
377 if not fRc:
378 if oTestVm.isLinux():
379 reporter.log('Boot log:');
380 sCmdJournalCtl = oTestVm.pathJoin(self.getGuestSystemDir(oTestVm), 'journalctl');
381 oTxsSession.syncExec(sCmdJournalCtl, (sCmdJournalCtl, '-b'), fIgnoreErrors = True);
382 reporter.log('Loaded processes:');
383 sCmdPs = oTestVm.pathJoin(self.getGuestSystemDir(oTestVm), 'ps');
384 oTxsSession.syncExec(sCmdPs, (sCmdPs, '-a', '-u', '-x'), fIgnoreErrors = True);
385 reporter.log('Kernel messages:');
386 sCmdDmesg = oTestVm.pathJoin(self.getGuestSystemDir(oTestVm), 'dmesg');
387 oTxsSession.syncExec(sCmdDmesg, (sCmdDmesg), fIgnoreErrors = True);
388 reporter.log('Loaded modules:');
389 sCmdLsMod = oTestVm.pathJoin(self.getGuestSystemAdminDir(oTestVm), 'lsmod');
390 oTxsSession.syncExec(sCmdLsMod, (sCmdLsMod), fIgnoreErrors = True);
391
392 return (fRc, oTxsSession);
393
394 def testWindowsInstallAdditions(self, oSession, oTxsSession, oTestVm):
395 """
396 Installs the Windows guest additions using the test execution service.
397 Since this involves rebooting the guest, we will have to create a new TXS session.
398 """
399
400 #
401 # Install the public signing key.
402 #
403 if oTestVm.sKind not in ('WindowsNT4', 'Windows2000', 'WindowsXP', 'Windows2003'):
404 fRc = self.txsRunTest(oTxsSession, 'VBoxCertUtil.exe', 1 * 60 * 1000, '${CDROM}/cert/VBoxCertUtil.exe',
405 ('${CDROM}/cert/VBoxCertUtil.exe', 'add-trusted-publisher', '${CDROM}/cert/vbox-sha1.cer'),
406 fCheckSessionStatus = True);
407 if not fRc:
408 reporter.error('Error installing SHA1 certificate');
409 else:
410 fRc = self.txsRunTest(oTxsSession, 'VBoxCertUtil.exe', 1 * 60 * 1000, '${CDROM}/cert/VBoxCertUtil.exe',
411 ('${CDROM}/cert/VBoxCertUtil.exe', 'add-trusted-publisher',
412 '${CDROM}/cert/vbox-sha256.cer'), fCheckSessionStatus = True);
413 if not fRc:
414 reporter.error('Error installing SHA256 certificate');
415
416 #
417 # Delete relevant log files.
418 #
419 # Note! On some guests the files in question still can be locked by the OS, so ignore
420 # deletion errors from the guest side (e.g. sharing violations) and just continue.
421 #
422 sWinDir = self.getGuestWinDir(oTestVm);
423 aasLogFiles = [
424 ( oTestVm.pathJoin(sWinDir, 'setupapi.log'), 'ga-setupapi-%s.log' % (oTestVm.sVmName,), ),
425 ( oTestVm.pathJoin(sWinDir, 'setupact.log'), 'ga-setupact-%s.log' % (oTestVm.sVmName,), ),
426 ( oTestVm.pathJoin(sWinDir, 'setuperr.log'), 'ga-setuperr-%s.log' % (oTestVm.sVmName,), ),
427 ];
428
429 # Apply The SetupAPI logging level so that we also get the (most verbose) setupapi.dev.log file.
430 ## @todo !!! HACK ALERT !!! Add the value directly into the testing source image. Later.
431 sRegExe = oTestVm.pathJoin(self.getGuestSystemDir(oTestVm), 'reg.exe');
432 fHaveSetupApiDevLog = self.txsRunTest(oTxsSession, 'Enabling setupapi.dev.log', 30 * 1000,
433 sRegExe,
434 (sRegExe, 'add',
435 '"HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Setup"',
436 '/v', 'LogLevel', '/t', 'REG_DWORD', '/d', '0xFF'),
437 fCheckSessionStatus = True);
438
439 for sGstFile, _ in aasLogFiles:
440 self.txsRmFile(oSession, oTxsSession, sGstFile, 10 * 1000, fIgnoreErrors = True);
441
442 #
443 # The actual install.
444 # Enable installing the optional auto-logon modules (VBoxGINA/VBoxCredProv).
445 # Also tell the installer to produce the appropriate log files.
446 #
447 fRc = self.txsRunTest(oTxsSession, 'VBoxWindowsAdditions.exe', 5 * 60 * 1000, '${CDROM}/VBoxWindowsAdditions.exe',
448 ('${CDROM}/VBoxWindowsAdditions.exe', '/S', '/l', '/with_autologon'), fCheckSessionStatus = True);
449
450 # Add the Windows Guest Additions installer files to the files we want to download
451 # from the guest. Note: There won't be a install_ui.log because of the silent installation.
452 sGuestAddsDir = 'C:\\Program Files\\Oracle\\VirtualBox Guest Additions\\';
453 aasLogFiles.append((sGuestAddsDir + 'install.log', 'ga-install-%s.log' % (oTestVm.sVmName,),));
454 aasLogFiles.append((sGuestAddsDir + 'install_drivers.log', 'ga-install_drivers-%s.log' % (oTestVm.sVmName,),));
455 aasLogFiles.append(('C:\\Windows\\setupapi.log', 'ga-setupapi-%s.log' % (oTestVm.sVmName,),));
456
457 # Note: setupapi.dev.log only is available since Windows 2000.
458 if fHaveSetupApiDevLog:
459 aasLogFiles.append(('C:\\Windows\\setupapi.dev.log', 'ga-setupapi.dev-%s.log' % (oTestVm.sVmName,),));
460
461 #
462 # Download log files.
463 # Ignore errors as all files above might not be present (or in different locations)
464 # on different Windows guests.
465 #
466 self.txsDownloadFiles(oSession, oTxsSession, aasLogFiles, fIgnoreErrors = True);
467
468 #
469 # Reboot the VM and reconnect the TXS session.
470 #
471 if fRc:
472 reporter.testStart('Rebooting guest w/ updated Guest Additions active');
473 (fRc, oTxsSession) = self.txsRebootAndReconnectViaTcp(oSession, oTxsSession, cMsTimeout = 15 * 60 * 1000);
474 if fRc:
475 pass;
476 else:
477 reporter.testFailure('Rebooting and reconnecting to TXS service failed');
478 reporter.testDone();
479 else:
480 reporter.error('Error installing Windows Guest Additions (installer returned with exit code <> 0)')
481
482 return (fRc, oTxsSession);
483
484 def getAdditionsInstallerResult(self, oTxsSession):
485 """
486 Extracts the Guest Additions installer exit code from a run before.
487 Assumes that nothing else has been run on the same TXS session in the meantime.
488 """
489 iRc = 0;
490 (_, sOpcode, abPayload) = oTxsSession.getLastReply();
491 if sOpcode.startswith('PROC NOK '): # Extract process rc
492 iRc = abPayload[0]; # ASSUMES 8-bit rc for now.
493 ## @todo Parse more statuses here.
494 return iRc;
495
496 def testLinuxInstallAdditions(self, oSession, oTxsSession, oTestVm):
497 #
498 # The actual install.
499 # Also tell the installer to produce the appropriate log files.
500 #
501 # Make sure to add "--nox11" to the makeself wrapper in order to not getting any blocking
502 # xterm window spawned.
503 fRc = self.txsRunTest(oTxsSession, 'VBoxLinuxAdditions.run', 30 * 60 * 1000,
504 self.getGuestSystemShell(oTestVm),
505 (self.getGuestSystemShell(oTestVm), '${CDROM}/VBoxLinuxAdditions.run', '--nox11'));
506 if not fRc:
507 iRc = self.getAdditionsInstallerResult(oTxsSession);
508 # Check for rc == 0 just for completeness.
509 if iRc in (0, 2): # Can happen if the GA installer has detected older VBox kernel modules running and needs a reboot.
510 reporter.log('Guest has old(er) VBox kernel modules still running; requires a reboot');
511 fRc = True;
512
513 if not fRc:
514 reporter.error('Installing Linux Additions failed (isSuccess=%s, lastReply=%s, see log file for details)'
515 % (oTxsSession.isSuccess(), oTxsSession.getLastReply()));
516
517 #
518 # Download log files.
519 # Ignore errors as all files above might not be present for whatever reason.
520 #
521 self.txsDownloadFiles(oSession, oTxsSession,
522 [('/var/log/vboxadd-install.log', 'vboxadd-install-%s.log' % oTestVm.sName), ],
523 fIgnoreErrors = True);
524
525 # Do the final reboot to get the just installed Guest Additions up and running.
526 if fRc:
527 reporter.testStart('Rebooting guest w/ updated Guest Additions active');
528 (fRc, oTxsSession) = self.txsRebootAndReconnectViaTcp(oSession, oTxsSession, cMsTimeout = 15 * 60 * 1000);
529 if fRc:
530 pass
531 else:
532 reporter.testFailure('Rebooting and reconnecting to TXS service failed');
533 reporter.testDone();
534
535 return (fRc, oTxsSession);
536
537 def testIGuest_additionsRunLevel(self, oSession, oTestVm, oGuest):
538 """
539 Do run level tests.
540 """
541 if oTestVm.isWindows():
542 if oTestVm.isLoggedOntoDesktop():
543 eExpectedRunLevel = vboxcon.AdditionsRunLevelType_Desktop;
544 else:
545 eExpectedRunLevel = vboxcon.AdditionsRunLevelType_Userland;
546 else:
547 ## @todo VBoxClient does not have facility statuses implemented yet.
548 eExpectedRunLevel = vboxcon.AdditionsRunLevelType_Userland;
549
550 return self.waitForGuestAdditionsRunLevel(oSession, oGuest, 5 * 60 * 1000, eExpectedRunLevel);
551
552 def testIGuest_additionsVersion(self, oGuest):
553 """
554 Returns False if no version string could be obtained, otherwise True
555 even though errors are logged.
556 """
557 try:
558 sVer = oGuest.additionsVersion;
559 except:
560 reporter.errorXcpt('Getting the additions version failed.');
561 return False;
562 reporter.log('IGuest::additionsVersion="%s"' % (sVer,));
563
564 if sVer.strip() == '':
565 reporter.error('IGuest::additionsVersion is empty.');
566 return False;
567
568 if sVer != sVer.strip():
569 reporter.error('IGuest::additionsVersion is contains spaces: "%s".' % (sVer,));
570
571 asBits = sVer.split('.');
572 if len(asBits) < 3:
573 reporter.error('IGuest::additionsVersion does not contain at least tree dot separated fields: "%s" (%d).'
574 % (sVer, len(asBits)));
575
576 ## @todo verify the format.
577 return True;
578
579 def checkFacilityStatus(self, oGuest, eFacilityType, sDesc, fMustSucceed = True):
580 """
581 Prints the current status of a Guest Additions facility.
582
583 Return success status.
584 """
585
586 fRc = True;
587
588 try:
589 eStatus, tsLastUpdatedMs = oGuest.getFacilityStatus(eFacilityType);
590 except:
591 if fMustSucceed:
592 reporter.errorXcpt('Getting facility status for "%s" failed' % (sDesc,));
593 fRc = False;
594 else:
595 if eStatus == vboxcon.AdditionsFacilityStatus_Inactive:
596 sStatus = "INACTIVE";
597 elif eStatus == vboxcon.AdditionsFacilityStatus_Paused:
598 sStatus = "PAUSED";
599 elif eStatus == vboxcon.AdditionsFacilityStatus_PreInit:
600 sStatus = "PREINIT";
601 elif eStatus == vboxcon.AdditionsFacilityStatus_Init:
602 sStatus = "INIT";
603 elif eStatus == vboxcon.AdditionsFacilityStatus_Active:
604 sStatus = "ACTIVE";
605 elif eStatus == vboxcon.AdditionsFacilityStatus_Terminating:
606 sStatus = "TERMINATING";
607 fRc = not fMustSucceed;
608 elif eStatus == vboxcon.AdditionsFacilityStatus_Terminated:
609 sStatus = "TERMINATED";
610 fRc = not fMustSucceed;
611 elif eStatus == vboxcon.AdditionsFacilityStatus_Failed:
612 sStatus = "FAILED";
613 fRc = not fMustSucceed;
614 elif eStatus == vboxcon.AdditionsFacilityStatus_Unknown:
615 sStatus = "UNKNOWN";
616 fRc = not fMustSucceed;
617 else:
618 sStatus = "???";
619 fRc = not fMustSucceed;
620
621 reporter.log('Guest Additions facility "%s": %s (last updated: %sms)' % (sDesc, sStatus, str(tsLastUpdatedMs)));
622 if fMustSucceed \
623 and not fRc:
624 reporter.error('Guest Additions facility "%s" did not report expected status (is "%s")' % (sDesc, sStatus));
625
626 return fRc;
627
628 def testIGuest_getFacilityStatus(self, oTestVm, oGuest):
629 """
630 Checks Guest Additions facilities for their status.
631
632 Returns success status.
633 """
634
635 reporter.testStart('Status VBoxGuest Driver');
636 fRc = self.checkFacilityStatus(oGuest, vboxcon.AdditionsFacilityType_VBoxGuestDriver, "VBoxGuest Driver");
637 reporter.testDone();
638
639 reporter.testStart('Status VBoxService');
640 fRc = self.checkFacilityStatus(oGuest, vboxcon.AdditionsFacilityType_VBoxService, "VBoxService") and fRc;
641 reporter.testDone();
642
643 if oTestVm.isWindows():
644 if oTestVm.isLoggedOntoDesktop():
645 ## @todo VBoxClient does not have facility statuses implemented yet.
646 reporter.testStart('Status VBoxTray / VBoxClient');
647 fRc = self.checkFacilityStatus(oGuest, vboxcon.AdditionsFacilityType_VBoxTrayClient,
648 "VBoxTray / VBoxClient") and fRc;
649 reporter.testDone();
650 ## @todo Add more.
651
652 return fRc;
653
654 def testGuestProperties(self, oSession, oTxsSession, oTestVm):
655 """
656 Test guest properties.
657 """
658 _ = oSession; _ = oTxsSession; _ = oTestVm;
659 return True;
660
661if __name__ == '__main__':
662 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