VirtualBox

source: vbox/trunk/src/VBox/ValidationKit/tests/autostart/tdAutostart1.py@ 84757

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

Main: bugref:9341: Added log about nested VM existence

  • Property svn:eol-style set to LF
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 73.2 KB
Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3
4"""
5AUtostart testcase using.
6"""
7
8__copyright__ = \
9"""
10Copyright (C) 2013-2020 Oracle Corporation
11
12This file is part of VirtualBox Open Source Edition (OSE), as
13available from http://www.virtualbox.org. This file is free software;
14you can redistribute it and/or modify it under the terms of the GNU
15General Public License (GPL) as published by the Free Software
16Foundation, in version 2 as it comes in the "COPYING" file of the
17VirtualBox OSE distribution. VirtualBox OSE is distributed in the
18hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
19
20The contents of this file may alternatively be used under the terms
21of the Common Development and Distribution License Version 1.0
22(CDDL) only, as it comes in the "COPYING.CDDL" file of the
23VirtualBox OSE distribution, in which case the provisions of the
24CDDL are applicable instead of those of the GPL.
25
26You may elect to license modified versions of this file under the
27terms and conditions of either the GPL or the CDDL or both.
28"""
29__version__ = "$Id: tdAutostart1.py 84757 2020-06-10 13:13:43Z vboxsync $"
30
31
32# Standard Python imports.
33import os;
34import sys;
35import re;
36import ssl;
37
38# Python 3 hacks:
39if sys.version_info[0] < 3:
40 import urllib2 as urllib; # pylint: disable=import-error,no-name-in-module
41 from urllib2 import ProxyHandler as urllib_ProxyHandler; # pylint: disable=import-error,no-name-in-module
42 from urllib2 import build_opener as urllib_build_opener; # pylint: disable=import-error,no-name-in-module
43else:
44 import urllib; # pylint: disable=import-error,no-name-in-module
45 from urllib.request import ProxyHandler as urllib_ProxyHandler; # pylint: disable=import-error,no-name-in-module
46 from urllib.request import build_opener as urllib_build_opener; # pylint: disable=import-error,no-name-in-module
47
48
49# Only the main script needs to modify the path.
50try: __file__
51except: __file__ = sys.argv[0];
52g_ksValidationKitDir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))));
53sys.path.append(g_ksValidationKitDir);
54
55# Validation Kit imports.
56from testdriver import reporter;
57from testdriver import base;
58from testdriver import vbox;
59from testdriver import vboxcon;
60from testdriver import vboxwrappers;
61from common import utils;
62
63# Python 3 hacks:
64if sys.version_info[0] >= 3:
65 long = int # pylint: disable=redefined-builtin,invalid-name
66 xrange = range; # pylint: disable=redefined-builtin,invalid-name
67
68
69class VBoxManageStdOutWrapper(object):
70 """ Parser for VBoxManage list runningvms """
71 def __init__(self):
72 self.sVmRunning = '';
73
74 def __del__(self):
75 self.close();
76
77 def close(self):
78 """file.close"""
79 return;
80
81 def read(self, cb):
82 """file.read"""
83 _ = cb;
84 return "";
85
86 def write(self, sText):
87 """VBoxManage stdout write"""
88 if sText is None:
89 return None;
90
91 try: sText = str(sText); # pylint: disable=redefined-variable-type
92 except: pass;
93
94 asLines = sText.splitlines();
95 for sLine in asLines:
96 sLine = sLine.strip();
97
98 reporter.log('Logging: ' + sLine);
99
100 # Extract the value
101 idxVmNameStart = sLine.find('"');
102 if idxVmNameStart == -1:
103 raise Exception('VBoxManageStdOutWrapper: Invalid output');
104
105 idxVmNameStart += 1;
106 idxVmNameEnd = idxVmNameStart;
107 while sLine[idxVmNameEnd] != '"':
108 idxVmNameEnd += 1;
109
110 self.sVmRunning = sLine[idxVmNameStart:idxVmNameEnd];
111 reporter.log('Logging: ' + self.sVmRunning);
112
113 return None;
114
115
116def downloadFile(sUrlFile, sDstFile, sLocalPrefix, fnLog, fnError = None, fNoProxies=True):
117 """
118 Downloads the given file if an URL is given, otherwise assume it's
119 something on the build share and copy it from there.
120
121 Raises no exceptions, returns log + success indicator instead.
122
123 Note! This method may use proxies configured on the system and the
124 http_proxy, ftp_proxy, no_proxy environment variables.
125
126 """
127 if fnError is None:
128 fnError = fnLog;
129
130 if sUrlFile.startswith('http://') \
131 or sUrlFile.startswith('https://') \
132 or sUrlFile.startswith('ftp://'):
133 # Download the file.
134 fnLog('Downloading "%s" to "%s"...' % (sUrlFile, sDstFile));
135 try:
136 # Disable SSL certificate verification for our servers
137 ssl_ctx = ssl.create_default_context();
138 ssl_ctx.check_hostname = False;
139 ssl_ctx.verify_mode = ssl.CERT_NONE;
140
141 ## @todo We get 404.html content instead of exceptions here, which is confusing and should be addressed.
142 if not fNoProxies:
143 oOpener = urllib_build_opener(urllib.HTTPSHandler(context = ssl_ctx));
144 else:
145 oOpener = urllib_build_opener(urllib.HTTPSHandler(context = ssl_ctx), urllib_ProxyHandler(proxies = dict()));
146 oSrc = oOpener.open(sUrlFile);
147 oDst = utils.openNoInherit(sDstFile, 'wb');
148 oDst.write(oSrc.read());
149 oDst.close();
150 oSrc.close();
151 except Exception as oXcpt:
152 fnError('Error downloading "%s" to "%s": %s' % (sUrlFile, sDstFile, oXcpt));
153 return False;
154 else:
155 # Assumes file from the build share.
156 sSrcPath = os.path.join(sLocalPrefix, sUrlFile);
157 fnLog('Copying "%s" to "%s"...' % (sSrcPath, sDstFile));
158 try:
159 utils.copyFileSimple(sSrcPath, sDstFile);
160 except Exception as oXcpt:
161 fnError('Error copying "%s" to "%s": %s' % (sSrcPath, sDstFile, oXcpt));
162 return False;
163
164 return True;
165
166
167class tdAutostartOs(object):
168 """
169 Base autostart helper class to provide common methods.
170 """
171
172 def __init__(self, oTestDriver, fpApiVer, sGuestAdditionsIso):
173 self.oTestDriver = oTestDriver;
174 self.fpApiVer = fpApiVer;
175 self.sGuestAdditionsIso = sGuestAdditionsIso;
176
177 def _findFile(self, sRegExp, asTestBuildDirs):
178 """
179 Returns a filepath based on the given regex and paths to look into
180 or None if no matching file is found.
181 """
182
183 oRegExp = re.compile(sRegExp);
184 for sTestBuildDir in asTestBuildDirs:
185 try:
186 #return most recent file if there are several ones matching the pattern
187 asFiles = [s for s in os.listdir(sTestBuildDir)
188 if os.path.isfile(os.path.join(sTestBuildDir, s))];
189 asFiles = (s for s in asFiles
190 if oRegExp.match(os.path.basename(s))
191 and os.path.exists(sTestBuildDir + '/' + s));
192 asFiles = sorted(asFiles, reverse = True,
193 key = lambda s, sTstBuildDir = sTestBuildDir: os.path.getmtime(os.path.join(sTstBuildDir, s)));
194 if asFiles:
195 return sTestBuildDir + '/' + asFiles[0];
196 except:
197 pass;
198
199 reporter.error('Failed to find a file matching "%s" in %s.' % (sRegExp, ','.join(asTestBuildDirs)));
200 return None;
201
202 def _createAutostartCfg(self, sDefaultPolicy = 'allow', asUserAllow = (), asUserDeny = ()):
203 """
204 Creates a autostart config for VirtualBox
205 """
206
207 sVBoxCfg = 'default_policy=' + sDefaultPolicy + '\n';
208
209 for sUserAllow in asUserAllow:
210 sVBoxCfg = sVBoxCfg + sUserAllow + ' = {\n allow = true\n }\n';
211
212 for sUserDeny in asUserDeny:
213 sVBoxCfg = sVBoxCfg + sUserDeny + ' = {\n allow = false\n }\n';
214
215 return sVBoxCfg;
216
217 def createSession(self, oSession, sName, sUser, sPassword, cMsTimeout = 10 * 1000, fIsError = True):
218 """
219 Creates (opens) a guest session.
220 Returns (True, IGuestSession) on success or (False, None) on failure.
221 """
222 oGuest = oSession.o.console.guest;
223 if sName is None:
224 sName = "<untitled>";
225
226 reporter.log('Creating session "%s" ...' % (sName,));
227 try:
228 oGuestSession = oGuest.createSession(sUser, sPassword, '', sName);
229 except:
230 # Just log, don't assume an error here (will be done in the main loop then).
231 reporter.maybeErrXcpt(fIsError, 'Creating a guest session "%s" failed; sUser="%s", pw="%s"'
232 % (sName, sUser, sPassword));
233 return (False, None);
234
235 reporter.log('Waiting for session "%s" to start within %dms...' % (sName, cMsTimeout));
236 aeWaitFor = [ vboxcon.GuestSessionWaitForFlag_Start, ];
237 try:
238 waitResult = oGuestSession.waitForArray(aeWaitFor, cMsTimeout);
239
240 #
241 # Be nice to Guest Additions < 4.3: They don't support session handling and
242 # therefore return WaitFlagNotSupported.
243 #
244 if waitResult not in (vboxcon.GuestSessionWaitResult_Start, vboxcon.GuestSessionWaitResult_WaitFlagNotSupported):
245 # Just log, don't assume an error here (will be done in the main loop then).
246 reporter.maybeErr(fIsError, 'Session did not start successfully, returned wait result: %d' % (waitResult,));
247 return (False, None);
248 reporter.log('Session "%s" successfully started' % (sName,));
249 except:
250 # Just log, don't assume an error here (will be done in the main loop then).
251 reporter.maybeErrXcpt(fIsError, 'Waiting for guest session "%s" (usr=%s;pw=%s) to start failed:'
252 % (sName, sUser, sPassword,));
253 return (False, None);
254 return (True, oGuestSession);
255
256 def closeSession(self, oGuestSession, fIsError = True):
257 """
258 Closes the guest session.
259 """
260 if oGuestSession is not None:
261 try:
262 sName = oGuestSession.name;
263 except:
264 return reporter.errorXcpt();
265
266 reporter.log('Closing session "%s" ...' % (sName,));
267 try:
268 oGuestSession.close();
269 oGuestSession = None;
270 except:
271 # Just log, don't assume an error here (will be done in the main loop then).
272 reporter.maybeErrXcpt(fIsError, 'Closing guest session "%s" failed:' % (sName,));
273 return False;
274 return True;
275
276 def guestProcessExecute(self, oGuestSession, sTestName, cMsTimeout, sExecName, asArgs = (),
277 fGetStdOut = True, fIsError = True):
278 """
279 Helper function to execute a program on a guest, specified in the current test.
280 Returns (True, ProcessStatus, ProcessExitCode, ProcessStdOutBuffer) on success or (False, 0, 0, None) on failure.
281 """
282 _ = sTestName;
283 fRc = True; # Be optimistic.
284
285 reporter.log2('Using session user=%s, name=%s, timeout=%d'
286 % (oGuestSession.user, oGuestSession.name, oGuestSession.timeout,));
287
288 #
289 # Start the process:
290 #
291 reporter.log2('Executing sCmd=%s, timeoutMS=%d, asArgs=%s'
292 % (sExecName, cMsTimeout, asArgs, ));
293 fTaskFlags = [];
294 if fGetStdOut:
295 fTaskFlags = [vboxcon.ProcessCreateFlag_WaitForStdOut,
296 vboxcon.ProcessCreateFlag_WaitForStdErr];
297 try:
298 oProcess = oGuestSession.processCreate(sExecName,
299 asArgs if self.fpApiVer >= 5.0 else asArgs[1:],
300 [], fTaskFlags, cMsTimeout);
301 except:
302 reporter.maybeErrXcpt(fIsError, 'asArgs=%s' % (asArgs,));
303 return (False, 0, 0, None);
304 if oProcess is None:
305 return (reporter.error('oProcess is None! (%s)' % (asArgs,)), 0, 0, None);
306
307 #time.sleep(5); # try this if you want to see races here.
308
309 # Wait for the process to start properly:
310 reporter.log2('Process start requested, waiting for start (%dms) ...' % (cMsTimeout,));
311 iPid = -1;
312 aeWaitFor = [ vboxcon.ProcessWaitForFlag_Start, ];
313 aBuf = None;
314 try:
315 eWaitResult = oProcess.waitForArray(aeWaitFor, cMsTimeout);
316 except:
317 reporter.maybeErrXcpt(fIsError, 'waitforArray failed for asArgs=%s' % (asArgs,));
318 fRc = False;
319 else:
320 try:
321 eStatus = oProcess.status;
322 iPid = oProcess.PID;
323 except:
324 fRc = reporter.errorXcpt('asArgs=%s' % (asArgs,));
325 else:
326 reporter.log2('Wait result returned: %d, current process status is: %d' % (eWaitResult, eStatus,));
327
328 #
329 # Wait for the process to run to completion if necessary.
330 #
331 # Note! The above eWaitResult return value can be ignored as it will
332 # (mostly) reflect the process status anyway.
333 #
334 if eStatus == vboxcon.ProcessStatus_Started:
335
336 # What to wait for:
337 aeWaitFor = [ vboxcon.ProcessWaitForFlag_Terminate,
338 vboxcon.ProcessWaitForFlag_StdOut,
339 vboxcon.ProcessWaitForFlag_StdErr];
340
341 reporter.log2('Process (PID %d) started, waiting for termination (%dms), aeWaitFor=%s ...'
342 % (iPid, cMsTimeout, aeWaitFor));
343 acbFdOut = [0,0,0];
344 while True:
345 try:
346 eWaitResult = oProcess.waitForArray(aeWaitFor, cMsTimeout);
347 except KeyboardInterrupt: # Not sure how helpful this is, but whatever.
348 reporter.error('Process (PID %d) execution interrupted' % (iPid,));
349 try: oProcess.close();
350 except: pass;
351 break;
352 except:
353 fRc = reporter.errorXcpt('asArgs=%s' % (asArgs,));
354 break;
355 reporter.log2('Wait returned: %d' % (eWaitResult,));
356
357 # Process output:
358 for eFdResult, iFd, sFdNm in [ (vboxcon.ProcessWaitResult_StdOut, 1, 'stdout'),
359 (vboxcon.ProcessWaitResult_StdErr, 2, 'stderr'), ]:
360 if eWaitResult in (eFdResult, vboxcon.ProcessWaitResult_WaitFlagNotSupported):
361 reporter.log2('Reading %s ...' % (sFdNm,));
362 try:
363 abBuf = oProcess.Read(1, 64 * 1024, cMsTimeout);
364 except KeyboardInterrupt: # Not sure how helpful this is, but whatever.
365 reporter.error('Process (PID %d) execution interrupted' % (iPid,));
366 try: oProcess.close();
367 except: pass;
368 except:
369 pass; ## @todo test for timeouts and fail on anything else!
370 else:
371 if abBuf:
372 reporter.log2('Process (PID %d) got %d bytes of %s data' % (iPid, len(abBuf), sFdNm,));
373 acbFdOut[iFd] += len(abBuf);
374 ## @todo Figure out how to uniform + append!
375 if aBuf:
376 aBuf += str(abBuf);
377 else:
378 aBuf = str(abBuf);
379
380 ## Process input (todo):
381 #if eWaitResult in (vboxcon.ProcessWaitResult_StdIn, vboxcon.ProcessWaitResult_WaitFlagNotSupported):
382 # reporter.log2('Process (PID %d) needs stdin data' % (iPid,));
383
384 # Termination or error?
385 if eWaitResult in (vboxcon.ProcessWaitResult_Terminate,
386 vboxcon.ProcessWaitResult_Error,
387 vboxcon.ProcessWaitResult_Timeout,):
388 try: eStatus = oProcess.status;
389 except: fRc = reporter.errorXcpt('asArgs=%s' % (asArgs,));
390 reporter.log2('Process (PID %d) reported terminate/error/timeout: %d, status: %d'
391 % (iPid, eWaitResult, eStatus,));
392 break;
393
394 # End of the wait loop.
395 _, cbStdOut, cbStdErr = acbFdOut;
396
397 try: eStatus = oProcess.status;
398 except: fRc = reporter.errorXcpt('asArgs=%s' % (asArgs,));
399 reporter.log2('Final process status (PID %d) is: %d' % (iPid, eStatus));
400 reporter.log2('Process (PID %d) %d stdout, %d stderr' % (iPid, cbStdOut, cbStdErr));
401
402 #
403 # Get the final status and exit code of the process.
404 #
405 try:
406 uExitStatus = oProcess.status;
407 iExitCode = oProcess.exitCode;
408 except:
409 fRc = reporter.errorXcpt('asArgs=%s' % (asArgs,));
410 reporter.log2('Process (PID %d) has exit code: %d; status: %d ' % (iPid, iExitCode, uExitStatus));
411
412 return (fRc, uExitStatus, iExitCode, aBuf);
413
414 def uploadString(self, oGuestSession, sSrcString, sDst):
415 """
416 Upload the string into guest.
417 """
418 fRc = True;
419 try:
420 oFile = oGuestSession.fileOpenEx(sDst, vboxcon.FileAccessMode_ReadWrite, vboxcon.FileOpenAction_CreateOrReplace,
421 vboxcon.FileSharingMode_All, 0, []);
422 except:
423 fRc = reporter.errorXcpt('Upload string failed. Could not create and open the file %s' % sDst);
424 else:
425 try:
426 oFile.write(bytearray(sSrcString), 60*1000);
427 except:
428 fRc = reporter.errorXcpt('Upload string failed. Could not write the string into the file %s' % sDst);
429 try:
430 oFile.close();
431 except:
432 fRc = reporter.errorXcpt('Upload string failed. Could not close the file %s' % sDst);
433
434 return fRc;
435
436 def uploadFile(self, oGuestSession, sSrc, sDst):
437 """
438 Upload the string into guest.
439 """
440 fRc = True;
441 try:
442 if self.fpApiVer >= 5.0:
443 oCurProgress = oGuestSession.fileCopyToGuest(sSrc, sDst, [0]);
444 else:
445 oCurProgress = oGuestSession.copyTo(sSrc, sDst, [0]);
446 except:
447 reporter.maybeErrXcpt(True, 'Upload file exception for sSrc="%s":'
448 % (self.sGuestAdditionsIso,));
449 fRc = False;
450 else:
451 if oCurProgress is not None:
452 oWrapperProgress = vboxwrappers.ProgressWrapper(oCurProgress, self.oTestDriver.oVBoxMgr,
453 self.oTestDriver, "uploadFile");
454 oWrapperProgress.wait();
455 if not oWrapperProgress.isSuccess():
456 oWrapperProgress.logResult(fIgnoreErrors = False);
457 fRc = False;
458 else:
459 fRc = reporter.error('No progress object returned');
460
461 return fRc;
462
463 def downloadFile(self, oGuestSession, sSrc, sDst, fIgnoreErrors = False):
464 """
465 Upload the string into guest.
466 """
467 fRc = True;
468 try:
469 if self.fpApiVer >= 5.0:
470 oCurProgress = oGuestSession.fileCopyFromGuest(sSrc, sDst, [0]);
471 else:
472 oCurProgress = oGuestSession.copyFrom(sSrc, sDst, [0]);
473 except:
474 if not fIgnoreErrors:
475 reporter.errorXcpt('Download file exception for sSrc="%s":' % (self.sGuestAdditionsIso,));
476 else:
477 reporter.log('warning: Download file exception for sSrc="%s":' % (self.sGuestAdditionsIso,));
478 fRc = False;
479 else:
480 if oCurProgress is not None:
481 oWrapperProgress = vboxwrappers.ProgressWrapper(oCurProgress, self.oTestDriver.oVBoxMgr,
482 self.oTestDriver, "downloadFile");
483 oWrapperProgress.wait();
484 if not oWrapperProgress.isSuccess():
485 oWrapperProgress.logResult(fIgnoreErrors);
486 fRc = False;
487 else:
488 if not fIgnoreErrors:
489 reporter.error('No progress object returned');
490 else:
491 reporter.log('warning: No progress object returned');
492 fRc = False;
493
494 return fRc;
495
496 def downloadFiles(self, oGuestSession, asFiles, fIgnoreErrors = False):
497 """
498 Convenience function to get files from the guest and stores it
499 into the scratch directory for later (manual) review.
500
501 Returns True on success.
502
503 Returns False on failure, logged.
504 """
505 fRc = True;
506 for sGstFile in asFiles:
507 sTmpFile = os.path.join(self.oTestDriver.sScratchPath, 'tmp-' + os.path.basename(sGstFile));
508 reporter.log2('Downloading file "%s" to "%s" ...' % (sGstFile, sTmpFile));
509 # First try to remove (unlink) an existing temporary file, as we don't truncate the file.
510 try: os.unlink(sTmpFile);
511 except: pass;
512 ## @todo Check for already existing files on the host and create a new
513 # name for the current file to download.
514 fRc = self.downloadFile(oGuestSession, sGstFile, sTmpFile, fIgnoreErrors);
515 if fRc:
516 reporter.addLogFile(sTmpFile, 'misc/other', 'guest - ' + sGstFile);
517 else:
518 if fIgnoreErrors is not True:
519 reporter.error('error downloading file "%s" to "%s"' % (sGstFile, sTmpFile));
520 return fRc;
521 reporter.log('warning: file "%s" was not downloaded, ignoring.' % (sGstFile,));
522 return True;
523
524
525class tdAutostartOsLinux(tdAutostartOs):
526 """
527 Autostart support methods for Linux guests.
528 """
529
530 def __init__(self, oTestDriver, asTestBuildDirs, fpApiVer, sGuestAdditionsIso):
531 tdAutostartOs.__init__(self, oTestDriver, fpApiVer, sGuestAdditionsIso);
532 self.sTestBuild = self._findFile('^VirtualBox-.*\\.run$', asTestBuildDirs);
533 if not self.sTestBuild:
534 raise base.GenError("VirtualBox install package not found");
535
536 def waitVMisReady(self, oSession):
537 """
538 Waits the VM is ready after start or reboot.
539 Returns result (true or false) and guest session obtained
540 """
541 # Give the VM a time to reboot
542 self.oTestDriver.sleep(30);
543
544 # Waiting the VM is ready.
545 # To do it, one will try to open the guest session and start the guest process in loop
546
547 cAttempt = 0;
548 oGuestSession = None;
549 fRc = False;
550 while cAttempt < 30:
551 fRc, oGuestSession = self.createSession(oSession, 'Session for user: vbox',
552 'vbox', 'password', 10 * 1000, False);
553 if fRc:
554 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Start a guest process',
555 30 * 1000, '/sbin/ifconfig',
556 ['ifconfig',],
557 False, False);
558 if fRc:
559 break;
560
561 self.closeSession(oGuestSession, False);
562
563 self.oTestDriver.sleep(10);
564 cAttempt += 1;
565
566 return (fRc, oGuestSession);
567
568 def rebootVMAndCheckReady(self, oSession, oGuestSession):
569 """
570 Reboot the VM and wait the VM is ready.
571 Returns result and guest session obtained after reboot
572 """
573 reporter.testStart('Reboot VM and wait for readiness');
574 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Reboot the VM',
575 30 * 1000, '/usr/bin/sudo',
576 ['sudo', 'reboot'],
577 False, True);
578 if not fRc:
579 reporter.error('Calling the reboot utility failed');
580 fRc = self.closeSession(oGuestSession, True) and fRc and True; # pychecker hack.
581 if fRc:
582 (fRc, oGuestSession) = self.waitVMisReady(oSession);
583
584 if not fRc:
585 reporter.error('VM is not ready after reboot');
586 reporter.testDone();
587 return (fRc, oGuestSession);
588
589 def powerDownVM(self, oGuestSession):
590 """
591 Power down the VM by calling guest process without wating
592 the VM is really powered off. Also, closes the guest session.
593 It helps the terminateBySession to stop the VM without aborting.
594 """
595
596 if oGuestSession is None:
597 return False;
598
599 reporter.testStart('Power down the VM');
600
601 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Power down the VM',
602 30 * 1000, '/usr/bin/sudo',
603 ['sudo', 'poweroff'],
604 False, True);
605 if not fRc:
606 reporter.error('Calling the poweroff utility failed');
607 fRc = self.closeSession(oGuestSession, True) and fRc and True; # pychecker hack.
608
609 if not fRc:
610 reporter.error('Power down the VM failed');
611 reporter.testDone();
612 return fRc;
613
614 def installAdditions(self, oSession, oGuestSession, oVM):
615 """
616 Install guest additions in the guest.
617 """
618 reporter.testStart('Install Guest Additions');
619
620 fRc = False;
621 # Install Kernel headers, which are required for actually installing the Linux Additions.
622 if oVM.OSTypeId.startswith('Debian') \
623 or oVM.OSTypeId.startswith('Ubuntu'):
624 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Installing Kernel headers',
625 5 * 60 *1000, '/usr/bin/apt-get',
626 ['/usr/bin/apt-get', 'install', '-y',
627 'linux-headers-generic'],
628 False, True);
629 if not fRc:
630 reporter.error('Error installing Kernel headers');
631 else:
632 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Installing Guest Additions depdendencies',
633 5 * 60 *1000, '/usr/bin/apt-get',
634 ['/usr/bin/apt-get', 'install', '-y', 'build-essential',
635 'perl'], False, True);
636 if not fRc:
637 reporter.error('Error installing additional installer dependencies');
638
639 elif oVM.OSTypeId.startswith('OL') \
640 or oVM.OSTypeId.startswith('Oracle') \
641 or oVM.OSTypeId.startswith('RHEL') \
642 or oVM.OSTypeId.startswith('Redhat') \
643 or oVM.OSTypeId.startswith('Cent'):
644 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Installing Kernel headers',
645 5 * 60 *1000, '/usr/bin/yum',
646 ['/usr/bin/yum', '-y', 'install', 'kernel-headers'],
647 False, True);
648 if not fRc:
649 reporter.error('Error installing Kernel headers');
650 else:
651 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Installing Guest Additions depdendencies',
652 5 * 60 *1000, '/usr/bin/yum',
653 ['/usr/bin/yum', '-y', 'install', 'make', 'automake', 'gcc',
654 'kernel-devel', 'dkms', 'bzip2', 'perl'], False, True);
655 if not fRc:
656 reporter.error('Error installing additional installer dependencies');
657
658 else:
659 reporter.error('Installing Linux Additions for the "%s" is not supported yet' % oVM.OSTypeId);
660 fRc = False;
661
662 if fRc:
663 #
664 # The actual install.
665 # Also tell the installer to produce the appropriate log files.
666 #
667
668 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Installing guest additions',
669 10 * 60 *1000, '/usr/bin/sudo',
670 ['/usr/bin/sudo', '/bin/sh',
671 '/media/cdrom/VBoxLinuxAdditions.run'],
672 False, True);
673 if fRc:
674 # Due to the GA updates as separate process the above function returns before
675 # the actual installation finished. So just wait until the GA installed
676 fRc = self.closeSession(oGuestSession);
677 if fRc:
678 (fRc, oGuestSession) = self.waitVMisReady(oSession);
679
680 # Download log files.
681 # Ignore errors as all files above might not be present for whatever reason.
682 #
683 if fRc:
684 asLogFile = [];
685 asLogFile.append('/var/log/vboxadd-install.log');
686 self.downloadFiles(oGuestSession, asLogFile, fIgnoreErrors = True);
687 else:
688 reporter.error('Installing guest additions failed: Error occured during vbox installer execution')
689
690 if fRc:
691 (fRc, oGuestSession) = self.rebootVMAndCheckReady(oSession, oGuestSession);
692 if not fRc:
693 reporter.error('Reboot after installing GuestAdditions failed');
694 reporter.testDone();
695 return (fRc, oGuestSession);
696
697 def installVirtualBox(self, oGuestSession):
698 """
699 Install VirtualBox in the guest.
700 """
701 if self.sTestBuild is None:
702 return False;
703
704 reporter.testStart('Install Virtualbox into the guest VM');
705
706 fRc = self.uploadFile(oGuestSession, self.sTestBuild,
707 '/tmp/' + os.path.basename(self.sTestBuild));
708 if not fRc:
709 reporter.error('Upload the vbox installer into guest VM failed');
710 else:
711 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession,
712 'Allowing execution for the vbox installer',
713 30 * 1000, '/usr/bin/sudo',
714 ['/usr/bin/sudo', '/bin/chmod', '755',
715 '/tmp/' + os.path.basename(self.sTestBuild)],
716 False, True);
717 if not fRc:
718 reporter.error('Allowing execution for the vbox installer failed');
719 if fRc:
720 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Installing VBox',
721 240 * 1000, '/usr/bin/sudo',
722 ['/usr/bin/sudo',
723 '/tmp/' + os.path.basename(self.sTestBuild),],
724 False, True);
725 if not fRc:
726 reporter.error('Installing VBox failed');
727 reporter.testDone();
728 return fRc;
729
730 def configureAutostart(self, oGuestSession, sDefaultPolicy = 'allow',
731 asUserAllow = (), asUserDeny = ()):
732 """
733 Configures the autostart feature in the guest.
734 """
735 reporter.testStart('Configure autostart');
736 # Create autostart database directory writeable for everyone
737 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Creating autostart database',
738 30 * 1000, '/usr/bin/sudo',
739 ['/usr/bin/sudo', '/bin/mkdir', '-m', '1777', '/etc/vbox/autostart.d'],
740 False, True);
741 if not fRc:
742 reporter.error('Creating autostart database failed');
743 # Create /etc/default/virtualbox
744 if fRc:
745 sVBoxCfg = 'VBOXAUTOSTART_CONFIG=/etc/vbox/autostart.cfg\n' \
746 + 'VBOXAUTOSTART_DB=/etc/vbox/autostart.d\n';
747 fRc = self.uploadString(oGuestSession, sVBoxCfg, '/tmp/virtualbox');
748 if not fRc:
749 reporter.error('Upload to /tmp/virtualbox failed');
750 if fRc:
751 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Moving to destination',
752 30 * 1000, '/usr/bin/sudo',
753 ['/usr/bin/sudo', '/bin/mv', '/tmp/virtualbox',
754 '/etc/default/virtualbox'],
755 False, True);
756 if not fRc:
757 reporter.error('Moving the /tmp/virtualbox to destination failed');
758 if fRc:
759 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Setting permissions',
760 30 * 1000, '/usr/bin/sudo',
761 ['/usr/bin/sudo', '/bin/chmod', '644',
762 '/etc/default/virtualbox'],
763 False, True);
764 if not fRc:
765 reporter.error('Setting permissions for the virtualbox failed');
766
767 if fRc:
768 sVBoxCfg = self._createAutostartCfg(sDefaultPolicy, asUserAllow, asUserDeny);
769 fRc = self.uploadString(oGuestSession, sVBoxCfg, '/tmp/autostart.cfg');
770 if not fRc:
771 reporter.error('Upload to /tmp/autostart.cfg failed');
772
773 if fRc:
774 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Moving to destination',
775 30 * 1000, '/usr/bin/sudo',
776 ['/usr/bin/sudo', '/bin/mv', '/tmp/autostart.cfg',
777 '/etc/vbox/autostart.cfg'],
778 False, True);
779 if not fRc:
780 reporter.error('Moving the /tmp/autostart.cfg to destination failed');
781 if fRc:
782 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Setting permissions',
783 30 * 1000, '/usr/bin/sudo',
784 ['/usr/bin/sudo', '/bin/chmod', '644',
785 '/etc/vbox/autostart.cfg'],
786 False, True);
787 if not fRc:
788 reporter.error('Setting permissions for the autostart.cfg failed');
789 reporter.testDone();
790 return fRc;
791
792 def createUser(self, oGuestSession, sUser):
793 """
794 Create a new user with the given name
795 """
796 reporter.testStart('Create user %s' % sUser);
797 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Creating new user',
798 30 * 1000, '/usr/bin/sudo',
799 ['/usr/bin/sudo', '/usr/sbin/useradd', '-m', '-U',
800 sUser], False, True);
801 if not fRc:
802 reporter.error('Create user %s failed' % sUser);
803 reporter.testDone();
804 return fRc;
805
806 # pylint: enable=too-many-arguments
807
808 def createTestVM(self, oSession, oGuestSession, sUser, sVmName):
809 """
810 Create a test VM in the guest and enable autostart.
811 Due to the sUser is created whithout password,
812 all calls will be perfomed using 'sudo -u sUser'
813 """
814
815 _ = oSession;
816
817 reporter.testStart('Create test VM for user %s' % sUser);
818
819 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Configuring autostart database',
820 30 * 1000, '/usr/bin/sudo',
821 ['/usr/bin/sudo', '-u', sUser, '-H', '/opt/VirtualBox/VBoxManage',
822 'setproperty', 'autostartdbpath', '/etc/vbox/autostart.d'],
823 False, True);
824 if not fRc:
825 reporter.error('Configuring autostart database failed');
826 else:
827 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Create VM ' + sVmName,
828 30 * 1000, '/usr/bin/sudo',
829 ['/usr/bin/sudo', '-u', sUser, '-H',
830 '/opt/VirtualBox/VBoxManage', 'createvm',
831 '--name', sVmName, '--register'], False, True);
832 if not fRc:
833 reporter.error('Create VM %s failed' % sVmName);
834 if fRc:
835 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Enabling autostart for test VM',
836 30 * 1000, '/usr/bin/sudo',
837 ['/usr/bin/sudo', '-u', sUser, '-H',
838 '/opt/VirtualBox/VBoxManage', 'modifyvm',
839 sVmName, '--autostart-enabled', 'on'], False, True);
840 if not fRc:
841 reporter.error('Enabling autostart for %s failed' % sVmName);
842 reporter.testDone();
843 return fRc;
844
845 def checkForRunningVM(self, oSession, oGuestSession, sUser, sVmName):
846 """
847 Check for VM running in the guest after autostart.
848 Due to the sUser is created whithout password,
849 all calls will be perfomed using 'sudo -u sUser'
850 """
851
852 _ = oSession;
853
854 reporter.testStart('Check the VM %s is running for user %s' % (sVmName, sUser));
855 (fRc, _, _, aBuf) = self.guestProcessExecute(oGuestSession, 'Check for running VM',
856 30 * 1000, '/usr/bin/sudo',
857 ['/usr/bin/sudo', '-u', sUser, '-H',
858 '/opt/VirtualBox/VBoxManage',
859 'list', 'runningvms'], True, True);
860 if not fRc:
861 reporter.error('Checking the VM %s is running for user %s failed' % (sVmName, sUser));
862 else:
863 bufWrapper = VBoxManageStdOutWrapper();
864 bufWrapper.write(aBuf);
865 fRc = bufWrapper.sVmRunning == sVmName;
866
867 reporter.testDone();
868 return fRc;
869
870
871class tdAutostartOsDarwin(tdAutostartOs):
872 """
873 Autostart support methods for Darwin guests.
874 """
875
876 def __init__(self, oTestDriver, sTestBuildDir, fpApiVer, sGuestAdditionsIso):
877 _ = sTestBuildDir;
878 tdAutostartOs.__init__(self, oTestDriver, fpApiVer, sGuestAdditionsIso);
879 raise base.GenError('Testing the autostart functionality for Darwin is not implemented');
880
881
882class tdAutostartOsSolaris(tdAutostartOs):
883 """
884 Autostart support methods for Solaris guests.
885 """
886
887 def __init__(self, oTestDriver, sTestBuildDir, fpApiVer, sGuestAdditionsIso):
888 _ = sTestBuildDir;
889 tdAutostartOs.__init__(self, oTestDriver, fpApiVer, sGuestAdditionsIso);
890 raise base.GenError('Testing the autostart functionality for Solaris is not implemented');
891
892
893class tdAutostartOsWin(tdAutostartOs):
894 """
895 Autostart support methods for Windows guests.
896 """
897
898 def __init__(self, oTestDriver, asTestBuildDirs, fpApiVer, sGuestAdditionsIso):
899 tdAutostartOs.__init__(self, oTestDriver, fpApiVer, sGuestAdditionsIso);
900 self.sTestBuild = self._findFile('^VirtualBox-.*\\.(exe|msi)$', asTestBuildDirs);
901 if not self.sTestBuild:
902 raise base.GenError("VirtualBox install package not found");
903 return;
904
905 def waitVMisReady(self, oSession):
906 """
907 Waits the VM is ready after start or reboot.
908 """
909 # Give the VM a time to reboot
910 self.oTestDriver.sleep(30);
911
912 # Waiting the VM is ready.
913 # To do it, one will try to open the guest session and start the guest process in loop
914
915 cAttempt = 0;
916 oGuestSession = None;
917 while cAttempt < 10:
918 fRc, oGuestSession = self.createSession(oSession, 'Session for user: vbox',
919 'vbox', 'password', 10 * 1000, False);
920 if fRc:
921 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Start a guest process',
922 30 * 1000, 'C:\\Windows\\System32\\ipconfig.exe',
923 ['C:\\Windows\\System32\\ipconfig.exe',],
924 False, False);
925 if fRc:
926 break;
927
928 self.closeSession(oGuestSession, False);
929
930 self.oTestDriver.sleep(10);
931 cAttempt += 1;
932
933 return (fRc, oGuestSession);
934
935 def rebootVMAndCheckReady(self, oSession, oGuestSession):
936 """
937 Reboot the VM and wait the VM is ready.
938 """
939 reporter.testStart('Reboot VM and wait for readiness');
940 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Reboot the VM',
941 30 * 1000, 'C:\\Windows\\System32\\shutdown.exe',
942 ['C:\\Windows\\System32\\shutdown.exe', '/f',
943 '/r', '/t', '0'],
944 False, True);
945 if not fRc:
946 reporter.error('Calling the shutdown utility failed');
947 fRc = self.closeSession(oGuestSession, True) and fRc and True; # pychecker hack.
948 if fRc:
949 (fRc, oGuestSession) = self.waitVMisReady(oSession);
950 if not fRc:
951 reporter.error('VM is not ready after reboot');
952 reporter.testDone();
953 return (fRc, oGuestSession);
954
955 def powerDownVM(self, oGuestSession):
956 """
957 Power down the VM by calling guest process without wating
958 the VM is really powered off. Also, closes the guest session.
959 It helps the terminateBySession to stop the VM without aborting.
960 """
961
962 if oGuestSession is None:
963 return False;
964
965 reporter.testStart('Power down the VM');
966 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Power down the VM',
967 30 * 1000, 'C:\\Windows\\System32\\shutdown.exe',
968 ['C:\\Windows\\System32\\shutdown.exe', '/f',
969 '/s', '/t', '0'],
970 False, True);
971 if not fRc:
972 reporter.error('Calling the shutdown utility failed');
973 fRc = self.closeSession(oGuestSession, True) and fRc and True; # pychecker hack.
974 if not fRc:
975 reporter.error('Power down the VM failed');
976 reporter.testDone();
977 return fRc;
978
979 def installAdditions(self, oSession, oGuestSession, oVM):
980 """
981 Installs the Windows guest additions using the test execution service.
982 """
983 #
984 # Delete relevant log files.
985 #
986 # Note! On some guests the files in question still can be locked by the OS, so ignore
987 # deletion errors from the guest side (e.g. sharing violations) and just continue.
988 #
989 reporter.testStart('Install Guest Additions');
990 asLogFiles = [];
991 fHaveSetupApiDevLog = False;
992 if oVM.OSTypeId in ('WindowsNT4',):
993 sWinDir = 'C:/WinNT/';
994 else:
995 sWinDir = 'C:/Windows/';
996 asLogFiles = [sWinDir + 'setupapi.log', sWinDir + 'setupact.log', sWinDir + 'setuperr.log'];
997
998 # Apply The SetupAPI logging level so that we also get the (most verbose) setupapi.dev.log file.
999 ## @todo !!! HACK ALERT !!! Add the value directly into the testing source image. Later.
1000 (fHaveSetupApiDevLog, _, _, _) = \
1001 self.guestProcessExecute(oGuestSession, 'Enabling setupapi.dev.log',
1002 60 * 1000, 'c:\\Windows\\System32\\reg.exe',
1003 ['c:\\Windows\\System32\\reg.exe', 'add',
1004 '"HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Setup"',
1005 '/v', 'LogLevel', '/t', 'REG_DWORD', '/d', '0xFF'],
1006 False, True);
1007 for sFile in asLogFiles:
1008 try: oGuestSession.fsObjRemove(sFile);
1009 except: pass;
1010
1011 fRc = self.closeSession(oGuestSession, True); # pychecker hack.
1012
1013 try:
1014 oCurProgress = oSession.o.console.guest.updateGuestAdditions(self.sGuestAdditionsIso, None, None);
1015 except:
1016 reporter.maybeErrXcpt(True, 'Updating Guest Additions exception for sSrc="%s":'
1017 % (self.sGuestAdditionsIso,));
1018 fRc = False;
1019 else:
1020 if oCurProgress is not None:
1021 oWrapperProgress = vboxwrappers.ProgressWrapper(oCurProgress, self.oTestDriver.oVBoxMgr,
1022 self.oTestDriver, "installAdditions");
1023 oWrapperProgress.wait(cMsTimeout = 10 * 60 * 1000);
1024 if not oWrapperProgress.isSuccess():
1025 oWrapperProgress.logResult(fIgnoreErrors = False);
1026 fRc = False;
1027 else:
1028 fRc = reporter.error('No progress object returned');
1029
1030 if fRc:
1031 fRc, oGuestSession = self.createSession(oSession, 'Session for user: vbox',
1032 'vbox', 'password', 10 * 1000, True);
1033 if fRc is True:
1034 (fRc, oGuestSession) = self.rebootVMAndCheckReady(oSession, oGuestSession);
1035 if fRc is True:
1036 # Add the Windows Guest Additions installer files to the files we want to download
1037 # from the guest.
1038 sGuestAddsDir = 'C:/Program Files/Oracle/VirtualBox Guest Additions/';
1039 asLogFiles.append(sGuestAddsDir + 'install.log');
1040 # Note: There won't be a install_ui.log because of the silent installation.
1041 asLogFiles.append(sGuestAddsDir + 'install_drivers.log');
1042 asLogFiles.append('C:/Windows/setupapi.log');
1043
1044 # Note: setupapi.dev.log only is available since Windows 2000.
1045 if fHaveSetupApiDevLog:
1046 asLogFiles.append('C:/Windows/setupapi.dev.log');
1047
1048 #
1049 # Download log files.
1050 # Ignore errors as all files above might not be present (or in different locations)
1051 # on different Windows guests.
1052 #
1053 self.downloadFiles(oGuestSession, asLogFiles, fIgnoreErrors = True);
1054 else:
1055 reporter.error('Reboot after installing GuestAdditions failed');
1056 else:
1057 reporter.error('Create session for user vbox after GA updating failed');
1058 reporter.testDone();
1059 return (fRc, oGuestSession);
1060
1061 def installVirtualBox(self, oGuestSession):
1062 """
1063 Install VirtualBox in the guest.
1064 """
1065
1066 if self.sTestBuild is None:
1067 return False;
1068 reporter.testStart('Install Virtualbox into the guest VM');
1069 # Used windows image already contains the C:\Temp
1070 fRc = self.uploadFile(oGuestSession, self.sTestBuild,
1071 'C:\\Temp\\' + os.path.basename(self.sTestBuild));
1072 if not fRc:
1073 reporter.error('Upload the installing into guest VM failed');
1074 else:
1075 if self.sTestBuild.endswith('.msi'):
1076 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Installing VBox',
1077 240 * 1000, 'C:\\Windows\\System32\\msiexec.exe',
1078 ['msiexec', '/quiet', '/i',
1079 'C:\\Temp\\' + os.path.basename(self.sTestBuild)],
1080 False, True);
1081 if not fRc:
1082 reporter.error('Installing the VBox from msi installer failed');
1083 else:
1084 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Installing VBox',
1085 240 * 1000, 'C:\\Temp\\' + os.path.basename(self.sTestBuild),
1086 ['C:\\Temp\\' + os.path.basename(self.sTestBuild), '--silent'],
1087 False, True);
1088 if not fRc:
1089 reporter.error('Installing the VBox failed');
1090 reporter.testDone();
1091 return fRc;
1092
1093 def configureAutostart(self, oGuestSession, sDefaultPolicy = 'allow',
1094 asUserAllow = (), asUserDeny = ()):
1095 """
1096 Configures the autostart feature in the guest.
1097 """
1098 reporter.testStart('Configure autostart');
1099 # Create autostart database directory writeable for everyone
1100 (fRc, _, _, _) = \
1101 self.guestProcessExecute(oGuestSession, 'Setting the autostart environment variable',
1102 30 * 1000, 'C:\\Windows\\System32\\reg.exe',
1103 ['reg', 'add',
1104 'HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment',
1105 '/v', 'VBOXAUTOSTART_CONFIG', '/d',
1106 'C:\\ProgramData\\autostart.cfg', '/f'],
1107 False, True);
1108 if not fRc:
1109 reporter.error('Setting the autostart environment variable failed');
1110
1111 if fRc:
1112 sVBoxCfg = self._createAutostartCfg(sDefaultPolicy, asUserAllow, asUserDeny);
1113 fRc = self.uploadString(oGuestSession, sVBoxCfg, 'C:\\ProgramData\\autostart.cfg');
1114 if not fRc:
1115 reporter.error('Upload the autostart.cfg failed');
1116 reporter.testDone();
1117 return fRc;
1118
1119 def createTestVM(self, oSession, oGuestSession, sUser, sVmName):
1120 """
1121 Create a test VM in the guest and enable autostart.
1122 """
1123 _ = oGuestSession;
1124
1125 reporter.testStart('Create test VM for user %s' % sUser);
1126
1127 fRc, oGuestSession = self.createSession(oSession, 'Session for user: %s' % (sUser,),
1128 sUser, 'password', 10 * 1000, True);
1129 if not fRc:
1130 reporter.error('Create session for user %s failed' % sUser);
1131 else:
1132 (fRc, _, _, _) = \
1133 self.guestProcessExecute(oGuestSession, 'Create VM ' + sVmName,
1134 30 * 1000, 'C:\\Program Files\\Oracle\\VirtualBox\\VBoxManage.exe',
1135 ['C:\\Program Files\\Oracle\\VirtualBox\\VBoxManage.exe', 'createvm',
1136 '--name', sVmName, '--register'], False, True);
1137 if not fRc:
1138 reporter.error('Create VM %s for user %s failed' % (sVmName, sUser));
1139 else:
1140 (fRc, _, _, _) = \
1141 self.guestProcessExecute(oGuestSession, 'Enabling autostart for test VM',
1142 30 * 1000, 'C:\\Program Files\\Oracle\\VirtualBox\\VBoxManage.exe',
1143 ['C:\\Program Files\\Oracle\\VirtualBox\\VBoxManage.exe',
1144 'modifyvm', sVmName, '--autostart-enabled', 'on'], False, True);
1145 if not fRc:
1146 reporter.error('Enabling autostart for VM %s for user %s failed' % (sVmName, sUser));
1147 if fRc:
1148 fRc = self.uploadString(oGuestSession, 'password', 'C:\\ProgramData\\password.cfg');
1149 if not fRc:
1150 reporter.error('Upload the password.cfg failed');
1151 if fRc:
1152 (fRc, _, _, _) = \
1153 self.guestProcessExecute(oGuestSession, 'Install autostart service for the user',
1154 30 * 1000, 'C:\\Program Files\\Oracle\\VirtualBox\\VBoxAutostartSvc.exe',
1155 ['C:\\Program Files\\Oracle\\VirtualBox\\VBoxAutostartSvc.exe',
1156 'install', '--user=' + sUser,
1157 '--password-file=C:\\ProgramData\\password.cfg'],
1158 False, True);
1159 if not fRc:
1160 reporter.error('Install autostart service for user %s failed' % sUser);
1161 fRc1 = self.closeSession(oGuestSession, True);
1162 if not fRc1:
1163 reporter.error('Closing session for user %s failed' % sUser);
1164 fRc = fRc1 and fRc and True; # pychecker hack.
1165 reporter.testDone();
1166 return fRc;
1167
1168 def checkForRunningVM(self, oSession, oGuestSession, sUser, sVmName):
1169 """
1170 Check for VM running in the guest after autostart.
1171 """
1172
1173 _ = oGuestSession;
1174
1175 reporter.testStart('Check the VM %s is running for user %s' % (sVmName, sUser));
1176
1177 fRc, oGuestSession = self.createSession(oSession, 'Session for user: %s' % (sUser,),
1178 sUser, 'password', 10 * 1000, True);
1179 if not fRc:
1180 reporter.error('Create session for user %s failed' % sUser);
1181 else:
1182
1183 #---- report tasklist for debug purpose -----
1184 (fRc, _, _, aBuf) = self.guestProcessExecute(oGuestSession, 'Check for running VM',
1185 60 * 1000, 'C:\\Windows\\System32\\tasklist.exe',
1186 ['C:\\Windows\\System32\\tasklist.exe', '/m',
1187 'vboxheadless*', '/nh'], True, True);
1188 try:
1189 sTaskList = str(aBuf);
1190 reporter.log("Guest tasks for user %s: %s" % (sUser, sTaskList));
1191 except:
1192 pass;
1193 #---- end report tasklist for debug purpose -----
1194
1195 (fRc, _, _, aBuf) = self.guestProcessExecute(oGuestSession, 'Check for running VM',
1196 60 * 1000, 'C:\\Program Files\\Oracle\\VirtualBox\\VBoxManage.exe',
1197 ['C:\\Program Files\\Oracle\\VirtualBox\\VBoxManage.exe',
1198 'list', 'runningvms'], True, True);
1199 if not fRc:
1200 reporter.error('Checking the VM %s is running for user %s failed' % (sVmName, sUser));
1201 else:
1202
1203 bufWrapper = VBoxManageStdOutWrapper();
1204 bufWrapper.write(aBuf);
1205 fRc = bufWrapper.sVmRunning == sVmName;
1206
1207 fRc1 = self.closeSession(oGuestSession, True);
1208 if not fRc1:
1209 reporter.error('Closing session for user %s failed' % sUser);
1210 fRc = fRc1 and fRc and True; # pychecker hack.
1211 reporter.testDone();
1212 return fRc;
1213
1214 def createUser(self, oGuestSession, sUser):
1215 """
1216 Create a new user with the given name
1217 """
1218 reporter.testStart('Create user %s' % sUser);
1219 # Create user
1220 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Creating user %s to run a VM' % sUser,
1221 30 * 1000, 'C:\\Windows\\System32\\net.exe',
1222 ['net', 'user', sUser, 'password', '/add' ], False, True);
1223 if not fRc:
1224 reporter.error('Creating user %s to run a VM failed' % sUser);
1225 # Add the user to Administrators group
1226 else:
1227 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Adding the user %s to Administrators group' % sUser,
1228 30 * 1000, 'C:\\Windows\\System32\\net.exe',
1229 ['net', 'localgroup', 'Administrators', sUser, '/add' ], False, True);
1230 if not fRc:
1231 reporter.error('Adding the user %s to Administrators group failed' % sUser);
1232
1233 #Allow the user to logon as service
1234 if fRc:
1235 sSecPolicyEditor = """
1236' SetLogonAsAServiceRight.vbs
1237' Sample VBScript to set or grant Logon As A Service Right.
1238' Author: http://www.morgantechspace.com/
1239' ------------------------------------------------------'
1240
1241Dim strUserName,ConfigFileName,OrgStr,RepStr,inputFile,strInputFile,outputFile,obj
1242strUserName = "%s"
1243Dim oShell
1244Set oShell = CreateObject ("WScript.Shell")
1245oShell.Run "secedit /export /cfg config.inf", 0, true
1246oShell.Run "secedit /import /cfg config.inf /db database.sdb", 0, true
1247
1248ConfigFileName = "config.inf"
1249OrgStr = "SeServiceLogonRight ="
1250RepStr = "SeServiceLogonRight = " & strUserName & ","
1251Set inputFile = CreateObject("Scripting.FileSystemObject").OpenTextFile("config.inf", 1,1,-1)
1252strInputFile = inputFile.ReadAll
1253inputFile.Close
1254Set inputFile = Nothing
1255
1256Set outputFile = CreateObject("Scripting.FileSystemObject").OpenTextFile("config.inf",2,1,-1)
1257outputFile.Write (Replace(strInputFile,OrgStr,RepStr))
1258outputFile.Close
1259Set outputFile = Nothing
1260
1261oShell.Run "secedit /configure /db database.sdb /cfg config.inf",0,true
1262set oShell= Nothing
1263
1264Set obj = CreateObject("Scripting.FileSystemObject")
1265obj.DeleteFile("config.inf")
1266obj.DeleteFile("database.sdb")
1267
1268WScript.Echo "Logon As A Service Right granted to user '"& strUserName &"'"
1269 """ % sUser;
1270 fRc = self.uploadString(oGuestSession, sSecPolicyEditor, 'C:\\Temp\\adjustsec.vbs');
1271 if not fRc:
1272 reporter.error('Upload the adjustsec.vbs failed');
1273 if fRc:
1274 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession,
1275 'Setting the "Logon as service" policy to the user %s' % sUser,
1276 30 * 1000, 'C:\\Windows\\System32\\cscript.exe',
1277 ['cscript.exe', 'C:\\Temp\\adjustsec.vbs', '//Nologo'], False, True);
1278 if not fRc:
1279 reporter.error('Setting the "Logon as service" policy to the user %s failed' % sUser);
1280 try:
1281 oGuestSession.fsObjRemove('C:\\Temp\\adjustsec.vbs');
1282 except:
1283 fRc = reporter.errorXcpt('Removing policy script failed');
1284 reporter.testDone();
1285 return fRc;
1286
1287
1288class tdAutostart(vbox.TestDriver): # pylint: disable=too-many-instance-attributes
1289 """
1290 Autostart testcase.
1291 """
1292
1293 ksOsLinux = 'tst-linux'
1294 ksOsWindows = 'tst-win'
1295 ksOsDarwin = 'tst-darwin'
1296 ksOsSolaris = 'tst-solaris'
1297 ksOsFreeBSD = 'tst-freebsd'
1298
1299 def __init__(self):
1300 vbox.TestDriver.__init__(self);
1301 self.asRsrcs = None;
1302 self.asTestVMsDef = [self.ksOsWindows, self.ksOsLinux]; #[self.ksOsLinux, self.ksOsWindows];
1303 self.asTestVMs = self.asTestVMsDef;
1304 self.asSkipVMs = [];
1305 self.asTestBuildDirs = None; #'D:/AlexD/TestBox/TestAdditionalFiles';
1306 self.sGuestAdditionsIso = None; #'D:/AlexD/TestBox/TestAdditionalFiles/VBoxGuestAdditions_6.1.2.iso';
1307
1308 #
1309 # Overridden methods.
1310 #
1311 def showUsage(self):
1312 rc = vbox.TestDriver.showUsage(self);
1313 reporter.log('');
1314 reporter.log('tdAutostart Options:');
1315 reporter.log(' --test-build-dirs <path1[,path2[,...]]>');
1316 reporter.log(' The list of directories with VirtualBox distros. The option is mandatory');
1317 reporter.log(' without any default value. The test raises an exception if the');
1318 reporter.log(' option is not specified. At least, one directory should be pointed.');
1319 reporter.log(' --guest-additions-iso <path/to/iso>');
1320 reporter.log(' The path to fresh VirtualBox Guest Additions iso. The option is');
1321 reporter.log(' mandatory without any default value. The test raises an exception');
1322 reporter.log(' if the option is not specified.');
1323 reporter.log(' --test-vms <vm1[:vm2[:...]]>');
1324 reporter.log(' Test the specified VMs in the given order. Use this to change');
1325 reporter.log(' the execution order or limit the choice of VMs');
1326 reporter.log(' Default: %s (all)' % (':'.join(self.asTestVMsDef)));
1327 reporter.log(' --skip-vms <vm1[:vm2[:...]]>');
1328 reporter.log(' Skip the specified VMs when testing.');
1329 return rc;
1330
1331 def parseOption(self, asArgs, iArg): # pylint: disable=too-many-branches,too-many-statements
1332 if asArgs[iArg] == '--test-build-dirs':
1333 iArg += 1;
1334 if iArg >= len(asArgs): raise base.InvalidOption('The "--test-build-dirs" takes a paths argument');
1335 self.asTestBuildDirs = asArgs[iArg].split(',');
1336 elif asArgs[iArg] == '--guest-additions-iso':
1337 iArg += 1;
1338 if iArg >= len(asArgs): raise base.InvalidOption('The "--guest-additions-iso" takes a path or url to iso argument');
1339 self.sGuestAdditionsIso = asArgs[iArg];
1340 elif asArgs[iArg] == '--test-vms':
1341 iArg += 1;
1342 if iArg >= len(asArgs): raise base.InvalidOption('The "--test-vms" takes colon separated list');
1343 self.asTestVMs = asArgs[iArg].split(':');
1344 for s in self.asTestVMs:
1345 if s not in self.asTestVMsDef:
1346 raise base.InvalidOption('The "--test-vms" value "%s" is not valid; valid values are: %s' \
1347 % (s, ' '.join(self.asTestVMsDef)));
1348 elif asArgs[iArg] == '--skip-vms':
1349 iArg += 1;
1350 if iArg >= len(asArgs): raise base.InvalidOption('The "--skip-vms" takes colon separated list');
1351 self.asSkipVMs = asArgs[iArg].split(':');
1352 for s in self.asSkipVMs:
1353 if s not in self.asTestVMsDef:
1354 reporter.log('warning: The "--test-vms" value "%s" does not specify any of our test VMs.' % (s));
1355 else:
1356 return vbox.TestDriver.parseOption(self, asArgs, iArg);
1357 return iArg + 1;
1358
1359 def completeOptions(self):
1360 # Remove skipped VMs from the test list.
1361 if self.asTestBuildDirs is None:
1362 raise base.InvalidOption('--test-build-dirs is not specified')
1363 if self.sGuestAdditionsIso is None:
1364 raise base.InvalidOption('--guest-additions-iso is not specified')
1365
1366 for sVM in self.asSkipVMs:
1367 try: self.asTestVMs.remove(sVM);
1368 except: pass;
1369
1370 return vbox.TestDriver.completeOptions(self);
1371
1372 def getResourceSet(self):
1373 # Construct the resource list the first time it's queried.
1374 if self.asRsrcs is None:
1375 self.asRsrcs = [];
1376 if self.ksOsLinux in self.asTestVMs:
1377 self.asRsrcs.append('6.0/ub1804piglit/ub1804piglit.vdi');
1378 if self.ksOsWindows in self.asTestVMs:
1379 self.asRsrcs.append('6.0/windows7piglit/windows7piglit.vdi');
1380 #disabled
1381 #if self.ksOsSolaris in self.asTestVMs:
1382 # self.asRsrcs.append('4.2/autostart/tst-solaris.vdi');
1383
1384 return self.asRsrcs;
1385
1386 def actionConfig(self):
1387
1388 # Make sure vboxapi has been imported so we can use the constants.
1389 if not self.importVBoxApi():
1390 return False;
1391
1392 # Download VBoxGuestAdditions.iso before work
1393 sDestinationIso = os.path.join(self.sScratchPath, 'VBoxGuestAdditions.iso');
1394 utils.noxcptDeleteFile(sDestinationIso);
1395 if not downloadFile(self.sGuestAdditionsIso, sDestinationIso, '', reporter.log, reporter.error):
1396 raise base.GenError("Could not download VBoxGuestAdditions.iso");
1397 self.sGuestAdditionsIso = sDestinationIso;
1398
1399 #
1400 # Configure the VMs we're going to use.
1401 #
1402
1403 fRc = True;
1404
1405 # Linux VMs
1406 if self.ksOsLinux in self.asTestVMs:
1407 # ub1804piglit is created with 2 CPUs.
1408 oVM = self.createTestVM(self.ksOsLinux, 1, '6.0/ub1804piglit/ub1804piglit.vdi', sKind = 'Ubuntu_64', \
1409 fIoApic = True, eNic0AttachType = vboxcon.NetworkAttachmentType_NAT, \
1410 eNic0Type = vboxcon.NetworkAdapterType_Am79C973, cMbRam = 4096, \
1411 cCpus = 2, sDvdImage = self.sGuestAdditionsIso);
1412 if oVM is None:
1413 return False;
1414 # Windows VMs
1415 if self.ksOsWindows in self.asTestVMs:
1416 # windows7piglit is created with PAE enabled and 2 CPUs.
1417 oVM = self.createTestVM(self.ksOsWindows, 1, '6.0/windows7piglit/windows7piglit.vdi', sKind = 'Windows7_64', \
1418 fIoApic = True, eNic0AttachType = vboxcon.NetworkAttachmentType_NAT, \
1419 sHddControllerType = "SATA Controller", cMbRam = 4096, fPae = True, cCpus = 2, \
1420 sDvdImage = self.sGuestAdditionsIso);
1421 if oVM is None:
1422 return False;
1423
1424 # additional options used during the windows7piglit creation
1425 oSession = self.openSession(oVM);
1426 if oSession is not None:
1427 fRc = fRc and oSession.setVRamSize(256);
1428 fRc = fRc and oSession.setVideoControllerType(vboxcon.GraphicsControllerType_VBoxSVGA)
1429 fRc = fRc and oSession.setAccelerate3DEnabled(True);
1430 fRc = fRc and oSession.enableUsbOhci(True);
1431 fRc = fRc and oSession.enableUsbHid(True);
1432 fRc = fRc and oSession.saveSettings();
1433 fRc = oSession.close() and fRc and True; # pychecker hack.
1434 oSession = None;
1435 else:
1436 fRc = False;
1437
1438 # disabled
1439 # Solaris VMs
1440 #if self.ksOsSolaris in self.asTestVMs:
1441 # oVM = self.createTestVM(self.ksOsSolaris, 1, '4.2/autostart/tst-solaris.vdi', sKind = 'Solaris_64', \
1442 # fIoApic = True, eNic0AttachType = vboxcon.NetworkAttachmentType_NAT, \
1443 # sHddControllerType = "SATA Controller");
1444 # if oVM is None:
1445 # return False;
1446
1447 return fRc;
1448
1449 def actionExecute(self):
1450 """
1451 Execute the testcase.
1452 """
1453 fRc = self.testAutostart();
1454 return fRc;
1455
1456 #
1457 # Test execution helpers.
1458 #
1459 def testAutostartRunProgs(self, oSession, sVmName, oVM):
1460 """
1461 Test VirtualBoxs autostart feature in a VM.
1462 """
1463 reporter.testStart('Autostart ' + sVmName);
1464
1465 oGuestOsHlp = None # type: tdAutostartOs
1466 if sVmName == self.ksOsLinux:
1467 oGuestOsHlp = tdAutostartOsLinux(self, self.asTestBuildDirs, self.fpApiVer, # pylint: disable=redefined-variable-type
1468 self.sGuestAdditionsIso);
1469 elif sVmName == self.ksOsSolaris:
1470 oGuestOsHlp = tdAutostartOsSolaris(self, self.asTestBuildDirs, self.fpApiVer, # pylint: disable=redefined-variable-type
1471 self.sGuestAdditionsIso);
1472 elif sVmName == self.ksOsDarwin:
1473 oGuestOsHlp = tdAutostartOsDarwin(self, self.asTestBuildDirs, self.fpApiVer, # pylint: disable=redefined-variable-type
1474 self.sGuestAdditionsIso);
1475 elif sVmName == self.ksOsWindows:
1476 oGuestOsHlp = tdAutostartOsWin(self, self.asTestBuildDirs, self.fpApiVer, # pylint: disable=redefined-variable-type
1477 self.sGuestAdditionsIso);
1478
1479 sTestUserAllow = 'test1';
1480 sTestUserDeny = 'test2';
1481 sTestVmName = 'TestVM';
1482
1483 if oGuestOsHlp is not None:
1484 #wait the VM is ready after starting
1485 (fRc, oGuestSession) = oGuestOsHlp.waitVMisReady(oSession);
1486 #install fresh guest additions
1487 if fRc:
1488 (fRc, oGuestSession) = oGuestOsHlp.installAdditions(oSession, oGuestSession, oVM);
1489 # Create two new users
1490 fRc = fRc and oGuestOsHlp.createUser(oGuestSession, sTestUserAllow);
1491 fRc = fRc and oGuestOsHlp.createUser(oGuestSession, sTestUserDeny);
1492 if fRc is True:
1493 # Install VBox first
1494 fRc = oGuestOsHlp.installVirtualBox(oGuestSession);
1495 if fRc is True:
1496 fRc = oGuestOsHlp.configureAutostart(oGuestSession, 'allow', (sTestUserAllow,), (sTestUserDeny,));
1497 if fRc is True:
1498 # Create a VM with autostart enabled in the guest for both users
1499 fRc = oGuestOsHlp.createTestVM(oSession, oGuestSession, sTestUserAllow, sTestVmName);
1500 fRc = fRc and oGuestOsHlp.createTestVM(oSession, oGuestSession, sTestUserDeny, sTestVmName);
1501 if fRc is True:
1502 # Reboot the guest
1503 (fRc, oGuestSession) = oGuestOsHlp.rebootVMAndCheckReady(oSession, oGuestSession);
1504 if fRc is True:
1505 # Fudge factor - Allow the guest VMs to finish starting up.
1506 self.sleep(60);
1507 fRc = oGuestOsHlp.checkForRunningVM(oSession, oGuestSession, sTestUserAllow, sTestVmName);
1508 if fRc is True:
1509 fRc = oGuestOsHlp.checkForRunningVM(oSession, oGuestSession, sTestUserDeny, sTestVmName);
1510 if fRc is True:
1511 reporter.error('Test VM is running inside the guest for denied user');
1512 fRc = not fRc;
1513 else:
1514 reporter.error('Test VM is not running inside the guest for allowed user');
1515 else:
1516 reporter.error('Rebooting the guest failed');
1517 else:
1518 reporter.error('Creating test VM failed');
1519 else:
1520 reporter.error('Configuring autostart in the guest failed');
1521 else:
1522 reporter.error('Installing VirtualBox in the guest failed');
1523 else:
1524 reporter.error('Creating test users failed');
1525
1526 if oGuestSession is not None:
1527 try: oGuestOsHlp.powerDownVM(oGuestSession);
1528 except: pass;
1529 else:
1530 reporter.error('Guest OS helper not created for VM %s' % (sVmName));
1531 fRc = False;
1532
1533 reporter.testDone();
1534 return fRc;
1535
1536 def testAutostartOneCfg(self, sVmName):
1537 """
1538 Runs the specified VM thru test #1.
1539
1540 Returns a success indicator on the general test execution. This is not
1541 the actual test result.
1542 """
1543 oVM = self.getVmByName(sVmName);
1544
1545 # Reconfigure the VM
1546 fRc = True;
1547 oSession = self.openSession(oVM);
1548 if oSession is not None:
1549 fRc = fRc and oSession.enableVirtEx(True);
1550 fRc = fRc and oSession.enableNestedPaging(True);
1551 fRc = fRc and oSession.enableNestedHwVirt(True);
1552 # disable 3D until the error is fixed.
1553 fRc = fRc and oSession.setAccelerate3DEnabled(False);
1554 fRc = fRc and oSession.saveSettings();
1555 fRc = oSession.close() and fRc and True; # pychecker hack.
1556 oSession = None;
1557 else:
1558 fRc = False;
1559
1560 # Start up.
1561 if fRc is True:
1562 self.logVmInfo(oVM);
1563 oSession = self.startVmByName(sVmName);
1564 if oSession is not None:
1565 fRc = self.testAutostartRunProgs(oSession, sVmName, oVM);
1566 try: self.terminateVmBySession(oSession);
1567 except: pass;
1568 else:
1569 fRc = False;
1570 return fRc;
1571
1572 def testAutostartForOneVM(self, sVmName):
1573 """
1574 Runs one VM thru the various configurations.
1575 """
1576 reporter.testStart(sVmName);
1577 fRc = True;
1578 self.testAutostartOneCfg(sVmName);
1579 reporter.testDone();
1580 return fRc;
1581
1582 def testAutostart(self):
1583 """
1584 Executes autostart test.
1585 """
1586
1587 # Loop thru the test VMs.
1588 for sVM in self.asTestVMs:
1589 # run test on the VM.
1590 if not self.testAutostartForOneVM(sVM):
1591 fRc = False;
1592 else:
1593 fRc = True;
1594
1595 return fRc;
1596
1597
1598
1599if __name__ == '__main__':
1600 sys.exit(tdAutostart().main(sys.argv));
1601
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