VirtualBox

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

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

Guest Control/Validation Kit: Try to fix tests (don't force NAT forwarding mode).

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

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