VirtualBox

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

Last change on this file since 85469 was 85469, checked in by vboxsync, 4 years ago

Main: bugref:9341: Fixed pylint issue

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