VirtualBox

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

Last change on this file since 78351 was 77755, checked in by vboxsync, 6 years ago

tdAddBasic1.py: nits

  • Property svn:eol-style set to LF
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 16.2 KB
Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3# $Id: tdAddBasic1.py 77755 2019-03-18 12:24:20Z vboxsync $
4
5"""
6VirtualBox Validation Kit - Additions Basics #1.
7"""
8
9__copyright__ = \
10"""
11Copyright (C) 2010-2019 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: 77755 $"
31
32# pylint: disable=unnecessary-semicolon
33
34# Standard Python imports.
35import os;
36import sys;
37
38# Only the main script needs to modify the path.
39try: __file__
40except: __file__ = sys.argv[0];
41g_ksValidationKitDir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))));
42sys.path.append(g_ksValidationKitDir);
43
44# Validation Kit imports.
45from testdriver import reporter;
46from testdriver import base;
47from testdriver import vbox;
48from testdriver import vboxcon;
49
50# Sub test driver imports.
51sys.path.append(os.path.dirname(os.path.abspath(__file__))); # For sub-test drivers.
52from tdAddGuestCtrl import SubTstDrvAddGuestCtrl;
53
54
55class tdAddBasic1(vbox.TestDriver): # pylint: disable=R0902
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'];
67 self.asTests = self.asTestsDef;
68 self.asRsrcs = None
69
70 self.addSubTestDriver(SubTstDrvAddGuestCtrl(self));
71
72 #
73 # Overridden methods.
74 #
75 def showUsage(self):
76 rc = vbox.TestDriver.showUsage(self);
77 reporter.log('');
78 reporter.log('tdAddBasic1 Options:');
79 reporter.log(' --tests <s1[:s2[:]]>');
80 reporter.log(' Default: %s (all)' % (':'.join(self.asTestsDef)));
81 reporter.log(' --quick');
82 reporter.log(' Same as --virt-modes hwvirt --cpu-counts 1.');
83 return rc;
84
85 def parseOption(self, asArgs, iArg): # pylint: disable=R0912,R0915
86 if asArgs[iArg] == '--tests':
87 iArg += 1;
88 if iArg >= len(asArgs): raise base.InvalidOption('The "--tests" takes a colon separated list of tests');
89 self.asTests = asArgs[iArg].split(':');
90 for s in self.asTests:
91 if s not in self.asTestsDef:
92 raise base.InvalidOption('The "--tests" value "%s" is not valid; valid values are: %s'
93 % (s, ' '.join(self.asTestsDef),));
94
95 elif asArgs[iArg] == '--quick':
96 self.parseOption(['--virt-modes', 'hwvirt'], 0);
97 self.parseOption(['--cpu-counts', '1'], 0);
98
99 else:
100 return vbox.TestDriver.parseOption(self, asArgs, iArg);
101 return iArg + 1;
102
103 def getResourceSet(self):
104 if self.asRsrcs is None:
105 self.asRsrcs = []
106 for oSubTstDrv in self.aoSubTstDrvs:
107 self.asRsrcs.extend(oSubTstDrv.asRsrcs)
108 self.asRsrcs.extend(self.oTestVmSet.getResourceSet())
109 return self.asRsrcs
110
111 def actionConfig(self):
112 if not self.importVBoxApi(): # So we can use the constant below.
113 return False;
114
115 eNic0AttachType = vboxcon.NetworkAttachmentType_NAT;
116 sGaIso = self.getGuestAdditionsIso();
117 return self.oTestVmSet.actionConfig(self, eNic0AttachType = eNic0AttachType, sDvdImage = sGaIso);
118
119 def actionExecute(self):
120 return self.oTestVmSet.actionExecute(self, self.testOneCfg);
121
122
123 #
124 # Test execution helpers.
125 #
126
127 def testOneCfg(self, oVM, oTestVm):
128 """
129 Runs the specified VM thru the tests.
130
131 Returns a success indicator on the general test execution. This is not
132 the actual test result.
133 """
134 fRc = False;
135
136 if oTestVm.isWindows():
137 sFileCdWait = 'VBoxWindowsAdditions.exe';
138 elif oTestVm.isLinux():
139 sFileCdWait = 'VBoxLinuxAdditions.run';
140
141 self.logVmInfo(oVM);
142 oSession, oTxsSession = self.startVmAndConnectToTxsViaTcp(oTestVm.sVmName, fCdWait = True, sFileCdWait = sFileCdWait);
143 if oSession is not None:
144 self.addTask(oTxsSession);
145 # Do the testing.
146 fSkip = 'install' not in self.asTests;
147 reporter.testStart('Install');
148 if not fSkip:
149 fRc, oTxsSession = self.testInstallAdditions(oSession, oTxsSession, oTestVm);
150 reporter.testDone(fSkip);
151
152 fSkip = 'guestprops' not in self.asTests;
153 reporter.testStart('Guest Properties');
154 if not fSkip:
155 fRc = self.testGuestProperties(oSession, oTxsSession, oTestVm) and fRc;
156 reporter.testDone(fSkip);
157
158 fSkip = 'guestcontrol' not in self.asTests;
159 reporter.testStart('Guest Control');
160 if not fSkip:
161 fRc, oTxsSession = self.aoSubTstDrvs[0].testIt(oTestVm, oSession, oTxsSession);
162 reporter.testDone(fSkip);
163
164 ## @todo Save and restore test.
165
166 ## @todo Reset tests.
167
168 ## @todo Final test: Uninstallation.
169
170 # Cleanup.
171 self.removeTask(oTxsSession);
172 self.terminateVmBySession(oSession)
173 return fRc;
174
175 def testInstallAdditions(self, oSession, oTxsSession, oTestVm):
176 """
177 Tests installing the guest additions
178 """
179 if oTestVm.isWindows():
180 (fRc, oTxsSession) = self.testWindowsInstallAdditions(oSession, oTxsSession, oTestVm);
181 elif oTestVm.isLinux():
182 (fRc, oTxsSession) = self.testLinuxInstallAdditions(oSession, oTxsSession, oTestVm);
183 else:
184 reporter.error('Guest Additions installation not implemented for %s yet! (%s)' % \
185 (oTestVm.sKind, oTestVm.sVmName,));
186 fRc = False;
187
188 #
189 # Verify installation of Guest Additions using commmon bits.
190 #
191 if fRc is True:
192 #
193 # Wait for the GAs to come up.
194 #
195
196 ## @todo need to signed up for a OnAdditionsStateChanged and wait runlevel to
197 # at least reach Userland.
198
199 #
200 # Check if the additions are operational.
201 #
202 try: oGuest = oSession.o.console.guest;
203 except:
204 reporter.errorXcpt('Getting IGuest failed.');
205 return (False, oTxsSession);
206
207 # Check the additionsVersion attribute. It must not be empty.
208 reporter.testStart('IGuest::additionsVersion');
209 fRc = self.testIGuest_additionsVersion(oGuest);
210 reporter.testDone();
211
212 reporter.testStart('IGuest::additionsRunLevel');
213 self.testIGuest_additionsRunLevel(oGuest, oTestVm);
214 reporter.testDone();
215
216 ## @todo test IAdditionsFacilities.
217
218 return (fRc, oTxsSession);
219
220 def testWindowsInstallAdditions(self, oSession, oTxsSession, oTestVm):
221 """
222 Installs the Windows guest additions using the test execution service.
223 Since this involves rebooting the guest, we will have to create a new TXS session.
224 """
225 asLogFiles = [];
226
227 fHaveSetupApiDevLog = False;
228
229 # Delete relevant log files.
230 if oTestVm.sKind in ('WindowsNT4',):
231 sWinDir = 'C:/WinNT/';
232 else:
233 sWinDir = 'C:/Windows/';
234 asLogFiles = [sWinDir + 'setupapi.log', sWinDir + 'setupact.log', sWinDir + 'setuperr.log'];
235
236 # Apply The SetupAPI logging level so that we also get the (most verbose) setupapi.dev.log file.
237 ## @todo !!! HACK ALERT !!! Add the value directly into the testing source image. Later.
238 fHaveSetupApiDevLog = self.txsRunTest(oTxsSession, 'Enabling setupapi.dev.log', 30 * 1000,
239 'c:\\Windows\\System32\\reg.exe',
240 ('c:\\Windows\\System32\\reg.exe', 'add',
241 '"HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Setup"',
242 '/v', 'LogLevel', '/t', 'REG_DWORD', '/d', '0xFF'));
243
244 # On some guests the files in question still can be locked by the OS, so ignore deletion
245 # errors from the guest side (e.g. sharing violations) and just continue.
246 for sFile in asLogFiles:
247 self.txsRmFile(oSession, oTxsSession, sFile, 10 * 1000, fIgnoreErrors = True);
248
249 # Install the public signing key.
250 if oTestVm.sKind not in ('WindowsNT4', 'Windows2000', 'WindowsXP', 'Windows2003'):
251 ## TODO
252 pass;
253
254 #
255 # The actual install.
256 # Enable installing the optional auto-logon modules (VBoxGINA/VBoxCredProv) + (Direct)3D support.
257 # Also tell the installer to produce the appropriate log files.
258 #
259 fRc = self.txsRunTest(oTxsSession, 'VBoxWindowsAdditions.exe', 5 * 60 * 1000, '${CDROM}/VBoxWindowsAdditions.exe',
260 ('${CDROM}/VBoxWindowsAdditions.exe', '/S', '/l', '/with_autologon'));
261 ## @todo For testing the installation (D)3D stuff ('/with_d3d') we need to boot up in safe mode.
262
263 #
264 # Reboot the VM and reconnect the TXS session.
265 #
266 if fRc is True:
267 (fRc, oTxsSession) = self.txsRebootAndReconnectViaTcp(oSession, oTxsSession, cMsTimeout = 3 * 60000);
268
269 if fRc is True:
270 # Add the Windows Guest Additions installer files to the files we want to download
271 # from the guest.
272 sGuestAddsDir = 'C:/Program Files/Oracle/VirtualBox Guest Additions/';
273 asLogFiles.append(sGuestAddsDir + 'install.log');
274 # Note: There won't be a install_ui.log because of the silent installation.
275 asLogFiles.append(sGuestAddsDir + 'install_drivers.log');
276 asLogFiles.append('C:/Windows/setupapi.log');
277
278 # Note: setupapi.dev.log only is available since Windows 2000.
279 if fHaveSetupApiDevLog:
280 asLogFiles.append('C:/Windows/setupapi.dev.log');
281
282 #
283 # Download log files.
284 # Ignore errors as all files above might not be present (or in different locations)
285 # on different Windows guests.
286 #
287 self.txsDownloadFiles(oSession, oTxsSession, asLogFiles, fIgnoreErrors = True);
288
289 return (fRc, oTxsSession);
290
291 def testLinuxInstallAdditions(self, oSession, oTxsSession, oTestVm):
292 oSession = oSession;
293 oTestVm = oTestVm;
294
295 fRc = False;
296
297 # Install Kernel headers, which are required for actually installing the Linux Additions.
298 if oTestVm.sKind.startswith('Debian') \
299 or oTestVm.sKind.startswith('Ubuntu'):
300 fRc = self.txsRunTest(oTxsSession, 'Installing Kernel headers', 5 * 60 *1000,
301 '/usr/bin/apt-get', ('/usr/bin/apt-get', 'install', '-y', 'linux-headers-generic'));
302 if not fRc:
303 reporter.error('Error installing Kernel headers');
304 fRc = self.txsRunTest(oTxsSession, 'Installing Guest Additions depdendencies', 5 * 60 *1000, \
305 '/usr/bin/apt-get', ('/usr/bin/apt-get', 'install', '-y', 'build-essential', 'perl'));
306 if not fRc:
307 reporter.error('Error installing additional installer dependencies');
308 elif oTestVm.sKind.startswith('OL') \
309 or oTestVm.sKind.startswith('Oracle') \
310 or oTestVm.sKind.startswith('RHEL') \
311 or oTestVm.sKind.startswith('Redhat') \
312 or oTestVm.sKind.startswith('Cent'):
313 fRc = self.txsRunTest(oTxsSession, 'Installing Kernel headers', 5 * 60 *1000,
314 '/usr/bin/yum', ('/usr/bin/yum', '-y', 'install', 'kernel-headers'));
315 if not fRc:
316 reporter.error('Error installing Kernel headers');
317 fRc = self.txsRunTest(oTxsSession, 'Installing Guest Additions depdendencies', 5 * 60 *1000, \
318 '/usr/bin/yum', ('/usr/bin/yum', '-y', 'install', \
319 'make', 'automake', 'gcc', 'kernel-devel', 'dkms', 'bzip2', 'perl'));
320 if not fRc:
321 reporter.error('Error installing additional installer dependencies');
322 else:
323 reporter.error('Installing Linux Additions for kind "%s" is not supported yet' % oTestVm.sKind);
324 return (False, oTxsSession);
325
326 if fRc:
327 #
328 # The actual install.
329 # Also tell the installer to produce the appropriate log files.
330 #
331 fRc = self.txsRunTest(oTxsSession, 'VBoxLinuxAdditions.run', 5 * 60 * 1000,
332 '/bin/sh', ('/bin/sh', '${CDROM}/VBoxLinuxAdditions.run'));
333 if not fRc:
334 reporter.error('Installing Linux Additions failed (see log file for details)');
335
336 #
337 # Download log files.
338 # Ignore errors as all files above might not be present for whatever reason.
339 #
340 asLogFile = [];
341 asLogFile.append('/var/log/vboxadd-install.log');
342 self.txsDownloadFiles(oSession, oTxsSession, asLogFile, fIgnoreErrors = True);
343
344 if fRc:
345 (fRc, oTxsSession) = self.txsRebootAndReconnectViaTcp(oSession, oTxsSession, cMsTimeout = 3 * 60000);
346
347 return (fRc, oTxsSession);
348
349 def testIGuest_additionsVersion(self, oGuest):
350 """
351 Returns False if no version string could be obtained, otherwise True
352 even though errors are logged.
353 """
354 try:
355 sVer = oGuest.additionsVersion;
356 except:
357 reporter.errorXcpt('Getting the additions version failed.');
358 return False;
359 reporter.log('IGuest::additionsVersion="%s"' % (sVer,));
360
361 if sVer.strip() == '':
362 reporter.error('IGuest::additionsVersion is empty.');
363 return False;
364
365 if sVer != sVer.strip():
366 reporter.error('IGuest::additionsVersion is contains spaces: "%s".' % (sVer,));
367
368 asBits = sVer.split('.');
369 if len(asBits) < 3:
370 reporter.error('IGuest::additionsVersion does not contain at least tree dot separated fields: "%s" (%d).'
371 % (sVer, len(asBits)));
372
373 ## @todo verify the format.
374 return True;
375
376 def testIGuest_additionsRunLevel(self, oGuest, oTestVm):
377 """
378 Do run level tests.
379 """
380 if oTestVm.isLoggedOntoDesktop():
381 eExpectedRunLevel = vboxcon.AdditionsRunLevelType_Desktop;
382 else:
383 eExpectedRunLevel = vboxcon.AdditionsRunLevelType_Userland;
384
385 ## @todo Insert wait for the desired run level.
386 try:
387 iLevel = oGuest.additionsRunLevel;
388 except:
389 reporter.errorXcpt('Getting the additions run level failed.');
390 return False;
391 reporter.log('IGuest::additionsRunLevel=%s' % (iLevel,));
392
393 if iLevel != eExpectedRunLevel:
394 pass; ## @todo We really need that wait!!
395 #reporter.error('Expected runlevel %d, found %d instead' % (eExpectedRunLevel, iLevel));
396 return True;
397
398
399 def testGuestProperties(self, oSession, oTxsSession, oTestVm):
400 """
401 Test guest properties.
402 """
403 _ = oSession; _ = oTxsSession; _ = oTestVm;
404 return True;
405
406if __name__ == '__main__':
407 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