VirtualBox

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

Last change on this file since 67013 was 65963, checked in by vboxsync, 8 years ago

ValidationKit/tests: pylint 2.0.0 fixes.

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