VirtualBox

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

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

tdAddGuestCtrl.py: Extended directory listing test to check names, sizes and types against the vboxtestfileset.TestFileSet object. bugref:9151 bugref:9320

  • Property svn:eol-style set to LF
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 189.6 KB
Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3# pylint: disable=too-many-lines
4
5"""
6VirtualBox Validation Kit - Guest Control Tests.
7"""
8
9__copyright__ = \
10"""
11Copyright (C) 2010-2019 Oracle Corporation
12
13This file is part of VirtualBox Open Source Edition (OSE), as
14available from http://www.virtualbox.org. This file is free software;
15you can redistribute it and/or modify it under the terms of the GNU
16General Public License (GPL) as published by the Free Software
17Foundation, in version 2 as it comes in the "COPYING" file of the
18VirtualBox OSE distribution. VirtualBox OSE is distributed in the
19hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
20
21The contents of this file may alternatively be used under the terms
22of the Common Development and Distribution License Version 1.0
23(CDDL) only, as it comes in the "COPYING.CDDL" file of the
24VirtualBox OSE distribution, in which case the provisions of the
25CDDL are applicable instead of those of the GPL.
26
27You may elect to license modified versions of this file under the
28terms and conditions of either the GPL or the CDDL or both.
29"""
30__version__ = "$Revision: 79159 $"
31
32# Standard Python imports.
33from array import array
34import errno
35import os
36import random
37import struct
38import sys
39import threading
40import time
41
42# Only the main script needs to modify the path.
43try: __file__
44except: __file__ = sys.argv[0];
45g_ksValidationKitDir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))));
46sys.path.append(g_ksValidationKitDir);
47
48# Validation Kit imports.
49from testdriver import reporter;
50from testdriver import base;
51from testdriver import vbox;
52from testdriver import vboxcon;
53from testdriver import vboxtestfileset;
54from testdriver import vboxwrappers;
55from common import utils;
56
57# Python 3 hacks:
58if sys.version_info[0] >= 3:
59 long = int # pylint: disable=redefined-builtin,invalid-name
60 xrange = range; # pylint: disable=redefined-builtin,invalid-name
61
62
63class GuestStream(bytearray):
64 """
65 Class for handling a guest process input/output stream.
66 """
67 def appendStream(self, stream, convertTo = '<b'):
68 """
69 Appends and converts a byte sequence to this object;
70 handy for displaying a guest stream.
71 """
72 self.extend(struct.pack(convertTo, stream));
73
74class tdCtxTest(object):
75 """
76 Provides the actual test environment.
77 Should be kept as generic as possible.
78 """
79 def __init__(self, oSession, oTxsSession, oTestVm): # pylint: disable=unused-argument
80 ## The desired Main API result.
81 self.fRc = False;
82 ## IGuest reference.
83 self.oGuest = oSession.o.console.guest; ## @todo may throw shit
84 self.oSesison = oSession;
85 self.oTxsSesison = oTxsSession;
86 self.oTestVm = oTestVm;
87
88class tdCtxCreds(object):
89 """
90 Provides credentials to pass to the guest.
91 """
92 def __init__(self, sUser = None, sPassword = None, sDomain = None):
93 self.oTestVm = None;
94 self.sUser = sUser;
95 self.sPassword = sPassword;
96 self.sDomain = sDomain;
97
98 def applyDefaultsIfNotSet(self, oTestVm):
99 """
100 Applies credential defaults, based on the test VM (guest OS), if
101 no credentials were set yet.
102 """
103 self.oTestVm = oTestVm;
104 assert self.oTestVm is not None;
105
106 if self.sUser is None:
107 self.sUser = self.oTestVm.getTestUser();
108
109 if self.sPassword is None:
110 self.sPassword = self.oTestVm.getTestUserPassword(self.sUser);
111
112 if self.sDomain is None:
113 self.sDomain = '';
114
115class tdTestGuestCtrlBase(object):
116 """
117 Base class for all guest control tests.
118
119 Note: This test ASSUMES that working Guest Additions
120 were installed and running on the guest to be tested.
121 """
122 def __init__(self):
123 self.oTest = None;
124 self.oCreds = None;
125 self.timeoutMS = 30 * 1000; # 30s timeout
126 ## IGuestSession reference or None.
127 self.oGuestSession = None;
128
129 def setEnvironment(self, oSession, oTxsSession, oTestVm):
130 """
131 Sets the test environment required for this test.
132 """
133 self.oTest = tdCtxTest(oSession, oTxsSession, oTestVm);
134 self.oCreds.applyDefaultsIfNotSet(oTestVm);
135 return self.oTest;
136
137 def uploadLogData(self, oTstDrv, aData, sFileName, sDesc):
138 """
139 Uploads (binary) data to a log file for manual (later) inspection.
140 """
141 reporter.log('Creating + uploading log data file "%s"' % sFileName);
142 sHstFileName = os.path.join(oTstDrv.sScratchPath, sFileName);
143 try:
144 oCurTestFile = open(sHstFileName, "wb");
145 oCurTestFile.write(aData);
146 oCurTestFile.close();
147 except:
148 return reporter.error('Unable to create temporary file for "%s"' % (sDesc,));
149 return reporter.addLogFile(sHstFileName, 'misc/other', sDesc);
150
151 def createSession(self, sName, fIsError = False):
152 """
153 Creates (opens) a guest session.
154 Returns (True, IGuestSession) on success or (False, None) on failure.
155 """
156 if self.oGuestSession is None:
157 if sName is None:
158 sName = "<untitled>";
159
160 reporter.log('Creating session "%s" ...' % (sName,));
161 try:
162 self.oGuestSession = self.oTest.oGuest.createSession(self.oCreds.sUser,
163 self.oCreds.sPassword,
164 self.oCreds.sDomain,
165 sName);
166 except:
167 # Just log, don't assume an error here (will be done in the main loop then).
168 reporter.maybeErrXcpt(fIsError, 'Creating a guest session "%s" failed; sUser="%s", pw="%s", sDomain="%s":'
169 % (sName, self.oCreds.sUser, self.oCreds.sPassword, self.oCreds.sDomain));
170 return (False, None);
171
172 reporter.log('Waiting for session "%s" to start within %dms...' % (sName, self.timeoutMS));
173 aeWaitFor = [ vboxcon.GuestSessionWaitForFlag_Start, ];
174 try:
175 waitResult = self.oGuestSession.waitForArray(aeWaitFor, self.timeoutMS);
176
177 #
178 # Be nice to Guest Additions < 4.3: They don't support session handling and
179 # therefore return WaitFlagNotSupported.
180 #
181 if waitResult not in (vboxcon.GuestSessionWaitResult_Start, vboxcon.GuestSessionWaitResult_WaitFlagNotSupported):
182 # Just log, don't assume an error here (will be done in the main loop then).
183 reporter.maybeErr(fIsError, 'Session did not start successfully, returned wait result: %d' % (waitResult,));
184 return (False, None);
185 reporter.log('Session "%s" successfully started' % (sName,));
186 except:
187 # Just log, don't assume an error here (will be done in the main loop then).
188 reporter.maybeErrXcpt(fIsError, 'Waiting for guest session "%s" (usr=%s;pw=%s;dom=%s) to start failed:'
189 % (sName, self.oCreds.sUser, self.oCreds.sPassword, self.oCreds.sDomain,));
190 return (False, None);
191 else:
192 reporter.log('Warning: Session already set; this is probably not what you want');
193 return (True, self.oGuestSession);
194
195 def setSession(self, oGuestSession):
196 """
197 Sets the current guest session and closes
198 an old one if necessary.
199 """
200 if self.oGuestSession is not None:
201 self.closeSession();
202 self.oGuestSession = oGuestSession;
203 return self.oGuestSession;
204
205 def closeSession(self, fIsError = False):
206 """
207 Closes the guest session.
208 """
209 if self.oGuestSession is not None:
210 try:
211 sName = self.oGuestSession.name;
212 except:
213 return reporter.errorXcpt();
214
215 reporter.log('Closing session "%s" ...' % (sName,));
216 try:
217 self.oGuestSession.close();
218 self.oGuestSession = None;
219 except:
220 # Just log, don't assume an error here (will be done in the main loop then).
221 reporter.maybeErrXcpt(fIsError, 'Closing guest session "%s" failed:' % (sName,));
222 return False;
223 return True;
224
225class tdTestCopyFrom(tdTestGuestCtrlBase):
226 """
227 Test for copying files from the guest to the host.
228 """
229 def __init__(self, sSrc = "", sDst = "", sUser = None, sPassword = None, fFlags = None):
230 tdTestGuestCtrlBase.__init__(self);
231 self.oCreds = tdCtxCreds(sUser, sPassword, sDomain = None);
232 self.sSrc = sSrc;
233 self.sDst = sDst;
234 self.fFlags = fFlags;
235
236class tdTestCopyTo(tdTestGuestCtrlBase):
237 """
238 Test for copying files from the host to the guest.
239 """
240 def __init__(self, sSrc = "", sDst = "", sUser = None, sPassword = None, fFlags = None):
241 tdTestGuestCtrlBase.__init__(self);
242 self.oCreds = tdCtxCreds(sUser, sPassword, sDomain = None);
243 self.sSrc = sSrc;
244 self.sDst = sDst;
245 self.fFlags = fFlags;
246
247class tdTestDirCreate(tdTestGuestCtrlBase):
248 """
249 Test for directoryCreate call.
250 """
251 def __init__(self, sDirectory = "", sUser = None, sPassword = None, fMode = 0, fFlags = None):
252 tdTestGuestCtrlBase.__init__(self);
253 self.oCreds = tdCtxCreds(sUser, sPassword, sDomain = None);
254 self.sDirectory = sDirectory;
255 self.fMode = fMode;
256 self.fFlags = fFlags;
257
258class tdTestDirCreateTemp(tdTestGuestCtrlBase):
259 """
260 Test for the directoryCreateTemp call.
261 """
262 def __init__(self, sDirectory = "", sTemplate = "", sUser = None, sPassword = None, fMode = 0, fSecure = False):
263 tdTestGuestCtrlBase.__init__(self);
264 self.oCreds = tdCtxCreds(sUser, sPassword, sDomain = None);
265 self.sDirectory = sDirectory;
266 self.sTemplate = sTemplate;
267 self.fMode = fMode;
268 self.fSecure = fSecure;
269
270class tdTestDirOpen(tdTestGuestCtrlBase):
271 """
272 Test for the directoryOpen call.
273 """
274 def __init__(self, sDirectory = "", sUser = None, sPassword = None, sFilter = "", fFlags = None):
275 tdTestGuestCtrlBase.__init__(self);
276 self.oCreds = tdCtxCreds(sUser, sPassword, sDomain = None);
277 self.sDirectory = sDirectory;
278 self.sFilter = sFilter;
279 self.fFlags = fFlags or [];
280
281class tdTestDirRead(tdTestDirOpen):
282 """
283 Test for the opening, reading and closing a certain directory.
284 """
285 def __init__(self, sDirectory = "", sUser = None, sPassword = None,
286 sFilter = "", fFlags = None):
287 tdTestDirOpen.__init__(self, sDirectory, sUser, sPassword, sFilter, fFlags);
288
289class tdTestExec(tdTestGuestCtrlBase):
290 """
291 Specifies exactly one guest control execution test.
292 Has a default timeout of 5 minutes (for safety).
293 """
294 def __init__(self, sCmd = "", asArgs = None, aEnv = None, fFlags = None, # pylint: disable=too-many-arguments
295 timeoutMS = 5 * 60 * 1000, sUser = None, sPassword = None, sDomain = None, fWaitForExit = True):
296 tdTestGuestCtrlBase.__init__(self);
297 self.oCreds = tdCtxCreds(sUser, sPassword, sDomain);
298 self.sCmd = sCmd;
299 self.asArgs = asArgs if asArgs is not None else [sCmd,];
300 self.aEnv = aEnv;
301 self.fFlags = fFlags or [];
302 self.timeoutMS = timeoutMS;
303 self.fWaitForExit = fWaitForExit;
304 self.uExitStatus = 0;
305 self.iExitCode = 0;
306 self.cbStdOut = 0;
307 self.cbStdErr = 0;
308 self.sBuf = '';
309
310class tdTestFileExists(tdTestGuestCtrlBase):
311 """
312 Test for the file exists API call (fileExists).
313 """
314 def __init__(self, sFile = "", sUser = None, sPassword = None):
315 tdTestGuestCtrlBase.__init__(self);
316 self.oCreds = tdCtxCreds(sUser, sPassword, sDomain = None);
317 self.sFile = sFile;
318
319class tdTestFileRemove(tdTestGuestCtrlBase):
320 """
321 Test querying guest file information.
322 """
323 def __init__(self, sFile = "", sUser = None, sPassword = None):
324 tdTestGuestCtrlBase.__init__(self);
325 self.oCreds = tdCtxCreds(sUser, sPassword, sDomain = None);
326 self.sFile = sFile;
327
328class tdTestFileStat(tdTestGuestCtrlBase):
329 """
330 Test querying guest file information.
331 """
332 def __init__(self, sFile = "", sUser = None, sPassword = None, cbSize = 0, eFileType = 0):
333 tdTestGuestCtrlBase.__init__(self);
334 self.oCreds = tdCtxCreds(sUser, sPassword, sDomain = None);
335 self.sFile = sFile;
336 self.cbSize = cbSize;
337 self.eFileType = eFileType;
338
339class tdTestFileIO(tdTestGuestCtrlBase):
340 """
341 Test for the IGuestFile object.
342 """
343 def __init__(self, sFile = "", sUser = None, sPassword = None):
344 tdTestGuestCtrlBase.__init__(self);
345 self.oCreds = tdCtxCreds(sUser, sPassword, sDomain = None);
346 self.sFile = sFile;
347
348class tdTestFileQuerySize(tdTestGuestCtrlBase):
349 """
350 Test for the file size query API call (fileQuerySize).
351 """
352 def __init__(self, sFile = "", sUser = None, sPassword = None):
353 tdTestGuestCtrlBase.__init__(self);
354 self.oCreds = tdCtxCreds(sUser, sPassword, sDomain = None);
355 self.sFile = sFile;
356
357class tdTestFileReadWrite(tdTestGuestCtrlBase):
358 """
359 Tests reading from guest files.
360 """
361 def __init__(self, sFile = "", sUser = None, sPassword = None, sOpenMode = "r", # pylint: disable=too-many-arguments
362 sDisposition = "", sSharingMode = "", fCreationMode = 0, offFile = 0, cbToReadWrite = 0, abBuf = None):
363 tdTestGuestCtrlBase.__init__(self);
364 self.oCreds = tdCtxCreds(sUser, sPassword, sDomain = None);
365 self.sFile = sFile;
366 self.sOpenMode = sOpenMode;
367 self.sDisposition = sDisposition;
368 self.sSharingMode = sSharingMode;
369 self.fCreationMode = fCreationMode;
370 self.offFile = offFile;
371 self.cbToReadWrite = cbToReadWrite;
372 self.abBuf = abBuf;
373
374 def getOpenAction(self):
375 """ Converts string disposition to open action enum. """
376 if self.sDisposition == 'oe': return vboxcon.FileOpenAction_OpenExisting;
377 if self.sDisposition == 'oc': return vboxcon.FileOpenAction_OpenOrCreate;
378 if self.sDisposition == 'ce': return vboxcon.FileOpenAction_CreateNew;
379 if self.sDisposition == 'ca': return vboxcon.FileOpenAction_CreateOrReplace;
380 if self.sDisposition == 'ot': return vboxcon.FileOpenAction_OpenExistingTruncated;
381 if self.sDisposition == 'oa': return vboxcon.FileOpenAction_AppendOrCreate;
382 raise base.GenError(self.sDisposition);
383
384 def getAccessMode(self):
385 """ Converts open mode to access mode enum. """
386 if self.sOpenMode == 'r': return vboxcon.FileAccessMode_ReadOnly;
387 if self.sOpenMode == 'w': return vboxcon.FileAccessMode_WriteOnly;
388 if self.sOpenMode == 'w+': return vboxcon.FileAccessMode_ReadWrite;
389 if self.sOpenMode == 'r+': return vboxcon.FileAccessMode_ReadWrite;
390 raise base.GenError(self.sOpenMode);
391
392 def getSharingMode(self):
393 """ Converts the sharing mode. """
394 return vboxcon.FileSharingMode_All;
395
396class tdTestSession(tdTestGuestCtrlBase):
397 """
398 Test the guest session handling.
399 """
400 def __init__(self, sUser = None, sPassword = None, sDomain = None, sSessionName = ""):
401 tdTestGuestCtrlBase.__init__(self);
402 self.sSessionName = sSessionName;
403 self.oCreds = tdCtxCreds(sUser, sPassword, sDomain);
404
405 def getSessionCount(self, oVBoxMgr):
406 """
407 Helper for returning the number of currently
408 opened guest sessions of a VM.
409 """
410 if self.oTest.oGuest is None:
411 return 0;
412 try:
413 aoSession = oVBoxMgr.getArray(self.oTest.oGuest, 'sessions')
414 except:
415 reporter.errorXcpt('sSessionName: %s' % (self.sSessionName,));
416 return 0;
417 return len(aoSession);
418
419class tdTestSessionEx(tdTestGuestCtrlBase):
420 """
421 Test the guest session.
422 """
423 def __init__(self, aoSteps = None, enmUser = None):
424 tdTestGuestCtrlBase.__init__(self);
425 assert enmUser is None; # For later.
426 self.enmUser = enmUser;
427 self.aoSteps = aoSteps if aoSteps is not None else [];
428
429 def execute(self, oTstDrv, oVmSession, oTxsSession, oTestVm, sMsgPrefix):
430 """
431 Executes the test.
432 """
433 #
434 # Create a session.
435 #
436 assert self.enmUser is None; # For later.
437 self.oCreds = tdCtxCreds();
438 self.setEnvironment(oVmSession, oTxsSession, oTestVm);
439 reporter.log2('%s: %s steps' % (sMsgPrefix, len(self.aoSteps),));
440 fRc, oCurSession = self.createSession(sMsgPrefix);
441 if fRc is True:
442 #
443 # Execute the tests.
444 #
445 try:
446 fRc = self.executeSteps(oTstDrv, oCurSession, sMsgPrefix);
447 except:
448 fRc = reporter.errorXcpt('%s: Unexpected exception executing test steps' % (sMsgPrefix,));
449
450 #
451 # Close the session.
452 #
453 fRc2 = self.closeSession(True);
454 if fRc2 is False:
455 fRc = reporter.error('%s: Session could not be closed' % (sMsgPrefix,));
456 else:
457 fRc = reporter.error('%s: Session creation failed' % (sMsgPrefix,));
458 return fRc;
459
460 def executeSteps(self, oTstDrv, oGstCtrlSession, sMsgPrefix):
461 """
462 Executes just the steps.
463 Returns True on success, False on test failure.
464 """
465 fRc = True;
466 for (i, oStep) in enumerate(self.aoSteps):
467 fRc2 = oStep.execute(oTstDrv, oGstCtrlSession, sMsgPrefix + ', step #%d' % i);
468 if fRc2 is True:
469 pass;
470 elif fRc2 is None:
471 reporter.log('%s: skipping remaining %d steps' % (sMsgPrefix, len(self.aoSteps) - i - 1,));
472 break;
473 else:
474 fRc = False;
475 return fRc;
476
477 @staticmethod
478 def executeListTestSessions(aoTests, oTstDrv, oVmSession, oTxsSession, oTestVm, sMsgPrefix):
479 """
480 Works thru a list of tdTestSessionEx object.
481 """
482 fRc = True;
483 for (i, oCurTest) in enumerate(aoTests):
484 try:
485 fRc2 = oCurTest.execute(oTstDrv, oVmSession, oTxsSession, oTestVm, '%s / %#d' % (sMsgPrefix, i,));
486 if fRc2 is not True:
487 fRc = False;
488 except:
489 fRc = reporter.errorXcpt('%s: Unexpected exception executing test #%d' % (sMsgPrefix, i ,));
490
491 return (fRc, oTxsSession);
492
493
494class tdSessionStepBase(object):
495 """
496 Base class for the guest control session test steps.
497 """
498
499 def execute(self, oTstDrv, oGstCtrlSession, sMsgPrefix):
500 """
501 Executes the test step.
502
503 Returns True on success.
504 Returns False on failure (must be reported as error).
505 Returns None if to skip the remaining steps.
506 """
507 _ = oTstDrv;
508 _ = oGstCtrlSession;
509 return reporter.error('%s: Missing execute implementation: %s' % (sMsgPrefix, self,));
510
511
512class tdStepRequireMinimumApiVer(tdSessionStepBase):
513 """
514 Special test step which will cause executeSteps to skip the remaining step
515 if the VBox API is too old:
516 """
517 def __init__(self, fpMinApiVer):
518 self.fpMinApiVer = fpMinApiVer;
519
520 def execute(self, oTstDrv, oGstCtrlSession, sMsgPrefix):
521 """ Returns None if API version is too old, otherwise True. """
522 if oTstDrv.fpApiVer >= self.fpMinApiVer:
523 return True;
524 _ = oGstCtrlSession;
525 _ = sMsgPrefix;
526 return None; # Special return value. Don't use elsewhere.
527
528
529#
530# Scheduling Environment Changes with the Guest Control Session.
531#
532
533class tdStepSessionSetEnv(tdSessionStepBase):
534 """
535 Guest session environment: schedule putenv
536 """
537 def __init__(self, sVar, sValue, hrcExpected = 0):
538 self.sVar = sVar;
539 self.sValue = sValue;
540 self.hrcExpected = hrcExpected;
541
542 def execute(self, oTstDrv, oGstCtrlSession, sMsgPrefix):
543 """
544 Executes the step.
545 Returns True on success, False on test failure.
546 """
547 reporter.log2('tdStepSessionSetEnv: sVar=%s sValue=%s hrcExpected=%#x' % (self.sVar, self.sValue, self.hrcExpected,));
548 try:
549 if oTstDrv.fpApiVer >= 5.0:
550 oGstCtrlSession.environmentScheduleSet(self.sVar, self.sValue);
551 else:
552 oGstCtrlSession.environmentSet(self.sVar, self.sValue);
553 except vbox.ComException as oXcpt:
554 # Is this an expected failure?
555 if vbox.ComError.equal(oXcpt, self.hrcExpected):
556 return True;
557 return reporter.errorXcpt('%s: Expected hrc=%#x (%s) got %#x (%s) instead (setenv %s=%s)'
558 % (sMsgPrefix, self.hrcExpected, vbox.ComError.toString(self.hrcExpected),
559 vbox.ComError.getXcptResult(oXcpt),
560 vbox.ComError.toString(vbox.ComError.getXcptResult(oXcpt)),
561 self.sVar, self.sValue,));
562 except:
563 return reporter.errorXcpt('%s: Unexpected exception in tdStepSessionSetEnv::execute (%s=%s)'
564 % (sMsgPrefix, self.sVar, self.sValue,));
565
566 # Should we succeed?
567 if self.hrcExpected != 0:
568 return reporter.error('%s: Expected hrcExpected=%#x, got S_OK (putenv %s=%s)'
569 % (sMsgPrefix, self.hrcExpected, self.sVar, self.sValue,));
570 return True;
571
572class tdStepSessionUnsetEnv(tdSessionStepBase):
573 """
574 Guest session environment: schedule unset.
575 """
576 def __init__(self, sVar, hrcExpected = 0):
577 self.sVar = sVar;
578 self.hrcExpected = hrcExpected;
579
580 def execute(self, oTstDrv, oGstCtrlSession, sMsgPrefix):
581 """
582 Executes the step.
583 Returns True on success, False on test failure.
584 """
585 reporter.log2('tdStepSessionUnsetEnv: sVar=%s hrcExpected=%#x' % (self.sVar, self.hrcExpected,));
586 try:
587 if oTstDrv.fpApiVer >= 5.0:
588 oGstCtrlSession.environmentScheduleUnset(self.sVar);
589 else:
590 oGstCtrlSession.environmentUnset(self.sVar);
591 except vbox.ComException as oXcpt:
592 # Is this an expected failure?
593 if vbox.ComError.equal(oXcpt, self.hrcExpected):
594 return True;
595 return reporter.errorXcpt('%s: Expected hrc=%#x (%s) got %#x (%s) instead (unsetenv %s)'
596 % (sMsgPrefix, self.hrcExpected, vbox.ComError.toString(self.hrcExpected),
597 vbox.ComError.getXcptResult(oXcpt),
598 vbox.ComError.toString(vbox.ComError.getXcptResult(oXcpt)),
599 self.sVar,));
600 except:
601 return reporter.errorXcpt('%s: Unexpected exception in tdStepSessionUnsetEnv::execute (%s)'
602 % (sMsgPrefix, self.sVar,));
603
604 # Should we succeed?
605 if self.hrcExpected != 0:
606 return reporter.error('%s: Expected hrcExpected=%#x, got S_OK (unsetenv %s)'
607 % (sMsgPrefix, self.hrcExpected, self.sVar,));
608 return True;
609
610class tdStepSessionBulkEnv(tdSessionStepBase):
611 """
612 Guest session environment: Bulk environment changes.
613 """
614 def __init__(self, asEnv = None, hrcExpected = 0):
615 self.asEnv = asEnv if asEnv is not None else [];
616 self.hrcExpected = hrcExpected;
617
618 def execute(self, oTstDrv, oGstCtrlSession, sMsgPrefix):
619 """
620 Executes the step.
621 Returns True on success, False on test failure.
622 """
623 reporter.log2('tdStepSessionBulkEnv: asEnv=%s hrcExpected=%#x' % (self.asEnv, self.hrcExpected,));
624 try:
625 if oTstDrv.fpApiVer >= 5.0:
626 oTstDrv.oVBoxMgr.setArray(oGstCtrlSession, 'environmentChanges', self.asEnv);
627 else:
628 oTstDrv.oVBoxMgr.setArray(oGstCtrlSession, 'environment', self.asEnv);
629 except vbox.ComException as oXcpt:
630 # Is this an expected failure?
631 if vbox.ComError.equal(oXcpt, self.hrcExpected):
632 return True;
633 return reporter.errorXcpt('%s: Expected hrc=%#x (%s) got %#x (%s) instead (asEnv=%s)'
634 % (sMsgPrefix, self.hrcExpected, vbox.ComError.toString(self.hrcExpected),
635 vbox.ComError.getXcptResult(oXcpt),
636 vbox.ComError.toString(vbox.ComError.getXcptResult(oXcpt)),
637 self.asEnv,));
638 except:
639 return reporter.errorXcpt('%s: Unexpected exception writing the environmentChanges property (asEnv=%s).'
640 % (sMsgPrefix, self.asEnv));
641 return True;
642
643class tdStepSessionClearEnv(tdStepSessionBulkEnv):
644 """
645 Guest session environment: clears the scheduled environment changes.
646 """
647 def __init__(self):
648 tdStepSessionBulkEnv.__init__(self);
649
650
651class tdStepSessionCheckEnv(tdSessionStepBase):
652 """
653 Check the currently scheduled environment changes of a guest control session.
654 """
655 def __init__(self, asEnv = None):
656 self.asEnv = asEnv if asEnv is not None else [];
657
658 def execute(self, oTstDrv, oGstCtrlSession, sMsgPrefix):
659 """
660 Executes the step.
661 Returns True on success, False on test failure.
662 """
663 reporter.log2('tdStepSessionCheckEnv: asEnv=%s' % (self.asEnv,));
664
665 #
666 # Get the environment change list.
667 #
668 try:
669 if oTstDrv.fpApiVer >= 5.0:
670 asCurEnv = oTstDrv.oVBoxMgr.getArray(oGstCtrlSession, 'environmentChanges');
671 else:
672 asCurEnv = oTstDrv.oVBoxMgr.getArray(oGstCtrlSession, 'environment');
673 except:
674 return reporter.errorXcpt('%s: Unexpected exception reading the environmentChanges property.' % (sMsgPrefix,));
675
676 #
677 # Compare it with the expected one by trying to remove each expected value
678 # and the list anything unexpected.
679 #
680 fRc = True;
681 asCopy = list(asCurEnv); # just in case asCurEnv is immutable
682 for sExpected in self.asEnv:
683 try:
684 asCopy.remove(sExpected);
685 except:
686 fRc = reporter.error('%s: Expected "%s" to be in the resulting environment' % (sMsgPrefix, sExpected,));
687 for sUnexpected in asCopy:
688 fRc = reporter.error('%s: Unexpected "%s" in the resulting environment' % (sMsgPrefix, sUnexpected,));
689
690 if fRc is not True:
691 reporter.log2('%s: Current environment: %s' % (sMsgPrefix, asCurEnv));
692 return fRc;
693
694
695#
696# File system object statistics (i.e. stat()).
697#
698
699class tdStepStat(tdSessionStepBase):
700 """
701 Stats a file system object.
702 """
703 def __init__(self, sPath, hrcExpected = 0, fFound = True, fFollowLinks = True, enmType = None):
704 self.sPath = sPath;
705 self.hrcExpected = hrcExpected;
706 self.fFound = fFound;
707 self.fFollowLinks = fFollowLinks;
708 self.enmType = enmType if enmType is not None else vboxcon.FsObjType_File;
709 self.cbExactSize = None;
710 self.cbMinSize = None;
711
712 def execute(self, oTstDrv, oGstCtrlSession, sMsgPrefix):
713 """
714 Execute the test step.
715 """
716 reporter.log2('tdStepStat: sPath=%s enmType=%s hrcExpected=%s fFound=%s fFollowLinks=%s'
717 % (self.sPath, self.enmType, self.hrcExpected, self.fFound, self.fFollowLinks,));
718
719 # Don't execute non-file tests on older VBox version.
720 if oTstDrv.fpApiVer >= 5.0 or self.enmType == vboxcon.FsObjType_File or not self.fFound:
721 #
722 # Call the API.
723 #
724 try:
725 if oTstDrv.fpApiVer >= 5.0:
726 oFsInfo = oGstCtrlSession.fsObjQueryInfo(self.sPath, self.fFollowLinks);
727 else:
728 oFsInfo = oGstCtrlSession.fileQueryInfo(self.sPath);
729 except vbox.ComException as oXcpt:
730 ## @todo: The error reporting in the API just plain sucks! Most of the errors are
731 ## VBOX_E_IPRT_ERROR and there seems to be no way to distinguish between
732 ## non-existing files/path and a lot of other errors. Fix API and test!
733 if not self.fFound:
734 return True;
735 if vbox.ComError.equal(oXcpt, self.hrcExpected): # Is this an expected failure?
736 return True;
737 return reporter.errorXcpt('%s: Unexpected exception for exiting path "%s" (enmType=%s, hrcExpected=%s):'
738 % (sMsgPrefix, self.sPath, self.enmType, self.hrcExpected,));
739 except:
740 return reporter.errorXcpt('%s: Unexpected exception in tdStepStat::execute (%s)'
741 % (sMsgPrefix, self.sPath,));
742 if oFsInfo is None:
743 return reporter.error('%s: "%s" got None instead of IFsObjInfo instance!' % (sMsgPrefix, self.sPath,));
744
745 #
746 # Check type expectations.
747 #
748 try:
749 enmType = oFsInfo.type;
750 except:
751 return reporter.errorXcpt('%s: Unexpected exception in reading "IFsObjInfo::type"' % (sMsgPrefix,));
752 if enmType != self.enmType:
753 return reporter.error('%s: "%s" has type %s, expected %s'
754 % (sMsgPrefix, self.sPath, enmType, self.enmType));
755
756 #
757 # Check size expectations.
758 # Note! This is unicode string here on windows, for some reason.
759 # long long mapping perhaps?
760 #
761 try:
762 cbObject = long(oFsInfo.objectSize);
763 except:
764 return reporter.errorXcpt('%s: Unexpected exception in reading "IFsObjInfo::objectSize"'
765 % (sMsgPrefix,));
766 if self.cbExactSize is not None \
767 and cbObject != self.cbExactSize:
768 return reporter.error('%s: "%s" has size %s bytes, expected %s bytes'
769 % (sMsgPrefix, self.sPath, cbObject, self.cbExactSize));
770 if self.cbMinSize is not None \
771 and cbObject < self.cbMinSize:
772 return reporter.error('%s: "%s" has size %s bytes, expected as least %s bytes'
773 % (sMsgPrefix, self.sPath, cbObject, self.cbMinSize));
774 return True;
775
776class tdStepStatDir(tdStepStat):
777 """ Checks for an existing directory. """
778 def __init__(self, sDirPath):
779 tdStepStat.__init__(self, sPath = sDirPath, enmType = vboxcon.FsObjType_Directory);
780
781class tdStepStatFile(tdStepStat):
782 """ Checks for an existing file """
783 def __init__(self, sFilePath):
784 tdStepStat.__init__(self, sPath = sFilePath, enmType = vboxcon.FsObjType_File);
785
786class tdStepStatFileSize(tdStepStat):
787 """ Checks for an existing file of a given expected size.. """
788 def __init__(self, sFilePath, cbExactSize = 0):
789 tdStepStat.__init__(self, sPath = sFilePath, enmType = vboxcon.FsObjType_File);
790 self.cbExactSize = cbExactSize;
791
792class tdStepStatFileNotFound(tdStepStat):
793 """ Checks for an existing directory. """
794 def __init__(self, sPath):
795 tdStepStat.__init__(self, sPath = sPath, fFound = False);
796
797class tdStepStatPathNotFound(tdStepStat):
798 """ Checks for an existing directory. """
799 def __init__(self, sPath):
800 tdStepStat.__init__(self, sPath = sPath, fFound = False);
801
802
803#
804#
805#
806
807class tdTestSessionFileRefs(tdTestGuestCtrlBase):
808 """
809 Tests session file (IGuestFile) reference counting.
810 """
811 def __init__(self, cRefs = 0):
812 tdTestGuestCtrlBase.__init__(self);
813 self.cRefs = cRefs;
814
815class tdTestSessionDirRefs(tdTestGuestCtrlBase):
816 """
817 Tests session directory (IGuestDirectory) reference counting.
818 """
819 def __init__(self, cRefs = 0):
820 tdTestGuestCtrlBase.__init__(self);
821 self.cRefs = cRefs;
822
823class tdTestSessionProcRefs(tdTestGuestCtrlBase):
824 """
825 Tests session process (IGuestProcess) reference counting.
826 """
827 def __init__(self, cRefs = 0):
828 tdTestGuestCtrlBase.__init__(self);
829 self.cRefs = cRefs;
830
831class tdTestUpdateAdditions(tdTestGuestCtrlBase):
832 """
833 Test updating the Guest Additions inside the guest.
834 """
835 def __init__(self, sSrc = "", asArgs = None, fFlags = None,
836 sUser = None, sPassword = None, sDomain = None):
837 tdTestGuestCtrlBase.__init__(self);
838 self.oCreds = tdCtxCreds(sUser, sPassword, sDomain);
839 self.sSrc = sSrc;
840 self.asArgs = asArgs;
841 self.fFlags = fFlags;
842
843class tdTestResult(object):
844 """
845 Base class for test results.
846 """
847 def __init__(self, fRc = False):
848 ## The overall test result.
849 self.fRc = fRc;
850
851class tdTestResultFailure(tdTestResult):
852 """
853 Base class for test results.
854 """
855 def __init__(self):
856 tdTestResult.__init__(self, fRc = False);
857
858class tdTestResultSuccess(tdTestResult):
859 """
860 Base class for test results.
861 """
862 def __init__(self):
863 tdTestResult.__init__(self, fRc = True);
864
865class tdTestResultDirRead(tdTestResult):
866 """
867 Test result for reading guest directories.
868 """
869 def __init__(self, fRc = False, cFiles = 0, cDirs = 0, cOthers = None):
870 tdTestResult.__init__(self, fRc = fRc);
871 self.cFiles = cFiles;
872 self.cDirs = cDirs;
873 self.cOthers = cOthers;
874
875class tdTestResultExec(tdTestResult):
876 """
877 Holds a guest process execution test result,
878 including the exit code, status + fFlags.
879 """
880 def __init__(self, fRc = False, uExitStatus = 500, iExitCode = 0, sBuf = None, cbBuf = 0, cbStdOut = None, cbStdErr = None):
881 tdTestResult.__init__(self);
882 ## The overall test result.
883 self.fRc = fRc;
884 ## Process exit stuff.
885 self.uExitStatus = uExitStatus;
886 self.iExitCode = iExitCode;
887 ## Desired buffer length returned back from stdout/stderr.
888 self.cbBuf = cbBuf;
889 ## Desired buffer result from stdout/stderr. Use with caution!
890 self.sBuf = sBuf;
891 self.cbStdOut = cbStdOut;
892 self.cbStdErr = cbStdErr;
893
894class tdTestResultFileStat(tdTestResult):
895 """
896 Test result for stat'ing guest files.
897 """
898 def __init__(self, fRc = False,
899 cbSize = 0, eFileType = 0):
900 tdTestResult.__init__(self, fRc = fRc);
901 self.cbSize = cbSize;
902 self.eFileType = eFileType;
903 ## @todo Add more information.
904
905class tdTestResultFileReadWrite(tdTestResult):
906 """
907 Test result for reading + writing guest directories.
908 """
909 def __init__(self, fRc = False,
910 cbProcessed = 0, offFile = 0, abBuf = None):
911 tdTestResult.__init__(self, fRc = fRc);
912 self.cbProcessed = cbProcessed;
913 self.offFile = offFile;
914 self.abBuf = abBuf;
915
916class tdTestResultSession(tdTestResult):
917 """
918 Test result for guest session counts.
919 """
920 def __init__(self, fRc = False, cNumSessions = 0):
921 tdTestResult.__init__(self, fRc = fRc);
922 self.cNumSessions = cNumSessions;
923
924
925class SubTstDrvAddGuestCtrl(base.SubTestDriverBase):
926 """
927 Sub-test driver for executing guest control (VBoxService, IGuest) tests.
928 """
929
930 def __init__(self, oTstDrv):
931 base.SubTestDriverBase.__init__(self, oTstDrv, 'add-guest-ctrl', 'Guest Control');
932
933 ## @todo base.TestBase.
934 self.asTestsDef = \
935 [
936 'session_basic', 'session_env', 'session_file_ref', 'session_dir_ref', 'session_proc_ref', 'session_reboot',
937 'exec_basic', 'exec_timeout',
938 'dir_create', 'dir_create_temp', 'dir_read',
939 'file_remove', 'file_stat', 'file_read', 'file_write',
940 'copy_to', 'copy_from',
941 'update_additions'
942 ];
943 self.asTests = self.asTestsDef;
944 self.asRsrcs = ['5.3/guestctrl/50mb_rnd.dat', ];
945 self.oTestFiles = None # type: vboxtestfileset.TestFileSet
946
947 def parseOption(self, asArgs, iArg): # pylint: disable=too-many-branches,too-many-statements
948 if asArgs[iArg] == '--add-guest-ctrl-tests':
949 iArg += 1;
950 iNext = self.oTstDrv.requireMoreArgs(1, asArgs, iArg);
951 if asArgs[iArg] == 'all': # Nice for debugging scripts.
952 self.asTests = self.asTestsDef;
953 else:
954 self.asTests = asArgs[iArg].split(':');
955 for s in self.asTests:
956 if s not in self.asTestsDef:
957 raise base.InvalidOption('The "--add-guest-ctrl-tests" value "%s" is not valid; valid values are: %s'
958 % (s, ' '.join(self.asTestsDef)));
959 return iNext;
960 return iArg;
961
962 def showUsage(self):
963 base.SubTestDriverBase.showUsage(self);
964 reporter.log(' --add-guest-ctrl-tests <s1[:s2[:]]>');
965 reporter.log(' Default: %s (all)' % (':'.join(self.asTestsDef)));
966 return True;
967
968 def testIt(self, oTestVm, oSession, oTxsSession):
969 """
970 Executes the test.
971
972 Returns fRc, oTxsSession. The latter may have changed.
973 """
974 reporter.log("Active tests: %s" % (self.asTests,));
975
976 # The tests. Must-succeed tests should be first.
977 atTests = [
978 ( True, self.prepareGuestForTesting, None, 'Preparations',),
979 ( True, self.testGuestCtrlSession, 'session_basic', 'Session Basics',),
980 ( True, self.testGuestCtrlExec, 'exec_basic', 'Execution',),
981 ( False, self.testGuestCtrlExecTimeout, 'exec_timeout', 'Execution Timeouts',),
982 ( False, self.testGuestCtrlSessionEnvironment, 'session_env', 'Session Environment',),
983 ( False, self.testGuestCtrlSessionFileRefs, 'session_file_ref', 'Session File References',),
984 #( False, self.testGuestCtrlSessionDirRefs, 'session_dir_ref', 'Session Directory References',),
985 ( False, self.testGuestCtrlSessionProcRefs, 'session_proc_ref', 'Session Process References',),
986 ( False, self.testGuestCtrlDirCreate, 'dir_create', 'Creating directories',),
987 ( False, self.testGuestCtrlDirCreateTemp, 'dir_create_temp', 'Creating temporary directories',),
988 ( False, self.testGuestCtrlDirRead, 'dir_read', 'Reading directories',),
989 ( False, self.testGuestCtrlCopyTo, 'copy_to', 'Copy to guest',),
990 ( False, self.testGuestCtrlCopyFrom, 'copy_from', 'Copy from guest',),
991 ( False, self.testGuestCtrlFileStat, 'file_stat', 'Querying file information (stat)',),
992 ( False, self.testGuestCtrlFileRead, 'file_read', 'File read',),
993 ( False, self.testGuestCtrlFileWrite, 'file_write', 'File write',),
994 ( False, self.testGuestCtrlFileRemove, 'file_remove', 'Removing files',), # Destroys prepped files.
995 ( False, self.testGuestCtrlSessionReboot, 'session_reboot', 'Session w/ Guest Reboot',), # May zap /tmp.
996 ( False, self.testGuestCtrlUpdateAdditions, 'update_additions', 'Updating Guest Additions',),
997 ];
998
999 fRc = True;
1000 for fMustSucceed, fnHandler, sShortNm, sTestNm in atTests:
1001 reporter.testStart(sTestNm);
1002
1003 if sShortNm is None or sShortNm in self.asTests:
1004 # Returns (fRc, oTxsSession, oSession) - but only the first one is mandatory.
1005 aoResult = fnHandler(oSession, oTxsSession, oTestVm);
1006 if aoResult is None or isinstance(aoResult, bool):
1007 fRcTest = aoResult;
1008 else:
1009 fRcTest = aoResult[0];
1010 if len(aoResult) > 1:
1011 oTxsSession = aoResult[1];
1012 if len(aoResult) > 2:
1013 oSession = aoResult[2];
1014 assert len(aoResult) == 3;
1015 else:
1016 fRcTest = None;
1017
1018 if fRcTest is False and reporter.testErrorCount() != 0:
1019 fRcTest = reporter.error('Buggy test! Returned False w/o logging the error!');
1020 if reporter.testDone(fRcTest is None)[1] != 0:
1021 fRcTest = False;
1022 fRc = False;
1023
1024 # Stop execution if this is a must-succeed test and it failed.
1025 if fRcTest is False and fMustSucceed is True:
1026 reporter.log('Skipping any remaining tests since the previous one failed.');
1027 break;
1028
1029 return (fRc, oTxsSession);
1030
1031 #
1032 # Guest locations.
1033 #
1034
1035 @staticmethod
1036 def getGuestTempDir(oTestVm):
1037 """
1038 Helper for finding a temporary directory in the test VM.
1039
1040 Note! It may be necessary to create it!
1041 """
1042 if oTestVm.isWindows():
1043 return "C:\\Temp";
1044 if oTestVm.isOS2():
1045 return "C:\\Temp";
1046 return '/var/tmp';
1047
1048 @staticmethod
1049 def getGuestSystemDir(oTestVm):
1050 """
1051 Helper for finding a system directory in the test VM that we can play around with.
1052
1053 On Windows this is always the System32 directory, so this function can be used as
1054 basis for locating other files in or under that directory.
1055 """
1056 if oTestVm.isWindows():
1057 if oTestVm.sKind in ['WindowsNT4', 'WindowsNT3x',]:
1058 return 'C:\\Winnt\\System32';
1059 return 'C:\\Windows\\System32';
1060 if oTestVm.isOS2():
1061 return 'C:\\OS2\\DLL';
1062 return "/bin";
1063
1064 @staticmethod
1065 def getGuestSystemShell(oTestVm):
1066 """
1067 Helper for finding the default system shell in the test VM.
1068 """
1069 if oTestVm.isWindows():
1070 return SubTstDrvAddGuestCtrl.getGuestSystemDir(oTestVm) + '\\cmd.exe';
1071 if oTestVm.isOS2():
1072 return SubTstDrvAddGuestCtrl.getGuestSystemDir(oTestVm) + '\\..\\CMD.EXE';
1073 return "/bin/sh";
1074
1075 @staticmethod
1076 def getGuestSystemFileForReading(oTestVm):
1077 """
1078 Helper for finding a file in the test VM that we can read.
1079 """
1080 if oTestVm.isWindows():
1081 return SubTstDrvAddGuestCtrl.getGuestSystemDir(oTestVm) + '\\ntdll.dll';
1082 if oTestVm.isOS2():
1083 return SubTstDrvAddGuestCtrl.getGuestSystemDir(oTestVm) + '\\DOSCALL1.DLL';
1084 return "/bin/sh";
1085
1086 #
1087 # Guest test files.
1088 #
1089
1090 def prepareGuestForTesting(self, oSession, oTxsSession, oTestVm):
1091 """
1092 Prepares the VM for testing, uploading a bunch of files and stuff via TXS.
1093 Returns success indicator.
1094 """
1095 _ = oSession;
1096
1097 #reporter.log('Take snapshot now!');
1098 #self.oTstDrv.sleep(22);
1099 #return False;
1100
1101 # Make sure the temporary directory exists.
1102 for sDir in [self.getGuestTempDir(oTestVm), ]:
1103 if oTxsSession.syncMkDirPath(sDir, 0o777) is not True:
1104 return reporter.error('Failed to create directory "%s"!' % (sDir,));
1105
1106 # Generate and upload some random files and dirs to the guest:
1107 self.oTestFiles = vboxtestfileset.TestFileSet(oTestVm, self.getGuestTempDir(oTestVm), 'addgst-1');
1108 return self.oTestFiles.upload(oTxsSession, self.oTstDrv);
1109
1110
1111 #
1112 # gctrlXxxx stuff.
1113 #
1114
1115 def gctrlCopyFileFrom(self, oGuestSession, sSrc, sDst, fFlags, fExpected):
1116 """
1117 Helper function to copy a single file from the guest to the host.
1118 """
1119 reporter.log2('Copying guest file "%s" to host "%s"' % (sSrc, sDst));
1120 try:
1121 if self.oTstDrv.fpApiVer >= 5.0:
1122 oCurProgress = oGuestSession.fileCopyFromGuest(sSrc, sDst, fFlags);
1123 else:
1124 oCurProgress = oGuestSession.copyFrom(sSrc, sDst, fFlags);
1125 except:
1126 reporter.maybeErrXcpt(fExpected, 'Copy from exception for sSrc="%s", sDst="%s":' % (sSrc, sDst,));
1127 return False;
1128 if oCurProgress is None:
1129 return reporter.error('No progress object returned');
1130 oProgress = vboxwrappers.ProgressWrapper(oCurProgress, self.oTstDrv.oVBoxMgr, self.oTstDrv, "gctrlFileCopyFrom");
1131 oProgress.wait();
1132 if not oProgress.isSuccess():
1133 oProgress.logResult(fIgnoreErrors = not fExpected);
1134 return False;
1135 return True;
1136
1137 def gctrlCopyDirFrom(self, oGuestSession, sSrc, sDst, fFlags, fExpected):
1138 """
1139 Helper function to copy a directory from the guest to the host.
1140 """
1141 reporter.log2('Copying guest dir "%s" to host "%s"' % (sSrc, sDst));
1142 try:
1143 oCurProgress = oGuestSession.directoryCopyFromGuest(sSrc, sDst, fFlags);
1144 except:
1145 reporter.maybeErrXcpt(fExpected, 'Copy dir from exception for sSrc="%s", sDst="%s":' % (sSrc, sDst,));
1146 return False;
1147 if oCurProgress is None:
1148 return reporter.error('No progress object returned');
1149
1150 oProgress = vboxwrappers.ProgressWrapper(oCurProgress, self.oTstDrv.oVBoxMgr, self.oTstDrv, "gctrlDirCopyFrom");
1151 oProgress.wait();
1152 if not oProgress.isSuccess():
1153 oProgress.logResult(fIgnoreErrors = not fExpected);
1154 return False;
1155 return True;
1156
1157 def gctrlCopyFileTo(self, oGuestSession, sSrc, sDst, fFlags):
1158 """
1159 Helper function to copy a single file from host to the guest.
1160 """
1161 fRc = True; # Be optimistic.
1162 try:
1163 reporter.log2('Copying host file "%s" to guest "%s" (flags %s)' % (sSrc, sDst, fFlags));
1164 if self.oTstDrv.fpApiVer >= 5.0:
1165 oCurProgress = oGuestSession.fileCopyToGuest(sSrc, sDst, fFlags);
1166 else:
1167 oCurProgress = oGuestSession.copyTo(sSrc, sDst, fFlags);
1168 if oCurProgress is not None:
1169 oProgress = vboxwrappers.ProgressWrapper(oCurProgress, self.oTstDrv.oVBoxMgr, self.oTstDrv, "gctrlCopyFileTo");
1170 try:
1171 oProgress.wait();
1172 if not oProgress.isSuccess():
1173 oProgress.logResult(fIgnoreErrors = True);
1174 fRc = False;
1175 except:
1176 reporter.logXcpt('Wait exception for sSrc="%s", sDst="%s":' % (sSrc, sDst));
1177 fRc = False;
1178 else:
1179 reporter.error('No progress object returned');
1180 fRc = False;
1181 except:
1182 # Just log, don't assume an error here (will be done in the main loop then).
1183 reporter.logXcpt('Copy to exception for sSrc="%s", sDst="%s":' % (sSrc, sDst));
1184 fRc = False;
1185
1186 return fRc;
1187
1188 def gctrlCreateDir(self, oTest, oRes, oGuestSession):
1189 """
1190 Helper function to create a guest directory specified in the current test.
1191 """
1192 reporter.log2('Creating directory "%s"' % (oTest.sDirectory,));
1193 try:
1194 oGuestSession.directoryCreate(oTest.sDirectory, oTest.fMode, oTest.fFlags);
1195 except:
1196 reporter.maybeErrXcpt(oRes.fRc, 'Failed to create "%s" fMode=%o fFlags=%s'
1197 % (oTest.sDirectory, oTest.fMode, oTest.fFlags,));
1198 return not oRes.fRc;
1199 if oRes.fRc is not True:
1200 return reporter.error('Did not expect to create directory "%s"!' % (oTest.sDirectory,));
1201
1202 # Check if the directory now exists.
1203 try:
1204 if self.oTstDrv.fpApiVer >= 5.0:
1205 fDirExists = oGuestSession.directoryExists(oTest.sDirectory, False);
1206 else:
1207 fDirExists = oGuestSession.directoryExists(oTest.sDirectory);
1208 except:
1209 return reporter.errorXcpt('directoryExists failed on "%s"!' % (oTest.sDirectory,));
1210 if not fDirExists:
1211 return reporter.errorXcpt('directoryExists returned False on "%s" after directoryCreate succeeded!'
1212 % (oTest.sDirectory,));
1213 return True;
1214
1215 def gctrlReadDirTree(self, oTest, oGuestSession, fIsError, sSubDir = None):
1216 """
1217 Helper function to recursively read a guest directory tree specified in the current test.
1218 """
1219 sDir = oTest.sDirectory;
1220 sFilter = oTest.sFilter;
1221 fFlags = oTest.fFlags;
1222 oTestVm = oTest.oCreds.oTestVm;
1223 sCurDir = oTestVm.pathJoin(sDir, sSubDir) if sSubDir else sDir;
1224
1225 fRc = True; # Be optimistic.
1226 cDirs = 0; # Number of directories read.
1227 cFiles = 0; # Number of files read.
1228 cOthers = 0; # Other files.
1229
1230 ##
1231 ## @todo r=bird: Unlike fileOpen, directoryOpen will not fail if the directory does not exist.
1232 ## This is of course a bug in the implementation, as it is documented to return
1233 ## VBOX_E_OBJECT_NOT_FOUND or VBOX_E_IPRT_ERROR!
1234 ##
1235
1236 # Open the directory:
1237 #reporter.log2('Directory="%s", filter="%s", fFlags="%s"' % (sCurDir, sFilter, fFlags));
1238 try:
1239 oCurDir = oGuestSession.directoryOpen(sCurDir, sFilter, fFlags);
1240 except:
1241 reporter.maybeErrXcpt(fIsError, 'sCurDir=%s sFilter=%s fFlags=%s' % (sCurDir, sFilter, fFlags,))
1242 return (False, 0, 0, 0);
1243
1244 # Read the directory.
1245 while fRc is True:
1246 try:
1247 oFsObjInfo = oCurDir.read();
1248 except Exception as oXcpt:
1249 if vbox.ComError.notEqual(oXcpt, vbox.ComError.VBOX_E_OBJECT_NOT_FOUND):
1250 ##
1251 ## @todo r=bird: Change this to reporter.errorXcpt() once directoryOpen() starts
1252 ## working the way it is documented.
1253 ##
1254 reporter.maybeErrXcpt(fIsError, 'Error reading directory "%s":' % (sCurDir,)); # See above why 'maybe'.
1255 fRc = False;
1256 #else: reporter.log2('\tNo more directory entries for "%s"' % (sCurDir,));
1257 break;
1258
1259 try:
1260 sName = oFsObjInfo.name;
1261 eType = oFsObjInfo.type;
1262 except:
1263 fRc = reporter.errorXcpt();
1264 break;
1265
1266 if sName in ('.', '..', ):
1267 if eType != vboxcon.FsObjType_Directory:
1268 fRc = reporter.error('Wrong type for "%s": %d, expected %d (Directory)'
1269 % (sName, eType, vboxcon.FsObjType_Directory));
1270 elif eType == vboxcon.FsObjType_Directory:
1271 #reporter.log2(' Directory "%s"' % oFsObjInfo.name);
1272 aSubResult = self.gctrlReadDirTree(oTest, oGuestSession, fIsError,
1273 oTestVm.pathJoin(sSubDir, sName) if sSubDir else sName);
1274 fRc = aSubResult[0];
1275 cDirs += aSubResult[1] + 1;
1276 cFiles += aSubResult[2];
1277 cOthers += aSubResult[3];
1278 elif eType is vboxcon.FsObjType_File:
1279 #reporter.log2(' File "%s"' % oFsObjInfo.name);
1280 cFiles += 1;
1281 elif eType is vboxcon.FsObjType_Symlink:
1282 #reporter.log2(' Symlink "%s" -- not tested yet' % oFsObjInfo.name);
1283 cOthers += 1;
1284 elif oTestVm.isWindows() \
1285 or oTestVm.isOS2() \
1286 or eType not in (vboxcon.FsObjType_Fifo, vboxcon.FsObjType_DevChar, vboxcon.FsObjType_DevBlock,
1287 vboxcon.FsObjType_Socket, vboxcon.FsObjType_WhiteOut):
1288 fRc = reporter.error('Directory "%s" contains invalid directory entry "%s" (type %d)' %
1289 (sCurDir, oFsObjInfo.name, oFsObjInfo.type,));
1290 else:
1291 cOthers += 1;
1292
1293 # Close the directory
1294 try:
1295 oCurDir.close();
1296 except:
1297 fRc = reporter.errorXcpt('sCurDir=%s' % (sCurDir));
1298
1299 return (fRc, cDirs, cFiles, cOthers);
1300
1301 def gctrlReadDirTree2(self, oGuestSession, oDir): # type: (vboxtestfileset.GstDir) -> bool
1302 """
1303 Helper function to recursively read a guest directory tree specified in the current test.
1304 """
1305
1306 #
1307 # Process the directory.
1308 #
1309
1310 # Open the directory:
1311 try:
1312 oCurDir = oGuestSession.directoryOpen(oDir.sPath, '', None);
1313 except:
1314 return reporter.errorXcpt('sPath=%s' % (oDir.sPath,));
1315
1316 # Read the directory.
1317 dLeftUpper = dict(oDir.dChildrenUpper);
1318 cDot = 0;
1319 cDotDot = 0;
1320 fRc = True;
1321 while True:
1322 try:
1323 oFsObjInfo = oCurDir.read();
1324 except Exception as oXcpt:
1325 if vbox.ComError.notEqual(oXcpt, vbox.ComError.VBOX_E_OBJECT_NOT_FOUND):
1326 fRc = reporter.errorXcpt('Error reading directory "%s":' % (oDir.sPath,));
1327 break;
1328
1329 try:
1330 sName = oFsObjInfo.name;
1331 eType = oFsObjInfo.type;
1332 cbFile = oFsObjInfo.objectSize;
1333 ## @todo check further attributes.
1334 except:
1335 fRc = reporter.errorXcpt();
1336 break;
1337
1338 # '.' and '..' entries are not present in oDir.aoChildren, so special treatment:
1339 if sName in ('.', '..', ):
1340 if eType != vboxcon.FsObjType_Directory:
1341 fRc = reporter.error('Wrong type for "%s": %d, expected %d (Directory)'
1342 % (sName, eType, vboxcon.FsObjType_Directory));
1343 if sName == '.': cDot += 1;
1344 else: cDotDot += 1;
1345 else:
1346 # Find the child and remove it from the dictionary.
1347 sNameUpper = sName.upper();
1348 oFsObj = dLeftUpper.get(sNameUpper);
1349 if oFsObj is None:
1350 fRc = reporter.error('Unknown object "%s" found in "%s" (type %s, size %s)!'
1351 % (sName, oDir.sPath, eType, cbFile,));
1352 else:
1353 del dLeftUpper[sNameUpper];
1354
1355 # Check type
1356 if isinstance(oFsObj, vboxtestfileset.GstDir):
1357 if eType != vboxcon.FsObjType_Directory:
1358 fRc = reporter.error('%s: expected directory (%d), got eType=%d!'
1359 % (oFsObj.sPath, vboxcon.FsObjType_Directory, eType,));
1360 elif isinstance(oFsObj, vboxtestfileset.GstFile):
1361 if eType != vboxcon.FsObjType_File:
1362 fRc = reporter.error('%s: expected file (%d), got eType=%d!'
1363 % (oFsObj.sPath, vboxcon.FsObjType_File, eType,));
1364 else:
1365 fRc = reporter.error('%s: WTF? type=%s' % (oFsObj.sPath, type(oFsObj),));
1366
1367 # Check the name.
1368 if oFsObj.sName != sName:
1369 fRc = reporter.error('%s: expected name "%s", got "%s" instead!' % (oFsObj.sPath, oFsObj.sName, sName,));
1370
1371 # Check the size if a file.
1372 if isinstance(oFsObj, vboxtestfileset.GstFile) and cbFile != oFsObj.cbContent:
1373 fRc = reporter.error('%s: expected size %s, got %s instead!' % (oFsObj.sPath, oFsObj.cbContent, cbFile,));
1374
1375 ## @todo check timestamps and attributes.
1376
1377 # Close the directory
1378 try:
1379 oCurDir.close();
1380 except:
1381 fRc = reporter.errorXcpt('oDir.sPath=%s' % (oDir.sPath,));
1382
1383 # Any files left over?
1384 for sKey in dLeftUpper:
1385 oFsObj = dLeftUpper[sKey];
1386 fRc = reporter.error('%s: Was not returned! (%s)' % (oFsObj.sPath, type(oFsObj),));
1387
1388 # Check the dot and dot-dot counts.
1389 if cDot != 1:
1390 fRc = reporter.error('%s: Found %s "." entries, expected exactly 1!' % (oDir.sPath, cDot,));
1391 if cDotDot != 1:
1392 fRc = reporter.error('%s: Found %s ".." entries, expected exactly 1!' % (oDir.sPath, cDotDot,));
1393
1394 #
1395 # Recurse into subdirectories using info from oDir.
1396 #
1397 for oFsObj in oDir.aoChildren:
1398 if isinstance(oFsObj, vboxtestfileset.GstDir):
1399 fRc = self.gctrlReadDirTree2(oGuestSession, oFsObj) and fRc;
1400
1401 return fRc;
1402
1403 def gctrlExecDoTest(self, i, oTest, oRes, oGuestSession):
1404 """
1405 Wrapper function around gctrlExecute to provide more sanity checking
1406 when needed in actual execution tests.
1407 """
1408 reporter.log('Testing #%d, cmd="%s" ...' % (i, oTest.sCmd));
1409 fRcExec = self.gctrlExecute(oTest, oGuestSession, oRes.fRc);
1410 if fRcExec == oRes.fRc:
1411 fRc = True;
1412 if fRcExec is True:
1413 # Compare exit status / code on successful process execution.
1414 if oTest.uExitStatus != oRes.uExitStatus \
1415 or oTest.iExitCode != oRes.iExitCode:
1416 fRc = reporter.error('Test #%d (%s) failed: Got exit status + code %d,%d, expected %d,%d'
1417 % (i, oTest.asArgs, oTest.uExitStatus, oTest.iExitCode,
1418 oRes.uExitStatus, oRes.iExitCode));
1419
1420 # Compare test / result buffers on successful process execution.
1421 if oTest.sBuf is not None and oRes.sBuf is not None:
1422 if not utils.areBytesEqual(oTest.sBuf, oRes.sBuf):
1423 fRc = reporter.error('Test #%d (%s) failed: Got buffer\n%s (%d bytes), expected\n%s (%d bytes)'
1424 % (i, oTest.asArgs,
1425 map(hex, map(ord, oTest.sBuf)), len(oTest.sBuf),
1426 map(hex, map(ord, oRes.sBuf)), len(oRes.sBuf)));
1427 reporter.log2('Test #%d passed: Buffers match (%d bytes)' % (i, len(oRes.sBuf)));
1428 elif oRes.sBuf and not oTest.sBuf:
1429 fRc = reporter.error('Test #%d (%s) failed: Got no buffer data, expected\n%s (%dbytes)' %
1430 (i, oTest.asArgs, map(hex, map(ord, oRes.sBuf)), len(oRes.sBuf),));
1431
1432 if oRes.cbStdOut is not None and oRes.cbStdOut != oTest.cbStdOut:
1433 fRc = reporter.error('Test #%d (%s) failed: Got %d bytes of stdout data, expected %d'
1434 % (i, oTest.asArgs, oTest.cbStdOut, oRes.cbStdOut));
1435 if oRes.cbStdErr is not None and oRes.cbStdErr != oTest.cbStdErr:
1436 fRc = reporter.error('Test #%d (%s) failed: Got %d bytes of stderr data, expected %d'
1437 % (i, oTest.asArgs, oTest.cbStdErr, oRes.cbStdErr));
1438 else:
1439 fRc = reporter.error('Test #%d (%s) failed: Got %s, expected %s' % (i, oTest.asArgs, fRcExec, oRes.fRc));
1440 return fRc;
1441
1442 def gctrlExecute(self, oTest, oGuestSession, fIsError):
1443 """
1444 Helper function to execute a program on a guest, specified in the current test.
1445
1446 Note! This weirdo returns results (process exitcode and status) in oTest.
1447 """
1448 fRc = True; # Be optimistic.
1449
1450 # Reset the weird result stuff:
1451 oTest.cbStdOut = 0;
1452 oTest.cbStdErr = 0;
1453 oTest.sBuf = '';
1454 oTest.uExitStatus = 0;
1455 oTest.iExitCode = 0;
1456
1457 ## @todo Compare execution timeouts!
1458 #tsStart = base.timestampMilli();
1459
1460 try:
1461 reporter.log2('Using session user=%s, sDomain=%s, name=%s, timeout=%d'
1462 % (oGuestSession.user, oGuestSession.domain, oGuestSession.name, oGuestSession.timeout,));
1463 except:
1464 return reporter.errorXcpt();
1465
1466 #
1467 # Start the process:
1468 #
1469 reporter.log2('Executing sCmd=%s, fFlags=%s, timeoutMS=%d, asArgs=%s, asEnv=%s'
1470 % (oTest.sCmd, oTest.fFlags, oTest.timeoutMS, oTest.asArgs, oTest.aEnv,));
1471 try:
1472 oProcess = oGuestSession.processCreate(oTest.sCmd,
1473 oTest.asArgs if self.oTstDrv.fpApiVer >= 5.0 else oTest.asArgs[1:],
1474 oTest.aEnv, oTest.fFlags, oTest.timeoutMS);
1475 except:
1476 reporter.maybeErrXcpt(fIsError, 'asArgs=%s' % (oTest.asArgs,));
1477 return False;
1478 if oProcess is None:
1479 return reporter.error('oProcess is None! (%s)' % (oTest.asArgs,));
1480
1481 #time.sleep(5); # try this if you want to see races here.
1482
1483 # Wait for the process to start properly:
1484 reporter.log2('Process start requested, waiting for start (%dms) ...' % (oTest.timeoutMS,));
1485 iPid = -1;
1486 aeWaitFor = [ vboxcon.ProcessWaitForFlag_Start, ];
1487 try:
1488 eWaitResult = oProcess.waitForArray(aeWaitFor, oTest.timeoutMS);
1489 except:
1490 reporter.maybeErrXcpt(fIsError, 'waitforArray failed for asArgs=%s' % (oTest.asArgs,));
1491 fRc = False;
1492 else:
1493 try:
1494 eStatus = oProcess.status;
1495 iPid = oProcess.PID;
1496 except:
1497 fRc = reporter.errorXcpt('asArgs=%s' % (oTest.asArgs,));
1498 else:
1499 reporter.log2('Wait result returned: %d, current process status is: %d' % (eWaitResult, eStatus,));
1500
1501 #
1502 # Wait for the process to run to completion if necessary.
1503 #
1504 # Note! The above eWaitResult return value can be ignored as it will
1505 # (mostly) reflect the process status anyway.
1506 #
1507 if eStatus == vboxcon.ProcessStatus_Started:
1508
1509 # What to wait for:
1510 aeWaitFor = [ vboxcon.ProcessWaitForFlag_Terminate, ];
1511 if vboxcon.ProcessCreateFlag_WaitForStdOut in oTest.fFlags:
1512 aeWaitFor.append(vboxcon.ProcessWaitForFlag_StdOut);
1513 if vboxcon.ProcessCreateFlag_WaitForStdErr in oTest.fFlags:
1514 aeWaitFor.append(vboxcon.ProcessWaitForFlag_StdErr);
1515 ## @todo Add vboxcon.ProcessWaitForFlag_StdIn.
1516
1517 reporter.log2('Process (PID %d) started, waiting for termination (%dms), aeWaitFor=%s ...'
1518 % (iPid, oTest.timeoutMS, aeWaitFor));
1519 acbFdOut = [0,0,0];
1520 while True:
1521 try:
1522 eWaitResult = oProcess.waitForArray(aeWaitFor, oTest.timeoutMS);
1523 except KeyboardInterrupt: # Not sure how helpful this is, but whatever.
1524 reporter.error('Process (PID %d) execution interrupted' % (iPid,));
1525 try: oProcess.close();
1526 except: pass;
1527 break;
1528 except:
1529 fRc = reporter.errorXcpt('asArgs=%s' % (oTest.asArgs,));
1530 break;
1531 reporter.log2('Wait returned: %d' % (eWaitResult,));
1532
1533 # Process output:
1534 for eFdResult, iFd, sFdNm in [ (vboxcon.ProcessWaitResult_StdOut, 1, 'stdout'),
1535 (vboxcon.ProcessWaitResult_StdErr, 2, 'stderr'), ]:
1536 if eWaitResult in (eFdResult, vboxcon.ProcessWaitResult_WaitFlagNotSupported):
1537 reporter.log2('Reading %s ...' % (sFdNm,));
1538 try:
1539 abBuf = oProcess.Read(1, 64 * 1024, oTest.timeoutMS);
1540 except KeyboardInterrupt: # Not sure how helpful this is, but whatever.
1541 reporter.error('Process (PID %d) execution interrupted' % (iPid,));
1542 try: oProcess.close();
1543 except: pass;
1544 except:
1545 pass; ## @todo test for timeouts and fail on anything else!
1546 else:
1547 if abBuf:
1548 reporter.log2('Process (PID %d) got %d bytes of %s data' % (iPid, len(abBuf), sFdNm,));
1549 acbFdOut[iFd] += len(abBuf);
1550 oTest.sBuf = abBuf; ## @todo Figure out how to uniform + append!
1551
1552 ## Process input (todo):
1553 #if eWaitResult in (vboxcon.ProcessWaitResult_StdIn, vboxcon.ProcessWaitResult_WaitFlagNotSupported):
1554 # reporter.log2('Process (PID %d) needs stdin data' % (iPid,));
1555
1556 # Termination or error?
1557 if eWaitResult in (vboxcon.ProcessWaitResult_Terminate,
1558 vboxcon.ProcessWaitResult_Error,
1559 vboxcon.ProcessWaitResult_Timeout,):
1560 try: eStatus = oProcess.status;
1561 except: fRc = reporter.errorXcpt('asArgs=%s' % (oTest.asArgs,));
1562 reporter.log2('Process (PID %d) reported terminate/error/timeout: %d, status: %d'
1563 % (iPid, eWaitResult, eStatus,));
1564 break;
1565
1566 # End of the wait loop.
1567 _, oTest.cbStdOut, oTest.cbStdErr = acbFdOut;
1568
1569 try: eStatus = oProcess.status;
1570 except: fRc = reporter.errorXcpt('asArgs=%s' % (oTest.asArgs,));
1571 reporter.log2('Final process status (PID %d) is: %d' % (iPid, eStatus));
1572 reporter.log2('Process (PID %d) %d stdout, %d stderr' % (iPid, oTest.cbStdOut, oTest.cbStdErr));
1573
1574 #
1575 # Get the final status and exit code of the process.
1576 #
1577 try:
1578 oTest.uExitStatus = oProcess.status;
1579 oTest.iExitCode = oProcess.exitCode;
1580 except:
1581 fRc = reporter.errorXcpt('asArgs=%s' % (oTest.asArgs,));
1582 reporter.log2('Process (PID %d) has exit code: %d; status: %d ' % (iPid, oTest.iExitCode, oTest.uExitStatus));
1583 return fRc;
1584
1585 def testGuestCtrlSessionEnvironment(self, oSession, oTxsSession, oTestVm): # pylint: disable=too-many-locals
1586 """
1587 Tests the guest session environment changes.
1588 """
1589 aoTests = [
1590 # Check basic operations.
1591 tdTestSessionEx([ # Initial environment is empty.
1592 tdStepSessionCheckEnv(),
1593 # Check clearing empty env.
1594 tdStepSessionClearEnv(),
1595 tdStepSessionCheckEnv(),
1596 # Check set.
1597 tdStepSessionSetEnv('FOO', 'BAR'),
1598 tdStepSessionCheckEnv(['FOO=BAR',]),
1599 tdStepRequireMinimumApiVer(5.0), # 4.3 can't cope with the remainder.
1600 tdStepSessionClearEnv(),
1601 tdStepSessionCheckEnv(),
1602 # Check unset.
1603 tdStepSessionUnsetEnv('BAR'),
1604 tdStepSessionCheckEnv(['BAR']),
1605 tdStepSessionClearEnv(),
1606 tdStepSessionCheckEnv(),
1607 # Set + unset.
1608 tdStepSessionSetEnv('FOO', 'BAR'),
1609 tdStepSessionCheckEnv(['FOO=BAR',]),
1610 tdStepSessionUnsetEnv('FOO'),
1611 tdStepSessionCheckEnv(['FOO']),
1612 # Bulk environment changes (via attrib) (shall replace existing 'FOO').
1613 tdStepSessionBulkEnv( ['PATH=/bin:/usr/bin', 'TMPDIR=/var/tmp', 'USER=root']),
1614 tdStepSessionCheckEnv(['PATH=/bin:/usr/bin', 'TMPDIR=/var/tmp', 'USER=root']),
1615 ]),
1616 tdTestSessionEx([ # Check that setting the same value several times works.
1617 tdStepSessionSetEnv('FOO','BAR'),
1618 tdStepSessionCheckEnv([ 'FOO=BAR',]),
1619 tdStepSessionSetEnv('FOO','BAR2'),
1620 tdStepSessionCheckEnv([ 'FOO=BAR2',]),
1621 tdStepSessionSetEnv('FOO','BAR3'),
1622 tdStepSessionCheckEnv([ 'FOO=BAR3',]),
1623 tdStepRequireMinimumApiVer(5.0), # 4.3 can't cope with the remainder.
1624 # Add a little unsetting to the mix.
1625 tdStepSessionSetEnv('BAR', 'BEAR'),
1626 tdStepSessionCheckEnv([ 'FOO=BAR3', 'BAR=BEAR',]),
1627 tdStepSessionUnsetEnv('FOO'),
1628 tdStepSessionCheckEnv([ 'FOO', 'BAR=BEAR',]),
1629 tdStepSessionSetEnv('FOO','BAR4'),
1630 tdStepSessionCheckEnv([ 'FOO=BAR4', 'BAR=BEAR',]),
1631 # The environment is case sensitive.
1632 tdStepSessionSetEnv('foo','BAR5'),
1633 tdStepSessionCheckEnv([ 'FOO=BAR4', 'BAR=BEAR', 'foo=BAR5']),
1634 tdStepSessionUnsetEnv('foo'),
1635 tdStepSessionCheckEnv([ 'FOO=BAR4', 'BAR=BEAR', 'foo']),
1636 ]),
1637 tdTestSessionEx([ # Bulk settings merges stuff, last entry standing.
1638 tdStepSessionBulkEnv(['FOO=bar', 'foo=bar', 'FOO=doofus', 'TMPDIR=/tmp', 'foo=bar2']),
1639 tdStepSessionCheckEnv(['FOO=doofus', 'TMPDIR=/tmp', 'foo=bar2']),
1640 tdStepRequireMinimumApiVer(5.0), # 4.3 is buggy!
1641 tdStepSessionBulkEnv(['2=1+1', 'FOO=doofus2', ]),
1642 tdStepSessionCheckEnv(['2=1+1', 'FOO=doofus2' ]),
1643 ]),
1644 # Invalid variable names.
1645 tdTestSessionEx([
1646 tdStepSessionSetEnv('', 'FOO', vbox.ComError.E_INVALIDARG),
1647 tdStepSessionCheckEnv(),
1648 tdStepRequireMinimumApiVer(5.0), # 4.3 is too relaxed checking input!
1649 tdStepSessionSetEnv('=', '===', vbox.ComError.E_INVALIDARG),
1650 tdStepSessionCheckEnv(),
1651 tdStepSessionSetEnv('FOO=', 'BAR', vbox.ComError.E_INVALIDARG),
1652 tdStepSessionCheckEnv(),
1653 tdStepSessionSetEnv('=FOO', 'BAR', vbox.ComError.E_INVALIDARG),
1654 tdStepSessionCheckEnv(),
1655 tdStepRequireMinimumApiVer(5.0), # 4.3 is buggy and too relaxed!
1656 tdStepSessionBulkEnv(['', 'foo=bar'], vbox.ComError.E_INVALIDARG),
1657 tdStepSessionCheckEnv(),
1658 tdStepSessionBulkEnv(['=', 'foo=bar'], vbox.ComError.E_INVALIDARG),
1659 tdStepSessionCheckEnv(),
1660 tdStepSessionBulkEnv(['=FOO', 'foo=bar'], vbox.ComError.E_INVALIDARG),
1661 tdStepSessionCheckEnv(),
1662 ]),
1663 # A bit more weird keys/values.
1664 tdTestSessionEx([ tdStepSessionSetEnv('$$$', ''),
1665 tdStepSessionCheckEnv([ '$$$=',]), ]),
1666 tdTestSessionEx([ tdStepSessionSetEnv('$$$', '%%%'),
1667 tdStepSessionCheckEnv([ '$$$=%%%',]),
1668 ]),
1669 tdTestSessionEx([ tdStepRequireMinimumApiVer(5.0), # 4.3 is buggy!
1670 tdStepSessionSetEnv(u'ß$%ß&', ''),
1671 tdStepSessionCheckEnv([ u'ß$%ß&=',]),
1672 ]),
1673 # Misc stuff.
1674 tdTestSessionEx([ tdStepSessionSetEnv('FOO', ''),
1675 tdStepSessionCheckEnv(['FOO=',]),
1676 ]),
1677 tdTestSessionEx([ tdStepSessionSetEnv('FOO', 'BAR'),
1678 tdStepSessionCheckEnv(['FOO=BAR',])
1679 ],),
1680 tdTestSessionEx([ tdStepSessionSetEnv('FOO', 'BAR'),
1681 tdStepSessionSetEnv('BAR', 'BAZ'),
1682 tdStepSessionCheckEnv([ 'FOO=BAR', 'BAR=BAZ',]),
1683 ]),
1684 ];
1685 return tdTestSessionEx.executeListTestSessions(aoTests, self.oTstDrv, oSession, oTxsSession, oTestVm, 'SessionEnv');
1686
1687 def testGuestCtrlSession(self, oSession, oTxsSession, oTestVm):
1688 """
1689 Tests the guest session handling.
1690 """
1691
1692 #
1693 # Parameters.
1694 #
1695 atTests = [
1696 # Invalid parameters.
1697 [ tdTestSession(sUser = ''), tdTestResultSession() ],
1698 [ tdTestSession(sPassword = 'bar'), tdTestResultSession() ],
1699 [ tdTestSession(sDomain = 'boo'),tdTestResultSession() ],
1700 [ tdTestSession(sPassword = 'bar', sDomain = 'boo'), tdTestResultSession() ],
1701 # User account without a passwort - forbidden.
1702 [ tdTestSession(sPassword = "" ), tdTestResultSession() ],
1703 # Wrong credentials.
1704 # Note: On Guest Additions < 4.3 this always succeeds because these don't
1705 # support creating dedicated sessions. Instead, guest process creation
1706 # then will fail. See note below.
1707 [ tdTestSession(sUser = 'foo', sPassword = 'bar', sDomain = 'boo'), tdTestResultSession() ],
1708 # Correct credentials.
1709 [ tdTestSession(), tdTestResultSession(fRc = True, cNumSessions = 1) ]
1710 ];
1711
1712 fRc = True;
1713 for (i, tTest) in enumerate(atTests):
1714 oCurTest = tTest[0] # type: tdTestSession
1715 oCurRes = tTest[1] # type: tdTestResult
1716
1717 oCurTest.setEnvironment(oSession, oTxsSession, oTestVm);
1718 reporter.log('Testing #%d, user="%s", sPassword="%s", sDomain="%s" ...'
1719 % (i, oCurTest.oCreds.sUser, oCurTest.oCreds.sPassword, oCurTest.oCreds.sDomain));
1720 sCurGuestSessionName = 'testGuestCtrlSession: Test #%d' % (i,);
1721 fRc2, oCurGuestSession = oCurTest.createSession(sCurGuestSessionName, fIsError = oCurRes.fRc);
1722
1723 # See note about < 4.3 Guest Additions above.
1724 uProtocolVersion = 2;
1725 if oCurGuestSession is not None:
1726 try:
1727 uProtocolVersion = oCurGuestSession.protocolVersion;
1728 except:
1729 fRc = reporter.errorXcpt('Test #%d' % (i,));
1730
1731 if uProtocolVersion >= 2 and fRc2 is not oCurRes.fRc:
1732 fRc = reporter.error('Test #%d failed: Session creation failed: Got %s, expected %s' % (i, fRc2, oCurRes.fRc,));
1733
1734 if fRc2 and oCurGuestSession is None:
1735 fRc = reporter.error('Test #%d failed: no session object' % (i,));
1736 fRc2 = False;
1737
1738 if fRc2:
1739 if uProtocolVersion >= 2: # For Guest Additions < 4.3 getSessionCount() always will return 1.
1740 cCurSessions = oCurTest.getSessionCount(self.oTstDrv.oVBoxMgr);
1741 if cCurSessions != oCurRes.cNumSessions:
1742 fRc = reporter.error('Test #%d failed: Session count does not match: Got %d, expected %d'
1743 % (i, cCurSessions, oCurRes.cNumSessions));
1744 try:
1745 sObjName = oCurGuestSession.name;
1746 except:
1747 fRc = reporter.errorXcpt('Test #%d' % (i,));
1748 else:
1749 if sObjName != sCurGuestSessionName:
1750 fRc = reporter.error('Test #%d failed: Session name does not match: Got "%s", expected "%s"'
1751 % (i, sObjName, sCurGuestSessionName));
1752 fRc2 = oCurTest.closeSession(True);
1753 if fRc2 is False:
1754 fRc = reporter.error('Test #%d failed: Session could not be closed' % (i,));
1755
1756 if fRc is False:
1757 return (False, oTxsSession);
1758
1759 #
1760 # Multiple sessions.
1761 #
1762 cMaxGuestSessions = 31; # Maximum number of concurrent guest session allowed.
1763 # Actually, this is 32, but we don't test session 0.
1764 aoMultiSessions = {};
1765 reporter.log2('Opening multiple guest tsessions at once ...');
1766 for i in xrange(cMaxGuestSessions + 1):
1767 aoMultiSessions[i] = tdTestSession(sSessionName = 'MultiSession #%d' % (i,));
1768 aoMultiSessions[i].setEnvironment(oSession, oTxsSession, oTestVm);
1769
1770 cCurSessions = aoMultiSessions[i].getSessionCount(self.oTstDrv.oVBoxMgr);
1771 reporter.log2('MultiSession test #%d count is %d' % (i, cCurSessions));
1772 if cCurSessions != i:
1773 return (reporter.error('MultiSession count is %d, expected %d' % (cCurSessions, i)), oTxsSession);
1774 fRc2, _ = aoMultiSessions[i].createSession('MultiSession #%d' % (i,), i < cMaxGuestSessions);
1775 if fRc2 is not True:
1776 if i < cMaxGuestSessions:
1777 return (reporter.error('MultiSession #%d test failed' % (i,)), oTxsSession);
1778 reporter.log('MultiSession #%d exceeded concurrent guest session count, good' % (i,));
1779 break;
1780
1781 cCurSessions = aoMultiSessions[i].getSessionCount(self.oTstDrv.oVBoxMgr);
1782 if cCurSessions is not cMaxGuestSessions:
1783 return (reporter.error('Final session count %d, expected %d ' % (cCurSessions, cMaxGuestSessions,)), oTxsSession);
1784
1785 reporter.log2('Closing MultiSessions ...');
1786 for i in xrange(cMaxGuestSessions):
1787 # Close this session:
1788 oClosedGuestSession = aoMultiSessions[i].oGuestSession;
1789 fRc2 = aoMultiSessions[i].closeSession(True);
1790 cCurSessions = aoMultiSessions[i].getSessionCount(self.oTstDrv.oVBoxMgr)
1791 reporter.log2('MultiSession #%d count is %d' % (i, cCurSessions,));
1792 if fRc2 is False:
1793 fRc = reporter.error('Closing MultiSession #%d failed' % (i,));
1794 elif cCurSessions != cMaxGuestSessions - (i + 1):
1795 fRc = reporter.error('Expected %d session after closing #%d, got %d instead'
1796 % (cMaxGuestSessions - (i + 1), cCurSessions, i,));
1797 assert aoMultiSessions[i].oGuestSession is None or not fRc2;
1798 ## @todo any way to check that the session is closed other than the 'sessions' attribute?
1799
1800 # Try check that none of the remaining sessions got closed.
1801 try:
1802 aoGuestSessions = self.oTstDrv.oVBoxMgr.getArray(atTests[0][0].oTest.oGuest, 'sessions');
1803 except:
1804 return (reporter.errorXcpt('i=%d/%d' % (i, cMaxGuestSessions,)), oTxsSession);
1805 if oClosedGuestSession in aoGuestSessions:
1806 fRc = reporter.error('i=%d/%d: %s should not be in %s'
1807 % (i, cMaxGuestSessions, oClosedGuestSession, aoGuestSessions));
1808 if i + 1 < cMaxGuestSessions: # Not sure what xrange(2,2) does...
1809 for j in xrange(i + 1, cMaxGuestSessions):
1810 if aoMultiSessions[j].oGuestSession not in aoGuestSessions:
1811 fRc = reporter.error('i=%d/j=%d/%d: %s should be in %s'
1812 % (i, j, cMaxGuestSessions, aoMultiSessions[j].oGuestSession, aoGuestSessions));
1813 ## @todo any way to check that they work?
1814
1815 ## @todo Test session timeouts.
1816
1817 return (fRc, oTxsSession);
1818
1819 def testGuestCtrlSessionFileRefs(self, oSession, oTxsSession, oTestVm):
1820 """
1821 Tests the guest session file reference handling.
1822 """
1823
1824 # Find a file to play around with:
1825 sFile = self.getGuestSystemFileForReading(oTestVm);
1826
1827 # Use credential defaults.
1828 oCreds = tdCtxCreds();
1829 oCreds.applyDefaultsIfNotSet(oTestVm);
1830
1831 # Number of stale guest files to create.
1832 cStaleFiles = 10;
1833
1834 #
1835 # Start a session.
1836 #
1837 aeWaitFor = [ vboxcon.GuestSessionWaitForFlag_Start ];
1838 try:
1839 oGuest = oSession.o.console.guest;
1840 oGuestSession = oGuest.createSession(oCreds.sUser, oCreds.sPassword, oCreds.sDomain, "testGuestCtrlSessionFileRefs");
1841 eWaitResult = oGuestSession.waitForArray(aeWaitFor, 30 * 1000);
1842 except:
1843 return (reporter.errorXcpt(), oTxsSession);
1844
1845 # Be nice to Guest Additions < 4.3: They don't support session handling and therefore return WaitFlagNotSupported.
1846 if eWaitResult not in (vboxcon.GuestSessionWaitResult_Start, vboxcon.GuestSessionWaitResult_WaitFlagNotSupported):
1847 return (reporter.error('Session did not start successfully - wait error: %d' % (eWaitResult,)), oTxsSession);
1848 reporter.log('Session successfully started');
1849
1850 #
1851 # Open guest files and "forget" them (stale entries).
1852 # For them we don't have any references anymore intentionally.
1853 #
1854 reporter.log2('Opening stale files');
1855 fRc = True;
1856 for i in xrange(0, cStaleFiles):
1857 try:
1858 if self.oTstDrv.fpApiVer >= 5.0:
1859 oGuestSession.fileOpen(sFile, vboxcon.FileAccessMode_ReadOnly, vboxcon.FileOpenAction_OpenExisting, 0);
1860 else:
1861 oGuestSession.fileOpen(sFile, "r", "oe", 0);
1862 # Note: Use a timeout in the call above for not letting the stale processes
1863 # hanging around forever. This can happen if the installed Guest Additions
1864 # do not support terminating guest processes.
1865 except:
1866 fRc = reporter.errorXcpt('Opening stale file #%d failed:' % (i,));
1867 break;
1868
1869 try: cFiles = len(self.oTstDrv.oVBoxMgr.getArray(oGuestSession, 'files'));
1870 except: fRc = reporter.errorXcpt();
1871 else:
1872 if cFiles != cStaleFiles:
1873 fRc = reporter.error('Got %d stale files, expected %d' % (cFiles, cStaleFiles));
1874
1875 if fRc is True:
1876 #
1877 # Open non-stale files and close them again.
1878 #
1879 reporter.log2('Opening non-stale files');
1880 aoFiles = [];
1881 for i in xrange(0, cStaleFiles):
1882 try:
1883 if self.oTstDrv.fpApiVer >= 5.0:
1884 oCurFile = oGuestSession.fileOpen(sFile, vboxcon.FileAccessMode_ReadOnly,
1885 vboxcon.FileOpenAction_OpenExisting, 0);
1886 else:
1887 oCurFile = oGuestSession.fileOpen(sFile, "r", "oe", 0);
1888 aoFiles.append(oCurFile);
1889 except:
1890 fRc = reporter.errorXcpt('Opening non-stale file #%d failed:' % (i,));
1891 break;
1892
1893 # Check the count.
1894 try: cFiles = len(self.oTstDrv.oVBoxMgr.getArray(oGuestSession, 'files'));
1895 except: fRc = reporter.errorXcpt();
1896 else:
1897 if cFiles != cStaleFiles * 2:
1898 fRc = reporter.error('Got %d total files, expected %d' % (cFiles, cStaleFiles * 2));
1899
1900 # Close them.
1901 reporter.log2('Closing all non-stale files again ...');
1902 for i, oFile in enumerate(aoFiles):
1903 try:
1904 oFile.close();
1905 except:
1906 fRc = reporter.errorXcpt('Closing non-stale file #%d failed:' % (i,));
1907
1908 # Check the count again.
1909 try: cFiles = len(self.oTstDrv.oVBoxMgr.getArray(oGuestSession, 'files'));
1910 except: fRc = reporter.errorXcpt();
1911 # Here we count the stale files (that is, files we don't have a reference
1912 # anymore for) and the opened and then closed non-stale files (that we still keep
1913 # a reference in aoFiles[] for).
1914 if cFiles != cStaleFiles:
1915 fRc = reporter.error('Got %d total files, expected %d' % (cFiles, cStaleFiles));
1916
1917 #
1918 # Check that all (referenced) non-stale files are now in the "closed" state.
1919 #
1920 reporter.log2('Checking statuses of all non-stale files ...');
1921 for i, oFile in enumerate(aoFiles):
1922 try:
1923 eFileStatus = aoFiles[i].status;
1924 except:
1925 fRc = reporter.errorXcpt('Checking status of file #%d failed:' % (i,));
1926 else:
1927 if eFileStatus != vboxcon.FileStatus_Closed:
1928 fRc = reporter.error('Non-stale file #%d has status %d, expected %d'
1929 % (i, eFileStatus, vboxcon.FileStatus_Closed));
1930
1931 if fRc is True:
1932 reporter.log2('All non-stale files closed');
1933
1934 try: cFiles = len(self.oTstDrv.oVBoxMgr.getArray(oGuestSession, 'files'));
1935 except: fRc = reporter.errorXcpt();
1936 else: reporter.log2('Final guest session file count: %d' % (cFiles,));
1937
1938 #
1939 # Now try to close the session and see what happens.
1940 # Note! Session closing is why we've been doing all the 'if fRc is True' stuff above rather than returning.
1941 #
1942 reporter.log2('Closing guest session ...');
1943 try:
1944 oGuestSession.close();
1945 except:
1946 fRc = reporter.errorXcpt('Testing for stale processes failed:');
1947
1948 return (fRc, oTxsSession);
1949
1950 #def testGuestCtrlSessionDirRefs(self, oSession, oTxsSession, oTestVm):
1951 # """
1952 # Tests the guest session directory reference handling.
1953 # """
1954
1955 # fRc = True;
1956 # return (fRc, oTxsSession);
1957
1958 def testGuestCtrlSessionProcRefs(self, oSession, oTxsSession, oTestVm): # pylint: disable=too-many-locals
1959 """
1960 Tests the guest session process reference handling.
1961 """
1962
1963 sCmd = self.getGuestSystemShell(oTestVm);
1964 asArgs = [sCmd,];
1965
1966 # Use credential defaults.
1967 oCreds = tdCtxCreds();
1968 oCreds.applyDefaultsIfNotSet(oTestVm);
1969
1970 # Number of stale guest processes to create.
1971 cStaleProcs = 10;
1972
1973 #
1974 # Start a session.
1975 #
1976 aeWaitFor = [ vboxcon.GuestSessionWaitForFlag_Start ];
1977 try:
1978 oGuest = oSession.o.console.guest;
1979 oGuestSession = oGuest.createSession(oCreds.sUser, oCreds.sPassword, oCreds.sDomain, "testGuestCtrlSessionProcRefs");
1980 eWaitResult = oGuestSession.waitForArray(aeWaitFor, 30 * 1000);
1981 except:
1982 return (reporter.errorXcpt(), oTxsSession);
1983
1984 # Be nice to Guest Additions < 4.3: They don't support session handling and therefore return WaitFlagNotSupported.
1985 if eWaitResult not in (vboxcon.GuestSessionWaitResult_Start, vboxcon.GuestSessionWaitResult_WaitFlagNotSupported):
1986 return (reporter.error('Session did not start successfully - wait error: %d' % (eWaitResult,)), oTxsSession);
1987 reporter.log('Session successfully started');
1988
1989 #
1990 # Fire off forever-running processes and "forget" them (stale entries).
1991 # For them we don't have any references anymore intentionally.
1992 #
1993 reporter.log2('Starting stale processes...');
1994 fRc = True;
1995 for i in xrange(0, cStaleProcs):
1996 try:
1997 oGuestSession.processCreate(sCmd,
1998 asArgs if self.oTstDrv.fpApiVer >= 5.0 else asArgs[1:], [],
1999 [ vboxcon.ProcessCreateFlag_WaitForStdOut ], \
2000 30 * 1000);
2001 # Note: Use a timeout in the call above for not letting the stale processes
2002 # hanging around forever. This can happen if the installed Guest Additions
2003 # do not support terminating guest processes.
2004 except:
2005 fRc = reporter.errorXcpt('Creating stale process #%d failed:' % (i,));
2006 break;
2007
2008 try: cProcesses = len(self.oTstDrv.oVBoxMgr.getArray(oGuestSession, 'processes'));
2009 except: fRc = reporter.errorXcpt();
2010 else:
2011 if cProcesses != cStaleProcs:
2012 fRc = reporter.error('Got %d stale processes, expected %d' % (cProcesses, cStaleProcs));
2013
2014 if fRc is True:
2015 #
2016 # Fire off non-stale processes and wait for termination.
2017 #
2018 if oTestVm.isWindows() or oTestVm.isOS2():
2019 asArgs = [ sCmd, '/C', 'dir', '/S', self.getGuestSystemDir(oTestVm), ];
2020 else:
2021 asArgs = [ sCmd, '-c', 'ls -la ' + self.getGuestSystemDir(oTestVm), ];
2022 reporter.log2('Starting non-stale processes...');
2023 aoProcesses = [];
2024 for i in xrange(0, cStaleProcs):
2025 try:
2026 oCurProc = oGuestSession.processCreate(sCmd, asArgs if self.oTstDrv.fpApiVer >= 5.0 else asArgs[1:],
2027 [], [], 0); # Infinite timeout.
2028 aoProcesses.append(oCurProc);
2029 except:
2030 fRc = reporter.errorXcpt('Creating non-stale process #%d failed:' % (i,));
2031 break;
2032
2033 reporter.log2('Waiting for non-stale processes to terminate...');
2034 for i, oProcess in enumerate(aoProcesses):
2035 try:
2036 oProcess.waitForArray([ vboxcon.ProcessWaitForFlag_Terminate, ], 30 * 1000);
2037 eProcessStatus = oProcess.status;
2038 except:
2039 fRc = reporter.errorXcpt('Waiting for non-stale process #%d failed:' % (i,));
2040 else:
2041 if eProcessStatus != vboxcon.ProcessStatus_TerminatedNormally:
2042 fRc = reporter.error('Waiting for non-stale processes #%d resulted in status %d, expected %d'
2043 % (i, eProcessStatus, vboxcon.ProcessStatus_TerminatedNormally));
2044
2045 try: cProcesses = len(self.oTstDrv.oVBoxMgr.getArray(oGuestSession, 'processes'));
2046 except: fRc = reporter.errorXcpt();
2047 else:
2048 # Here we count the stale processes (that is, processes we don't have a reference
2049 # anymore for) and the started + terminated non-stale processes (that we still keep
2050 # a reference in aoProcesses[] for).
2051 if cProcesses != (cStaleProcs * 2):
2052 fRc = reporter.error('Got %d total processes, expected %d' % (cProcesses, cStaleProcs));
2053
2054 if fRc is True:
2055 reporter.log2('All non-stale processes terminated');
2056
2057 #
2058 # Fire off non-stale blocking processes which are terminated via terminate().
2059 #
2060 if oTestVm.isWindows() or oTestVm.isOS2():
2061 asArgs = [ sCmd, '/C', 'pause'];
2062 else:
2063 asArgs = [ sCmd ];
2064 reporter.log2('Starting blocking processes...');
2065 aoProcesses = [];
2066 for i in xrange(0, cStaleProcs):
2067 try:
2068 oCurProc = oGuestSession.processCreate(sCmd, asArgs if self.oTstDrv.fpApiVer >= 5.0 else asArgs[1:],
2069 [], [], 30 * 1000);
2070 # Note: Use a timeout in the call above for not letting the stale processes
2071 # hanging around forever. This can happen if the installed Guest Additions
2072 # do not support terminating guest processes.
2073 aoProcesses.append(oCurProc);
2074 except:
2075 fRc = reporter.errorXcpt('Creating non-stale blocking process #%d failed:' % (i,));
2076 break;
2077
2078 reporter.log2('Terminating blocking processes...');
2079 for i, oProcess in enumerate(aoProcesses):
2080 try:
2081 oProcess.terminate();
2082 except: # Termination might not be supported, just skip and log it.
2083 reporter.logXcpt('Termination of blocking process #%d failed, skipped:' % (i,));
2084
2085 # There still should be 20 processes because we terminated the 10 newest ones.
2086 try: cProcesses = len(self.oTstDrv.oVBoxMgr.getArray(oGuestSession, 'processes'));
2087 except: fRc = reporter.errorXcpt();
2088 else:
2089 if cProcesses != (cStaleProcs * 2):
2090 fRc = reporter.error('Got %d total processes, expected %d' % (cProcesses, cStaleProcs));
2091 reporter.log2('Final guest session processes count: %d' % (cProcesses,));
2092
2093 #
2094 # Now try to close the session and see what happens.
2095 #
2096 reporter.log2('Closing guest session ...');
2097 try:
2098 oGuestSession.close();
2099 except:
2100 fRc = reporter.errorXcpt('Testing for stale processes failed:');
2101
2102 return (fRc, oTxsSession);
2103
2104 def testGuestCtrlExec(self, oSession, oTxsSession, oTestVm): # pylint: disable=too-many-locals,too-many-statements
2105 """
2106 Tests the basic execution feature.
2107 """
2108
2109 # Paths:
2110 sVBoxControl = None; ## @todo Get path of installed Guest Additions. Later.
2111 sShell = self.getGuestSystemShell(oTestVm);
2112 sShellOpt = '/C' if oTestVm.isWindows() or oTestVm.isOS2() else '-c';
2113 sSystemDir = self.getGuestSystemDir(oTestVm);
2114 sFileForReading = self.getGuestSystemFileForReading(oTestVm);
2115 if oTestVm.isWindows() or oTestVm.isOS2():
2116 sImageOut = self.getGuestSystemShell(oTestVm);
2117 if oTestVm.isWindows():
2118 sVBoxControl = "C:\\Program Files\\Oracle\\VirtualBox Guest Additions\\VBoxControl.exe";
2119 else:
2120 sImageOut = "/bin/ls";
2121 if oTestVm.isLinux(): ## @todo check solaris and darwin.
2122 sVBoxControl = "/usr/bin/VBoxControl"; # Symlink
2123
2124 # Use credential defaults.
2125 oCreds = tdCtxCreds();
2126 oCreds.applyDefaultsIfNotSet(oTestVm);
2127
2128 atInvalid = [
2129 # Invalid parameters.
2130 [ tdTestExec(), tdTestResultExec() ],
2131 # Non-existent / invalid image.
2132 [ tdTestExec(sCmd = "non-existent"), tdTestResultExec() ],
2133 [ tdTestExec(sCmd = "non-existent2"), tdTestResultExec() ],
2134 # Use an invalid format string.
2135 [ tdTestExec(sCmd = "%$%%%&"), tdTestResultExec() ],
2136 # More stuff.
2137 [ tdTestExec(sCmd = u"ƒ‰‹ˆ÷‹¸"), tdTestResultExec() ],
2138 [ tdTestExec(sCmd = "???://!!!"), tdTestResultExec() ],
2139 [ tdTestExec(sCmd = "<>!\\"), tdTestResultExec() ],
2140 # Enable as soon as ERROR_BAD_DEVICE is implemented.
2141 #[ tdTestExec(sCmd = "CON", tdTestResultExec() ],
2142 ];
2143
2144 atExec = [];
2145 if oTestVm.isWindows() or oTestVm.isOS2():
2146 atExec += [
2147 # Basic execution.
2148 [ tdTestExec(sCmd = sImageOut, asArgs = [ sImageOut, '/C', 'dir', '/S', sSystemDir ]),
2149 tdTestResultExec(fRc = True) ],
2150 [ tdTestExec(sCmd = sImageOut, asArgs = [ sImageOut, '/C', 'dir', '/S', sFileForReading ]),
2151 tdTestResultExec(fRc = True) ],
2152 [ tdTestExec(sCmd = sImageOut, asArgs = [ sImageOut, '/C', 'dir', '/S', sSystemDir + '\\nonexist.dll' ]),
2153 tdTestResultExec(fRc = True, iExitCode = 1) ],
2154 [ tdTestExec(sCmd = sImageOut, asArgs = [ sImageOut, '/C', 'dir', '/S', '/wrongparam' ]),
2155 tdTestResultExec(fRc = True, iExitCode = 1) ],
2156 [ tdTestExec(sCmd = sShell, asArgs = [ sShell, sShellOpt, 'wrongcommand' ]),
2157 tdTestResultExec(fRc = True, iExitCode = 1) ],
2158 # StdOut.
2159 [ tdTestExec(sCmd = sImageOut, asArgs = [ sImageOut, '/C', 'dir', '/S', sSystemDir ]),
2160 tdTestResultExec(fRc = True) ],
2161 [ tdTestExec(sCmd = sImageOut, asArgs = [ sImageOut, '/C', 'dir', '/S', 'stdout-non-existing' ]),
2162 tdTestResultExec(fRc = True, iExitCode = 1) ],
2163 # StdErr.
2164 [ tdTestExec(sCmd = sImageOut, asArgs = [ sImageOut, '/C', 'dir', '/S', sSystemDir ]),
2165 tdTestResultExec(fRc = True) ],
2166 [ tdTestExec(sCmd = sImageOut, asArgs = [ sImageOut, '/C', 'dir', '/S', 'stderr-non-existing' ]),
2167 tdTestResultExec(fRc = True, iExitCode = 1) ],
2168 # StdOut + StdErr.
2169 [ tdTestExec(sCmd = sImageOut, asArgs = [ sImageOut, '/C', 'dir', '/S', sSystemDir ]),
2170 tdTestResultExec(fRc = True) ],
2171 [ tdTestExec(sCmd = sImageOut, asArgs = [ sImageOut, '/C', 'dir', '/S', 'stdouterr-non-existing' ]),
2172 tdTestResultExec(fRc = True, iExitCode = 1) ],
2173 ];
2174 # atExec.extend([
2175 # FIXME: Failing tests.
2176 # Environment variables.
2177 # [ tdTestExec(sCmd = sImageOut, asArgs = [ sImageOut, '/C', 'set', 'TEST_NONEXIST' ],
2178 # tdTestResultExec(fRc = True, iExitCode = 1) ]
2179 # [ tdTestExec(sCmd = sImageOut, asArgs = [ sImageOut, '/C', 'set', 'windir' ],
2180 # fFlags = [ vboxcon.ProcessCreateFlag_WaitForStdOut, vboxcon.ProcessCreateFlag_WaitForStdErr ]),
2181 # tdTestResultExec(fRc = True, sBuf = 'windir=C:\\WINDOWS\r\n') ],
2182 # [ tdTestExec(sCmd = sImageOut, asArgs = [ sImageOut, '/C', 'set', 'TEST_FOO' ],
2183 # aEnv = [ 'TEST_FOO=BAR' ],
2184 # fFlags = [ vboxcon.ProcessCreateFlag_WaitForStdOut, vboxcon.ProcessCreateFlag_WaitForStdErr ]),
2185 # tdTestResultExec(fRc = True, sBuf = 'TEST_FOO=BAR\r\n') ],
2186 # [ tdTestExec(sCmd = sImageOut, asArgs = [ sImageOut, '/C', 'set', 'TEST_FOO' ],
2187 # aEnv = [ 'TEST_FOO=BAR', 'TEST_BAZ=BAR' ],
2188 # fFlags = [ vboxcon.ProcessCreateFlag_WaitForStdOut, vboxcon.ProcessCreateFlag_WaitForStdErr ]),
2189 # tdTestResultExec(fRc = True, sBuf = 'TEST_FOO=BAR\r\n') ]
2190
2191 ## @todo Create some files (or get files) we know the output size of to validate output length!
2192 ## @todo Add task which gets killed at some random time while letting the guest output something.
2193 #];
2194 else:
2195 atExec += [
2196 # Basic execution.
2197 [ tdTestExec(sCmd = sImageOut, asArgs = [ sImageOut, '-R', sSystemDir ]),
2198 tdTestResultExec(fRc = True, iExitCode = 1) ],
2199 [ tdTestExec(sCmd = sImageOut, asArgs = [ sImageOut, sFileForReading ]),
2200 tdTestResultExec(fRc = True) ],
2201 [ tdTestExec(sCmd = sImageOut, asArgs = [ sImageOut, '--wrong-parameter' ]),
2202 tdTestResultExec(fRc = True, iExitCode = 2) ],
2203 [ tdTestExec(sCmd = sImageOut, asArgs = [ sImageOut, '/non/existent' ]),
2204 tdTestResultExec(fRc = True, iExitCode = 2) ],
2205 [ tdTestExec(sCmd = sShell, asArgs = [ sShell, sShellOpt, 'wrongcommand' ]),
2206 tdTestResultExec(fRc = True, iExitCode = 127) ],
2207 # StdOut.
2208 [ tdTestExec(sCmd = sImageOut, asArgs = [ sImageOut, sSystemDir ]),
2209 tdTestResultExec(fRc = True) ],
2210 [ tdTestExec(sCmd = sImageOut, asArgs = [ sImageOut, 'stdout-non-existing' ]),
2211 tdTestResultExec(fRc = True, iExitCode = 2) ],
2212 # StdErr.
2213 [ tdTestExec(sCmd = sImageOut, asArgs = [ sImageOut, sSystemDir ]),
2214 tdTestResultExec(fRc = True) ],
2215 [ tdTestExec(sCmd = sImageOut, asArgs = [ sImageOut, 'stderr-non-existing' ]),
2216 tdTestResultExec(fRc = True, iExitCode = 2) ],
2217 # StdOut + StdErr.
2218 [ tdTestExec(sCmd = sImageOut, asArgs = [ sImageOut, sSystemDir ]),
2219 tdTestResultExec(fRc = True) ],
2220 [ tdTestExec(sCmd = sImageOut, asArgs = [ sImageOut, 'stdouterr-non-existing' ]),
2221 tdTestResultExec(fRc = True, iExitCode = 2) ],
2222 ];
2223 # atExec.extend([
2224 # FIXME: Failing tests.
2225 # Environment variables.
2226 # [ tdTestExec(sCmd = sImageOut, asArgs = [ sImageOut, '/C', 'set', 'TEST_NONEXIST' ],
2227 # tdTestResultExec(fRc = True, iExitCode = 1) ]
2228 # [ tdTestExec(sCmd = sImageOut, asArgs = [ sImageOut, '/C', 'set', 'windir' ],
2229 #
2230 # fFlags = [ vboxcon.ProcessCreateFlag_WaitForStdOut, vboxcon.ProcessCreateFlag_WaitForStdErr ]),
2231 # tdTestResultExec(fRc = True, sBuf = 'windir=C:\\WINDOWS\r\n') ],
2232 # [ tdTestExec(sCmd = sImageOut, asArgs = [ sImageOut, '/C', 'set', 'TEST_FOO' ],
2233 # aEnv = [ 'TEST_FOO=BAR' ],
2234 # fFlags = [ vboxcon.ProcessCreateFlag_WaitForStdOut, vboxcon.ProcessCreateFlag_WaitForStdErr ]),
2235 # tdTestResultExec(fRc = True, sBuf = 'TEST_FOO=BAR\r\n') ],
2236 # [ tdTestExec(sCmd = sImageOut, asArgs = [ sImageOut, '/C', 'set', 'TEST_FOO' ],
2237 # aEnv = [ 'TEST_FOO=BAR', 'TEST_BAZ=BAR' ],
2238 # fFlags = [ vboxcon.ProcessCreateFlag_WaitForStdOut, vboxcon.ProcessCreateFlag_WaitForStdErr ]),
2239 # tdTestResultExec(fRc = True, sBuf = 'TEST_FOO=BAR\r\n') ]
2240
2241 ## @todo Create some files (or get files) we know the output size of to validate output length!
2242 ## @todo Add task which gets killed at some random time while letting the guest output something.
2243 #];
2244
2245 #
2246 for iExitCode in xrange(0, 127):
2247 atExec.append([ tdTestExec(sCmd = sShell, asArgs = [ sShell, sShellOpt, 'exit %s' % iExitCode ]),
2248 tdTestResultExec(fRc = True, iExitCode = iExitCode) ]);
2249
2250 if sVBoxControl:
2251 # Paths with spaces on windows.
2252 atExec.append([ tdTestExec(sCmd = sVBoxControl, asArgs = [ sVBoxControl, 'version' ]),
2253 tdTestResultExec(fRc = True) ]);
2254
2255 # Build up the final test array for the first batch.
2256 atTests = atInvalid + atExec;
2257
2258 #
2259 # First batch: One session per guest process.
2260 #
2261 reporter.log('One session per guest process ...');
2262 fRc = True;
2263 for (i, tTest) in enumerate(atTests):
2264 oCurTest = tTest[0] # type: tdTestExec
2265 oCurRes = tTest[1] # type: tdTestResultExec
2266 oCurTest.setEnvironment(oSession, oTxsSession, oTestVm);
2267 fRc, oCurGuestSession = oCurTest.createSession('testGuestCtrlExec: Test #%d' % (i,), True);
2268 if fRc is not True:
2269 reporter.error('Test #%d failed: Could not create session' % (i,));
2270 break;
2271 fRc = self.gctrlExecDoTest(i, oCurTest, oCurRes, oCurGuestSession);
2272 if fRc is not True:
2273 break;
2274 fRc = oCurTest.closeSession(True);
2275 if fRc is not True:
2276 break;
2277
2278 reporter.log('Execution of all tests done, checking for stale sessions');
2279
2280 # No sessions left?
2281 try:
2282 aSessions = self.oTstDrv.oVBoxMgr.getArray(oSession.o.console.guest, 'sessions');
2283 except:
2284 fRc = reporter.errorXcpt();
2285 else:
2286 cSessions = len(aSessions);
2287 if cSessions != 0:
2288 fRc = reporter.error('Found %d stale session(s), expected 0:' % (cSessions,));
2289 for (i, aSession) in enumerate(aSessions):
2290 try: reporter.log(' Stale session #%d ("%s")' % (aSession.id, aSession.name));
2291 except: reporter.errorXcpt();
2292
2293 if fRc is not True:
2294 return (fRc, oTxsSession);
2295
2296 reporter.log('Now using one guest session for all tests ...');
2297
2298 #
2299 # Second batch: One session for *all* guest processes.
2300 #
2301
2302 # Create session.
2303 reporter.log('Creating session for all tests ...');
2304 aeWaitFor = [ vboxcon.GuestSessionWaitForFlag_Start, ];
2305 try:
2306 oGuest = oSession.o.console.guest;
2307 oCurGuestSession = oGuest.createSession(oCreds.sUser, oCreds.sPassword, oCreds.sDomain,
2308 'testGuestCtrlExec: One session for all tests');
2309 except:
2310 return (reporter.errorXcpt(), oTxsSession);
2311
2312 try:
2313 eWaitResult = oCurGuestSession.waitForArray(aeWaitFor, 30 * 1000);
2314 except:
2315 fRc = reporter.errorXcpt('Waiting for guest session to start failed:');
2316 else:
2317 if eWaitResult not in (vboxcon.GuestSessionWaitResult_Start, vboxcon.GuestSessionWaitResult_WaitFlagNotSupported):
2318 fRc = reporter.error('Session did not start successfully, returned wait result: %d' % (eWaitResult,));
2319 else:
2320 reporter.log('Session successfully started');
2321
2322 # Do the tests within this session.
2323 for (i, tTest) in enumerate(atTests):
2324 oCurTest = tTest[0] # type: tdTestExec
2325 oCurRes = tTest[1] # type: tdTestResultExec
2326
2327 oCurTest.setEnvironment(oSession, oTxsSession, oTestVm);
2328 fRc = self.gctrlExecDoTest(i, oCurTest, oCurRes, oCurGuestSession);
2329 if fRc is False:
2330 break;
2331
2332 # Close the session.
2333 reporter.log2('Closing guest session ...');
2334 try:
2335 oCurGuestSession.close();
2336 oCurGuestSession = None;
2337 except:
2338 fRc = reporter.errorXcpt('Closing guest session failed:');
2339
2340 # No sessions left?
2341 reporter.log('Execution of all tests done, checking for stale sessions again');
2342 try: cSessions = len(self.oTstDrv.oVBoxMgr.getArray(oSession.o.console.guest, 'sessions'));
2343 except: fRc = reporter.errorXcpt();
2344 else:
2345 if cSessions != 0:
2346 fRc = reporter.error('Found %d stale session(s), expected 0' % (cSessions,));
2347 return (fRc, oTxsSession);
2348
2349 def threadForTestGuestCtrlSessionReboot(self, oGuestProcess):
2350 """
2351 Thread routine which waits for the stale guest process getting terminated (or some error)
2352 while the main test routine reboots the guest. It then compares the expected guest process result
2353 and logs an error if appropriate.
2354 """
2355 reporter.log('Waiting for process to get terminated at reboot ...');
2356 try:
2357 eWaitResult = oGuestProcess.waitForArray([ vboxcon.ProcessWaitForFlag_Terminate ], 5 * 60 * 1000);
2358 except:
2359 return reporter.errorXcpt('waitForArray failed');
2360 try:
2361 eStatus = oGuestProcess.status
2362 except:
2363 return reporter.errorXcpt('failed to get status (wait result %d)' % (eWaitResult,));
2364
2365 if eWaitResult == vboxcon.ProcessWaitResult_Terminate and eStatus == vboxcon.ProcessStatus_Down:
2366 reporter.log('Stale process was correctly terminated (status: down)');
2367 return True;
2368
2369 return reporter.error('Process wait across reboot failed: eWaitResult=%d, expected %d; eStatus=%d, expected %d'
2370 % (eWaitResult, vboxcon.ProcessWaitResult_Terminate, eStatus, vboxcon.ProcessStatus_Down,));
2371
2372 def testGuestCtrlSessionReboot(self, oSession, oTxsSession, oTestVm): # pylint: disable=too-many-locals
2373 """
2374 Tests guest object notifications when a guest gets rebooted / shutdown.
2375
2376 These notifications gets sent from the guest sessions in order to make API clients
2377 aware of guest session changes.
2378
2379 To test that we create a stale guest process and trigger a reboot of the guest.
2380 """
2381
2382 ## @todo backport fixes to 6.0 and maybe 5.2
2383 if self.oTstDrv.fpApiVer <= 6.0:
2384 reporter.log('Skipping: Required fixes not yet backported!');
2385 return None;
2386
2387 # Use credential defaults.
2388 oCreds = tdCtxCreds();
2389 oCreds.applyDefaultsIfNotSet(oTestVm);
2390
2391 fRc = True;
2392
2393 #
2394 # Start a session.
2395 #
2396 aeWaitFor = [ vboxcon.GuestSessionWaitForFlag_Start ];
2397 try:
2398 oGuest = oSession.o.console.guest;
2399 oGuestSession = oGuest.createSession(oCreds.sUser, oCreds.sPassword, oCreds.sDomain, "testGuestCtrlSessionReboot");
2400 eWaitResult = oGuestSession.waitForArray(aeWaitFor, 30 * 1000);
2401 except:
2402 return (reporter.errorXcpt(), oTxsSession);
2403
2404 # Be nice to Guest Additions < 4.3: They don't support session handling and therefore return WaitFlagNotSupported.
2405 if eWaitResult not in (vboxcon.GuestSessionWaitResult_Start, vboxcon.GuestSessionWaitResult_WaitFlagNotSupported):
2406 return (reporter.error('Session did not start successfully - wait error: %d' % (eWaitResult,)), oTxsSession);
2407 reporter.log('Session successfully started');
2408
2409 #
2410 # Create a process.
2411 #
2412 sImage = self.getGuestSystemShell(oTestVm);
2413 asArgs = [ sImage, ];
2414 aEnv = [];
2415 fFlags = [];
2416 try:
2417 oGuestProcess = oGuestSession.processCreate(sImage,
2418 asArgs if self.oTstDrv.fpApiVer >= 5.0 else asArgs[1:], aEnv, fFlags,
2419 30 * 1000);
2420 except:
2421 fRc = reporter.error('Failed to start shell process (%s)' % (sImage,));
2422 else:
2423 try:
2424 eWaitResult = oGuestProcess.waitForArray([ vboxcon.ProcessWaitForFlag_Start ], 30 * 1000);
2425 except:
2426 fRc = reporter.errorXcpt('Waiting for shell process (%s) to start failed' % (sImage,));
2427 else:
2428 # Check the result and state:
2429 try: eStatus = oGuestProcess.status;
2430 except: fRc = reporter.errorXcpt('Waiting for shell process (%s) to start failed' % (sImage,));
2431 else:
2432 reporter.log2('Starting process wait result returned: %d; Process status is: %d' % (eWaitResult, eStatus,));
2433 if eWaitResult != vboxcon.ProcessWaitResult_Start:
2434 fRc = reporter.error('wait for ProcessWaitForFlag_Start failed: %d, expected %d (Start)'
2435 % (eWaitResult, vboxcon.ProcessWaitResult_Start,));
2436 elif eStatus != vboxcon.ProcessStatus_Started:
2437 fRc = reporter.error('Unexpected process status after startup: %d, wanted %d (Started)'
2438 % (eStatus, vboxcon.ProcessStatus_Started,));
2439 else:
2440 # Create a thread that waits on the process to terminate
2441 reporter.log('Creating reboot thread ...');
2442 oThreadReboot = threading.Thread(target = self.threadForTestGuestCtrlSessionReboot,
2443 args = (oGuestProcess,),
2444 name = ('threadForTestGuestCtrlSessionReboot'));
2445 oThreadReboot.setDaemon(True);
2446 oThreadReboot.start();
2447
2448 # Not sure why this fudge is needed...
2449 reporter.log('5 second wait fudge before triggering reboot ...');
2450 self.oTstDrv.sleep(5);
2451
2452 # Do the reboot.
2453 reporter.log('Rebooting guest and reconnecting TXS ...');
2454 (oSession, oTxsSession) = self.oTstDrv.txsRebootAndReconnectViaTcp(oSession, oTxsSession,
2455 cMsTimeout = 3 * 60000);
2456 if not oSession or not oTxsSession:
2457 try: oGuestProcess.terminate();
2458 except: reporter.logXcpt();
2459 fRc = False;
2460
2461 reporter.log('Waiting for thread to finish ...');
2462 oThreadReboot.join();
2463
2464 #
2465 # Try make sure we don't leave with a stale process on failure.
2466 #
2467 try: oGuestProcess.terminate();
2468 except: reporter.logXcpt();
2469
2470 #
2471 # Close the session.
2472 #
2473 reporter.log2('Closing guest session ...');
2474 try:
2475 oGuestSession.close();
2476 except:
2477 fRc = reporter.errorXcpt();
2478
2479 return (fRc, oTxsSession);
2480
2481 def testGuestCtrlExecTimeout(self, oSession, oTxsSession, oTestVm):
2482 """
2483 Tests handling of timeouts of started guest processes.
2484 """
2485
2486 sShell = self.getGuestSystemShell(oTestVm);
2487
2488 # Use credential defaults.
2489 oCreds = tdCtxCreds();
2490 oCreds.applyDefaultsIfNotSet(oTestVm);
2491
2492 #
2493 # Create a session.
2494 #
2495 try:
2496 oGuest = oSession.o.console.guest;
2497 oGuestSession = oGuest.createSession(oCreds.sUser, oCreds.sPassword, oCreds.sDomain, "testGuestCtrlExecTimeout");
2498 eWaitResult = oGuestSession.waitForArray([ vboxcon.GuestSessionWaitForFlag_Start, ], 30 * 1000);
2499 except:
2500 return (reporter.errorXcpt(), oTxsSession);
2501
2502 # Be nice to Guest Additions < 4.3: They don't support session handling and therefore return WaitFlagNotSupported.
2503 if eWaitResult not in (vboxcon.GuestSessionWaitResult_Start, vboxcon.GuestSessionWaitResult_WaitFlagNotSupported):
2504 return (reporter.error('Session did not start successfully - wait error: %d' % (eWaitResult,)), oTxsSession);
2505 reporter.log('Session successfully started');
2506
2507 #
2508 # Create a process which never terminates and should timeout when
2509 # waiting for termination.
2510 #
2511 fRc = True;
2512 try:
2513 oCurProcess = oGuestSession.processCreate(sShell, [sShell,] if self.oTstDrv.fpApiVer >= 5.0 else [],
2514 [], [], 30 * 1000);
2515 except:
2516 fRc = reporter.errorXcpt();
2517 else:
2518 reporter.log('Waiting for process 1 being started ...');
2519 try:
2520 eWaitResult = oCurProcess.waitForArray([ vboxcon.ProcessWaitForFlag_Start ], 30 * 1000);
2521 except:
2522 fRc = reporter.errorXcpt();
2523 else:
2524 if eWaitResult != vboxcon.ProcessWaitResult_Start:
2525 fRc = reporter.error('Waiting for process 1 to start failed, got status %d' % (eWaitResult,));
2526 else:
2527 for msWait in (1, 32, 2000,):
2528 reporter.log('Waiting for process 1 to time out within %sms ...' % (msWait,));
2529 try:
2530 eWaitResult = oCurProcess.waitForArray([ vboxcon.ProcessWaitForFlag_Terminate, ], msWait);
2531 except:
2532 fRc = reporter.errorXcpt();
2533 break;
2534 if eWaitResult != vboxcon.ProcessWaitResult_Timeout:
2535 fRc = reporter.error('Waiting for process 1 did not time out in %sms as expected: %d'
2536 % (msWait, eWaitResult,));
2537 break;
2538 reporter.log('Waiting for process 1 timed out in %u ms, good' % (msWait,));
2539
2540 try:
2541 oCurProcess.terminate();
2542 except:
2543 reporter.errorXcpt();
2544 oCurProcess = None;
2545
2546 #
2547 # Create another process that doesn't terminate, but which will be killed by VBoxService
2548 # because it ran out of execution time (3 seconds).
2549 #
2550 try:
2551 oCurProcess = oGuestSession.processCreate(sShell, [sShell,] if self.oTstDrv.fpApiVer >= 5.0 else [],
2552 [], [], 3 * 1000);
2553 except:
2554 fRc = reporter.errorXcpt();
2555 else:
2556 reporter.log('Waiting for process 2 being started ...');
2557 try:
2558 eWaitResult = oCurProcess.waitForArray([ vboxcon.ProcessWaitForFlag_Start ], 30 * 1000);
2559 except:
2560 fRc = reporter.errorXcpt();
2561 else:
2562 if eWaitResult != vboxcon.ProcessWaitResult_Start:
2563 fRc = reporter.error('Waiting for process 2 to start failed, got status %d' % (eWaitResult,));
2564 else:
2565 reporter.log('Waiting for process 2 to get killed for running out of execution time ...');
2566 try:
2567 eWaitResult = oCurProcess.waitForArray([ vboxcon.ProcessWaitForFlag_Terminate, ], 15 * 1000);
2568 except:
2569 fRc = reporter.errorXcpt();
2570 else:
2571 if eWaitResult != vboxcon.ProcessWaitResult_Timeout:
2572 fRc = reporter.error('Waiting for process 2 did not time out when it should, got wait result %d'
2573 % (eWaitResult,));
2574 else:
2575 reporter.log('Waiting for process 2 did not time out, good: %s' % (eWaitResult,));
2576 try:
2577 eStatus = oCurProcess.status;
2578 except:
2579 fRc = reporter.errorXcpt();
2580 else:
2581 if eStatus != vboxcon.ProcessStatus_TimedOutKilled:
2582 fRc = reporter.error('Status of process 2 wrong; excepted %d, got %d'
2583 % (vboxcon.ProcessStatus_TimedOutKilled, eStatus));
2584 else:
2585 reporter.log('Status of process 2 is TimedOutKilled (%d) is it should be.'
2586 % (vboxcon.ProcessStatus_TimedOutKilled,));
2587 try:
2588 oCurProcess.terminate();
2589 except:
2590 reporter.logXcpt();
2591 oCurProcess = None;
2592
2593 #
2594 # Clean up the session.
2595 #
2596 try:
2597 oGuestSession.close();
2598 except:
2599 fRc = reporter.errorXcpt();
2600
2601 return (fRc, oTxsSession);
2602
2603 def testGuestCtrlDirCreate(self, oSession, oTxsSession, oTestVm):
2604 """
2605 Tests creation of guest directories.
2606 """
2607
2608 sScratch = oTestVm.pathJoin(self.getGuestTempDir(oTestVm), 'testGuestCtrlDirCreate');
2609
2610 atTests = [
2611 # Invalid stuff.
2612 [ tdTestDirCreate(sDirectory = '' ), tdTestResultFailure() ],
2613 # More unusual stuff.
2614 [ tdTestDirCreate(sDirectory = oTestVm.pathJoin('..', '..') ), tdTestResultFailure() ],
2615 [ tdTestDirCreate(sDirectory = oTestVm.pathJoin('..', '.') ), tdTestResultFailure() ],
2616 ];
2617 if oTestVm.isWindows() or oTestVm.isOS2():
2618 atTests.extend([
2619 [ tdTestDirCreate(sDirectory = '..' ), tdTestResultFailure() ],
2620 [ tdTestDirCreate(sDirectory = '../' ), tdTestResultFailure() ],
2621 [ tdTestDirCreate(sDirectory = '../../' ), tdTestResultFailure() ],
2622 [ tdTestDirCreate(sDirectory = 'C:\\' ), tdTestResultFailure() ],
2623 [ tdTestDirCreate(sDirectory = '\\\\uncrulez\\foo' ), tdTestResultFailure() ],
2624 ]);
2625 atTests.extend([
2626 # Existing directories and files.
2627 [ tdTestDirCreate(sDirectory = self.getGuestSystemDir(oTestVm) ), tdTestResultFailure() ],
2628 [ tdTestDirCreate(sDirectory = self.getGuestSystemShell(oTestVm) ), tdTestResultFailure() ],
2629 [ tdTestDirCreate(sDirectory = self.getGuestSystemFileForReading(oTestVm) ), tdTestResultFailure() ],
2630 ]);
2631
2632 atTests.extend([
2633 # Creating directories.
2634 [ tdTestDirCreate(sDirectory = sScratch ), tdTestResultSuccess() ],
2635 [ tdTestDirCreate(sDirectory = oTestVm.pathJoin(sScratch, 'foo', 'bar', 'baz'),
2636 fFlags = (vboxcon.DirectoryCreateFlag_Parents,) ), tdTestResultSuccess() ],
2637 [ tdTestDirCreate(sDirectory = oTestVm.pathJoin(sScratch, 'foo', 'bar', 'baz'),
2638 fFlags = (vboxcon.DirectoryCreateFlag_Parents,) ), tdTestResultSuccess() ],
2639 # Long random names.
2640 [ tdTestDirCreate(sDirectory = oTestVm.pathJoin(sScratch, self.oTestFiles.generateFilenameEx(36, 28))),
2641 tdTestResultSuccess() ],
2642 [ tdTestDirCreate(sDirectory = oTestVm.pathJoin(sScratch, self.oTestFiles.generateFilenameEx(140, 116))),
2643 tdTestResultSuccess() ],
2644 # Too long names. ASSUMES a guests has a 255 filename length limitation.
2645 [ tdTestDirCreate(sDirectory = oTestVm.pathJoin(sScratch, self.oTestFiles.generateFilenameEx(2048, 256))),
2646 tdTestResultFailure() ],
2647 [ tdTestDirCreate(sDirectory = oTestVm.pathJoin(sScratch, self.oTestFiles.generateFilenameEx(2048, 256))),
2648 tdTestResultFailure() ],
2649 # Missing directory in path.
2650 [ tdTestDirCreate(sDirectory = oTestVm.pathJoin(sScratch, 'foo1', 'bar') ), tdTestResultFailure() ],
2651 ]);
2652
2653 fRc = True;
2654 for (i, tTest) in enumerate(atTests):
2655 oCurTest = tTest[0] # type: tdTestDirCreate
2656 oCurRes = tTest[1] # type: tdTestResult
2657 reporter.log('Testing #%d, sDirectory="%s" ...' % (i, oCurTest.sDirectory));
2658
2659 oCurTest.setEnvironment(oSession, oTxsSession, oTestVm);
2660 fRc, oCurGuestSession = oCurTest.createSession('testGuestCtrlDirCreate: Test #%d' % (i,), fIsError = True);
2661 if fRc is False:
2662 return reporter.error('Test #%d failed: Could not create session' % (i,));
2663
2664 fRc = self.gctrlCreateDir(oCurTest, oCurRes, oCurGuestSession);
2665
2666 fRc = oCurTest.closeSession(fIsError = True) and fRc;
2667 if fRc is False:
2668 reporter.error('Test #%d failed' % (i,));
2669 break;
2670
2671 return (fRc, oTxsSession);
2672
2673 def testGuestCtrlDirCreateTemp(self, oSession, oTxsSession, oTestVm): # pylint: disable=too-many-locals
2674 """
2675 Tests creation of temporary directories.
2676 """
2677
2678 atTests = [];
2679 if oTestVm.isWindows():
2680 atTests.extend([
2681 # Invalid stuff.
2682 [ tdTestDirCreateTemp(sDirectory = ''), tdTestResultFailure() ],
2683 [ tdTestDirCreateTemp(sDirectory = 'C:\\Windows', fMode = 1234), tdTestResultFailure() ],
2684 [ tdTestDirCreateTemp(sTemplate = '', sDirectory = 'C:\\Windows', fMode = 1234), tdTestResultFailure() ],
2685 [ tdTestDirCreateTemp(sTemplate = 'xXx', sDirectory = 'C:\\Windows', fMode = 0o700), tdTestResultFailure() ],
2686 [ tdTestDirCreateTemp(sTemplate = 'xxx', sDirectory = 'C:\\Windows', fMode = 0o700), tdTestResultFailure() ],
2687 # More unusual stuff.
2688 [ tdTestDirCreateTemp(sTemplate = 'foo', sDirectory = 'z:\\'), tdTestResultFailure() ],
2689 [ tdTestDirCreateTemp(sTemplate = 'foo', sDirectory = '\\\\uncrulez\\foo'), tdTestResultFailure() ],
2690 # Non-existing stuff.
2691 [ tdTestDirCreateTemp(sTemplate = 'bar', sDirectory = 'c:\\Apps\\nonexisting\\foo'), tdTestResultFailure() ],
2692 # FIXME: Failing test. Non Windows path
2693 # [ tdTestDirCreateTemp(sTemplate = 'bar', sDirectory = '/tmp/non/existing'), tdTestResultFailure() ]
2694 ]);
2695 elif oTestVm.isLinux():
2696 atTests.extend([
2697 # Invalid stuff.
2698 [ tdTestDirCreateTemp(sDirectory = ''), tdTestResultFailure() ],
2699 [ tdTestDirCreateTemp(sDirectory = '/etc', fMode = 1234) ],
2700 [ tdTestDirCreateTemp(sTemplate = '', sDirectory = '/etc', fMode = 1234), tdTestResultFailure() ],
2701 [ tdTestDirCreateTemp(sTemplate = 'xXx', sDirectory = '/etc', fMode = 0o700), tdTestResultFailure() ],
2702 [ tdTestDirCreateTemp(sTemplate = 'xxx', sDirectory = '/etc', fMode = 0o700), tdTestResultFailure() ],
2703 # More unusual stuff.
2704 [ tdTestDirCreateTemp(sTemplate = 'foo', sDirectory = 'z:\\'), tdTestResultFailure() ],
2705 [ tdTestDirCreateTemp(sTemplate = 'foo', sDirectory = '\\\\uncrulez\\foo'), tdTestResultFailure() ],
2706 # Non-existing stuff.
2707 [ tdTestDirCreateTemp(sTemplate = 'bar', sDirectory = '/non/existing'), tdTestResultFailure() ],
2708 ]);
2709
2710 # FIXME: Failing tests.
2711 # atTests.extend([
2712 # Non-secure variants.
2713 # [ tdTestDirCreateTemp(sTemplate = 'XXX',
2714 # sDirectory = sScratch),
2715 # tdTestResultSuccess() ],
2716 # [ tdTestDirCreateTemp(sTemplate = 'XXX',
2717 # sDirectory = sScratch),
2718 # tdTestResultSuccess() ],
2719 # [ tdTestDirCreateTemp(sTemplate = 'X',
2720 # sDirectory = sScratch),
2721 # tdTestResultSuccess() ],
2722 # [ tdTestDirCreateTemp(sTemplate = 'X',
2723 # sDirectory = sScratch),
2724 # tdTestResultSuccess() ],
2725 # [ tdTestDirCreateTemp(sTemplate = 'XXX',
2726 # sDirectory = sScratch,
2727 # fMode = 0o700),
2728 # tdTestResultSuccess() ],
2729 # [ tdTestDirCreateTemp(sTemplate = 'XXX',
2730 # sDirectory = sScratch,
2731 # fMode = 0o700),
2732 # tdTestResultSuccess() ],
2733 # [ tdTestDirCreateTemp(sTemplate = 'XXX',
2734 # sDirectory = sScratch,
2735 # fMode = 0o755),
2736 # tdTestResultSuccess() ],
2737 # [ tdTestDirCreateTemp(sTemplate = 'XXX',
2738 # sDirectory = sScratch,
2739 # fMode = 0o755),
2740 # tdTestResultSuccess() ],
2741 # Secure variants.
2742 # [ tdTestDirCreateTemp(sTemplate = 'XXX',
2743 # sDirectory = sScratch, fSecure = True),
2744 # tdTestResultSuccess() ],
2745 # [ tdTestDirCreateTemp(sTemplate = 'XXX',
2746 # sDirectory = sScratch, fSecure = True),
2747 # tdTestResultSuccess() ],
2748 # [ tdTestDirCreateTemp(sTemplate = 'XXX',
2749 # sDirectory = sScratch, fSecure = True),
2750 # tdTestResultSuccess() ],
2751 # [ tdTestDirCreateTemp(sTemplate = 'XXX',
2752 # sDirectory = sScratch, fSecure = True),
2753 # tdTestResultSuccess() ],
2754 # [ tdTestDirCreateTemp(sTemplate = 'XXX',
2755 # sDirectory = sScratch,
2756 # fSecure = True, fMode = 0o700),
2757 # tdTestResultSuccess() ],
2758 # [ tdTestDirCreateTemp(sTemplate = 'XXX',
2759 # sDirectory = sScratch,
2760 # fSecure = True, fMode = 0o700),
2761 # tdTestResultSuccess() ],
2762 # [ tdTestDirCreateTemp(sTemplate = 'XXX',
2763 # sDirectory = sScratch,
2764 # fSecure = True, fMode = 0o755),
2765 # tdTestResultSuccess() ],
2766 # [ tdTestDirCreateTemp(sTemplate = 'XXX',
2767 # sDirectory = sScratch,
2768 # fSecure = True, fMode = 0o755),
2769 # tdTestResultSuccess() ],
2770 # Random stuff.
2771 # [ tdTestDirCreateTemp(
2772 # sTemplate = "XXX-".join(random.choice(string.ascii_lowercase) for i in xrange(32)),
2773 # sDirectory = sScratch,
2774 # fSecure = True, fMode = 0o755),
2775 # tdTestResultSuccess() ],
2776 # [ tdTestDirCreateTemp(sTemplate = "".join('X' for i in xrange(32)),
2777 # sDirectory = sScratch,
2778 # fSecure = True, fMode = 0o755),
2779 # tdTestResultSuccess() ],
2780 # [ tdTestDirCreateTemp(sTemplate = "".join('X' for i in xrange(128)),
2781 # sDirectory = sScratch,
2782 # fSecure = True, fMode = 0o755),
2783 # tdTestResultSuccess() ]
2784 # ]);
2785
2786 fRc = True;
2787 for (i, aTest) in enumerate(atTests):
2788 oCurTest = aTest[0]; # tdTestExec, use an index, later.
2789 oCurRes = aTest[1]; # tdTestResult
2790 reporter.log('Testing #%d, sTemplate="%s", fMode=%#o, path="%s", secure="%s" ...' %
2791 (i, oCurTest.sTemplate, oCurTest.fMode, oCurTest.sDirectory, oCurTest.fSecure));
2792 oCurTest.setEnvironment(oSession, oTxsSession, oTestVm);
2793 fRc, oCurGuestSession = oCurTest.createSession('testGuestCtrlDirCreateTemp: Test #%d' % (i,));
2794 if fRc is False:
2795 reporter.error('Test #%d failed: Could not create session' % (i,));
2796 break;
2797 sDirTemp = "";
2798 try:
2799 sDirTemp = oCurGuestSession.directoryCreateTemp(oCurTest.sTemplate, oCurTest.fMode,
2800 oCurTest.sDirectory, oCurTest.fSecure);
2801 except:
2802 if oCurRes.fRc is True:
2803 reporter.errorXcpt('Creating temp directory "%s" failed:' % (oCurTest.sDirectory,));
2804 fRc = False;
2805 break;
2806 else:
2807 reporter.logXcpt('Creating temp directory "%s" failed expectedly, skipping:' % (oCurTest.sDirectory,));
2808 oCurTest.closeSession();
2809 if sDirTemp != "":
2810 reporter.log2('Temporary directory is: %s' % (sDirTemp,));
2811 if self.oTstDrv.fpApiVer >= 5.0:
2812 fExists = oCurGuestSession.directoryExists(sDirTemp, False);
2813 else:
2814 fExists = oCurGuestSession.directoryExists(sDirTemp);
2815 if fExists is False:
2816 reporter.error('Test #%d failed: Temporary directory "%s" does not exists' % (i, sDirTemp));
2817 fRc = False;
2818 break;
2819 return (fRc, oTxsSession);
2820
2821 def testGuestCtrlDirRead(self, oSession, oTxsSession, oTestVm):
2822 """
2823 Tests opening and reading (enumerating) guest directories.
2824 """
2825
2826 sSystemDir = self.getGuestSystemDir(oTestVm);
2827 atTests = [
2828 # Invalid stuff.
2829 [ tdTestDirRead(sDirectory = ''), tdTestResultDirRead() ],
2830 [ tdTestDirRead(sDirectory = sSystemDir, fFlags = [ 1234 ]), tdTestResultDirRead() ],
2831 [ tdTestDirRead(sDirectory = sSystemDir, sFilter = '*.foo'), tdTestResultDirRead() ],
2832 # Non-existing stuff.
2833 [ tdTestDirRead(sDirectory = oTestVm.pathJoin(sSystemDir, 'really-no-such-subdir')), tdTestResultDirRead() ],
2834 [ tdTestDirRead(sDirectory = oTestVm.pathJoin(sSystemDir, 'non', 'existing')), tdTestResultDirRead() ],
2835 ];
2836
2837 if oTestVm.isWindows() or oTestVm.isOS2():
2838 atTests.extend([
2839 # More unusual stuff.
2840 [ tdTestDirRead(sDirectory = 'z:\\'), tdTestResultDirRead() ],
2841 [ tdTestDirRead(sDirectory = '\\\\uncrulez\\foo'), tdTestResultDirRead() ],
2842 ]);
2843 else:
2844 atTests.extend([
2845 # More unusual stuff.
2846 [ tdTestDirRead(sDirectory = 'z:/'), tdTestResultDirRead() ],
2847 [ tdTestDirRead(sDirectory = '\\\\uncrulez\\foo'), tdTestResultDirRead() ],
2848 ]);
2849 # Read the system directory (ASSUMES at least 5 files in it):
2850 atTests.append([ tdTestDirRead(sDirectory = sSystemDir), tdTestResultDirRead(fRc = True, cFiles = -5, cDirs = None) ]);
2851 ## @todo trailing slash
2852
2853 # Read from the test file set.
2854 atTests.extend([
2855 [ tdTestDirRead(sDirectory = self.oTestFiles.oEmptyDir.sPath),
2856 tdTestResultDirRead(fRc = True, cFiles = 0, cDirs = 0, cOthers = 0) ],
2857 [ tdTestDirRead(sDirectory = self.oTestFiles.oManyDir.sPath),
2858 tdTestResultDirRead(fRc = True, cFiles = len(self.oTestFiles.oManyDir.aoChildren), cDirs = 0, cOthers = 0) ],
2859 [ tdTestDirRead(sDirectory = self.oTestFiles.oTreeDir.sPath),
2860 tdTestResultDirRead(fRc = True, cFiles = self.oTestFiles.cTreeFiles, cDirs = self.oTestFiles.cTreeDirs,
2861 cOthers = self.oTestFiles.cTreeOthers) ],
2862 ]);
2863
2864
2865 fRc = True;
2866 for (i, tTest) in enumerate(atTests):
2867 oCurTest = tTest[0] # type: tdTestExec
2868 oCurRes = tTest[1] # type: tdTestResultDirRead
2869
2870 reporter.log('Testing #%d, dir="%s" ...' % (i, oCurTest.sDirectory));
2871 oCurTest.setEnvironment(oSession, oTxsSession, oTestVm);
2872 fRc, oCurGuestSession = oCurTest.createSession('testGuestCtrlDirRead: Test #%d' % (i,), True);
2873 if fRc is not True:
2874 break;
2875 (fRc2, cDirs, cFiles, cOthers) = self.gctrlReadDirTree(oCurTest, oCurGuestSession, oCurRes.fRc);
2876 fRc = oCurTest.closeSession(True) and fRc;
2877
2878 reporter.log2('Test #%d: Returned %d directories, %d files total' % (i, cDirs, cFiles));
2879 if fRc2 is oCurRes.fRc:
2880 if fRc2 is True:
2881 if oCurRes.cFiles is None:
2882 pass; # ignore
2883 elif oCurRes.cFiles >= 0 and cFiles != oCurRes.cFiles:
2884 fRc = reporter.error('Test #%d failed: Got %d files, expected %d' % (i, cFiles, oCurRes.cFiles));
2885 elif oCurRes.cFiles < 0 and cFiles < -oCurRes.cFiles:
2886 fRc = reporter.error('Test #%d failed: Got %d files, expected at least %d'
2887 % (i, cFiles, -oCurRes.cFiles));
2888 if oCurRes.cDirs is None:
2889 pass; # ignore
2890 elif oCurRes.cDirs >= 0 and cDirs != oCurRes.cDirs:
2891 fRc = reporter.error('Test #%d failed: Got %d directories, expected %d' % (i, cDirs, oCurRes.cDirs));
2892 elif oCurRes.cDirs < 0 and cDirs < -oCurRes.cDirs:
2893 fRc = reporter.error('Test #%d failed: Got %d directories, expected at least %d'
2894 % (i, cDirs, -oCurRes.cDirs));
2895 if oCurRes.cOthers is None:
2896 pass; # ignore
2897 elif oCurRes.cOthers >= 0 and cOthers != oCurRes.cOthers:
2898 fRc = reporter.error('Test #%d failed: Got %d other types, expected %d' % (i, cOthers, oCurRes.cOthers));
2899 elif oCurRes.cOthers < 0 and cOthers < -oCurRes.cOthers:
2900 fRc = reporter.error('Test #%d failed: Got %d other types, expected at least %d'
2901 % (i, cOthers, -oCurRes.cOthers));
2902
2903 else:
2904 fRc = reporter.error('Test #%d failed: Got %s, expected %s' % (i, fRc2, oCurRes.fRc));
2905
2906
2907 #
2908 # Go over a few directories in the test file set and compare names,
2909 # types and sizes rather than just the counts like we did above.
2910 #
2911 if fRc is True:
2912 oCurTest = tdTestDirRead();
2913 oCurTest.setEnvironment(oSession, oTxsSession, oTestVm);
2914 fRc, oCurGuestSession = oCurTest.createSession('testGuestCtrlDirRead: gctrlReadDirTree2', True);
2915 if fRc is True:
2916 for oDir in (self.oTestFiles.oEmptyDir, self.oTestFiles.oManyDir, self.oTestFiles.oTreeDir):
2917 reporter.log('Checking "%s" ...' % (oDir.sPath,));
2918 fRc = self.gctrlReadDirTree2(oCurGuestSession, oDir) and fRc;
2919 fRc = oCurTest.closeSession(True) and fRc;
2920
2921 return (fRc, oTxsSession);
2922
2923 def testGuestCtrlFileRemove(self, oSession, oTxsSession, oTestVm):
2924 """
2925 Tests removing guest files.
2926 """
2927
2928 ## @todo r=bird: This fails on windows 7 RTM. Just create a stupid file and delete it again,
2929 # this chord.wav stuff is utter nonsense.
2930 if oTestVm.isWindows():
2931 sFileToDelete = "c:\\Windows\\Media\\chord.wav";
2932 else:
2933 sFileToDelete = "/home/vbox/.profile";
2934
2935 atTests = [];
2936 if oTestVm.isWindows():
2937 atTests.extend([
2938 # Invalid stuff.
2939 [ tdTestFileRemove(sFile = ''), tdTestResultFailure() ],
2940 [ tdTestFileRemove(sFile = 'C:\\Windows'), tdTestResultFailure() ],
2941 # More unusual stuff.
2942 [ tdTestFileRemove(sFile = 'z:\\'), tdTestResultFailure() ],
2943 [ tdTestFileRemove(sFile = '\\\\uncrulez\\foo'), tdTestResultFailure() ],
2944 # Non-existing stuff.
2945 [ tdTestFileRemove(sFile = 'c:\\Apps\\nonexisting'), tdTestResultFailure() ],
2946 # Try to delete system files.
2947 [ tdTestFileRemove(sFile = 'c:\\pagefile.sys'), tdTestResultFailure() ],
2948 [ tdTestFileRemove(sFile = 'c:\\Windows\\kernel32.sys'), tdTestResultFailure() ] ## r=bird: it's in \system32\ ...
2949 ]);
2950
2951 if oTestVm.sKind == "WindowsXP":
2952 atTests.extend([
2953 # Try delete some unimportant media stuff.
2954 [ tdTestFileRemove(sFile = 'c:\\Windows\\Media\\chimes.wav'), tdTestResultSuccess() ],
2955 # Second attempt should fail.
2956 [ tdTestFileRemove(sFile = 'c:\\Windows\\Media\\chimes.wav'), tdTestResultFailure() ]
2957 ]);
2958 elif oTestVm.isLinux():
2959 atTests.extend([
2960 # Invalid stuff.
2961 [ tdTestFileRemove(sFile = ''), tdTestResultFailure() ],
2962 [ tdTestFileRemove(sFile = 'C:\\Windows'), tdTestResultFailure() ],
2963 # More unusual stuff.
2964 [ tdTestFileRemove(sFile = 'z:/'), tdTestResultFailure() ],
2965 [ tdTestFileRemove(sFile = '//uncrulez/foo'), tdTestResultFailure() ],
2966 # Non-existing stuff.
2967 [ tdTestFileRemove(sFile = '/non/existing'), tdTestResultFailure() ],
2968 # Try to delete system files.
2969 [ tdTestFileRemove(sFile = '/etc'), tdTestResultFailure() ],
2970 [ tdTestFileRemove(sFile = '/bin/sh'), tdTestResultFailure() ]
2971 ]);
2972
2973 atTests.extend([
2974 # Try delete some unimportant stuff.
2975 [ tdTestFileRemove(sFile = sFileToDelete), tdTestResultSuccess() ],
2976 # Second attempt should fail.
2977 [ tdTestFileRemove(sFile = sFileToDelete), tdTestResultFailure() ]
2978 ]);
2979
2980 fRc = True;
2981 for (i, aTest) in enumerate(atTests):
2982 oCurTest = aTest[0]; # tdTestExec, use an index, later.
2983 oCurRes = aTest[1]; # tdTestResult
2984 reporter.log('Testing #%d, file="%s" ...' % (i, oCurTest.sFile));
2985 oCurTest.setEnvironment(oSession, oTxsSession, oTestVm);
2986 fRc, oCurGuestSession = oCurTest.createSession('testGuestCtrlFileRemove: Test #%d' % (i,));
2987 if fRc is False:
2988 reporter.error('Test #%d failed: Could not create session' % (i,));
2989 break;
2990 try:
2991 if self.oTstDrv.fpApiVer >= 5.0:
2992 oCurGuestSession.fsObjRemove(oCurTest.sFile);
2993 else:
2994 oCurGuestSession.fileRemove(oCurTest.sFile);
2995 except:
2996 if oCurRes.fRc is True:
2997 reporter.errorXcpt('Removing file "%s" failed:' % (oCurTest.sFile,));
2998 fRc = False;
2999 break;
3000 else:
3001 reporter.logXcpt('Removing file "%s" failed expectedly, skipping:' % (oCurTest.sFile,));
3002 oCurTest.closeSession();
3003 return (fRc, oTxsSession);
3004
3005 def testGuestCtrlFileStat(self, oSession, oTxsSession, oTestVm): # pylint: disable=too-many-locals
3006 """
3007 Tests querying file information through stat.
3008 """
3009
3010 # Basic stuff, existing stuff.
3011 aoTests = [
3012 tdTestSessionEx([ tdStepStatDir('.'),
3013 tdStepStatDir('..'),
3014 ]),
3015 ];
3016 if oTestVm.isWindows():
3017 aoTests += [ tdTestSessionEx([ tdStepStatDir('C:\\Windows'),
3018 tdStepStatDir('C:\\Windows\\System32'),
3019 tdStepStatDir('C:\\Windows\\System32\\'),
3020 tdStepStatDir('C:\\Windows\\System32\\.'),
3021 tdStepStatDir('C:\\Windows\\System32\\.\\'),
3022 tdStepStatDir('C:\\Windows\\System32\\..'),
3023 tdStepStatDir('C:\\Windows\\System32\\..\\'),
3024 tdStepStatDir('C:\\Windows\\System32\\..\\\\'),
3025 tdStepStatDir('C:\\Windows\\System32\\\\..\\\\'),
3026 tdStepStatDir('C:/Windows/System32'),
3027 tdStepStatDir('C:/Windows/System32/'),
3028 tdStepStatDir('c:/winDowS/sYsTeM32/'),
3029 tdStepStatDir('C:/Windows/System32/.'),
3030 tdStepStatDir('C:/Windows/System32/./'),
3031 tdStepStatDir('C:/Windows/System32/..'),
3032 tdStepStatDir('C:/Windows/System32/../'),
3033 tdStepStatDir('C:/Windows/System32/..//'),
3034 tdStepStatDir('C:/Windows/System32//..//'),
3035 tdStepStatFile('C:\\Windows\\System32\\kernel32.dll'),
3036 tdStepStatFile('C:/Windows/System32/kernel32.dll')
3037 ]) ];
3038 elif oTestVm.isOS2():
3039 aoTests += [ tdTestSessionEx([ tdStepStatDir('C:\\OS2'),
3040 tdStepStatDir('C:\\OS2\\DLL'),
3041 tdStepStatDir('C:\\OS2\\DLL\\'),
3042 tdStepStatDir('C:/OS2/DLL'),
3043 tdStepStatDir('c:/OS2/DLL'),
3044 tdStepStatDir('c:/OS2/DLL/'),
3045 tdStepStatFile('C:\\CONFIG.SYS'),
3046 tdStepStatFile('C:\\OS2\\DLL\\DOSCALL1.DLL'),
3047 ]) ];
3048 else: # generic unix.
3049 aoTests += [ tdTestSessionEx([ tdStepStatDir('/'),
3050 tdStepStatDir('///'),
3051 tdStepStatDir('/usr/bin/.'),
3052 tdStepStatDir('/usr/bin/./'),
3053 tdStepStatDir('/usr/bin/..'),
3054 tdStepStatDir('/usr/bin/../'),
3055 tdStepStatFile('/bin/ls'),
3056 tdStepStatFile('/bin/cp'),
3057 tdStepStatFile('/bin/date'),
3058 ]) ];
3059 # None existing stuff.
3060 if oTestVm.isWindows() or oTestVm.isOS2():
3061 aoTests += [ tdTestSessionEx([ tdStepStatFileNotFound('C:\\NoSuchFileOrDirectory', ),
3062 tdStepStatPathNotFound('C:\\NoSuchDirectory\\'),
3063 tdStepStatPathNotFound('C:/NoSuchDirectory/'),
3064 tdStepStatPathNotFound('C:\\NoSuchDirectory\\.'),
3065 tdStepStatPathNotFound('C:/NoSuchDirectory/.'),
3066 tdStepStatPathNotFound('C:\\NoSuchDirectory\\NoSuchFileOrDirectory'),
3067 tdStepStatPathNotFound('C:/NoSuchDirectory/NoSuchFileOrDirectory'),
3068 tdStepStatPathNotFound('C:/NoSuchDirectory/NoSuchFileOrDirectory/'),
3069 tdStepStatPathNotFound('N:\\'), # ASSUMES nothing mounted on N:!
3070 tdStepStatPathNotFound('\\\\NoSuchUncServerName\\NoSuchShare'),
3071 ]) ];
3072 else: # generic unix.
3073 aoTests += [ tdTestSessionEx([ tdStepStatFileNotFound('/NoSuchFileOrDirectory', ),
3074 tdStepStatFileNotFound('/bin/NoSuchFileOrDirectory'),
3075 tdStepStatPathNotFound('/NoSuchDirectory/'),
3076 tdStepStatPathNotFound('/NoSuchDirectory/.'),
3077 ]) ];
3078 # Invalid parameter check.
3079 aoTests += [ tdTestSessionEx([ tdStepStat('', vbox.ComError.E_INVALIDARG), ]), ];
3080
3081 # Some test VM specific tests.
3082 if oTestVm.sVmName.startswith('tst-xpsp2'):
3083 aoTests += [ tdTestSessionEx([ tdStepStatFileSize('c:\\Windows\\system32\\kernel32.dll', 983552), ]) ];
3084
3085 #
3086 # Execute the tests.
3087 #
3088 return tdTestSessionEx.executeListTestSessions(aoTests, self.oTstDrv, oSession, oTxsSession, oTestVm, 'FsStat');
3089
3090 def testGuestCtrlFileRead(self, oSession, oTxsSession, oTestVm): # pylint: disable=too-many-locals
3091 """
3092 Tests reading from guest files.
3093 """
3094
3095 if oTxsSession.syncMkDir('${SCRATCH}/testGuestCtrlFileRead') is False:
3096 reporter.error('Could not create scratch directory on guest');
3097 return (False, oTxsSession);
3098
3099 atTests = [];
3100 atTests.extend([
3101 # Invalid stuff.
3102 [ tdTestFileReadWrite(cbToReadWrite = 0), tdTestResultFileReadWrite() ],
3103 [ tdTestFileReadWrite(sFile = ''), tdTestResultFileReadWrite() ],
3104 [ tdTestFileReadWrite(sFile = 'non-existing.file'), tdTestResultFileReadWrite() ],
3105 # Wrong open mode.
3106 [ tdTestFileReadWrite(sFile = 'non-existing.file', sOpenMode = 'rt', sDisposition = 'oe'),
3107 tdTestResultFileReadWrite() ],
3108 [ tdTestFileReadWrite(sFile = '\\\\uncrulez\\non-existing.file', sOpenMode = 'tr', sDisposition = 'oe'),
3109 tdTestResultFileReadWrite() ],
3110 [ tdTestFileReadWrite(sFile = '../../non-existing.file', sOpenMode = 'wr', sDisposition = 'oe'),
3111 tdTestResultFileReadWrite() ],
3112 # Wrong disposition.
3113 [ tdTestFileReadWrite(sFile = 'non-existing.file', sOpenMode = 'r', sDisposition = 'e'),
3114 tdTestResultFileReadWrite() ],
3115 [ tdTestFileReadWrite(sFile = '\\\\uncrulez\\non-existing.file', sOpenMode = 'r', sDisposition = 'o'),
3116 tdTestResultFileReadWrite() ],
3117 [ tdTestFileReadWrite(sFile = '../../non-existing.file', sOpenMode = 'r', sDisposition = 'c'),
3118 tdTestResultFileReadWrite() ],
3119 # Opening non-existing file when it should exist.
3120 [ tdTestFileReadWrite(sFile = 'non-existing.file', sOpenMode = 'r', sDisposition = 'oe'),
3121 tdTestResultFileReadWrite() ],
3122 [ tdTestFileReadWrite(sFile = '\\\\uncrulez\\non-existing.file', sOpenMode = 'r', sDisposition = 'oe'),
3123 tdTestResultFileReadWrite() ],
3124 [ tdTestFileReadWrite(sFile = '../../non-existing.file', sOpenMode = 'r', sDisposition = 'oe'),
3125 tdTestResultFileReadWrite() ]
3126 ]);
3127
3128 if oTestVm.isWindows():
3129 atTests.extend([
3130 # Create a file which must not exist (but it hopefully does).
3131 [ tdTestFileReadWrite(sFile = 'C:\\Windows\\System32\\calc.exe', sOpenMode = 'w', sDisposition = 'ce'),
3132 tdTestResultFileReadWrite() ],
3133 # Open a file which must exist.
3134 [ tdTestFileReadWrite(sFile = 'C:\\Windows\\System32\\kernel32.dll', sOpenMode = 'r', sDisposition = 'oe'),
3135 tdTestResultFileReadWrite(fRc = True) ],
3136 # Try truncating a file which already is opened with a different sharing mode (and thus should fail).
3137 [ tdTestFileReadWrite(sFile = 'C:\\Windows\\System32\\kernel32.dll', sOpenMode = 'w', sDisposition = 'ot'),
3138 tdTestResultFileReadWrite() ]
3139 ]);
3140
3141 # Note: tst-xppro has other contents in eula.txt.
3142 if oTestVm.sVmName.startswith('tst-xpsp2'):
3143 atTests.extend([
3144 # Reading from beginning.
3145 [ tdTestFileReadWrite(sFile = 'C:\\Windows\\System32\\eula.txt',
3146 sOpenMode = 'r', sDisposition = 'oe', cbToReadWrite = 33),
3147 tdTestResultFileReadWrite(fRc = True, abBuf = 'Microsoft(r) Windows(r) XP Profes',
3148 cbProcessed = 33, offFile = 33) ],
3149 # Reading from offset.
3150 [ tdTestFileReadWrite(sFile = 'C:\\Windows\\System32\\eula.txt',
3151 sOpenMode = 'r', sDisposition = 'oe', offFile = 17769, cbToReadWrite = 31),
3152 tdTestResultFileReadWrite(fRc = True, abBuf = 'only with the HARDWARE. If\x0d\x0a ',
3153 cbProcessed = 31, offFile = 17769 + 31) ]
3154 ]);
3155 elif oTestVm.isLinux():
3156 atTests.extend([
3157 # Create a file which must not exist (but it hopefully does).
3158 [ tdTestFileReadWrite(sFile = '/etc/issue', sOpenMode = 'w', sDisposition = 'ce'),
3159 tdTestResultFileReadWrite() ],
3160 # Open a file which must exist.
3161 [ tdTestFileReadWrite(sFile = '/etc/issue', sOpenMode = 'r', sDisposition = 'oe'),
3162 tdTestResultFileReadWrite(fRc = True) ],
3163 # Try truncating a file which already is opened with a different sharing mode (and thus should fail).
3164 [ tdTestFileReadWrite(sFile = '/etc/issue', sOpenMode = 'w', sDisposition = 'ot'),
3165 tdTestResultFileReadWrite() ]
3166 ]);
3167
3168 fRc = True;
3169 for (i, aTest) in enumerate(atTests):
3170 oCurTest = aTest[0]; # tdTestFileReadWrite, use an index, later.
3171 oCurRes = aTest[1]; # tdTestResult
3172 reporter.log('Testing #%d, sFile="%s", cbToReadWrite=%d, sOpenMode="%s", sDisposition="%s", offFile=%d ...'
3173 % (i, oCurTest.sFile, oCurTest.cbToReadWrite, oCurTest.sOpenMode,
3174 oCurTest.sDisposition, oCurTest.offFile));
3175 oCurTest.setEnvironment(oSession, oTxsSession, oTestVm);
3176 fRc, oCurGuestSession = oCurTest.createSession('testGuestCtrlFileRead: Test #%d' % (i,));
3177 if fRc is False:
3178 reporter.error('Test #%d failed: Could not create session' % (i,));
3179 break;
3180 try:
3181 fRc2 = True;
3182 if oCurTest.offFile > 0: # The offset parameter is gone.
3183 if self.oTstDrv.fpApiVer >= 5.0:
3184 curFile = oCurGuestSession.fileOpenEx(oCurTest.sFile, oCurTest.getAccessMode(), oCurTest.getOpenAction(),
3185 oCurTest.getSharingMode(), oCurTest.fCreationMode, []);
3186 curFile.seek(oCurTest.offFile, vboxcon.FileSeekOrigin_Begin);
3187 else:
3188 curFile = oCurGuestSession.fileOpenEx(oCurTest.sFile, oCurTest.sOpenMode, oCurTest.sDisposition,
3189 oCurTest.sSharingMode, oCurTest.fCreationMode, oCurTest.offFile);
3190 curOffset = long(curFile.offset);
3191 resOffset = long(oCurTest.offFile);
3192 if curOffset != resOffset:
3193 reporter.error('Test #%d failed: Initial offset on open does not match: Got %d, expected %d'
3194 % (i, curOffset, resOffset));
3195 fRc2 = False;
3196 else:
3197 if self.oTstDrv.fpApiVer >= 5.0:
3198 curFile = oCurGuestSession.fileOpen(oCurTest.sFile, oCurTest.getAccessMode(), oCurTest.getOpenAction(),
3199 oCurTest.fCreationMode);
3200 else:
3201 curFile = oCurGuestSession.fileOpen(oCurTest.sFile, oCurTest.sOpenMode, oCurTest.sDisposition,
3202 oCurTest.fCreationMode);
3203 if fRc2 and oCurTest.cbToReadWrite > 0:
3204 ## @todo Split this up in 64K reads. Later.
3205 ## @todo Test timeouts.
3206 aBufRead = curFile.read(oCurTest.cbToReadWrite, 30 * 1000);
3207 if oCurRes.cbProcessed > 0 \
3208 and oCurRes.cbProcessed != len(aBufRead):
3209 reporter.error('Test #%d failed: Read buffer length does not match: Got %d, expected %d'
3210 % (i, len(aBufRead), oCurRes.cbProcessed));
3211 fRc2 = False;
3212 if fRc2:
3213 if oCurRes.abBuf is not None \
3214 and not utils.areBytesEqual(oCurRes.abBuf, aBufRead):
3215 reporter.error('Test #%d failed: Got buffer:\n"%s" (%d bytes, type %s)\n'
3216 'Expected buffer:\n"%s" (%d bytes, type %s)'
3217 % (i, map(hex, map(ord, aBufRead)), len(aBufRead), type(aBufRead),
3218 map(hex, map(ord, oCurRes.abBuf)), len(oCurRes.abBuf), type(oCurRes.abBuf),));
3219 reporter.error('Test #%d failed: Got buffer:\n"%s"\nExpected buffer:\n"%s"'
3220 % (i, aBufRead, oCurRes.abBuf));
3221 fRc2 = False;
3222 # Test final offset.
3223 curOffset = long(curFile.offset);
3224 resOffset = long(oCurRes.offFile);
3225 if curOffset != resOffset:
3226 reporter.error('Test #%d failed: Final offset does not match: Got %d, expected %d' \
3227 % (i, curOffset, resOffset));
3228 fRc2 = False;
3229 curFile.close();
3230
3231 if fRc2 != oCurRes.fRc:
3232 reporter.error('Test #%d failed: Got %s, expected %s' % (i, fRc2, oCurRes.fRc));
3233 fRc = False;
3234
3235 except:
3236 reporter.logXcpt('Opening "%s" failed:' % (oCurTest.sFile,));
3237 fRc = False;
3238
3239 oCurTest.closeSession();
3240
3241 return (fRc, oTxsSession);
3242
3243 def testGuestCtrlFileWrite(self, oSession, oTxsSession, oTestVm): # pylint: disable=too-many-locals
3244 """
3245 Tests writing to guest files.
3246 """
3247
3248 if oTestVm.isWindows():
3249 sScratch = "C:\\Temp\\vboxtest\\testGuestCtrlFileWrite\\";
3250 else:
3251 sScratch = "/tmp/";
3252
3253 if oTxsSession.syncMkDir('${SCRATCH}/testGuestCtrlFileWrite') is False:
3254 reporter.error('Could not create scratch directory on guest');
3255 return (False, oTxsSession);
3256
3257 atTests = [];
3258
3259 cbScratchBuf = random.randint(1, 4096);
3260 abScratchBuf = os.urandom(cbScratchBuf);
3261 atTests.extend([
3262 # Write to a non-existing file.
3263 [ tdTestFileReadWrite(sFile = sScratch + 'testGuestCtrlFileWrite.txt',
3264 sOpenMode = 'w+', sDisposition = 'ce', cbToReadWrite = cbScratchBuf, abBuf = abScratchBuf),
3265 tdTestResultFileReadWrite(fRc = True, abBuf = abScratchBuf, cbProcessed = cbScratchBuf, offFile = cbScratchBuf) ],
3266 ]);
3267
3268 aScratchBuf2 = os.urandom(cbScratchBuf);
3269 atTests.extend([
3270 # Append the same amount of data to the just created file.
3271 [ tdTestFileReadWrite(sFile = sScratch + 'testGuestCtrlFileWrite.txt',
3272 sOpenMode = 'w+', sDisposition = 'oa', cbToReadWrite = cbScratchBuf,
3273 offFile = cbScratchBuf, abBuf = aScratchBuf2),
3274 tdTestResultFileReadWrite(fRc = True, abBuf = aScratchBuf2, cbProcessed = cbScratchBuf,
3275 offFile = cbScratchBuf * 2) ],
3276 ]);
3277
3278 fRc = True;
3279 for (i, aTest) in enumerate(atTests):
3280 oCurTest = aTest[0]; # tdTestFileReadWrite, use an index, later.
3281 oCurRes = aTest[1]; # tdTestResult
3282 reporter.log('Testing #%d, sFile="%s", cbToReadWrite=%d, sOpenMode="%s", sDisposition="%s", offFile=%d ...'
3283 % (i, oCurTest.sFile, oCurTest.cbToReadWrite, oCurTest.sOpenMode,
3284 oCurTest.sDisposition, oCurTest.offFile,));
3285 oCurTest.setEnvironment(oSession, oTxsSession, oTestVm);
3286 fRc, oCurGuestSession = oCurTest.createSession('testGuestCtrlFileWrite: Test #%d' % (i,));
3287 if fRc is False:
3288 reporter.error('Test #%d failed: Could not create session' % (i,));
3289 break;
3290
3291 try:
3292 if oCurTest.offFile > 0: # The offset parameter is gone.
3293 if self.oTstDrv.fpApiVer >= 5.0:
3294 curFile = oCurGuestSession.fileOpenEx(oCurTest.sFile, oCurTest.getAccessMode(), oCurTest.getOpenAction(),
3295 oCurTest.getSharingMode(), oCurTest.fCreationMode, []);
3296 curFile.seek(oCurTest.offFile, vboxcon.FileSeekOrigin_Begin);
3297 else:
3298 curFile = oCurGuestSession.fileOpenEx(oCurTest.sFile, oCurTest.sOpenMode, oCurTest.sDisposition,
3299 oCurTest.sSharingMode, oCurTest.fCreationMode, oCurTest.offFile);
3300 curOffset = long(curFile.offset);
3301 resOffset = long(oCurTest.offFile);
3302 if curOffset != resOffset:
3303 reporter.error('Test #%d failed: Initial offset on open does not match: Got %d, expected %d' \
3304 % (i, curOffset, resOffset));
3305 fRc = False;
3306 else:
3307 if self.oTstDrv.fpApiVer >= 5.0:
3308 curFile = oCurGuestSession.fileOpenEx(oCurTest.sFile, oCurTest.getAccessMode(), oCurTest.getOpenAction(),
3309 oCurTest.getSharingMode(), oCurTest.fCreationMode, []);
3310 else:
3311 curFile = oCurGuestSession.fileOpen(oCurTest.sFile, oCurTest.sOpenMode, oCurTest.sDisposition,
3312 oCurTest.fCreationMode);
3313 if fRc and oCurTest.cbToReadWrite > 0:
3314 reporter.log("File '%s' opened" % oCurTest.sFile);
3315 ## @todo Split this up in 64K writes. Later.
3316 ## @todo Test timeouts.
3317 cBytesWritten = curFile.write(array('b', oCurTest.abBuf), 30 * 1000);
3318 if oCurRes.cbProcessed > 0 \
3319 and oCurRes.cbProcessed != cBytesWritten:
3320 reporter.error('Test #%d failed: Written buffer length does not match: Got %d, expected %d' \
3321 % (i, cBytesWritten, oCurRes.cbProcessed));
3322 fRc = False;
3323 if fRc:
3324 # Verify written content by seeking back to the initial offset and
3325 # re-read & compare the written data.
3326 try:
3327 if self.oTstDrv.fpApiVer >= 5.0:
3328 curFile.seek(-(oCurTest.cbToReadWrite), vboxcon.FileSeekOrigin_Current);
3329 else:
3330 curFile.seek(-(oCurTest.cbToReadWrite), vboxcon.FileSeekType_Current);
3331 except:
3332 reporter.logXcpt('Seeking back to initial write position failed:');
3333 fRc = False;
3334 if fRc and long(curFile.offset) != oCurTest.offFile:
3335 reporter.error('Test #%d failed: Initial write position does not match current position, ' \
3336 'got %d, expected %d' % (i, long(curFile.offset), oCurTest.offFile));
3337 fRc = False;
3338 if fRc:
3339 aBufRead = curFile.read(oCurTest.cbToReadWrite, 30 * 1000);
3340 if len(aBufRead) != oCurTest.cbToReadWrite:
3341 reporter.error('Test #%d failed: Got buffer length %d, expected %d' \
3342 % (i, len(aBufRead), oCurTest.cbToReadWrite));
3343 fRc = False;
3344 if fRc \
3345 and oCurRes.abBuf is not None \
3346 and bytes(oCurRes.abBuf) != bytes(aBufRead):
3347 reporter.error('Test #%d failed: Read back buffer (%d bytes) does not match ' \
3348 'written content (%d bytes)' % (i, len(aBufRead), len(aBufRead)));
3349
3350 curFile.close();
3351
3352 # Download written file from guest.
3353 aGstFiles = [];
3354 aGstFiles.append(oCurTest.sFile.replace('\\', '/'));
3355 self.oTstDrv.txsDownloadFiles(oSession, oTxsSession, aGstFiles, fIgnoreErrors = True);
3356
3357 # Create files with buffer contents and upload those for later (manual) inspection.
3358 oCurTest.uploadLogData(self.oTstDrv, oCurRes.abBuf, ('testGuestCtrlWriteTest%d-BufExcepted' % i),
3359 ('Test #%d: Expected buffer' % i));
3360 oCurTest.uploadLogData(self.oTstDrv, aBufRead, ('testGuestCtrlWriteTest%d-BufGot' % i),
3361 ('Test #%d: Got buffer' % i));
3362 fRc = False;
3363 # Test final offset.
3364 curOffset = long(curFile.offset);
3365 resOffset = long(oCurRes.offFile);
3366 if curOffset != resOffset:
3367 reporter.error('Test #%d failed: Final offset does not match: Got %d, expected %d' \
3368 % (i, curOffset, resOffset));
3369 fRc = False;
3370 if curFile.status == vboxcon.FileStatus_Open:
3371 curFile.close();
3372 reporter.log("File '%s' closed" % oCurTest.sFile);
3373 except:
3374 reporter.logXcpt('Opening "%s" failed:' % (oCurTest.sFile,));
3375 fRc = False;
3376
3377 oCurTest.closeSession();
3378
3379 if fRc != oCurRes.fRc:
3380 reporter.error('Test #%d failed: Got %s, expected %s' % (i, fRc, oCurRes.fRc));
3381 fRc = False;
3382 break;
3383
3384 return (fRc, oTxsSession);
3385
3386 def testGuestCtrlCopyTo(self, oSession, oTxsSession, oTestVm):
3387 """
3388 Tests copying files from host to the guest.
3389 """
3390
3391 if oTestVm.isWindows():
3392 sScratchGst = "C:\\Temp\\vboxtest\\testGuestCtrlCopyTo\\";
3393 sScratchGstNotExist = "C:\\does-not-exist\\";
3394 sScratchGstInvalid = "?*|invalid-name?*|";
3395 else:
3396 sScratchGst = "/tmp/"; ## @todo Use "${SCRATCH}/testGuestCtrlCopyTo" as soon as TXS CHMOD is implemented.
3397 sScratchGstNotExist = "/tmp/does-not-exist/";
3398 sScratchGstInvalid = "/";
3399
3400 if oTxsSession.syncMkDir('${SCRATCH}/testGuestCtrlCopyTo') is False:
3401 reporter.error('Could not create scratch directory on guest');
3402 return (False, oTxsSession);
3403
3404 ## @todo r=klaus It's not good to use files with unpredictable size
3405 # for testing. Causes all sorts of weird failures as things grow,
3406 # exceeding the free space of the test VMs. Especially as this used
3407 # the very big (and quickly growing) validation kit ISO originally.
3408 sTestFileBig = self.oTstDrv.getFullResourceName('5.3/guestctrl/50mb_rnd.dat');
3409 if not os.path.isfile(sTestFileBig):
3410 sTestFileBig = self.oTstDrv.getGuestAdditionsIso();
3411 if sTestFileBig == '' or not os.path.isfile(sTestFileBig):
3412 sTestFileBig = self.oTstDrv.sVBoxValidationKitIso;
3413 if os.path.isfile(sTestFileBig):
3414 reporter.log('Test file for big copy found at: %s' % (sTestFileBig,));
3415 else:
3416 reporter.log('Warning: Test file for big copy not found -- some tests might fail');
3417
3418 atTests = [];
3419 atTests.extend([
3420 # Destination missing.
3421 [ tdTestCopyTo(sSrc = ''), tdTestResultFailure() ],
3422 [ tdTestCopyTo(sSrc = '/placeholder', fFlags = [ 80 ] ), tdTestResultFailure() ],
3423 # Source missing.
3424 [ tdTestCopyTo(sDst = ''), tdTestResultFailure() ],
3425 [ tdTestCopyTo(sDst = '/placeholder', fFlags = [ 80 ] ), tdTestResultFailure() ],
3426 # Testing DirectoryCopyFlag flags.
3427 [ tdTestCopyTo(sSrc = sTestFileBig, sDst = sScratchGstInvalid, fFlags = [ 80 ] ), tdTestResultFailure() ],
3428 # Testing FileCopyFlag flags.
3429 [ tdTestCopyTo(sSrc = sTestFileBig, sDst = sScratchGstInvalid, fFlags = [ 80 ] ), tdTestResultFailure() ],
3430 # Nothing to copy (source and/or destination is empty).
3431 [ tdTestCopyTo(sSrc = 'z:\\'), tdTestResultFailure() ],
3432 [ tdTestCopyTo(sSrc = '\\\\uncrulez\\foo'), tdTestResultFailure() ],
3433 [ tdTestCopyTo(sSrc = 'non-exist', sDst = os.path.join(sScratchGst, 'non-exist.dll')), tdTestResultFailure() ]
3434 ]);
3435
3436 #
3437 # Single file handling.
3438 #
3439 if self.oTstDrv.fpApiVer > 5.2:
3440 atTests.extend([
3441 [ tdTestCopyTo(sSrc = sTestFileBig, sDst = sScratchGstInvalid), tdTestResultFailure() ],
3442 [ tdTestCopyTo(sSrc = sTestFileBig, sDst = sScratchGstNotExist), tdTestResultFailure() ],
3443 [ tdTestCopyTo(sSrc = sTestFileBig, sDst = sScratchGstNotExist), tdTestResultFailure() ],
3444 [ tdTestCopyTo(sSrc = sTestFileBig, sDst = os.path.join(sScratchGstNotExist, 'renamedfile.dll')),
3445 tdTestResultFailure() ],
3446 [ tdTestCopyTo(sSrc = sTestFileBig, sDst = os.path.join(sScratchGst, 'HostGABig.dat')),
3447 tdTestResultSuccess() ],
3448 [ tdTestCopyTo(sSrc = sTestFileBig, sDst = os.path.join(sScratchGst, 'HostGABig.dat')),
3449 tdTestResultSuccess() ],
3450 # Note: Copying files into directories via Main is supported only in versions > 5.2.
3451 # Destination is a directory.
3452 [ tdTestCopyTo(sSrc = sTestFileBig, sDst = sScratchGst),
3453 tdTestResultSuccess() ],
3454 # Copy over file again into same directory (overwrite).
3455 [ tdTestCopyTo(sSrc = sTestFileBig, sDst = sScratchGst),
3456 tdTestResultSuccess() ]
3457 ]);
3458
3459 if oTestVm.isWindows():
3460 atTests.extend([
3461 # Copy the same file over to the guest, but this time store the file into the former
3462 # file's ADS (Alternate Data Stream). Only works on Windows, of course.
3463 [ tdTestCopyTo(sSrc = sTestFileBig, sDst = os.path.join(sScratchGst, 'HostGABig.dat:ADS-Test')),
3464 tdTestResultSuccess() ]
3465 ]);
3466
3467 #
3468 # Directory handling.
3469 #
3470 ## @todo r=michaln disabled completely, can fill up the guest disk or fail without giving a reason
3471 if self.oTstDrv.fpApiVer > 6.0: # Copying directories via Main is supported only in versions > 5.2.
3472 if self.oTstDrv.sHost == "win":
3473 sSystemRoot = os.getenv('SystemRoot', 'C:\\Windows')
3474 atTests.extend([
3475 # Copying directories with contain files we don't have read access to.
3476 ## @todo r=klaus disabled, because this can fill up the guest disk, making other tests fail,
3477 ## additionally it's not really clear if this fails reliably on all Windows versions, even
3478 ## the old ones like XP with a "proper" administrator.
3479 #[ tdTestCopyTo(sSrc = os.path.join(sSystemRoot, 'security'),
3480 # sDst = sScratchGst, fFlags = [ vboxcon.DirectoryCopyFlag_CopyIntoExisting ]),
3481 #
3482 # Copying directories with regular files.
3483 [ tdTestCopyTo(sSrc = os.path.join(sSystemRoot, 'Help'),
3484 sDst = sScratchGst, fFlags = [ vboxcon.DirectoryCopyFlag_CopyIntoExisting ]),
3485 tdTestResultSuccess() ]
3486 ]);
3487
3488 fRc = True;
3489 for (i, aTest) in enumerate(atTests):
3490 oCurTest = aTest[0]; # tdTestExec, use an index, later.
3491 oCurRes = aTest[1]; # tdTestResult
3492 reporter.log('Testing #%d, sSrc=%s, sDst=%s, fFlags=%s ...' % \
3493 (i, oCurTest.sSrc, oCurTest.sDst, oCurTest.fFlags));
3494 oCurTest.setEnvironment(oSession, oTxsSession, oTestVm);
3495 fRc, oCurGuestSession = oCurTest.createSession('testGuestCtrlCopyTo: Test #%d' % (i,));
3496 if fRc is False:
3497 reporter.error('Test #%d failed: Could not create session' % (i,));
3498 break;
3499
3500 fRc2 = False;
3501 if os.path.isdir(oCurTest.sSrc):
3502 try:
3503 oCurProgress = oCurGuestSession.directoryCopyToGuest(oCurTest.sSrc, oCurTest.sDst, oCurTest.fFlags);
3504 if oCurProgress is not None:
3505 oProgress = vboxwrappers.ProgressWrapper(oCurProgress, self.oTstDrv.oVBoxMgr, self.oTstDrv, \
3506 "gctrlDirCopyTo");
3507 try:
3508 oProgress.wait();
3509 if oProgress.isSuccess():
3510 fRc2 = True;
3511 else:
3512 oProgress.logResult(fIgnoreErrors = True);
3513 except:
3514 reporter.logXcpt('Waiting exception for sSrc="%s", sDst="%s":' % (oCurTest.sSrc, oCurTest.sDst));
3515 else:
3516 reporter.error('No progress object returned');
3517 except:
3518 reporter.logXcpt('directoryCopyToGuest exception for sSrc="%s", sDst="%s":' % (oCurTest.sSrc, oCurTest.sDst));
3519 else:
3520 fRc2 = self.gctrlCopyFileTo(oCurGuestSession, oCurTest.sSrc, oCurTest.sDst, oCurTest.fFlags);
3521
3522 oCurTest.closeSession();
3523
3524 if fRc2 is oCurRes.fRc:
3525 ## @todo Verify the copied results (size, checksum?).
3526 pass;
3527 else:
3528 reporter.error('Test #%d failed: Got %s, expected %s' % (i, fRc2, oCurRes.fRc));
3529 fRc = False;
3530 break;
3531
3532 return (fRc, oTxsSession);
3533
3534 def testGuestCtrlCopyFrom(self, oSession, oTxsSession, oTestVm): # pylint: disable=too-many-locals
3535 """
3536 Tests copying files from guest to the host.
3537 """
3538
3539 if oTestVm.isWindows():
3540 sPathSep = "\\";
3541 sSrcDirExisting = "C:\\Windows\\Web";
3542 sSrcFileExisting = "C:\\Windows\\system32\\ole32.dll";
3543 else:
3544 sPathSep = "/";
3545 sSrcDirExisting = "/bin";
3546 sSrcFileExisting = "/etc/issue";
3547
3548 sScratchHst = os.path.join(self.oTstDrv.sScratchPath, "testGctrlCopyFrom");
3549
3550 if self.oTstDrv.sHost == "win":
3551 sScratchHstNotExist = sScratchHst + "\\does-not-exist\\";
3552 sScratchHstNotExistChain = sScratchHst + "\\does\\not\\exist\\";
3553 sScratchHstInvalid = "?*|invalid-name?*|";
3554 else:
3555 sScratchHstNotExist = sScratchHst + "/does-not-exist/";
3556 sScratchHstNotExistChain = sScratchHst + "/does/not/exist/";
3557 sScratchHstInvalid = "/";
3558
3559 try:
3560 os.makedirs(sScratchHst);
3561 except OSError as e:
3562 if e.errno != errno.EEXIST:
3563 reporter.error('Failed: Unable to create scratch directory \"%s\"' % (sScratchHst,));
3564 return (False, oTxsSession);
3565 reporter.log('Scratch path is: %s' % (sScratchHst,));
3566
3567 atTests = [];
3568 atTests.extend([
3569 # Destination missing.
3570 [ tdTestCopyFrom(sSrc = ''), tdTestResultFailure() ],
3571 [ tdTestCopyFrom(sSrc = 'Something', fFlags = [ 80 ] ), tdTestResultFailure() ],
3572 # Source missing.
3573 [ tdTestCopyFrom(sDst = ''), tdTestResultFailure() ],
3574 [ tdTestCopyFrom(sDst = 'Something', fFlags = [ 80 ] ), tdTestResultFailure() ],
3575 # Testing DirectoryCopyFlag flags.
3576 [ tdTestCopyFrom(sSrc = sSrcDirExisting, sDst = sScratchHstInvalid, fFlags = [ 80 ] ), tdTestResultFailure() ],
3577 # Testing FileCopyFlag flags.
3578 [ tdTestCopyFrom(sSrc = sSrcFileExisting, sDst = sScratchHstInvalid, fFlags = [ 80 ] ), tdTestResultFailure() ],
3579 # Nothing to copy (sDst is empty / unreachable).
3580 [ tdTestCopyFrom(sSrc = 'z:\\'), tdTestResultFailure() ],
3581 [ tdTestCopyFrom(sSrc = '\\\\uncrulez\\foo'), tdTestResultFailure() ],
3582 [ tdTestCopyFrom(sSrc = 'non-exist', sDst = os.path.join(sScratchHst, 'non-exist')), tdTestResultFailure() ]
3583 ]);
3584
3585 #
3586 # Single file handling.
3587 #
3588 if self.oTstDrv.fpApiVer > 5.2:
3589 reporter.log(("Single file handling"));
3590 atTests.extend([
3591 # Copying single files.
3592 [ tdTestCopyFrom(sSrc = sSrcFileExisting, sDst = sScratchHstInvalid), tdTestResultFailure() ],
3593 [ tdTestCopyFrom(sSrc = sSrcFileExisting, sDst = os.path.join(sScratchHstInvalid, 'tstCopyFrom-renamedfile')),
3594 tdTestResultFailure() ],
3595 # Copy over file using a different destination name.
3596 [ tdTestCopyFrom(sSrc = sSrcFileExisting, sDst = os.path.join(sScratchHst, 'tstCopyFrom-renamedfile')),
3597 tdTestResultSuccess() ],
3598 # Copy over same file (and overwrite existing one).
3599 [ tdTestCopyFrom(sSrc = sSrcFileExisting, sDst = os.path.join(sScratchHst, 'tstCopyFrom-renamedfile')),
3600 tdTestResultSuccess() ],
3601 # Note: Copying files into directories via Main is supported only in versions > 5.2.
3602 # Destination is a directory with a trailing slash (should work).
3603 # See "cp" syntax.
3604 [ tdTestCopyFrom(sSrc = sSrcFileExisting, sDst = sScratchHst + "/"),
3605 tdTestResultSuccess() ],
3606 # Destination is a directory (without a trailing slash, should also work).
3607 # See "cp" syntax.
3608 [ tdTestCopyFrom(sSrc = sSrcFileExisting, sDst = sScratchHst),
3609 tdTestResultSuccess() ],
3610 # Destination is a non-existing directory.
3611 [ tdTestCopyFrom(sSrc = sSrcFileExisting, sDst = sScratchHstNotExist), tdTestResultFailure() ]
3612 ]);
3613
3614 #
3615 # Directory handling.
3616 #
3617 if self.oTstDrv.fpApiVer > 5.2: # Copying directories via Main is supported only in versions > 5.2.
3618 reporter.log(("Directory handling"));
3619 atTests.extend([
3620 # Copying entire directories (destination is "<sScratchHst>\Web").
3621 [ tdTestCopyFrom(sSrc = sSrcDirExisting, sDst = sScratchHst),
3622 tdTestResultSuccess() ],
3623 # Repeat -- this time it should fail, as the destination directory already exists (and
3624 # DirectoryCopyFlag_CopyIntoExisting is not specified).
3625 [ tdTestCopyFrom(sSrc = sSrcDirExisting, sDst = sScratchHst), tdTestResultFailure() ],
3626 # Next try with the DirectoryCopyFlag_CopyIntoExisting flag being set.
3627 [ tdTestCopyFrom(sSrc = sSrcDirExisting, sDst = sScratchHst,
3628 fFlags = [ vboxcon.DirectoryCopyFlag_CopyIntoExisting ] ),
3629 tdTestResultSuccess() ],
3630 # Ditto, with trailing slash.
3631 [ tdTestCopyFrom(sSrc = sSrcDirExisting,
3632 sDst = sScratchHst + "/", fFlags = [ vboxcon.DirectoryCopyFlag_CopyIntoExisting ]),
3633 tdTestResultSuccess() ],
3634 # Copying contents of directories into a non-existing directory chain on the host which fail.
3635 [ tdTestCopyFrom(sSrc = sSrcDirExisting + sPathSep, sDst = sScratchHstNotExistChain,
3636 fFlags = [ vboxcon.DirectoryCopyFlag_CopyIntoExisting ]), tdTestResultFailure() ],
3637 # Copying contents of directories into a non-existing directory on the host, which should succeed.
3638 [ tdTestCopyFrom(sSrc = sSrcDirExisting + sPathSep, sDst = sScratchHstNotExist,
3639 fFlags = [ vboxcon.DirectoryCopyFlag_CopyIntoExisting ] ),
3640 tdTestResultSuccess() ]
3641 ]);
3642
3643 fRc = True;
3644 for (i, aTest) in enumerate(atTests):
3645 oCurTest = aTest[0]; # tdTestExec, use an index, later.
3646 oCurRes = aTest[1]; # tdTestResult
3647 reporter.log('Testing #%d, sSrc="%s", sDst="%s", fFlags="%s" ...'
3648 % (i, oCurTest.sSrc, oCurTest.sDst, oCurTest.fFlags,));
3649
3650 oCurTest.setEnvironment(oSession, oTxsSession, oTestVm);
3651 fRc2, oCurGuestSession = oCurTest.createSession('testGuestCtrlCopyFrom: Test #%d' % (i,));
3652 if fRc2 is not True:
3653 fRc = reporter.error('Test #%d failed: Could not create session' % (i,));
3654 break;
3655
3656 try:
3657 if self.oTstDrv.fpApiVer >= 5.0:
3658 oFsInfo = oCurGuestSession.fsObjQueryInfo(oCurTest.sSrc, True); # fFollowSymlinks
3659 else:
3660 oFsInfo = oCurGuestSession.fileQueryInfo(oCurTest.sSrc);
3661 eFsObjType = oFsInfo.type;
3662 except:
3663 if oCurRes.fRc:
3664 reporter.errorXcpt('Query information exception for sSrc="%s", sDst="%s":' % (oCurTest.sSrc, oCurTest.sDst,));
3665 else:
3666 reporter.logXcpt( 'Query information exception for sSrc="%s", sDst="%s":' % (oCurTest.sSrc, oCurTest.sDst,));
3667 fRc2 = False;
3668 else:
3669 if eFsObjType == vboxcon.FsObjType_Directory:
3670 fRc2 = self.gctrlCopyDirFrom(oCurGuestSession, oCurTest.sSrc, oCurTest.sDst, oCurTest.fFlags, oCurRes.fRc);
3671 elif eFsObjType == vboxcon.FsObjType_File:
3672 fRc2 = self.gctrlCopyFileFrom(oCurGuestSession, oCurTest.sSrc, oCurTest.sDst, oCurTest.fFlags, oCurRes.fRc);
3673 else:
3674 reporter.log2('Element "%s" not handled (yet), skipping' % oFsInfo.name);
3675
3676 oCurTest.closeSession();
3677 if fRc2 == oCurRes.fRc:
3678 pass; ## @todo Verify the copied results (size, checksum?).
3679 else:
3680 fRc = reporter.error('Test #%d failed: Got %s, expected %s' % (i, fRc2, oCurRes.fRc));
3681
3682 return (fRc, oTxsSession);
3683
3684 def testGuestCtrlUpdateAdditions(self, oSession, oTxsSession, oTestVm): # pylint: disable=too-many-locals
3685 """
3686 Tests updating the Guest Additions inside the guest.
3687
3688 """
3689
3690 # Skip test for updating Guest Additions if we run on a too old (Windows) guest.
3691 ##
3692 ## @todo make it work everywhere!
3693 ##
3694 if oTestVm.sKind in ('WindowsNT4', 'Windows2000', 'WindowsXP', 'Windows2003'):
3695 reporter.log("Skipping updating GAs on old windows vm (sKind=%s)" % (oTestVm.sKind,));
3696 return (None, oTxsSession);
3697 if oTestVm.isOS2():
3698 reporter.log("Skipping updating GAs on OS/2 guest");
3699 return (None, oTxsSession);
3700
3701 # Some stupid trickery to guess the location of the iso.
3702 sVBoxValidationKitISO = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../VBoxValidationKit.iso'));
3703 if not os.path.isfile(sVBoxValidationKitISO):
3704 sVBoxValidationKitISO = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../VBoxTestSuite.iso'));
3705 if not os.path.isfile(sVBoxValidationKitISO):
3706 sCur = os.getcwd();
3707 for i in xrange(0, 10):
3708 sVBoxValidationKitISO = os.path.join(sCur, 'validationkit/VBoxValidationKit.iso');
3709 if os.path.isfile(sVBoxValidationKitISO):
3710 break;
3711 sVBoxValidationKitISO = os.path.join(sCur, 'testsuite/VBoxTestSuite.iso');
3712 if os.path.isfile(sVBoxValidationKitISO):
3713 break;
3714 sCur = os.path.abspath(os.path.join(sCur, '..'));
3715 if i is None: pass; # shut up pychecker/pylint.
3716 if os.path.isfile(sVBoxValidationKitISO):
3717 reporter.log('Validation Kit .ISO found at: %s' % (sVBoxValidationKitISO,));
3718 else:
3719 reporter.log('Warning: Validation Kit .ISO not found -- some tests might fail');
3720
3721 sScratch = os.path.join(self.oTstDrv.sScratchPath, "testGctrlUpdateAdditions");
3722 try:
3723 os.makedirs(sScratch);
3724 except OSError as e:
3725 if e.errno != errno.EEXIST:
3726 reporter.error('Failed: Unable to create scratch directory \"%s\"' % (sScratch,));
3727 return (False, oTxsSession);
3728 reporter.log('Scratch path is: %s' % (sScratch,));
3729
3730 atTests = [];
3731 if oTestVm.isWindows():
3732 atTests.extend([
3733 # Source is missing.
3734 [ tdTestUpdateAdditions(sSrc = ''), tdTestResultFailure() ],
3735
3736 # Wrong fFlags.
3737 [ tdTestUpdateAdditions(sSrc = self.oTstDrv.getGuestAdditionsIso(),
3738 fFlags = [ 1234 ]), tdTestResultFailure() ],
3739
3740 # Non-existing .ISO.
3741 [ tdTestUpdateAdditions(sSrc = "non-existing.iso"), tdTestResultFailure() ],
3742
3743 # Wrong .ISO.
3744 [ tdTestUpdateAdditions(sSrc = sVBoxValidationKitISO), tdTestResultFailure() ],
3745
3746 # The real thing.
3747 [ tdTestUpdateAdditions(sSrc = self.oTstDrv.getGuestAdditionsIso()),
3748 tdTestResultSuccess() ],
3749 # Test the (optional) installer arguments. This will extract the
3750 # installer into our guest's scratch directory.
3751 [ tdTestUpdateAdditions(sSrc = self.oTstDrv.getGuestAdditionsIso(),
3752 asArgs = [ '/extract', '/D=' + sScratch ]),
3753 tdTestResultSuccess() ]
3754 # Some debg ISO. Only enable locally.
3755 #[ tdTestUpdateAdditions(
3756 # sSrc = "V:\\Downloads\\VBoxGuestAdditions-r80354.iso"),
3757 # tdTestResultSuccess() ]
3758 ]);
3759 else:
3760 reporter.log('No OS-specific tests for non-Windows yet!');
3761
3762 fRc = True;
3763 for (i, aTest) in enumerate(atTests):
3764 oCurTest = aTest[0]; # tdTestExec, use an index, later.
3765 oCurRes = aTest[1]; # tdTestResult
3766 reporter.log('Testing #%d, sSrc="%s", fFlags="%s" ...' % \
3767 (i, oCurTest.sSrc, oCurTest.fFlags));
3768 oCurTest.setEnvironment(oSession, oTxsSession, oTestVm);
3769 fRc, _ = oCurTest.createSession('Test #%d' % (i,));
3770 if fRc is False:
3771 reporter.error('Test #%d failed: Could not create session' % (i,));
3772 break;
3773 try:
3774 oCurProgress = oCurTest.oTest.oGuest.updateGuestAdditions(oCurTest.sSrc, oCurTest.asArgs, oCurTest.fFlags);
3775 if oCurProgress is not None:
3776 oProgress = vboxwrappers.ProgressWrapper(oCurProgress, self.oTstDrv.oVBoxMgr, self.oTstDrv, "gctrlUpGA");
3777 try:
3778 oProgress.wait();
3779 if not oProgress.isSuccess():
3780 oProgress.logResult(fIgnoreErrors = True);
3781 fRc = False;
3782 except:
3783 reporter.logXcpt('Waiting exception for updating Guest Additions:');
3784 fRc = False;
3785 else:
3786 reporter.error('No progress object returned');
3787 fRc = False;
3788 except:
3789 # Just log, don't assume an error here (will be done in the main loop then).
3790 reporter.logXcpt('Updating Guest Additions exception for sSrc="%s", fFlags="%s":' \
3791 % (oCurTest.sSrc, oCurTest.fFlags));
3792 fRc = False;
3793 oCurTest.closeSession();
3794 if fRc is oCurRes.fRc:
3795 if fRc:
3796 ## @todo Verify if Guest Additions were really updated (build, revision, ...).
3797 pass;
3798 else:
3799 reporter.error('Test #%d failed: Got %s, expected %s' % (i, fRc, oCurRes.fRc));
3800 fRc = False;
3801 break;
3802
3803 return (fRc, oTxsSession);
3804
3805
3806
3807class tdAddGuestCtrl(vbox.TestDriver): # pylint: disable=too-many-instance-attributes,too-many-public-methods
3808 """
3809 Guest control using VBoxService on the guest.
3810 """
3811
3812 def __init__(self):
3813 vbox.TestDriver.__init__(self);
3814 self.oTestVmSet = self.oTestVmManager.getSmokeVmSet('nat');
3815 self.asRsrcs = None;
3816 self.fQuick = False; # Don't skip lengthly tests by default.
3817 self.addSubTestDriver(SubTstDrvAddGuestCtrl(self));
3818
3819 #
3820 # Overridden methods.
3821 #
3822 def showUsage(self):
3823 """
3824 Shows the testdriver usage.
3825 """
3826 rc = vbox.TestDriver.showUsage(self);
3827 reporter.log('');
3828 reporter.log('tdAddGuestCtrl Options:');
3829 reporter.log(' --quick');
3830 reporter.log(' Same as --virt-modes hwvirt --cpu-counts 1.');
3831 return rc;
3832
3833 def parseOption(self, asArgs, iArg): # pylint: disable=too-many-branches,too-many-statements
3834 """
3835 Parses the testdriver arguments from the command line.
3836 """
3837 if asArgs[iArg] == '--quick':
3838 self.parseOption(['--virt-modes', 'hwvirt'], 0);
3839 self.parseOption(['--cpu-counts', '1'], 0);
3840 self.fQuick = True;
3841 else:
3842 return vbox.TestDriver.parseOption(self, asArgs, iArg);
3843 return iArg + 1;
3844
3845 def actionConfig(self):
3846 if not self.importVBoxApi(): # So we can use the constant below.
3847 return False;
3848
3849 eNic0AttachType = vboxcon.NetworkAttachmentType_NAT;
3850 sGaIso = self.getGuestAdditionsIso();
3851 return self.oTestVmSet.actionConfig(self, eNic0AttachType = eNic0AttachType, sDvdImage = sGaIso);
3852
3853 def actionExecute(self):
3854 return self.oTestVmSet.actionExecute(self, self.testOneCfg);
3855
3856 #
3857 # Test execution helpers.
3858 #
3859 def testOneCfg(self, oVM, oTestVm): # pylint: disable=too-many-statements
3860 """
3861 Runs the specified VM thru the tests.
3862
3863 Returns a success indicator on the general test execution. This is not
3864 the actual test result.
3865 """
3866
3867 self.logVmInfo(oVM);
3868
3869 fRc = True;
3870 oSession, oTxsSession = self.startVmAndConnectToTxsViaTcp(oTestVm.sVmName, fCdWait = False);
3871 reporter.log("TxsSession: %s" % (oTxsSession,));
3872 if oSession is not None:
3873 self.addTask(oTxsSession);
3874
3875 fManual = False; # Manual override for local testing. (Committed version shall be False.)
3876 if not fManual:
3877 fRc, oTxsSession = self.aoSubTstDrvs[0].testIt(oTestVm, oSession, oTxsSession);
3878 else:
3879 fRc, oTxsSession = self.testGuestCtrlManual(oSession, oTxsSession, oTestVm);
3880
3881 # Cleanup.
3882 self.removeTask(oTxsSession);
3883 if not fManual:
3884 self.terminateVmBySession(oSession);
3885 else:
3886 fRc = False;
3887 return fRc;
3888
3889 def gctrlReportError(self, progress):
3890 """
3891 Helper function to report an error of a
3892 given progress object.
3893 """
3894 if progress is None:
3895 reporter.log('No progress object to print error for');
3896 else:
3897 errInfo = progress.errorInfo;
3898 if errInfo:
3899 reporter.log('%s' % (errInfo.text,));
3900 return False;
3901
3902 def gctrlGetRemainingTime(self, msTimeout, msStart):
3903 """
3904 Helper function to return the remaining time (in ms)
3905 based from a timeout value and the start time (both in ms).
3906 """
3907 if msTimeout == 0:
3908 return 0xFFFFFFFE; # Wait forever.
3909 msElapsed = base.timestampMilli() - msStart;
3910 if msElapsed > msTimeout:
3911 return 0; # No time left.
3912 return msTimeout - msElapsed;
3913
3914 def testGuestCtrlManual(self, oSession, oTxsSession, oTestVm): # pylint: disable=too-many-locals,too-many-statements,unused-argument,unused-variable
3915 """
3916 For manually testing certain bits.
3917 """
3918
3919 reporter.log('Manual testing ...');
3920 fRc = True;
3921
3922 sUser = 'Administrator';
3923 sPassword = 'password';
3924
3925 oGuest = oSession.o.console.guest;
3926 oGuestSession = oGuest.createSession(sUser,
3927 sPassword,
3928 "", "Manual Test");
3929
3930 aWaitFor = [ vboxcon.GuestSessionWaitForFlag_Start ];
3931 _ = oGuestSession.waitForArray(aWaitFor, 30 * 1000);
3932
3933 sCmd = SubTstDrvAddGuestCtrl.getGuestSystemShell(oTestVm);
3934 asArgs = [ sCmd, '/C', 'dir', '/S', 'c:\\windows' ];
3935 aEnv = [];
3936 fFlags = [];
3937
3938 for _ in xrange(100):
3939 oProc = oGuestSession.processCreate(sCmd, asArgs if self.fpApiVer >= 5.0 else asArgs[1:],
3940 aEnv, fFlags, 30 * 1000);
3941
3942 aWaitFor = [ vboxcon.ProcessWaitForFlag_Terminate ];
3943 _ = oProc.waitForArray(aWaitFor, 30 * 1000);
3944
3945 oGuestSession.close();
3946 oGuestSession = None;
3947
3948 time.sleep(5);
3949
3950 oSession.o.console.PowerDown();
3951
3952 return (fRc, oTxsSession);
3953
3954if __name__ == '__main__':
3955 sys.exit(tdAddGuestCtrl().main(sys.argv));
Note: See TracBrowser for help on using the repository browser.

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