VirtualBox

source: vbox/trunk/src/VBox/ValidationKit/tests/additions/tdAddGuestCtrl.py@ 55876

Last change on this file since 55876 was 55668, checked in by vboxsync, 10 years ago

Modified IGuestSession::fileOpenEx: removed the 'offset' parameter and added generic flags parameter so we can easily add features later when we need them (see RTFILE_O_XXX for inspiration). Changed FileSeekOrigin_Set to FileSeekOrigin_Begin.

  • Property svn:eol-style set to LF
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 168.9 KB
Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3# pylint: disable=C0302
4
5"""
6VirtualBox Validation Kit - Guest Control Tests.
7"""
8
9__copyright__ = \
10"""
11Copyright (C) 2010-2015 Oracle Corporation
12
13This file is part of VirtualBox Open Source Edition (OSE), as
14available from http://www.virtualbox.org. This file is free software;
15you can redistribute it and/or modify it under the terms of the GNU
16General Public License (GPL) as published by the Free Software
17Foundation, in version 2 as it comes in the "COPYING" file of the
18VirtualBox OSE distribution. VirtualBox OSE is distributed in the
19hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
20
21The contents of this file may alternatively be used under the terms
22of the Common Development and Distribution License Version 1.0
23(CDDL) only, as it comes in the "COPYING.CDDL" file of the
24VirtualBox OSE distribution, in which case the provisions of the
25CDDL are applicable instead of those of the GPL.
26
27You may elect to license modified versions of this file under the
28terms and conditions of either the GPL or the CDDL or both.
29"""
30__version__ = "$Revision: 55668 $"
31
32# Disable bitching about too many arguments per function.
33# pylint: disable=R0913
34
35## @todo Convert map() usage to a cleaner alternative Python now offers.
36# pylint: disable=W0141
37
38## @todo Convert the context/test classes into named tuples. Not in the mood right now, so
39# disabling it.
40# pylint: disable=R0903
41
42# Standard Python imports.
43from array import array
44import errno
45import os
46import random
47import string # pylint: disable=W0402
48import struct
49import sys
50import time
51
52# Only the main script needs to modify the path.
53try: __file__
54except: __file__ = sys.argv[0];
55g_ksValidationKitDir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))));
56sys.path.append(g_ksValidationKitDir);
57
58# Validation Kit imports.
59from testdriver import reporter;
60from testdriver import base;
61from testdriver import vbox;
62from testdriver import vboxcon;
63from testdriver import vboxwrappers;
64
65
66class GuestStream(bytearray):
67 """
68 Class for handling a guest process input/output stream.
69 """
70 def appendStream(self, stream, convertTo='<b'):
71 """
72 Appends and converts a byte sequence to this object;
73 handy for displaying a guest stream.
74 """
75 self.extend(struct.pack(convertTo, stream));
76
77class tdCtxTest(object):
78 """
79 Provides the actual test environment. Should be kept
80 as generic as possible.
81 """
82 def __init__(self, oSession, oTxsSession, oTestVm): # pylint: disable=W0613
83 ## The desired Main API result.
84 self.fRc = False;
85 ## IGuest reference.
86 self.oGuest = oSession.o.console.guest;
87 # Rest not used (yet).
88
89class tdCtxCreds(object):
90 """
91 Provides credentials to pass to the guest.
92 """
93 def __init__(self, sUser, sPassword, sDomain):
94 self.sUser = sUser;
95 self.sPassword = sPassword;
96 self.sDomain = sDomain;
97
98class tdTestGuestCtrlBase(object):
99 """
100 Base class for all guest control tests.
101 Note: This test ASSUMES that working Guest Additions
102 were installed and running on the guest to be tested.
103 """
104 def __init__(self):
105 self.oTest = None;
106 self.oCreds = None;
107 self.timeoutMS = 30 * 1000; # 30s timeout
108 ## IGuestSession reference or None.
109 self.oGuestSession = None;
110
111 def setEnvironment(self, oSession, oTxsSession, oTestVm):
112 """
113 Sets the test environment required for this test.
114 """
115 self.oTest = tdCtxTest(oSession, oTxsSession, oTestVm);
116 return self.oTest;
117
118 def createSession(self, sName):
119 """
120 Creates (opens) a guest session.
121 Returns (True, IGuestSession) on success or (False, None) on failure.
122 """
123 if self.oGuestSession is None:
124 if sName is None:
125 sName = "<untitled>";
126 try:
127 reporter.log('Creating session "%s" ...' % (sName,));
128 self.oGuestSession = self.oTest.oGuest.createSession(self.oCreds.sUser,
129 self.oCreds.sPassword,
130 self.oCreds.sDomain,
131 sName);
132 except:
133 # Just log, don't assume an error here (will be done in the main loop then).
134 reporter.logXcpt('Creating a guest session "%s" failed; sUser="%s", pw="%s", sDomain="%s":'
135 % (sName, self.oCreds.sUser, self.oCreds.sPassword, self.oCreds.sDomain));
136 return (False, None);
137
138 try:
139 reporter.log('Waiting for session "%s" to start within %ldms...' % (sName, self.timeoutMS));
140 fWaitFor = [ vboxcon.GuestSessionWaitForFlag_Start ];
141 waitResult = self.oGuestSession.waitForArray(fWaitFor, self.timeoutMS);
142 #
143 # Be nice to Guest Additions < 4.3: They don't support session handling and
144 # therefore return WaitFlagNotSupported.
145 #
146 if waitResult != vboxcon.GuestSessionWaitResult_Start \
147 and waitResult != vboxcon.GuestSessionWaitResult_WaitFlagNotSupported:
148 # Just log, don't assume an error here (will be done in the main loop then).
149 reporter.log('Session did not start successfully, returned wait result: %ld' \
150 % (waitResult));
151 return (False, None);
152 reporter.log('Session "%s" successfully started' % (sName,));
153 except:
154 # Just log, don't assume an error here (will be done in the main loop then).
155 reporter.logXcpt('Waiting for guest session "%s" to start failed:' % (sName));
156 return (False, None);
157 else:
158 reporter.log('Warning: Session already set; this is probably not what you want');
159 return (True, self.oGuestSession);
160
161 def setSession(self, oGuestSession):
162 """
163 Sets the current guest session and closes
164 an old one if necessary.
165 """
166 if self.oGuestSession is not None:
167 self.closeSession();
168 self.oGuestSession = oGuestSession;
169 return self.oGuestSession;
170
171 def closeSession(self):
172 """
173 Closes the guest session.
174 """
175 if self.oGuestSession is not None:
176 sName = self.oGuestSession.name;
177 try:
178 reporter.log('Closing session "%s" ...' % (sName,));
179 self.oGuestSession.close();
180 self.oGuestSession = None;
181 except:
182 # Just log, don't assume an error here (will be done in the main loop then).
183 reporter.logXcpt('Closing guest session "%s" failed:' % (sName,));
184 return False;
185 return True;
186
187class tdTestCopyFrom(tdTestGuestCtrlBase):
188 """
189 Test for copying files from the guest to the host.
190 """
191 def __init__(self, sSrc = "", sDst = "", sUser = "", sPassword = "", aFlags = None):
192 tdTestGuestCtrlBase.__init__(self);
193 self.oCreds = tdCtxCreds(sUser, sPassword, sDomain = "");
194 self.sSrc = sSrc;
195 self.sDst = sDst;
196 self.aFlags = aFlags;
197
198class tdTestCopyTo(tdTestGuestCtrlBase):
199 """
200 Test for copying files from the host to the guest.
201 """
202 def __init__(self, sSrc = "", sDst = "", sUser = "", sPassword = "", aFlags = None):
203 tdTestGuestCtrlBase.__init__(self);
204 self.oCreds = tdCtxCreds(sUser, sPassword, sDomain = "");
205 self.sSrc = sSrc;
206 self.sDst = sDst;
207 self.aFlags = aFlags;
208
209class tdTestDirCreate(tdTestGuestCtrlBase):
210 """
211 Test for directoryCreate call.
212 """
213 def __init__(self, sDirectory = "", sUser = "", sPassword = "", fMode = 0, aFlags = None):
214 tdTestGuestCtrlBase.__init__(self);
215 self.oCreds = tdCtxCreds(sUser, sPassword, sDomain = "");
216 self.sDirectory = sDirectory;
217 self.fMode = fMode;
218 self.aFlags = aFlags;
219
220class tdTestDirCreateTemp(tdTestGuestCtrlBase):
221 """
222 Test for the directoryCreateTemp call.
223 """
224 def __init__(self, sDirectory = "", sTemplate = "", sUser = "", sPassword = "", fMode = 0, fSecure = False):
225 tdTestGuestCtrlBase.__init__(self);
226 self.oCreds = tdCtxCreds(sUser, sPassword, sDomain = "");
227 self.sDirectory = sDirectory;
228 self.sTemplate = sTemplate;
229 self.fMode = fMode;
230 self.fSecure = fSecure;
231
232class tdTestDirOpen(tdTestGuestCtrlBase):
233 """
234 Test for the directoryOpen call.
235 """
236 def __init__(self, sDirectory = "", sUser = "", sPassword = "",
237 sFilter = "", aFlags = None):
238 tdTestGuestCtrlBase.__init__(self);
239 self.oCreds = tdCtxCreds(sUser, sPassword, sDomain = "");
240 self.sDirectory = sDirectory;
241 self.sFilter = sFilter;
242 self.aFlags = aFlags or [];
243
244class tdTestDirRead(tdTestDirOpen):
245 """
246 Test for the opening, reading and closing a certain directory.
247 """
248 def __init__(self, sDirectory = "", sUser = "", sPassword = "",
249 sFilter = "", aFlags = None):
250 tdTestDirOpen.__init__(self, sDirectory, sUser, sPassword, sFilter, aFlags);
251
252class tdTestExec(tdTestGuestCtrlBase):
253 """
254 Specifies exactly one guest control execution test.
255 Has a default timeout of 5 minutes (for safety).
256 """
257 def __init__(self, sCmd = "", aArgs = None, aEnv = None, \
258 aFlags = None, timeoutMS = 5 * 60 * 1000, \
259 sUser = "", sPassword = "", sDomain = "", \
260 fWaitForExit = True):
261 tdTestGuestCtrlBase.__init__(self);
262 self.oCreds = tdCtxCreds(sUser, sPassword, sDomain);
263 self.sCmd = sCmd;
264 self.aArgs = aArgs if aArgs is not None else [sCmd,];
265 self.aEnv = aEnv;
266 self.aFlags = aFlags or [];
267 self.timeoutMS = timeoutMS;
268 self.fWaitForExit = fWaitForExit;
269 self.uExitStatus = 0;
270 self.iExitCode = 0;
271 self.cbStdOut = 0;
272 self.cbStdErr = 0;
273 self.sBuf = '';
274
275class tdTestFileExists(tdTestGuestCtrlBase):
276 """
277 Test for the file exists API call (fileExists).
278 """
279 def __init__(self, sFile = "", sUser = "", sPassword = ""):
280 tdTestGuestCtrlBase.__init__(self);
281 self.oCreds = tdCtxCreds(sUser, sPassword, sDomain = "");
282 self.sFile = sFile;
283
284class tdTestFileRemove(tdTestGuestCtrlBase):
285 """
286 Test querying guest file information.
287 """
288 def __init__(self, sFile = "", sUser = "", sPassword = ""):
289 tdTestGuestCtrlBase.__init__(self);
290 self.oCreds = tdCtxCreds(sUser, sPassword, sDomain = "");
291 self.sFile = sFile;
292
293class tdTestFileStat(tdTestGuestCtrlBase):
294 """
295 Test querying guest file information.
296 """
297 def __init__(self, sFile = "", sUser = "", sPassword = "", cbSize = 0, eFileType = 0):
298 tdTestGuestCtrlBase.__init__(self);
299 self.oCreds = tdCtxCreds(sUser, sPassword, sDomain = "");
300 self.sFile = sFile;
301 self.cbSize = cbSize;
302 self.eFileType = eFileType;
303
304class tdTestFileIO(tdTestGuestCtrlBase):
305 """
306 Test for the IGuestFile object.
307 """
308 def __init__(self, sFile = "", sUser = "", sPassword = ""):
309 tdTestGuestCtrlBase.__init__(self);
310 self.oCreds = tdCtxCreds(sUser, sPassword, sDomain = "");
311 self.sFile = sFile;
312
313class tdTestFileQuerySize(tdTestGuestCtrlBase):
314 """
315 Test for the file size query API call (fileQuerySize).
316 """
317 def __init__(self, sFile = "", sUser = "", sPassword = ""):
318 tdTestGuestCtrlBase.__init__(self);
319 self.oCreds = tdCtxCreds(sUser, sPassword, sDomain = "");
320 self.sFile = sFile;
321
322class tdTestFileReadWrite(tdTestGuestCtrlBase):
323 """
324 Tests reading from guest files.
325 """
326 def __init__(self, sFile = "", sUser = "", sPassword = "",
327 sOpenMode = "r", sDisposition = "",
328 sSharingMode = "",
329 lCreationMode = 0, cbOffset = 0, cbToReadWrite = 0,
330 aBuf = None):
331 tdTestGuestCtrlBase.__init__(self);
332 self.oCreds = tdCtxCreds(sUser, sPassword, sDomain = "");
333 self.sFile = sFile;
334 self.sOpenMode = sOpenMode;
335 self.sDisposition = sDisposition;
336 self.sSharingMode = sSharingMode;
337 self.lCreationMode = lCreationMode;
338 self.cbOffset = cbOffset;
339 self.cbToReadWrite = cbToReadWrite;
340 self.aBuf = aBuf;
341
342 def getOpenAction(self):
343 """ Converts string disposition to open action enum. """
344 if self.sDisposition == 'oe': return vboxcon.FileOpenAction_OpenExisting;
345 if self.sDisposition == 'oc': return vboxcon.FileOpenAction_OpenOrCreate;
346 if self.sDisposition == 'ce': return vboxcon.FileOpenAction_CreateNew;
347 if self.sDisposition == 'ca': return vboxcon.FileOpenAction_CreateOrReplace;
348 if self.sDisposition == 'ot': return vboxcon.FileOpenAction_OpenExistingTruncated;
349 if self.sDisposition == 'oa': return vboxcon.FileOpenAction_AppendOrCreate;
350 raise base.GenError(self.sDisposition);
351
352 def getAccessMode(self):
353 """ Converts open mode to access mode enum. """
354 if self.sOpenMode == 'r': return vboxcon.FileOpenMode_ReadOnly;
355 if self.sOpenMode == 'w': return vboxcon.FileOpenMode_WriteOnly;
356 if self.sOpenMode == 'w+': return vboxcon.FileOpenMode_ReadWrite;
357 if self.sOpenMode == 'r+': return vboxcon.FileOpenMode_ReadWrite;
358 raise base.GenError(self.sOpenMode);
359
360 def getSharingMode(self):
361 """ Converts the sharing mode. """
362 return vboxcon.FileSharingMode_All;
363
364class tdTestSession(tdTestGuestCtrlBase):
365 """
366 Test the guest session handling.
367 """
368 def __init__(self, sUser = "", sPassword = "", sDomain = "", \
369 sSessionName = ""):
370 tdTestGuestCtrlBase.__init__(self);
371 self.sSessionName = sSessionName;
372 self.oCreds = tdCtxCreds(sUser, sPassword, sDomain);
373
374 def getSessionCount(self, oVBoxMgr):
375 """
376 Helper for returning the number of currently
377 opened guest sessions of a VM.
378 """
379 if self.oTest.oGuest is None:
380 return 0;
381 aoSession = oVBoxMgr.getArray(self.oTest.oGuest, 'sessions')
382 return len(aoSession);
383
384class tdTestSessionEnv(tdTestGuestCtrlBase):
385 """
386 Test the guest session environment.
387 """
388 def __init__(self, sUser = "", sPassword = "", aEnv = None):
389 tdTestGuestCtrlBase.__init__(self);
390 self.oCreds = tdCtxCreds(sUser, sPassword, sDomain = "");
391 self.aEnv = aEnv or [];
392
393class tdTestSessionFileRefs(tdTestGuestCtrlBase):
394 """
395 Tests session file (IGuestFile) reference counting.
396 """
397 def __init__(self, cRefs = 0):
398 tdTestGuestCtrlBase.__init__(self);
399 self.cRefs = cRefs;
400
401class tdTestSessionDirRefs(tdTestGuestCtrlBase):
402 """
403 Tests session directory (IGuestDirectory) reference counting.
404 """
405 def __init__(self, cRefs = 0):
406 tdTestGuestCtrlBase.__init__(self);
407 self.cRefs = cRefs;
408
409class tdTestSessionProcRefs(tdTestGuestCtrlBase):
410 """
411 Tests session process (IGuestProcess) reference counting.
412 """
413 def __init__(self, cRefs = 0):
414 tdTestGuestCtrlBase.__init__(self);
415 self.cRefs = cRefs;
416
417class tdTestUpdateAdditions(tdTestGuestCtrlBase):
418 """
419 Test updating the Guest Additions inside the guest.
420 """
421 def __init__(self, sSrc = "", aArgs = None, aFlags = None,
422 sUser = "", sPassword = "", sDomain = ""):
423 tdTestGuestCtrlBase.__init__(self);
424 self.oCreds = tdCtxCreds(sUser, sPassword, sDomain);
425 self.sSrc = sSrc;
426 self.aArgs = aArgs;
427 self.aFlags = aFlags;
428
429class tdTestResult(object):
430 """
431 Base class for test results.
432 """
433 def __init__(self, fRc = False):
434 ## The overall test result.
435 self.fRc = fRc;
436
437class tdTestResultDirRead(tdTestResult):
438 """
439 Test result for reading guest directories.
440 """
441 def __init__(self, fRc = False,
442 numFiles = 0, numDirs = 0):
443 tdTestResult.__init__(self, fRc = fRc);
444 self.numFiles = numFiles;
445 self.numDirs = numDirs;
446
447class tdTestResultExec(tdTestResult):
448 """
449 Holds a guest process execution test result,
450 including the exit code, status + aFlags.
451 """
452 def __init__(self, fRc = False, \
453 uExitStatus = 500, iExitCode = 0, \
454 sBuf = None, cbBuf = 0, \
455 cbStdOut = 0, cbStdErr = 0):
456 tdTestResult.__init__(self);
457 ## The overall test result.
458 self.fRc = fRc;
459 ## Process exit stuff.
460 self.uExitStatus = uExitStatus;
461 self.iExitCode = iExitCode;
462 ## Desired buffer length returned back from stdout/stderr.
463 self.cbBuf = cbBuf;
464 ## Desired buffer result from stdout/stderr. Use with caution!
465 self.sBuf = sBuf;
466 self.cbStdOut = cbStdOut;
467 self.cbStdErr = cbStdErr;
468
469class tdTestResultFileStat(tdTestResult):
470 """
471 Test result for stat'ing guest files.
472 """
473 def __init__(self, fRc = False,
474 cbSize = 0, eFileType = 0):
475 tdTestResult.__init__(self, fRc = fRc);
476 self.cbSize = cbSize;
477 self.eFileType = eFileType;
478 ## @todo Add more information.
479
480class tdTestResultFileReadWrite(tdTestResult):
481 """
482 Test result for reading + writing guest directories.
483 """
484 def __init__(self, fRc = False,
485 cbProcessed = 0, cbOffset = 0, aBuf = None):
486 tdTestResult.__init__(self, fRc = fRc);
487 self.cbProcessed = cbProcessed;
488 self.cbOffset = cbOffset;
489 self.aBuf = aBuf;
490
491class tdTestResultSession(tdTestResult):
492 """
493 Test result for guest session counts.
494 """
495 def __init__(self, fRc = False, cNumSessions = 0):
496 tdTestResult.__init__(self, fRc = fRc);
497 self.cNumSessions = cNumSessions;
498
499class tdTestResultSessionEnv(tdTestResult):
500 """
501 Test result for guest session environment tests.
502 """
503 def __init__(self, fRc = False, cNumVars = 0):
504 tdTestResult.__init__(self, fRc = fRc);
505 self.cNumVars = cNumVars;
506
507
508class SubTstDrvAddGuestCtrl(base.SubTestDriverBase):
509 """
510 Sub-test driver for executing guest control (VBoxService, IGuest) tests.
511 """
512
513 def __init__(self, oTstDrv):
514 base.SubTestDriverBase.__init__(self, 'add-guest-ctrl', oTstDrv);
515
516 ## @todo base.TestBase.
517 self.asTestsDef = \
518 [
519 'session_basic', 'session_env', 'session_file_ref', 'session_dir_ref', 'session_proc_ref', \
520 'exec_basic', 'exec_errorlevel', 'exec_timeout', \
521 'dir_create', 'dir_create_temp', 'dir_read', \
522 'file_remove', 'file_stat', 'file_read', 'file_write', \
523 'copy_to', 'copy_from', \
524 'update_additions'
525 ];
526 self.asTests = self.asTestsDef;
527
528 def parseOption(self, asArgs, iArg): # pylint: disable=R0912,R0915
529 if asArgs[iArg] == '--add-guest-ctrl-tests':
530 iArg += 1;
531 if asArgs[iArg] == 'all': # Nice for debugging scripts.
532 self.asTests = self.asTestsDef;
533 return iArg + 1;
534
535 iNext = self.oTstDrv.requireMoreArgs(1, asArgs, iArg);
536 self.asTests = asArgs[iArg].split(':');
537 for s in self.asTests:
538 if s not in self.asTestsDef:
539 raise base.InvalidOption('The "--add-guest-ctrl-tests" value "%s" is not valid; valid values are: %s' \
540 % (s, ' '.join(self.asTestsDef)));
541 return iNext;
542 return iArg;
543
544 def showUsage(self):
545 base.SubTestDriverBase.showUsage(self);
546 reporter.log(' --add-guest-ctrl-tests <s1[:s2[:]]>');
547 reporter.log(' Default: %s (all)' % (':'.join(self.asTestsDef)));
548 return True;
549
550 def testIt(self, oTestVm, oSession, oTxsSession):
551 """
552 Executes the test.
553
554 Returns fRc, oTxsSession. The latter may have changed.
555 """
556 reporter.log("Active tests: %s" % (self.asTests,));
557
558 # Do the testing.
559 reporter.testStart('Session Basics');
560 fSkip = 'session_basic' not in self.asTests;
561 if fSkip == False:
562 fRc, oTxsSession = self.testGuestCtrlSession(oSession, oTxsSession, oTestVm);
563 reporter.testDone(fSkip);
564
565 reporter.testStart('Session Environment');
566 fSkip = 'session_env' not in self.asTests or fRc is False;
567 if fSkip == False:
568 fRc, oTxsSession = self.testGuestCtrlSessionEnvironment(oSession, oTxsSession, oTestVm);
569 reporter.testDone(fSkip);
570
571 reporter.testStart('Session File References');
572 fSkip = 'session_file_ref' not in self.asTests;
573 if fSkip == False:
574 fRc, oTxsSession = self.testGuestCtrlSessionFileRefs(oSession, oTxsSession, oTestVm);
575 reporter.testDone(fSkip);
576
577 ## @todo Implement this.
578 #reporter.testStart('Session Directory References');
579 #fSkip = 'session_dir_ref' not in self.asTests;
580 #if fSkip == False:
581 # fRc, oTxsSession = self.testGuestCtrlSessionDirRefs(oSession, oTxsSession, oTestVm);
582 #reporter.testDone(fSkip);
583
584 reporter.testStart('Session Process References');
585 fSkip = 'session_proc_ref' not in self.asTests or fRc is False;
586 if fSkip == False:
587 fRc, oTxsSession = self.testGuestCtrlSessionProcRefs(oSession, oTxsSession, oTestVm);
588 reporter.testDone(fSkip);
589
590 reporter.testStart('Execution');
591 fSkip = 'exec_basic' not in self.asTests or fRc is False;
592 if fSkip == False:
593 fRc, oTxsSession = self.testGuestCtrlExec(oSession, oTxsSession, oTestVm);
594 reporter.testDone(fSkip);
595
596 reporter.testStart('Execution Error Levels');
597 fSkip = 'exec_errorlevel' not in self.asTests or fRc is False;
598 if fSkip == False:
599 fRc, oTxsSession = self.testGuestCtrlExecErrorLevel(oSession, oTxsSession, oTestVm);
600 reporter.testDone(fSkip);
601
602 reporter.testStart('Execution Timeouts');
603 fSkip = 'exec_timeout' not in self.asTests or fRc is False;
604 if fSkip == False:
605 fRc, oTxsSession = self.testGuestCtrlExecTimeout(oSession, oTxsSession, oTestVm);
606 reporter.testDone(fSkip);
607
608 reporter.testStart('Creating directories');
609 fSkip = 'dir_create' not in self.asTests or fRc is False;
610 if fSkip == False:
611 fRc, oTxsSession = self.testGuestCtrlDirCreate(oSession, oTxsSession, oTestVm);
612 reporter.testDone(fSkip);
613
614 reporter.testStart('Creating temporary directories');
615 fSkip = 'dir_create_temp' not in self.asTests or fRc is False;
616 if fSkip == False:
617 fRc, oTxsSession = self.testGuestCtrlDirCreateTemp(oSession, oTxsSession, oTestVm);
618 reporter.testDone(fSkip);
619
620 reporter.testStart('Reading directories');
621 fSkip = 'dir_read' not in self.asTests or fRc is False;
622 if fSkip == False:
623 fRc, oTxsSession = self.testGuestCtrlDirRead(oSession, oTxsSession, oTestVm);
624 reporter.testDone(fSkip);
625
626 # FIXME: Failing test.
627 # reporter.testStart('Copy to guest');
628 # fSkip = 'copy_to' not in self.asTests or fRc is False;
629 # if fSkip == False:
630 # fRc, oTxsSession = self.testGuestCtrlCopyTo(oSession, oTxsSession, oTestVm);
631 # reporter.testDone(fSkip);
632
633 reporter.testStart('Copy from guest');
634 fSkip = 'copy_from' not in self.asTests or fRc is False;
635 if fSkip == False:
636 fRc, oTxsSession = self.testGuestCtrlCopyFrom(oSession, oTxsSession, oTestVm);
637 reporter.testDone(fSkip);
638
639 reporter.testStart('Removing files');
640 fSkip = 'file_remove' not in self.asTests or fRc is False;
641 if fSkip == False:
642 fRc, oTxsSession = self.testGuestCtrlFileRemove(oSession, oTxsSession, oTestVm);
643 reporter.testDone(fSkip);
644
645 reporter.testStart('Querying file information (stat)');
646 fSkip = 'file_stat' not in self.asTests or fRc is False;
647 if fSkip == False:
648 fRc, oTxsSession = self.testGuestCtrlFileStat(oSession, oTxsSession, oTestVm);
649 reporter.testDone(fSkip);
650
651 # FIXME: Failing tests.
652 # reporter.testStart('File read');
653 # fSkip = 'file_read' not in self.asTests or fRc is False;
654 # if fSkip == False:
655 # fRc, oTxsSession = self.testGuestCtrlFileRead(oSession, oTxsSession, oTestVm);
656 # reporter.testDone(fSkip);
657
658 # reporter.testStart('File write');
659 # fSkip = 'file_write' not in self.asTests or fRc is False;
660 # if fSkip == False:
661 # fRc, oTxsSession = self.testGuestCtrlFileWrite(oSession, oTxsSession, oTestVm);
662 # reporter.testDone(fSkip);
663
664 reporter.testStart('Updating Guest Additions');
665 fSkip = 'update_additions' not in self.asTests or fRc is False;
666 # Skip test for updating Guest Additions if we run on a too old (Windows) guest.
667 fSkip = oTestVm.sKind in ('WindowsNT4', 'Windows2000', 'WindowsXP', 'Windows2003');
668 if fSkip == False:
669 fRc, oTxsSession = self.testGuestCtrlUpdateAdditions(oSession, oTxsSession, oTestVm);
670 reporter.testDone(fSkip);
671
672 return (fRc, oTxsSession);
673
674 def gctrlCopyFileFrom(self, oGuestSession, sSrc, sDst, aFlags):
675 """
676 Helper function to copy a single file from the guest to the host.
677 """
678 fRc = True; # Be optimistic.
679 try:
680 reporter.log2('Copying guest file "%s" to host "%s"' % (sSrc, sDst));
681 if self.oTstDrv.fpApiVer >= 5.0:
682 curProgress = oGuestSession.fileCopyFromGuest(sSrc, sDst, aFlags);
683 else:
684 curProgress = oGuestSession.copyFrom(sSrc, sDst, aFlags);
685 if curProgress is not None:
686 oProgress = vboxwrappers.ProgressWrapper(curProgress, self.oTstDrv.oVBoxMgr, self, "gctrlCopyFrm");
687 try:
688 iRc = oProgress.waitForOperation(0, fIgnoreErrors = True);
689 if iRc != 0:
690 reporter.log('Waiting for copyFrom failed');
691 fRc = False;
692 except:
693 reporter.logXcpt('Copy from waiting exception for sSrc="%s", sDst="%s":' \
694 % (sSrc, sDst));
695 fRc = False;
696 except:
697 # Just log, don't assume an error here (will be done in the main loop then).
698 reporter.logXcpt('Copy from exception for sSrc="%s", sDst="%s":' \
699 % (sSrc, sDst));
700 fRc = False;
701
702 return fRc;
703
704 def gctrlCopyFileTo(self, oGuestSession, sSrc, sDst, aFlags):
705 """
706 Helper function to copy a single file from host to the guest.
707 """
708 fRc = True; # Be optimistic.
709 try:
710 reporter.log2('Copying host file "%s" to guest "%s"' % (sSrc, sDst));
711 if self.oTstDrv.fpApiVer >= 5.0:
712 curProgress = oGuestSession.fileCopyToGuest(sSrc, sDst, aFlags);
713 else:
714 curProgress = oGuestSession.copyTo(sSrc, sDst, aFlags);
715 if curProgress is not None:
716 oProgress = vboxwrappers.ProgressWrapper(curProgress, self.oTstDrv.oVBoxMgr, self, "gctrlCopyTo");
717 try:
718 iRc = oProgress.waitForOperation(0, fIgnoreErrors = True);
719 if iRc != 0:
720 reporter.log('Waiting for copyTo failed');
721 fRc = False;
722 except:
723 reporter.logXcpt('Copy to waiting exception for sSrc="%s", sDst="%s":' \
724 % (sSrc, sDst));
725 fRc = False;
726 else:
727 reporter.error('No progress object returned');
728 except:
729 # Just log, don't assume an error here (will be done in the main loop then).
730 reporter.logXcpt('Copy to exception for sSrc="%s", sDst="%s":' \
731 % (sSrc, sDst));
732 fRc = False;
733
734 return fRc;
735
736 def gctrlCopyFrom(self, oTest, oRes, oGuestSession, subDir = ''): # pylint: disable=R0914
737 """
738 Copies files / directories to the host.
739 Source always contains the absolute path, subDir all paths
740 below it.
741 """
742 ## @todo r=bird: The use subDir and sSubDir in this method is extremely confusing!!
743 # Just follow the coding guidelines and ALWAYS use prefixes, please!
744 fRc = True; # Be optimistic.
745
746 sSrc = oTest.sSrc;
747 sDst = oTest.sDst;
748 aFlags = oTest.aFlags;
749
750 if sSrc == "" \
751 or os.path.isfile(sSrc):
752 return self.gctrlCopyFileFrom(oGuestSession, \
753 sSrc, sDst, aFlags);
754 sSrcAbs = sSrc;
755 if subDir != "":
756 sSrcAbs = os.path.join(sSrc, subDir);
757 sFilter = ""; # No filter.
758
759 sDstAbs = os.path.join(sDst, subDir);
760 reporter.log2('Copying guest directory "%s" to host "%s"' % (sSrcAbs, sDstAbs));
761
762 try:
763 #reporter.log2('Directory="%s", filter="%s", aFlags="%s"' % (sCurDir, sFilter, aFlags));
764 oCurDir = oGuestSession.directoryOpen(sSrcAbs, sFilter, aFlags);
765 while fRc:
766 try:
767 oFsObjInfo = oCurDir.read();
768 if oFsObjInfo.name == "." \
769 or oFsObjInfo.name == "..":
770 #reporter.log2('\tSkipping "%s"' % (oFsObjInfo.name,));
771 continue; # Skip "." and ".." entries.
772 if oFsObjInfo.type is vboxcon.FsObjType_Directory:
773 #reporter.log2('\tDirectory "%s"' % (oFsObjInfo.name,));
774 sDirCreate = sDst;
775 if subDir != "":
776 sDirCreate = os.path.join(sDirCreate, subDir);
777 sDirCreate = os.path.join(sDirCreate, oFsObjInfo.name);
778 try:
779 reporter.log2('\tCreating directory "%s"' % (sDirCreate,));
780 os.makedirs(sDirCreate);
781 sSubDir = oFsObjInfo.name;
782 if subDir != "":
783 sSubDir = os.path.join(subDir, oFsObjInfo.name);
784 self.gctrlCopyFrom(oTest, oRes, oGuestSession, sSubDir);
785 except (OSError) as e:
786 if e.errno == errno.EEXIST:
787 pass;
788 else:
789 # Just log, don't assume an error here (will be done in the main loop then).
790 reporter.logXcpt('\tDirectory creation exception for directory="%s":' % (sSubDir,));
791 raise;
792 elif oFsObjInfo.type is vboxcon.FsObjType_File:
793 #reporter.log2('\tFile "%s"' % (oFsObjInfo.name,));
794 sSourceFile = os.path.join(sSrcAbs, oFsObjInfo.name);
795 sDestFile = os.path.join(sDstAbs, oFsObjInfo.name);
796 self.gctrlCopyFileFrom(oGuestSession, sSourceFile, sDestFile, aFlags);
797 elif oFsObjInfo.type is vboxcon.FsObjType_Symlink:
798 #reporter.log2('\tSymlink "%s" -- not tested yet' % oFsObjInfo.name);
799 pass;
800 else:
801 reporter.error('\tDirectory "%s" contains invalid directory entry "%s" (%d)' \
802 % (sSubDir, oFsObjInfo.name, oFsObjInfo.type));
803 fRc = False;
804 except Exception, oXcpt:
805 # No necessarily an error -- could be VBOX_E_OBJECT_NOT_FOUND. See reference.
806 if vbox.ComError.equal(oXcpt, vbox.ComError.VBOX_E_OBJECT_NOT_FOUND):
807 #reporter.log2('\tNo more directory entries for "%s"' % (sCurDir,));
808 break
809 # Just log, don't assume an error here (will be done in the main loop then).
810 reporter.logXcpt('\tDirectory read exception for directory="%s":' % (sSrcAbs,));
811 fRc = False;
812 break;
813 oCurDir.close();
814 except:
815 # Just log, don't assume an error here (will be done in the main loop then).
816 reporter.logXcpt('\tDirectory open exception for directory="%s":' % (sSrcAbs,));
817 fRc = False;
818
819 return fRc;
820
821 def gctrlCopyTo(self, oTest, oGuestSession, subDir = ''): # pylint: disable=R0914
822 """
823 Copies files / directories to the guest.
824 Source always contains the absolute path,
825 subDir all paths below it.
826 """
827 fRc = True; # Be optimistic.
828
829 sSrc = oTest.sSrc;
830 sDst = oTest.sDst;
831 aFlags = oTest.aFlags;
832
833 reporter.log2('sSrc=%s, sDst=%s, aFlags=%s' % (sSrc, sDst, aFlags));
834
835 sSrcAbs = sSrc;
836 if subDir != "":
837 sSrcAbs = os.path.join(sSrc, subDir);
838
839 # Note: Current test might want to test copying empty sources
840 if not os.path.exists(sSrcAbs) \
841 or os.path.isfile(sSrcAbs):
842 return self.gctrlCopyFileTo(oGuestSession, \
843 sSrcAbs, sDst, aFlags);
844
845 sDstAbs = os.path.join(sDst, subDir);
846 reporter.log2('Copying host directory "%s" to guest "%s"' % (sSrcAbs, sDstAbs));
847
848 try:
849 # Note: Symlinks intentionally not considered here.
850 for (sDirCurrent, oDirs, oFiles) in os.walk(sSrcAbs, topdown=True):
851 for sFile in oFiles:
852 sCurFile = os.path.join(sDirCurrent, sFile);
853 reporter.log2('Processing host file "%s"' % (sCurFile,));
854 sFileDest = os.path.join(sDstAbs, os.path.relpath(sCurFile, sSrcAbs));
855 reporter.log2('Copying file to "%s"' % (sFileDest,));
856 fRc = self.gctrlCopyFileTo(oGuestSession, \
857 sCurFile, sFileDest, aFlags);
858 if fRc is False:
859 break;
860
861 if fRc is False:
862 break;
863
864 for sSubDir in oDirs:
865 sCurDir = os.path.join(sDirCurrent, sSubDir);
866 reporter.log2('Processing host dir "%s"' % (sCurDir,));
867 sDirDest = os.path.join(sDstAbs, os.path.relpath(sCurDir, sSrcAbs));
868 reporter.log2('Creating guest dir "%s"' % (sDirDest,));
869 oGuestSession.directoryCreate(sDirDest, \
870 700, [ vboxcon.DirectoryCreateFlag_Parents ]);
871 if fRc is False:
872 break;
873
874 if fRc is False:
875 break;
876 except:
877 # Just log, don't assume an error here (will be done in the main loop then).
878 reporter.logXcpt('Copy to exception for sSrc="%s", sDst="%s":' \
879 % (sSrcAbs, sDst));
880 return False;
881
882 return fRc;
883
884 def gctrlCreateDir(self, oTest, oRes, oGuestSession):
885 """
886 Helper function to create a guest directory specified in
887 the current test.
888 """
889 fRc = True; # Be optimistic.
890 reporter.log2('Creating directory "%s"' % (oTest.sDirectory,));
891
892 try:
893 oGuestSession.directoryCreate(oTest.sDirectory, \
894 oTest.fMode, oTest.aFlags);
895 if self.oTstDrv.fpApiVer >= 5.0:
896 fDirExists = oGuestSession.directoryExists(oTest.sDirectory, False);
897 else:
898 fDirExists = oGuestSession.directoryExists(oTest.sDirectory);
899 if fDirExists is False \
900 and oRes.fRc is True:
901 # Directory does not exist but we want it to.
902 fRc = False;
903 except:
904 reporter.logXcpt('Directory create exception for directory "%s":' % (oTest.sDirectory,));
905 if oRes.fRc is True:
906 # Just log, don't assume an error here (will be done in the main loop then).
907 fRc = False;
908 # Directory creation failed, which was the expected result.
909
910 return fRc;
911
912 def gctrlReadDir(self, oTest, oRes, oGuestSession, subDir = ''): # pylint: disable=R0914
913 """
914 Helper function to read a guest directory specified in
915 the current test.
916 """
917 sDir = oTest.sDirectory;
918 sFilter = oTest.sFilter;
919 aFlags = oTest.aFlags;
920
921 fRc = True; # Be optimistic.
922 cDirs = 0; # Number of directories read.
923 cFiles = 0; # Number of files read.
924
925 try:
926 sCurDir = os.path.join(sDir, subDir);
927 #reporter.log2('Directory="%s", filter="%s", aFlags="%s"' % (sCurDir, sFilter, aFlags));
928 oCurDir = oGuestSession.directoryOpen(sCurDir, sFilter, aFlags);
929 while fRc:
930 try:
931 oFsObjInfo = oCurDir.read();
932 if oFsObjInfo.name == "." \
933 or oFsObjInfo.name == "..":
934 #reporter.log2('\tSkipping "%s"' % oFsObjInfo.name);
935 continue; # Skip "." and ".." entries.
936 if oFsObjInfo.type is vboxcon.FsObjType_Directory:
937 #reporter.log2('\tDirectory "%s"' % oFsObjInfo.name);
938 cDirs += 1;
939 sSubDir = oFsObjInfo.name;
940 if subDir != "":
941 sSubDir = os.path.join(subDir, oFsObjInfo.name);
942 fRc, cSubDirs, cSubFiles = self.gctrlReadDir(oTest, oRes, oGuestSession, sSubDir);
943 cDirs += cSubDirs;
944 cFiles += cSubFiles;
945 elif oFsObjInfo.type is vboxcon.FsObjType_File:
946 #reporter.log2('\tFile "%s"' % oFsObjInfo.name);
947 cFiles += 1;
948 elif oFsObjInfo.type is vboxcon.FsObjType_Symlink:
949 #reporter.log2('\tSymlink "%s" -- not tested yet' % oFsObjInfo.name);
950 pass;
951 else:
952 reporter.error('\tDirectory "%s" contains invalid directory entry "%s" (type %d)' % \
953 (sCurDir, oFsObjInfo.name, oFsObjInfo.type));
954 fRc = False;
955 except Exception, oXcpt:
956 # No necessarily an error -- could be VBOX_E_OBJECT_NOT_FOUND. See reference.
957 if vbox.ComError.equal(oXcpt, vbox.ComError.VBOX_E_OBJECT_NOT_FOUND):
958 #reporter.log2('\tNo more directory entries for "%s"' % (sCurDir,));
959 break
960 # Just log, don't assume an error here (will be done in the main loop then).
961 reporter.logXcpt('\tDirectory open exception for directory="%s":' % (sCurDir,));
962 fRc = False;
963 break;
964 oCurDir.close();
965 except:
966 # Just log, don't assume an error here (will be done in the main loop then).
967 reporter.logXcpt('\tDirectory open exception for directory="%s":' % (sCurDir,));
968 fRc = False;
969
970 return (fRc, cDirs, cFiles);
971
972 def gctrlExecDoTest(self, i, oTest, oRes, oGuestSession):
973 """
974 Wrapper function around gctrlExecute to provide more sanity checking
975 when needed in actual execution tests.
976 """
977 reporter.log('Testing #%d, cmd="%s" ...' % (i, oTest.sCmd));
978 fRc = self.gctrlExecute(oTest, oGuestSession);
979 if fRc is oRes.fRc:
980 if fRc is True:
981 # Compare exit status / code on successful process execution.
982 if oTest.uExitStatus != oRes.uExitStatus \
983 or oTest.iExitCode != oRes.iExitCode:
984 reporter.error('Test #%d failed: Got exit status + code %d,%d, expected %d,%d' % \
985 (i, oTest.uExitStatus, oTest.iExitCode, \
986 oRes.uExitStatus, oRes.iExitCode));
987 return False;
988 if fRc is True:
989 # Compare test / result buffers on successful process execution.
990 if oTest.sBuf is not None \
991 and oRes.sBuf is not None:
992 if bytes(oTest.sBuf) != bytes(oRes.sBuf):
993 reporter.error('Test #%d failed: Got buffer\n%s (%ld bytes), expected\n%s (%ld bytes)' %
994 (i, map(hex, map(ord, oTest.sBuf)), len(oTest.sBuf), \
995 map(hex, map(ord, oRes.sBuf)), len(oRes.sBuf)));
996 return False;
997 else:
998 reporter.log2('Test #%d passed: Buffers match (%ld bytes)' % (i, len(oRes.sBuf)));
999 elif oRes.sBuf is not None \
1000 and len(oRes.sBuf):
1001 reporter.error('Test #%d failed: Got no buffer data, expected\n%s (%dbytes)' %
1002 (i, map(hex, map(ord, oRes.sBuf)), len(oRes.sBuf)));
1003 return False;
1004 elif oRes.cbStdOut > 0 \
1005 and oRes.cbStdOut != oTest.cbStdOut:
1006 reporter.error('Test #%d failed: Got %ld stdout data, expected %ld'
1007 % (i, oTest.cbStdOut, oRes.cbStdOut));
1008 return False;
1009 else:
1010 reporter.error('Test #%d failed: Got %s, expected %s' % (i, fRc, oRes.fRc));
1011 return False;
1012 return True;
1013
1014 def gctrlExecute(self, oTest, oGuestSession):
1015 """
1016 Helper function to execute a program on a guest, specified in
1017 the current test.
1018 """
1019 fRc = True; # Be optimistic.
1020
1021 ## @todo Compare execution timeouts!
1022 #tsStart = base.timestampMilli();
1023
1024 reporter.log2('Using session user=%s, sDomain=%s, session name=%s, session timeout=%ld' \
1025 % (oGuestSession.user, oGuestSession.domain, \
1026 oGuestSession.name, oGuestSession.timeout));
1027 reporter.log2('Executing cmd=%s, aFlags=%s, timeout=%ld, args=%s, env=%s' \
1028 % (oTest.sCmd, oTest.aFlags, oTest.timeoutMS, \
1029 oTest.aArgs, oTest.aEnv));
1030 try:
1031 curProc = oGuestSession.processCreate(oTest.sCmd,
1032 oTest.aArgs if self.oTstDrv.fpApiVer >= 5.0 else oTest.aArgs[1:],
1033 oTest.aEnv, oTest.aFlags, oTest.timeoutMS);
1034 if curProc is not None:
1035 reporter.log2('Process start requested, waiting for start (%ldms) ...' % (oTest.timeoutMS,));
1036 fWaitFor = [ vboxcon.ProcessWaitForFlag_Start ];
1037 waitResult = curProc.waitForArray(fWaitFor, oTest.timeoutMS);
1038 reporter.log2('Wait result returned: %d, current process status is: %ld' % (waitResult, curProc.status));
1039
1040 if curProc.status == vboxcon.ProcessStatus_Started:
1041 fWaitFor = [ vboxcon.ProcessWaitForFlag_Terminate ];
1042 if vboxcon.ProcessCreateFlag_WaitForStdOut in oTest.aFlags:
1043 fWaitFor.append(vboxcon.ProcessWaitForFlag_StdOut);
1044 if vboxcon.ProcessCreateFlag_WaitForStdErr in oTest.aFlags:
1045 fWaitFor.append(vboxcon.ProcessWaitForFlag_StdErr);
1046 ## @todo Add vboxcon.ProcessWaitForFlag_StdIn.
1047 reporter.log2('Process (PID %ld) started, waiting for termination (%dms), waitFlags=%s ...' \
1048 % (curProc.PID, oTest.timeoutMS, fWaitFor));
1049 while True:
1050 waitResult = curProc.waitForArray(fWaitFor, oTest.timeoutMS);
1051 reporter.log2('Wait returned: %d' % (waitResult,));
1052 try:
1053 # Try stdout.
1054 if waitResult == vboxcon.ProcessWaitResult_StdOut \
1055 or waitResult == vboxcon.ProcessWaitResult_WaitFlagNotSupported:
1056 reporter.log2('Reading stdout ...');
1057 buf = curProc.Read(1, 64 * 1024, oTest.timeoutMS);
1058 if len(buf):
1059 reporter.log2('Process (PID %ld) got %ld bytes of stdout data' % (curProc.PID, len(buf)));
1060 oTest.cbStdOut += len(buf);
1061 oTest.sBuf = buf; # Appending does *not* work atm, so just assign it. No time now.
1062 # Try stderr.
1063 if waitResult == vboxcon.ProcessWaitResult_StdErr \
1064 or waitResult == vboxcon.ProcessWaitResult_WaitFlagNotSupported:
1065 reporter.log2('Reading stderr ...');
1066 buf = curProc.Read(2, 64 * 1024, oTest.timeoutMS);
1067 if len(buf):
1068 reporter.log2('Process (PID %ld) got %ld bytes of stderr data' % (curProc.PID, len(buf)));
1069 oTest.cbStdErr += len(buf);
1070 oTest.sBuf = buf; # Appending does *not* work atm, so just assign it. No time now.
1071 # Use stdin.
1072 if waitResult == vboxcon.ProcessWaitResult_StdIn \
1073 or waitResult == vboxcon.ProcessWaitResult_WaitFlagNotSupported:
1074 pass; #reporter.log2('Process (PID %ld) needs stdin data' % (curProc.pid,));
1075 # Termination or error?
1076 if waitResult == vboxcon.ProcessWaitResult_Terminate \
1077 or waitResult == vboxcon.ProcessWaitResult_Error \
1078 or waitResult == vboxcon.ProcessWaitResult_Timeout:
1079 reporter.log2('Process (PID %ld) reported terminate/error/timeout: %ld, status: %ld' \
1080 % (curProc.PID, waitResult, curProc.status));
1081 break;
1082 except:
1083 # Just skip reads which returned nothing.
1084 pass;
1085 reporter.log2('Final process status (PID %ld) is: %ld' % (curProc.PID, curProc.status));
1086 reporter.log2('Process (PID %ld) %ld stdout, %ld stderr' % (curProc.PID, oTest.cbStdOut, oTest.cbStdErr));
1087 oTest.uExitStatus = curProc.status;
1088 oTest.iExitCode = curProc.exitCode;
1089 reporter.log2('Process (PID %ld) has exit code: %ld' % (curProc.PID, oTest.iExitCode));
1090 except KeyboardInterrupt:
1091 reporter.error('Process (PID %ld) execution interrupted' % (curProc.PID,));
1092 if curProc is not None:
1093 curProc.close();
1094 except:
1095 # Just log, don't assume an error here (will be done in the main loop then).
1096 reporter.logXcpt('Execution exception for command "%s":' % (oTest.sCmd,));
1097 fRc = False;
1098
1099 return fRc;
1100
1101 def testGuestCtrlSessionEnvironment(self, oSession, oTxsSession, oTestVm): # pylint: disable=R0914
1102 """
1103 Tests the guest session environment changes.
1104 """
1105
1106 if oTestVm.isWindows():
1107 sUser = "Administrator";
1108 else:
1109 sUser = "vbox";
1110 sPassword = "password";
1111
1112 aaTests = [
1113 # No environment set.
1114 [ tdTestSessionEnv(sUser = sUser, sPassword = sPassword),
1115 tdTestResultSessionEnv(fRc = False) ],
1116 # Invalid stuff.
1117 [ tdTestSessionEnv(sUser = sUser, sPassword = sPassword, aEnv = [ '=FOO' ]),
1118 tdTestResultSessionEnv(fRc = False) ],
1119 [ tdTestSessionEnv(sUser = sUser, sPassword = sPassword, aEnv = [ '====' ]),
1120 tdTestResultSessionEnv(fRc = False) ],
1121 [ tdTestSessionEnv(sUser = sUser, sPassword = sPassword, aEnv = [ '=BAR' ]),
1122 tdTestResultSessionEnv(fRc = False) ],
1123 [ tdTestSessionEnv(sUser = sUser, sPassword = sPassword, aEnv = [ u'ß$%ß&' ]),
1124 tdTestResultSessionEnv(fRc = False) ],
1125 # Key only.
1126 [ tdTestSessionEnv(sUser = sUser, sPassword = sPassword, aEnv = [ 'FOO=' ]),
1127 tdTestResultSessionEnv(fRc = True, cNumVars = 1) ],
1128 # Values.
1129 [ tdTestSessionEnv(sUser = sUser, sPassword = sPassword, aEnv = [ 'FOO' ]),
1130 tdTestResultSessionEnv(fRc = True, cNumVars = 1) ],
1131 [ tdTestSessionEnv(sUser = sUser, sPassword = sPassword, aEnv = [ 'FOO=BAR' ]),
1132 tdTestResultSessionEnv(fRc = True, cNumVars = 1) ],
1133 [ tdTestSessionEnv(sUser = sUser, sPassword = sPassword, aEnv = [ 'FOO=BAR', 'BAR=BAZ' ]),
1134 tdTestResultSessionEnv(fRc = True, cNumVars = 2) ],
1135 # A bit more weird keys/values.
1136 [ tdTestSessionEnv(sUser = sUser, sPassword = sPassword, aEnv = [ '$$$=' ]),
1137 tdTestResultSessionEnv(fRc = True, cNumVars = 1) ],
1138 [ tdTestSessionEnv(sUser = sUser, sPassword = sPassword, aEnv = [ '$$$=%%%' ]),
1139 tdTestResultSessionEnv(fRc = True, cNumVars = 1) ],
1140 # Same stuff.
1141 [ tdTestSessionEnv(sUser = sUser, sPassword = sPassword, aEnv = [ 'FOO=BAR', 'FOO=BAR' ]),
1142 tdTestResultSessionEnv(fRc = True, cNumVars = 1) ]
1143 ];
1144
1145 # The IGuestSession::environment attribute changed late in 5.0 development.
1146 sEnvironmentChangesAttr = 'environmentChanges' if self.oTstDrv.fpApiVer >= 5.0 else 'environment';
1147
1148 # Parameters.
1149 fRc = True;
1150 for (i, aTest) in enumerate(aaTests):
1151 curTest = aTest[0]; # tdTestExec, use an index, later.
1152 curRes = aTest[1]; # tdTestResult
1153 curTest.setEnvironment(oSession, oTxsSession, oTestVm);
1154 reporter.log('Testing #%d, user="%s", sPassword="%s", env="%s" (%d)...' \
1155 % (i, curTest.oCreds.sUser, curTest.oCreds.sPassword, curTest.aEnv, len(curTest.aEnv)));
1156 curGuestSessionName = 'testGuestCtrlSessionEnvironment: Test #%d' % (i,);
1157 fRc2, curGuestSession = curTest.createSession(curGuestSessionName);
1158 if fRc2 is not True:
1159 reporter.error('Test #%d failed: Session creation failed: Got %s, expected True' % (i, fRc2));
1160 fRc = False;
1161 break;
1162 # Make sure environment is empty.
1163 curEnv = self.oTstDrv.oVBoxMgr.getArray(curGuestSession, sEnvironmentChangesAttr);
1164 reporter.log2('Test #%d: Environment initially has %d elements' % (i, len(curEnv)));
1165 if len(curEnv) != 0:
1166 reporter.error('Test #%d failed: Initial session environment has %d vars, expected 0' % (i, len(curEnv)));
1167 fRc = False;
1168 break;
1169 try:
1170 for (_, aEnv) in enumerate(curTest.aEnv):
1171 aElems = aEnv.split('=');
1172 strKey = ''; ## @todo s/Key/Var/g
1173 strValue = '';
1174 if len(aElems) > 0:
1175 strKey = aElems[0];
1176 if len(aElems) == 2:
1177 strValue = aElems[1];
1178 reporter.log2('Test #%d: Single var="%s", value="%s" (%d) ...' \
1179 % (i, strKey, strValue, len(aElems)));
1180 try:
1181 if self.oTstDrv.fpApiVer >= 5.0:
1182 curGuestSession.environmentScheduleSet(strKey, strValue);
1183 else:
1184 curGuestSession.environmentSet(strKey, strValue);
1185 except:
1186 # Setting environment variables might fail (e.g. if empty name specified). Check.
1187 reporter.logXcpt('Test #%d failed: Setting environment variable failed:' % (i,));
1188 curEnv = self.oTstDrv.oVBoxMgr.getArray(curGuestSession, sEnvironmentChangesAttr);
1189 if len(curEnv) is not curRes.cNumVars:
1190 reporter.error('Test #%d failed: Session environment has %d vars, expected %d' \
1191 % (i, len(curEnv), curRes.cNumVars));
1192 fRc = False;
1193 break;
1194 else:
1195 reporter.log('Test #%d: API reported an error (single), good' % (i,));
1196 ## @todo environmentGet() has been removed in 5.0 because it's not up to the task of returning all the
1197 ## putenv strings forms and gives the impression that the environment is something it isn't. This test
1198 ## should be rewritten using the attribute. What's more, there should be an Unset test here, shouldn't
1199 ## there?
1200 #
1201 #reporter.log2('Getting key="%s" ...' % (strKey,));
1202 #try:
1203 # strValue2 = curGuestSession.environmentGet(strKey);
1204 # if strKey.isalnum() \
1205 # and strValue != strValue2:
1206 # reporter.error('Test #%d failed: Got environment value "%s", expected "%s" (var: "%s")' \
1207 # % (i, strValue2, strValue, strKey));
1208 # fRc = False;
1209 # break;
1210 # # Getting back an empty value when specifying an invalid key is fine.
1211 # reporter.log2('Got key "%s=%s"' % (strKey, strValue2));
1212 #except UnicodeDecodeError: # Might happen on unusal values, fine.
1213 # if strValue != strValue2:
1214 # reporter.error('Test #%d failed: Got (undecoded) environment variable "%s", ' \
1215 # 'expected "%s" (var: "%s")' \
1216 # % (i, strValue2, strValue, strKey));
1217 # fRc = False;
1218 # break;
1219 #except:
1220 # if strKey == "" \
1221 # or not strKey.isalnum():
1222 # reporter.log('Test #%d: API reported an error (invalid key "%s"), good' % (i, strKey));
1223 # else:
1224 # reporter.errorXcpt('Test #%d failed: Getting environment variable:' % (i));
1225 if fRc is False:
1226 continue;
1227 # Set the same stuff again, this time all at once using the array.
1228 if len(curTest.aEnv):
1229 reporter.log('Test #%d: Array %s (%d)' % (i, curTest.aEnv, len(curTest.aEnv)));
1230 try:
1231 ## @todo No return (e.g. boolean) value available thru wrapper.
1232 #curGuestSession.environmentSetArray(curTest.aEnv);
1233 pass;
1234 except:
1235 # Setting environment variables might fail (e.g. if empty name specified). Check.
1236 curEnv = self.oTstDrv.oVBoxMgr.getArray(curGuestSession, sEnvironmentChangesAttr);
1237 if len(curEnv) is not curRes.cNumVars:
1238 reporter.error('Test #%d failed: Session environment has %d vars, expected %d (array)' \
1239 % (i, len(curEnv), curRes.cNumVars));
1240 fRc = False;
1241 break;
1242 else:
1243 reporter.log('Test #%d: API reported an error (array), good' % (i,));
1244 ## @todo Get current system environment and add it to curRes.cNumVars before comparing!
1245 reporter.log('Test #%d: Environment size' % (i,));
1246 curEnv = self.oTstDrv.oVBoxMgr.getArray(curGuestSession, sEnvironmentChangesAttr);
1247 reporter.log2('Test #%d: Environment (%d) -> %s' % (i, len(curEnv), curEnv));
1248 if len(curEnv) != curRes.cNumVars:
1249 reporter.error('Test #%d failed: Session environment has %d vars (%s), expected %d' \
1250 % (i, len(curEnv), curEnv, curRes.cNumVars));
1251 fRc = False;
1252 break;
1253
1254 self.oTstDrv.oVBoxMgr.setArray(curGuestSession, sEnvironmentChangesAttr, []);
1255 curEnv = self.oTstDrv.oVBoxMgr.getArray(curGuestSession, sEnvironmentChangesAttr);
1256 if len(curEnv) is not 0:
1257 reporter.error('Test #%d failed: Session environment has %d vars, expected 0');
1258 fRc = False;
1259 break;
1260 except:
1261 reporter.errorXcpt('Test #%d failed:' % (i,));
1262
1263 fRc2 = curTest.closeSession();
1264 if fRc2 is False:
1265 reporter.error('Test #%d failed: Session could not be closed' % (i,));
1266 fRc = False;
1267 break;
1268
1269 return (fRc, oTxsSession);
1270
1271 def testGuestCtrlSession(self, oSession, oTxsSession, oTestVm): # pylint: disable=R0914
1272 """
1273 Tests the guest session handling.
1274 """
1275
1276 if oTestVm.isWindows():
1277 sUser = "Administrator";
1278 else:
1279 sUser = "vbox";
1280 sPassword = "password";
1281
1282 aaTests = [
1283 # Invalid parameters.
1284 [ tdTestSession(),
1285 tdTestResultSession(fRc = False) ],
1286 [ tdTestSession(sUser = ''),
1287 tdTestResultSession(fRc = False) ],
1288 [ tdTestSession(sPassword = 'bar'),
1289 tdTestResultSession(fRc = False) ],
1290 [ tdTestSession(sDomain = 'boo'),
1291 tdTestResultSession(fRc = False) ],
1292 [ tdTestSession(sPassword = 'bar', sDomain = 'boo'),
1293 tdTestResultSession(fRc = False) ],
1294 # User account without a passwort - forbidden.
1295 [ tdTestSession(sUser = sUser),
1296 tdTestResultSession(fRc = False) ],
1297 # Wrong credentials.
1298 # Note: On Guest Additions < 4.3 this always succeeds because these don't
1299 # support creating dedicated sessions. Instead, guest process creation
1300 # then will fail. See note below.
1301 [ tdTestSession(sUser = 'foo', sPassword = 'bar', sDomain = 'boo'),
1302 tdTestResultSession(fRc = False) ],
1303 # Correct credentials.
1304 [ tdTestSession(sUser = sUser, sPassword = sPassword),
1305 tdTestResultSession(fRc = True, cNumSessions = 1) ]
1306 ];
1307
1308 # Parameters.
1309 fRc = True;
1310 for (i, aTest) in enumerate(aaTests):
1311 curTest = aTest[0]; # tdTestSession, use an index, later.
1312 curRes = aTest[1]; # tdTestResult
1313 curTest.setEnvironment(oSession, oTxsSession, oTestVm);
1314 reporter.log('Testing #%d, user="%s", sPassword="%s", sDomain="%s" ...' \
1315 % (i, curTest.oCreds.sUser, curTest.oCreds.sPassword, curTest.oCreds.sDomain));
1316 curGuestSessionName = 'testGuestCtrlSession: Test #%d' % (i);
1317 fRc2, curGuestSession = curTest.createSession(curGuestSessionName);
1318 # See note about < 4.3 Guest Additions above.
1319 if curGuestSession is not None \
1320 and curGuestSession.protocolVersion >= 2 \
1321 and fRc2 is not curRes.fRc:
1322 reporter.error('Test #%d failed: Session creation failed: Got %s, expected %s' \
1323 % (i, fRc2, curRes.fRc));
1324 fRc = False;
1325 if fRc2:
1326 # On Guest Additions < 4.3 getSessionCount() always will return 1, so skip the
1327 # check then.
1328 if curGuestSession.protocolVersion >= 2:
1329 curSessionCount = curTest.getSessionCount(self.oTstDrv.oVBoxMgr);
1330 if curSessionCount is not curRes.cNumSessions:
1331 reporter.error('Test #%d failed: Session count does not match: Got %d, expected %d' \
1332 % (i, curSessionCount, curRes.cNumSessions));
1333 fRc = False;
1334 break;
1335 if curGuestSession is not None \
1336 and curGuestSession.name != curGuestSessionName:
1337 reporter.error('Test #%d failed: Session name does not match: Got "%s", expected "%s"' \
1338 % (i, curGuestSession.name, curGuestSessionName));
1339 fRc = False;
1340 break;
1341 fRc2 = curTest.closeSession();
1342 if fRc2 is False:
1343 reporter.error('Test #%d failed: Session could not be closed' % (i,));
1344 fRc = False;
1345 break;
1346
1347 if fRc is False:
1348 return (False, oTxsSession);
1349
1350 # Multiple sessions.
1351 iMaxGuestSessions = 31; # Maximum number of concurrent guest session allowed.
1352 # Actually, this is 32, but we don't test session 0.
1353 multiSession = {};
1354 reporter.log2('Opening multiple guest tsessions at once ...');
1355 for i in range(iMaxGuestSessions + 1):
1356 multiSession[i] = tdTestSession(sUser = sUser, sPassword = sPassword, sSessionName = 'MultiSession #%d' % (i,));
1357 multiSession[i].setEnvironment(oSession, oTxsSession, oTestVm);
1358 curSessionCount = multiSession[i].getSessionCount(self.oTstDrv.oVBoxMgr);
1359 reporter.log2('MultiSession test #%d count is %d' % (i, curSessionCount));
1360 if curSessionCount is not i:
1361 reporter.error('MultiSession count #%d must be %d, got %d' % (i, i, curSessionCount));
1362 fRc = False;
1363 break;
1364 fRc2, _ = multiSession[i].createSession('MultiSession #%d' % (i,));
1365 if fRc2 is not True:
1366 if i < iMaxGuestSessions:
1367 reporter.error('MultiSession #%d test failed' % (i,));
1368 fRc = False;
1369 else:
1370 reporter.log('MultiSession #%d exceeded concurrent guest session count, good' % (i,));
1371 break;
1372
1373 curSessionCount = multiSession[i].getSessionCount(self.oTstDrv.oVBoxMgr);
1374 if curSessionCount is not iMaxGuestSessions:
1375 reporter.error('Final MultiSession count must be %d, got %d'
1376 % (iMaxGuestSessions, curSessionCount));
1377 return (False, oTxsSession);
1378
1379 reporter.log2('Closing MultiSessions ...');
1380 iLastSession = iMaxGuestSessions - 1;
1381 for i in range(iLastSession): # Close all but the last opened session.
1382 fRc2 = multiSession[i].closeSession();
1383 reporter.log2('MultiSession #%d count is %d' % (i, multiSession[i].getSessionCount(self.oTstDrv.oVBoxMgr),));
1384 if fRc2 is False:
1385 reporter.error('Closing MultiSession #%d failed' % (i,));
1386 fRc = False;
1387 break;
1388 curSessionCount = multiSession[i].getSessionCount(self.oTstDrv.oVBoxMgr);
1389 if curSessionCount is not 1:
1390 reporter.error('Final MultiSession count #2 must be 1, got %d' % (curSessionCount,));
1391 fRc = False;
1392
1393 try:
1394 # Make sure that accessing the first opened guest session does not work anymore because we just removed (closed) it.
1395 curSessionName = multiSession[0].oGuestSession.name;
1396 reporter.error('Accessing first removed MultiSession should not be possible, got name="%s"' % (curSessionName,));
1397 fRc = False;
1398 except:
1399 reporter.logXcpt('Could not access first removed MultiSession object, good:');
1400
1401 try:
1402 # Try Accessing last opened session which did not get removed yet.
1403 curSessionName = multiSession[iLastSession].oGuestSession.name;
1404 reporter.log('Accessing last standing MultiSession worked, got name="%s"' % (curSessionName,));
1405 multiSession[iLastSession].closeSession();
1406 curSessionCount = multiSession[i].getSessionCount(self.oTstDrv.oVBoxMgr);
1407 if curSessionCount is not 0:
1408 reporter.error('Final MultiSession count #3 must be 0, got %d' % (curSessionCount,));
1409 fRc = False;
1410 except:
1411 reporter.logXcpt('Could not access last standing MultiSession object:');
1412 fRc = False;
1413
1414 ## @todo Test session timeouts.
1415
1416 return (fRc, oTxsSession);
1417
1418 def testGuestCtrlSessionFileRefs(self, oSession, oTxsSession, oTestVm): # pylint: disable=R0914
1419 """
1420 Tests the guest session file reference handling.
1421 """
1422
1423 if oTestVm.isWindows():
1424 sUser = "Administrator";
1425 sPassword = "password";
1426 sDomain = "";
1427 sFile = "C:\\windows\\system32\\kernel32.dll";
1428
1429 # Number of stale guest files to create.
1430 cStaleFiles = 10;
1431
1432 fRc = True;
1433 try:
1434 oGuest = oSession.o.console.guest;
1435 oGuestSession = oGuest.createSession(sUser, sPassword, sDomain, \
1436 "testGuestCtrlSessionFileRefs");
1437 fWaitFor = [ vboxcon.GuestSessionWaitForFlag_Start ];
1438 waitResult = oGuestSession.waitForArray(fWaitFor, 30 * 1000);
1439 #
1440 # Be nice to Guest Additions < 4.3: They don't support session handling and
1441 # therefore return WaitFlagNotSupported.
1442 #
1443 if waitResult != vboxcon.GuestSessionWaitResult_Start \
1444 and waitResult != vboxcon.GuestSessionWaitResult_WaitFlagNotSupported:
1445 # Just log, don't assume an error here (will be done in the main loop then).
1446 reporter.log('Session did not start successfully, returned wait result: %ld' \
1447 % (waitResult));
1448 return (False, oTxsSession);
1449 reporter.log('Session successfully started');
1450
1451 #
1452 # Open guest files and "forget" them (stale entries).
1453 # For them we don't have any references anymore intentionally.
1454 #
1455 reporter.log2('Opening stale files');
1456 for i in range(0, cStaleFiles):
1457 try:
1458 if self.oTstDrv.fpApiVer >= 5.0:
1459 oGuestSession.fileOpen(sFile, vboxcon.FileAccessMode_ReadOnly, vboxcon.FileOpenAction_OpenExisting, 0);
1460 else:
1461 oGuestSession.fileOpen(sFile, "r", "oe", 0);
1462 # Note: Use a timeout in the call above for not letting the stale processes
1463 # hanging around forever. This can happen if the installed Guest Additions
1464 # do not support terminating guest processes.
1465 except:
1466 reporter.errorXcpt('Opening stale file #%ld failed:' % (i,));
1467 fRc = False;
1468 break;
1469
1470 if fRc:
1471 cFiles = len(self.oTstDrv.oVBoxMgr.getArray(oGuestSession, 'files'));
1472 if cFiles != cStaleFiles:
1473 reporter.error('Test failed: Got %ld stale files, expected %ld' % (cFiles, cStaleFiles));
1474 fRc = False;
1475
1476 if fRc:
1477 #
1478 # Open non-stale files and close them again.
1479 #
1480 reporter.log2('Opening non-stale files');
1481 aaFiles = [];
1482 for i in range(0, cStaleFiles):
1483 try:
1484 if self.oTstDrv.fpApiVer >= 5.0:
1485 oCurFile = oGuestSession.fileOpen(sFile, vboxcon.FileAccessMode_ReadOnly,
1486 vboxcon.FileOpenAction_OpenExisting, 0);
1487 else:
1488 oCurFile = oGuestSession.fileOpen(sFile, "r", "oe", 0);
1489 aaFiles.append(oCurFile);
1490 except:
1491 reporter.errorXcpt('Opening non-stale file #%ld failed:' % (i,));
1492 fRc = False;
1493 break;
1494 if fRc:
1495 cFiles = len(self.oTstDrv.oVBoxMgr.getArray(oGuestSession, 'files'));
1496 if cFiles != cStaleFiles * 2:
1497 reporter.error('Test failed: Got %ld total files, expected %ld' % (cFiles, cStaleFiles * 2));
1498 fRc = False;
1499 if fRc:
1500 reporter.log2('Closing all non-stale files again ...');
1501 for i in range(0, cStaleFiles):
1502 try:
1503 aaFiles[i].close();
1504 except:
1505 reporter.errorXcpt('Waiting for non-stale file #%ld failed:' % (i,));
1506 fRc = False;
1507 break;
1508 cFiles = len(self.oTstDrv.oVBoxMgr.getArray(oGuestSession, 'files'));
1509 # Here we count the stale files (that is, files we don't have a reference
1510 # anymore for) and the opened and then closed non-stale files (that we still keep
1511 # a reference in aaFiles[] for).
1512 if cFiles != cStaleFiles:
1513 reporter.error('Test failed: Got %ld total files, expected %ld' \
1514 % (cFiles, cStaleFiles));
1515 fRc = False;
1516 if fRc:
1517 #
1518 # Check if all (referenced) non-stale files now are in "closed" state.
1519 #
1520 reporter.log2('Checking statuses of all non-stale files ...');
1521 for i in range(0, cStaleFiles):
1522 try:
1523 curFilesStatus = aaFiles[i].status;
1524 if curFilesStatus != vboxcon.FileStatus_Closed:
1525 reporter.error('Test failed: Non-stale file #%ld has status %ld, expected %ld' \
1526 % (i, curFilesStatus, vboxcon.FileStatus_Closed));
1527 fRc = False;
1528 except:
1529 reporter.errorXcpt('Checking status of file #%ld failed:' % (i,));
1530 fRc = False;
1531 break;
1532 if fRc:
1533 reporter.log2('All non-stale files closed');
1534 cFiles = len(self.oTstDrv.oVBoxMgr.getArray(oGuestSession, 'files'));
1535 reporter.log2('Final guest session file count: %ld' % (cFiles,));
1536 # Now try to close the session and see what happens.
1537 reporter.log2('Closing guest session ...');
1538 oGuestSession.close();
1539 except:
1540 reporter.errorXcpt('Testing for stale processes failed:');
1541 fRc = False;
1542
1543 return (fRc, oTxsSession);
1544
1545 #def testGuestCtrlSessionDirRefs(self, oSession, oTxsSession, oTestVm):
1546 # """
1547 # Tests the guest session directory reference handling.
1548 # """
1549
1550 # fRc = True;
1551 # return (fRc, oTxsSession);
1552
1553 def testGuestCtrlSessionProcRefs(self, oSession, oTxsSession, oTestVm): # pylint: disable=R0914
1554 """
1555 Tests the guest session process reference handling.
1556 """
1557
1558 if oTestVm.isWindows():
1559 sUser = "Administrator";
1560 sPassword = "password";
1561 sDomain = "";
1562 sCmd = "C:\\windows\\system32\\cmd.exe";
1563 aArgs = [sCmd,];
1564
1565 # Number of stale guest processes to create.
1566 cStaleProcs = 10;
1567
1568 fRc = True;
1569 try:
1570 oGuest = oSession.o.console.guest;
1571 oGuestSession = oGuest.createSession(sUser, sPassword, sDomain, \
1572 "testGuestCtrlSessionProcRefs");
1573 fWaitFor = [ vboxcon.GuestSessionWaitForFlag_Start ];
1574 waitResult = oGuestSession.waitForArray(fWaitFor, 30 * 1000);
1575 #
1576 # Be nice to Guest Additions < 4.3: They don't support session handling and
1577 # therefore return WaitFlagNotSupported.
1578 #
1579 if waitResult != vboxcon.GuestSessionWaitResult_Start \
1580 and waitResult != vboxcon.GuestSessionWaitResult_WaitFlagNotSupported:
1581 # Just log, don't assume an error here (will be done in the main loop then).
1582 reporter.log('Session did not start successfully, returned wait result: %ld' \
1583 % (waitResult));
1584 return (False, oTxsSession);
1585 reporter.log('Session successfully started');
1586
1587 #
1588 # Fire off forever-running processes and "forget" them (stale entries).
1589 # For them we don't have any references anymore intentionally.
1590 #
1591 reporter.log2('Starting stale processes');
1592 for i in range(0, cStaleProcs):
1593 try:
1594 oGuestSession.processCreate(sCmd,
1595 aArgs if self.oTstDrv.fpApiVer >= 5.0 else aArgs[1:], [],
1596 [ vboxcon.ProcessCreateFlag_WaitForStdOut ], \
1597 30 * 1000);
1598 # Note: Use a timeout in the call above for not letting the stale processes
1599 # hanging around forever. This can happen if the installed Guest Additions
1600 # do not support terminating guest processes.
1601 except:
1602 reporter.logXcpt('Creating stale process #%ld failed:' % (i,));
1603 fRc = False;
1604 break;
1605
1606 if fRc:
1607 cProcs = len(self.oTstDrv.oVBoxMgr.getArray(oGuestSession, 'processes'));
1608 if cProcs != cStaleProcs:
1609 reporter.error('Test failed: Got %ld stale processes, expected %ld' % (cProcs, cStaleProcs));
1610 fRc = False;
1611
1612 if fRc:
1613 #
1614 # Fire off non-stale processes and wait for termination.
1615 #
1616 if oTestVm.isWindows():
1617 aArgs = [ sCmd, '/C', 'dir', '/S', 'C:\\Windows\\system'];
1618 reporter.log2('Starting non-stale processes');
1619 aaProcs = [];
1620 for i in range(0, cStaleProcs):
1621 try:
1622 oCurProc = oGuestSession.processCreate(sCmd, aArgs if self.oTstDrv.fpApiVer >= 5.0 else aArgs[1:],
1623 [], [], 0); # Infinite timeout.
1624 aaProcs.append(oCurProc);
1625 except:
1626 reporter.logXcpt('Creating non-stale process #%ld failed:' % (i,));
1627 fRc = False;
1628 break;
1629 if fRc:
1630 reporter.log2('Waiting for non-stale processes to terminate');
1631 for i in range(0, cStaleProcs):
1632 try:
1633 aaProcs[i].waitForArray([ vboxcon.ProcessWaitForFlag_Terminate ], 30 * 1000);
1634 curProcStatus = aaProcs[i].status;
1635 if aaProcs[i].status != vboxcon.ProcessStatus_TerminatedNormally:
1636 reporter.error('Test failed: Waiting for non-stale processes #%ld'
1637 ' resulted in status %ld, expected %ld' \
1638 % (i, curProcStatus, vboxcon.ProcessStatus_TerminatedNormally));
1639 fRc = False;
1640 except:
1641 reporter.logXcpt('Waiting for non-stale process #%ld failed:' % (i,));
1642 fRc = False;
1643 break;
1644 cProcs = len(self.oTstDrv.oVBoxMgr.getArray(oGuestSession, 'processes'));
1645 # Here we count the stale processes (that is, processes we don't have a reference
1646 # anymore for) and the started + terminated non-stale processes (that we still keep
1647 # a reference in aaProcs[] for).
1648 if cProcs != (cStaleProcs * 2):
1649 reporter.error('Test failed: Got %ld total processes, expected %ld' \
1650 % (cProcs, cStaleProcs));
1651 fRc = False;
1652 if fRc:
1653 #
1654 # Check if all (referenced) non-stale processes now are in "terminated" state.
1655 #
1656 for i in range(0, cStaleProcs):
1657 curProcStatus = aaProcs[i].status;
1658 if aaProcs[i].status != vboxcon.ProcessStatus_TerminatedNormally:
1659 reporter.error('Test failed: Non-stale processes #%ld has status %ld, expected %ld' \
1660 % (i, curProcStatus, vboxcon.ProcessStatus_TerminatedNormally));
1661 fRc = False;
1662 if fRc:
1663 reporter.log2('All non-stale processes terminated');
1664
1665 # Fire off blocking processes which are terminated via terminate().
1666 if oTestVm.isWindows():
1667 aArgs = [ sCmd, '/C', 'dir', '/S', 'C:\\Windows'];
1668 reporter.log2('Starting blocking processes');
1669 aaProcs = [];
1670 for i in range(0, cStaleProcs):
1671 try:
1672 oCurProc = oGuestSession.processCreate(sCmd, aArgs if self.oTstDrv.fpApiVer >= 5.0 else aArgs[1:],
1673 [], [], 30 * 1000);
1674 # Note: Use a timeout in the call above for not letting the stale processes
1675 # hanging around forever. This can happen if the installed Guest Additions
1676 # do not support terminating guest processes.
1677 aaProcs.append(oCurProc);
1678 except:
1679 reporter.logXcpt('Creating blocking process failed:');
1680 fRc = False;
1681 break;
1682 if fRc:
1683 reporter.log2('Terminating blocking processes');
1684 for i in range(0, cStaleProcs):
1685 try:
1686 aaProcs[i].terminate();
1687 except: # Termination might not be supported, just skip and log it.
1688 reporter.logXcpt('Termination of blocking process failed, skipped:');
1689 cProcs = len(self.oTstDrv.oVBoxMgr.getArray(oGuestSession, 'processes'));
1690 if cProcs != (cStaleProcs * 2): # Still should be 20 processes because we terminated the 10 newest ones.
1691 reporter.error('Test failed: Got %ld total processes, expected %ld' % (cProcs, cStaleProcs * 2));
1692 fRc = False;
1693 cProcs = len(self.oTstDrv.oVBoxMgr.getArray(oGuestSession, 'processes'));
1694 reporter.log2('Final guest session processes count: %ld' % (cProcs,));
1695 # Now try to close the session and see what happens.
1696 reporter.log2('Closing guest session ...');
1697 oGuestSession.close();
1698 except:
1699 reporter.logXcpt('Testing for stale processes failed:');
1700 fRc = False;
1701
1702 return (fRc, oTxsSession);
1703
1704 def testGuestCtrlExec(self, oSession, oTxsSession, oTestVm): # pylint: disable=R0914,R0915
1705 """
1706 Tests the basic execution feature.
1707 """
1708
1709 if oTestVm.isWindows():
1710 sUser = "Administrator";
1711 else:
1712 sUser = "vbox";
1713 sPassword = "password";
1714
1715 if oTestVm.isWindows():
1716 # Outputting stuff.
1717 sImageOut = "C:\\windows\\system32\\cmd.exe";
1718 else:
1719 reporter.error('Implement me!'); ## @todo Implement non-Windows bits.
1720 return (False, oTxsSession);
1721
1722 aaInvalid = [
1723 # Invalid parameters.
1724 [ tdTestExec(sUser = sUser, sPassword = sPassword),
1725 tdTestResultExec(fRc = False) ],
1726 # Non-existent / invalid image.
1727 [ tdTestExec(sCmd = "non-existent", sUser = sUser, sPassword = sPassword),
1728 tdTestResultExec(fRc = False) ],
1729 [ tdTestExec(sCmd = "non-existent2", sUser = sUser, sPassword = sPassword, fWaitForExit = True),
1730 tdTestResultExec(fRc = False) ],
1731 # Use an invalid format string.
1732 [ tdTestExec(sCmd = "%$%%%&", sUser = sUser, sPassword = sPassword),
1733 tdTestResultExec(fRc = False) ],
1734 # More stuff.
1735 [ tdTestExec(sCmd = "ƒ‰‹ˆ÷‹¸", sUser = sUser, sPassword = sPassword),
1736 tdTestResultExec(fRc = False) ],
1737 [ tdTestExec(sCmd = "???://!!!", sUser = sUser, sPassword = sPassword),
1738 tdTestResultExec(fRc = False) ],
1739 [ tdTestExec(sCmd = "<>!\\", sUser = sUser, sPassword = sPassword),
1740 tdTestResultExec(fRc = False) ]
1741 # Enable as soon as ERROR_BAD_DEVICE is implemented.
1742 #[ tdTestExec(sCmd = "CON", sUser = sUser, sPassword = sPassword),
1743 # tdTestResultExec(fRc = False) ]
1744 ];
1745
1746 if oTestVm.isWindows():
1747 sVBoxControl = "C:\\Program Files\\Oracle\\VirtualBox Guest Additions\\VBoxControl.exe";
1748 aaExec = [
1749 # Basic executon.
1750 [ tdTestExec(sCmd = sImageOut, aArgs = [ sImageOut, '/C', 'dir', '/S', 'c:\\windows\\system32' ],
1751 sUser = sUser, sPassword = sPassword),
1752 tdTestResultExec(fRc = True) ],
1753 [ tdTestExec(sCmd = sImageOut, aArgs = [ sImageOut, '/C', 'dir', '/S', 'c:\\windows\\system32\\kernel32.dll' ],
1754 sUser = sUser, sPassword = sPassword),
1755 tdTestResultExec(fRc = True) ],
1756 [ tdTestExec(sCmd = sImageOut, aArgs = [ sImageOut, '/C', 'dir', '/S', 'c:\\windows\\system32\\nonexist.dll' ],
1757 sUser = sUser, sPassword = sPassword),
1758 tdTestResultExec(fRc = True, iExitCode = 1) ],
1759 [ tdTestExec(sCmd = sImageOut, aArgs = [ sImageOut, '/C', 'dir', '/S', '/wrongparam' ],
1760 sUser = sUser, sPassword = sPassword),
1761 tdTestResultExec(fRc = True, iExitCode = 1) ],
1762 # Paths with spaces.
1763 ## @todo Get path of installed Guest Additions. Later.
1764 [ tdTestExec(sCmd = sVBoxControl, aArgs = [ sVBoxControl, 'version' ],
1765 sUser = sUser, sPassword = sPassword),
1766 tdTestResultExec(fRc = True) ],
1767 # StdOut.
1768 [ tdTestExec(sCmd = sImageOut, aArgs = [ sImageOut, '/C', 'dir', '/S', 'c:\\windows\\system32' ],
1769 sUser = sUser, sPassword = sPassword),
1770 tdTestResultExec(fRc = True) ],
1771 [ tdTestExec(sCmd = sImageOut, aArgs = [ sImageOut, '/C', 'dir', '/S', 'stdout-non-existing' ],
1772 sUser = sUser, sPassword = sPassword),
1773 tdTestResultExec(fRc = True, iExitCode = 1) ],
1774 # StdErr.
1775 [ tdTestExec(sCmd = sImageOut, aArgs = [ sImageOut, '/C', 'dir', '/S', 'c:\\windows\\system32' ],
1776 sUser = sUser, sPassword = sPassword),
1777 tdTestResultExec(fRc = True) ],
1778 [ tdTestExec(sCmd = sImageOut, aArgs = [ sImageOut, '/C', 'dir', '/S', 'stderr-non-existing' ],
1779 sUser = sUser, sPassword = sPassword),
1780 tdTestResultExec(fRc = True, iExitCode = 1) ],
1781 # StdOut + StdErr.
1782 [ tdTestExec(sCmd = sImageOut, aArgs = [ sImageOut, '/C', 'dir', '/S', 'c:\\windows\\system32' ],
1783 sUser = sUser, sPassword = sPassword),
1784 tdTestResultExec(fRc = True) ],
1785 [ tdTestExec(sCmd = sImageOut, aArgs = [ sImageOut, '/C', 'dir', '/S', 'stdouterr-non-existing' ],
1786 sUser = sUser, sPassword = sPassword),
1787 tdTestResultExec(fRc = True, iExitCode = 1) ]
1788 # FIXME: Failing tests.
1789 # Environment variables.
1790 # [ tdTestExec(sCmd = sImageOut, aArgs = [ sImageOut, '/C', 'set', 'TEST_NONEXIST' ],
1791 # sUser = sUser, sPassword = sPassword),
1792 # tdTestResultExec(fRc = True, iExitCode = 1) ]
1793 # [ tdTestExec(sCmd = sImageOut, aArgs = [ sImageOut, '/C', 'set', 'windir' ],
1794 # sUser = sUser, sPassword = sPassword,
1795 # aFlags = [ vboxcon.ProcessCreateFlag_WaitForStdOut, vboxcon.ProcessCreateFlag_WaitForStdErr ]),
1796 # tdTestResultExec(fRc = True, sBuf = 'windir=C:\\WINDOWS\r\n') ],
1797 # [ tdTestExec(sCmd = sImageOut, aArgs = [ sImageOut, '/C', 'set', 'TEST_FOO' ],
1798 # sUser = sUser, sPassword = sPassword,
1799 # aEnv = [ 'TEST_FOO=BAR' ],
1800 # aFlags = [ vboxcon.ProcessCreateFlag_WaitForStdOut, vboxcon.ProcessCreateFlag_WaitForStdErr ]),
1801 # tdTestResultExec(fRc = True, sBuf = 'TEST_FOO=BAR\r\n') ],
1802 # [ tdTestExec(sCmd = sImageOut, aArgs = [ sImageOut, '/C', 'set', 'TEST_FOO' ],
1803 # sUser = sUser, sPassword = sPassword,
1804 # aEnv = [ 'TEST_FOO=BAR', 'TEST_BAZ=BAR' ],
1805 # aFlags = [ vboxcon.ProcessCreateFlag_WaitForStdOut, vboxcon.ProcessCreateFlag_WaitForStdErr ]),
1806 # tdTestResultExec(fRc = True, sBuf = 'TEST_FOO=BAR\r\n') ]
1807
1808 ## @todo Create some files (or get files) we know the output size of to validate output length!
1809 ## @todo Add task which gets killed at some random time while letting the guest output something.
1810 ];
1811
1812 # Manual test, not executed automatically.
1813 aaManual = [
1814 [ tdTestExec(sCmd = sImageOut, aArgs = [ sImageOut, '/C', 'dir /S C:\\Windows' ],
1815 sUser = sUser, sPassword = sPassword,
1816 aFlags = [ vboxcon.ProcessCreateFlag_WaitForStdOut, vboxcon.ProcessCreateFlag_WaitForStdErr ]),
1817 tdTestResultExec(fRc = True, cbStdOut = 497917) ] ];
1818 else:
1819 reporter.log('No OS-specific tests for non-Windows yet!');
1820
1821 # Build up the final test array for the first batch.
1822 aaTests = [];
1823 aaTests.extend(aaInvalid);
1824 if aaExec is not None:
1825 aaTests.extend(aaExec);
1826 fRc = True;
1827
1828 #
1829 # Single execution stuff. Nice for debugging.
1830 #
1831 fManual = False;
1832 if fManual:
1833 curTest = aaTests[1][0]; # tdTestExec, use an index, later.
1834 curRes = aaTests[1][1]; # tdTestResultExec
1835 curTest.setEnvironment(oSession, oTxsSession, oTestVm);
1836 fRc, curGuestSession = curTest.createSession('testGuestCtrlExec: Single test 1');
1837 if fRc is False:
1838 reporter.error('Single test failed: Could not create session');
1839 else:
1840 fRc = self.gctrlExecDoTest(0, curTest, curRes, curGuestSession);
1841 curTest.closeSession();
1842
1843 curTest = aaTests[2][0]; # tdTestExec, use an index, later.
1844 curRes = aaTests[2][1]; # tdTestResultExec
1845 curTest.setEnvironment(oSession, oTxsSession, oTestVm);
1846 fRc, curGuestSession = curTest.createSession('testGuestCtrlExec: Single test 2');
1847 if fRc is False:
1848 reporter.error('Single test failed: Could not create session');
1849 else:
1850 fRc = self.gctrlExecDoTest(0, curTest, curRes, curGuestSession);
1851 curTest.closeSession();
1852
1853 curTest = aaTests[3][0]; # tdTestExec, use an index, later.
1854 curRes = aaTests[3][1]; # tdTestResultExec
1855 curTest.setEnvironment(oSession, oTxsSession, oTestVm);
1856 fRc, curGuestSession = curTest.createSession('testGuestCtrlExec: Single test 3');
1857 if fRc is False:
1858 reporter.error('Single test failed: Could not create session');
1859 else:
1860 fRc = self.gctrlExecDoTest(0, curTest, curRes, curGuestSession);
1861 curTest.closeSession();
1862 return (fRc, oTxsSession);
1863 else:
1864 aaManual = aaManual; # Workaround for pylint #W0612.
1865
1866 if fRc is False:
1867 return (fRc, oTxsSession);
1868
1869 #
1870 # First batch: One session per guest process.
1871 #
1872 for (i, aTest) in enumerate(aaTests):
1873 curTest = aTest[0]; # tdTestExec, use an index, later.
1874 curRes = aTest[1]; # tdTestResultExec
1875 curTest.setEnvironment(oSession, oTxsSession, oTestVm);
1876 fRc, curGuestSession = curTest.createSession('testGuestCtrlExec: Test #%d' % (i,));
1877 if fRc is False:
1878 reporter.error('Test #%d failed: Could not create session' % (i,));
1879 break;
1880 fRc = self.gctrlExecDoTest(i, curTest, curRes, curGuestSession);
1881 if fRc is False:
1882 break;
1883 fRc = curTest.closeSession();
1884 if fRc is False:
1885 break;
1886
1887 # No sessions left?
1888 if fRc is True:
1889 cSessions = len(self.oTstDrv.oVBoxMgr.getArray(oSession.o.console.guest, 'sessions'));
1890 if cSessions is not 0:
1891 reporter.error('Found %d stale session(s), expected 0' % (cSessions,));
1892 fRc = False;
1893
1894 if fRc is False:
1895 return (fRc, oTxsSession);
1896
1897 reporter.log('Now using one guest session for all tests ...');
1898
1899 #
1900 # Second batch: One session for *all* guest processes.
1901 #
1902 oGuest = oSession.o.console.guest;
1903 try:
1904 reporter.log('Creating session for all tests ...');
1905 curGuestSession = oGuest.createSession(sUser, sPassword, '', 'testGuestCtrlExec: One session for all tests');
1906 try:
1907 fWaitFor = [ vboxcon.GuestSessionWaitForFlag_Start ];
1908 waitResult = curGuestSession.waitForArray(fWaitFor, 30 * 1000);
1909 if waitResult != vboxcon.GuestSessionWaitResult_Start \
1910 and waitResult != vboxcon.GuestSessionWaitResult_WaitFlagNotSupported:
1911 reporter.error('Session did not start successfully, returned wait result: %ld' \
1912 % (waitResult));
1913 return (False, oTxsSession);
1914 reporter.log('Session successfully started');
1915 except:
1916 # Just log, don't assume an error here (will be done in the main loop then).
1917 reporter.logXcpt('Waiting for guest session to start failed:');
1918 return (False, oTxsSession);
1919 # Note: Not waiting for the guest session to start here
1920 # is intentional. This must be handled by the process execution
1921 # call then.
1922 for (i, aTest) in enumerate(aaTests):
1923 curTest = aTest[0]; # tdTestExec, use an index, later.
1924 curRes = aTest[1]; # tdTestResultExec
1925 curTest.setEnvironment(oSession, oTxsSession, oTestVm);
1926 fRc = self.gctrlExecDoTest(i, curTest, curRes, curGuestSession);
1927 if fRc is False:
1928 break;
1929 try:
1930 reporter.log2('Closing guest session ...');
1931 curGuestSession.close();
1932 curGuestSession = None;
1933 except:
1934 # Just log, don't assume an error here (will be done in the main loop then).
1935 reporter.logXcpt('Closing guest session failed:');
1936 fRc = False;
1937 except:
1938 reporter.logXcpt('Could not create one session:');
1939
1940 # No sessions left?
1941 if fRc is True:
1942 cSessions = len(self.oTstDrv.oVBoxMgr.getArray(oSession.o.console.guest, 'sessions'));
1943 if cSessions is not 0:
1944 reporter.error('Found %d stale session(s), expected 0' % (cSessions,));
1945 fRc = False;
1946
1947 return (fRc, oTxsSession);
1948
1949 def testGuestCtrlExecErrorLevel(self, oSession, oTxsSession, oTestVm):
1950 """
1951 Tests handling of error levels from started guest processes.
1952 """
1953
1954 if oTestVm.isWindows():
1955 sUser = "Administrator";
1956 else:
1957 sUser = "vbox";
1958 sPassword = "password";
1959
1960 if oTestVm.isWindows():
1961 # Outputting stuff.
1962 sImage = "C:\\windows\\system32\\cmd.exe";
1963 else:
1964 reporter.error('Implement me!'); ## @todo Implement non-Windows bits.
1965 return (False, oTxsSession);
1966
1967 aaTests = [];
1968 if oTestVm.isWindows():
1969 aaTests.extend([
1970 # Simple.
1971 [ tdTestExec(sCmd = sImage, aArgs = [ sImage, '/C', 'wrongcommand' ],
1972 sUser = sUser, sPassword = sPassword),
1973 tdTestResultExec(fRc = True, iExitCode = 1) ],
1974 [ tdTestExec(sCmd = sImage, aArgs = [ sImage, '/C', 'exit', '22' ],
1975 sUser = sUser, sPassword = sPassword),
1976 tdTestResultExec(fRc = True, iExitCode = 22) ],
1977 [ tdTestExec(sCmd = sImage, aArgs = [ sImage, '/C', 'set', 'ERRORLEVEL=234' ],
1978 sUser = sUser, sPassword = sPassword),
1979 tdTestResultExec(fRc = True, iExitCode = 0) ],
1980 [ tdTestExec(sCmd = sImage, aArgs = [ sImage, '/C', 'echo', '%WINDIR%' ],
1981 sUser = sUser, sPassword = sPassword),
1982 tdTestResultExec(fRc = True, iExitCode = 0) ],
1983 [ tdTestExec(sCmd = sImage, aArgs = [ sImage, '/C', 'set', 'ERRORLEVEL=0' ],
1984 sUser = sUser, sPassword = sPassword),
1985 tdTestResultExec(fRc = True, iExitCode = 0) ],
1986 [ tdTestExec(sCmd = sImage, aArgs = [ sImage, '/C', 'dir', 'c:\\windows\\system32' ],
1987 sUser = sUser, sPassword = sPassword),
1988 tdTestResultExec(fRc = True, iExitCode = 0) ],
1989 [ tdTestExec(sCmd = sImage, aArgs = [ sImage, '/C', 'dir', 'c:\\windows\\system32\\kernel32.dll' ],
1990 sUser = sUser, sPassword = sPassword),
1991 tdTestResultExec(fRc = True, iExitCode = 0) ],
1992 [ tdTestExec(sCmd = sImage, aArgs = [ sImage, '/C', 'dir', 'c:\\nonexisting-file' ],
1993 sUser = sUser, sPassword = sPassword),
1994 tdTestResultExec(fRc = True, iExitCode = 1) ],
1995 [ tdTestExec(sCmd = sImage, aArgs = [ sImage, '/C', 'dir', 'c:\\nonexisting-dir\\' ],
1996 sUser = sUser, sPassword = sPassword),
1997 tdTestResultExec(fRc = True, iExitCode = 1) ]
1998 # FIXME: Failing tests.
1999 # With stdout.
2000 # [ tdTestExec(sCmd = sImage, aArgs = [ sImage, '/C', 'dir', 'c:\\windows\\system32' ],
2001 # sUser = sUser, sPassword = sPassword, aFlags = [ vboxcon.ProcessCreateFlag_WaitForStdOut ]),
2002 # tdTestResultExec(fRc = True, iExitCode = 0) ],
2003 # [ tdTestExec(sCmd = sImage, aArgs = [ sImage, '/C', 'dir', 'c:\\nonexisting-file' ],
2004 # sUser = sUser, sPassword = sPassword, aFlags = [ vboxcon.ProcessCreateFlag_WaitForStdOut ]),
2005 # tdTestResultExec(fRc = True, iExitCode = 1) ],
2006 # [ tdTestExec(sCmd = sImage, aArgs = [ sImage, '/C', 'dir', 'c:\\nonexisting-dir\\' ],
2007 # sUser = sUser, sPassword = sPassword, aFlags = [ vboxcon.ProcessCreateFlag_WaitForStdOut ]),
2008 # tdTestResultExec(fRc = True, iExitCode = 1) ],
2009 # With stderr.
2010 # [ tdTestExec(sCmd = sImage, aArgs = [ sImage, '/C', 'dir', 'c:\\windows\\system32' ],
2011 # sUser = sUser, sPassword = sPassword, aFlags = [ vboxcon.ProcessCreateFlag_WaitForStdErr ]),
2012 # tdTestResultExec(fRc = True, iExitCode = 0) ],
2013 # [ tdTestExec(sCmd = sImage, aArgs = [ sImage, '/C', 'dir', 'c:\\nonexisting-file' ],
2014 # sUser = sUser, sPassword = sPassword, aFlags = [ vboxcon.ProcessCreateFlag_WaitForStdErr ]),
2015 # tdTestResultExec(fRc = True, iExitCode = 1) ],
2016 # [ tdTestExec(sCmd = sImage, aArgs = [ sImage, '/C', 'dir', 'c:\\nonexisting-dir\\' ],
2017 # sUser = sUser, sPassword = sPassword, aFlags = [ vboxcon.ProcessCreateFlag_WaitForStdErr ]),
2018 # tdTestResultExec(fRc = True, iExitCode = 1) ],
2019 # With stdout/stderr.
2020 # [ tdTestExec(sCmd = sImage, aArgs = [ sImage, '/C', 'dir', 'c:\\windows\\system32' ],
2021 # sUser = sUser, sPassword = sPassword,
2022 # aFlags = [ vboxcon.ProcessCreateFlag_WaitForStdOut, vboxcon.ProcessCreateFlag_WaitForStdErr ]),
2023 # tdTestResultExec(fRc = True, iExitCode = 0) ],
2024 # [ tdTestExec(sCmd = sImage, aArgs = [ sImage, '/C', 'dir', 'c:\\nonexisting-file' ],
2025 # sUser = sUser, sPassword = sPassword,
2026 # aFlags = [ vboxcon.ProcessCreateFlag_WaitForStdOut, vboxcon.ProcessCreateFlag_WaitForStdErr ]),
2027 # tdTestResultExec(fRc = True, iExitCode = 1) ],
2028 # [ tdTestExec(sCmd = sImage, aArgs = [ sImage, '/C', 'dir', 'c:\\nonexisting-dir\\' ],
2029 # sUser = sUser, sPassword = sPassword,
2030 # aFlags = [ vboxcon.ProcessCreateFlag_WaitForStdOut, vboxcon.ProcessCreateFlag_WaitForStdErr ]),
2031 # tdTestResultExec(fRc = True, iExitCode = 1) ]
2032 ## @todo Test stdin!
2033 ]);
2034 else:
2035 reporter.log('No OS-specific tests for non-Windows yet!');
2036
2037 fRc = True;
2038 for (i, aTest) in enumerate(aaTests):
2039 curTest = aTest[0]; # tdTestExec, use an index, later.
2040 curRes = aTest[1]; # tdTestResult
2041 curTest.setEnvironment(oSession, oTxsSession, oTestVm);
2042 fRc, curGuestSession = curTest.createSession('testGuestCtrlExecErrorLevel: Test #%d' % (i,));
2043 if fRc is False:
2044 reporter.error('Test #%d failed: Could not create session' % (i,));
2045 break;
2046 fRc = self.gctrlExecDoTest(i, curTest, curRes, curGuestSession);
2047 curTest.closeSession();
2048 if fRc is False:
2049 break;
2050
2051 return (fRc, oTxsSession);
2052
2053 def testGuestCtrlExecTimeout(self, oSession, oTxsSession, oTestVm):
2054 """
2055 Tests handling of timeouts of started guest processes.
2056 """
2057
2058 if oTestVm.isWindows():
2059 sUser = "Administrator";
2060 else:
2061 sUser = "vbox";
2062 sPassword = "password";
2063 sDomain = "";
2064
2065 if oTestVm.isWindows():
2066 # Outputting stuff.
2067 sImage = "C:\\windows\\system32\\cmd.exe";
2068 else:
2069 reporter.error('Implement me!'); ## @todo Implement non-Windows bits.
2070 return (False, oTxsSession);
2071
2072 fRc = True;
2073 try:
2074 oGuest = oSession.o.console.guest;
2075 oGuestSession = oGuest.createSession(sUser, sPassword, sDomain, "testGuestCtrlExecTimeout");
2076 oGuestSession.waitForArray([ vboxcon.GuestSessionWaitForFlag_Start ], 30 * 1000);
2077 # Create a process which never terminates and should timeout when
2078 # waiting for termination.
2079 try:
2080 curProc = oGuestSession.processCreate(sImage, [sImage,] if self.oTstDrv.fpApiVer >= 5.0 else [], \
2081 [], [], 30 * 1000);
2082 reporter.log('Waiting for process 1 being started ...');
2083 waitRes = curProc.waitForArray([ vboxcon.ProcessWaitForFlag_Start ], 30 * 1000);
2084 if waitRes != vboxcon.ProcessWaitResult_Start:
2085 reporter.error('Waiting for process 1 to start failed, got status %ld');
2086 fRc = False;
2087 if fRc:
2088 reporter.log('Waiting for process 1 to time out within 1ms ...');
2089 waitRes = curProc.waitForArray([ vboxcon.ProcessWaitForFlag_Terminate ], 1);
2090 if waitRes != vboxcon.ProcessWaitResult_Timeout:
2091 reporter.error('Waiting for process 1 did not time out when it should (1)');
2092 fRc = False;
2093 else:
2094 reporter.log('Waiting for process 1 timed out (1), good');
2095 if fRc:
2096 reporter.log('Waiting for process 1 to time out within 5000ms ...');
2097 waitRes = curProc.waitForArray([ vboxcon.ProcessWaitForFlag_Terminate ], 5000);
2098 if waitRes != vboxcon.ProcessWaitResult_Timeout:
2099 reporter.error('Waiting for process 1 did not time out when it should, got wait result %ld' % (waitRes,));
2100 fRc = False;
2101 else:
2102 reporter.log('Waiting for process 1 timed out (5000), good');
2103 ## @todo Add curProc.terminate() as soon as it's implemented.
2104 except:
2105 reporter.errorXcpt('Exception for process 1:');
2106 fRc = False;
2107 # Create a lengthly running guest process which will be killed by VBoxService on the
2108 # guest because it ran out of execution time (5 seconds).
2109 if fRc:
2110 try:
2111 curProc = oGuestSession.processCreate(sImage, [sImage,] if self.oTstDrv.fpApiVer >= 5.0 else [], \
2112 [], [], 5 * 1000);
2113 reporter.log('Waiting for process 2 being started ...');
2114 waitRes = curProc.waitForArray([ vboxcon.ProcessWaitForFlag_Start ], 30 * 1000);
2115 if waitRes != vboxcon.ProcessWaitResult_Start:
2116 reporter.error('Waiting for process 1 to start failed, got status %ld');
2117 fRc = False;
2118 if fRc:
2119 reporter.log('Waiting for process 2 to get killed because it ran out of execution time ...');
2120 waitRes = curProc.waitForArray([ vboxcon.ProcessWaitForFlag_Terminate ], 30 * 1000);
2121 if waitRes != vboxcon.ProcessWaitResult_Timeout:
2122 reporter.error('Waiting for process 2 did not time out when it should, got wait result %ld' \
2123 % (waitRes,));
2124 fRc = False;
2125 if fRc:
2126 reporter.log('Waiting for process 2 indicated an error, good');
2127 if curProc.status != vboxcon.ProcessStatus_TimedOutKilled:
2128 reporter.error('Status of process 2 wrong; excepted %ld, got %ld' \
2129 % (vboxcon.ProcessStatus_TimedOutKilled, curProc.status));
2130 fRc = False;
2131 else:
2132 reporter.log('Status of process 2 correct (%ld)' % (vboxcon.ProcessStatus_TimedOutKilled,));
2133 ## @todo Add curProc.terminate() as soon as it's implemented.
2134 except:
2135 reporter.errorXcpt('Exception for process 2:');
2136 fRc = False;
2137 oGuestSession.close();
2138 except:
2139 reporter.errorXcpt('Could not handle session:');
2140 fRc = False;
2141
2142 return (fRc, oTxsSession);
2143
2144 def testGuestCtrlDirCreate(self, oSession, oTxsSession, oTestVm):
2145 """
2146 Tests creation of guest directories.
2147 """
2148
2149 if oTestVm.isWindows():
2150 sUser = "Administrator";
2151 else:
2152 sUser = "vbox";
2153 sPassword = "password";
2154
2155 if oTestVm.isWindows():
2156 sScratch = "C:\\Temp\\vboxtest\\testGuestCtrlDirCreate\\";
2157
2158 aaTests = [];
2159 if oTestVm.isWindows():
2160 aaTests.extend([
2161 # Invalid stuff.
2162 [ tdTestDirCreate(sUser = sUser, sPassword = sPassword, sDirectory = '' ),
2163 tdTestResult(fRc = False) ],
2164 # More unusual stuff.
2165 [ tdTestDirCreate(sUser = sUser, sPassword = sPassword, sDirectory = '..\\..\\' ),
2166 tdTestResult(fRc = False) ],
2167 [ tdTestDirCreate(sUser = sUser, sPassword = sPassword, sDirectory = '../../' ),
2168 tdTestResult(fRc = False) ],
2169 [ tdTestDirCreate(sUser = sUser, sPassword = sPassword, sDirectory = 'z:\\' ),
2170 tdTestResult(fRc = False) ],
2171 [ tdTestDirCreate(sUser = sUser, sPassword = sPassword, sDirectory = '\\\\uncrulez\\foo' ),
2172 tdTestResult(fRc = False) ],
2173 # Creating directories.
2174 [ tdTestDirCreate(sUser = sUser, sPassword = sPassword, sDirectory = sScratch ),
2175 tdTestResult(fRc = False) ],
2176 [ tdTestDirCreate(sUser = sUser, sPassword = sPassword, sDirectory = os.path.join(sScratch, 'foo\\bar\\baz'),
2177 aFlags = [ vboxcon.DirectoryCreateFlag_Parents ] ),
2178 tdTestResult(fRc = True) ],
2179 [ tdTestDirCreate(sUser = sUser, sPassword = sPassword, sDirectory = os.path.join(sScratch, 'foo\\bar\\baz'),
2180 aFlags = [ vboxcon.DirectoryCreateFlag_Parents ] ),
2181 tdTestResult(fRc = True) ],
2182 # Long (+ random) stuff.
2183 [ tdTestDirCreate(sUser = sUser, sPassword = sPassword,
2184 sDirectory = os.path.join(sScratch,
2185 "".join(random.choice(string.ascii_lowercase) for i in range(32))) ),
2186 tdTestResult(fRc = True) ],
2187 [ tdTestDirCreate(sUser = sUser, sPassword = sPassword,
2188 sDirectory = os.path.join(sScratch,
2189 "".join(random.choice(string.ascii_lowercase) for i in range(128))) ),
2190 tdTestResult(fRc = True) ],
2191 # Following two should fail on Windows (paths too long). Both should timeout.
2192 [ tdTestDirCreate(sUser = sUser, sPassword = sPassword,
2193 sDirectory = os.path.join(sScratch,
2194 "".join(random.choice(string.ascii_lowercase) for i in range(255))) ),
2195 tdTestResult(fRc = False) ],
2196 [ tdTestDirCreate(sUser = sUser, sPassword = sPassword,
2197 sDirectory = os.path.join(sScratch,
2198 "".join(random.choice(string.ascii_lowercase) for i in range(1024))) ),
2199 tdTestResult(fRc = False) ]
2200 ]);
2201 else:
2202 reporter.log('No OS-specific tests for non-Windows yet!');
2203
2204 fRc = True;
2205 for (i, aTest) in enumerate(aaTests):
2206 curTest = aTest[0]; # tdTestExec, use an index, later.
2207 curRes = aTest[1]; # tdTestResult
2208 reporter.log('Testing #%d, sDirectory="%s" ...' % (i, curTest.sDirectory));
2209 curTest.setEnvironment(oSession, oTxsSession, oTestVm);
2210 fRc, curGuestSession = curTest.createSession('testGuestCtrlDirCreate: Test #%d' % (i,));
2211 if fRc is False:
2212 reporter.error('Test #%d failed: Could not create session' % (i,));
2213 break;
2214 fRc = self.gctrlCreateDir(curTest, curRes, curGuestSession);
2215 curTest.closeSession();
2216 if fRc is False:
2217 reporter.error('Test #%d failed' % (i,));
2218 fRc = False;
2219 break;
2220
2221 return (fRc, oTxsSession);
2222
2223 def testGuestCtrlDirCreateTemp(self, oSession, oTxsSession, oTestVm): # pylint: disable=R0914
2224 """
2225 Tests creation of temporary directories.
2226 """
2227
2228 if oTestVm.isWindows():
2229 sUser = "Administrator";
2230 else:
2231 sUser = "vbox";
2232 sPassword = "password";
2233
2234 # if oTestVm.isWindows():
2235 # sScratch = "C:\\Temp\\vboxtest\\testGuestCtrlDirCreateTemp\\";
2236
2237 aaTests = [];
2238 if oTestVm.isWindows():
2239 aaTests.extend([
2240 # Invalid stuff.
2241 [ tdTestDirCreateTemp(sUser = sUser, sPassword = sPassword, sDirectory = ''),
2242 tdTestResult(fRc = False) ],
2243 [ tdTestDirCreateTemp(sUser = sUser, sPassword = sPassword, sDirectory = 'C:\\Windows',
2244 fMode = 1234),
2245 tdTestResult(fRc = False) ],
2246 [ tdTestDirCreateTemp(sUser = sUser, sPassword = sPassword, sTemplate = '',
2247 sDirectory = 'C:\\Windows', fMode = 1234),
2248 tdTestResult(fRc = False) ],
2249 [ tdTestDirCreateTemp(sUser = sUser, sPassword = sPassword, sTemplate = 'xXx',
2250 sDirectory = 'C:\\Windows', fMode = 0700),
2251 tdTestResult(fRc = False) ],
2252 [ tdTestDirCreateTemp(sUser = sUser, sPassword = sPassword, sTemplate = 'xxx',
2253 sDirectory = 'C:\\Windows', fMode = 0700),
2254 tdTestResult(fRc = False) ],
2255 # More unusual stuff.
2256 [ tdTestDirCreateTemp(sUser = sUser, sPassword = sPassword, sTemplate = 'foo',
2257 sDirectory = 'z:\\'),
2258 tdTestResult(fRc = False) ],
2259 [ tdTestDirCreateTemp(sUser = sUser, sPassword = sPassword, sTemplate = 'foo',
2260 sDirectory = '\\\\uncrulez\\foo'),
2261 tdTestResult(fRc = False) ],
2262 # Non-existing stuff.
2263 [ tdTestDirCreateTemp(sUser = sUser, sPassword = sPassword, sTemplate = 'bar',
2264 sDirectory = 'c:\\Apps\\nonexisting\\foo'),
2265 tdTestResult(fRc = False) ],
2266 # FIXME: Failing test. Non Windows path
2267 # [ tdTestDirCreateTemp(sUser = sUser, sPassword = sPassword, sTemplate = 'bar',
2268 # sDirectory = '/tmp/non/existing'),
2269 # tdTestResult(fRc = False) ]
2270 ]);
2271 else:
2272 reporter.log('No OS-specific tests for non-Windows yet!');
2273
2274 # FIXME: Failing tests.
2275 # aaTests.extend([
2276 # Non-secure variants.
2277 # [ tdTestDirCreateTemp(sUser = sUser, sPassword = sPassword, sTemplate = 'XXX',
2278 # sDirectory = sScratch),
2279 # tdTestResult(fRc = True) ],
2280 # [ tdTestDirCreateTemp(sUser = sUser, sPassword = sPassword, sTemplate = 'XXX',
2281 # sDirectory = sScratch),
2282 # tdTestResult(fRc = True) ],
2283 # [ tdTestDirCreateTemp(sUser = sUser, sPassword = sPassword, sTemplate = 'X',
2284 # sDirectory = sScratch),
2285 # tdTestResult(fRc = True) ],
2286 # [ tdTestDirCreateTemp(sUser = sUser, sPassword = sPassword, sTemplate = 'X',
2287 # sDirectory = sScratch),
2288 # tdTestResult(fRc = True) ],
2289 # [ tdTestDirCreateTemp(sUser = sUser, sPassword = sPassword, sTemplate = 'XXX',
2290 # sDirectory = sScratch,
2291 # fMode = 0700),
2292 # tdTestResult(fRc = True) ],
2293 # [ tdTestDirCreateTemp(sUser = sUser, sPassword = sPassword, sTemplate = 'XXX',
2294 # sDirectory = sScratch,
2295 # fMode = 0700),
2296 # tdTestResult(fRc = True) ],
2297 # [ tdTestDirCreateTemp(sUser = sUser, sPassword = sPassword, sTemplate = 'XXX',
2298 # sDirectory = sScratch,
2299 # fMode = 0755),
2300 # tdTestResult(fRc = True) ],
2301 # [ tdTestDirCreateTemp(sUser = sUser, sPassword = sPassword, sTemplate = 'XXX',
2302 # sDirectory = sScratch,
2303 # fMode = 0755),
2304 # tdTestResult(fRc = True) ],
2305 # Secure variants.
2306 # [ tdTestDirCreateTemp(sUser = sUser, sPassword = sPassword, sTemplate = 'XXX',
2307 # sDirectory = sScratch, fSecure = True),
2308 # tdTestResult(fRc = True) ],
2309 # [ tdTestDirCreateTemp(sUser = sUser, sPassword = sPassword, sTemplate = 'XXX',
2310 # sDirectory = sScratch, fSecure = True),
2311 # tdTestResult(fRc = True) ],
2312 # [ tdTestDirCreateTemp(sUser = sUser, sPassword = sPassword, sTemplate = 'XXX',
2313 # sDirectory = sScratch, fSecure = True),
2314 # tdTestResult(fRc = True) ],
2315 # [ tdTestDirCreateTemp(sUser = sUser, sPassword = sPassword, sTemplate = 'XXX',
2316 # sDirectory = sScratch, fSecure = True),
2317 # tdTestResult(fRc = True) ],
2318 # [ tdTestDirCreateTemp(sUser = sUser, sPassword = sPassword, sTemplate = 'XXX',
2319 # sDirectory = sScratch,
2320 # fSecure = True, fMode = 0700),
2321 # tdTestResult(fRc = True) ],
2322 # [ tdTestDirCreateTemp(sUser = sUser, sPassword = sPassword, sTemplate = 'XXX',
2323 # sDirectory = sScratch,
2324 # fSecure = True, fMode = 0700),
2325 # tdTestResult(fRc = True) ],
2326 # [ tdTestDirCreateTemp(sUser = sUser, sPassword = sPassword, sTemplate = 'XXX',
2327 # sDirectory = sScratch,
2328 # fSecure = True, fMode = 0755),
2329 # tdTestResult(fRc = True) ],
2330 # [ tdTestDirCreateTemp(sUser = sUser, sPassword = sPassword, sTemplate = 'XXX',
2331 # sDirectory = sScratch,
2332 # fSecure = True, fMode = 0755),
2333 # tdTestResult(fRc = True) ],
2334 # Random stuff.
2335 # [ tdTestDirCreateTemp(sUser = sUser, sPassword = sPassword,
2336 # sTemplate = "XXX-".join(random.choice(string.ascii_lowercase) for i in range(32)),
2337 # sDirectory = sScratch,
2338 # fSecure = True, fMode = 0755),
2339 # tdTestResult(fRc = True) ],
2340 # [ tdTestDirCreateTemp(sUser = sUser, sPassword = sPassword, sTemplate = "".join('X' for i in range(32)),
2341 # sDirectory = sScratch,
2342 # fSecure = True, fMode = 0755),
2343 # tdTestResult(fRc = True) ],
2344 # [ tdTestDirCreateTemp(sUser = sUser, sPassword = sPassword, sTemplate = "".join('X' for i in range(128)),
2345 # sDirectory = sScratch,
2346 # fSecure = True, fMode = 0755),
2347 # tdTestResult(fRc = True) ]
2348 # ]);
2349
2350 fRc = True;
2351 for (i, aTest) in enumerate(aaTests):
2352 curTest = aTest[0]; # tdTestExec, use an index, later.
2353 curRes = aTest[1]; # tdTestResult
2354 reporter.log('Testing #%d, sTemplate="%s", fMode=%#o, path="%s", secure="%s" ...' %
2355 (i, curTest.sTemplate, curTest.fMode, curTest.sDirectory, curTest.fSecure));
2356 curTest.setEnvironment(oSession, oTxsSession, oTestVm);
2357 fRc, curGuestSession = curTest.createSession('testGuestCtrlDirCreateTemp: Test #%d' % (i,));
2358 if fRc is False:
2359 reporter.error('Test #%d failed: Could not create session' % (i,));
2360 break;
2361 sDirTemp = "";
2362 try:
2363 sDirTemp = curGuestSession.directoryCreateTemp(curTest.sTemplate, curTest.fMode,
2364 curTest.sDirectory, curTest.fSecure);
2365 except:
2366 if curRes.fRc is True:
2367 reporter.errorXcpt('Creating temp directory "%s" failed:' % (curTest.sDirectory,));
2368 fRc = False;
2369 break;
2370 else:
2371 reporter.logXcpt('Creating temp directory "%s" failed expectedly, skipping:' % (curTest.sDirectory,));
2372 curTest.closeSession();
2373 if sDirTemp != "":
2374 reporter.log2('Temporary directory is: %s' % (sDirTemp,));
2375 if self.oTstDrv.fpApiVer >= 5.0:
2376 fExists = curGuestSession.directoryExists(sDirTemp, False);
2377 else:
2378 fExists = curGuestSession.directoryExists(sDirTemp);
2379 if fExists is False:
2380 reporter.error('Test #%d failed: Temporary directory "%s" does not exists' % (i, sDirTemp));
2381 fRc = False;
2382 break;
2383 return (fRc, oTxsSession);
2384
2385 def testGuestCtrlDirRead(self, oSession, oTxsSession, oTestVm): # pylint: disable=R0914
2386 """
2387 Tests opening and reading (enumerating) guest directories.
2388 """
2389
2390 if oTestVm.isWindows():
2391 sUser = "Administrator";
2392 else:
2393 sUser = "vbox";
2394 sPassword = "password";
2395
2396 aaTests = [];
2397 if oTestVm.isWindows():
2398 aaTests.extend([
2399 # Invalid stuff.
2400 [ tdTestDirRead(sUser = sUser, sPassword = sPassword, sDirectory = ''),
2401 tdTestResultDirRead(fRc = False) ],
2402 [ tdTestDirRead(sUser = sUser, sPassword = sPassword, sDirectory = 'C:\\Windows', aFlags = [ 1234 ]),
2403 tdTestResultDirRead(fRc = False) ],
2404 [ tdTestDirRead(sUser = sUser, sPassword = sPassword, sDirectory = 'C:\\Windows', sFilter = '*.foo'),
2405 tdTestResultDirRead(fRc = False) ],
2406 # More unusual stuff.
2407 [ tdTestDirRead(sUser = sUser, sPassword = sPassword, sDirectory = 'z:\\'),
2408 tdTestResultDirRead(fRc = False) ],
2409 [ tdTestDirRead(sUser = sUser, sPassword = sPassword, sDirectory = '\\\\uncrulez\\foo'),
2410 tdTestResultDirRead(fRc = False) ],
2411 # Non-existing stuff.
2412 [ tdTestDirRead(sUser = sUser, sPassword = sPassword, sDirectory = 'c:\\Apps\\nonexisting'),
2413 tdTestResultDirRead(fRc = False) ],
2414 [ tdTestDirRead(sUser = sUser, sPassword = sPassword, sDirectory = 'c:\\Apps\\testDirRead'),
2415 tdTestResultDirRead(fRc = False) ]
2416 ]);
2417
2418 if oTestVm.sVmName == 'tst-xppro':
2419 aaTests.extend([
2420 # Reading directories.
2421 [ tdTestDirRead(sUser = sUser, sPassword = sPassword, sDirectory = '../../Windows/Fonts'),
2422 tdTestResultDirRead(fRc = True, numFiles = 191) ],
2423 [ tdTestDirRead(sUser = sUser, sPassword = sPassword, sDirectory = 'c:\\Windows\\Help'),
2424 tdTestResultDirRead(fRc = True, numDirs = 13, numFiles = 569) ],
2425 [ tdTestDirRead(sUser = sUser, sPassword = sPassword, sDirectory = 'c:\\Windows\\Web'),
2426 tdTestResultDirRead(fRc = True, numDirs = 3, numFiles = 55) ]
2427 ]);
2428 else:
2429 reporter.log('No OS-specific tests for non-Windows yet!');
2430
2431 fRc = True;
2432 for (i, aTest) in enumerate(aaTests):
2433 curTest = aTest[0]; # tdTestExec, use an index, later.
2434 curRes = aTest[1]; # tdTestResult
2435 reporter.log('Testing #%d, dir="%s" ...' % (i, curTest.sDirectory));
2436 curTest.setEnvironment(oSession, oTxsSession, oTestVm);
2437 fRc, curGuestSession = curTest.createSession('testGuestCtrlDirRead: Test #%d' % (i,));
2438 if fRc is False:
2439 reporter.error('Test #%d failed: Could not create session' % (i,));
2440 break;
2441 (fRc2, cDirs, cFiles) = self.gctrlReadDir(curTest, curRes, curGuestSession);
2442 curTest.closeSession();
2443 reporter.log2('Test #%d: Returned %ld directories, %ld files total' % (i, cDirs, cFiles));
2444 if fRc2 is curRes.fRc:
2445 if fRc2 is True:
2446 if curRes.numFiles != cFiles:
2447 reporter.error('Test #%d failed: Got %ld files, expected %ld' % (i, cFiles, curRes.numFiles));
2448 fRc = False;
2449 break;
2450 if curRes.numDirs != cDirs:
2451 reporter.error('Test #%d failed: Got %ld directories, expected %ld' % (i, cDirs, curRes.numDirs));
2452 fRc = False;
2453 break;
2454 else:
2455 reporter.error('Test #%d failed: Got %s, expected %s' % (i, fRc2, curRes.fRc));
2456 fRc = False;
2457 break;
2458
2459 return (fRc, oTxsSession);
2460
2461 def testGuestCtrlFileRemove(self, oSession, oTxsSession, oTestVm):
2462 """
2463 Tests removing guest files.
2464 """
2465
2466 if oTestVm.isWindows():
2467 sUser = "Administrator";
2468 else:
2469 sUser = "vbox";
2470 sPassword = "password";
2471
2472 aaTests = [];
2473 if oTestVm.isWindows():
2474 aaTests.extend([
2475 # Invalid stuff.
2476 [ tdTestFileRemove(sUser = sUser, sPassword = sPassword, sFile = ''), tdTestResult(fRc = False) ],
2477 [ tdTestFileRemove(sUser = sUser, sPassword = sPassword, sFile = 'C:\\Windows'), tdTestResult(fRc = False) ],
2478 [ tdTestFileRemove(sUser = sUser, sPassword = sPassword, sFile = 'C:\\Windows'), tdTestResult(fRc = False) ],
2479 # More unusual stuff.
2480 [ tdTestFileRemove(sUser = sUser, sPassword = sPassword, sFile = 'z:\\'), tdTestResult(fRc = False) ],
2481 [ tdTestFileRemove(sUser = sUser, sPassword = sPassword, sFile = '\\\\uncrulez\\foo'),
2482 tdTestResult(fRc = False) ],
2483 # Non-existing stuff.
2484 [ tdTestFileRemove(sUser = sUser, sPassword = sPassword, sFile = 'c:\\Apps\\nonexisting'),
2485 tdTestResult(fRc = False) ],
2486 [ tdTestFileRemove(sUser = sUser, sPassword = sPassword, sFile = 'c:\\Apps\\testFileRemove'),
2487 tdTestResult(fRc = False) ],
2488 # Try to delete system files.
2489 [ tdTestFileRemove(sUser = sUser, sPassword = sPassword, sFile = 'c:\\pagefile.sys'),
2490 tdTestResult(fRc = False) ],
2491 [ tdTestFileRemove(sUser = sUser, sPassword = sPassword, sFile = 'c:\\Windows\\kernel32.sys'),
2492 tdTestResult(fRc = False) ]
2493 ]);
2494
2495 if oTestVm.sVmName == 'tst-xppro':
2496 aaTests.extend([
2497 # Try delete some unimportant media stuff.
2498 [ tdTestFileRemove(sUser = sUser, sPassword = sPassword, sFile = 'c:\\Windows\\Media\\chimes.wav'),
2499 tdTestResult(fRc = True) ],
2500 # Second attempt should fail.
2501 [ tdTestFileRemove(sUser = sUser, sPassword = sPassword, sFile = 'c:\\Windows\\Media\\chimes.wav'),
2502 tdTestResult(fRc = False) ],
2503 [ tdTestFileRemove(sUser = sUser, sPassword = sPassword, sFile = 'c:\\Windows\\Media\\chord.wav'),
2504 tdTestResult(fRc = True) ],
2505 [ tdTestFileRemove(sUser = sUser, sPassword = sPassword, sFile = 'c:\\Windows\\Media\\chord.wav'),
2506 tdTestResult(fRc = False) ]
2507 ]);
2508 else:
2509 reporter.log('No OS-specific tests for non-Windows yet!');
2510
2511 fRc = True;
2512 for (i, aTest) in enumerate(aaTests):
2513 curTest = aTest[0]; # tdTestExec, use an index, later.
2514 curRes = aTest[1]; # tdTestResult
2515 reporter.log('Testing #%d, file="%s" ...' % (i, curTest.sFile));
2516 curTest.setEnvironment(oSession, oTxsSession, oTestVm);
2517 fRc, curGuestSession = curTest.createSession('testGuestCtrlFileRemove: Test #%d' % (i,));
2518 if fRc is False:
2519 reporter.error('Test #%d failed: Could not create session' % (i,));
2520 break;
2521 try:
2522 if self.oTstDrv.fpApiVer >= 5.0:
2523 curGuestSession.fsObjRemove(curTest.sFile);
2524 else:
2525 curGuestSession.fileRemove(curTest.sFile);
2526 except:
2527 if curRes.fRc is True:
2528 reporter.errorXcpt('Removing file "%s" failed:' % (curTest.sFile,));
2529 fRc = False;
2530 break;
2531 else:
2532 reporter.logXcpt('Removing file "%s" failed expectedly, skipping:' % (curTest.sFile,));
2533 curTest.closeSession();
2534 return (fRc, oTxsSession);
2535
2536 def testGuestCtrlFileStat(self, oSession, oTxsSession, oTestVm): # pylint: disable=R0914
2537 """
2538 Tests querying file information through stat.
2539 """
2540
2541 if oTestVm.isWindows():
2542 sUser = "Administrator";
2543 else:
2544 sUser = "vbox";
2545 sPassword = "password";
2546
2547 aaTests = [];
2548 if oTestVm.isWindows():
2549 aaTests.extend([
2550 # Invalid stuff.
2551 [ tdTestFileStat(sUser = sUser, sPassword = sPassword, sFile = ''),
2552 tdTestResultFileStat(fRc = False) ],
2553 [ tdTestFileStat(sUser = sUser, sPassword = sPassword, sFile = 'C:\\Windows'),
2554 tdTestResultFileStat(fRc = False) ],
2555 [ tdTestFileStat(sUser = sUser, sPassword = sPassword, sFile = 'C:\\Windows'),
2556 tdTestResultFileStat(fRc = False) ],
2557 # More unusual stuff.
2558 [ tdTestFileStat(sUser = sUser, sPassword = sPassword, sFile = 'z:\\'),
2559 tdTestResultFileStat(fRc = False) ],
2560 [ tdTestFileStat(sUser = sUser, sPassword = sPassword, sFile = '\\\\uncrulez\\foo'),
2561 tdTestResultFileStat(fRc = False) ],
2562 # Non-existing stuff.
2563 [ tdTestFileStat(sUser = sUser, sPassword = sPassword, sFile = 'c:\\Apps\\nonexisting'),
2564 tdTestResultFileStat(fRc = False) ],
2565 [ tdTestFileStat(sUser = sUser, sPassword = sPassword, sFile = 'c:\\Apps\\testDirRead'),
2566 tdTestResultFileStat(fRc = False) ]
2567 ]);
2568
2569 if oTestVm.sVmName == 'tst-xppro':
2570 aaTests.extend([
2571 # Directories; should fail.
2572 [ tdTestFileStat(sUser = sUser, sPassword = sPassword, sFile = '../../Windows/Fonts'),
2573 tdTestResultFileStat(fRc = False) ],
2574 [ tdTestFileStat(sUser = sUser, sPassword = sPassword, sFile = 'c:\\Windows\\Help'),
2575 tdTestResultFileStat(fRc = False) ],
2576 [ tdTestFileStat(sUser = sUser, sPassword = sPassword, sFile = 'c:\\Windows\\system32'),
2577 tdTestResultFileStat(fRc = False) ],
2578 # Regular files.
2579 [ tdTestFileStat(sUser = sUser, sPassword = sPassword, sFile = 'c:\\Windows\\system32\\kernel32.dll'),
2580 tdTestResultFileStat(fRc = False, cbSize = 926720, eFileType = vboxcon.FsObjType_File) ]
2581 ]);
2582 else:
2583 reporter.log('No OS-specific tests for non-Windows yet!');
2584
2585 fRc = True;
2586 for (i, aTest) in enumerate(aaTests):
2587 curTest = aTest[0]; # tdTestExec, use an index, later.
2588 curRes = aTest[1]; # tdTestResult
2589 reporter.log('Testing #%d, sFile="%s" ...' % (i, curTest.sFile));
2590 curTest.setEnvironment(oSession, oTxsSession, oTestVm);
2591 fRc, curGuestSession = curTest.createSession('testGuestCtrlFileStat: Test #%d' % (i,));
2592 if fRc is False:
2593 reporter.error('Test #%d failed: Could not create session' % (i,));
2594 break;
2595 fileObjInfo = None;
2596 try:
2597 if self.oTstDrv.fpApiVer >= 5.0:
2598 fileObjInfo = curGuestSession.fsObjQueryInfo(curTest.sFile, True);
2599 else:
2600 fileObjInfo = curGuestSession.fileQueryInfo(curTest.sFile);
2601 except:
2602 if curRes.fRc is True:
2603 reporter.errorXcpt('Querying file information for "%s" failed:' % (curTest.sFile,));
2604 fRc = False;
2605 break;
2606 else:
2607 reporter.logXcpt('Querying file information for "%s" failed expectedly, skipping:' % (curTest.sFile,));
2608 curTest.closeSession();
2609 if fileObjInfo is not None:
2610 eFileType = fileObjInfo.type;
2611 if curRes.eFileType != eFileType:
2612 reporter.error('Test #%d failed: Got file type %ld, expected %ld' % (i, eFileType, curRes.eFileType));
2613 fRc = False;
2614 break;
2615 cbFile = long(fileObjInfo.objectSize);
2616 if curRes.cbSize != cbFile:
2617 reporter.error('Test #%d failed: Got %ld bytes size, expected %ld bytes' % (i, cbFile, curRes.cbSize));
2618 fRc = False;
2619 break;
2620 ## @todo Add more checks later.
2621
2622 return (fRc, oTxsSession);
2623
2624 def testGuestCtrlFileRead(self, oSession, oTxsSession, oTestVm): # pylint: disable=R0914
2625 """
2626 Tests reading from guest files.
2627 """
2628
2629 if oTestVm.isWindows():
2630 sUser = "Administrator";
2631 else:
2632 sUser = "vbox";
2633 sPassword = "password";
2634
2635 if oTxsSession.syncMkDir('${SCRATCH}/testGuestCtrlFileRead') is False:
2636 reporter.error('Could not create scratch directory on guest');
2637 return (False, oTxsSession);
2638
2639 aaTests = [];
2640 aaTests.extend([
2641 # Invalid stuff.
2642 [ tdTestFileReadWrite(sUser = sUser, sPassword = sPassword, cbToReadWrite = 0),
2643 tdTestResultFileReadWrite(fRc = False) ],
2644 [ tdTestFileReadWrite(sUser = sUser, sPassword = sPassword, sFile = ''),
2645 tdTestResultFileReadWrite(fRc = False) ],
2646 [ tdTestFileReadWrite(sUser = sUser, sPassword = sPassword, sFile = 'non-existing.file'),
2647 tdTestResultFileReadWrite(fRc = False) ],
2648 # Wrong open mode.
2649 [ tdTestFileReadWrite(sUser = sUser, sPassword = sPassword, sFile = 'non-existing.file', \
2650 sOpenMode = 'rt', sDisposition = 'oe'),
2651 tdTestResultFileReadWrite(fRc = False) ],
2652 [ tdTestFileReadWrite(sUser = sUser, sPassword = sPassword, sFile = '\\\\uncrulez\\non-existing.file', \
2653 sOpenMode = 'tr', sDisposition = 'oe'),
2654 tdTestResultFileReadWrite(fRc = False) ],
2655 [ tdTestFileReadWrite(sUser = sUser, sPassword = sPassword, sFile = '../../non-existing.file', \
2656 sOpenMode = 'wr', sDisposition = 'oe'),
2657 tdTestResultFileReadWrite(fRc = False) ],
2658 # Wrong disposition.
2659 [ tdTestFileReadWrite(sUser = sUser, sPassword = sPassword, sFile = 'non-existing.file', \
2660 sOpenMode = 'r', sDisposition = 'e'),
2661 tdTestResultFileReadWrite(fRc = False) ],
2662 [ tdTestFileReadWrite(sUser = sUser, sPassword = sPassword, sFile = '\\\\uncrulez\\non-existing.file', \
2663 sOpenMode = 'r', sDisposition = 'o'),
2664 tdTestResultFileReadWrite(fRc = False) ],
2665 [ tdTestFileReadWrite(sUser = sUser, sPassword = sPassword, sFile = '../../non-existing.file', \
2666 sOpenMode = 'r', sDisposition = 'c'),
2667 tdTestResultFileReadWrite(fRc = False) ],
2668 # Opening non-existing file when it should exist.
2669 [ tdTestFileReadWrite(sUser = sUser, sPassword = sPassword, sFile = 'non-existing.file', \
2670 sOpenMode = 'r', sDisposition = 'oe'),
2671 tdTestResultFileReadWrite(fRc = False) ],
2672 [ tdTestFileReadWrite(sUser = sUser, sPassword = sPassword, sFile = '\\\\uncrulez\\non-existing.file', \
2673 sOpenMode = 'r', sDisposition = 'oe'),
2674 tdTestResultFileReadWrite(fRc = False) ],
2675 [ tdTestFileReadWrite(sUser = sUser, sPassword = sPassword, sFile = '../../non-existing.file', \
2676 sOpenMode = 'r', sDisposition = 'oe'),
2677 tdTestResultFileReadWrite(fRc = False) ]
2678 ]);
2679
2680 if oTestVm.isWindows():
2681 aaTests.extend([
2682 # Create a file which must not exist (but it hopefully does).
2683 [ tdTestFileReadWrite(sUser = sUser, sPassword = sPassword, sFile = 'C:\\Windows\\System32\\calc.exe', \
2684 sOpenMode = 'w', sDisposition = 'ce'),
2685 tdTestResultFileReadWrite(fRc = False) ],
2686 # Open a file which must exist.
2687 [ tdTestFileReadWrite(sUser = sUser, sPassword = sPassword, sFile = 'C:\\Windows\\System32\\kernel32.dll', \
2688 sOpenMode = 'r', sDisposition = 'oe'),
2689 tdTestResultFileReadWrite(fRc = True) ],
2690 # Try truncating a file which already is opened with a different sharing mode (and thus should fail).
2691 [ tdTestFileReadWrite(sUser = sUser, sPassword = sPassword, sFile = 'C:\\Windows\\System32\\kernel32.dll', \
2692 sOpenMode = 'w', sDisposition = 'ot'),
2693 tdTestResultFileReadWrite(fRc = False) ]
2694 ]);
2695
2696 if oTestVm.sKind == "WindowsXP":
2697 aaTests.extend([
2698 # Reading from beginning.
2699 [ tdTestFileReadWrite(sUser = sUser, sPassword = sPassword, sFile = 'C:\\Windows\\System32\\eula.txt', \
2700 sOpenMode = 'r', sDisposition = 'oe', cbToReadWrite = 33),
2701 tdTestResultFileReadWrite(fRc = True, aBuf = 'Microsoft Windows XP Professional', \
2702 cbProcessed = 33, cbOffset = 33) ],
2703 # Reading from offset.
2704 [ tdTestFileReadWrite(sUser = sUser, sPassword = sPassword, sFile = 'C:\\Windows\\System32\\eula.txt', \
2705 sOpenMode = 'r', sDisposition = 'oe', cbOffset = 17782, cbToReadWrite = 26),
2706 tdTestResultFileReadWrite(fRc = True, aBuf = 'LINKS TO THIRD PARTY SITES', \
2707 cbProcessed = 26, cbOffset = 17782 + 26) ]
2708 ]);
2709
2710 fRc = True;
2711 for (i, aTest) in enumerate(aaTests):
2712 curTest = aTest[0]; # tdTestFileReadWrite, use an index, later.
2713 curRes = aTest[1]; # tdTestResult
2714 reporter.log('Testing #%d, sFile="%s", cbToReadWrite=%d, sOpenMode="%s", sDisposition="%s", cbOffset=%ld ...' % \
2715 (i, curTest.sFile, curTest.cbToReadWrite, curTest.sOpenMode, curTest.sDisposition, curTest.cbOffset));
2716 curTest.setEnvironment(oSession, oTxsSession, oTestVm);
2717 fRc, curGuestSession = curTest.createSession('testGuestCtrlFileRead: Test #%d' % (i,));
2718 if fRc is False:
2719 reporter.error('Test #%d failed: Could not create session' % (i,));
2720 break;
2721 try:
2722 if curTest.cbOffset > 0: # The offset parameter is gone.
2723 if self.oTstDrv.fpApiVer >= 5.0:
2724 curFile = curGuestSession.fileOpenEx(curTest.sFile, curTest.getAccessMode(), curTest.getOpenAction(),
2725 curTest.getSharingMode(), curTest.lCreationMode, []);
2726 curFile.seek(curTest.cbOffset, vboxcon.FileSeekOrigin_Begin);
2727 else:
2728 curFile = curGuestSession.fileOpenEx(curTest.sFile, curTest.sOpenMode, curTest.sDisposition, \
2729 curTest.sSharingMode, curTest.lCreationMode, curTest.cbOffset);
2730 curOffset = long(curFile.offset);
2731 resOffset = long(curTest.cbOffset);
2732 if curOffset != resOffset:
2733 reporter.error('Test #%d failed: Initial offset on open does not match: Got %ld, expected %ld' \
2734 % (i, curOffset, resOffset));
2735 fRc = False;
2736 else:
2737 if self.oTstDrv.fpApiVer >= 5.0:
2738 curFile = curGuestSession.fileOpen(curTest.sFile, curTest.getAccessMode(), curTest.getOpenAction(),
2739 curTest.lCreationMode);
2740 else:
2741 curFile = curGuestSession.fileOpen(curTest.sFile, curTest.sOpenMode, curTest.sDisposition, \
2742 curTest.lCreationMode);
2743 if fRc \
2744 and curTest.cbToReadWrite > 0:
2745 ## @todo Split this up in 64K reads. Later.
2746 ## @todo Test timeouts.
2747 aBufRead = curFile.read(curTest.cbToReadWrite, 30 * 1000);
2748 if curRes.cbProcessed > 0 \
2749 and curRes.cbProcessed is not len(aBufRead):
2750 reporter.error('Test #%d failed: Read buffer length does not match: Got %ld, expected %ld' \
2751 % (i, len(aBufRead), curRes.cbProcessed));
2752 fRc = False;
2753 if fRc:
2754 if curRes.aBuf is not None \
2755 and bytes(curRes.aBuf) != bytes(aBufRead):
2756 reporter.error('Test #%d failed: Got buffer\n%s (%ld bytes), expected\n%s (%ld bytes)' \
2757 % (i, map(hex, map(ord, aBufRead)), len(aBufRead), \
2758 map(hex, map(ord, curRes.aBuf)), len(curRes.aBuf)));
2759 reporter.error('Test #%d failed: Got buffer\n%s, expected\n%s' \
2760 % (i, aBufRead, curRes.aBuf));
2761 fRc = False;
2762 # Test final offset.
2763 curOffset = long(curFile.offset);
2764 resOffset = long(curRes.cbOffset);
2765 if curOffset != resOffset:
2766 reporter.error('Test #%d failed: Final offset does not match: Got %ld, expected %ld' \
2767 % (i, curOffset, resOffset));
2768 fRc = False;
2769 curFile.close();
2770 except:
2771 reporter.logXcpt('Opening "%s" failed:' % (curTest.sFile,));
2772 fRc = False;
2773
2774 curTest.closeSession();
2775
2776 if fRc != curRes.fRc:
2777 reporter.error('Test #%d failed: Got %s, expected %s' % (i, fRc, curRes.fRc));
2778 fRc = False;
2779 break;
2780
2781 return (fRc, oTxsSession);
2782
2783 def testGuestCtrlFileWrite(self, oSession, oTxsSession, oTestVm): # pylint: disable=R0914
2784 """
2785 Tests writing to guest files.
2786 """
2787
2788 if oTestVm.isWindows():
2789 sUser = "Administrator";
2790 else:
2791 sUser = "vbox";
2792 sPassword = "password";
2793
2794 if oTestVm.isWindows():
2795 sScratch = "C:\\Temp\\vboxtest\\testGuestCtrlFileWrite\\";
2796
2797 if oTxsSession.syncMkDir('${SCRATCH}/testGuestCtrlFileWrite') is False:
2798 reporter.error('Could not create scratch directory on guest');
2799 return (False, oTxsSession);
2800
2801 aaTests = [];
2802
2803 cScratchBuf = 512;
2804 aScratchBuf = array('b', [random.randint(-128, 127) for i in range(cScratchBuf)]);
2805 aaTests.extend([
2806 # Write to a non-existing file.
2807 [ tdTestFileReadWrite(sUser = sUser, sPassword = sPassword, sFile = sScratch + 'testGuestCtrlFileWrite.txt', \
2808 sOpenMode = 'w+', sDisposition = 'ce', cbToReadWrite = cScratchBuf,
2809 aBuf = aScratchBuf),
2810 tdTestResultFileReadWrite(fRc = True, aBuf = aScratchBuf, \
2811 cbProcessed = cScratchBuf, cbOffset = cScratchBuf) ]
2812 ]);
2813
2814 aScratchBuf2 = array('b', [random.randint(-128, 127) for i in range(cScratchBuf)]);
2815 aaTests.extend([
2816 # Append the same amount of data to the just created file.
2817 [ tdTestFileReadWrite(sUser = sUser, sPassword = sPassword, sFile = sScratch + 'testGuestCtrlFileWrite.txt', \
2818 sOpenMode = 'w+', sDisposition = 'oa', cbToReadWrite = cScratchBuf,
2819 cbOffset = cScratchBuf, aBuf = aScratchBuf2),
2820 tdTestResultFileReadWrite(fRc = True, aBuf = aScratchBuf2, \
2821 cbProcessed = cScratchBuf, cbOffset = cScratchBuf * 2) ],
2822 ]);
2823
2824 fRc = True;
2825 for (i, aTest) in enumerate(aaTests):
2826 curTest = aTest[0]; # tdTestFileReadWrite, use an index, later.
2827 curRes = aTest[1]; # tdTestResult
2828 reporter.log('Testing #%d, sFile="%s", cbToReadWrite=%d, sOpenMode="%s", sDisposition="%s", cbOffset=%ld ...' % \
2829 (i, curTest.sFile, curTest.cbToReadWrite, curTest.sOpenMode, curTest.sDisposition, curTest.cbOffset));
2830 curTest.setEnvironment(oSession, oTxsSession, oTestVm);
2831 fRc, curGuestSession = curTest.createSession('testGuestCtrlFileWrite: Test #%d' % (i,));
2832 if fRc is False:
2833 reporter.error('Test #%d failed: Could not create session' % (i,));
2834 break;
2835 try:
2836 if curTest.cbOffset > 0: # The offset parameter is gone.
2837 if self.oTstDrv.fpApiVer >= 5.0:
2838 curFile = curGuestSession.fileOpenEx(curTest.sFile, curTest.getAccessMode(), curTest.getOpenAction(),
2839 curTest.getSharingMode(), []);
2840 curFile.seek(curTest.cbOffset, vboxcon.FileSeekOrigin_Begin);
2841 else:
2842 curFile = curGuestSession.fileOpenEx(curTest.sFile, curTest.sOpenMode, curTest.sDisposition, \
2843 curTest.sSharingMode, curTest.lCreationMode, curTest.cbOffset);
2844 curOffset = long(curFile.offset);
2845 resOffset = long(curTest.cbOffset);
2846 if curOffset != resOffset:
2847 reporter.error('Test #%d failed: Initial offset on open does not match: Got %ld, expected %ld' \
2848 % (i, curOffset, resOffset));
2849 fRc = False;
2850 else:
2851 if self.oTstDrv.fpApiVer >= 5.0:
2852 curFile = curGuestSession.fileOpen(curTest.sFile, curTest.getAccessMode(), curTest.getOpenAction(),
2853 curTest.lCreationMode);
2854 else:
2855 curFile = curGuestSession.fileOpen(curTest.sFile, curTest.sOpenMode, curTest.sDisposition, \
2856 curTest.lCreationMode);
2857 if fRc \
2858 and curTest.cbToReadWrite > 0:
2859 ## @todo Split this up in 64K writes. Later.
2860 ## @todo Test timeouts.
2861 cBytesWritten = curFile.write(curTest.aBuf, 30 * 1000);
2862 if curRes.cbProcessed > 0 \
2863 and curRes.cbProcessed != cBytesWritten:
2864 reporter.error('Test #%d failed: Written buffer length does not match: Got %ld, expected %ld' \
2865 % (i, cBytesWritten, curRes.cbProcessed));
2866 fRc = False;
2867 if fRc:
2868 # Verify written content by seeking back to the initial offset and
2869 # re-read & compare the written data.
2870 try:
2871 if self.oTstDrv.fpApiVer >= 5.0:
2872 curFile.seek(-(curTest.cbToReadWrite), vboxcon.FileSeekOrigin_Current);
2873 else:
2874 curFile.seek(-(curTest.cbToReadWrite), vboxcon.FileSeekType_Current);
2875 except:
2876 reporter.logXcpt('Seeking back to initial write position failed:');
2877 fRc = False;
2878 if fRc \
2879 and long(curFile.offset) != curTest.cbOffset:
2880 reporter.error('Test #%d failed: Initial write position does not match current position, \
2881 got %ld, expected %ld' \
2882 % (i, long(curFile.offset), curTest.cbOffset));
2883 fRc = False;
2884 if fRc:
2885 aBufRead = curFile.read(curTest.cbToReadWrite, 30 * 1000);
2886 if len(aBufRead) != curTest.cbToReadWrite:
2887 reporter.error('Test #%d failed: Got buffer length %ld, expected %ld' \
2888 % (i, len(aBufRead), curTest.cbToReadWrite));
2889 fRc = False;
2890 if fRc \
2891 and curRes.aBuf is not None \
2892 and buffer(curRes.aBuf) != aBufRead:
2893 reporter.error('Test #%d failed: Got buffer\n%s, expected\n%s' \
2894 % (i, aBufRead, curRes.aBuf));
2895 fRc = False;
2896 # Test final offset.
2897 curOffset = long(curFile.offset);
2898 resOffset = long(curRes.cbOffset);
2899 if curOffset != resOffset:
2900 reporter.error('Test #%d failed: Final offset does not match: Got %ld, expected %ld' \
2901 % (i, curOffset, resOffset));
2902 fRc = False;
2903 curFile.close();
2904 except:
2905 reporter.logXcpt('Opening "%s" failed:' % (curTest.sFile,));
2906 fRc = False;
2907
2908 curTest.closeSession();
2909
2910 if fRc != curRes.fRc:
2911 reporter.error('Test #%d failed: Got %s, expected %s' % (i, fRc, curRes.fRc));
2912 fRc = False;
2913 break;
2914
2915 return (fRc, oTxsSession);
2916
2917 def testGuestCtrlCopyTo(self, oSession, oTxsSession, oTestVm):
2918 """
2919 Tests copying files from host to the guest.
2920 """
2921
2922 if oTestVm.isWindows():
2923 sUser = "Administrator";
2924 else:
2925 sUser = "vbox";
2926 sPassword = "password";
2927
2928 if oTestVm.isWindows():
2929 sScratch = "C:\\Temp\\vboxtest\\testGuestCtrlCopyTo\\";
2930
2931 if oTxsSession.syncMkDir('${SCRATCH}/testGuestCtrlCopyTo') is False:
2932 reporter.error('Could not create scratch directory on guest');
2933 return (False, oTxsSession);
2934
2935 # Some stupid trickery to guess the location of the iso.
2936 sVBoxValidationKitISO = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../VBoxValidationKit.iso'));
2937 if not os.path.isfile(sVBoxValidationKitISO):
2938 sVBoxValidationKitISO = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../VBoxTestSuite.iso'));
2939 if not os.path.isfile(sVBoxValidationKitISO):
2940 sCur = os.getcwd();
2941 for i in range(0, 10):
2942 sVBoxValidationKitISO = os.path.join(sCur, 'validationkit/VBoxValidationKit.iso');
2943 if os.path.isfile(sVBoxValidationKitISO):
2944 break;
2945 sVBoxValidationKitISO = os.path.join(sCur, 'testsuite/VBoxTestSuite.iso');
2946 if os.path.isfile(sVBoxValidationKitISO):
2947 break;
2948 sCur = os.path.abspath(os.path.join(sCur, '..'));
2949 if i is None: pass; # shut up pychecker/pylint.
2950 if os.path.isfile(sVBoxValidationKitISO):
2951 reporter.log('Validation Kit .ISO found at: %s' % (sVBoxValidationKitISO,));
2952 else:
2953 reporter.log('Warning: Validation Kit .ISO not found -- some tests might fail');
2954
2955 aaTests = [];
2956 if oTestVm.isWindows():
2957 aaTests.extend([
2958 # Destination missing.
2959 [ tdTestCopyTo(sUser = sUser, sPassword = sPassword, sSrc = ''), tdTestResult(fRc = False) ],
2960 [ tdTestCopyTo(sUser = sUser, sPassword = sPassword, sSrc = 'C:\\Windows',
2961 aFlags = [ 1234 ] ), tdTestResult(fRc = False) ],
2962 # Source missing.
2963 [ tdTestCopyTo(sUser = sUser, sPassword = sPassword, sDst = ''), tdTestResult(fRc = False) ],
2964 [ tdTestCopyTo(sUser = sUser, sPassword = sPassword, sDst = 'C:\\Windows',
2965 aFlags = [ 1234 ] ), tdTestResult(fRc = False) ],
2966 # Nothing to copy (source and/or destination is empty).
2967 [ tdTestCopyTo(sUser = sUser, sPassword = sPassword, sSrc = 'z:\\'), tdTestResult(fRc = False) ],
2968 [ tdTestCopyTo(sUser = sUser, sPassword = sPassword, sSrc = '\\\\uncrulez\\foo'),
2969 tdTestResult(fRc = False) ],
2970 [ tdTestCopyTo(sUser = sUser, sPassword = sPassword, sSrc = 'non-exist',
2971 sDst = os.path.join(sScratch, 'non-exist.dll')), tdTestResult(fRc = False) ],
2972 # Copying single files.
2973 [ tdTestCopyTo(sUser = sUser, sPassword = sPassword, sSrc = sVBoxValidationKitISO,
2974 sDst = 'C:\\non-exist\\'), tdTestResult(fRc = False) ],
2975 [ tdTestCopyTo(sUser = sUser, sPassword = sPassword, sSrc = sVBoxValidationKitISO,
2976 sDst = 'C:\\non\\exist\\'), tdTestResult(fRc = False) ],
2977 [ tdTestCopyTo(sUser = sUser, sPassword = sPassword, sSrc = sVBoxValidationKitISO,
2978 sDst = 'C:\\non\\exist\\renamedfile.dll'), tdTestResult(fRc = False) ],
2979 [ tdTestCopyTo(sUser = sUser, sPassword = sPassword, sSrc = sVBoxValidationKitISO,
2980 sDst = os.path.join(sScratch, 'HostGuestAdditions.iso')), tdTestResult(fRc = True) ],
2981 [ tdTestCopyTo(sUser = sUser, sPassword = sPassword, sSrc = sVBoxValidationKitISO,
2982 sDst = os.path.join(sScratch, 'HostGuestAdditions.iso')), tdTestResult(fRc = True) ],
2983 # Destination is a directory, should fail.
2984 [ tdTestCopyTo(sUser = sUser, sPassword = sPassword, sSrc = sVBoxValidationKitISO,
2985 sDst = sScratch), tdTestResult(fRc = False) ]
2986 ## @todo Add testing the CopyTo flags here!
2987 ]);
2988
2989 if self.oTstDrv.sHost == 'win':
2990 ## @todo Check for Windows (7) host.
2991 aaTests.extend([
2992 # Copying directories with contain files we don't have read access to.
2993 [ tdTestCopyTo(sUser = sUser, sPassword = sPassword, sSrc = 'C:\\Windows\\security',
2994 sDst = sScratch), tdTestResult(fRc = False) ],
2995 # Copying directories with regular files.
2996 [ tdTestCopyTo(sUser = sUser, sPassword = sPassword, sSrc = 'C:\\Windows\\Help',
2997 sDst = sScratch), tdTestResult(fRc = True) ]
2998 ]);
2999 else:
3000 reporter.log('No OS-specific tests for non-Windows yet!');
3001
3002 fRc = True;
3003 for (i, aTest) in enumerate(aaTests):
3004 curTest = aTest[0]; # tdTestExec, use an index, later.
3005 curRes = aTest[1]; # tdTestResult
3006 reporter.log('Testing #%d, sSrc="%s", sDst="%s", aFlags="%s" ...' % \
3007 (i, curTest.sSrc, curTest.sDst, curTest.aFlags));
3008 curTest.setEnvironment(oSession, oTxsSession, oTestVm);
3009 fRc, curGuestSession = curTest.createSession('testGuestCtrlCopyTo: Test #%d' % (i,));
3010 if fRc is False:
3011 reporter.error('Test #%d failed: Could not create session' % (i,));
3012 break;
3013 fRc2 = self.gctrlCopyTo(curTest, curGuestSession);
3014 curTest.closeSession();
3015 if fRc2 is curRes.fRc:
3016 ## @todo Verify the copied results (size, checksum?).
3017 pass;
3018 else:
3019 reporter.error('Test #%d failed: Got %s, expected %s' % (i, fRc2, curRes.fRc));
3020 fRc = False;
3021 break;
3022
3023 return (fRc, oTxsSession);
3024
3025 def testGuestCtrlCopyFrom(self, oSession, oTxsSession, oTestVm): # pylint: disable=R0914
3026 """
3027 Tests copying files from guest to the host.
3028 """
3029
3030 if oTestVm.isWindows():
3031 sUser = "Administrator";
3032 else:
3033 sUser = "vbox";
3034 sPassword = "password";
3035
3036 sScratch = os.path.join(self.oTstDrv.sScratchPath, "testGctrlCopyFrom");
3037 try:
3038 os.makedirs(sScratch);
3039 except OSError as e:
3040 if e.errno != errno.EEXIST:
3041 reporter.error('Failed: Unable to create scratch directory \"%s\"' % (sScratch,));
3042 return (False, oTxsSession);
3043 reporter.log('Scratch path is: %s' % (sScratch,));
3044
3045 aaTests = [];
3046 if oTestVm.isWindows():
3047 aaTests.extend([
3048 # Destination missing.
3049 [ tdTestCopyFrom(sUser = sUser, sPassword = sPassword, sSrc = ''),
3050 tdTestResult(fRc = False) ],
3051 [ tdTestCopyFrom(sUser = sUser, sPassword = sPassword, sSrc = 'C:\\Windows',
3052 aFlags = [ 1234 ] ),
3053 tdTestResult(fRc = False) ],
3054 # Source missing.
3055 [ tdTestCopyFrom(sUser = sUser, sPassword = sPassword, sDst = ''),
3056 tdTestResult(fRc = False) ],
3057 [ tdTestCopyFrom(sUser = sUser, sPassword = sPassword, sDst = 'C:\\Windows',
3058 aFlags = [ 1234 ] ),
3059 tdTestResult(fRc = False) ],
3060 # Nothing to copy (sDst is empty / unreachable).
3061 [ tdTestCopyFrom(sUser = sUser, sPassword = sPassword, sSrc = 'z:\\'),
3062 tdTestResult(fRc = False) ],
3063 [ tdTestCopyFrom(sUser = sUser, sPassword = sPassword, sSrc = '\\\\uncrulez\\foo'),
3064
3065 tdTestResult(fRc = False) ],
3066 [ tdTestCopyFrom(sUser = sUser, sPassword = sPassword, sSrc = 'non-exist',
3067 sDst = os.path.join(sScratch, 'non-exist.dll')),
3068 tdTestResult(fRc = False) ]
3069 ## @todo Add testing the CopyFrom aFlags here!
3070 ]);
3071
3072 if self.oTstDrv.sHost == 'win':
3073 aaTests.extend([
3074 # FIXME: Failing test.
3075 # Copying single files.
3076 # [ tdTestCopyFrom(sUser = sUser, sPassword = sPassword, sSrc = 'C:\\Windows\\system32\\ole32.dll',
3077 # sDst = 'C:\\non-exist\\'), tdTestResult(fRc = False) ],
3078 # [ tdTestCopyFrom(sUser = sUser, sPassword = sPassword, sSrc = 'C:\\Windows\\system32\\ole32.dll',
3079 # sDst = 'C:\\non\\exist\\'), tdTestResult(fRc = False) ],
3080 # [ tdTestCopyFrom(sUser = sUser, sPassword = sPassword, sSrc = 'C:\\Windows\\system32\\ole32.dll',
3081 # sDst = 'C:\\non\\exist\\renamedfile.dll'), tdTestResult(fRc = False) ],
3082 # [ tdTestCopyFrom(sUser = sUser, sPassword = sPassword, sSrc = 'C:\\Windows\\system32\\ole32.dll',
3083 # sDst = os.path.join(sScratch, 'renamedfile.dll')), tdTestResult(fRc = True) ],
3084 # [ tdTestCopyFrom(sUser = sUser, sPassword = sPassword, sSrc = 'C:\\Windows\\system32\\ole32.dll',
3085 # sDst = os.path.join(sScratch, 'renamedfile.dll')), tdTestResult(fRc = True) ],
3086 # Destination is a directory, should fail.
3087 [ tdTestCopyFrom(sUser = sUser, sPassword = sPassword, sSrc = 'C:\\Windows\\system32\\ole32.dll',
3088 sDst = sScratch), tdTestResult(fRc = False) ],
3089 # Copying directories.
3090 [ tdTestCopyFrom(sUser = sUser, sPassword = sPassword, sSrc = 'C:\\Windows\\Web',
3091 sDst = sScratch), tdTestResult(fRc = True) ]
3092 ## @todo Add testing the CopyFrom aFlags here!
3093 ]);
3094 else:
3095 reporter.log('No OS-specific tests for non-Windows yet!');
3096
3097 fRc = True;
3098 for (i, aTest) in enumerate(aaTests):
3099 curTest = aTest[0]; # tdTestExec, use an index, later.
3100 curRes = aTest[1]; # tdTestResult
3101 reporter.log('Testing #%d, sSrc="%s", sDst="%s", aFlags="%s" ...' % \
3102 (i, curTest.sSrc, curTest.sDst, curTest.aFlags));
3103 curTest.setEnvironment(oSession, oTxsSession, oTestVm);
3104 fRc, curGuestSession = curTest.createSession('testGuestCtrlCopyFrom: Test #%d' % (i,));
3105 if fRc is False:
3106 reporter.error('Test #%d failed: Could not create session' % (i,));
3107 break;
3108 fRc2 = self.gctrlCopyFrom(curTest, curRes, curGuestSession);
3109 curTest.closeSession();
3110 if fRc2 is curRes.fRc:
3111 ## @todo Verify the copied results (size, checksum?).
3112 pass;
3113 else:
3114 reporter.error('Test #%d failed: Got %s, expected %s' % (i, fRc2, curRes.fRc));
3115 fRc = False;
3116 break;
3117
3118 return (fRc, oTxsSession);
3119
3120 def testGuestCtrlUpdateAdditions(self, oSession, oTxsSession, oTestVm): # pylint: disable=R0914
3121 """
3122 Tests updating the Guest Additions inside the guest.
3123 """
3124
3125 if oTestVm.isWindows():
3126 sUser = "Administrator";
3127 else:
3128 sUser = "vbox";
3129 sPassword = "password";
3130
3131 # Some stupid trickery to guess the location of the iso.
3132 sVBoxValidationKitISO = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../VBoxValidationKit.iso'));
3133 if not os.path.isfile(sVBoxValidationKitISO):
3134 sVBoxValidationKitISO = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../VBoxTestSuite.iso'));
3135 if not os.path.isfile(sVBoxValidationKitISO):
3136 sCur = os.getcwd();
3137 for i in range(0, 10):
3138 sVBoxValidationKitISO = os.path.join(sCur, 'validationkit/VBoxValidationKit.iso');
3139 if os.path.isfile(sVBoxValidationKitISO):
3140 break;
3141 sVBoxValidationKitISO = os.path.join(sCur, 'testsuite/VBoxTestSuite.iso');
3142 if os.path.isfile(sVBoxValidationKitISO):
3143 break;
3144 sCur = os.path.abspath(os.path.join(sCur, '..'));
3145 if i is None: pass; # shut up pychecker/pylint.
3146 if os.path.isfile(sVBoxValidationKitISO):
3147 reporter.log('Validation Kit .ISO found at: %s' % (sVBoxValidationKitISO,));
3148 else:
3149 reporter.log('Warning: Validation Kit .ISO not found -- some tests might fail');
3150
3151 sScratch = os.path.join(self.oTstDrv.sScratchPath, "testGctrlUpdateAdditions");
3152 try:
3153 os.makedirs(sScratch);
3154 except OSError as e:
3155 if e.errno != errno.EEXIST:
3156 reporter.error('Failed: Unable to create scratch directory \"%s\"' % (sScratch,));
3157 return (False, oTxsSession);
3158 reporter.log('Scratch path is: %s' % (sScratch,));
3159
3160 aaTests = [];
3161 if oTestVm.isWindows():
3162 aaTests.extend([
3163 # Source is missing.
3164 [ tdTestUpdateAdditions(sUser = sUser, sPassword = sPassword, sSrc = ''),
3165 tdTestResult(fRc = False) ],
3166 # Wrong aFlags.
3167 [ tdTestUpdateAdditions(sUser = sUser, sPassword = sPassword, sSrc = self.oTstDrv.getGuestAdditionsIso(),
3168 aFlags = [ 1234 ]),
3169 tdTestResult(fRc = False) ],
3170 # Non-existing .ISO.
3171 [ tdTestUpdateAdditions(sUser = sUser, sPassword = sPassword, sSrc = "non-existing.iso"),
3172 tdTestResult(fRc = False) ],
3173 # Wrong .ISO.
3174 [ tdTestUpdateAdditions(sUser = sUser, sPassword = sPassword, sSrc = sVBoxValidationKitISO),
3175 tdTestResult(fRc = False) ],
3176 # The real thing.
3177 [ tdTestUpdateAdditions(sUser = sUser, sPassword = sPassword, sSrc = self.oTstDrv.getGuestAdditionsIso()),
3178 tdTestResult(fRc = True) ],
3179 # Test the (optional) installer arguments. This will extract the
3180 # installer into our guest's scratch directory.
3181 [ tdTestUpdateAdditions(sUser = sUser, sPassword = sPassword, sSrc = self.oTstDrv.getGuestAdditionsIso(),
3182 aArgs = [ '/extract', '/D=' + sScratch ]),
3183 tdTestResult(fRc = True) ]
3184 # Some debg ISO. Only enable locally.
3185 #[ tdTestUpdateAdditions(sUser = sUser, sPassword = sPassword,
3186 # sSrc = "V:\\Downloads\\VBoxGuestAdditions-r80354.iso"),
3187 # tdTestResult(fRc = True) ]
3188 ]);
3189 else:
3190 reporter.log('No OS-specific tests for non-Windows yet!');
3191
3192 fRc = True;
3193 for (i, aTest) in enumerate(aaTests):
3194 curTest = aTest[0]; # tdTestExec, use an index, later.
3195 curRes = aTest[1]; # tdTestResult
3196 reporter.log('Testing #%d, sSrc="%s", aFlags="%s" ...' % \
3197 (i, curTest.sSrc, curTest.aFlags));
3198 curTest.setEnvironment(oSession, oTxsSession, oTestVm);
3199 fRc, _ = curTest.createSession('Test #%d' % (i,));
3200 if fRc is False:
3201 reporter.error('Test #%d failed: Could not create session' % (i,));
3202 break;
3203 try:
3204 curProgress = curTest.oTest.oGuest.updateGuestAdditions(curTest.sSrc, curTest.aArgs, curTest.aFlags);
3205 if curProgress is not None:
3206 oProgress = vboxwrappers.ProgressWrapper(curProgress, self.oTstDrv.oVBoxMgr, self, "gctrlUpGA");
3207 try:
3208 iRc = oProgress.waitForOperation(0, fIgnoreErrors = True);
3209 if iRc != 0:
3210 reporter.log('Waiting for updating Guest Additions failed');
3211 fRc = False;
3212 except:
3213 reporter.logXcpt('Updating Guest Additions waiting exception for sSrc="%s", aFlags="%s":' \
3214 % (curTest.sSrc, curTest.aFlags));
3215 fRc = False;
3216 except:
3217 # Just log, don't assume an error here (will be done in the main loop then).
3218 reporter.logXcpt('Updating Guest Additions exception for sSrc="%s", aFlags="%s":' \
3219 % (curTest.sSrc, curTest.aFlags));
3220 fRc = False;
3221 curTest.closeSession();
3222 if fRc is curRes.fRc:
3223 if fRc:
3224 ## @todo Verify if Guest Additions were really updated (build, revision, ...).
3225 pass;
3226 else:
3227 reporter.error('Test #%d failed: Got %s, expected %s' % (i, fRc, curRes.fRc));
3228 fRc = False;
3229 break;
3230
3231 return (fRc, oTxsSession);
3232
3233
3234
3235class tdAddGuestCtrl(vbox.TestDriver): # pylint: disable=R0902,R0904
3236 """
3237 Guest control using VBoxService on the guest.
3238 """
3239
3240 def __init__(self):
3241 vbox.TestDriver.__init__(self);
3242 self.oTestVmSet = self.oTestVmManager.getStandardVmSet('nat');
3243 self.fQuick = False; # Don't skip lengthly tests by default.
3244 self.addSubTestDriver(SubTstDrvAddGuestCtrl(self));
3245
3246 #
3247 # Overridden methods.
3248 #
3249 def showUsage(self):
3250 """
3251 Shows the testdriver usage.
3252 """
3253 rc = vbox.TestDriver.showUsage(self);
3254 reporter.log('');
3255 reporter.log('tdAddGuestCtrl Options:');
3256 reporter.log(' --quick');
3257 reporter.log(' Same as --virt-modes hwvirt --cpu-counts 1.');
3258 return rc;
3259
3260 def parseOption(self, asArgs, iArg): # pylint: disable=R0912,R0915
3261 """
3262 Parses the testdriver arguments from the command line.
3263 """
3264 if asArgs[iArg] == '--quick':
3265 self.parseOption(['--virt-modes', 'hwvirt'], 0);
3266 self.parseOption(['--cpu-counts', '1'], 0);
3267 self.fQuick = True;
3268 else:
3269 return vbox.TestDriver.parseOption(self, asArgs, iArg);
3270 return iArg + 1;
3271
3272 def actionConfig(self):
3273 if not self.importVBoxApi(): # So we can use the constant below.
3274 return False;
3275
3276 eNic0AttachType = vboxcon.NetworkAttachmentType_NAT;
3277 sGaIso = self.getGuestAdditionsIso();
3278 return self.oTestVmSet.actionConfig(self, eNic0AttachType = eNic0AttachType, sDvdImage = sGaIso);
3279
3280 def actionExecute(self):
3281 return self.oTestVmSet.actionExecute(self, self.testOneCfg);
3282
3283 #
3284 # Test execution helpers.
3285 #
3286 def testOneCfg(self, oVM, oTestVm): # pylint: disable=R0915
3287 """
3288 Runs the specified VM thru the tests.
3289
3290 Returns a success indicator on the general test execution. This is not
3291 the actual test result.
3292 """
3293
3294 self.logVmInfo(oVM);
3295
3296 fRc = True;
3297 oSession, oTxsSession = self.startVmAndConnectToTxsViaTcp(oTestVm.sVmName, fCdWait = False);
3298 reporter.log("TxsSession: %s" % (oTxsSession,));
3299 if oSession is not None:
3300 self.addTask(oSession);
3301
3302 fManual = False; # Manual override for local testing. (Committed version shall be False.)
3303 if not fManual:
3304 fRc, oTxsSession = self.aoSubTstDrvs[0].testIt(oTestVm, oSession, oTxsSession);
3305 else:
3306 fRc, oTxsSession = self.testGuestCtrlManual(oSession, oTxsSession, oTestVm);
3307
3308 # Cleanup.
3309 self.removeTask(oTxsSession);
3310 if not fManual:
3311 self.terminateVmBySession(oSession);
3312 else:
3313 fRc = False;
3314 return fRc;
3315
3316 def gctrlReportError(self, progress):
3317 """
3318 Helper function to report an error of a
3319 given progress object.
3320 """
3321 if progress is None:
3322 reporter.log('No progress object to print error for');
3323 else:
3324 errInfo = progress.errorInfo;
3325 if errInfo:
3326 reporter.log('%s' % (errInfo.text,));
3327 return False;
3328
3329 def gctrlGetRemainingTime(self, msTimeout, msStart):
3330 """
3331 Helper function to return the remaining time (in ms)
3332 based from a timeout value and the start time (both in ms).
3333 """
3334 if msTimeout is 0:
3335 return 0xFFFFFFFE; # Wait forever.
3336 msElapsed = base.timestampMilli() - msStart;
3337 if msElapsed > msTimeout:
3338 return 0; # No time left.
3339 return msTimeout - msElapsed;
3340
3341 def testGuestCtrlManual(self, oSession, oTxsSession, oTestVm): # pylint: disable=R0914,R0915,W0613,W0612
3342 """
3343 For manually testing certain bits.
3344 """
3345
3346 reporter.log('Manual testing ...');
3347 fRc = True;
3348
3349 sUser = 'Administrator';
3350 sPassword = 'password';
3351
3352 oGuest = oSession.o.console.guest;
3353 oGuestSession = oGuest.createSession(sUser,
3354 sPassword,
3355 "", "Manual Test");
3356
3357 aWaitFor = [ vboxcon.GuestSessionWaitForFlag_Start ];
3358 _ = oGuestSession.waitForArray(aWaitFor, 30 * 1000);
3359
3360 sCmd = 'c:\\windows\\system32\\cmd.exe';
3361 aArgs = [ sCmd, '/C', 'dir', '/S', 'c:\\windows' ];
3362 aEnv = [];
3363 aFlags = [];
3364
3365 for _ in range(100):
3366 oProc = oGuestSession.processCreate(sCmd, aArgs if self.fpApiVer >= 5.0 else aArgs[1:],
3367 aEnv, aFlags, 30 * 1000);
3368
3369 aWaitFor = [ vboxcon.ProcessWaitForFlag_Terminate ];
3370 _ = oProc.waitForArray(aWaitFor, 30 * 1000);
3371
3372 oGuestSession.close();
3373 oGuestSession = None;
3374
3375 time.sleep(5);
3376
3377 oSession.o.console.PowerDown();
3378
3379 return (fRc, oTxsSession);
3380
3381if __name__ == '__main__':
3382 sys.exit(tdAddGuestCtrl().main(sys.argv));
3383
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette