VirtualBox

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

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

Main: bugref:9341: Added powering down the VM by calling the guest process in the testcase

  • Property svn:eol-style set to LF
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 70.5 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 84590 2020-05-28 13:13:09Z 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 fRc = True; # Be optimistic.
283
284 reporter.testStart(sTestName);
285
286 reporter.log2('Using session user=%s, name=%s, timeout=%d'
287 % (oGuestSession.user, oGuestSession.name, oGuestSession.timeout,));
288
289 #
290 # Start the process:
291 #
292 reporter.log2('Executing sCmd=%s, timeoutMS=%d, asArgs=%s'
293 % (sExecName, cMsTimeout, asArgs, ));
294 fTaskFlags = [];
295 if fGetStdOut:
296 fTaskFlags = [vboxcon.ProcessCreateFlag_WaitForStdOut,
297 vboxcon.ProcessCreateFlag_WaitForStdErr];
298 try:
299 oProcess = oGuestSession.processCreate(sExecName,
300 asArgs if self.fpApiVer >= 5.0 else asArgs[1:],
301 [], fTaskFlags, cMsTimeout);
302 except:
303 reporter.maybeErrXcpt(fIsError, 'asArgs=%s' % (asArgs,));
304 return (False, 0, 0, None);
305 if oProcess is None:
306 return (reporter.error('oProcess is None! (%s)' % (asArgs,)), 0, 0, None);
307
308 #time.sleep(5); # try this if you want to see races here.
309
310 # Wait for the process to start properly:
311 reporter.log2('Process start requested, waiting for start (%dms) ...' % (cMsTimeout,));
312 iPid = -1;
313 aeWaitFor = [ vboxcon.ProcessWaitForFlag_Start, ];
314 aBuf = None;
315 try:
316 eWaitResult = oProcess.waitForArray(aeWaitFor, cMsTimeout);
317 except:
318 reporter.maybeErrXcpt(fIsError, 'waitforArray failed for asArgs=%s' % (asArgs,));
319 fRc = False;
320 else:
321 try:
322 eStatus = oProcess.status;
323 iPid = oProcess.PID;
324 except:
325 fRc = reporter.errorXcpt('asArgs=%s' % (asArgs,));
326 else:
327 reporter.log2('Wait result returned: %d, current process status is: %d' % (eWaitResult, eStatus,));
328
329 #
330 # Wait for the process to run to completion if necessary.
331 #
332 # Note! The above eWaitResult return value can be ignored as it will
333 # (mostly) reflect the process status anyway.
334 #
335 if eStatus == vboxcon.ProcessStatus_Started:
336
337 # What to wait for:
338 aeWaitFor = [ vboxcon.ProcessWaitForFlag_Terminate,
339 vboxcon.ProcessWaitForFlag_StdOut,
340 vboxcon.ProcessWaitForFlag_StdErr];
341
342 reporter.log2('Process (PID %d) started, waiting for termination (%dms), aeWaitFor=%s ...'
343 % (iPid, cMsTimeout, aeWaitFor));
344 acbFdOut = [0,0,0];
345 while True:
346 try:
347 eWaitResult = oProcess.waitForArray(aeWaitFor, cMsTimeout);
348 except KeyboardInterrupt: # Not sure how helpful this is, but whatever.
349 reporter.error('Process (PID %d) execution interrupted' % (iPid,));
350 try: oProcess.close();
351 except: pass;
352 break;
353 except:
354 fRc = reporter.errorXcpt('asArgs=%s' % (asArgs,));
355 break;
356 reporter.log2('Wait returned: %d' % (eWaitResult,));
357
358 # Process output:
359 for eFdResult, iFd, sFdNm in [ (vboxcon.ProcessWaitResult_StdOut, 1, 'stdout'),
360 (vboxcon.ProcessWaitResult_StdErr, 2, 'stderr'), ]:
361 if eWaitResult in (eFdResult, vboxcon.ProcessWaitResult_WaitFlagNotSupported):
362 reporter.log2('Reading %s ...' % (sFdNm,));
363 try:
364 abBuf = oProcess.Read(1, 64 * 1024, cMsTimeout);
365 except KeyboardInterrupt: # Not sure how helpful this is, but whatever.
366 reporter.error('Process (PID %d) execution interrupted' % (iPid,));
367 try: oProcess.close();
368 except: pass;
369 except:
370 pass; ## @todo test for timeouts and fail on anything else!
371 else:
372 if abBuf:
373 reporter.log2('Process (PID %d) got %d bytes of %s data' % (iPid, len(abBuf), sFdNm,));
374 acbFdOut[iFd] += len(abBuf);
375 ## @todo Figure out how to uniform + append!
376 if aBuf:
377 aBuf += str(abBuf);
378 else:
379 aBuf = str(abBuf);
380
381 ## Process input (todo):
382 #if eWaitResult in (vboxcon.ProcessWaitResult_StdIn, vboxcon.ProcessWaitResult_WaitFlagNotSupported):
383 # reporter.log2('Process (PID %d) needs stdin data' % (iPid,));
384
385 # Termination or error?
386 if eWaitResult in (vboxcon.ProcessWaitResult_Terminate,
387 vboxcon.ProcessWaitResult_Error,
388 vboxcon.ProcessWaitResult_Timeout,):
389 try: eStatus = oProcess.status;
390 except: fRc = reporter.errorXcpt('asArgs=%s' % (asArgs,));
391 reporter.log2('Process (PID %d) reported terminate/error/timeout: %d, status: %d'
392 % (iPid, eWaitResult, eStatus,));
393 break;
394
395 # End of the wait loop.
396 _, cbStdOut, cbStdErr = acbFdOut;
397
398 try: eStatus = oProcess.status;
399 except: fRc = reporter.errorXcpt('asArgs=%s' % (asArgs,));
400 reporter.log2('Final process status (PID %d) is: %d' % (iPid, eStatus));
401 reporter.log2('Process (PID %d) %d stdout, %d stderr' % (iPid, cbStdOut, cbStdErr));
402
403 #
404 # Get the final status and exit code of the process.
405 #
406 try:
407 uExitStatus = oProcess.status;
408 iExitCode = oProcess.exitCode;
409 except:
410 fRc = reporter.errorXcpt('asArgs=%s' % (asArgs,));
411 reporter.log2('Process (PID %d) has exit code: %d; status: %d ' % (iPid, iExitCode, uExitStatus));
412 reporter.testDone();
413
414 return (fRc, uExitStatus, iExitCode, aBuf);
415
416 def uploadString(self, oSession, sSrcString, sDst):
417 """
418 Upload the string into guest.
419 """
420
421 fRc, oGuestSession = self.createSession(oSession, 'vbox session for installing guest additions',
422 'vbox', 'password', cMsTimeout = 10 * 1000, fIsError = True);
423 if fRc is not True:
424 return reporter.errorXcpt('Upload string failed: Could not create session for vbox');
425
426 try:
427 oFile = oGuestSession.fileOpenEx(sDst, vboxcon.FileAccessMode_ReadWrite, vboxcon.FileOpenAction_CreateOrReplace,
428 vboxcon.FileSharingMode_All, 0, []);
429 except:
430 fRc = reporter.errorXcpt('Upload string failed. Could not create and open the file %s' % sDst);
431 else:
432 try:
433 oFile.write(bytearray(sSrcString), 60*1000);
434 except:
435 fRc = reporter.errorXcpt('Upload string failed. Could not write the string into the file %s' % sDst);
436 try:
437 oFile.close();
438 except:
439 fRc = reporter.errorXcpt('Upload string failed. Could not close the file %s' % sDst);
440
441 self.closeSession(oGuestSession);
442 return fRc;
443
444 def uploadFile(self, oSession, sSrc, sDst):
445 """
446 Upload the string into guest.
447 """
448
449 fRc, oGuestSession = self.createSession(oSession, 'vbox session for upload the file',
450 'vbox', 'password', cMsTimeout = 10 * 1000, fIsError = True);
451 if fRc is not True:
452 return reporter.errorXcpt('Upload file failed: Could not create session for vbox');
453
454 try:
455 if self.fpApiVer >= 5.0:
456 oCurProgress = oGuestSession.fileCopyToGuest(sSrc, sDst, [0]);
457 else:
458 oCurProgress = oGuestSession.copyTo(sSrc, sDst, [0]);
459 except:
460 reporter.maybeErrXcpt(True, 'Upload file exception for sSrc="%s":'
461 % (self.sGuestAdditionsIso,));
462 fRc = False;
463 else:
464 if oCurProgress is not None:
465 oWrapperProgress = vboxwrappers.ProgressWrapper(oCurProgress, self.oTestDriver.oVBoxMgr,
466 self.oTestDriver, "uploadFile");
467 oWrapperProgress.wait();
468 if not oWrapperProgress.isSuccess():
469 oWrapperProgress.logResult(fIgnoreErrors = False);
470 fRc = False;
471 else:
472 fRc = reporter.error('No progress object returned');
473
474 self.closeSession(oGuestSession);
475 return fRc;
476
477 def downloadFile(self, oSession, sSrc, sDst, fIgnoreErrors = False):
478 """
479 Upload the string into guest.
480 """
481
482 fRc, oGuestSession = self.createSession(oSession, 'vbox session for download the file',
483 'vbox', 'password', cMsTimeout = 10 * 1000, fIsError = True);
484 if fRc is not True:
485 if not fIgnoreErrors:
486 return reporter.errorXcpt('Download file failed: Could not create session for vbox');
487 reporter.log('warning: Download file failed: Could not create session for vbox');
488 return False;
489
490 try:
491 if self.fpApiVer >= 5.0:
492 oCurProgress = oGuestSession.fileCopyFromGuest(sSrc, sDst, [0]);
493 else:
494 oCurProgress = oGuestSession.copyFrom(sSrc, sDst, [0]);
495 except:
496 if not fIgnoreErrors:
497 reporter.errorXcpt('Download file exception for sSrc="%s":' % (self.sGuestAdditionsIso,));
498 else:
499 reporter.log('warning: Download file exception for sSrc="%s":' % (self.sGuestAdditionsIso,));
500 fRc = False;
501 else:
502 if oCurProgress is not None:
503 oWrapperProgress = vboxwrappers.ProgressWrapper(oCurProgress, self.oTestDriver.oVBoxMgr,
504 self.oTestDriver, "downloadFile");
505 oWrapperProgress.wait();
506 if not oWrapperProgress.isSuccess():
507 oWrapperProgress.logResult(fIgnoreErrors);
508 fRc = False;
509 else:
510 if not fIgnoreErrors:
511 reporter.error('No progress object returned');
512 else:
513 reporter.log('warning: No progress object returned');
514 fRc = False;
515
516 self.closeSession(oGuestSession);
517 return fRc;
518
519 def downloadFiles(self, oSession, asFiles, fIgnoreErrors = False):
520 """
521 Convenience function to get files from the guest and stores it
522 into the scratch directory for later (manual) review.
523
524 Returns True on success.
525
526 Returns False on failure, logged.
527 """
528 fRc = True;
529 for sGstFile in asFiles:
530 sTmpFile = os.path.join(self.oTestDriver.sScratchPath, 'tmp-' + os.path.basename(sGstFile));
531 reporter.log2('Downloading file "%s" to "%s" ...' % (sGstFile, sTmpFile));
532 # First try to remove (unlink) an existing temporary file, as we don't truncate the file.
533 try: os.unlink(sTmpFile);
534 except: pass;
535 ## @todo Check for already existing files on the host and create a new
536 # name for the current file to download.
537 fRc = self.downloadFile(oSession, sGstFile, sTmpFile, fIgnoreErrors);
538 if fRc:
539 reporter.addLogFile(sTmpFile, 'misc/other', 'guest - ' + sGstFile);
540 else:
541 if fIgnoreErrors is not True:
542 reporter.error('error downloading file "%s" to "%s"' % (sGstFile, sTmpFile));
543 return fRc;
544 reporter.log('warning: file "%s" was not downloaded, ignoring.' % (sGstFile,));
545 return True;
546
547
548class tdAutostartOsLinux(tdAutostartOs):
549 """
550 Autostart support methods for Linux guests.
551 """
552
553 def __init__(self, oTestDriver, asTestBuildDirs, fpApiVer, sGuestAdditionsIso):
554 tdAutostartOs.__init__(self, oTestDriver, fpApiVer, sGuestAdditionsIso);
555 self.sTestBuild = self._findFile('^VirtualBox-.*\\.run$', asTestBuildDirs);
556 if not self.sTestBuild:
557 raise base.GenError("VirtualBox install package not found");
558
559 def waitVMisReady(self, oSession):
560 """
561 Waits the VM is ready after start or reboot.
562 """
563 # Give the VM a time to reboot
564 self.oTestDriver.sleep(30);
565
566 # Waiting the VM is ready.
567 # To do it, one will try to open the guest session and start the guest process in loop
568
569 cAttempt = 0;
570
571 while cAttempt < 30:
572 fRc, oGuestSession = self.createSession(oSession, 'Session for user: vbox',
573 'vbox', 'password', 10 * 1000, False);
574 if fRc:
575 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Start a guest process',
576 30 * 1000, '/sbin/ifconfig',
577 ['ifconfig',],
578 False, False);
579 fRc = self.closeSession(oGuestSession, False) and fRc and True; # pychecker hack.
580
581 if fRc:
582 break;
583
584 self.oTestDriver.sleep(10);
585 cAttempt += 1;
586
587 return fRc;
588
589 def rebootVMAndCheckReady(self, oSession):
590 """
591 Reboot the VM and wait the VM is ready.
592 """
593
594 fRc, oGuestSession = self.createSession(oSession, 'Session for user: vbox',
595 'vbox', 'password', 10 * 1000, True);
596 if not fRc:
597 return fRc;
598
599 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Reboot the VM',
600 30 * 1000, '/usr/bin/sudo',
601 ['sudo', 'reboot'],
602 False, True);
603 fRc = self.closeSession(oGuestSession, True) and fRc and True; # pychecker hack.
604 fRc = fRc and self.waitVMisReady(oSession);
605 return fRc;
606
607 def powerDownVM(self, oSession):
608 """
609 Power down the VM by calling guest process without wating
610 the VM is really powered off.
611 It helps the terminateBySession to stop the VM without aborting.
612 """
613
614 fRc, oGuestSession = self.createSession(oSession, 'Session for user: vbox',
615 'vbox', 'password', 10 * 1000, True);
616 if not fRc:
617 return fRc;
618
619 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Power down the VM',
620 30 * 1000, '/usr/bin/sudo',
621 ['sudo', 'poweroff'],
622 False, True);
623 fRc = self.closeSession(oGuestSession, True) and fRc and True; # pychecker hack.
624 return fRc;
625
626 def installAdditions(self, oSession, oVM):
627 """
628 Install guest additions in the guest.
629 """
630 fRc, oGuestSession = self.createSession(oSession, 'Session for user: vbox',
631 'vbox', 'password', 10 * 1000, True);
632 if not fRc:
633 return fRc;
634
635 # Install Kernel headers, which are required for actually installing the Linux Additions.
636 if oVM.OSTypeId.startswith('Debian') \
637 or oVM.OSTypeId.startswith('Ubuntu'):
638 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Installing Kernel headers',
639 5 * 60 *1000, '/usr/bin/apt-get',
640 ['/usr/bin/apt-get', 'install', '-y',
641 'linux-headers-generic'],
642 False, True);
643 if not fRc:
644 reporter.error('Error installing Kernel headers');
645 else:
646 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Installing Guest Additions depdendencies',
647 5 * 60 *1000, '/usr/bin/apt-get',
648 ['/usr/bin/apt-get', 'install', '-y', 'build-essential',
649 'perl'], False, True);
650 if not fRc:
651 reporter.error('Error installing additional installer dependencies');
652
653 elif oVM.OSTypeId.startswith('OL') \
654 or oVM.OSTypeId.startswith('Oracle') \
655 or oVM.OSTypeId.startswith('RHEL') \
656 or oVM.OSTypeId.startswith('Redhat') \
657 or oVM.OSTypeId.startswith('Cent'):
658 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Installing Kernel headers',
659 5 * 60 *1000, '/usr/bin/yum',
660 ['/usr/bin/yum', '-y', 'install', 'kernel-headers'],
661 False, True);
662 if not fRc:
663 reporter.error('Error installing Kernel headers');
664 else:
665 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Installing Guest Additions depdendencies',
666 5 * 60 *1000, '/usr/bin/yum',
667 ['/usr/bin/yum', '-y', 'install', 'make', 'automake', 'gcc',
668 'kernel-devel', 'dkms', 'bzip2', 'perl'], False, True);
669 if not fRc:
670 reporter.error('Error installing additional installer dependencies');
671
672 else:
673 reporter.error('Installing Linux Additions for kind "%s" is not supported yet' % oVM.sKind);
674 fRc = False;
675
676 if fRc:
677 #
678 # The actual install.
679 # Also tell the installer to produce the appropriate log files.
680 #
681
682 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Installing guest additions',
683 5 * 60 *1000, '/usr/bin/sudo',
684 ['/usr/bin/sudo', '/bin/sh',
685 '/media/cdrom/VBoxLinuxAdditions.run'],
686 False, True);
687 if fRc:
688 # Due to the GA updates as separate process the above function returns before
689 # the actual installation finished. So just wait until the GA installed
690 fRc = self.waitVMisReady(oSession);
691
692 # Download log files.
693 # Ignore errors as all files above might not be present for whatever reason.
694 #
695 if fRc:
696 asLogFile = [];
697 asLogFile.append('/var/log/vboxadd-install.log');
698 self.downloadFiles(oSession, asLogFile, fIgnoreErrors = True);
699
700 fRc = self.closeSession(oGuestSession, True) and fRc and True; # pychecker hack.
701 if fRc:
702 fRc = self.rebootVMAndCheckReady(oSession);
703
704 return fRc;
705
706 def installVirtualBox(self, oSession):
707 """
708 Install VirtualBox in the guest.
709 """
710 if self.sTestBuild is None:
711 return False;
712
713 fRc, oGuestSession = self.createSession(oSession, 'Session for user: vbox',
714 'vbox', 'password', 10 * 1000, True);
715 if not fRc:
716 return fRc;
717
718 fRc = self.uploadFile(oSession, self.sTestBuild,
719 '/tmp/' + os.path.basename(self.sTestBuild));
720
721 if fRc:
722 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession,
723 'Allowing execution for the vbox installer',
724 30 * 1000, '/usr/bin/sudo',
725 ['/usr/bin/sudo', '/bin/chmod', '755',
726 '/tmp/' + os.path.basename(self.sTestBuild)],
727 False, True);
728 if fRc:
729 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Installing VBox',
730 240 * 1000, '/usr/bin/sudo',
731 ['/usr/bin/sudo',
732 '/tmp/' + os.path.basename(self.sTestBuild),],
733 False, True);
734
735 fRc = self.closeSession(oGuestSession, True) and fRc and True; # pychecker hack.
736 return fRc;
737
738 def configureAutostart(self, oSession, sDefaultPolicy = 'allow',
739 asUserAllow = (), asUserDeny = ()):
740 """
741 Configures the autostart feature in the guest.
742 """
743
744 fRc, oGuestSession = self.createSession(oSession, 'Session for confiure autostart',
745 'vbox', 'password', 10 * 1000, True);
746 if not fRc:
747 return fRc;
748
749 # Create autostart database directory writeable for everyone
750 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Creating autostart database',
751 30 * 1000, '/usr/bin/sudo',
752 ['/usr/bin/sudo', '/bin/mkdir', '-m', '1777', '/etc/vbox/autostart.d'],
753 False, True);
754 # Create /etc/default/virtualbox
755 sVBoxCfg = 'VBOXAUTOSTART_CONFIG=/etc/vbox/autostart.cfg\n' \
756 + 'VBOXAUTOSTART_DB=/etc/vbox/autostart.d\n';
757 fRc = fRc and self.uploadString(oSession, sVBoxCfg, '/tmp/virtualbox');
758 if fRc:
759 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Moving to destination',
760 30 * 1000, '/usr/bin/sudo',
761 ['/usr/bin/sudo', '/bin/mv', '/tmp/virtualbox',
762 '/etc/default/virtualbox'],
763 False, True);
764 if fRc:
765 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Setting permissions',
766 30 * 1000, '/usr/bin/sudo',
767 ['/usr/bin/sudo', '/bin/chmod', '644',
768 '/etc/default/virtualbox'],
769 False, True);
770
771 sVBoxCfg = self._createAutostartCfg(sDefaultPolicy, asUserAllow, asUserDeny);
772 fRc = fRc and self.uploadString(oSession, sVBoxCfg, '/tmp/autostart.cfg');
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 fRc:
780 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Setting permissions',
781 30 * 1000, '/usr/bin/sudo',
782 ['/usr/bin/sudo', '/bin/chmod', '644',
783 '/etc/vbox/autostart.cfg'],
784 False, True);
785 fRc = self.closeSession(oGuestSession, True) and fRc and True; # pychecker hack.
786 return fRc;
787
788 def createUser(self, oSession, sUser):
789 """
790 Create a new user with the given name
791 """
792
793 fRc, oGuestSession = self.createSession(oSession, 'Creating new user',
794 'vbox', 'password', 10 * 1000, True);
795 if fRc:
796 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Creating new user',
797 30 * 1000, '/usr/bin/sudo',
798 ['/usr/bin/sudo', '/usr/sbin/useradd', '-m', '-U',
799 sUser], False, True);
800 fRc = self.closeSession(oGuestSession, True) and fRc and True; # pychecker hack.
801 return fRc;
802
803 # pylint: enable=too-many-arguments
804
805 def createTestVM(self, oSession, sUser, sVmName):
806 """
807 Create a test VM in the guest and enable autostart.
808 Due to the sUser is created whithout password,
809 all calls will be perfomed using 'sudo -u sUser'
810 """
811
812 fRc, oGuestSession = self.createSession(oSession, 'Session for create VM for user: %s' % (sUser,),
813 'vbox', 'password', 10 * 1000, True);
814 if not fRc:
815 return fRc;
816
817 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Configuring autostart database',
818 30 * 1000, '/usr/bin/sudo',
819 ['/usr/bin/sudo', '-u', sUser, '-H', '/opt/VirtualBox/VBoxManage',
820 'setproperty', 'autostartdbpath', '/etc/vbox/autostart.d'],
821 False, True);
822 if fRc:
823 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Create VM ' + sVmName,
824 30 * 1000, '/usr/bin/sudo',
825 ['/usr/bin/sudo', '-u', sUser, '-H',
826 '/opt/VirtualBox/VBoxManage', 'createvm',
827 '--name', sVmName, '--register'], False, True);
828 if fRc:
829 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Enabling autostart for test VM',
830 30 * 1000, '/usr/bin/sudo',
831 ['/usr/bin/sudo', '-u', sUser, '-H',
832 '/opt/VirtualBox/VBoxManage', 'modifyvm',
833 sVmName, '--autostart-enabled', 'on'], False, True);
834 fRc = self.closeSession(oGuestSession, True) and fRc and True; # pychecker hack.
835 return fRc;
836
837 def checkForRunningVM(self, oSession, sUser, sVmName):
838 """
839 Check for VM running in the guest after autostart.
840 Due to the sUser is created whithout password,
841 all calls will be perfomed using 'sudo -u sUser'
842 """
843
844 fRc, oGuestSession = self.createSession(oSession, 'Session for checking running VMs for user: %s' % (sUser,),
845 'vbox', 'password', 10 * 1000, True);
846 if not fRc:
847 return fRc;
848
849 (fRc, _, _, aBuf) = self.guestProcessExecute(oGuestSession, 'Check for running VM',
850 30 * 1000, '/usr/bin/sudo',
851 ['/usr/bin/sudo', '-u', sUser, '-H',
852 '/opt/VirtualBox/VBoxManage',
853 'list', 'runningvms'], True, True);
854 if fRc:
855 bufWrapper = VBoxManageStdOutWrapper();
856 bufWrapper.write(aBuf);
857 fRc = bufWrapper.sVmRunning == sVmName;
858
859 fRc = self.closeSession(oGuestSession, True) and fRc and True; # pychecker hack.
860 return fRc;
861
862
863class tdAutostartOsDarwin(tdAutostartOs):
864 """
865 Autostart support methods for Darwin guests.
866 """
867
868 def __init__(self, oTestDriver, sTestBuildDir, fpApiVer, sGuestAdditionsIso):
869 _ = sTestBuildDir;
870 tdAutostartOs.__init__(self, oTestDriver, fpApiVer, sGuestAdditionsIso);
871 raise base.GenError('Testing the autostart functionality for Darwin is not implemented');
872
873
874class tdAutostartOsSolaris(tdAutostartOs):
875 """
876 Autostart support methods for Solaris guests.
877 """
878
879 def __init__(self, oTestDriver, sTestBuildDir, fpApiVer, sGuestAdditionsIso):
880 _ = sTestBuildDir;
881 tdAutostartOs.__init__(self, oTestDriver, fpApiVer, sGuestAdditionsIso);
882 raise base.GenError('Testing the autostart functionality for Solaris is not implemented');
883
884
885class tdAutostartOsWin(tdAutostartOs):
886 """
887 Autostart support methods for Windows guests.
888 """
889
890 def __init__(self, oTestDriver, asTestBuildDirs, fpApiVer, sGuestAdditionsIso):
891 tdAutostartOs.__init__(self, oTestDriver, fpApiVer, sGuestAdditionsIso);
892 self.sTestBuild = self._findFile('^VirtualBox-.*\\.(exe|msi)$', asTestBuildDirs);
893 if not self.sTestBuild:
894 raise base.GenError("VirtualBox install package not found");
895 return;
896
897 def waitVMisReady(self, oSession):
898 """
899 Waits the VM is ready after start or reboot.
900 """
901 # Give the VM a time to reboot
902 self.oTestDriver.sleep(30);
903
904 # Waiting the VM is ready.
905 # To do it, one will try to open the guest session and start the guest process in loop
906
907 cAttempt = 0;
908
909 while cAttempt < 10:
910 fRc, oGuestSession = self.createSession(oSession, 'Session for user: vbox',
911 'vbox', 'password', 10 * 1000, False);
912 if fRc:
913 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Start a guest process',
914 30 * 1000, 'C:\\Windows\\System32\\ipconfig.exe',
915 ['C:\\Windows\\System32\\ipconfig.exe',],
916 False, False);
917 fRc = self.closeSession(oGuestSession, False) and fRc and True; # pychecker hack.
918
919 if fRc:
920 break;
921
922 self.oTestDriver.sleep(10);
923 cAttempt += 1;
924
925 return fRc;
926
927 def rebootVMAndCheckReady(self, oSession):
928 """
929 Reboot the VM and wait the VM is ready.
930 """
931
932 fRc, oGuestSession = self.createSession(oSession, 'Session for user: vbox',
933 'vbox', 'password', 10 * 1000, True);
934 if not fRc:
935 return fRc;
936
937 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Reboot the VM',
938 30 * 1000, 'C:\\Windows\\System32\\shutdown.exe',
939 ['C:\\Windows\\System32\\shutdown.exe', '/f',
940 '/r', '/t', '0'],
941 False, True);
942 fRc = self.closeSession(oGuestSession, True) and fRc and True; # pychecker hack.
943
944 fRc = fRc and self.waitVMisReady(oSession);
945 return fRc;
946
947 def powerDownVM(self, oSession):
948 """
949 Power down the VM by calling guest process without wating
950 the VM is really powered off.
951 It helps the terminateBySession to stop the VM without aborting.
952 """
953
954 fRc, oGuestSession = self.createSession(oSession, 'Session for user: vbox',
955 'vbox', 'password', 10 * 1000, True);
956 if not fRc:
957 return fRc;
958
959 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Power down the VM',
960 30 * 1000, 'C:\\Windows\\System32\\shutdown.exe',
961 ['C:\\Windows\\System32\\shutdown.exe', '/f',
962 '/s', '/t', '0'],
963 False, True);
964 fRc = self.closeSession(oGuestSession, True) and fRc and True; # pychecker hack.
965 return fRc;
966
967 def installAdditions(self, oSession, oVM):
968 """
969 Installs the Windows guest additions using the test execution service.
970 """
971 fRc, oGuestSession = self.createSession(oSession, 'Session for user: vbox',
972 'vbox', 'password', 10 * 1000, True);
973 if not fRc:
974 return fRc;
975 #
976 # Delete relevant log files.
977 #
978 # Note! On some guests the files in question still can be locked by the OS, so ignore
979 # deletion errors from the guest side (e.g. sharing violations) and just continue.
980 #
981 asLogFiles = [];
982 fHaveSetupApiDevLog = False;
983 if oVM.OSTypeId in ('WindowsNT4',):
984 sWinDir = 'C:/WinNT/';
985 else:
986 sWinDir = 'C:/Windows/';
987 asLogFiles = [sWinDir + 'setupapi.log', sWinDir + 'setupact.log', sWinDir + 'setuperr.log'];
988
989 # Apply The SetupAPI logging level so that we also get the (most verbose) setupapi.dev.log file.
990 ## @todo !!! HACK ALERT !!! Add the value directly into the testing source image. Later.
991 (fHaveSetupApiDevLog, _, _, _) = \
992 self.guestProcessExecute(oGuestSession, 'Enabling setupapi.dev.log',
993 60 * 1000, 'c:\\Windows\\System32\\reg.exe',
994 ['c:\\Windows\\System32\\reg.exe', 'add',
995 '"HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Setup"',
996 '/v', 'LogLevel', '/t', 'REG_DWORD', '/d', '0xFF'],
997 False, True);
998 for sFile in asLogFiles:
999 try: oGuestSession.fsObjRemove(sFile);
1000 except: pass;
1001
1002 fRc = self.closeSession(oGuestSession, True) and fRc and True; # pychecker hack.
1003
1004 try:
1005 oCurProgress = oSession.o.console.guest.updateGuestAdditions(self.sGuestAdditionsIso, None, None);
1006 except:
1007 reporter.maybeErrXcpt(True, 'Updating Guest Additions exception for sSrc="%s":'
1008 % (self.sGuestAdditionsIso,));
1009 fRc = False;
1010 else:
1011 if oCurProgress is not None:
1012 oWrapperProgress = vboxwrappers.ProgressWrapper(oCurProgress, self.oTestDriver.oVBoxMgr,
1013 self.oTestDriver, "installAdditions");
1014 oWrapperProgress.wait();
1015 if not oWrapperProgress.isSuccess():
1016 oWrapperProgress.logResult(fIgnoreErrors = False);
1017 fRc = False;
1018 else:
1019 fRc = reporter.error('No progress object returned');
1020
1021 if fRc:
1022 fRc = self.rebootVMAndCheckReady(oSession);
1023 if fRc is True:
1024 # Add the Windows Guest Additions installer files to the files we want to download
1025 # from the guest.
1026 sGuestAddsDir = 'C:/Program Files/Oracle/VirtualBox Guest Additions/';
1027 asLogFiles.append(sGuestAddsDir + 'install.log');
1028 # Note: There won't be a install_ui.log because of the silent installation.
1029 asLogFiles.append(sGuestAddsDir + 'install_drivers.log');
1030 asLogFiles.append('C:/Windows/setupapi.log');
1031
1032 # Note: setupapi.dev.log only is available since Windows 2000.
1033 if fHaveSetupApiDevLog:
1034 asLogFiles.append('C:/Windows/setupapi.dev.log');
1035
1036 #
1037 # Download log files.
1038 # Ignore errors as all files above might not be present (or in different locations)
1039 # on different Windows guests.
1040 #
1041 self.downloadFiles(oSession, asLogFiles, fIgnoreErrors = True);
1042
1043 return fRc;
1044
1045 def installVirtualBox(self, oSession):
1046 """
1047 Install VirtualBox in the guest.
1048 """
1049
1050 if self.sTestBuild is None:
1051 return False;
1052
1053 fRc, oGuestSession = self.createSession(oSession, 'Session for user: vbox',
1054 'vbox', 'password', 10 * 1000, True);
1055 if not fRc:
1056 return fRc;
1057
1058 # Used windows image already contains the C:\Temp
1059 fRc = fRc and self.uploadFile(oSession, self.sTestBuild,
1060 'C:\\Temp\\' + os.path.basename(self.sTestBuild));
1061
1062 if fRc:
1063 if self.sTestBuild.endswith('.msi'):
1064 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Installing VBox',
1065 240 * 1000, 'C:\\Windows\\System32\\msiexec.exe',
1066 ['msiexec', '/quiet', '/i',
1067 'C:\\Temp\\' + os.path.basename(self.sTestBuild)],
1068 False, True);
1069 else:
1070 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Installing VBox',
1071 240 * 1000, 'C:\\Temp\\' + os.path.basename(self.sTestBuild),
1072 ['C:\\Temp\\' + os.path.basename(self.sTestBuild), '--silent'],
1073 False, True);
1074
1075 fRc = self.closeSession(oGuestSession, True) and fRc and True; # pychecker hack.
1076 return fRc;
1077
1078 def configureAutostart(self, oSession, sDefaultPolicy = 'allow',
1079 asUserAllow = (), asUserDeny = ()):
1080 """
1081 Configures the autostart feature in the guest.
1082 """
1083
1084 fRc, oGuestSession = self.createSession(oSession, 'Session for confiure autostart',
1085 'vbox', 'password', 10 * 1000, True);
1086 if not fRc:
1087 return fRc;
1088
1089 # Create autostart database directory writeable for everyone
1090 (fRc, _, _, _) = \
1091 self.guestProcessExecute(oGuestSession, 'Setting the autostart environment variable',
1092 30 * 1000, 'C:\\Windows\\System32\\reg.exe',
1093 ['reg', 'add',
1094 'HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment',
1095 '/v', 'VBOXAUTOSTART_CONFIG', '/d',
1096 'C:\\ProgramData\\autostart.cfg', '/f'],
1097 False, True);
1098
1099 sVBoxCfg = self._createAutostartCfg(sDefaultPolicy, asUserAllow, asUserDeny);
1100 fRc = fRc and self.uploadString(oSession, sVBoxCfg, 'C:\\ProgramData\\autostart.cfg');
1101 fRc = self.closeSession(oGuestSession, True) and fRc and True; # pychecker hack.
1102 return fRc;
1103
1104 def createTestVM(self, oSession, sUser, sVmName):
1105 """
1106 Create a test VM in the guest and enable autostart.
1107 """
1108
1109 fRc, oGuestSession = self.createSession(oSession, 'Session for user: %s' % (sUser,),
1110 sUser, 'password', 10 * 1000, True);
1111 if not fRc:
1112 return fRc;
1113
1114 (fRc, _, _, _) = \
1115 self.guestProcessExecute(oGuestSession, 'Create VM ' + sVmName,
1116 30 * 1000, 'C:\\Program Files\\Oracle\\VirtualBox\\VBoxManage.exe',
1117 ['C:\\Program Files\\Oracle\\VirtualBox\\VBoxManage.exe', 'createvm',
1118 '--name', sVmName, '--register'], False, True);
1119 if fRc:
1120 (fRc, _, _, _) = \
1121 self.guestProcessExecute(oGuestSession, 'Enabling autostart for test VM',
1122 30 * 1000, 'C:\\Program Files\\Oracle\\VirtualBox\\VBoxManage.exe',
1123 ['C:\\Program Files\\Oracle\\VirtualBox\\VBoxManage.exe',
1124 'modifyvm', sVmName, '--autostart-enabled', 'on'], False, True);
1125 fRc = fRc and self.uploadString(oSession, 'password', 'C:\\ProgramData\\password.cfg');
1126 if fRc:
1127 (fRc, _, _, _) = \
1128 self.guestProcessExecute(oGuestSession, 'Install autostart service for the user',
1129 30 * 1000, 'C:\\Program Files\\Oracle\\VirtualBox\\VBoxAutostartSvc.exe',
1130 ['C:\\Program Files\\Oracle\\VirtualBox\\VBoxAutostartSvc.exe',
1131 'install', '--user=' + sUser,
1132 '--password-file=C:\\ProgramData\\password.cfg'],
1133 False, True);
1134 fRc = self.closeSession(oGuestSession, True) and fRc and True; # pychecker hack.
1135
1136 return fRc;
1137
1138 def checkForRunningVM(self, oSession, sUser, sVmName):
1139 """
1140 Check for VM running in the guest after autostart.
1141 """
1142
1143 fRc, oGuestSession = self.createSession(oSession, 'Session for user: %s' % (sUser,),
1144 sUser, 'password', 10 * 1000, True);
1145 if not fRc:
1146 return fRc;
1147
1148 (fRc, _, _, aBuf) = self.guestProcessExecute(oGuestSession, 'Check for running VM',
1149 30 * 1000, 'C:\\Program Files\\Oracle\\VirtualBox\\VBoxManage.exe',
1150 ['C:\\Program Files\\Oracle\\VirtualBox\\VBoxManage.exe',
1151 'list', 'runningvms'], True, True);
1152 if fRc:
1153 bufWrapper = VBoxManageStdOutWrapper();
1154 bufWrapper.write(aBuf);
1155 fRc = bufWrapper.sVmRunning == sVmName;
1156
1157 fRc = self.closeSession(oGuestSession, True) and fRc and True; # pychecker hack.
1158
1159 return fRc;
1160
1161 def createUser(self, oSession, sUser):
1162 """
1163 Create a new user with the given name
1164 """
1165
1166 fRc, oGuestSession = self.createSession(oSession, 'Creating user %s to run a VM' % sUser,
1167 'vbox', 'password', 10 * 1000, True);
1168 if not fRc:
1169 return fRc;
1170
1171 # Create user
1172 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Creating user %s to run a VM' % sUser,
1173 30 * 1000, 'C:\\Windows\\System32\\net.exe',
1174 ['net', 'user', sUser, 'password', '/add' ], False, True);
1175
1176 # Add the user to Administrators group
1177 if fRc:
1178 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Adding the user %s to Administrators group' % sUser,
1179 30 * 1000, 'C:\\Windows\\System32\\net.exe',
1180 ['net', 'localgroup', 'Administrators', sUser, '/add' ], False, True);
1181
1182 #Allow the user to logon as service
1183 sSecPolicyEditor = """
1184' SetLogonAsAServiceRight.vbs
1185' Sample VBScript to set or grant Logon As A Service Right.
1186' Author: http://www.morgantechspace.com/
1187' ------------------------------------------------------'
1188
1189Dim strUserName,ConfigFileName,OrgStr,RepStr,inputFile,strInputFile,outputFile,obj
1190strUserName = "%s"
1191Dim oShell
1192Set oShell = CreateObject ("WScript.Shell")
1193oShell.Run "secedit /export /cfg config.inf", 0, true
1194oShell.Run "secedit /import /cfg config.inf /db database.sdb", 0, true
1195
1196ConfigFileName = "config.inf"
1197OrgStr = "SeServiceLogonRight ="
1198RepStr = "SeServiceLogonRight = " & strUserName & ","
1199Set inputFile = CreateObject("Scripting.FileSystemObject").OpenTextFile("config.inf", 1,1,-1)
1200strInputFile = inputFile.ReadAll
1201inputFile.Close
1202Set inputFile = Nothing
1203
1204Set outputFile = CreateObject("Scripting.FileSystemObject").OpenTextFile("config.inf",2,1,-1)
1205outputFile.Write (Replace(strInputFile,OrgStr,RepStr))
1206outputFile.Close
1207Set outputFile = Nothing
1208
1209oShell.Run "secedit /configure /db database.sdb /cfg config.inf",0,true
1210set oShell= Nothing
1211
1212Set obj = CreateObject("Scripting.FileSystemObject")
1213obj.DeleteFile("config.inf")
1214obj.DeleteFile("database.sdb")
1215
1216WScript.Echo "Logon As A Service Right granted to user '"& strUserName &"'"
1217 """ % sUser;
1218 fRc = fRc and self.uploadString(oSession, sSecPolicyEditor, 'C:\\Temp\\adjustsec.vbs');
1219 if fRc:
1220 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession,
1221 'Setting the "Logon as service" policy to the user %s' % sUser,
1222 30 * 1000, 'C:\\Windows\\System32\\cscript.exe',
1223 ['cscript.exe', 'C:\\Temp\\adjustsec.vbs', '//Nologo'], False, True);
1224 try:
1225 oGuestSession.fsObjRemove('C:\\Temp\\adjustsec.vbs');
1226 except:
1227 fRc = reporter.errorXcpt('Removing policy script failed');
1228
1229 fRc = self.closeSession(oGuestSession, True) and fRc and True; # pychecker hack.
1230 return fRc;
1231
1232
1233class tdAutostart(vbox.TestDriver): # pylint: disable=too-many-instance-attributes
1234 """
1235 Autostart testcase.
1236 """
1237
1238 ksOsLinux = 'tst-linux'
1239 ksOsWindows = 'tst-win'
1240 ksOsDarwin = 'tst-darwin'
1241 ksOsSolaris = 'tst-solaris'
1242 ksOsFreeBSD = 'tst-freebsd'
1243
1244 def __init__(self):
1245 vbox.TestDriver.__init__(self);
1246 self.asRsrcs = None;
1247 self.asTestVMsDef = [self.ksOsLinux, self.ksOsWindows];
1248 self.asTestVMs = self.asTestVMsDef;
1249 self.asSkipVMs = [];
1250 self.asTestBuildDirs = None; #'D:/AlexD/TestBox/TestAdditionalFiles';
1251 self.sGuestAdditionsIso = None; #'D:/AlexD/TestBox/TestAdditionalFiles/VBoxGuestAdditions_6.1.2.iso';
1252
1253 #
1254 # Overridden methods.
1255 #
1256 def showUsage(self):
1257 rc = vbox.TestDriver.showUsage(self);
1258 reporter.log('');
1259 reporter.log('tdAutostart Options:');
1260 reporter.log(' --test-build-dirs <path1[,path2[,...]]>');
1261 reporter.log(' The list of directories with VirtualBox distros. The option is mandatory');
1262 reporter.log(' without any default value. The test raises an exception if the');
1263 reporter.log(' option is not specified. At least, one directory should be pointed.');
1264 reporter.log(' --guest-additions-iso <path/to/iso>');
1265 reporter.log(' The path to fresh VirtualBox Guest Additions iso. The option is');
1266 reporter.log(' mandatory without any default value. The test raises an exception');
1267 reporter.log(' if the option is not specified.');
1268 reporter.log(' --test-vms <vm1[:vm2[:...]]>');
1269 reporter.log(' Test the specified VMs in the given order. Use this to change');
1270 reporter.log(' the execution order or limit the choice of VMs');
1271 reporter.log(' Default: %s (all)' % (':'.join(self.asTestVMsDef)));
1272 reporter.log(' --skip-vms <vm1[:vm2[:...]]>');
1273 reporter.log(' Skip the specified VMs when testing.');
1274 return rc;
1275
1276 def parseOption(self, asArgs, iArg): # pylint: disable=too-many-branches,too-many-statements
1277 if asArgs[iArg] == '--test-build-dirs':
1278 iArg += 1;
1279 if iArg >= len(asArgs): raise base.InvalidOption('The "--test-build-dirs" takes a paths argument');
1280 self.asTestBuildDirs = asArgs[iArg].split(',');
1281 elif asArgs[iArg] == '--guest-additions-iso':
1282 iArg += 1;
1283 if iArg >= len(asArgs): raise base.InvalidOption('The "--guest-additions-iso" takes a path or url to iso argument');
1284 self.sGuestAdditionsIso = asArgs[iArg];
1285 elif asArgs[iArg] == '--test-vms':
1286 iArg += 1;
1287 if iArg >= len(asArgs): raise base.InvalidOption('The "--test-vms" takes colon separated list');
1288 self.asTestVMs = asArgs[iArg].split(':');
1289 for s in self.asTestVMs:
1290 if s not in self.asTestVMsDef:
1291 raise base.InvalidOption('The "--test-vms" value "%s" is not valid; valid values are: %s' \
1292 % (s, ' '.join(self.asTestVMsDef)));
1293 elif asArgs[iArg] == '--skip-vms':
1294 iArg += 1;
1295 if iArg >= len(asArgs): raise base.InvalidOption('The "--skip-vms" takes colon separated list');
1296 self.asSkipVMs = asArgs[iArg].split(':');
1297 for s in self.asSkipVMs:
1298 if s not in self.asTestVMsDef:
1299 reporter.log('warning: The "--test-vms" value "%s" does not specify any of our test VMs.' % (s));
1300 else:
1301 return vbox.TestDriver.parseOption(self, asArgs, iArg);
1302 return iArg + 1;
1303
1304 def completeOptions(self):
1305 # Remove skipped VMs from the test list.
1306 if self.asTestBuildDirs is None:
1307 raise base.InvalidOption('--test-build-dirs is not specified')
1308 if self.sGuestAdditionsIso is None:
1309 raise base.InvalidOption('--guest-additions-iso is not specified')
1310
1311 for sVM in self.asSkipVMs:
1312 try: self.asTestVMs.remove(sVM);
1313 except: pass;
1314
1315 return vbox.TestDriver.completeOptions(self);
1316
1317 def getResourceSet(self):
1318 # Construct the resource list the first time it's queried.
1319 if self.asRsrcs is None:
1320 self.asRsrcs = [];
1321 if self.ksOsLinux in self.asTestVMs:
1322 self.asRsrcs.append('6.0/ub1804piglit/ub1804piglit.vdi');
1323 if self.ksOsWindows in self.asTestVMs:
1324 self.asRsrcs.append('6.0/windows7piglit/windows7piglit.vdi');
1325 #disabled
1326 #if self.ksOsSolaris in self.asTestVMs:
1327 # self.asRsrcs.append('4.2/autostart/tst-solaris.vdi');
1328
1329 return self.asRsrcs;
1330
1331 def actionConfig(self):
1332
1333 # Make sure vboxapi has been imported so we can use the constants.
1334 if not self.importVBoxApi():
1335 return False;
1336
1337 # Download VBoxGuestAdditions.iso before work
1338 sDestinationIso = os.path.join(self.sScratchPath, 'VBoxGuestAdditions.iso');
1339 utils.noxcptDeleteFile(sDestinationIso);
1340 if not downloadFile(self.sGuestAdditionsIso, sDestinationIso, '', reporter.log, reporter.error):
1341 raise base.GenError("Could not download VBoxGuestAdditions.iso");
1342 self.sGuestAdditionsIso = sDestinationIso;
1343
1344 #
1345 # Configure the VMs we're going to use.
1346 #
1347
1348 fRc = True;
1349
1350 # Linux VMs
1351 if self.ksOsLinux in self.asTestVMs:
1352 # ub1804piglit is created with 2 CPUs.
1353 oVM = self.createTestVM(self.ksOsLinux, 1, '6.0/ub1804piglit/ub1804piglit.vdi', sKind = 'Ubuntu_64', \
1354 fIoApic = True, eNic0AttachType = vboxcon.NetworkAttachmentType_NAT, \
1355 eNic0Type = vboxcon.NetworkAdapterType_Am79C973, cMbRam = 4096, \
1356 cCpus = 2, sDvdImage = self.sGuestAdditionsIso);
1357 if oVM is None:
1358 return False;
1359 # Windows VMs
1360 if self.ksOsWindows in self.asTestVMs:
1361 # windows7piglit is created with PAE enabled and 2 CPUs.
1362 oVM = self.createTestVM(self.ksOsWindows, 1, '6.0/windows7piglit/windows7piglit.vdi', sKind = 'Windows7_64', \
1363 fIoApic = True, eNic0AttachType = vboxcon.NetworkAttachmentType_NAT, \
1364 sHddControllerType = "SATA Controller", cMbRam = 4096, fPae = True, cCpus = 2, \
1365 sDvdImage = self.sGuestAdditionsIso);
1366 if oVM is None:
1367 return False;
1368
1369 # additional options used during the windows7piglit creation
1370 oSession = self.openSession(oVM);
1371 if oSession is not None:
1372 fRc = fRc and oSession.setVRamSize(256);
1373 fRc = fRc and oSession.setVideoControllerType(vboxcon.GraphicsControllerType_VBoxSVGA)
1374 fRc = fRc and oSession.setAccelerate3DEnabled(True);
1375 fRc = fRc and oSession.enableUsbOhci(True);
1376 fRc = fRc and oSession.enableUsbHid(True);
1377 fRc = fRc and oSession.saveSettings();
1378 fRc = oSession.close() and fRc and True; # pychecker hack.
1379 oSession = None;
1380 else:
1381 fRc = False;
1382
1383 # disabled
1384 # Solaris VMs
1385 #if self.ksOsSolaris in self.asTestVMs:
1386 # oVM = self.createTestVM(self.ksOsSolaris, 1, '4.2/autostart/tst-solaris.vdi', sKind = 'Solaris_64', \
1387 # fIoApic = True, eNic0AttachType = vboxcon.NetworkAttachmentType_NAT, \
1388 # sHddControllerType = "SATA Controller");
1389 # if oVM is None:
1390 # return False;
1391
1392 return fRc;
1393
1394 def actionExecute(self):
1395 """
1396 Execute the testcase.
1397 """
1398 fRc = self.testAutostart();
1399 return fRc;
1400
1401 #
1402 # Test execution helpers.
1403 #
1404 def testAutostartRunProgs(self, oSession, sVmName, oVM):
1405 """
1406 Test VirtualBoxs autostart feature in a VM.
1407 """
1408 reporter.testStart('Autostart ' + sVmName);
1409
1410 oGuestOsHlp = None # type: tdAutostartOs
1411 if sVmName == self.ksOsLinux:
1412 oGuestOsHlp = tdAutostartOsLinux(self, self.asTestBuildDirs, self.fpApiVer, # pylint: disable=redefined-variable-type
1413 self.sGuestAdditionsIso);
1414 elif sVmName == self.ksOsSolaris:
1415 oGuestOsHlp = tdAutostartOsSolaris(self, self.asTestBuildDirs, self.fpApiVer, # pylint: disable=redefined-variable-type
1416 self.sGuestAdditionsIso);
1417 elif sVmName == self.ksOsDarwin:
1418 oGuestOsHlp = tdAutostartOsDarwin(self, self.asTestBuildDirs, self.fpApiVer, # pylint: disable=redefined-variable-type
1419 self.sGuestAdditionsIso);
1420 elif sVmName == self.ksOsWindows:
1421 oGuestOsHlp = tdAutostartOsWin(self, self.asTestBuildDirs, self.fpApiVer, # pylint: disable=redefined-variable-type
1422 self.sGuestAdditionsIso);
1423
1424 sTestUserAllow = 'test1';
1425 sTestUserDeny = 'test2';
1426 sTestVmName = 'TestVM';
1427
1428 if oGuestOsHlp is not None:
1429 #wait the VM is ready after starting
1430 fRc = oGuestOsHlp.waitVMisReady(oSession);
1431 #install fresh guest additions
1432 fRc = fRc and oGuestOsHlp.installAdditions(oSession, oVM);
1433 # Create two new users
1434 fRc = fRc and oGuestOsHlp.createUser(oSession, sTestUserAllow);
1435 fRc = fRc and oGuestOsHlp.createUser(oSession, sTestUserDeny);
1436 if fRc is True:
1437 # Install VBox first
1438 fRc = oGuestOsHlp.installVirtualBox(oSession);
1439 if fRc is True:
1440 fRc = oGuestOsHlp.configureAutostart(oSession, 'allow', (sTestUserAllow,), (sTestUserDeny,));
1441 if fRc is True:
1442 # Create a VM with autostart enabled in the guest for both users
1443 fRc = oGuestOsHlp.createTestVM(oSession, sTestUserAllow, sTestVmName);
1444 fRc = fRc and oGuestOsHlp.createTestVM(oSession, sTestUserDeny, sTestVmName);
1445 if fRc is True:
1446 # Reboot the guest
1447 fRc = oGuestOsHlp.rebootVMAndCheckReady(oSession);
1448 if fRc is True:
1449 # Fudge factor - Allow the guest to finish starting up.
1450 self.sleep(30);
1451 fRc = oGuestOsHlp.checkForRunningVM(oSession, sTestUserAllow, sTestVmName);
1452 if fRc is True:
1453 fRc = oGuestOsHlp.checkForRunningVM(oSession, sTestUserDeny, sTestVmName);
1454 if fRc is True:
1455 reporter.error('Test VM is running inside the guest for denied user');
1456 fRc = not fRc;
1457 else:
1458 reporter.error('Test VM is not running inside the guest for allowed user');
1459 else:
1460 reporter.log('Rebooting the guest failed');
1461 else:
1462 reporter.log('Creating test VM failed');
1463 else:
1464 reporter.log('Configuring autostart in the guest failed');
1465 else:
1466 reporter.log('Installing VirtualBox in the guest failed');
1467 else:
1468 reporter.log('Creating test users failed');
1469
1470 try: oGuestOsHlp.powerDownVM(oSession);
1471 except: pass;
1472
1473 else:
1474 reporter.log('Guest OS helper not created for VM %s' % (sVmName));
1475 fRc = False;
1476
1477 reporter.testDone();
1478 return fRc;
1479
1480 def deleteVM(self, oVM):
1481 try: self.oVBox.unregisterMachine(oVM.id);
1482 except: pass;
1483 if self.fpApiVer >= 4.0:
1484 try:
1485 if self.fpApiVer >= 4.3:
1486 oProgress = oVM.deleteConfig([]);
1487 else:
1488 oProgress = oVM.delete(None);
1489 self.waitOnProgress(oProgress);
1490 except:
1491 reporter.logXcpt();
1492 else:
1493 try: oVM.deleteSettings();
1494 except: reporter.logXcpt();
1495 return None;
1496
1497 def testAutostartOneCfg(self, sVmName):
1498 """
1499 Runs the specified VM thru test #1.
1500
1501 Returns a success indicator on the general test execution. This is not
1502 the actual test result.
1503 """
1504 oVM = self.getVmByName(sVmName);
1505
1506 # Reconfigure the VM
1507 fRc = True;
1508 oSession = self.openSession(oVM);
1509 if oSession is not None:
1510 fRc = fRc and oSession.enableVirtEx(True);
1511 fRc = fRc and oSession.enableNestedPaging(True);
1512 fRc = fRc and oSession.enableNestedHwVirt(True);
1513 fRc = fRc and oSession.saveSettings();
1514 fRc = oSession.close() and fRc and True; # pychecker hack.
1515 oSession = None;
1516 else:
1517 fRc = False;
1518
1519 # Start up.
1520 if fRc is True:
1521 self.logVmInfo(oVM);
1522 oSession = self.startVmByName(sVmName);
1523 if oSession is not None:
1524 fRc = self.testAutostartRunProgs(oSession, sVmName, oVM);
1525 try: self.terminateVmBySession(oSession);
1526 except: pass;
1527 self.deleteVM(oVM);
1528 else:
1529 fRc = False;
1530 return fRc;
1531
1532 def testAutostartForOneVM(self, sVmName):
1533 """
1534 Runs one VM thru the various configurations.
1535 """
1536 reporter.testStart(sVmName);
1537 fRc = True;
1538 self.testAutostartOneCfg(sVmName);
1539 reporter.testDone();
1540 return fRc;
1541
1542 def testAutostart(self):
1543 """
1544 Executes autostart test.
1545 """
1546
1547 # Loop thru the test VMs.
1548 for sVM in self.asTestVMs:
1549 # run test on the VM.
1550 if not self.testAutostartForOneVM(sVM):
1551 fRc = False;
1552 else:
1553 fRc = True;
1554
1555 return fRc;
1556
1557
1558
1559if __name__ == '__main__':
1560 sys.exit(tdAutostart().main(sys.argv));
1561
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