VirtualBox

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

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

scm --update-copyright-year

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