VirtualBox

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

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

Validation Kit/tdAAddBasic1.py: More CD waiting fixes, needed for busy testboxes.

  • Property svn:eol-style set to LF
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 18.9 KB
Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3# $Id: tdAddBasic1.py 84113 2020-04-30 16:09:02Z 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: 84113 $"
31
32# Standard Python imports.
33import os;
34import sys;
35import uuid;
36
37# Only the main script needs to modify the path.
38try: __file__
39except: __file__ = sys.argv[0];
40g_ksValidationKitDir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))));
41sys.path.append(g_ksValidationKitDir);
42
43# Validation Kit imports.
44from testdriver import reporter;
45from testdriver import base;
46from testdriver import vbox;
47from testdriver import vboxcon;
48
49# Sub-test driver imports.
50sys.path.append(os.path.dirname(os.path.abspath(__file__))); # For sub-test drivers.
51from tdAddGuestCtrl import SubTstDrvAddGuestCtrl;
52from tdAddSharedFolders1 import SubTstDrvAddSharedFolders1;
53
54
55class tdAddBasic1(vbox.TestDriver): # pylint: disable=too-many-instance-attributes
56 """
57 Additions Basics #1.
58 """
59 ## @todo
60 # - More of the settings stuff can be and need to be generalized!
61 #
62
63 def __init__(self):
64 vbox.TestDriver.__init__(self);
65 self.oTestVmSet = self.oTestVmManager.getSmokeVmSet('nat');
66 self.asTestsDef = ['install', 'guestprops', 'stdguestprops', 'guestcontrol', 'sharedfolders'];
67 self.asTests = self.asTestsDef;
68 self.asRsrcs = None
69 # The file we're going to use as a beacon to wait if the Guest Additions CD-ROM is ready.
70 self.sFileCdWait = '';
71
72 self.addSubTestDriver(SubTstDrvAddGuestCtrl(self));
73 self.addSubTestDriver(SubTstDrvAddSharedFolders1(self));
74
75 #
76 # Overridden methods.
77 #
78 def showUsage(self):
79 rc = vbox.TestDriver.showUsage(self);
80 reporter.log('');
81 reporter.log('tdAddBasic1 Options:');
82 reporter.log(' --tests <s1[:s2[:]]>');
83 reporter.log(' Default: %s (all)' % (':'.join(self.asTestsDef)));
84 reporter.log(' --quick');
85 reporter.log(' Same as --virt-modes hwvirt --cpu-counts 1.');
86 return rc;
87
88 def parseOption(self, asArgs, iArg): # pylint: disable=too-many-branches,too-many-statements
89 if asArgs[iArg] == '--tests':
90 iArg += 1;
91 if iArg >= len(asArgs): raise base.InvalidOption('The "--tests" takes a colon separated list of tests');
92 self.asTests = asArgs[iArg].split(':');
93 for s in self.asTests:
94 if s not in self.asTestsDef:
95 raise base.InvalidOption('The "--tests" value "%s" is not valid; valid values are: %s'
96 % (s, ' '.join(self.asTestsDef),));
97
98 elif asArgs[iArg] == '--quick':
99 self.parseOption(['--virt-modes', 'hwvirt'], 0);
100 self.parseOption(['--cpu-counts', '1'], 0);
101
102 else:
103 return vbox.TestDriver.parseOption(self, asArgs, iArg);
104 return iArg + 1;
105
106 def getResourceSet(self):
107 if self.asRsrcs is None:
108 self.asRsrcs = []
109 for oSubTstDrv in self.aoSubTstDrvs:
110 self.asRsrcs.extend(oSubTstDrv.asRsrcs)
111 self.asRsrcs.extend(self.oTestVmSet.getResourceSet())
112 return self.asRsrcs
113
114 def actionConfig(self):
115 if not self.importVBoxApi(): # So we can use the constant below.
116 return False;
117
118 eNic0AttachType = vboxcon.NetworkAttachmentType_NAT;
119 sGaIso = self.getGuestAdditionsIso();
120
121 # On 6.0 we merge the GAs with the ValidationKit so we can get at FsPerf.
122 # Note! Not possible to do a dboule import as both images an '/OS2' dir.
123 # So, using same dir as with unattended VISOs for the valkit.
124 if self.fpApiVer >= 6.0 and 'sharedfolders' in self.asTests:
125 sGaViso = os.path.join(self.sScratchPath, 'AdditionsAndValKit.viso');
126 ## @todo encode as bash cmd line:
127 sVisoContent = '--iprt-iso-maker-file-marker-bourne-sh %s ' \
128 '--import-iso \'%s\' ' \
129 '--push-iso \'%s\' ' \
130 '/vboxvalidationkit=/ ' \
131 '--pop ' \
132 % (uuid.uuid4(), sGaIso, self.sVBoxValidationKitIso);
133 reporter.log2('Using VISO combining GAs and ValKit "%s": %s' % (sGaViso, sVisoContent));
134 oGaViso = open(sGaViso, 'w');
135 oGaViso.write(sVisoContent);
136 oGaViso.close();
137 sGaIso = sGaViso;
138
139 return self.oTestVmSet.actionConfig(self, eNic0AttachType = eNic0AttachType, sDvdImage = sGaIso);
140
141 def actionExecute(self):
142 return self.oTestVmSet.actionExecute(self, self.testOneCfg);
143
144
145 #
146 # Test execution helpers.
147 #
148
149 def testOneCfg(self, oVM, oTestVm):
150 """
151 Runs the specified VM thru the tests.
152
153 Returns a success indicator on the general test execution. This is not
154 the actual test result.
155 """
156 fRc = False;
157
158 if oTestVm.isWindows():
159 self.sFileCdWait = 'VBoxWindowsAdditions.exe';
160 elif oTestVm.isLinux():
161 self.sFileCdWait = 'VBoxLinuxAdditions.run';
162
163 self.logVmInfo(oVM);
164 oSession, oTxsSession = self.startVmAndConnectToTxsViaTcp(oTestVm.sVmName, fCdWait = True,
165 cMsCdWait = 5 * 60 * 1000,
166 sFileCdWait = self.sFileCdWait);
167 if oSession is not None:
168 self.addTask(oTxsSession);
169 # Do the testing.
170 fSkip = 'install' not in self.asTests;
171 reporter.testStart('Install');
172 if not fSkip:
173 fRc, oTxsSession = self.testInstallAdditions(oSession, oTxsSession, oTestVm);
174 reporter.testDone(fSkip);
175
176 if not fSkip \
177 and not fRc:
178 reporter.log('Skipping following tests as Guest Additions were not installed successfully');
179 else:
180 fSkip = 'guestprops' not in self.asTests;
181 reporter.testStart('Guest Properties');
182 if not fSkip:
183 fRc = self.testGuestProperties(oSession, oTxsSession, oTestVm) and fRc;
184 reporter.testDone(fSkip);
185
186 fSkip = 'guestcontrol' not in self.asTests;
187 reporter.testStart('Guest Control');
188 if not fSkip:
189 fRc, oTxsSession = self.aoSubTstDrvs[0].testIt(oTestVm, oSession, oTxsSession);
190 reporter.testDone(fSkip);
191
192 fSkip = 'sharedfolders' not in self.asTests and self.fpApiVer >= 6.0;
193 reporter.testStart('Shared Folders');
194 if not fSkip:
195 fRc, oTxsSession = self.aoSubTstDrvs[1].testIt(oTestVm, oSession, oTxsSession);
196 reporter.testDone(fSkip or fRc is None);
197
198 ## @todo Save and restore test.
199
200 ## @todo Reset tests.
201
202 ## @todo Final test: Uninstallation.
203
204 # Cleanup.
205 self.removeTask(oTxsSession);
206 self.terminateVmBySession(oSession)
207 return fRc;
208
209 def testInstallAdditions(self, oSession, oTxsSession, oTestVm):
210 """
211 Tests installing the guest additions
212 """
213 if oTestVm.isWindows():
214 (fRc, oTxsSession) = self.testWindowsInstallAdditions(oSession, oTxsSession, oTestVm);
215 elif oTestVm.isLinux():
216 (fRc, oTxsSession) = self.testLinuxInstallAdditions(oSession, oTxsSession, oTestVm);
217 else:
218 reporter.error('Guest Additions installation not implemented for %s yet! (%s)' %
219 (oTestVm.sKind, oTestVm.sVmName,));
220 fRc = False;
221
222 #
223 # Verify installation of Guest Additions using commmon bits.
224 #
225 if fRc is True:
226 #
227 # Wait for the GAs to come up.
228 #
229
230 ## @todo need to signed up for a OnAdditionsStateChanged and wait runlevel to
231 # at least reach Userland.
232
233 #
234 # Check if the additions are operational.
235 #
236 try: oGuest = oSession.o.console.guest;
237 except:
238 reporter.errorXcpt('Getting IGuest failed.');
239 return (False, oTxsSession);
240
241 # Check the additionsVersion attribute. It must not be empty.
242 reporter.testStart('IGuest::additionsVersion');
243 fRc = self.testIGuest_additionsVersion(oGuest);
244 reporter.testDone();
245
246 reporter.testStart('IGuest::additionsRunLevel');
247 self.testIGuest_additionsRunLevel(oGuest, oTestVm);
248 reporter.testDone();
249
250 ## @todo test IAdditionsFacilities.
251
252 return (fRc, oTxsSession);
253
254 def testWindowsInstallAdditions(self, oSession, oTxsSession, oTestVm):
255 """
256 Installs the Windows guest additions using the test execution service.
257 Since this involves rebooting the guest, we will have to create a new TXS session.
258 """
259
260 #
261 # Install the public signing key.
262 #
263 if oTestVm.sKind not in ('WindowsNT4', 'Windows2000', 'WindowsXP', 'Windows2003'):
264 fRc = self.txsRunTest(oTxsSession, 'VBoxCertUtil.exe', 1 * 60 * 1000, '${CDROM}/cert/VBoxCertUtil.exe',
265 ('${CDROM}/cert/VBoxCertUtil.exe', 'add-trusted-publisher', '${CDROM}/cert/vbox-sha1.cer'),
266 fCheckSessionStatus = True);
267 if not fRc:
268 reporter.error('Error installing SHA1 certificate');
269 else:
270 fRc = self.txsRunTest(oTxsSession, 'VBoxCertUtil.exe', 1 * 60 * 1000, '${CDROM}/cert/VBoxCertUtil.exe',
271 ('${CDROM}/cert/VBoxCertUtil.exe', 'add-trusted-publisher',
272 '${CDROM}/cert/vbox-sha256.cer'), fCheckSessionStatus = True);
273 if not fRc:
274 reporter.error('Error installing SHA256 certificate');
275
276 #
277 # Delete relevant log files.
278 #
279 # Note! On some guests the files in question still can be locked by the OS, so ignore
280 # deletion errors from the guest side (e.g. sharing violations) and just continue.
281 #
282 asLogFiles = [];
283 fHaveSetupApiDevLog = False;
284 if oTestVm.sKind in ('WindowsNT4',):
285 sWinDir = 'C:/WinNT/';
286 else:
287 sWinDir = 'C:/Windows/';
288 asLogFiles = [sWinDir + 'setupapi.log', sWinDir + 'setupact.log', sWinDir + 'setuperr.log'];
289
290 # Apply The SetupAPI logging level so that we also get the (most verbose) setupapi.dev.log file.
291 ## @todo !!! HACK ALERT !!! Add the value directly into the testing source image. Later.
292 fHaveSetupApiDevLog = self.txsRunTest(oTxsSession, 'Enabling setupapi.dev.log', 30 * 1000,
293 'c:\\Windows\\System32\\reg.exe',
294 ('c:\\Windows\\System32\\reg.exe', 'add',
295 '"HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Setup"',
296 '/v', 'LogLevel', '/t', 'REG_DWORD', '/d', '0xFF'),
297 fCheckSessionStatus = True);
298
299 for sFile in asLogFiles:
300 self.txsRmFile(oSession, oTxsSession, sFile, 10 * 1000, fIgnoreErrors = True);
301
302 #
303 # The actual install.
304 # Enable installing the optional auto-logon modules (VBoxGINA/VBoxCredProv).
305 # Also tell the installer to produce the appropriate log files.
306 #
307 fRc = self.txsRunTest(oTxsSession, 'VBoxWindowsAdditions.exe', 5 * 60 * 1000, '${CDROM}/VBoxWindowsAdditions.exe',
308 ('${CDROM}/VBoxWindowsAdditions.exe', '/S', '/l', '/with_autologon'), fCheckSessionStatus = True);
309
310 #
311 # Reboot the VM and reconnect the TXS session.
312 #
313 if not fRc \
314 or oTxsSession.getResult() is False:
315 reporter.error('Error installing Windows Guest Additions (installer returned with exit code)')
316 else:
317 (fRc, oTxsSession) = self.txsRebootAndReconnectViaTcp(oSession, oTxsSession, cMsTimeout = 15 * 60 * 1000,
318 cMsCdWait = 15 * 60 * 1000);
319 if fRc is True:
320 # Add the Windows Guest Additions installer files to the files we want to download
321 # from the guest.
322 sGuestAddsDir = 'C:/Program Files/Oracle/VirtualBox Guest Additions/';
323 asLogFiles.append(sGuestAddsDir + 'install.log');
324 # Note: There won't be a install_ui.log because of the silent installation.
325 asLogFiles.append(sGuestAddsDir + 'install_drivers.log');
326 asLogFiles.append('C:/Windows/setupapi.log');
327
328 # Note: setupapi.dev.log only is available since Windows 2000.
329 if fHaveSetupApiDevLog:
330 asLogFiles.append('C:/Windows/setupapi.dev.log');
331
332 #
333 # Download log files.
334 # Ignore errors as all files above might not be present (or in different locations)
335 # on different Windows guests.
336 #
337 self.txsDownloadFiles(oSession, oTxsSession, asLogFiles, fIgnoreErrors = True);
338
339 return (fRc, oTxsSession);
340
341 def getAdditionsInstallerResult(self, oTxsSession):
342 """
343 Extracts the Guest Additions installer exit code from a run before.
344 Assumes that nothing else has been run on the same TXS session in the meantime.
345 """
346 iRc = 0;
347 (_, sOpcode, abPayload) = oTxsSession.getLastReply();
348 if sOpcode.startswith('PROC NOK '): # Extract process rc
349 iRc = abPayload[0]; # ASSUMES 8-bit rc for now.
350 ## @todo Parse more statuses here.
351 return iRc;
352
353 def testLinuxInstallAdditions(self, oSession, oTxsSession, oTestVm):
354 _ = oSession;
355 _ = oTestVm;
356
357 fRc = False;
358
359 #
360 # The actual install.
361 # Also tell the installer to produce the appropriate log files.
362 #
363 # Make sure to add "--nox11" to the makeself wrapper in order to not getting any blocking
364 # xterm window spawned.
365 fRc = self.txsRunTest(oTxsSession, 'VBoxLinuxAdditions.run', 30 * 60 * 1000,
366 '/bin/sh', ('/bin/sh', '${CDROM}/VBoxLinuxAdditions.run', '--nox11'));
367 if not fRc:
368 iRc = self.getAdditionsInstallerResult(oTxsSession);
369 # Check for rc == 0 just for completeness.
370 if iRc in (0, 2): # Can happen if the GA installer has detected older VBox kernel modules running and needs a reboot.
371 reporter.log('Guest has old(er) VBox kernel modules still running; requires a reboot');
372 fRc = True;
373
374 if not fRc:
375 reporter.error('Installing Linux Additions failed (isSuccess=%s, lastReply=%s, see log file for details)'
376 % (oTxsSession.isSuccess(), oTxsSession.getLastReply()));
377
378 #
379 # Download log files.
380 # Ignore errors as all files above might not be present for whatever reason.
381 #
382 asLogFile = [];
383 asLogFile.append('/var/log/vboxadd-install.log');
384 self.txsDownloadFiles(oSession, oTxsSession, asLogFile, fIgnoreErrors = True);
385
386 # Do the final reboot to get the just installed Guest Additions up and running.
387 if fRc:
388 reporter.testStart('Rebooting guest w/ updated Guest Additions active');
389 (fRc, oTxsSession) = self.txsRebootAndReconnectViaTcp(oSession, oTxsSession, cMsTimeout = 15 * 60 * 1000,
390 cMsCdWait = 15 * 60 * 1000);
391 if fRc:
392 pass
393 else:
394 reporter.testFailure('Rebooting and reconnecting to TXS service failed');
395 reporter.testDone();
396
397 return (fRc, oTxsSession);
398
399 def testIGuest_additionsVersion(self, oGuest):
400 """
401 Returns False if no version string could be obtained, otherwise True
402 even though errors are logged.
403 """
404 try:
405 sVer = oGuest.additionsVersion;
406 except:
407 reporter.errorXcpt('Getting the additions version failed.');
408 return False;
409 reporter.log('IGuest::additionsVersion="%s"' % (sVer,));
410
411 if sVer.strip() == '':
412 reporter.error('IGuest::additionsVersion is empty.');
413 return False;
414
415 if sVer != sVer.strip():
416 reporter.error('IGuest::additionsVersion is contains spaces: "%s".' % (sVer,));
417
418 asBits = sVer.split('.');
419 if len(asBits) < 3:
420 reporter.error('IGuest::additionsVersion does not contain at least tree dot separated fields: "%s" (%d).'
421 % (sVer, len(asBits)));
422
423 ## @todo verify the format.
424 return True;
425
426 def testIGuest_additionsRunLevel(self, oGuest, oTestVm):
427 """
428 Do run level tests.
429 """
430 if oTestVm.isLoggedOntoDesktop():
431 eExpectedRunLevel = vboxcon.AdditionsRunLevelType_Desktop;
432 else:
433 eExpectedRunLevel = vboxcon.AdditionsRunLevelType_Userland;
434
435 ## @todo Insert wait for the desired run level.
436 try:
437 iLevel = oGuest.additionsRunLevel;
438 except:
439 reporter.errorXcpt('Getting the additions run level failed.');
440 return False;
441 reporter.log('IGuest::additionsRunLevel=%s' % (iLevel,));
442
443 if iLevel != eExpectedRunLevel:
444 pass; ## @todo We really need that wait!!
445 #reporter.error('Expected runlevel %d, found %d instead' % (eExpectedRunLevel, iLevel));
446 return True;
447
448
449 def testGuestProperties(self, oSession, oTxsSession, oTestVm):
450 """
451 Test guest properties.
452 """
453 _ = oSession; _ = oTxsSession; _ = oTestVm;
454 return True;
455
456if __name__ == '__main__':
457 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