VirtualBox

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

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

Validation Kit/Guest Additions: Fixed proxy settings for APT.

  • Property svn:eol-style set to LF
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 21.9 KB
Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3# $Id: tdAddBasic1.py 83868 2020-04-20 17:22:27Z 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: 83868 $"
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
70 self.addSubTestDriver(SubTstDrvAddGuestCtrl(self));
71 self.addSubTestDriver(SubTstDrvAddSharedFolders1(self));
72
73 #
74 # Overridden methods.
75 #
76 def showUsage(self):
77 rc = vbox.TestDriver.showUsage(self);
78 reporter.log('');
79 reporter.log('tdAddBasic1 Options:');
80 reporter.log(' --tests <s1[:s2[:]]>');
81 reporter.log(' Default: %s (all)' % (':'.join(self.asTestsDef)));
82 reporter.log(' --quick');
83 reporter.log(' Same as --virt-modes hwvirt --cpu-counts 1.');
84 return rc;
85
86 def parseOption(self, asArgs, iArg): # pylint: disable=too-many-branches,too-many-statements
87 if asArgs[iArg] == '--tests':
88 iArg += 1;
89 if iArg >= len(asArgs): raise base.InvalidOption('The "--tests" takes a colon separated list of tests');
90 self.asTests = asArgs[iArg].split(':');
91 for s in self.asTests:
92 if s not in self.asTestsDef:
93 raise base.InvalidOption('The "--tests" value "%s" is not valid; valid values are: %s'
94 % (s, ' '.join(self.asTestsDef),));
95
96 elif asArgs[iArg] == '--quick':
97 self.parseOption(['--virt-modes', 'hwvirt'], 0);
98 self.parseOption(['--cpu-counts', '1'], 0);
99
100 else:
101 return vbox.TestDriver.parseOption(self, asArgs, iArg);
102 return iArg + 1;
103
104 def getResourceSet(self):
105 if self.asRsrcs is None:
106 self.asRsrcs = []
107 for oSubTstDrv in self.aoSubTstDrvs:
108 self.asRsrcs.extend(oSubTstDrv.asRsrcs)
109 self.asRsrcs.extend(self.oTestVmSet.getResourceSet())
110 return self.asRsrcs
111
112 def actionConfig(self):
113 if not self.importVBoxApi(): # So we can use the constant below.
114 return False;
115
116 eNic0AttachType = vboxcon.NetworkAttachmentType_NAT;
117 sGaIso = self.getGuestAdditionsIso();
118
119 # On 6.0 we merge the GAs with the ValidationKit so we can get at FsPerf.
120 # Note! Not possible to do a dboule import as both images an '/OS2' dir.
121 # So, using same dir as with unattended VISOs for the valkit.
122 if self.fpApiVer >= 6.0 and 'sharedfolders' in self.asTests:
123 sGaViso = os.path.join(self.sScratchPath, 'AdditionsAndValKit.viso');
124 ## @todo encode as bash cmd line:
125 sVisoContent = '--iprt-iso-maker-file-marker-bourne-sh %s ' \
126 '--import-iso \'%s\' ' \
127 '--push-iso \'%s\' ' \
128 '/vboxvalidationkit=/ ' \
129 '--pop ' \
130 % (uuid.uuid4(), sGaIso, self.sVBoxValidationKitIso);
131 reporter.log2('Using VISO combining GAs and ValKit "%s": %s' % (sGaViso, sVisoContent));
132 oGaViso = open(sGaViso, 'w');
133 oGaViso.write(sVisoContent);
134 oGaViso.close();
135 sGaIso = sGaViso;
136
137 return self.oTestVmSet.actionConfig(self, eNic0AttachType = eNic0AttachType, sDvdImage = sGaIso);
138
139 def actionExecute(self):
140 return self.oTestVmSet.actionExecute(self, self.testOneCfg);
141
142
143 #
144 # Test execution helpers.
145 #
146
147 def testOneCfg(self, oVM, oTestVm):
148 """
149 Runs the specified VM thru the tests.
150
151 Returns a success indicator on the general test execution. This is not
152 the actual test result.
153 """
154 fRc = False;
155
156 if oTestVm.isWindows():
157 sFileCdWait = 'VBoxWindowsAdditions.exe';
158 elif oTestVm.isLinux():
159 sFileCdWait = 'VBoxLinuxAdditions.run';
160
161 self.logVmInfo(oVM);
162 oSession, oTxsSession = self.startVmAndConnectToTxsViaTcp(oTestVm.sVmName, fCdWait = True, sFileCdWait = sFileCdWait);
163 if oSession is not None:
164 self.addTask(oTxsSession);
165 # Do the testing.
166 fSkip = 'install' not in self.asTests;
167 reporter.testStart('Install');
168 if not fSkip:
169 fRc, oTxsSession = self.testInstallAdditions(oSession, oTxsSession, oTestVm);
170 reporter.testDone(fSkip);
171
172 if not fSkip \
173 and not fRc:
174 reporter.log('Skipping following tests as Guest Additions were not installed successfully');
175 else:
176 fSkip = 'guestprops' not in self.asTests;
177 reporter.testStart('Guest Properties');
178 if not fSkip:
179 fRc = self.testGuestProperties(oSession, oTxsSession, oTestVm) and fRc;
180 reporter.testDone(fSkip);
181
182 fSkip = 'guestcontrol' not in self.asTests;
183 reporter.testStart('Guest Control');
184 if not fSkip:
185 fRc, oTxsSession = self.aoSubTstDrvs[0].testIt(oTestVm, oSession, oTxsSession);
186 reporter.testDone(fSkip);
187
188 fSkip = 'sharedfolders' not in self.asTests and self.fpApiVer >= 6.0;
189 reporter.testStart('Shared Folders');
190 if not fSkip:
191 fRc, oTxsSession = self.aoSubTstDrvs[1].testIt(oTestVm, oSession, oTxsSession);
192 reporter.testDone(fSkip or fRc is None);
193
194 ## @todo Save and restore test.
195
196 ## @todo Reset tests.
197
198 ## @todo Final test: Uninstallation.
199
200 # Cleanup.
201 self.removeTask(oTxsSession);
202 self.terminateVmBySession(oSession)
203 return fRc;
204
205 def testInstallAdditions(self, oSession, oTxsSession, oTestVm):
206 """
207 Tests installing the guest additions
208 """
209 if oTestVm.isWindows():
210 (fRc, oTxsSession) = self.testWindowsInstallAdditions(oSession, oTxsSession, oTestVm);
211 elif oTestVm.isLinux():
212 (fRc, oTxsSession) = self.testLinuxInstallAdditions(oSession, oTxsSession, oTestVm);
213 else:
214 reporter.error('Guest Additions installation not implemented for %s yet! (%s)' %
215 (oTestVm.sKind, oTestVm.sVmName,));
216 fRc = False;
217
218 #
219 # Verify installation of Guest Additions using commmon bits.
220 #
221 if fRc is True:
222 #
223 # Wait for the GAs to come up.
224 #
225
226 ## @todo need to signed up for a OnAdditionsStateChanged and wait runlevel to
227 # at least reach Userland.
228
229 #
230 # Check if the additions are operational.
231 #
232 try: oGuest = oSession.o.console.guest;
233 except:
234 reporter.errorXcpt('Getting IGuest failed.');
235 return (False, oTxsSession);
236
237 # Check the additionsVersion attribute. It must not be empty.
238 reporter.testStart('IGuest::additionsVersion');
239 fRc = self.testIGuest_additionsVersion(oGuest);
240 reporter.testDone();
241
242 reporter.testStart('IGuest::additionsRunLevel');
243 self.testIGuest_additionsRunLevel(oGuest, oTestVm);
244 reporter.testDone();
245
246 ## @todo test IAdditionsFacilities.
247
248 return (fRc, oTxsSession);
249
250 def testWindowsInstallAdditions(self, oSession, oTxsSession, oTestVm):
251 """
252 Installs the Windows guest additions using the test execution service.
253 Since this involves rebooting the guest, we will have to create a new TXS session.
254 """
255
256 #
257 # Install the public signing key.
258 #
259 if oTestVm.sKind not in ('WindowsNT4', 'Windows2000', 'WindowsXP', 'Windows2003'):
260 fRc = self.txsRunTest(oTxsSession, 'VBoxCertUtil.exe', 1 * 60 * 1000, '${CDROM}/cert/VBoxCertUtil.exe',
261 ('${CDROM}/cert/VBoxCertUtil.exe', 'add-trusted-publisher', '${CDROM}/cert/vbox-sha1.cer'),
262 fCheckSessionStatus = True);
263 if not fRc:
264 reporter.error('Error installing SHA1 certificate');
265 else:
266 fRc = self.txsRunTest(oTxsSession, 'VBoxCertUtil.exe', 1 * 60 * 1000, '${CDROM}/cert/VBoxCertUtil.exe',
267 ('${CDROM}/cert/VBoxCertUtil.exe', 'add-trusted-publisher',
268 '${CDROM}/cert/vbox-sha256.cer'), fCheckSessionStatus = True);
269 if not fRc:
270 reporter.error('Error installing SHA256 certificate');
271
272 #
273 # Delete relevant log files.
274 #
275 # Note! On some guests the files in question still can be locked by the OS, so ignore
276 # deletion errors from the guest side (e.g. sharing violations) and just continue.
277 #
278 asLogFiles = [];
279 fHaveSetupApiDevLog = False;
280 if oTestVm.sKind in ('WindowsNT4',):
281 sWinDir = 'C:/WinNT/';
282 else:
283 sWinDir = 'C:/Windows/';
284 asLogFiles = [sWinDir + 'setupapi.log', sWinDir + 'setupact.log', sWinDir + 'setuperr.log'];
285
286 # Apply The SetupAPI logging level so that we also get the (most verbose) setupapi.dev.log file.
287 ## @todo !!! HACK ALERT !!! Add the value directly into the testing source image. Later.
288 fHaveSetupApiDevLog = self.txsRunTest(oTxsSession, 'Enabling setupapi.dev.log', 30 * 1000,
289 'c:\\Windows\\System32\\reg.exe',
290 ('c:\\Windows\\System32\\reg.exe', 'add',
291 '"HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Setup"',
292 '/v', 'LogLevel', '/t', 'REG_DWORD', '/d', '0xFF'),
293 fCheckSessionStatus = True);
294
295 for sFile in asLogFiles:
296 self.txsRmFile(oSession, oTxsSession, sFile, 10 * 1000, fIgnoreErrors = True);
297
298 #
299 # The actual install.
300 # Enable installing the optional auto-logon modules (VBoxGINA/VBoxCredProv).
301 # Also tell the installer to produce the appropriate log files.
302 #
303 fRc = self.txsRunTest(oTxsSession, 'VBoxWindowsAdditions.exe', 5 * 60 * 1000, '${CDROM}/VBoxWindowsAdditions.exe',
304 ('${CDROM}/VBoxWindowsAdditions.exe', '/S', '/l', '/with_autologon'), fCheckSessionStatus = True);
305
306 #
307 # Reboot the VM and reconnect the TXS session.
308 #
309 if not fRc \
310 or oTxsSession.getResult() is False:
311 reporter.error('Error installing Windows Guest Additions (installer returned with exit code)')
312 else:
313 (fRc, oTxsSession) = self.txsRebootAndReconnectViaTcp(oSession, oTxsSession, cMsTimeout = 3 * 60000);
314 if fRc is True:
315 # Add the Windows Guest Additions installer files to the files we want to download
316 # from the guest.
317 sGuestAddsDir = 'C:/Program Files/Oracle/VirtualBox Guest Additions/';
318 asLogFiles.append(sGuestAddsDir + 'install.log');
319 # Note: There won't be a install_ui.log because of the silent installation.
320 asLogFiles.append(sGuestAddsDir + 'install_drivers.log');
321 asLogFiles.append('C:/Windows/setupapi.log');
322
323 # Note: setupapi.dev.log only is available since Windows 2000.
324 if fHaveSetupApiDevLog:
325 asLogFiles.append('C:/Windows/setupapi.dev.log');
326
327 #
328 # Download log files.
329 # Ignore errors as all files above might not be present (or in different locations)
330 # on different Windows guests.
331 #
332 self.txsDownloadFiles(oSession, oTxsSession, asLogFiles, fIgnoreErrors = True);
333
334 return (fRc, oTxsSession);
335
336 def testLinuxInstallAdditions(self, oSession, oTxsSession, oTestVm):
337 _ = oSession;
338 _ = oTestVm;
339
340 fRc = False;
341
342 # Additional environment block to add to the following commands.
343 asEnv = ();
344
345 fNeedsProxy = True; ## @todo Make this more flexible / dynamic.
346 sHttpProxy = 'http://emea-proxy.uk.oracle.com:80/';
347 sHttpsProxy = sHttpProxy;
348
349 if fNeedsProxy:
350 reporter.log('Using proxy: ' + sHttpProxy);
351 asEnv += ('http_proxy=' + sHttpProxy, 'https_proxy=' + sHttpsProxy);
352
353 cMsTimeout = 15 * 60 * 1000; # Use a 15 minutes timeout; needed for sloooow internet connections :-/
354
355 # Install Kernel headers, which are required for actually installing the Linux Additions.
356 if oTestVm.sKind.startswith('Debian') \
357 or oTestVm.sKind.startswith('Ubuntu'):
358
359 if fNeedsProxy:
360 fRc = oTxsSession.syncMkDirPath("/etc/apt/apt.conf.d/", 0o755);
361 if fRc:
362 fRc = oTxsSession.syncUploadString('Acquire::http::Proxy \"' + sHttpProxy + '\";\n'
363 'Acquire::https::Proxy \"' + sHttpsProxy + '\";',
364 '/etc/apt/apt.conf.d/proxy.conf', 0o644);
365 if not fRc:
366 reporter.error('Unable to write to /etc/apt/apt.conf.d/proxy.conf');
367 else:
368 reporter.error('Unable to create /etc/apt/apt.conf.d');
369
370 # As Ubuntu 15.10 is EOL we need to tweak the package sources by hand first in order to have a working
371 # package update path again; otherwise updating and installing packages will fail.
372 if 'ubuntu-15_10' in oTestVm.sVmName:
373 fRc = self.txsRunTest(oTxsSession, 'Applying EOL upgrade path of Ubuntu 15.10', 5 * 60 *1000,
374 '/bin/sed',
375 ('/bin/sed', '-E', '-i',
376 's/http:\\/\\/.*\\.ubuntu\\.com/http:\\/\\/old-releases.ubuntu.com/',
377 '/etc/apt/sources.list'),
378 fCheckSessionStatus = True);
379 if fRc:
380 fRc = self.txsRunTest(oTxsSession, 'Updating package sources', cMsTimeout,
381 '/usr/bin/apt-get', ('/usr/bin/apt-get', 'update'),
382 asAddEnv = asEnv,
383 fCheckSessionStatus = True);
384 if fRc:
385 fRc = self.txsRunTest(oTxsSession, 'Installing Kernel headers', cMsTimeout,
386 '/usr/bin/apt-get', ('/usr/bin/apt-get', 'install', '-y', 'linux-headers-generic'),
387 asAddEnv = asEnv,
388 fCheckSessionStatus = True);
389 if fRc:
390 fRc = self.txsRunTest(oTxsSession, 'Installing Guest Additions depdendencies', cMsTimeout, \
391 '/usr/bin/apt-get', ('/usr/bin/apt-get', 'install', '-y', 'build-essential', 'perl'),
392 asAddEnv = asEnv,
393 fCheckSessionStatus = True);
394 elif oTestVm.sKind.startswith('OL') \
395 or oTestVm.sKind.startswith('Oracle') \
396 or oTestVm.sKind.startswith('RHEL') \
397 or oTestVm.sKind.startswith('Redhat') \
398 or oTestVm.sKind.startswith('Cent'):
399
400 fRc = self.txsRunTest(oTxsSession, 'Updating package sources', cMsTimeout,
401 '/usr/bin/yum', ('/usr/bin/yum', 'update'),
402 asAddEnv = asEnv,
403 fCheckSessionStatus = True);
404 if fRc:
405 fRc = self.txsRunTest(oTxsSession, 'Installing Kernel headers', cMsTimeout,
406 '/usr/bin/yum', ('/usr/bin/yum', '-y', 'install', 'kernel-headers'),
407 asAddEnv = asEnv,
408 fCheckSessionStatus = True);
409 if fRc:
410 fRc = self.txsRunTest(oTxsSession, 'Installing Guest Additions depdendencies', cMsTimeout, \
411 '/usr/bin/yum', ('/usr/bin/yum', '-y', 'install', \
412 'make', 'automake', 'gcc', 'kernel-devel', 'dkms', 'bzip2', 'perl'),
413 asAddEnv = asEnv,
414 fCheckSessionStatus = True);
415 else:
416 reporter.error('Installing Linux Additions for kind "%s" is not supported yet' % oTestVm.sKind);
417 return (False, oTxsSession);
418
419 if fRc:
420 #
421 # The actual install.
422 # Also tell the installer to produce the appropriate log files.
423 #
424 # Make sure to add "--nox11" to the makeself wrapper in order to not getting any blocking
425 # xterm window spawned.
426 fRc = self.txsRunTest(oTxsSession, 'VBoxLinuxAdditions.run', 5 * 60 * 1000,
427 '/bin/sh', ('/bin/sh', '${CDROM}/VBoxLinuxAdditions.run', '--nox11'));
428 ## @todo We need to figure out why the result is != 0 when running the .run installer. For now just ignore it.
429 if not fRc:
430 reporter.error('Installing Linux Additions failed (isSuccess=%s, iResult=%d, see log file for details)'
431 % (oTxsSession.isSuccess(), oTxsSession.getResult()));
432
433 #
434 # Download log files.
435 # Ignore errors as all files above might not be present for whatever reason.
436 #
437 asLogFile = [];
438 asLogFile.append('/var/log/vboxadd-install.log');
439 self.txsDownloadFiles(oSession, oTxsSession, asLogFile, fIgnoreErrors = True);
440
441 if fRc:
442 (fRc, oTxsSession) = self.txsRebootAndReconnectViaTcp(oSession, oTxsSession, cMsTimeout = 3 * 60000);
443
444 return (fRc, oTxsSession);
445
446 def testIGuest_additionsVersion(self, oGuest):
447 """
448 Returns False if no version string could be obtained, otherwise True
449 even though errors are logged.
450 """
451 try:
452 sVer = oGuest.additionsVersion;
453 except:
454 reporter.errorXcpt('Getting the additions version failed.');
455 return False;
456 reporter.log('IGuest::additionsVersion="%s"' % (sVer,));
457
458 if sVer.strip() == '':
459 reporter.error('IGuest::additionsVersion is empty.');
460 return False;
461
462 if sVer != sVer.strip():
463 reporter.error('IGuest::additionsVersion is contains spaces: "%s".' % (sVer,));
464
465 asBits = sVer.split('.');
466 if len(asBits) < 3:
467 reporter.error('IGuest::additionsVersion does not contain at least tree dot separated fields: "%s" (%d).'
468 % (sVer, len(asBits)));
469
470 ## @todo verify the format.
471 return True;
472
473 def testIGuest_additionsRunLevel(self, oGuest, oTestVm):
474 """
475 Do run level tests.
476 """
477 if oTestVm.isLoggedOntoDesktop():
478 eExpectedRunLevel = vboxcon.AdditionsRunLevelType_Desktop;
479 else:
480 eExpectedRunLevel = vboxcon.AdditionsRunLevelType_Userland;
481
482 ## @todo Insert wait for the desired run level.
483 try:
484 iLevel = oGuest.additionsRunLevel;
485 except:
486 reporter.errorXcpt('Getting the additions run level failed.');
487 return False;
488 reporter.log('IGuest::additionsRunLevel=%s' % (iLevel,));
489
490 if iLevel != eExpectedRunLevel:
491 pass; ## @todo We really need that wait!!
492 #reporter.error('Expected runlevel %d, found %d instead' % (eExpectedRunLevel, iLevel));
493 return True;
494
495
496 def testGuestProperties(self, oSession, oTxsSession, oTestVm):
497 """
498 Test guest properties.
499 """
500 _ = oSession; _ = oTxsSession; _ = oTestVm;
501 return True;
502
503if __name__ == '__main__':
504 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