VirtualBox

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

Last change on this file since 79111 was 79111, checked in by vboxsync, 6 years ago

tdAddGuestCtrl.py: Cleanups. bugref:9151

  • Property svn:eol-style set to LF
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 182.2 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: 79111 $"
31
32# Standard Python imports.
33from array import array
34import errno
35import os
36import random
37import string
38import struct
39import sys
40import threading
41import time
42
43# Only the main script needs to modify the path.
44try: __file__
45except: __file__ = sys.argv[0];
46g_ksValidationKitDir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))));
47sys.path.append(g_ksValidationKitDir);
48
49# Validation Kit imports.
50from testdriver import reporter;
51from testdriver import base;
52from testdriver import vbox;
53from testdriver import vboxcon;
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 = "", aArgs = 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.aArgs = aArgs if aArgs 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 = "", aArgs = 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.aArgs = aArgs;
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 tdTestResultDirRead(tdTestResult):
852 """
853 Test result for reading guest directories.
854 """
855 def __init__(self, fRc = False,
856 numFiles = 0, numDirs = 0):
857 tdTestResult.__init__(self, fRc = fRc);
858 self.numFiles = numFiles;
859 self.numDirs = numDirs;
860
861class tdTestResultExec(tdTestResult):
862 """
863 Holds a guest process execution test result,
864 including the exit code, status + fFlags.
865 """
866 def __init__(self, fRc = False, \
867 uExitStatus = 500, iExitCode = 0, \
868 sBuf = None, cbBuf = 0, \
869 cbStdOut = 0, cbStdErr = 0):
870 tdTestResult.__init__(self);
871 ## The overall test result.
872 self.fRc = fRc;
873 ## Process exit stuff.
874 self.uExitStatus = uExitStatus;
875 self.iExitCode = iExitCode;
876 ## Desired buffer length returned back from stdout/stderr.
877 self.cbBuf = cbBuf;
878 ## Desired buffer result from stdout/stderr. Use with caution!
879 self.sBuf = sBuf;
880 self.cbStdOut = cbStdOut;
881 self.cbStdErr = cbStdErr;
882
883class tdTestResultFileStat(tdTestResult):
884 """
885 Test result for stat'ing guest files.
886 """
887 def __init__(self, fRc = False,
888 cbSize = 0, eFileType = 0):
889 tdTestResult.__init__(self, fRc = fRc);
890 self.cbSize = cbSize;
891 self.eFileType = eFileType;
892 ## @todo Add more information.
893
894class tdTestResultFileReadWrite(tdTestResult):
895 """
896 Test result for reading + writing guest directories.
897 """
898 def __init__(self, fRc = False,
899 cbProcessed = 0, offFile = 0, abBuf = None):
900 tdTestResult.__init__(self, fRc = fRc);
901 self.cbProcessed = cbProcessed;
902 self.offFile = offFile;
903 self.abBuf = abBuf;
904
905class tdTestResultSession(tdTestResult):
906 """
907 Test result for guest session counts.
908 """
909 def __init__(self, fRc = False, cNumSessions = 0):
910 tdTestResult.__init__(self, fRc = fRc);
911 self.cNumSessions = cNumSessions;
912
913class SubTstDrvAddGuestCtrl(base.SubTestDriverBase):
914 """
915 Sub-test driver for executing guest control (VBoxService, IGuest) tests.
916 """
917
918 def __init__(self, oTstDrv):
919 base.SubTestDriverBase.__init__(self, oTstDrv, 'add-guest-ctrl', 'Guest Control');
920
921 ## @todo base.TestBase.
922 self.asTestsDef = \
923 [
924 'session_basic', 'session_env', 'session_file_ref', 'session_dir_ref', 'session_proc_ref', 'session_reboot',
925 'exec_basic', 'exec_errorlevel', 'exec_timeout',
926 'dir_create', 'dir_create_temp', 'dir_read',
927 'file_remove', 'file_stat', 'file_read', 'file_write',
928 'copy_to', 'copy_from',
929 'update_additions'
930 ];
931 self.asTests = self.asTestsDef;
932 self.asRsrcs = ['5.3/guestctrl/50mb_rnd.dat', ];
933
934 def parseOption(self, asArgs, iArg): # pylint: disable=too-many-branches,too-many-statements
935 if asArgs[iArg] == '--add-guest-ctrl-tests':
936 iArg += 1;
937 iNext = self.oTstDrv.requireMoreArgs(1, asArgs, iArg);
938 if asArgs[iArg] == 'all': # Nice for debugging scripts.
939 self.asTests = self.asTestsDef;
940 else:
941 self.asTests = asArgs[iArg].split(':');
942 for s in self.asTests:
943 if s not in self.asTestsDef:
944 raise base.InvalidOption('The "--add-guest-ctrl-tests" value "%s" is not valid; valid values are: %s'
945 % (s, ' '.join(self.asTestsDef)));
946 return iNext;
947 return iArg;
948
949 def showUsage(self):
950 base.SubTestDriverBase.showUsage(self);
951 reporter.log(' --add-guest-ctrl-tests <s1[:s2[:]]>');
952 reporter.log(' Default: %s (all)' % (':'.join(self.asTestsDef)));
953 return True;
954
955 def testIt(self, oTestVm, oSession, oTxsSession):
956 """
957 Executes the test.
958
959 Returns fRc, oTxsSession. The latter may have changed.
960 """
961 reporter.log("Active tests: %s" % (self.asTests,));
962
963 fRc = True;
964
965 # Do the testing.
966 reporter.testStart('Session Basics');
967 fSkip = 'session_basic' not in self.asTests;
968 if fSkip is False:
969 fRc, oTxsSession = self.testGuestCtrlSession(oSession, oTxsSession, oTestVm);
970 reporter.testDone(fSkip);
971
972 reporter.testStart('Session Environment');
973 fSkip = 'session_env' not in self.asTests or fRc is False;
974 if fSkip is False:
975 fRc, oTxsSession = self.testGuestCtrlSessionEnvironment(oSession, oTxsSession, oTestVm);
976 reporter.testDone(fSkip);
977
978 reporter.testStart('Session File References');
979 fSkip = 'session_file_ref' not in self.asTests;
980 if fSkip is False:
981 fRc, oTxsSession = self.testGuestCtrlSessionFileRefs(oSession, oTxsSession, oTestVm);
982 reporter.testDone(fSkip);
983
984 ## @todo Implement this.
985 #reporter.testStart('Session Directory References');
986 #fSkip = 'session_dir_ref' not in self.asTests;
987 #if fSkip is False:
988 # fRc, oTxsSession = self.testGuestCtrlSessionDirRefs(oSession, oTxsSession, oTestVm);
989 #reporter.testDone(fSkip);
990
991 reporter.testStart('Session Process References');
992 fSkip = 'session_proc_ref' not in self.asTests or fRc is False;
993 if fSkip is False:
994 fRc, oTxsSession = self.testGuestCtrlSessionProcRefs(oSession, oTxsSession, oTestVm);
995 reporter.testDone(fSkip);
996
997 reporter.testStart('Session w/ Guest Reboot');
998 fSkip = 'session_reboot' not in self.asTests \
999 or self.oTstDrv.fpApiVer <= 6.0; # Not backported yet.
1000 if fSkip is False:
1001 fRc, oTxsSession = self.testGuestCtrlSessionReboot(oSession, oTxsSession, oTestVm);
1002 reporter.testDone(fSkip);
1003
1004 reporter.testStart('Execution');
1005 fSkip = 'exec_basic' not in self.asTests or fRc is False;
1006 if fSkip is False:
1007 fRc, oTxsSession = self.testGuestCtrlExec(oSession, oTxsSession, oTestVm);
1008 reporter.testDone(fSkip);
1009
1010 reporter.testStart('Execution Error Levels');
1011 fSkip = 'exec_errorlevel' not in self.asTests or fRc is False;
1012 if fSkip is False:
1013 fRc, oTxsSession = self.testGuestCtrlExecErrorLevel(oSession, oTxsSession, oTestVm);
1014 reporter.testDone(fSkip);
1015
1016 reporter.testStart('Execution Timeouts');
1017 fSkip = 'exec_timeout' not in self.asTests or fRc is False;
1018 if fSkip is False:
1019 fRc, oTxsSession = self.testGuestCtrlExecTimeout(oSession, oTxsSession, oTestVm);
1020 reporter.testDone(fSkip);
1021
1022 reporter.testStart('Creating directories');
1023 fSkip = 'dir_create' not in self.asTests or fRc is False;
1024 if fSkip is False:
1025 fRc, oTxsSession = self.testGuestCtrlDirCreate(oSession, oTxsSession, oTestVm);
1026 reporter.testDone(fSkip);
1027
1028 reporter.testStart('Creating temporary directories');
1029 fSkip = 'dir_create_temp' not in self.asTests or fRc is False;
1030 if fSkip is False:
1031 fRc, oTxsSession = self.testGuestCtrlDirCreateTemp(oSession, oTxsSession, oTestVm);
1032 reporter.testDone(fSkip);
1033
1034 reporter.testStart('Reading directories');
1035 fSkip = 'dir_read' not in self.asTests or fRc is False;
1036 if fSkip is False:
1037 fRc, oTxsSession = self.testGuestCtrlDirRead(oSession, oTxsSession, oTestVm);
1038 reporter.testDone(fSkip);
1039
1040 reporter.testStart('Copy to guest');
1041 fSkip = 'copy_to' not in self.asTests or fRc is False;
1042 if fSkip is False:
1043 fRc, oTxsSession = self.testGuestCtrlCopyTo(oSession, oTxsSession, oTestVm);
1044 reporter.testDone(fSkip);
1045
1046 reporter.testStart('Copy from guest');
1047 fSkip = 'copy_from' not in self.asTests or fRc is False;
1048 if fSkip is False:
1049 fRc, oTxsSession = self.testGuestCtrlCopyFrom(oSession, oTxsSession, oTestVm);
1050 reporter.testDone(fSkip);
1051
1052 reporter.testStart('Removing files');
1053 fSkip = 'file_remove' not in self.asTests or fRc is False;
1054 if fSkip is False:
1055 fRc, oTxsSession = self.testGuestCtrlFileRemove(oSession, oTxsSession, oTestVm);
1056 reporter.testDone(fSkip);
1057
1058 reporter.testStart('Querying file information (stat)');
1059 fSkip = 'file_stat' not in self.asTests or fRc is False;
1060 if fSkip is False:
1061 fRc, oTxsSession = self.testGuestCtrlFileStat(oSession, oTxsSession, oTestVm);
1062 reporter.testDone(fSkip);
1063
1064 reporter.testStart('File read');
1065 fSkip = 'file_read' not in self.asTests or fRc is False;
1066 if fSkip is False:
1067 fRc, oTxsSession = self.testGuestCtrlFileRead(oSession, oTxsSession, oTestVm);
1068 reporter.testDone(fSkip);
1069
1070 reporter.testStart('File write');
1071 fSkip = 'file_write' not in self.asTests or fRc is False;
1072 if fSkip is False:
1073 fRc, oTxsSession = self.testGuestCtrlFileWrite(oSession, oTxsSession, oTestVm);
1074 reporter.testDone(fSkip);
1075
1076 reporter.testStart('Updating Guest Additions');
1077 fSkip = 'update_additions' not in self.asTests or fRc is False;
1078 # Skip test for updating Guest Additions if we run on a too old (Windows) guest.
1079 fSkip = oTestVm.sKind in ('WindowsNT4', 'Windows2000', 'WindowsXP', 'Windows2003');
1080 if fSkip is False:
1081 fRc, oTxsSession = self.testGuestCtrlUpdateAdditions(oSession, oTxsSession, oTestVm);
1082 reporter.testDone(fSkip);
1083
1084 return (fRc, oTxsSession);
1085
1086 def gctrlCopyFileFrom(self, oGuestSession, sSrc, sDst, fFlags, fExpected):
1087 """
1088 Helper function to copy a single file from the guest to the host.
1089 """
1090 reporter.log2('Copying guest file "%s" to host "%s"' % (sSrc, sDst));
1091 try:
1092 if self.oTstDrv.fpApiVer >= 5.0:
1093 oCurProgress = oGuestSession.fileCopyFromGuest(sSrc, sDst, fFlags);
1094 else:
1095 oCurProgress = oGuestSession.copyFrom(sSrc, sDst, fFlags);
1096 except:
1097 reporter.maybeErrXcpt(fExpected, 'Copy from exception for sSrc="%s", sDst="%s":' % (sSrc, sDst,));
1098 return False;
1099 if oCurProgress is None:
1100 return reporter.error('No progress object returned');
1101 oProgress = vboxwrappers.ProgressWrapper(oCurProgress, self.oTstDrv.oVBoxMgr, self.oTstDrv, "gctrlFileCopyFrom");
1102 oProgress.wait();
1103 if not oProgress.isSuccess():
1104 oProgress.logResult(fIgnoreErrors = not fExpected);
1105 return False;
1106 return True;
1107
1108 def gctrlCopyDirFrom(self, oGuestSession, sSrc, sDst, fFlags, fExpected):
1109 """
1110 Helper function to copy a directory from the guest to the host.
1111 """
1112 reporter.log2('Copying guest dir "%s" to host "%s"' % (sSrc, sDst));
1113 try:
1114 oCurProgress = oGuestSession.directoryCopyFromGuest(sSrc, sDst, fFlags);
1115 except:
1116 reporter.maybeErrXcpt(fExpected, 'Copy dir from exception for sSrc="%s", sDst="%s":' % (sSrc, sDst,));
1117 return False;
1118 if oCurProgress is None:
1119 return reporter.error('No progress object returned');
1120
1121 oProgress = vboxwrappers.ProgressWrapper(oCurProgress, self.oTstDrv.oVBoxMgr, self.oTstDrv, "gctrlDirCopyFrom");
1122 oProgress.wait();
1123 if not oProgress.isSuccess():
1124 oProgress.logResult(fIgnoreErrors = not fExpected);
1125 return False;
1126 return True;
1127
1128 def gctrlCopyFileTo(self, oGuestSession, sSrc, sDst, fFlags):
1129 """
1130 Helper function to copy a single file from host to the guest.
1131 """
1132 fRc = True; # Be optimistic.
1133 try:
1134 reporter.log2('Copying host file "%s" to guest "%s" (flags %s)' % (sSrc, sDst, fFlags));
1135 if self.oTstDrv.fpApiVer >= 5.0:
1136 oCurProgress = oGuestSession.fileCopyToGuest(sSrc, sDst, fFlags);
1137 else:
1138 oCurProgress = oGuestSession.copyTo(sSrc, sDst, fFlags);
1139 if oCurProgress is not None:
1140 oProgress = vboxwrappers.ProgressWrapper(oCurProgress, self.oTstDrv.oVBoxMgr, self.oTstDrv, "gctrlCopyFileTo");
1141 try:
1142 oProgress.wait();
1143 if not oProgress.isSuccess():
1144 oProgress.logResult(fIgnoreErrors = True);
1145 fRc = False;
1146 except:
1147 reporter.logXcpt('Wait exception for sSrc="%s", sDst="%s":' % (sSrc, sDst));
1148 fRc = False;
1149 else:
1150 reporter.error('No progress object returned');
1151 fRc = False;
1152 except:
1153 # Just log, don't assume an error here (will be done in the main loop then).
1154 reporter.logXcpt('Copy to exception for sSrc="%s", sDst="%s":' % (sSrc, sDst));
1155 fRc = False;
1156
1157 return fRc;
1158
1159 def gctrlCreateDir(self, oTest, oRes, oGuestSession):
1160 """
1161 Helper function to create a guest directory specified in
1162 the current test.
1163 """
1164 fRc = True; # Be optimistic.
1165 reporter.log2('Creating directory "%s"' % (oTest.sDirectory,));
1166
1167 try:
1168 oGuestSession.directoryCreate(oTest.sDirectory, \
1169 oTest.fMode, oTest.fFlags);
1170 if self.oTstDrv.fpApiVer >= 5.0:
1171 fDirExists = oGuestSession.directoryExists(oTest.sDirectory, False);
1172 else:
1173 fDirExists = oGuestSession.directoryExists(oTest.sDirectory);
1174 if fDirExists is False \
1175 and oRes.fRc is True:
1176 # Directory does not exist but we want it to.
1177 fRc = False;
1178 except:
1179 reporter.logXcpt('Directory create exception for directory "%s":' % (oTest.sDirectory,));
1180 if oRes.fRc is True:
1181 # Just log, don't assume an error here (will be done in the main loop then).
1182 fRc = False;
1183 # Directory creation failed, which was the expected result.
1184
1185 return fRc;
1186
1187 def gctrlReadDir(self, oTest, oRes, oGuestSession, subDir = ''): # pylint: disable=too-many-locals
1188 """
1189 Helper function to read a guest directory specified in
1190 the current test.
1191 """
1192 sDir = oTest.sDirectory;
1193 sFilter = oTest.sFilter;
1194 fFlags = oTest.fFlags;
1195
1196 fRc = True; # Be optimistic.
1197 cDirs = 0; # Number of directories read.
1198 cFiles = 0; # Number of files read.
1199
1200 try:
1201 sCurDir = os.path.join(sDir, subDir);
1202 #reporter.log2('Directory="%s", filter="%s", fFlags="%s"' % (sCurDir, sFilter, fFlags));
1203 oCurDir = oGuestSession.directoryOpen(sCurDir, sFilter, fFlags);
1204 while fRc:
1205 try:
1206 oFsObjInfo = oCurDir.read();
1207 if oFsObjInfo.name == "." \
1208 or oFsObjInfo.name == "..":
1209 #reporter.log2('\tSkipping "%s"' % oFsObjInfo.name);
1210 continue; # Skip "." and ".." entries.
1211 if oFsObjInfo.type is vboxcon.FsObjType_Directory:
1212 #reporter.log2('\tDirectory "%s"' % oFsObjInfo.name);
1213 cDirs += 1;
1214 sSubDir = oFsObjInfo.name;
1215 if subDir != "":
1216 sSubDir = os.path.join(subDir, oFsObjInfo.name);
1217 fRc, cSubDirs, cSubFiles = self.gctrlReadDir(oTest, oRes, oGuestSession, sSubDir);
1218 cDirs += cSubDirs;
1219 cFiles += cSubFiles;
1220 elif oFsObjInfo.type is vboxcon.FsObjType_File:
1221 #reporter.log2('\tFile "%s"' % oFsObjInfo.name);
1222 cFiles += 1;
1223 elif oFsObjInfo.type is vboxcon.FsObjType_Symlink:
1224 #reporter.log2('\tSymlink "%s" -- not tested yet' % oFsObjInfo.name);
1225 pass;
1226 else:
1227 reporter.error('\tDirectory "%s" contains invalid directory entry "%s" (type %d)' % \
1228 (sCurDir, oFsObjInfo.name, oFsObjInfo.type));
1229 fRc = False;
1230 except Exception as oXcpt:
1231 # No necessarily an error -- could be VBOX_E_OBJECT_NOT_FOUND. See reference.
1232 if vbox.ComError.equal(oXcpt, vbox.ComError.VBOX_E_OBJECT_NOT_FOUND):
1233 #reporter.log2('\tNo more directory entries for "%s"' % (sCurDir,));
1234 break
1235 # Just log, don't assume an error here (will be done in the main loop then).
1236 reporter.logXcpt('\tDirectory open exception for directory="%s":' % (sCurDir,));
1237 fRc = False;
1238 break;
1239 oCurDir.close();
1240 except:
1241 # Just log, don't assume an error here (will be done in the main loop then).
1242 reporter.logXcpt('\tDirectory open exception for directory="%s":' % (sCurDir,));
1243 fRc = False;
1244
1245 return (fRc, cDirs, cFiles);
1246
1247 def gctrlExecDoTest(self, i, oTest, oRes, oGuestSession):
1248 """
1249 Wrapper function around gctrlExecute to provide more sanity checking
1250 when needed in actual execution tests.
1251 """
1252 reporter.log('Testing #%d, cmd="%s" ...' % (i, oTest.sCmd));
1253 fRc = self.gctrlExecute(oTest, oGuestSession);
1254 if fRc is oRes.fRc:
1255 if fRc is True:
1256 # Compare exit status / code on successful process execution.
1257 if oTest.uExitStatus != oRes.uExitStatus \
1258 or oTest.iExitCode != oRes.iExitCode:
1259 reporter.error('Test #%d failed: Got exit status + code %d,%d, expected %d,%d'
1260 % (i, oTest.uExitStatus, oTest.iExitCode, oRes.uExitStatus, oRes.iExitCode));
1261 return False;
1262 if fRc is True:
1263 # Compare test / result buffers on successful process execution.
1264 if oTest.sBuf is not None \
1265 and oRes.sBuf is not None:
1266 if bytes(oTest.sBuf) != bytes(oRes.sBuf):
1267 reporter.error('Test #%d failed: Got buffer\n%s (%d bytes), expected\n%s (%d bytes)'
1268 % (i, map(hex, map(ord, oTest.sBuf)), len(oTest.sBuf), \
1269 map(hex, map(ord, oRes.sBuf)), len(oRes.sBuf)));
1270 return False;
1271 reporter.log2('Test #%d passed: Buffers match (%d bytes)' % (i, len(oRes.sBuf)));
1272 elif oRes.sBuf is not None \
1273 and oRes.sBuf:
1274 reporter.error('Test #%d failed: Got no buffer data, expected\n%s (%dbytes)' %
1275 (i, map(hex, map(ord, oRes.sBuf)), len(oRes.sBuf)));
1276 return False;
1277 elif oRes.cbStdOut > 0 \
1278 and oRes.cbStdOut != oTest.cbStdOut:
1279 reporter.error('Test #%d failed: Got %d stdout data, expected %d'
1280 % (i, oTest.cbStdOut, oRes.cbStdOut));
1281 return False;
1282 else:
1283 reporter.error('Test #%d failed: Got %s, expected %s' % (i, fRc, oRes.fRc));
1284 return False;
1285 return True;
1286
1287 def gctrlExecute(self, oTest, oGuestSession):
1288 """
1289 Helper function to execute a program on a guest, specified in
1290 the current test.
1291 """
1292 fRc = True; # Be optimistic.
1293
1294 ## @todo Compare execution timeouts!
1295 #tsStart = base.timestampMilli();
1296
1297 reporter.log2('Using session user=%s, sDomain=%s, name=%s, timeout=%d'
1298 % (oGuestSession.user, oGuestSession.domain, oGuestSession.name, oGuestSession.timeout));
1299 reporter.log2('Executing sCmd=%s, fFlags=%s, timeoutMS=%d, aArgs=%s, aEnv=%s'
1300 % (oTest.sCmd, oTest.fFlags, oTest.timeoutMS, oTest.aArgs, oTest.aEnv));
1301 try:
1302 curProc = oGuestSession.processCreate(oTest.sCmd,
1303 oTest.aArgs if self.oTstDrv.fpApiVer >= 5.0 else oTest.aArgs[1:],
1304 oTest.aEnv, oTest.fFlags, oTest.timeoutMS);
1305 if curProc is not None:
1306 reporter.log2('Process start requested, waiting for start (%dms) ...' % (oTest.timeoutMS,));
1307 aeWaitFor = [ vboxcon.ProcessWaitForFlag_Start ];
1308 waitResult = curProc.waitForArray(aeWaitFor, oTest.timeoutMS);
1309 reporter.log2('Wait result returned: %d, current process status is: %d' % (waitResult, curProc.status));
1310
1311 if curProc.status == vboxcon.ProcessStatus_Started:
1312 aeWaitFor = [ vboxcon.ProcessWaitForFlag_Terminate ];
1313 if vboxcon.ProcessCreateFlag_WaitForStdOut in oTest.fFlags:
1314 aeWaitFor.append(vboxcon.ProcessWaitForFlag_StdOut);
1315 if vboxcon.ProcessCreateFlag_WaitForStdErr in oTest.fFlags:
1316 aeWaitFor.append(vboxcon.ProcessWaitForFlag_StdErr);
1317 ## @todo Add vboxcon.ProcessWaitForFlag_StdIn.
1318 reporter.log2('Process (PID %d) started, waiting for termination (%dms), waitFlags=%s ...'
1319 % (curProc.PID, oTest.timeoutMS, aeWaitFor));
1320 while True:
1321 waitResult = curProc.waitForArray(aeWaitFor, oTest.timeoutMS);
1322 reporter.log2('Wait returned: %d' % (waitResult,));
1323 try:
1324 # Try stdout.
1325 if waitResult in (vboxcon.ProcessWaitResult_StdOut, vboxcon.ProcessWaitResult_WaitFlagNotSupported):
1326 reporter.log2('Reading stdout ...');
1327 abBuf = curProc.Read(1, 64 * 1024, oTest.timeoutMS);
1328 if abBuf:
1329 reporter.log2('Process (PID %d) got %d bytes of stdout data' % (curProc.PID, len(abBuf)));
1330 oTest.cbStdOut += len(abBuf);
1331 oTest.sBuf = abBuf; # Appending does *not* work atm, so just assign it. No time now.
1332 # Try stderr.
1333 if waitResult in (vboxcon.ProcessWaitResult_StdErr, vboxcon.ProcessWaitResult_WaitFlagNotSupported):
1334 reporter.log2('Reading stderr ...');
1335 abBuf = curProc.Read(2, 64 * 1024, oTest.timeoutMS);
1336 if abBuf:
1337 reporter.log2('Process (PID %d) got %d bytes of stderr data' % (curProc.PID, len(abBuf)));
1338 oTest.cbStdErr += len(abBuf);
1339 oTest.sBuf = abBuf; # Appending does *not* work atm, so just assign it. No time now.
1340 # Use stdin.
1341 if waitResult in (vboxcon.ProcessWaitResult_StdIn, vboxcon.ProcessWaitResult_WaitFlagNotSupported):
1342 pass; #reporter.log2('Process (PID %d) needs stdin data' % (curProc.pid,));
1343 # Termination or error?
1344 if waitResult in (vboxcon.ProcessWaitResult_Terminate,
1345 vboxcon.ProcessWaitResult_Error,
1346 vboxcon.ProcessWaitResult_Timeout,):
1347 reporter.log2('Process (PID %d) reported terminate/error/timeout: %d, status: %d'
1348 % (curProc.PID, waitResult, curProc.status));
1349 break;
1350 except:
1351 # Just skip reads which returned nothing.
1352 pass;
1353 reporter.log2('Final process status (PID %d) is: %d' % (curProc.PID, curProc.status));
1354 reporter.log2('Process (PID %d) %d stdout, %d stderr' % (curProc.PID, oTest.cbStdOut, oTest.cbStdErr));
1355 oTest.uExitStatus = curProc.status;
1356 oTest.iExitCode = curProc.exitCode;
1357 reporter.log2('Process (PID %d) has exit code: %d' % (curProc.PID, oTest.iExitCode));
1358 except KeyboardInterrupt:
1359 reporter.error('Process (PID %d) execution interrupted' % (curProc.PID,));
1360 if curProc is not None:
1361 curProc.close();
1362 except:
1363 # Just log, don't assume an error here (will be done in the main loop then).
1364 reporter.logXcpt('Execution exception for command "%s":' % (oTest.sCmd,));
1365 fRc = False;
1366
1367 return fRc;
1368
1369 def testGuestCtrlSessionEnvironment(self, oSession, oTxsSession, oTestVm): # pylint: disable=too-many-locals
1370 """
1371 Tests the guest session environment changes.
1372 """
1373 aoTests = [
1374 # Check basic operations.
1375 tdTestSessionEx([ # Initial environment is empty.
1376 tdStepSessionCheckEnv(),
1377 # Check clearing empty env.
1378 tdStepSessionClearEnv(),
1379 tdStepSessionCheckEnv(),
1380 # Check set.
1381 tdStepSessionSetEnv('FOO', 'BAR'),
1382 tdStepSessionCheckEnv(['FOO=BAR',]),
1383 tdStepRequireMinimumApiVer(5.0), # 4.3 can't cope with the remainder.
1384 tdStepSessionClearEnv(),
1385 tdStepSessionCheckEnv(),
1386 # Check unset.
1387 tdStepSessionUnsetEnv('BAR'),
1388 tdStepSessionCheckEnv(['BAR']),
1389 tdStepSessionClearEnv(),
1390 tdStepSessionCheckEnv(),
1391 # Set + unset.
1392 tdStepSessionSetEnv('FOO', 'BAR'),
1393 tdStepSessionCheckEnv(['FOO=BAR',]),
1394 tdStepSessionUnsetEnv('FOO'),
1395 tdStepSessionCheckEnv(['FOO']),
1396 # Bulk environment changes (via attrib) (shall replace existing 'FOO').
1397 tdStepSessionBulkEnv( ['PATH=/bin:/usr/bin', 'TMPDIR=/var/tmp', 'USER=root']),
1398 tdStepSessionCheckEnv(['PATH=/bin:/usr/bin', 'TMPDIR=/var/tmp', 'USER=root']),
1399 ]),
1400 tdTestSessionEx([ # Check that setting the same value several times works.
1401 tdStepSessionSetEnv('FOO','BAR'),
1402 tdStepSessionCheckEnv([ 'FOO=BAR',]),
1403 tdStepSessionSetEnv('FOO','BAR2'),
1404 tdStepSessionCheckEnv([ 'FOO=BAR2',]),
1405 tdStepSessionSetEnv('FOO','BAR3'),
1406 tdStepSessionCheckEnv([ 'FOO=BAR3',]),
1407 tdStepRequireMinimumApiVer(5.0), # 4.3 can't cope with the remainder.
1408 # Add a little unsetting to the mix.
1409 tdStepSessionSetEnv('BAR', 'BEAR'),
1410 tdStepSessionCheckEnv([ 'FOO=BAR3', 'BAR=BEAR',]),
1411 tdStepSessionUnsetEnv('FOO'),
1412 tdStepSessionCheckEnv([ 'FOO', 'BAR=BEAR',]),
1413 tdStepSessionSetEnv('FOO','BAR4'),
1414 tdStepSessionCheckEnv([ 'FOO=BAR4', 'BAR=BEAR',]),
1415 # The environment is case sensitive.
1416 tdStepSessionSetEnv('foo','BAR5'),
1417 tdStepSessionCheckEnv([ 'FOO=BAR4', 'BAR=BEAR', 'foo=BAR5']),
1418 tdStepSessionUnsetEnv('foo'),
1419 tdStepSessionCheckEnv([ 'FOO=BAR4', 'BAR=BEAR', 'foo']),
1420 ]),
1421 tdTestSessionEx([ # Bulk settings merges stuff, last entry standing.
1422 tdStepSessionBulkEnv(['FOO=bar', 'foo=bar', 'FOO=doofus', 'TMPDIR=/tmp', 'foo=bar2']),
1423 tdStepSessionCheckEnv(['FOO=doofus', 'TMPDIR=/tmp', 'foo=bar2']),
1424 tdStepRequireMinimumApiVer(5.0), # 4.3 is buggy!
1425 tdStepSessionBulkEnv(['2=1+1', 'FOO=doofus2', ]),
1426 tdStepSessionCheckEnv(['2=1+1', 'FOO=doofus2' ]),
1427 ]),
1428 # Invalid variable names.
1429 tdTestSessionEx([
1430 tdStepSessionSetEnv('', 'FOO', vbox.ComError.E_INVALIDARG),
1431 tdStepSessionCheckEnv(),
1432 tdStepRequireMinimumApiVer(5.0), # 4.3 is too relaxed checking input!
1433 tdStepSessionSetEnv('=', '===', vbox.ComError.E_INVALIDARG),
1434 tdStepSessionCheckEnv(),
1435 tdStepSessionSetEnv('FOO=', 'BAR', vbox.ComError.E_INVALIDARG),
1436 tdStepSessionCheckEnv(),
1437 tdStepSessionSetEnv('=FOO', 'BAR', vbox.ComError.E_INVALIDARG),
1438 tdStepSessionCheckEnv(),
1439 tdStepRequireMinimumApiVer(5.0), # 4.3 is buggy and too relaxed!
1440 tdStepSessionBulkEnv(['', 'foo=bar'], vbox.ComError.E_INVALIDARG),
1441 tdStepSessionCheckEnv(),
1442 tdStepSessionBulkEnv(['=', 'foo=bar'], vbox.ComError.E_INVALIDARG),
1443 tdStepSessionCheckEnv(),
1444 tdStepSessionBulkEnv(['=FOO', 'foo=bar'], vbox.ComError.E_INVALIDARG),
1445 tdStepSessionCheckEnv(),
1446 ]),
1447 # A bit more weird keys/values.
1448 tdTestSessionEx([ tdStepSessionSetEnv('$$$', ''),
1449 tdStepSessionCheckEnv([ '$$$=',]), ]),
1450 tdTestSessionEx([ tdStepSessionSetEnv('$$$', '%%%'),
1451 tdStepSessionCheckEnv([ '$$$=%%%',]),
1452 ]),
1453 tdTestSessionEx([ tdStepRequireMinimumApiVer(5.0), # 4.3 is buggy!
1454 tdStepSessionSetEnv(u'ß$%ß&', ''),
1455 tdStepSessionCheckEnv([ u'ß$%ß&=',]),
1456 ]),
1457 # Misc stuff.
1458 tdTestSessionEx([ tdStepSessionSetEnv('FOO', ''),
1459 tdStepSessionCheckEnv(['FOO=',]),
1460 ]),
1461 tdTestSessionEx([ tdStepSessionSetEnv('FOO', 'BAR'),
1462 tdStepSessionCheckEnv(['FOO=BAR',])
1463 ],),
1464 tdTestSessionEx([ tdStepSessionSetEnv('FOO', 'BAR'),
1465 tdStepSessionSetEnv('BAR', 'BAZ'),
1466 tdStepSessionCheckEnv([ 'FOO=BAR', 'BAR=BAZ',]),
1467 ]),
1468 ];
1469 return tdTestSessionEx.executeListTestSessions(aoTests, self.oTstDrv, oSession, oTxsSession, oTestVm, 'SessionEnv');
1470
1471 def testGuestCtrlSession(self, oSession, oTxsSession, oTestVm):
1472 """
1473 Tests the guest session handling.
1474 """
1475
1476 #
1477 # Parameters.
1478 #
1479 atTests = [
1480 # Invalid parameters.
1481 [ tdTestSession(sUser = ''), tdTestResultSession() ],
1482 [ tdTestSession(sPassword = 'bar'), tdTestResultSession() ],
1483 [ tdTestSession(sDomain = 'boo'),tdTestResultSession() ],
1484 [ tdTestSession(sPassword = 'bar', sDomain = 'boo'), tdTestResultSession() ],
1485 # User account without a passwort - forbidden.
1486 [ tdTestSession(sPassword = "" ), tdTestResultSession() ],
1487 # Wrong credentials.
1488 # Note: On Guest Additions < 4.3 this always succeeds because these don't
1489 # support creating dedicated sessions. Instead, guest process creation
1490 # then will fail. See note below.
1491 [ tdTestSession(sUser = 'foo', sPassword = 'bar', sDomain = 'boo'), tdTestResultSession() ],
1492 # Correct credentials.
1493 [ tdTestSession(), tdTestResultSession(fRc = True, cNumSessions = 1) ]
1494 ];
1495
1496 fRc = True;
1497 for (i, tTest) in enumerate(atTests):
1498 oCurTest = tTest[0] # type: tdTestSession
1499 oCurRes = tTest[1] # type: tdTestResult
1500
1501 oCurTest.setEnvironment(oSession, oTxsSession, oTestVm);
1502 reporter.log('Testing #%d, user="%s", sPassword="%s", sDomain="%s" ...'
1503 % (i, oCurTest.oCreds.sUser, oCurTest.oCreds.sPassword, oCurTest.oCreds.sDomain));
1504 sCurGuestSessionName = 'testGuestCtrlSession: Test #%d' % (i,);
1505 fRc2, oCurGuestSession = oCurTest.createSession(sCurGuestSessionName, fIsError = oCurRes.fRc);
1506
1507 # See note about < 4.3 Guest Additions above.
1508 uProtocolVersion = 2;
1509 if oCurGuestSession is not None:
1510 try:
1511 uProtocolVersion = oCurGuestSession.protocolVersion;
1512 except:
1513 fRc = reporter.errorXcpt('Test #%d' % (i,));
1514
1515 if uProtocolVersion >= 2 and fRc2 is not oCurRes.fRc:
1516 fRc = reporter.error('Test #%d failed: Session creation failed: Got %s, expected %s' % (i, fRc2, oCurRes.fRc,));
1517
1518 if fRc2 and oCurGuestSession is None:
1519 fRc = reporter.error('Test #%d failed: no session object' % (i,));
1520 fRc2 = False;
1521
1522 if fRc2:
1523 if uProtocolVersion >= 2: # For Guest Additions < 4.3 getSessionCount() always will return 1.
1524 cCurSessions = oCurTest.getSessionCount(self.oTstDrv.oVBoxMgr);
1525 if cCurSessions != oCurRes.cNumSessions:
1526 fRc = reporter.error('Test #%d failed: Session count does not match: Got %d, expected %d'
1527 % (i, cCurSessions, oCurRes.cNumSessions));
1528 try:
1529 sObjName = oCurGuestSession.name;
1530 except:
1531 fRc = reporter.errorXcpt('Test #%d' % (i,));
1532 else:
1533 if sObjName != sCurGuestSessionName:
1534 fRc = reporter.error('Test #%d failed: Session name does not match: Got "%s", expected "%s"'
1535 % (i, sObjName, sCurGuestSessionName));
1536 fRc2 = oCurTest.closeSession(True);
1537 if fRc2 is False:
1538 fRc = reporter.error('Test #%d failed: Session could not be closed' % (i,));
1539
1540 if fRc is False:
1541 return (False, oTxsSession);
1542
1543 #
1544 # Multiple sessions.
1545 #
1546 cMaxGuestSessions = 31; # Maximum number of concurrent guest session allowed.
1547 # Actually, this is 32, but we don't test session 0.
1548 aoMultiSessions = {};
1549 reporter.log2('Opening multiple guest tsessions at once ...');
1550 for i in xrange(cMaxGuestSessions + 1):
1551 aoMultiSessions[i] = tdTestSession(sSessionName = 'MultiSession #%d' % (i,));
1552 aoMultiSessions[i].setEnvironment(oSession, oTxsSession, oTestVm);
1553
1554 cCurSessions = aoMultiSessions[i].getSessionCount(self.oTstDrv.oVBoxMgr);
1555 reporter.log2('MultiSession test #%d count is %d' % (i, cCurSessions));
1556 if cCurSessions != i:
1557 return (reporter.error('MultiSession count is %d, expected %d' % (cCurSessions, i)), oTxsSession);
1558 fRc2, _ = aoMultiSessions[i].createSession('MultiSession #%d' % (i,), i < cMaxGuestSessions);
1559 if fRc2 is not True:
1560 if i < cMaxGuestSessions:
1561 return (reporter.error('MultiSession #%d test failed' % (i,)), oTxsSession);
1562 reporter.log('MultiSession #%d exceeded concurrent guest session count, good' % (i,));
1563 break;
1564
1565 cCurSessions = aoMultiSessions[i].getSessionCount(self.oTstDrv.oVBoxMgr);
1566 if cCurSessions is not cMaxGuestSessions:
1567 return (reporter.error('Final session count %d, expected %d ' % (cCurSessions, cMaxGuestSessions,)), oTxsSession);
1568
1569 reporter.log2('Closing MultiSessions ...');
1570 for i in xrange(cMaxGuestSessions):
1571 # Close this session:
1572 oClosedGuestSession = aoMultiSessions[i].oGuestSession;
1573 fRc2 = aoMultiSessions[i].closeSession(True);
1574 cCurSessions = aoMultiSessions[i].getSessionCount(self.oTstDrv.oVBoxMgr)
1575 reporter.log2('MultiSession #%d count is %d' % (i, cCurSessions,));
1576 if fRc2 is False:
1577 fRc = reporter.error('Closing MultiSession #%d failed' % (i,));
1578 elif cCurSessions != cMaxGuestSessions - (i + 1):
1579 fRc = reporter.error('Expected %d session after closing #%d, got %d instead'
1580 % (cMaxGuestSessions - (i + 1), cCurSessions, i,));
1581 assert aoMultiSessions[i].oGuestSession is None or not fRc2;
1582 ## @todo any way to check that the session is closed other than the 'sessions' attribute?
1583
1584 # Try check that none of the remaining sessions got closed.
1585 try:
1586 aoGuestSessions = self.oTstDrv.oVBoxMgr.getArray(atTests[0][0].oTest.oGuest, 'sessions');
1587 except:
1588 return (reporter.errorXcpt('i=%d/%d' % (i, cMaxGuestSessions,)), oTxsSession);
1589 if oClosedGuestSession in aoGuestSessions:
1590 fRc = reporter.error('i=%d/%d: %s should not be in %s'
1591 % (i, cMaxGuestSessions, oClosedGuestSession, aoGuestSessions));
1592 if i + 1 < cMaxGuestSessions: # Not sure what xrange(2,2) does...
1593 for j in xrange(i + 1, cMaxGuestSessions):
1594 if aoMultiSessions[j].oGuestSession not in aoGuestSessions:
1595 fRc = reporter.error('i=%d/j=%d/%d: %s should be in %s'
1596 % (i, j, cMaxGuestSessions, aoMultiSessions[j].oGuestSession, aoGuestSessions));
1597 ## @todo any way to check that they work?
1598
1599 ## @todo Test session timeouts.
1600
1601 return (fRc, oTxsSession);
1602
1603 def testGuestCtrlSessionFileRefs(self, oSession, oTxsSession, oTestVm): # pylint: disable=too-many-locals
1604 """
1605 Tests the guest session file reference handling.
1606 """
1607
1608 # Find a file to play around with:
1609 if oTestVm.isWindows():
1610 sFile = "C:\\Windows\\System32\\ntdll.dll";
1611 if oTestVm.sKind in ['WindowsNT4', 'WindowsNT3x',]:
1612 sFile = "C:\\Winnt\\System32\\ntdll.dll";
1613 else:
1614 sFile = "/bin/sh";
1615
1616 # Use credential defaults.
1617 oCreds = tdCtxCreds();
1618 oCreds.applyDefaultsIfNotSet(oTestVm);
1619
1620 # Number of stale guest files to create.
1621 cStaleFiles = 10;
1622
1623 #
1624 # Start a session.
1625 #
1626 aeWaitFor = [ vboxcon.GuestSessionWaitForFlag_Start ];
1627 try:
1628 oGuest = oSession.o.console.guest;
1629 oGuestSession = oGuest.createSession(oCreds.sUser, oCreds.sPassword, oCreds.sDomain, "testGuestCtrlSessionFileRefs");
1630 eWaitResult = oGuestSession.waitForArray(aeWaitFor, 30 * 1000);
1631 except:
1632 return (reporter.errorXcpt(), oTxsSession);
1633
1634 # Be nice to Guest Additions < 4.3: They don't support session handling and therefore return WaitFlagNotSupported.
1635 if eWaitResult not in (vboxcon.GuestSessionWaitResult_Start, vboxcon.GuestSessionWaitResult_WaitFlagNotSupported):
1636 return (reporter.error('Session did not start successfully - wait error: %d' % (eWaitResult,)), oTxsSession);
1637 reporter.log('Session successfully started');
1638
1639 #
1640 # Open guest files and "forget" them (stale entries).
1641 # For them we don't have any references anymore intentionally.
1642 #
1643 reporter.log2('Opening stale files');
1644 fRc = True;
1645 for i in xrange(0, cStaleFiles):
1646 try:
1647 if self.oTstDrv.fpApiVer >= 5.0:
1648 oGuestSession.fileOpen(sFile, vboxcon.FileAccessMode_ReadOnly, vboxcon.FileOpenAction_OpenExisting, 0);
1649 else:
1650 oGuestSession.fileOpen(sFile, "r", "oe", 0);
1651 # Note: Use a timeout in the call above for not letting the stale processes
1652 # hanging around forever. This can happen if the installed Guest Additions
1653 # do not support terminating guest processes.
1654 except:
1655 fRc = reporter.errorXcpt('Opening stale file #%d failed:' % (i,));
1656 break;
1657
1658 try: cFiles = len(self.oTstDrv.oVBoxMgr.getArray(oGuestSession, 'files'));
1659 except: fRc = reporter.errorXcpt();
1660 else:
1661 if cFiles != cStaleFiles:
1662 fRc = reporter.error('Test failed: Got %d stale files, expected %d' % (cFiles, cStaleFiles));
1663
1664 if fRc is True:
1665 #
1666 # Open non-stale files and close them again.
1667 #
1668 reporter.log2('Opening non-stale files');
1669 aoFiles = [];
1670 for i in xrange(0, cStaleFiles):
1671 try:
1672 if self.oTstDrv.fpApiVer >= 5.0:
1673 oCurFile = oGuestSession.fileOpen(sFile, vboxcon.FileAccessMode_ReadOnly,
1674 vboxcon.FileOpenAction_OpenExisting, 0);
1675 else:
1676 oCurFile = oGuestSession.fileOpen(sFile, "r", "oe", 0);
1677 aoFiles.append(oCurFile);
1678 except:
1679 fRc = reporter.errorXcpt('Opening non-stale file #%d failed:' % (i,));
1680 break;
1681
1682 # Check the count.
1683 try: cFiles = len(self.oTstDrv.oVBoxMgr.getArray(oGuestSession, 'files'));
1684 except: fRc = reporter.errorXcpt();
1685 else:
1686 if cFiles != cStaleFiles * 2:
1687 fRc = reporter.error('Test failed: Got %d total files, expected %d' % (cFiles, cStaleFiles * 2));
1688
1689 # Close them.
1690 reporter.log2('Closing all non-stale files again ...');
1691 for i, oFile in enumerate(aoFiles):
1692 try:
1693 oFile.close();
1694 except:
1695 fRc = reporter.errorXcpt('Closing non-stale file #%d failed:' % (i,));
1696
1697 # Check the count again.
1698 try: cFiles = len(self.oTstDrv.oVBoxMgr.getArray(oGuestSession, 'files'));
1699 except: fRc = reporter.errorXcpt();
1700 # Here we count the stale files (that is, files we don't have a reference
1701 # anymore for) and the opened and then closed non-stale files (that we still keep
1702 # a reference in aoFiles[] for).
1703 if cFiles != cStaleFiles:
1704 fRc = reporter.error('Test failed: Got %d total files, expected %d' % (cFiles, cStaleFiles));
1705
1706 #
1707 # Check that all (referenced) non-stale files are now in the "closed" state.
1708 #
1709 reporter.log2('Checking statuses of all non-stale files ...');
1710 for i, oFile in enumerate(aoFiles):
1711 try:
1712 eFileStatus = aoFiles[i].status;
1713 except:
1714 fRc = reporter.errorXcpt('Checking status of file #%d failed:' % (i,));
1715 else:
1716 if eFileStatus != vboxcon.FileStatus_Closed:
1717 fRc = reporter.error('Test failed: Non-stale file #%d has status %d, expected %d'
1718 % (i, eFileStatus, vboxcon.FileStatus_Closed));
1719
1720 if fRc is True:
1721 reporter.log2('All non-stale files closed');
1722
1723 try: cFiles = len(self.oTstDrv.oVBoxMgr.getArray(oGuestSession, 'files'));
1724 except: fRc = reporter.errorXcpt();
1725 else: reporter.log2('Final guest session file count: %d' % (cFiles,));
1726
1727 #
1728 # Now try to close the session and see what happens.
1729 # Note! Session closing is why we've been doing all the 'if fRc is True' stuff above rather than returning.
1730 #
1731 reporter.log2('Closing guest session ...');
1732 try:
1733 oGuestSession.close();
1734 except:
1735 fRc = reporter.errorXcpt('Testing for stale processes failed:');
1736
1737 return (fRc, oTxsSession);
1738
1739 #def testGuestCtrlSessionDirRefs(self, oSession, oTxsSession, oTestVm):
1740 # """
1741 # Tests the guest session directory reference handling.
1742 # """
1743
1744 # fRc = True;
1745 # return (fRc, oTxsSession);
1746
1747 def testGuestCtrlSessionProcRefs(self, oSession, oTxsSession, oTestVm): # pylint: disable=too-many-locals
1748 """
1749 Tests the guest session process reference handling.
1750 """
1751
1752 if oTestVm.isWindows():
1753 sCmd = "C:\\windows\\system32\\cmd.exe";
1754 elif oTestVm.isLinux():
1755 sCmd = "/bin/sh";
1756 aArgs = [sCmd,];
1757
1758 # Use credential defaults.
1759 oCreds = tdCtxCreds();
1760 oCreds.applyDefaultsIfNotSet(oTestVm);
1761
1762 # Number of stale guest processes to create.
1763 cStaleProcs = 10;
1764
1765 fRc = True;
1766 try:
1767 oGuest = oSession.o.console.guest;
1768 oGuestSession = oGuest.createSession(oCreds.sUser, oCreds.sPassword, oCreds.sDomain, "testGuestCtrlSessionProcRefs");
1769 aeWaitFor = [ vboxcon.GuestSessionWaitForFlag_Start ];
1770 waitResult = oGuestSession.waitForArray(aeWaitFor, 30 * 1000);
1771 #
1772 # Be nice to Guest Additions < 4.3: They don't support session handling and
1773 # therefore return WaitFlagNotSupported.
1774 #
1775 if waitResult not in (vboxcon.GuestSessionWaitResult_Start, vboxcon.GuestSessionWaitResult_WaitFlagNotSupported):
1776 # Just log, don't assume an error here (will be done in the main loop then).
1777 reporter.log('Session did not start successfully, returned wait result: %d' \
1778 % (waitResult));
1779 return (False, oTxsSession);
1780 reporter.log('Session successfully started');
1781
1782 #
1783 # Fire off forever-running processes and "forget" them (stale entries).
1784 # For them we don't have any references anymore intentionally.
1785 #
1786 reporter.log2('Starting stale processes');
1787 for i in xrange(0, cStaleProcs):
1788 try:
1789 oGuestSession.processCreate(sCmd,
1790 aArgs if self.oTstDrv.fpApiVer >= 5.0 else aArgs[1:], [],
1791 [ vboxcon.ProcessCreateFlag_WaitForStdOut ], \
1792 30 * 1000);
1793 # Note: Use a timeout in the call above for not letting the stale processes
1794 # hanging around forever. This can happen if the installed Guest Additions
1795 # do not support terminating guest processes.
1796 except:
1797 reporter.logXcpt('Creating stale process #%d failed:' % (i,));
1798 fRc = False;
1799 break;
1800
1801 if fRc:
1802 cProcs = len(self.oTstDrv.oVBoxMgr.getArray(oGuestSession, 'processes'));
1803 if cProcs != cStaleProcs:
1804 reporter.error('Test failed: Got %d stale processes, expected %d' % (cProcs, cStaleProcs));
1805 fRc = False;
1806
1807 if fRc:
1808 #
1809 # Fire off non-stale processes and wait for termination.
1810 #
1811 if oTestVm.isWindows():
1812 aArgs = [ sCmd, '/C', 'dir', '/S', 'C:\\Windows\\system'];
1813 else:
1814 aArgs = [ sCmd, '-c', 'date'];
1815 reporter.log2('Starting non-stale processes');
1816 aaProcs = [];
1817 for i in xrange(0, cStaleProcs):
1818 try:
1819 oCurProc = oGuestSession.processCreate(sCmd, aArgs if self.oTstDrv.fpApiVer >= 5.0 else aArgs[1:],
1820 [], [], 0); # Infinite timeout.
1821 aaProcs.append(oCurProc);
1822 except:
1823 reporter.logXcpt('Creating non-stale process #%d failed:' % (i,));
1824 fRc = False;
1825 break;
1826 if fRc:
1827 reporter.log2('Waiting for non-stale processes to terminate');
1828 for i in xrange(0, cStaleProcs):
1829 try:
1830 aaProcs[i].waitForArray([ vboxcon.ProcessWaitForFlag_Terminate ], 30 * 1000);
1831 curProcStatus = aaProcs[i].status;
1832 if aaProcs[i].status != vboxcon.ProcessStatus_TerminatedNormally:
1833 reporter.error('Test failed: Waiting for non-stale processes #%d'
1834 ' resulted in status %d, expected %d' \
1835 % (i, curProcStatus, vboxcon.ProcessStatus_TerminatedNormally));
1836 fRc = False;
1837 except:
1838 reporter.logXcpt('Waiting for non-stale process #%d failed:' % (i,));
1839 fRc = False;
1840 break;
1841 cProcs = len(self.oTstDrv.oVBoxMgr.getArray(oGuestSession, 'processes'));
1842 # Here we count the stale processes (that is, processes we don't have a reference
1843 # anymore for) and the started + terminated non-stale processes (that we still keep
1844 # a reference in aaProcs[] for).
1845 if cProcs != (cStaleProcs * 2):
1846 reporter.error('Test failed: Got %d total processes, expected %d' \
1847 % (cProcs, cStaleProcs));
1848 fRc = False;
1849 if fRc:
1850 #
1851 # Check if all (referenced) non-stale processes now are in "terminated" state.
1852 #
1853 for i in xrange(0, cStaleProcs):
1854 curProcStatus = aaProcs[i].status;
1855 if aaProcs[i].status != vboxcon.ProcessStatus_TerminatedNormally:
1856 reporter.error('Test failed: Non-stale processes #%d has status %d, expected %d' \
1857 % (i, curProcStatus, vboxcon.ProcessStatus_TerminatedNormally));
1858 fRc = False;
1859 if fRc:
1860 reporter.log2('All non-stale processes terminated');
1861
1862 # Fire off blocking processes which are terminated via terminate().
1863 if oTestVm.isWindows():
1864 aArgs = [ sCmd, '/C', 'dir', '/S', 'C:\\Windows'];
1865 else:
1866 aArgs = [ sCmd ];
1867 reporter.log2('Starting blocking processes');
1868 aaProcs = [];
1869 for i in xrange(0, cStaleProcs):
1870 try:
1871 oCurProc = oGuestSession.processCreate(sCmd, aArgs if self.oTstDrv.fpApiVer >= 5.0 else aArgs[1:],
1872 [], [], 30 * 1000);
1873 # Note: Use a timeout in the call above for not letting the stale processes
1874 # hanging around forever. This can happen if the installed Guest Additions
1875 # do not support terminating guest processes.
1876 aaProcs.append(oCurProc);
1877 except:
1878 reporter.logXcpt('Creating blocking process failed:');
1879 fRc = False;
1880 break;
1881 if fRc:
1882 reporter.log2('Terminating blocking processes');
1883 for i in xrange(0, cStaleProcs):
1884 try:
1885 aaProcs[i].terminate();
1886 except: # Termination might not be supported, just skip and log it.
1887 reporter.logXcpt('Termination of blocking process failed, skipped:');
1888 cProcs = len(self.oTstDrv.oVBoxMgr.getArray(oGuestSession, 'processes'));
1889 if cProcs != (cStaleProcs * 2): # Still should be 20 processes because we terminated the 10 newest ones.
1890 reporter.error('Test failed: Got %d total processes, expected %d' % (cProcs, cStaleProcs * 2));
1891 fRc = False;
1892 cProcs = len(self.oTstDrv.oVBoxMgr.getArray(oGuestSession, 'processes'));
1893 reporter.log2('Final guest session processes count: %d' % (cProcs,));
1894 # Now try to close the session and see what happens.
1895 reporter.log2('Closing guest session ...');
1896 oGuestSession.close();
1897 except:
1898 reporter.logXcpt('Testing for stale processes failed:');
1899 fRc = False;
1900
1901 return (fRc, oTxsSession);
1902
1903 def testGuestCtrlExec(self, oSession, oTxsSession, oTestVm): # pylint: disable=too-many-locals,too-many-statements
1904 """
1905 Tests the basic execution feature.
1906 """
1907
1908 if oTestVm.isWindows():
1909 sImageOut = "C:\\windows\\system32\\cmd.exe";
1910 else:
1911 sImageOut = "/bin/ls";
1912
1913 # Use credential defaults.
1914 oCreds = tdCtxCreds();
1915 oCreds.applyDefaultsIfNotSet(oTestVm);
1916
1917 aaInvalid = [
1918 # Invalid parameters.
1919 [ tdTestExec(), tdTestResultExec() ],
1920 # Non-existent / invalid image.
1921 [ tdTestExec(sCmd = "non-existent"), tdTestResultExec() ],
1922 [ tdTestExec(sCmd = "non-existent2"), tdTestResultExec() ],
1923 # Use an invalid format string.
1924 [ tdTestExec(sCmd = "%$%%%&"), tdTestResultExec() ],
1925 # More stuff.
1926 [ tdTestExec(sCmd = u"ƒ‰‹ˆ÷‹¸"), tdTestResultExec() ],
1927 [ tdTestExec(sCmd = "???://!!!"), tdTestResultExec() ],
1928 [ tdTestExec(sCmd = "<>!\\"), tdTestResultExec() ],
1929 # Enable as soon as ERROR_BAD_DEVICE is implemented.
1930 #[ tdTestExec(sCmd = "CON", tdTestResultExec() ],
1931 ];
1932
1933 if oTestVm.isWindows():
1934 sVBoxControl = "C:\\Program Files\\Oracle\\VirtualBox Guest Additions\\VBoxControl.exe";
1935 aaExec = [
1936 # Basic executon.
1937 [ tdTestExec(sCmd = sImageOut, aArgs = [ sImageOut, '/C', 'dir', '/S', 'c:\\windows\\system32' ]),
1938 tdTestResultExec(fRc = True) ],
1939 [ tdTestExec(sCmd = sImageOut, aArgs = [ sImageOut, '/C', 'dir', '/S', 'c:\\windows\\system32\\kernel32.dll' ]),
1940 tdTestResultExec(fRc = True) ],
1941 [ tdTestExec(sCmd = sImageOut, aArgs = [ sImageOut, '/C', 'dir', '/S', 'c:\\windows\\system32\\nonexist.dll' ]),
1942 tdTestResultExec(fRc = True, iExitCode = 1) ],
1943 [ tdTestExec(sCmd = sImageOut, aArgs = [ sImageOut, '/C', 'dir', '/S', '/wrongparam' ]),
1944 tdTestResultExec(fRc = True, iExitCode = 1) ],
1945 # Paths with spaces.
1946 ## @todo Get path of installed Guest Additions. Later.
1947 [ tdTestExec(sCmd = sVBoxControl, aArgs = [ sVBoxControl, 'version' ]),
1948 tdTestResultExec(fRc = True) ],
1949 # StdOut.
1950 [ tdTestExec(sCmd = sImageOut, aArgs = [ sImageOut, '/C', 'dir', '/S', 'c:\\windows\\system32' ]),
1951 tdTestResultExec(fRc = True) ],
1952 [ tdTestExec(sCmd = sImageOut, aArgs = [ sImageOut, '/C', 'dir', '/S', 'stdout-non-existing' ]),
1953 tdTestResultExec(fRc = True, iExitCode = 1) ],
1954 # StdErr.
1955 [ tdTestExec(sCmd = sImageOut, aArgs = [ sImageOut, '/C', 'dir', '/S', 'c:\\windows\\system32' ]),
1956 tdTestResultExec(fRc = True) ],
1957 [ tdTestExec(sCmd = sImageOut, aArgs = [ sImageOut, '/C', 'dir', '/S', 'stderr-non-existing' ]),
1958 tdTestResultExec(fRc = True, iExitCode = 1) ],
1959 # StdOut + StdErr.
1960 [ tdTestExec(sCmd = sImageOut, aArgs = [ sImageOut, '/C', 'dir', '/S', 'c:\\windows\\system32' ]),
1961 tdTestResultExec(fRc = True) ],
1962 [ tdTestExec(sCmd = sImageOut, aArgs = [ sImageOut, '/C', 'dir', '/S', 'stdouterr-non-existing' ]),
1963 tdTestResultExec(fRc = True, iExitCode = 1) ]
1964 # FIXME: Failing tests.
1965 # Environment variables.
1966 # [ tdTestExec(sCmd = sImageOut, aArgs = [ sImageOut, '/C', 'set', 'TEST_NONEXIST' ],
1967 # tdTestResultExec(fRc = True, iExitCode = 1) ]
1968 # [ tdTestExec(sCmd = sImageOut, aArgs = [ sImageOut, '/C', 'set', 'windir' ],
1969 # fFlags = [ vboxcon.ProcessCreateFlag_WaitForStdOut, vboxcon.ProcessCreateFlag_WaitForStdErr ]),
1970 # tdTestResultExec(fRc = True, sBuf = 'windir=C:\\WINDOWS\r\n') ],
1971 # [ tdTestExec(sCmd = sImageOut, aArgs = [ sImageOut, '/C', 'set', 'TEST_FOO' ],
1972 # aEnv = [ 'TEST_FOO=BAR' ],
1973 # fFlags = [ vboxcon.ProcessCreateFlag_WaitForStdOut, vboxcon.ProcessCreateFlag_WaitForStdErr ]),
1974 # tdTestResultExec(fRc = True, sBuf = 'TEST_FOO=BAR\r\n') ],
1975 # [ tdTestExec(sCmd = sImageOut, aArgs = [ sImageOut, '/C', 'set', 'TEST_FOO' ],
1976 # aEnv = [ 'TEST_FOO=BAR', 'TEST_BAZ=BAR' ],
1977 # fFlags = [ vboxcon.ProcessCreateFlag_WaitForStdOut, vboxcon.ProcessCreateFlag_WaitForStdErr ]),
1978 # tdTestResultExec(fRc = True, sBuf = 'TEST_FOO=BAR\r\n') ]
1979
1980 ## @todo Create some files (or get files) we know the output size of to validate output length!
1981 ## @todo Add task which gets killed at some random time while letting the guest output something.
1982 ];
1983 elif oTestVm.isLinux():
1984 sVBoxControl = "/usr/bin/VBoxControl"; # Symlink
1985 aaExec = [
1986 # Basic executon.
1987 [ tdTestExec(sCmd = sImageOut, aArgs = [ sImageOut, '-R', '/etc' ]),
1988 tdTestResultExec(fRc = True, iExitCode = 1) ],
1989 [ tdTestExec(sCmd = sImageOut, aArgs = [ sImageOut, '/bin/sh' ]),
1990 tdTestResultExec(fRc = True) ],
1991 [ tdTestExec(sCmd = sImageOut, aArgs = [ sImageOut, '--wrong-parameter' ]),
1992 tdTestResultExec(fRc = True, iExitCode = 2) ],
1993 [ tdTestExec(sCmd = sImageOut, aArgs = [ sImageOut, '/non/existent' ]),
1994 tdTestResultExec(fRc = True, iExitCode = 2) ],
1995 # Paths with spaces.
1996 ## @todo Get path of installed Guest Additions. Later.
1997 [ tdTestExec(sCmd = sVBoxControl, aArgs = [ sVBoxControl, 'version' ]),
1998 tdTestResultExec(fRc = True) ],
1999 # StdOut.
2000 [ tdTestExec(sCmd = sImageOut, aArgs = [ sImageOut, '/etc' ]),
2001 tdTestResultExec(fRc = True) ],
2002 [ tdTestExec(sCmd = sImageOut, aArgs = [ sImageOut, 'stdout-non-existing' ]),
2003 tdTestResultExec(fRc = True, iExitCode = 2) ],
2004 # StdErr.
2005 [ tdTestExec(sCmd = sImageOut, aArgs = [ sImageOut, '/etc' ]),
2006 tdTestResultExec(fRc = True) ],
2007 [ tdTestExec(sCmd = sImageOut, aArgs = [ sImageOut, 'stderr-non-existing' ]),
2008 tdTestResultExec(fRc = True, iExitCode = 2) ],
2009 # StdOut + StdErr.
2010 [ tdTestExec(sCmd = sImageOut, aArgs = [ sImageOut, '/etc' ]),
2011 tdTestResultExec(fRc = True) ],
2012 [ tdTestExec(sCmd = sImageOut, aArgs = [ sImageOut, 'stdouterr-non-existing' ]),
2013 tdTestResultExec(fRc = True, iExitCode = 2) ]
2014 # FIXME: Failing tests.
2015 # Environment variables.
2016 # [ tdTestExec(sCmd = sImageOut, aArgs = [ sImageOut, '/C', 'set', 'TEST_NONEXIST' ],
2017 # tdTestResultExec(fRc = True, iExitCode = 1) ]
2018 # [ tdTestExec(sCmd = sImageOut, aArgs = [ sImageOut, '/C', 'set', 'windir' ],
2019 #
2020 # fFlags = [ vboxcon.ProcessCreateFlag_WaitForStdOut, vboxcon.ProcessCreateFlag_WaitForStdErr ]),
2021 # tdTestResultExec(fRc = True, sBuf = 'windir=C:\\WINDOWS\r\n') ],
2022 # [ tdTestExec(sCmd = sImageOut, aArgs = [ sImageOut, '/C', 'set', 'TEST_FOO' ],
2023 # aEnv = [ 'TEST_FOO=BAR' ],
2024 # fFlags = [ vboxcon.ProcessCreateFlag_WaitForStdOut, vboxcon.ProcessCreateFlag_WaitForStdErr ]),
2025 # tdTestResultExec(fRc = True, sBuf = 'TEST_FOO=BAR\r\n') ],
2026 # [ tdTestExec(sCmd = sImageOut, aArgs = [ sImageOut, '/C', 'set', 'TEST_FOO' ],
2027 # aEnv = [ 'TEST_FOO=BAR', 'TEST_BAZ=BAR' ],
2028 # fFlags = [ vboxcon.ProcessCreateFlag_WaitForStdOut, vboxcon.ProcessCreateFlag_WaitForStdErr ]),
2029 # tdTestResultExec(fRc = True, sBuf = 'TEST_FOO=BAR\r\n') ]
2030
2031 ## @todo Create some files (or get files) we know the output size of to validate output length!
2032 ## @todo Add task which gets killed at some random time while letting the guest output something.
2033 ];
2034
2035 # Build up the final test array for the first batch.
2036 aaTests = [];
2037 aaTests.extend(aaInvalid);
2038 if aaExec is not None:
2039 aaTests.extend(aaExec);
2040 fRc = True;
2041
2042 if fRc is False:
2043 return (fRc, oTxsSession);
2044
2045 #
2046 # First batch: One session per guest process.
2047 #
2048 reporter.log('One session per guest process ...');
2049 for (i, aTest) in enumerate(aaTests):
2050 oCurTest = aTest[0]; # tdTestExec, use an index, later.
2051 oCurRes = aTest[1]; # tdTestResultExec
2052 oCurTest.setEnvironment(oSession, oTxsSession, oTestVm);
2053 fRc, oCurGuestSession = oCurTest.createSession('testGuestCtrlExec: Test #%d' % (i,));
2054 if fRc is False:
2055 reporter.error('Test #%d failed: Could not create session' % (i,));
2056 break;
2057 fRc = self.gctrlExecDoTest(i, oCurTest, oCurRes, oCurGuestSession);
2058 if fRc is False:
2059 break;
2060 fRc = oCurTest.closeSession();
2061 if fRc is False:
2062 break;
2063
2064 reporter.log('Execution of all tests done, checking for stale sessions');
2065
2066 # No sessions left?
2067 if fRc is True:
2068 aSessions = self.oTstDrv.oVBoxMgr.getArray(oSession.o.console.guest, 'sessions');
2069 cSessions = len(aSessions);
2070 if cSessions != 0:
2071 reporter.error('Found %d stale session(s), expected 0:' % (cSessions,));
2072 for (i, aSession) in enumerate(aSessions):
2073 reporter.log('\tStale session #%d ("%s")' % (aSession.id, aSession.name));
2074 fRc = False;
2075
2076 if fRc is False:
2077 return (fRc, oTxsSession);
2078
2079 reporter.log('Now using one guest session for all tests ...');
2080
2081 #
2082 # Second batch: One session for *all* guest processes.
2083 #
2084 oGuest = oSession.o.console.guest;
2085 try:
2086 reporter.log('Creating session for all tests ...');
2087 oCurGuestSession = oGuest.createSession(oCreds.sUser, oCreds.sPassword, oCreds.sDomain,
2088 'testGuestCtrlExec: One session for all tests');
2089 try:
2090 aeWaitFor = [ vboxcon.GuestSessionWaitForFlag_Start ];
2091 waitResult = oCurGuestSession.waitForArray(aeWaitFor, 30 * 1000);
2092 if waitResult not in (vboxcon.GuestSessionWaitResult_Start, vboxcon.GuestSessionWaitResult_WaitFlagNotSupported):
2093 reporter.error('Session did not start successfully, returned wait result: %d' \
2094 % (waitResult));
2095 return (False, oTxsSession);
2096 reporter.log('Session successfully started');
2097 except:
2098 # Just log, don't assume an error here (will be done in the main loop then).
2099 reporter.logXcpt('Waiting for guest session to start failed:');
2100 return (False, oTxsSession);
2101 # Note: Not waiting for the guest session to start here
2102 # is intentional. This must be handled by the process execution
2103 # call then.
2104 for (i, aTest) in enumerate(aaTests):
2105 oCurTest = aTest[0]; # tdTestExec, use an index, later.
2106 oCurRes = aTest[1]; # tdTestResultExec
2107 oCurTest.setEnvironment(oSession, oTxsSession, oTestVm);
2108 fRc = self.gctrlExecDoTest(i, oCurTest, oCurRes, oCurGuestSession);
2109 if fRc is False:
2110 break;
2111 try:
2112 reporter.log2('Closing guest session ...');
2113 oCurGuestSession.close();
2114 oCurGuestSession = None;
2115 except:
2116 # Just log, don't assume an error here (will be done in the main loop then).
2117 reporter.logXcpt('Closing guest session failed:');
2118 fRc = False;
2119 except:
2120 reporter.logXcpt('Could not create one session:');
2121
2122 reporter.log('Execution of all tests done, checking for stale sessions again');
2123
2124 # No sessions left?
2125 if fRc is True:
2126 cSessions = len(self.oTstDrv.oVBoxMgr.getArray(oSession.o.console.guest, 'sessions'));
2127 if cSessions != 0:
2128 reporter.error('Found %d stale session(s), expected 0' % (cSessions,));
2129 fRc = False;
2130
2131 return (fRc, oTxsSession);
2132
2133 def threadForTestGuestCtrlSessionReboot(self, oGuestProcess):
2134 """
2135 Thread routine which waits for the stale guest process getting terminated (or some error)
2136 while the main test routine reboots the guest. It then compares the expected guest process result
2137 and logs an error if appropriate.
2138 """
2139 reporter.log('Waiting for stale process getting killed ...');
2140 waitResult = oGuestProcess.waitForArray([ vboxcon.ProcessWaitForFlag_Terminate ], 5 * 60 * 1000);
2141
2142 if waitResult == vboxcon.ProcessWaitResult_Terminate \
2143 and oGuestProcess.status == vboxcon.ProcessStatus_Down:
2144 reporter.log('Stale process was correctly terminated (status: down)');
2145 else:
2146 reporter.error('Got wrong stale process result: waitResult is %d, current process status is: %d' \
2147 % (waitResult, oGuestProcess.status));
2148
2149 def testGuestCtrlSessionReboot(self, oSession, oTxsSession, oTestVm): # pylint: disable=too-many-locals
2150 """
2151 Tests guest object notifications when a guest gets rebooted / shutdown.
2152 These notifications gets sent from the guest sessions in order to make API clients
2153 aware of guest session changes.
2154
2155 For that to test we create a stale guest process and trigger a reboot on the guest.
2156 """
2157
2158 if oTestVm.isWindows():
2159 sImage = "C:\\windows\\system32\\cmd.exe";
2160 else:
2161 sImage = "/bin/sh";
2162
2163 # Use credential defaults.
2164 oCreds = tdCtxCreds();
2165 oCreds.applyDefaultsIfNotSet(oTestVm);
2166
2167 fRc = True;
2168
2169 try:
2170 reporter.log('Creating session ...');
2171 oGuest = oSession.o.console.guest;
2172 oGuestSession = oGuest.createSession(oCreds.sUser, oCreds.sPassword, oCreds.sDomain, 'testGuestCtrlExecReboot');
2173 try:
2174 aeWaitFor = [ vboxcon.GuestSessionWaitForFlag_Start ];
2175 waitResult = oGuestSession.waitForArray(aeWaitFor, 30 * 1000);
2176 if waitResult not in (vboxcon.GuestSessionWaitResult_Start, vboxcon.GuestSessionWaitResult_WaitFlagNotSupported):
2177 reporter.error('Session did not start successfully, returned wait result: %d' \
2178 % (waitResult));
2179 return (False, oTxsSession);
2180 reporter.log('Session successfully started');
2181 except:
2182 # Just log, don't assume an error here (will be done in the main loop then).
2183 reporter.logXcpt('Waiting for guest session to start failed:');
2184 return (False, oTxsSession);
2185
2186 try:
2187 aArgs = [ sImage ];
2188 aEnv = [];
2189 fFlags = [];
2190 oGuestProcess = oGuestSession.processCreate(sImage,
2191 aArgs if self.oTstDrv.fpApiVer >= 5.0 else aArgs[1:], aEnv, fFlags,
2192 30 * 1000);
2193 waitResult = oGuestProcess.waitForArray([ vboxcon.ProcessWaitForFlag_Start ], 30 * 1000);
2194 reporter.log2('Starting process wait result returned: %d, current process status is: %d' \
2195 % (waitResult, oGuestProcess.status));
2196 except:
2197 reporter.logXcpt('Creating stale process failed:');
2198 fRc = False;
2199
2200 if fRc:
2201 reporter.log('Creating reboot thread ...');
2202 oThreadReboot = threading.Thread(target = self.threadForTestGuestCtrlSessionReboot,
2203 args=(oGuestProcess,),
2204 name=('threadForTestGuestCtrlSessionReboot'));
2205 oThreadReboot.setDaemon(True);
2206 oThreadReboot.start();
2207
2208 reporter.log('Waiting for reboot ....');
2209 time.sleep(15);
2210 reporter.log('Rebooting guest and reconnecting TxS');
2211
2212 (oSession, oTxsSession) = self.oTstDrv.txsRebootAndReconnectViaTcp(oSession, oTxsSession, cMsTimeout = 3 * 60000);
2213
2214 reporter.log('Waiting for thread to finish ...');
2215 oThreadReboot.join();
2216 try:
2217 reporter.log2('Closing guest session ...');
2218 oGuestSession.close();
2219 oGuestSession = None;
2220 except:
2221 # Just log, don't assume an error here (will be done in the main loop then).
2222 reporter.logXcpt('Closing guest session failed:');
2223 fRc = False;
2224 except:
2225 reporter.logXcpt('Could not create one session:');
2226
2227 return (fRc, oTxsSession);
2228
2229 def testGuestCtrlExecErrorLevel(self, oSession, oTxsSession, oTestVm):
2230 """
2231 Tests handling of error levels from started guest processes.
2232 """
2233
2234 if oTestVm.isWindows():
2235 sImage = "C:\\windows\\system32\\cmd.exe";
2236 else:
2237 sImage = "/bin/sh";
2238
2239 aaTests = [];
2240 if oTestVm.isWindows():
2241 aaTests.extend([
2242 # Simple.
2243 [ tdTestExec(sCmd = sImage, aArgs = [ sImage, '/C', 'wrongcommand' ]),
2244 tdTestResultExec(fRc = True, iExitCode = 1) ],
2245 [ tdTestExec(sCmd = sImage, aArgs = [ sImage, '/C', 'exit', '22' ]),
2246 tdTestResultExec(fRc = True, iExitCode = 22) ],
2247 [ tdTestExec(sCmd = sImage, aArgs = [ sImage, '/C', 'set', 'ERRORLEVEL=234' ]),
2248 tdTestResultExec(fRc = True, iExitCode = 0) ],
2249 [ tdTestExec(sCmd = sImage, aArgs = [ sImage, '/C', 'echo', '%WINDIR%' ]),
2250 tdTestResultExec(fRc = True, iExitCode = 0) ],
2251 [ tdTestExec(sCmd = sImage, aArgs = [ sImage, '/C', 'set', 'ERRORLEVEL=0' ]),
2252 tdTestResultExec(fRc = True, iExitCode = 0) ],
2253 [ tdTestExec(sCmd = sImage, aArgs = [ sImage, '/C', 'dir', 'c:\\windows\\system32' ]),
2254 tdTestResultExec(fRc = True, iExitCode = 0) ],
2255 [ tdTestExec(sCmd = sImage, aArgs = [ sImage, '/C', 'dir', 'c:\\windows\\system32\\kernel32.dll' ]),
2256 tdTestResultExec(fRc = True, iExitCode = 0) ],
2257 [ tdTestExec(sCmd = sImage, aArgs = [ sImage, '/C', 'dir', 'c:\\nonexisting-file' ]),
2258 tdTestResultExec(fRc = True, iExitCode = 1) ],
2259 [ tdTestExec(sCmd = sImage, aArgs = [ sImage, '/C', 'dir', 'c:\\nonexisting-dir\\' ]),
2260 tdTestResultExec(fRc = True, iExitCode = 1) ]
2261 # FIXME: Failing tests.
2262 # With stdout.
2263 # [ tdTestExec(sCmd = sImage, aArgs = [ sImage, '/C', 'dir', 'c:\\windows\\system32' ],
2264 # fFlags = [ vboxcon.ProcessCreateFlag_WaitForStdOut ]),
2265 # tdTestResultExec(fRc = True, iExitCode = 0) ],
2266 # [ tdTestExec(sCmd = sImage, aArgs = [ sImage, '/C', 'dir', 'c:\\nonexisting-file' ],
2267 # fFlags = [ vboxcon.ProcessCreateFlag_WaitForStdOut ]),
2268 # tdTestResultExec(fRc = True, iExitCode = 1) ],
2269 # [ tdTestExec(sCmd = sImage, aArgs = [ sImage, '/C', 'dir', 'c:\\nonexisting-dir\\' ],
2270 # fFlags = [ vboxcon.ProcessCreateFlag_WaitForStdOut ]),
2271 # tdTestResultExec(fRc = True, iExitCode = 1) ],
2272 # With stderr.
2273 # [ tdTestExec(sCmd = sImage, aArgs = [ sImage, '/C', 'dir', 'c:\\windows\\system32' ],
2274 # fFlags = [ vboxcon.ProcessCreateFlag_WaitForStdErr ]),
2275 # tdTestResultExec(fRc = True, iExitCode = 0) ],
2276 # [ tdTestExec(sCmd = sImage, aArgs = [ sImage, '/C', 'dir', 'c:\\nonexisting-file' ],
2277 # fFlags = [ vboxcon.ProcessCreateFlag_WaitForStdErr ]),
2278 # tdTestResultExec(fRc = True, iExitCode = 1) ],
2279 # [ tdTestExec(sCmd = sImage, aArgs = [ sImage, '/C', 'dir', 'c:\\nonexisting-dir\\' ],
2280 # fFlags = [ vboxcon.ProcessCreateFlag_WaitForStdErr ]),
2281 # tdTestResultExec(fRc = True, iExitCode = 1) ],
2282 # With stdout/stderr.
2283 # [ tdTestExec(sCmd = sImage, aArgs = [ sImage, '/C', 'dir', 'c:\\windows\\system32' ],
2284 # fFlags = [ vboxcon.ProcessCreateFlag_WaitForStdOut, vboxcon.ProcessCreateFlag_WaitForStdErr ]),
2285 # tdTestResultExec(fRc = True, iExitCode = 0) ],
2286 # [ tdTestExec(sCmd = sImage, aArgs = [ sImage, '/C', 'dir', 'c:\\nonexisting-file' ],
2287 # fFlags = [ vboxcon.ProcessCreateFlag_WaitForStdOut, vboxcon.ProcessCreateFlag_WaitForStdErr ]),
2288 # tdTestResultExec(fRc = True, iExitCode = 1) ],
2289 # [ tdTestExec(sCmd = sImage, aArgs = [ sImage, '/C', 'dir', 'c:\\nonexisting-dir\\' ],
2290 # fFlags = [ vboxcon.ProcessCreateFlag_WaitForStdOut, vboxcon.ProcessCreateFlag_WaitForStdErr ]),
2291 # tdTestResultExec(fRc = True, iExitCode = 1) ]
2292 ## @todo Test stdin!
2293 ]);
2294 elif oTestVm.isLinux():
2295 aaTests.extend([
2296 # Simple.
2297 [ tdTestExec(sCmd = sImage, aArgs = [ sImage, '-c', 'wrongcommand' ]),
2298 tdTestResultExec(fRc = True, iExitCode = 127) ],
2299 [ tdTestExec(sCmd = sImage, aArgs = [ sImage, '-c', 'exit 22' ]),
2300 tdTestResultExec(fRc = True, iExitCode = 22) ],
2301 [ tdTestExec(sCmd = sImage, aArgs = [ sImage, '-c', 'echo $PWD' ]),
2302 tdTestResultExec(fRc = True, iExitCode = 0) ],
2303 [ tdTestExec(sCmd = sImage, aArgs = [ sImage, '-c', 'export MY_ERRORLEVEL=0' ]),
2304 tdTestResultExec(fRc = True, iExitCode = 0) ],
2305 [ tdTestExec(sCmd = sImage, aArgs = [ sImage, '-c', 'ls /etc' ]),
2306 tdTestResultExec(fRc = True, iExitCode = 0) ],
2307 [ tdTestExec(sCmd = sImage, aArgs = [ sImage, '-c', 'ls /bin/sh' ]),
2308 tdTestResultExec(fRc = True, iExitCode = 0) ],
2309 [ tdTestExec(sCmd = sImage, aArgs = [ sImage, '-c', 'ls /non/existing/file' ]),
2310 tdTestResultExec(fRc = True, iExitCode = 2) ],
2311 [ tdTestExec(sCmd = sImage, aArgs = [ sImage, '-c', 'ls /non/existing/dir/' ]),
2312 tdTestResultExec(fRc = True, iExitCode = 2) ]
2313 ]);
2314
2315 fRc = True;
2316 for (i, aTest) in enumerate(aaTests):
2317 oCurTest = aTest[0]; # tdTestExec, use an index, later.
2318 oCurRes = aTest[1]; # tdTestResult
2319 oCurTest.setEnvironment(oSession, oTxsSession, oTestVm);
2320 fRc, oCurGuestSession = oCurTest.createSession('testGuestCtrlExecErrorLevel: Test #%d' % (i,));
2321 if fRc is False:
2322 reporter.error('Test #%d failed: Could not create session' % (i,));
2323 break;
2324 fRc = self.gctrlExecDoTest(i, oCurTest, oCurRes, oCurGuestSession);
2325 oCurTest.closeSession();
2326 if fRc is False:
2327 break;
2328
2329 return (fRc, oTxsSession);
2330
2331 def testGuestCtrlExecTimeout(self, oSession, oTxsSession, oTestVm):
2332 """
2333 Tests handling of timeouts of started guest processes.
2334 """
2335
2336 if oTestVm.isWindows():
2337 sImage = "C:\\windows\\system32\\cmd.exe";
2338 else:
2339 sImage = "/bin/sh";
2340
2341 # Use credential defaults.
2342 oCreds = tdCtxCreds();
2343 oCreds.applyDefaultsIfNotSet(oTestVm);
2344
2345 fRc = True;
2346 try:
2347 oGuest = oSession.o.console.guest;
2348 oGuestSession = oGuest.createSession(oCreds.sUser, oCreds.sPassword, oCreds.sDomain, "testGuestCtrlExecTimeout");
2349 oGuestSession.waitForArray([ vboxcon.GuestSessionWaitForFlag_Start ], 30 * 1000);
2350 # Create a process which never terminates and should timeout when
2351 # waiting for termination.
2352 try:
2353 curProc = oGuestSession.processCreate(sImage, [sImage,] if self.oTstDrv.fpApiVer >= 5.0 else [], \
2354 [], [], 30 * 1000);
2355 reporter.log('Waiting for process 1 being started ...');
2356 waitRes = curProc.waitForArray([ vboxcon.ProcessWaitForFlag_Start ], 30 * 1000);
2357 if waitRes != vboxcon.ProcessWaitResult_Start:
2358 reporter.error('Waiting for process 1 to start failed, got status %d');
2359 fRc = False;
2360 if fRc:
2361 reporter.log('Waiting for process 1 to time out within 1ms ...');
2362 waitRes = curProc.waitForArray([ vboxcon.ProcessWaitForFlag_Terminate ], 1);
2363 if waitRes != vboxcon.ProcessWaitResult_Timeout:
2364 reporter.error('Waiting for process 1 did not time out when it should (1)');
2365 fRc = False;
2366 else:
2367 reporter.log('Waiting for process 1 timed out (1), good');
2368 if fRc:
2369 reporter.log('Waiting for process 1 to time out within 5000ms ...');
2370 waitRes = curProc.waitForArray([ vboxcon.ProcessWaitForFlag_Terminate ], 5000);
2371 if waitRes != vboxcon.ProcessWaitResult_Timeout:
2372 reporter.error('Waiting for process 1 did not time out when it should, got wait result %d' % (waitRes,));
2373 fRc = False;
2374 else:
2375 reporter.log('Waiting for process 1 timed out (5000), good');
2376 ## @todo Add curProc.terminate() as soon as it's implemented.
2377 except:
2378 reporter.errorXcpt('Exception for process 1:');
2379 fRc = False;
2380 # Create a lengthly running guest process which will be killed by VBoxService on the
2381 # guest because it ran out of execution time (5 seconds).
2382 if fRc:
2383 try:
2384 curProc = oGuestSession.processCreate(sImage, [sImage,] if self.oTstDrv.fpApiVer >= 5.0 else [], \
2385 [], [], 5 * 1000);
2386 reporter.log('Waiting for process 2 being started ...');
2387 waitRes = curProc.waitForArray([ vboxcon.ProcessWaitForFlag_Start ], 30 * 1000);
2388 if waitRes != vboxcon.ProcessWaitResult_Start:
2389 reporter.error('Waiting for process 1 to start failed, got status %d');
2390 fRc = False;
2391 if fRc:
2392 reporter.log('Waiting for process 2 to get killed because it ran out of execution time ...');
2393 waitRes = curProc.waitForArray([ vboxcon.ProcessWaitForFlag_Terminate ], 30 * 1000);
2394 if waitRes != vboxcon.ProcessWaitResult_Timeout:
2395 reporter.error('Waiting for process 2 did not time out when it should, got wait result %d' \
2396 % (waitRes,));
2397 fRc = False;
2398 if fRc:
2399 reporter.log('Waiting for process 2 indicated an error, good');
2400 if curProc.status != vboxcon.ProcessStatus_TimedOutKilled:
2401 reporter.error('Status of process 2 wrong; excepted %d, got %d' \
2402 % (vboxcon.ProcessStatus_TimedOutKilled, curProc.status));
2403 fRc = False;
2404 else:
2405 reporter.log('Status of process 2 correct (%d)' % (vboxcon.ProcessStatus_TimedOutKilled,));
2406 ## @todo Add curProc.terminate() as soon as it's implemented.
2407 except:
2408 reporter.errorXcpt('Exception for process 2:');
2409 fRc = False;
2410 oGuestSession.close();
2411 except:
2412 reporter.errorXcpt('Could not handle session:');
2413 fRc = False;
2414
2415 return (fRc, oTxsSession);
2416
2417 def testGuestCtrlDirCreate(self, oSession, oTxsSession, oTestVm):
2418 """
2419 Tests creation of guest directories.
2420 """
2421
2422 if oTestVm.isWindows():
2423 sScratch = "C:\\Temp\\vboxtest\\testGuestCtrlDirCreate\\";
2424 else:
2425 sScratch = "/tmp/testGuestCtrlDirCreate/";
2426
2427 aaTests = [];
2428 aaTests.extend([
2429 # Invalid stuff.
2430 [ tdTestDirCreate(sDirectory = '' ), tdTestResult() ],
2431 # More unusual stuff.
2432 [ tdTestDirCreate(sDirectory = '..\\..\\' ), tdTestResult() ],
2433 [ tdTestDirCreate(sDirectory = '../../' ), tdTestResult() ],
2434 [ tdTestDirCreate(sDirectory = 'z:\\' ), tdTestResult() ],
2435 [ tdTestDirCreate(sDirectory = '\\\\uncrulez\\foo' ), tdTestResult() ],
2436 # Creating directories.
2437 [ tdTestDirCreate(sDirectory = sScratch ), tdTestResult() ],
2438 [ tdTestDirCreate(sDirectory = os.path.join(sScratch, 'foo\\bar\\baz'),
2439 fFlags = [ vboxcon.DirectoryCreateFlag_Parents ] ),
2440 tdTestResult(fRc = True) ],
2441 [ tdTestDirCreate(sDirectory = os.path.join(sScratch, 'foo\\bar\\baz'),
2442 fFlags = [ vboxcon.DirectoryCreateFlag_Parents ] ),
2443 tdTestResult(fRc = True) ],
2444 # Long (+ random) stuff.
2445 [ tdTestDirCreate(sDirectory = os.path.join(sScratch,
2446 "".join(random.choice(string.ascii_lowercase) for i in xrange(32))) ),
2447 tdTestResult(fRc = True) ],
2448 [ tdTestDirCreate(sDirectory = os.path.join(sScratch,
2449 "".join(random.choice(string.ascii_lowercase) for i in xrange(128))) ),
2450 tdTestResult(fRc = True) ],
2451 # Following two should fail on Windows (paths too long). Both should timeout.
2452 [ tdTestDirCreate(sDirectory = os.path.join(sScratch,
2453 "".join(random.choice(string.ascii_lowercase) for i in xrange(255))) ),
2454 tdTestResult(fRc = not oTestVm.isWindows()) ],
2455 [ tdTestDirCreate(sDirectory = os.path.join(sScratch,
2456 "".join(random.choice(string.ascii_lowercase) for i in xrange(255))) ),
2457 tdTestResult(fRc = not oTestVm.isWindows()) ]
2458 ]);
2459
2460 fRc = True;
2461 for (i, aTest) in enumerate(aaTests):
2462 oCurTest = aTest[0]; # tdTestExec, use an index, later.
2463 oCurRes = aTest[1]; # tdTestResult
2464 reporter.log('Testing #%d, sDirectory="%s" ...' % (i, oCurTest.sDirectory));
2465 oCurTest.setEnvironment(oSession, oTxsSession, oTestVm);
2466 fRc, oCurGuestSession = oCurTest.createSession('testGuestCtrlDirCreate: Test #%d' % (i,));
2467 if fRc is False:
2468 reporter.error('Test #%d failed: Could not create session' % (i,));
2469 break;
2470 fRc = self.gctrlCreateDir(oCurTest, oCurRes, oCurGuestSession);
2471 oCurTest.closeSession();
2472 if fRc is False:
2473 reporter.error('Test #%d failed' % (i,));
2474 fRc = False;
2475 break;
2476
2477 return (fRc, oTxsSession);
2478
2479 def testGuestCtrlDirCreateTemp(self, oSession, oTxsSession, oTestVm): # pylint: disable=too-many-locals
2480 """
2481 Tests creation of temporary directories.
2482 """
2483
2484 aaTests = [];
2485 if oTestVm.isWindows():
2486 aaTests.extend([
2487 # Invalid stuff.
2488 [ tdTestDirCreateTemp(sDirectory = ''), tdTestResult() ],
2489 [ tdTestDirCreateTemp(sDirectory = 'C:\\Windows', fMode = 1234), tdTestResult() ],
2490 [ tdTestDirCreateTemp(sTemplate = '', sDirectory = 'C:\\Windows', fMode = 1234), tdTestResult() ],
2491 [ tdTestDirCreateTemp(sTemplate = 'xXx', sDirectory = 'C:\\Windows', fMode = 0o700), tdTestResult() ],
2492 [ tdTestDirCreateTemp(sTemplate = 'xxx', sDirectory = 'C:\\Windows', fMode = 0o700), tdTestResult() ],
2493 # More unusual stuff.
2494 [ tdTestDirCreateTemp(sTemplate = 'foo', sDirectory = 'z:\\'), tdTestResult() ],
2495 [ tdTestDirCreateTemp(sTemplate = 'foo', sDirectory = '\\\\uncrulez\\foo'), tdTestResult() ],
2496 # Non-existing stuff.
2497 [ tdTestDirCreateTemp(sTemplate = 'bar', sDirectory = 'c:\\Apps\\nonexisting\\foo'), tdTestResult() ],
2498 # FIXME: Failing test. Non Windows path
2499 # [ tdTestDirCreateTemp(sTemplate = 'bar', sDirectory = '/tmp/non/existing'), tdTestResult() ]
2500 ]);
2501 elif oTestVm.isLinux():
2502 aaTests.extend([
2503 # Invalid stuff.
2504 [ tdTestDirCreateTemp(sDirectory = ''), tdTestResult() ],
2505 [ tdTestDirCreateTemp(sDirectory = '/etc', fMode = 1234) ],
2506 [ tdTestDirCreateTemp(sTemplate = '', sDirectory = '/etc', fMode = 1234), tdTestResult() ],
2507 [ tdTestDirCreateTemp(sTemplate = 'xXx', sDirectory = '/etc', fMode = 0o700), tdTestResult() ],
2508 [ tdTestDirCreateTemp(sTemplate = 'xxx', sDirectory = '/etc', fMode = 0o700), tdTestResult() ],
2509 # More unusual stuff.
2510 [ tdTestDirCreateTemp(sTemplate = 'foo', sDirectory = 'z:\\'), tdTestResult() ],
2511 [ tdTestDirCreateTemp(sTemplate = 'foo', sDirectory = '\\\\uncrulez\\foo'), tdTestResult() ],
2512 # Non-existing stuff.
2513 [ tdTestDirCreateTemp(sTemplate = 'bar', sDirectory = '/non/existing'), tdTestResult() ],
2514 ]);
2515
2516 # FIXME: Failing tests.
2517 # aaTests.extend([
2518 # Non-secure variants.
2519 # [ tdTestDirCreateTemp(sTemplate = 'XXX',
2520 # sDirectory = sScratch),
2521 # tdTestResult(fRc = True) ],
2522 # [ tdTestDirCreateTemp(sTemplate = 'XXX',
2523 # sDirectory = sScratch),
2524 # tdTestResult(fRc = True) ],
2525 # [ tdTestDirCreateTemp(sTemplate = 'X',
2526 # sDirectory = sScratch),
2527 # tdTestResult(fRc = True) ],
2528 # [ tdTestDirCreateTemp(sTemplate = 'X',
2529 # sDirectory = sScratch),
2530 # tdTestResult(fRc = True) ],
2531 # [ tdTestDirCreateTemp(sTemplate = 'XXX',
2532 # sDirectory = sScratch,
2533 # fMode = 0o700),
2534 # tdTestResult(fRc = True) ],
2535 # [ tdTestDirCreateTemp(sTemplate = 'XXX',
2536 # sDirectory = sScratch,
2537 # fMode = 0o700),
2538 # tdTestResult(fRc = True) ],
2539 # [ tdTestDirCreateTemp(sTemplate = 'XXX',
2540 # sDirectory = sScratch,
2541 # fMode = 0o755),
2542 # tdTestResult(fRc = True) ],
2543 # [ tdTestDirCreateTemp(sTemplate = 'XXX',
2544 # sDirectory = sScratch,
2545 # fMode = 0o755),
2546 # tdTestResult(fRc = True) ],
2547 # Secure variants.
2548 # [ tdTestDirCreateTemp(sTemplate = 'XXX',
2549 # sDirectory = sScratch, fSecure = True),
2550 # tdTestResult(fRc = True) ],
2551 # [ tdTestDirCreateTemp(sTemplate = 'XXX',
2552 # sDirectory = sScratch, fSecure = True),
2553 # tdTestResult(fRc = True) ],
2554 # [ tdTestDirCreateTemp(sTemplate = 'XXX',
2555 # sDirectory = sScratch, fSecure = True),
2556 # tdTestResult(fRc = True) ],
2557 # [ tdTestDirCreateTemp(sTemplate = 'XXX',
2558 # sDirectory = sScratch, fSecure = True),
2559 # tdTestResult(fRc = True) ],
2560 # [ tdTestDirCreateTemp(sTemplate = 'XXX',
2561 # sDirectory = sScratch,
2562 # fSecure = True, fMode = 0o700),
2563 # tdTestResult(fRc = True) ],
2564 # [ tdTestDirCreateTemp(sTemplate = 'XXX',
2565 # sDirectory = sScratch,
2566 # fSecure = True, fMode = 0o700),
2567 # tdTestResult(fRc = True) ],
2568 # [ tdTestDirCreateTemp(sTemplate = 'XXX',
2569 # sDirectory = sScratch,
2570 # fSecure = True, fMode = 0o755),
2571 # tdTestResult(fRc = True) ],
2572 # [ tdTestDirCreateTemp(sTemplate = 'XXX',
2573 # sDirectory = sScratch,
2574 # fSecure = True, fMode = 0o755),
2575 # tdTestResult(fRc = True) ],
2576 # Random stuff.
2577 # [ tdTestDirCreateTemp(
2578 # sTemplate = "XXX-".join(random.choice(string.ascii_lowercase) for i in xrange(32)),
2579 # sDirectory = sScratch,
2580 # fSecure = True, fMode = 0o755),
2581 # tdTestResult(fRc = True) ],
2582 # [ tdTestDirCreateTemp(sTemplate = "".join('X' for i in xrange(32)),
2583 # sDirectory = sScratch,
2584 # fSecure = True, fMode = 0o755),
2585 # tdTestResult(fRc = True) ],
2586 # [ tdTestDirCreateTemp(sTemplate = "".join('X' for i in xrange(128)),
2587 # sDirectory = sScratch,
2588 # fSecure = True, fMode = 0o755),
2589 # tdTestResult(fRc = True) ]
2590 # ]);
2591
2592 fRc = True;
2593 for (i, aTest) in enumerate(aaTests):
2594 oCurTest = aTest[0]; # tdTestExec, use an index, later.
2595 oCurRes = aTest[1]; # tdTestResult
2596 reporter.log('Testing #%d, sTemplate="%s", fMode=%#o, path="%s", secure="%s" ...' %
2597 (i, oCurTest.sTemplate, oCurTest.fMode, oCurTest.sDirectory, oCurTest.fSecure));
2598 oCurTest.setEnvironment(oSession, oTxsSession, oTestVm);
2599 fRc, oCurGuestSession = oCurTest.createSession('testGuestCtrlDirCreateTemp: Test #%d' % (i,));
2600 if fRc is False:
2601 reporter.error('Test #%d failed: Could not create session' % (i,));
2602 break;
2603 sDirTemp = "";
2604 try:
2605 sDirTemp = oCurGuestSession.directoryCreateTemp(oCurTest.sTemplate, oCurTest.fMode,
2606 oCurTest.sDirectory, oCurTest.fSecure);
2607 except:
2608 if oCurRes.fRc is True:
2609 reporter.errorXcpt('Creating temp directory "%s" failed:' % (oCurTest.sDirectory,));
2610 fRc = False;
2611 break;
2612 else:
2613 reporter.logXcpt('Creating temp directory "%s" failed expectedly, skipping:' % (oCurTest.sDirectory,));
2614 oCurTest.closeSession();
2615 if sDirTemp != "":
2616 reporter.log2('Temporary directory is: %s' % (sDirTemp,));
2617 if self.oTstDrv.fpApiVer >= 5.0:
2618 fExists = oCurGuestSession.directoryExists(sDirTemp, False);
2619 else:
2620 fExists = oCurGuestSession.directoryExists(sDirTemp);
2621 if fExists is False:
2622 reporter.error('Test #%d failed: Temporary directory "%s" does not exists' % (i, sDirTemp));
2623 fRc = False;
2624 break;
2625 return (fRc, oTxsSession);
2626
2627 def testGuestCtrlDirRead(self, oSession, oTxsSession, oTestVm): # pylint: disable=too-many-locals
2628 """
2629 Tests opening and reading (enumerating) guest directories.
2630 """
2631
2632 aaTests = [];
2633 if oTestVm.isWindows():
2634 aaTests.extend([
2635 # Invalid stuff.
2636 [ tdTestDirRead(sDirectory = ''), tdTestResultDirRead(fRc = False) ],
2637 [ tdTestDirRead(sDirectory = 'C:\\Windows', fFlags = [ 1234 ]), tdTestResultDirRead() ],
2638 [ tdTestDirRead(sDirectory = 'C:\\Windows', sFilter = '*.foo'), tdTestResultDirRead() ],
2639 # More unusual stuff.
2640 [ tdTestDirRead(sDirectory = 'z:\\'), tdTestResultDirRead() ],
2641 [ tdTestDirRead(sDirectory = '\\\\uncrulez\\foo'), tdTestResultDirRead() ],
2642 # Non-existing stuff.
2643 [ tdTestDirRead(sDirectory = 'c:\\Apps\\nonexisting'), tdTestResultDirRead() ],
2644 [ tdTestDirRead(sDirectory = 'c:\\Apps\\testDirRead'), tdTestResultDirRead() ]
2645 ]);
2646
2647 if oTestVm.sVmName.startswith('tst-xpsp2'):
2648 aaTests.extend([
2649 # Reading directories.
2650 [ tdTestDirRead(sDirectory = '../../Windows/Media'),
2651 tdTestResultDirRead(fRc = True, numFiles = 38) ],
2652 [ tdTestDirRead(sDirectory = 'c:\\Windows\\Help'),
2653 tdTestResultDirRead(fRc = True, numDirs = 13, numFiles = 574) ],
2654 [ tdTestDirRead(sDirectory = 'c:\\Windows\\Web'),
2655 tdTestResultDirRead(fRc = True, numDirs = 3, numFiles = 49) ]
2656 ]);
2657 elif oTestVm.isLinux():
2658 aaTests.extend([
2659 # Invalid stuff.
2660 [ tdTestDirRead(sDirectory = ''), tdTestResultDirRead() ],
2661 [ tdTestDirRead(sDirectory = '/etc', fFlags = [ 1234 ]), tdTestResultDirRead() ],
2662 [ tdTestDirRead(sDirectory = '/etc', sFilter = '*.foo'), tdTestResultDirRead() ],
2663 # More unusual stuff.
2664 [ tdTestDirRead(sDirectory = 'z:/'), tdTestResultDirRead() ],
2665 [ tdTestDirRead(sDirectory = '\\\\uncrulez\\foo'), tdTestResultDirRead() ],
2666 # Non-existing stuff.
2667 [ tdTestDirRead(sDirectory = '/etc/non/existing'), tdTestResultDirRead() ]
2668 ]);
2669
2670 fRc = True;
2671 for (i, aTest) in enumerate(aaTests):
2672 oCurTest = aTest[0]; # tdTestExec, use an index, later.
2673 oCurRes = aTest[1]; # tdTestResult
2674 reporter.log('Testing #%d, dir="%s" ...' % (i, oCurTest.sDirectory));
2675 oCurTest.setEnvironment(oSession, oTxsSession, oTestVm);
2676 fRc, oCurGuestSession = oCurTest.createSession('testGuestCtrlDirRead: Test #%d' % (i,));
2677 if fRc is False:
2678 reporter.error('Test #%d failed: Could not create session' % (i,));
2679 break;
2680 (fRc2, cDirs, cFiles) = self.gctrlReadDir(oCurTest, oCurRes, oCurGuestSession);
2681 oCurTest.closeSession();
2682 reporter.log2('Test #%d: Returned %d directories, %d files total' % (i, cDirs, cFiles));
2683 if fRc2 is oCurRes.fRc:
2684 if fRc2 is True:
2685 if oCurRes.numFiles != cFiles:
2686 reporter.error('Test #%d failed: Got %d files, expected %d' % (i, cFiles, oCurRes.numFiles));
2687 fRc = False;
2688 if oCurRes.numDirs != cDirs:
2689 reporter.error('Test #%d failed: Got %d directories, expected %d' % (i, cDirs, oCurRes.numDirs));
2690 fRc = False;
2691 else:
2692 reporter.error('Test #%d failed: Got %s, expected %s' % (i, fRc2, oCurRes.fRc));
2693 fRc = False;
2694
2695 return (fRc, oTxsSession);
2696
2697 def testGuestCtrlFileRemove(self, oSession, oTxsSession, oTestVm):
2698 """
2699 Tests removing guest files.
2700 """
2701
2702 ## @todo r=bird: This fails on windows 7 RTM. Just create a stupid file and delete it again,
2703 # this chord.wav stuff is utter nonsense.
2704 if oTestVm.isWindows():
2705 sFileToDelete = "c:\\Windows\\Media\\chord.wav";
2706 else:
2707 sFileToDelete = "/home/vbox/.profile";
2708
2709 aaTests = [];
2710 if oTestVm.isWindows():
2711 aaTests.extend([
2712 # Invalid stuff.
2713 [ tdTestFileRemove(sFile = ''), tdTestResult() ],
2714 [ tdTestFileRemove(sFile = 'C:\\Windows'), tdTestResult() ],
2715 # More unusual stuff.
2716 [ tdTestFileRemove(sFile = 'z:\\'), tdTestResult() ],
2717 [ tdTestFileRemove(sFile = '\\\\uncrulez\\foo'), tdTestResult() ],
2718 # Non-existing stuff.
2719 [ tdTestFileRemove(sFile = 'c:\\Apps\\nonexisting'), tdTestResult() ],
2720 # Try to delete system files.
2721 [ tdTestFileRemove(sFile = 'c:\\pagefile.sys'), tdTestResult() ],
2722 [ tdTestFileRemove(sFile = 'c:\\Windows\\kernel32.sys'), tdTestResult() ] ## r=bird: it's in \system32\ ...
2723 ]);
2724
2725 if oTestVm.sKind == "WindowsXP":
2726 aaTests.extend([
2727 # Try delete some unimportant media stuff.
2728 [ tdTestFileRemove(sFile = 'c:\\Windows\\Media\\chimes.wav'), tdTestResult(fRc = True) ],
2729 # Second attempt should fail.
2730 [ tdTestFileRemove(sFile = 'c:\\Windows\\Media\\chimes.wav'), tdTestResult() ]
2731 ]);
2732 elif oTestVm.isLinux():
2733 aaTests.extend([
2734 # Invalid stuff.
2735 [ tdTestFileRemove(sFile = ''), tdTestResult() ],
2736 [ tdTestFileRemove(sFile = 'C:\\Windows'), tdTestResult() ],
2737 # More unusual stuff.
2738 [ tdTestFileRemove(sFile = 'z:/'), tdTestResult() ],
2739 [ tdTestFileRemove(sFile = '//uncrulez/foo'), tdTestResult() ],
2740 # Non-existing stuff.
2741 [ tdTestFileRemove(sFile = '/non/existing'), tdTestResult() ],
2742 # Try to delete system files.
2743 [ tdTestFileRemove(sFile = '/etc'), tdTestResult() ],
2744 [ tdTestFileRemove(sFile = '/bin/sh'), tdTestResult() ]
2745 ]);
2746
2747 aaTests.extend([
2748 # Try delete some unimportant stuff.
2749 [ tdTestFileRemove(sFile = sFileToDelete), tdTestResult(fRc = True) ],
2750 # Second attempt should fail.
2751 [ tdTestFileRemove(sFile = sFileToDelete), tdTestResult() ]
2752 ]);
2753
2754 fRc = True;
2755 for (i, aTest) in enumerate(aaTests):
2756 oCurTest = aTest[0]; # tdTestExec, use an index, later.
2757 oCurRes = aTest[1]; # tdTestResult
2758 reporter.log('Testing #%d, file="%s" ...' % (i, oCurTest.sFile));
2759 oCurTest.setEnvironment(oSession, oTxsSession, oTestVm);
2760 fRc, oCurGuestSession = oCurTest.createSession('testGuestCtrlFileRemove: Test #%d' % (i,));
2761 if fRc is False:
2762 reporter.error('Test #%d failed: Could not create session' % (i,));
2763 break;
2764 try:
2765 if self.oTstDrv.fpApiVer >= 5.0:
2766 oCurGuestSession.fsObjRemove(oCurTest.sFile);
2767 else:
2768 oCurGuestSession.fileRemove(oCurTest.sFile);
2769 except:
2770 if oCurRes.fRc is True:
2771 reporter.errorXcpt('Removing file "%s" failed:' % (oCurTest.sFile,));
2772 fRc = False;
2773 break;
2774 else:
2775 reporter.logXcpt('Removing file "%s" failed expectedly, skipping:' % (oCurTest.sFile,));
2776 oCurTest.closeSession();
2777 return (fRc, oTxsSession);
2778
2779 def testGuestCtrlFileStat(self, oSession, oTxsSession, oTestVm): # pylint: disable=too-many-locals
2780 """
2781 Tests querying file information through stat.
2782 """
2783
2784 # Basic stuff, existing stuff.
2785 aoTests = [
2786 tdTestSessionEx([ tdStepStatDir('.'),
2787 tdStepStatDir('..'),
2788 ]),
2789 ];
2790 if oTestVm.isWindows():
2791 aoTests += [ tdTestSessionEx([ tdStepStatDir('C:\\Windows'),
2792 tdStepStatDir('C:\\Windows\\System32'),
2793 tdStepStatDir('C:\\Windows\\System32\\'),
2794 tdStepStatDir('C:\\Windows\\System32\\.'),
2795 tdStepStatDir('C:\\Windows\\System32\\.\\'),
2796 tdStepStatDir('C:\\Windows\\System32\\..'),
2797 tdStepStatDir('C:\\Windows\\System32\\..\\'),
2798 tdStepStatDir('C:\\Windows\\System32\\..\\\\'),
2799 tdStepStatDir('C:\\Windows\\System32\\\\..\\\\'),
2800 tdStepStatDir('C:/Windows/System32'),
2801 tdStepStatDir('C:/Windows/System32/'),
2802 tdStepStatDir('c:/winDowS/sYsTeM32/'),
2803 tdStepStatDir('C:/Windows/System32/.'),
2804 tdStepStatDir('C:/Windows/System32/./'),
2805 tdStepStatDir('C:/Windows/System32/..'),
2806 tdStepStatDir('C:/Windows/System32/../'),
2807 tdStepStatDir('C:/Windows/System32/..//'),
2808 tdStepStatDir('C:/Windows/System32//..//'),
2809 tdStepStatFile('C:\\Windows\\System32\\kernel32.dll'),
2810 tdStepStatFile('C:/Windows/System32/kernel32.dll')
2811 ]) ];
2812 elif oTestVm.isOS2():
2813 aoTests += [ tdTestSessionEx([ tdStepStatDir('C:\\OS2'),
2814 tdStepStatDir('C:\\OS2\\DLL'),
2815 tdStepStatDir('C:\\OS2\\DLL\\'),
2816 tdStepStatDir('C:/OS2/DLL'),
2817 tdStepStatDir('c:/OS2/DLL'),
2818 tdStepStatDir('c:/OS2/DLL/'),
2819 tdStepStatFile('C:\\CONFIG.SYS'),
2820 tdStepStatFile('C:\\OS2\\DLL\\DOSCALL1.DLL'),
2821 ]) ];
2822 else: # generic unix.
2823 aoTests += [ tdTestSessionEx([ tdStepStatDir('/'),
2824 tdStepStatDir('///'),
2825 tdStepStatDir('/usr/bin/.'),
2826 tdStepStatDir('/usr/bin/./'),
2827 tdStepStatDir('/usr/bin/..'),
2828 tdStepStatDir('/usr/bin/../'),
2829 tdStepStatFile('/bin/ls'),
2830 tdStepStatFile('/bin/cp'),
2831 tdStepStatFile('/bin/date'),
2832 ]) ];
2833 # None existing stuff.
2834 if oTestVm.isWindows() or oTestVm.isOS2():
2835 aoTests += [ tdTestSessionEx([ tdStepStatFileNotFound('C:\\NoSuchFileOrDirectory', ),
2836 tdStepStatPathNotFound('C:\\NoSuchDirectory\\'),
2837 tdStepStatPathNotFound('C:/NoSuchDirectory/'),
2838 tdStepStatPathNotFound('C:\\NoSuchDirectory\\.'),
2839 tdStepStatPathNotFound('C:/NoSuchDirectory/.'),
2840 tdStepStatPathNotFound('C:\\NoSuchDirectory\\NoSuchFileOrDirectory'),
2841 tdStepStatPathNotFound('C:/NoSuchDirectory/NoSuchFileOrDirectory'),
2842 tdStepStatPathNotFound('C:/NoSuchDirectory/NoSuchFileOrDirectory/'),
2843 tdStepStatPathNotFound('N:\\'), # ASSUMES nothing mounted on N:!
2844 tdStepStatPathNotFound('\\\\NoSuchUncServerName\\NoSuchShare'),
2845 ]) ];
2846 else: # generic unix.
2847 aoTests += [ tdTestSessionEx([ tdStepStatFileNotFound('/NoSuchFileOrDirectory', ),
2848 tdStepStatFileNotFound('/bin/NoSuchFileOrDirectory'),
2849 tdStepStatPathNotFound('/NoSuchDirectory/'),
2850 tdStepStatPathNotFound('/NoSuchDirectory/.'),
2851 ]) ];
2852 # Invalid parameter check.
2853 aoTests += [ tdTestSessionEx([ tdStepStat('', vbox.ComError.E_INVALIDARG), ]), ];
2854
2855 # Some test VM specific tests.
2856 if oTestVm.sVmName.startswith('tst-xpsp2'):
2857 aoTests += [ tdTestSessionEx([ tdStepStatFileSize('c:\\Windows\\system32\\kernel32.dll', 983552), ]) ];
2858
2859 #
2860 # Execute the tests.
2861 #
2862 return tdTestSessionEx.executeListTestSessions(aoTests, self.oTstDrv, oSession, oTxsSession, oTestVm, 'FsStat');
2863
2864 def testGuestCtrlFileRead(self, oSession, oTxsSession, oTestVm): # pylint: disable=too-many-locals
2865 """
2866 Tests reading from guest files.
2867 """
2868
2869 if oTxsSession.syncMkDir('${SCRATCH}/testGuestCtrlFileRead') is False:
2870 reporter.error('Could not create scratch directory on guest');
2871 return (False, oTxsSession);
2872
2873 aaTests = [];
2874 aaTests.extend([
2875 # Invalid stuff.
2876 [ tdTestFileReadWrite(cbToReadWrite = 0), tdTestResultFileReadWrite() ],
2877 [ tdTestFileReadWrite(sFile = ''), tdTestResultFileReadWrite() ],
2878 [ tdTestFileReadWrite(sFile = 'non-existing.file'), tdTestResultFileReadWrite() ],
2879 # Wrong open mode.
2880 [ tdTestFileReadWrite(sFile = 'non-existing.file', sOpenMode = 'rt', sDisposition = 'oe'),
2881 tdTestResultFileReadWrite() ],
2882 [ tdTestFileReadWrite(sFile = '\\\\uncrulez\\non-existing.file', sOpenMode = 'tr', sDisposition = 'oe'),
2883 tdTestResultFileReadWrite() ],
2884 [ tdTestFileReadWrite(sFile = '../../non-existing.file', sOpenMode = 'wr', sDisposition = 'oe'),
2885 tdTestResultFileReadWrite() ],
2886 # Wrong disposition.
2887 [ tdTestFileReadWrite(sFile = 'non-existing.file', sOpenMode = 'r', sDisposition = 'e'),
2888 tdTestResultFileReadWrite() ],
2889 [ tdTestFileReadWrite(sFile = '\\\\uncrulez\\non-existing.file', sOpenMode = 'r', sDisposition = 'o'),
2890 tdTestResultFileReadWrite() ],
2891 [ tdTestFileReadWrite(sFile = '../../non-existing.file', sOpenMode = 'r', sDisposition = 'c'),
2892 tdTestResultFileReadWrite() ],
2893 # Opening non-existing file when it should exist.
2894 [ tdTestFileReadWrite(sFile = 'non-existing.file', sOpenMode = 'r', sDisposition = 'oe'),
2895 tdTestResultFileReadWrite() ],
2896 [ tdTestFileReadWrite(sFile = '\\\\uncrulez\\non-existing.file', sOpenMode = 'r', sDisposition = 'oe'),
2897 tdTestResultFileReadWrite() ],
2898 [ tdTestFileReadWrite(sFile = '../../non-existing.file', sOpenMode = 'r', sDisposition = 'oe'),
2899 tdTestResultFileReadWrite() ]
2900 ]);
2901
2902 if oTestVm.isWindows():
2903 aaTests.extend([
2904 # Create a file which must not exist (but it hopefully does).
2905 [ tdTestFileReadWrite(sFile = 'C:\\Windows\\System32\\calc.exe', sOpenMode = 'w', sDisposition = 'ce'),
2906 tdTestResultFileReadWrite() ],
2907 # Open a file which must exist.
2908 [ tdTestFileReadWrite(sFile = 'C:\\Windows\\System32\\kernel32.dll', sOpenMode = 'r', sDisposition = 'oe'),
2909 tdTestResultFileReadWrite(fRc = True) ],
2910 # Try truncating a file which already is opened with a different sharing mode (and thus should fail).
2911 [ tdTestFileReadWrite(sFile = 'C:\\Windows\\System32\\kernel32.dll', sOpenMode = 'w', sDisposition = 'ot'),
2912 tdTestResultFileReadWrite() ]
2913 ]);
2914
2915 # Note: tst-xppro has other contents in eula.txt.
2916 if oTestVm.sVmName.startswith('tst-xpsp2'):
2917 aaTests.extend([
2918 # Reading from beginning.
2919 [ tdTestFileReadWrite(sFile = 'C:\\Windows\\System32\\eula.txt',
2920 sOpenMode = 'r', sDisposition = 'oe', cbToReadWrite = 33),
2921 tdTestResultFileReadWrite(fRc = True, abBuf = 'Microsoft(r) Windows(r) XP Profes',
2922 cbProcessed = 33, offFile = 33) ],
2923 # Reading from offset.
2924 [ tdTestFileReadWrite(sFile = 'C:\\Windows\\System32\\eula.txt',
2925 sOpenMode = 'r', sDisposition = 'oe', offFile = 17769, cbToReadWrite = 31),
2926 tdTestResultFileReadWrite(fRc = True, abBuf = 'only with the HARDWARE. If\x0d\x0a ',
2927 cbProcessed = 31, offFile = 17769 + 31) ]
2928 ]);
2929 elif oTestVm.isLinux():
2930 aaTests.extend([
2931 # Create a file which must not exist (but it hopefully does).
2932 [ tdTestFileReadWrite(sFile = '/etc/issue', sOpenMode = 'w', sDisposition = 'ce'),
2933 tdTestResultFileReadWrite() ],
2934 # Open a file which must exist.
2935 [ tdTestFileReadWrite(sFile = '/etc/issue', sOpenMode = 'r', sDisposition = 'oe'),
2936 tdTestResultFileReadWrite(fRc = True) ],
2937 # Try truncating a file which already is opened with a different sharing mode (and thus should fail).
2938 [ tdTestFileReadWrite(sFile = '/etc/issue', sOpenMode = 'w', sDisposition = 'ot'),
2939 tdTestResultFileReadWrite() ]
2940 ]);
2941
2942 fRc = True;
2943 for (i, aTest) in enumerate(aaTests):
2944 oCurTest = aTest[0]; # tdTestFileReadWrite, use an index, later.
2945 oCurRes = aTest[1]; # tdTestResult
2946 reporter.log('Testing #%d, sFile="%s", cbToReadWrite=%d, sOpenMode="%s", sDisposition="%s", offFile=%d ...'
2947 % (i, oCurTest.sFile, oCurTest.cbToReadWrite, oCurTest.sOpenMode,
2948 oCurTest.sDisposition, oCurTest.offFile));
2949 oCurTest.setEnvironment(oSession, oTxsSession, oTestVm);
2950 fRc, oCurGuestSession = oCurTest.createSession('testGuestCtrlFileRead: Test #%d' % (i,));
2951 if fRc is False:
2952 reporter.error('Test #%d failed: Could not create session' % (i,));
2953 break;
2954 try:
2955 fRc2 = True;
2956 if oCurTest.offFile > 0: # The offset parameter is gone.
2957 if self.oTstDrv.fpApiVer >= 5.0:
2958 curFile = oCurGuestSession.fileOpenEx(oCurTest.sFile, oCurTest.getAccessMode(), oCurTest.getOpenAction(),
2959 oCurTest.getSharingMode(), oCurTest.fCreationMode, []);
2960 curFile.seek(oCurTest.offFile, vboxcon.FileSeekOrigin_Begin);
2961 else:
2962 curFile = oCurGuestSession.fileOpenEx(oCurTest.sFile, oCurTest.sOpenMode, oCurTest.sDisposition,
2963 oCurTest.sSharingMode, oCurTest.fCreationMode, oCurTest.offFile);
2964 curOffset = long(curFile.offset);
2965 resOffset = long(oCurTest.offFile);
2966 if curOffset != resOffset:
2967 reporter.error('Test #%d failed: Initial offset on open does not match: Got %d, expected %d'
2968 % (i, curOffset, resOffset));
2969 fRc2 = False;
2970 else:
2971 if self.oTstDrv.fpApiVer >= 5.0:
2972 curFile = oCurGuestSession.fileOpen(oCurTest.sFile, oCurTest.getAccessMode(), oCurTest.getOpenAction(),
2973 oCurTest.fCreationMode);
2974 else:
2975 curFile = oCurGuestSession.fileOpen(oCurTest.sFile, oCurTest.sOpenMode, oCurTest.sDisposition,
2976 oCurTest.fCreationMode);
2977 if fRc2 and oCurTest.cbToReadWrite > 0:
2978 ## @todo Split this up in 64K reads. Later.
2979 ## @todo Test timeouts.
2980 aBufRead = curFile.read(oCurTest.cbToReadWrite, 30 * 1000);
2981 if oCurRes.cbProcessed > 0 \
2982 and oCurRes.cbProcessed != len(aBufRead):
2983 reporter.error('Test #%d failed: Read buffer length does not match: Got %d, expected %d'
2984 % (i, len(aBufRead), oCurRes.cbProcessed));
2985 fRc2 = False;
2986 if fRc2:
2987 if oCurRes.abBuf is not None \
2988 and not utils.areBytesEqual(oCurRes.abBuf, aBufRead):
2989 reporter.error('Test #%d failed: Got buffer:\n"%s" (%d bytes, type %s)\n'
2990 'Expected buffer:\n"%s" (%d bytes, type %s)'
2991 % (i, map(hex, map(ord, aBufRead)), len(aBufRead), type(aBufRead),
2992 map(hex, map(ord, oCurRes.abBuf)), len(oCurRes.abBuf), type(oCurRes.abBuf),));
2993 reporter.error('Test #%d failed: Got buffer:\n"%s"\nExpected buffer:\n"%s"'
2994 % (i, aBufRead, oCurRes.abBuf));
2995 fRc2 = False;
2996 # Test final offset.
2997 curOffset = long(curFile.offset);
2998 resOffset = long(oCurRes.offFile);
2999 if curOffset != resOffset:
3000 reporter.error('Test #%d failed: Final offset does not match: Got %d, expected %d' \
3001 % (i, curOffset, resOffset));
3002 fRc2 = False;
3003 curFile.close();
3004
3005 if fRc2 != oCurRes.fRc:
3006 reporter.error('Test #%d failed: Got %s, expected %s' % (i, fRc2, oCurRes.fRc));
3007 fRc = False;
3008
3009 except:
3010 reporter.logXcpt('Opening "%s" failed:' % (oCurTest.sFile,));
3011 fRc = False;
3012
3013 oCurTest.closeSession();
3014
3015 return (fRc, oTxsSession);
3016
3017 def testGuestCtrlFileWrite(self, oSession, oTxsSession, oTestVm): # pylint: disable=too-many-locals
3018 """
3019 Tests writing to guest files.
3020 """
3021
3022 if oTestVm.isWindows():
3023 sScratch = "C:\\Temp\\vboxtest\\testGuestCtrlFileWrite\\";
3024 else:
3025 sScratch = "/tmp/";
3026
3027 if oTxsSession.syncMkDir('${SCRATCH}/testGuestCtrlFileWrite') is False:
3028 reporter.error('Could not create scratch directory on guest');
3029 return (False, oTxsSession);
3030
3031 aaTests = [];
3032
3033 cbScratchBuf = random.randint(1, 4096);
3034 abScratchBuf = os.urandom(cbScratchBuf);
3035 aaTests.extend([
3036 # Write to a non-existing file.
3037 [ tdTestFileReadWrite(sFile = sScratch + 'testGuestCtrlFileWrite.txt',
3038 sOpenMode = 'w+', sDisposition = 'ce', cbToReadWrite = cbScratchBuf, abBuf = abScratchBuf),
3039 tdTestResultFileReadWrite(fRc = True, abBuf = abScratchBuf, cbProcessed = cbScratchBuf, offFile = cbScratchBuf) ],
3040 ]);
3041
3042 aScratchBuf2 = os.urandom(cbScratchBuf);
3043 aaTests.extend([
3044 # Append the same amount of data to the just created file.
3045 [ tdTestFileReadWrite(sFile = sScratch + 'testGuestCtrlFileWrite.txt',
3046 sOpenMode = 'w+', sDisposition = 'oa', cbToReadWrite = cbScratchBuf,
3047 offFile = cbScratchBuf, abBuf = aScratchBuf2),
3048 tdTestResultFileReadWrite(fRc = True, abBuf = aScratchBuf2, cbProcessed = cbScratchBuf,
3049 offFile = cbScratchBuf * 2) ],
3050 ]);
3051
3052 fRc = True;
3053 for (i, aTest) in enumerate(aaTests):
3054 oCurTest = aTest[0]; # tdTestFileReadWrite, use an index, later.
3055 oCurRes = aTest[1]; # tdTestResult
3056 reporter.log('Testing #%d, sFile="%s", cbToReadWrite=%d, sOpenMode="%s", sDisposition="%s", offFile=%d ...'
3057 % (i, oCurTest.sFile, oCurTest.cbToReadWrite, oCurTest.sOpenMode,
3058 oCurTest.sDisposition, oCurTest.offFile,));
3059 oCurTest.setEnvironment(oSession, oTxsSession, oTestVm);
3060 fRc, oCurGuestSession = oCurTest.createSession('testGuestCtrlFileWrite: Test #%d' % (i,));
3061 if fRc is False:
3062 reporter.error('Test #%d failed: Could not create session' % (i,));
3063 break;
3064
3065 try:
3066 if oCurTest.offFile > 0: # The offset parameter is gone.
3067 if self.oTstDrv.fpApiVer >= 5.0:
3068 curFile = oCurGuestSession.fileOpenEx(oCurTest.sFile, oCurTest.getAccessMode(), oCurTest.getOpenAction(),
3069 oCurTest.getSharingMode(), oCurTest.fCreationMode, []);
3070 curFile.seek(oCurTest.offFile, vboxcon.FileSeekOrigin_Begin);
3071 else:
3072 curFile = oCurGuestSession.fileOpenEx(oCurTest.sFile, oCurTest.sOpenMode, oCurTest.sDisposition,
3073 oCurTest.sSharingMode, oCurTest.fCreationMode, oCurTest.offFile);
3074 curOffset = long(curFile.offset);
3075 resOffset = long(oCurTest.offFile);
3076 if curOffset != resOffset:
3077 reporter.error('Test #%d failed: Initial offset on open does not match: Got %d, expected %d' \
3078 % (i, curOffset, resOffset));
3079 fRc = False;
3080 else:
3081 if self.oTstDrv.fpApiVer >= 5.0:
3082 curFile = oCurGuestSession.fileOpenEx(oCurTest.sFile, oCurTest.getAccessMode(), oCurTest.getOpenAction(),
3083 oCurTest.getSharingMode(), oCurTest.fCreationMode, []);
3084 else:
3085 curFile = oCurGuestSession.fileOpen(oCurTest.sFile, oCurTest.sOpenMode, oCurTest.sDisposition,
3086 oCurTest.fCreationMode);
3087 if fRc and oCurTest.cbToReadWrite > 0:
3088 reporter.log("File '%s' opened" % oCurTest.sFile);
3089 ## @todo Split this up in 64K writes. Later.
3090 ## @todo Test timeouts.
3091 cBytesWritten = curFile.write(array('b', oCurTest.abBuf), 30 * 1000);
3092 if oCurRes.cbProcessed > 0 \
3093 and oCurRes.cbProcessed != cBytesWritten:
3094 reporter.error('Test #%d failed: Written buffer length does not match: Got %d, expected %d' \
3095 % (i, cBytesWritten, oCurRes.cbProcessed));
3096 fRc = False;
3097 if fRc:
3098 # Verify written content by seeking back to the initial offset and
3099 # re-read & compare the written data.
3100 try:
3101 if self.oTstDrv.fpApiVer >= 5.0:
3102 curFile.seek(-(oCurTest.cbToReadWrite), vboxcon.FileSeekOrigin_Current);
3103 else:
3104 curFile.seek(-(oCurTest.cbToReadWrite), vboxcon.FileSeekType_Current);
3105 except:
3106 reporter.logXcpt('Seeking back to initial write position failed:');
3107 fRc = False;
3108 if fRc and long(curFile.offset) != oCurTest.offFile:
3109 reporter.error('Test #%d failed: Initial write position does not match current position, ' \
3110 'got %d, expected %d' % (i, long(curFile.offset), oCurTest.offFile));
3111 fRc = False;
3112 if fRc:
3113 aBufRead = curFile.read(oCurTest.cbToReadWrite, 30 * 1000);
3114 if len(aBufRead) != oCurTest.cbToReadWrite:
3115 reporter.error('Test #%d failed: Got buffer length %d, expected %d' \
3116 % (i, len(aBufRead), oCurTest.cbToReadWrite));
3117 fRc = False;
3118 if fRc \
3119 and oCurRes.abBuf is not None \
3120 and bytes(oCurRes.abBuf) != bytes(aBufRead):
3121 reporter.error('Test #%d failed: Read back buffer (%d bytes) does not match ' \
3122 'written content (%d bytes)' % (i, len(aBufRead), len(aBufRead)));
3123
3124 curFile.close();
3125
3126 # Download written file from guest.
3127 aGstFiles = [];
3128 aGstFiles.append(oCurTest.sFile.replace('\\', '/'));
3129 self.oTstDrv.txsDownloadFiles(oSession, oTxsSession, aGstFiles, fIgnoreErrors = True);
3130
3131 # Create files with buffer contents and upload those for later (manual) inspection.
3132 oCurTest.uploadLogData(self.oTstDrv, oCurRes.abBuf, ('testGuestCtrlWriteTest%d-BufExcepted' % i),
3133 ('Test #%d: Expected buffer' % i));
3134 oCurTest.uploadLogData(self.oTstDrv, aBufRead, ('testGuestCtrlWriteTest%d-BufGot' % i),
3135 ('Test #%d: Got buffer' % i));
3136 fRc = False;
3137 # Test final offset.
3138 curOffset = long(curFile.offset);
3139 resOffset = long(oCurRes.offFile);
3140 if curOffset != resOffset:
3141 reporter.error('Test #%d failed: Final offset does not match: Got %d, expected %d' \
3142 % (i, curOffset, resOffset));
3143 fRc = False;
3144 if curFile.status == vboxcon.FileStatus_Open:
3145 curFile.close();
3146 reporter.log("File '%s' closed" % oCurTest.sFile);
3147 except:
3148 reporter.logXcpt('Opening "%s" failed:' % (oCurTest.sFile,));
3149 fRc = False;
3150
3151 oCurTest.closeSession();
3152
3153 if fRc != oCurRes.fRc:
3154 reporter.error('Test #%d failed: Got %s, expected %s' % (i, fRc, oCurRes.fRc));
3155 fRc = False;
3156 break;
3157
3158 return (fRc, oTxsSession);
3159
3160 def testGuestCtrlCopyTo(self, oSession, oTxsSession, oTestVm):
3161 """
3162 Tests copying files from host to the guest.
3163 """
3164
3165 if oTestVm.isWindows():
3166 sScratchGst = "C:\\Temp\\vboxtest\\testGuestCtrlCopyTo\\";
3167 sScratchGstNotExist = "C:\\does-not-exist\\";
3168 sScratchGstInvalid = "?*|invalid-name?*|";
3169 else:
3170 sScratchGst = "/tmp/"; ## @todo Use "${SCRATCH}/testGuestCtrlCopyTo" as soon as TXS CHMOD is implemented.
3171 sScratchGstNotExist = "/tmp/does-not-exist/";
3172 sScratchGstInvalid = "/";
3173
3174 if oTxsSession.syncMkDir('${SCRATCH}/testGuestCtrlCopyTo') is False:
3175 reporter.error('Could not create scratch directory on guest');
3176 return (False, oTxsSession);
3177
3178 ## @todo r=klaus It's not good to use files with unpredictable size
3179 # for testing. Causes all sorts of weird failures as things grow,
3180 # exceeding the free space of the test VMs. Especially as this used
3181 # the very big (and quickly growing) validation kit ISO originally.
3182 sTestFileBig = self.oTstDrv.getFullResourceName('5.3/guestctrl/50mb_rnd.dat');
3183 if not os.path.isfile(sTestFileBig):
3184 sTestFileBig = self.oTstDrv.getGuestAdditionsIso();
3185 if sTestFileBig == '' or not os.path.isfile(sTestFileBig):
3186 sTestFileBig = self.oTstDrv.sVBoxValidationKitIso;
3187 if os.path.isfile(sTestFileBig):
3188 reporter.log('Test file for big copy found at: %s' % (sTestFileBig,));
3189 else:
3190 reporter.log('Warning: Test file for big copy not found -- some tests might fail');
3191
3192 aaTests = [];
3193 aaTests.extend([
3194 # Destination missing.
3195 [ tdTestCopyTo(sSrc = ''), tdTestResult() ],
3196 [ tdTestCopyTo(sSrc = '/placeholder', fFlags = [ 80 ] ), tdTestResult() ],
3197 # Source missing.
3198 [ tdTestCopyTo(sDst = ''), tdTestResult() ],
3199 [ tdTestCopyTo(sDst = '/placeholder', fFlags = [ 80 ] ), tdTestResult() ],
3200 # Testing DirectoryCopyFlag flags.
3201 [ tdTestCopyTo(sSrc = sTestFileBig, sDst = sScratchGstInvalid, fFlags = [ 80 ] ), tdTestResult() ],
3202 # Testing FileCopyFlag flags.
3203 [ tdTestCopyTo(sSrc = sTestFileBig, sDst = sScratchGstInvalid, fFlags = [ 80 ] ), tdTestResult() ],
3204 # Nothing to copy (source and/or destination is empty).
3205 [ tdTestCopyTo(sSrc = 'z:\\'), tdTestResult() ],
3206 [ tdTestCopyTo(sSrc = '\\\\uncrulez\\foo'), tdTestResult() ],
3207 [ tdTestCopyTo(sSrc = 'non-exist', sDst = os.path.join(sScratchGst, 'non-exist.dll')), tdTestResult() ]
3208 ]);
3209
3210 #
3211 # Single file handling.
3212 #
3213 if self.oTstDrv.fpApiVer > 5.2:
3214 aaTests.extend([
3215 [ tdTestCopyTo(sSrc = sTestFileBig, sDst = sScratchGstInvalid), tdTestResult() ],
3216 [ tdTestCopyTo(sSrc = sTestFileBig, sDst = sScratchGstNotExist), tdTestResult() ],
3217 [ tdTestCopyTo(sSrc = sTestFileBig, sDst = sScratchGstNotExist), tdTestResult() ],
3218 [ tdTestCopyTo(sSrc = sTestFileBig, sDst = os.path.join(sScratchGstNotExist, 'renamedfile.dll')),
3219 tdTestResult() ],
3220 [ tdTestCopyTo(sSrc = sTestFileBig, sDst = os.path.join(sScratchGst, 'HostGABig.dat')),
3221 tdTestResult(fRc = True) ],
3222 [ tdTestCopyTo(sSrc = sTestFileBig, sDst = os.path.join(sScratchGst, 'HostGABig.dat')),
3223 tdTestResult(fRc = True) ],
3224 # Note: Copying files into directories via Main is supported only in versions > 5.2.
3225 # Destination is a directory.
3226 [ tdTestCopyTo(sSrc = sTestFileBig, sDst = sScratchGst),
3227 tdTestResult(fRc = True) ],
3228 # Copy over file again into same directory (overwrite).
3229 [ tdTestCopyTo(sSrc = sTestFileBig, sDst = sScratchGst),
3230 tdTestResult(fRc = True) ]
3231 ]);
3232
3233 if oTestVm.isWindows():
3234 aaTests.extend([
3235 # Copy the same file over to the guest, but this time store the file into the former
3236 # file's ADS (Alternate Data Stream). Only works on Windows, of course.
3237 [ tdTestCopyTo(sSrc = sTestFileBig, sDst = os.path.join(sScratchGst, 'HostGABig.dat:ADS-Test')),
3238 tdTestResult(fRc = True) ]
3239 ]);
3240
3241 #
3242 # Directory handling.
3243 #
3244 ## @todo r=michaln disabled completely, can fill up the guest disk or fail without giving a reason
3245 if self.oTstDrv.fpApiVer > 6.0: # Copying directories via Main is supported only in versions > 5.2.
3246 if self.oTstDrv.sHost == "win":
3247 sSystemRoot = os.getenv('SystemRoot', 'C:\\Windows')
3248 aaTests.extend([
3249 # Copying directories with contain files we don't have read access to.
3250 ## @todo r=klaus disabled, because this can fill up the guest disk, making other tests fail,
3251 ## additionally it's not really clear if this fails reliably on all Windows versions, even
3252 ## the old ones like XP with a "proper" administrator.
3253 #[ tdTestCopyTo(sSrc = os.path.join(sSystemRoot, 'security'),
3254 # sDst = sScratchGst, fFlags = [ vboxcon.DirectoryCopyFlag_CopyIntoExisting ]),
3255 #
3256 # Copying directories with regular files.
3257 [ tdTestCopyTo(sSrc = os.path.join(sSystemRoot, 'Help'),
3258 sDst = sScratchGst, fFlags = [ vboxcon.DirectoryCopyFlag_CopyIntoExisting ]),
3259 tdTestResult(fRc = True) ]
3260 ]);
3261
3262 fRc = True;
3263 for (i, aTest) in enumerate(aaTests):
3264 oCurTest = aTest[0]; # tdTestExec, use an index, later.
3265 oCurRes = aTest[1]; # tdTestResult
3266 reporter.log('Testing #%d, sSrc=%s, sDst=%s, fFlags=%s ...' % \
3267 (i, oCurTest.sSrc, oCurTest.sDst, oCurTest.fFlags));
3268 oCurTest.setEnvironment(oSession, oTxsSession, oTestVm);
3269 fRc, oCurGuestSession = oCurTest.createSession('testGuestCtrlCopyTo: Test #%d' % (i,));
3270 if fRc is False:
3271 reporter.error('Test #%d failed: Could not create session' % (i,));
3272 break;
3273
3274 fRc2 = False;
3275 if os.path.isdir(oCurTest.sSrc):
3276 try:
3277 oCurProgress = oCurGuestSession.directoryCopyToGuest(oCurTest.sSrc, oCurTest.sDst, oCurTest.fFlags);
3278 if oCurProgress is not None:
3279 oProgress = vboxwrappers.ProgressWrapper(oCurProgress, self.oTstDrv.oVBoxMgr, self.oTstDrv, \
3280 "gctrlDirCopyTo");
3281 try:
3282 oProgress.wait();
3283 if oProgress.isSuccess():
3284 fRc2 = True;
3285 else:
3286 oProgress.logResult(fIgnoreErrors = True);
3287 except:
3288 reporter.logXcpt('Waiting exception for sSrc="%s", sDst="%s":' % (oCurTest.sSrc, oCurTest.sDst));
3289 else:
3290 reporter.error('No progress object returned');
3291 except:
3292 reporter.logXcpt('directoryCopyToGuest exception for sSrc="%s", sDst="%s":' % (oCurTest.sSrc, oCurTest.sDst));
3293 else:
3294 fRc2 = self.gctrlCopyFileTo(oCurGuestSession, oCurTest.sSrc, oCurTest.sDst, oCurTest.fFlags);
3295
3296 oCurTest.closeSession();
3297
3298 if fRc2 is oCurRes.fRc:
3299 ## @todo Verify the copied results (size, checksum?).
3300 pass;
3301 else:
3302 reporter.error('Test #%d failed: Got %s, expected %s' % (i, fRc2, oCurRes.fRc));
3303 fRc = False;
3304 break;
3305
3306 return (fRc, oTxsSession);
3307
3308 def testGuestCtrlCopyFrom(self, oSession, oTxsSession, oTestVm): # pylint: disable=too-many-locals
3309 """
3310 Tests copying files from guest to the host.
3311 """
3312
3313 if oTestVm.isWindows():
3314 sPathSep = "\\";
3315 sSrcDirExisting = "C:\\Windows\\Web";
3316 sSrcFileExisting = "C:\\Windows\\system32\\ole32.dll";
3317 else:
3318 sPathSep = "/";
3319 sSrcDirExisting = "/bin";
3320 sSrcFileExisting = "/etc/issue";
3321
3322 sScratchHst = os.path.join(self.oTstDrv.sScratchPath, "testGctrlCopyFrom");
3323
3324 if self.oTstDrv.sHost == "win":
3325 sScratchHstNotExist = sScratchHst + "\\does-not-exist\\";
3326 sScratchHstNotExistChain = sScratchHst + "\\does\\not\\exist\\";
3327 sScratchHstInvalid = "?*|invalid-name?*|";
3328 else:
3329 sScratchHstNotExist = sScratchHst + "/does-not-exist/";
3330 sScratchHstNotExistChain = sScratchHst + "/does/not/exist/";
3331 sScratchHstInvalid = "/";
3332
3333 try:
3334 os.makedirs(sScratchHst);
3335 except OSError as e:
3336 if e.errno != errno.EEXIST:
3337 reporter.error('Failed: Unable to create scratch directory \"%s\"' % (sScratchHst,));
3338 return (False, oTxsSession);
3339 reporter.log('Scratch path is: %s' % (sScratchHst,));
3340
3341 aaTests = [];
3342 aaTests.extend([
3343 # Destination missing.
3344 [ tdTestCopyFrom(sSrc = ''), tdTestResult() ],
3345 [ tdTestCopyFrom(sSrc = 'Something', fFlags = [ 80 ] ), tdTestResult() ],
3346 # Source missing.
3347 [ tdTestCopyFrom(sDst = ''), tdTestResult() ],
3348 [ tdTestCopyFrom(sDst = 'Something', fFlags = [ 80 ] ), tdTestResult() ],
3349 # Testing DirectoryCopyFlag flags.
3350 [ tdTestCopyFrom(sSrc = sSrcDirExisting, sDst = sScratchHstInvalid, fFlags = [ 80 ] ), tdTestResult() ],
3351 # Testing FileCopyFlag flags.
3352 [ tdTestCopyFrom(sSrc = sSrcFileExisting, sDst = sScratchHstInvalid, fFlags = [ 80 ] ), tdTestResult() ],
3353 # Nothing to copy (sDst is empty / unreachable).
3354 [ tdTestCopyFrom(sSrc = 'z:\\'), tdTestResult() ],
3355 [ tdTestCopyFrom(sSrc = '\\\\uncrulez\\foo'), tdTestResult() ],
3356 [ tdTestCopyFrom(sSrc = 'non-exist', sDst = os.path.join(sScratchHst, 'non-exist')), tdTestResult() ]
3357 ]);
3358
3359 #
3360 # Single file handling.
3361 #
3362 if self.oTstDrv.fpApiVer > 5.2:
3363 reporter.log(("Single file handling"));
3364 aaTests.extend([
3365 # Copying single files.
3366 [ tdTestCopyFrom(sSrc = sSrcFileExisting, sDst = sScratchHstInvalid), tdTestResult() ],
3367 [ tdTestCopyFrom(sSrc = sSrcFileExisting, sDst = os.path.join(sScratchHstInvalid, 'tstCopyFrom-renamedfile')),
3368 tdTestResult() ],
3369 # Copy over file using a different destination name.
3370 [ tdTestCopyFrom(sSrc = sSrcFileExisting, sDst = os.path.join(sScratchHst, 'tstCopyFrom-renamedfile')),
3371 tdTestResult(fRc = True) ],
3372 # Copy over same file (and overwrite existing one).
3373 [ tdTestCopyFrom(sSrc = sSrcFileExisting, sDst = os.path.join(sScratchHst, 'tstCopyFrom-renamedfile')),
3374 tdTestResult(fRc = True) ],
3375 # Note: Copying files into directories via Main is supported only in versions > 5.2.
3376 # Destination is a directory with a trailing slash (should work).
3377 # See "cp" syntax.
3378 [ tdTestCopyFrom(sSrc = sSrcFileExisting, sDst = sScratchHst + "/"),
3379 tdTestResult(fRc = True) ],
3380 # Destination is a directory (without a trailing slash, should also work).
3381 # See "cp" syntax.
3382 [ tdTestCopyFrom(sSrc = sSrcFileExisting, sDst = sScratchHst),
3383 tdTestResult(fRc = True) ],
3384 # Destination is a non-existing directory.
3385 [ tdTestCopyFrom(sSrc = sSrcFileExisting, sDst = sScratchHstNotExist), tdTestResult() ]
3386 ]);
3387
3388 #
3389 # Directory handling.
3390 #
3391 if self.oTstDrv.fpApiVer > 5.2: # Copying directories via Main is supported only in versions > 5.2.
3392 reporter.log(("Directory handling"));
3393 aaTests.extend([
3394 # Copying entire directories (destination is "<sScratchHst>\Web").
3395 [ tdTestCopyFrom(sSrc = sSrcDirExisting, sDst = sScratchHst),
3396 tdTestResult(fRc = True) ],
3397 # Repeat -- this time it should fail, as the destination directory already exists (and
3398 # DirectoryCopyFlag_CopyIntoExisting is not specified).
3399 [ tdTestCopyFrom(sSrc = sSrcDirExisting, sDst = sScratchHst), tdTestResult() ],
3400 # Next try with the DirectoryCopyFlag_CopyIntoExisting flag being set.
3401 [ tdTestCopyFrom(sSrc = sSrcDirExisting, sDst = sScratchHst,
3402 fFlags = [ vboxcon.DirectoryCopyFlag_CopyIntoExisting ] ),
3403 tdTestResult(fRc = True) ],
3404 # Ditto, with trailing slash.
3405 [ tdTestCopyFrom(sSrc = sSrcDirExisting,
3406 sDst = sScratchHst + "/", fFlags = [ vboxcon.DirectoryCopyFlag_CopyIntoExisting ]),
3407 tdTestResult(fRc = True) ],
3408 # Copying contents of directories into a non-existing directory chain on the host which fail.
3409 [ tdTestCopyFrom(sSrc = sSrcDirExisting + sPathSep, sDst = sScratchHstNotExistChain,
3410 fFlags = [ vboxcon.DirectoryCopyFlag_CopyIntoExisting ]), tdTestResult() ],
3411 # Copying contents of directories into a non-existing directory on the host, which should succeed.
3412 [ tdTestCopyFrom(sSrc = sSrcDirExisting + sPathSep, sDst = sScratchHstNotExist,
3413 fFlags = [ vboxcon.DirectoryCopyFlag_CopyIntoExisting ] ),
3414 tdTestResult(fRc = True) ]
3415 ]);
3416
3417 fRc = True;
3418 for (i, aTest) in enumerate(aaTests):
3419 oCurTest = aTest[0]; # tdTestExec, use an index, later.
3420 oCurRes = aTest[1]; # tdTestResult
3421 reporter.log('Testing #%d, sSrc="%s", sDst="%s", fFlags="%s" ...'
3422 % (i, oCurTest.sSrc, oCurTest.sDst, oCurTest.fFlags,));
3423
3424 oCurTest.setEnvironment(oSession, oTxsSession, oTestVm);
3425 fRc2, oCurGuestSession = oCurTest.createSession('testGuestCtrlCopyFrom: Test #%d' % (i,));
3426 if fRc2 is not True:
3427 fRc = reporter.error('Test #%d failed: Could not create session' % (i,));
3428 break;
3429
3430 try:
3431 if self.oTstDrv.fpApiVer >= 5.0:
3432 oFsInfo = oCurGuestSession.fsObjQueryInfo(oCurTest.sSrc, True); # fFollowSymlinks
3433 else:
3434 oFsInfo = oCurGuestSession.fileQueryInfo(oCurTest.sSrc);
3435 eFsObjType = oFsInfo.type;
3436 except:
3437 if oCurRes.fRc:
3438 reporter.errorXcpt('Query information exception for sSrc="%s", sDst="%s":' % (oCurTest.sSrc, oCurTest.sDst,));
3439 else:
3440 reporter.logXcpt( 'Query information exception for sSrc="%s", sDst="%s":' % (oCurTest.sSrc, oCurTest.sDst,));
3441 fRc2 = False;
3442 else:
3443 if eFsObjType == vboxcon.FsObjType_Directory:
3444 fRc2 = self.gctrlCopyDirFrom(oCurGuestSession, oCurTest.sSrc, oCurTest.sDst, oCurTest.fFlags, oCurRes.fRc);
3445 elif eFsObjType == vboxcon.FsObjType_File:
3446 fRc2 = self.gctrlCopyFileFrom(oCurGuestSession, oCurTest.sSrc, oCurTest.sDst, oCurTest.fFlags, oCurRes.fRc);
3447 else:
3448 reporter.log2('Element "%s" not handled (yet), skipping' % oFsInfo.name);
3449
3450 oCurTest.closeSession();
3451 if fRc2 == oCurRes.fRc:
3452 pass; ## @todo Verify the copied results (size, checksum?).
3453 else:
3454 fRc = reporter.error('Test #%d failed: Got %s, expected %s' % (i, fRc2, oCurRes.fRc));
3455
3456 return (fRc, oTxsSession);
3457
3458 def testGuestCtrlUpdateAdditions(self, oSession, oTxsSession, oTestVm): # pylint: disable=too-many-locals
3459 """
3460 Tests updating the Guest Additions inside the guest.
3461 """
3462
3463 # Some stupid trickery to guess the location of the iso.
3464 sVBoxValidationKitISO = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../VBoxValidationKit.iso'));
3465 if not os.path.isfile(sVBoxValidationKitISO):
3466 sVBoxValidationKitISO = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../VBoxTestSuite.iso'));
3467 if not os.path.isfile(sVBoxValidationKitISO):
3468 sCur = os.getcwd();
3469 for i in xrange(0, 10):
3470 sVBoxValidationKitISO = os.path.join(sCur, 'validationkit/VBoxValidationKit.iso');
3471 if os.path.isfile(sVBoxValidationKitISO):
3472 break;
3473 sVBoxValidationKitISO = os.path.join(sCur, 'testsuite/VBoxTestSuite.iso');
3474 if os.path.isfile(sVBoxValidationKitISO):
3475 break;
3476 sCur = os.path.abspath(os.path.join(sCur, '..'));
3477 if i is None: pass; # shut up pychecker/pylint.
3478 if os.path.isfile(sVBoxValidationKitISO):
3479 reporter.log('Validation Kit .ISO found at: %s' % (sVBoxValidationKitISO,));
3480 else:
3481 reporter.log('Warning: Validation Kit .ISO not found -- some tests might fail');
3482
3483 sScratch = os.path.join(self.oTstDrv.sScratchPath, "testGctrlUpdateAdditions");
3484 try:
3485 os.makedirs(sScratch);
3486 except OSError as e:
3487 if e.errno != errno.EEXIST:
3488 reporter.error('Failed: Unable to create scratch directory \"%s\"' % (sScratch,));
3489 return (False, oTxsSession);
3490 reporter.log('Scratch path is: %s' % (sScratch,));
3491
3492 aaTests = [];
3493 if oTestVm.isWindows():
3494 aaTests.extend([
3495 # Source is missing.
3496 [ tdTestUpdateAdditions(sSrc = ''), tdTestResult() ],
3497
3498 # Wrong fFlags.
3499 [ tdTestUpdateAdditions(sSrc = self.oTstDrv.getGuestAdditionsIso(),
3500 fFlags = [ 1234 ]), tdTestResult() ],
3501
3502 # Non-existing .ISO.
3503 [ tdTestUpdateAdditions(sSrc = "non-existing.iso"), tdTestResult() ],
3504
3505 # Wrong .ISO.
3506 [ tdTestUpdateAdditions(sSrc = sVBoxValidationKitISO), tdTestResult() ],
3507
3508 # The real thing.
3509 [ tdTestUpdateAdditions(sSrc = self.oTstDrv.getGuestAdditionsIso()),
3510 tdTestResult(fRc = True) ],
3511 # Test the (optional) installer arguments. This will extract the
3512 # installer into our guest's scratch directory.
3513 [ tdTestUpdateAdditions(sSrc = self.oTstDrv.getGuestAdditionsIso(),
3514 aArgs = [ '/extract', '/D=' + sScratch ]),
3515 tdTestResult(fRc = True) ]
3516 # Some debg ISO. Only enable locally.
3517 #[ tdTestUpdateAdditions(
3518 # sSrc = "V:\\Downloads\\VBoxGuestAdditions-r80354.iso"),
3519 # tdTestResult(fRc = True) ]
3520 ]);
3521 else:
3522 reporter.log('No OS-specific tests for non-Windows yet!');
3523
3524 fRc = True;
3525 for (i, aTest) in enumerate(aaTests):
3526 oCurTest = aTest[0]; # tdTestExec, use an index, later.
3527 oCurRes = aTest[1]; # tdTestResult
3528 reporter.log('Testing #%d, sSrc="%s", fFlags="%s" ...' % \
3529 (i, oCurTest.sSrc, oCurTest.fFlags));
3530 oCurTest.setEnvironment(oSession, oTxsSession, oTestVm);
3531 fRc, _ = oCurTest.createSession('Test #%d' % (i,));
3532 if fRc is False:
3533 reporter.error('Test #%d failed: Could not create session' % (i,));
3534 break;
3535 try:
3536 oCurProgress = oCurTest.oTest.oGuest.updateGuestAdditions(oCurTest.sSrc, oCurTest.aArgs, oCurTest.fFlags);
3537 if oCurProgress is not None:
3538 oProgress = vboxwrappers.ProgressWrapper(oCurProgress, self.oTstDrv.oVBoxMgr, self.oTstDrv, "gctrlUpGA");
3539 try:
3540 oProgress.wait();
3541 if not oProgress.isSuccess():
3542 oProgress.logResult(fIgnoreErrors = True);
3543 fRc = False;
3544 except:
3545 reporter.logXcpt('Waiting exception for updating Guest Additions:');
3546 fRc = False;
3547 else:
3548 reporter.error('No progress object returned');
3549 fRc = False;
3550 except:
3551 # Just log, don't assume an error here (will be done in the main loop then).
3552 reporter.logXcpt('Updating Guest Additions exception for sSrc="%s", fFlags="%s":' \
3553 % (oCurTest.sSrc, oCurTest.fFlags));
3554 fRc = False;
3555 oCurTest.closeSession();
3556 if fRc is oCurRes.fRc:
3557 if fRc:
3558 ## @todo Verify if Guest Additions were really updated (build, revision, ...).
3559 pass;
3560 else:
3561 reporter.error('Test #%d failed: Got %s, expected %s' % (i, fRc, oCurRes.fRc));
3562 fRc = False;
3563 break;
3564
3565 return (fRc, oTxsSession);
3566
3567
3568
3569class tdAddGuestCtrl(vbox.TestDriver): # pylint: disable=too-many-instance-attributes,too-many-public-methods
3570 """
3571 Guest control using VBoxService on the guest.
3572 """
3573
3574 def __init__(self):
3575 vbox.TestDriver.__init__(self);
3576 self.oTestVmSet = self.oTestVmManager.getSmokeVmSet('nat');
3577 self.asRsrcs = None;
3578 self.fQuick = False; # Don't skip lengthly tests by default.
3579 self.addSubTestDriver(SubTstDrvAddGuestCtrl(self));
3580
3581 #
3582 # Overridden methods.
3583 #
3584 def showUsage(self):
3585 """
3586 Shows the testdriver usage.
3587 """
3588 rc = vbox.TestDriver.showUsage(self);
3589 reporter.log('');
3590 reporter.log('tdAddGuestCtrl Options:');
3591 reporter.log(' --quick');
3592 reporter.log(' Same as --virt-modes hwvirt --cpu-counts 1.');
3593 return rc;
3594
3595 def parseOption(self, asArgs, iArg): # pylint: disable=too-many-branches,too-many-statements
3596 """
3597 Parses the testdriver arguments from the command line.
3598 """
3599 if asArgs[iArg] == '--quick':
3600 self.parseOption(['--virt-modes', 'hwvirt'], 0);
3601 self.parseOption(['--cpu-counts', '1'], 0);
3602 self.fQuick = True;
3603 else:
3604 return vbox.TestDriver.parseOption(self, asArgs, iArg);
3605 return iArg + 1;
3606
3607 def actionConfig(self):
3608 if not self.importVBoxApi(): # So we can use the constant below.
3609 return False;
3610
3611 eNic0AttachType = vboxcon.NetworkAttachmentType_NAT;
3612 sGaIso = self.getGuestAdditionsIso();
3613 return self.oTestVmSet.actionConfig(self, eNic0AttachType = eNic0AttachType, sDvdImage = sGaIso);
3614
3615 def actionExecute(self):
3616 return self.oTestVmSet.actionExecute(self, self.testOneCfg);
3617
3618 #
3619 # Test execution helpers.
3620 #
3621 def testOneCfg(self, oVM, oTestVm): # pylint: disable=too-many-statements
3622 """
3623 Runs the specified VM thru the tests.
3624
3625 Returns a success indicator on the general test execution. This is not
3626 the actual test result.
3627 """
3628
3629 self.logVmInfo(oVM);
3630
3631 fRc = True;
3632 oSession, oTxsSession = self.startVmAndConnectToTxsViaTcp(oTestVm.sVmName, fCdWait = False);
3633 reporter.log("TxsSession: %s" % (oTxsSession,));
3634 if oSession is not None:
3635 self.addTask(oTxsSession);
3636
3637 fManual = False; # Manual override for local testing. (Committed version shall be False.)
3638 if not fManual:
3639 fRc, oTxsSession = self.aoSubTstDrvs[0].testIt(oTestVm, oSession, oTxsSession);
3640 else:
3641 fRc, oTxsSession = self.testGuestCtrlManual(oSession, oTxsSession, oTestVm);
3642
3643 # Cleanup.
3644 self.removeTask(oTxsSession);
3645 if not fManual:
3646 self.terminateVmBySession(oSession);
3647 else:
3648 fRc = False;
3649 return fRc;
3650
3651 def gctrlReportError(self, progress):
3652 """
3653 Helper function to report an error of a
3654 given progress object.
3655 """
3656 if progress is None:
3657 reporter.log('No progress object to print error for');
3658 else:
3659 errInfo = progress.errorInfo;
3660 if errInfo:
3661 reporter.log('%s' % (errInfo.text,));
3662 return False;
3663
3664 def gctrlGetRemainingTime(self, msTimeout, msStart):
3665 """
3666 Helper function to return the remaining time (in ms)
3667 based from a timeout value and the start time (both in ms).
3668 """
3669 if msTimeout == 0:
3670 return 0xFFFFFFFE; # Wait forever.
3671 msElapsed = base.timestampMilli() - msStart;
3672 if msElapsed > msTimeout:
3673 return 0; # No time left.
3674 return msTimeout - msElapsed;
3675
3676 def testGuestCtrlManual(self, oSession, oTxsSession, oTestVm): # pylint: disable=too-many-locals,too-many-statements,unused-argument,unused-variable
3677 """
3678 For manually testing certain bits.
3679 """
3680
3681 reporter.log('Manual testing ...');
3682 fRc = True;
3683
3684 sUser = 'Administrator';
3685 sPassword = 'password';
3686
3687 oGuest = oSession.o.console.guest;
3688 oGuestSession = oGuest.createSession(sUser,
3689 sPassword,
3690 "", "Manual Test");
3691
3692 aWaitFor = [ vboxcon.GuestSessionWaitForFlag_Start ];
3693 _ = oGuestSession.waitForArray(aWaitFor, 30 * 1000);
3694
3695 sCmd = 'c:\\windows\\system32\\cmd.exe';
3696 aArgs = [ sCmd, '/C', 'dir', '/S', 'c:\\windows' ];
3697 aEnv = [];
3698 fFlags = [];
3699
3700 for _ in xrange(100):
3701 oProc = oGuestSession.processCreate(sCmd, aArgs if self.fpApiVer >= 5.0 else aArgs[1:],
3702 aEnv, fFlags, 30 * 1000);
3703
3704 aWaitFor = [ vboxcon.ProcessWaitForFlag_Terminate ];
3705 _ = oProc.waitForArray(aWaitFor, 30 * 1000);
3706
3707 oGuestSession.close();
3708 oGuestSession = None;
3709
3710 time.sleep(5);
3711
3712 oSession.o.console.PowerDown();
3713
3714 return (fRc, oTxsSession);
3715
3716if __name__ == '__main__':
3717 sys.exit(tdAddGuestCtrl().main(sys.argv));
Note: See TracBrowser for help on using the repository browser.

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