VirtualBox

source: vbox/trunk/src/VBox/ValidationKit/tests/additions/tdAddSharedFolders1.py@ 99477

Last change on this file since 99477 was 99477, checked in by vboxsync, 20 months ago

Validation Kit/Shared Folders: Added a "basic" test definition placeholder, to be able to run the test driver w/o "fsperf" or "all", also added "--add-shared-folders-quick", which does the same thing. That way we can split up testing further if needed.

  • Property svn:eol-style set to LF
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 16.5 KB
Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3
4"""
5VirtualBox Validation Kit - Shared Folders #1.
6"""
7
8__copyright__ = \
9"""
10Copyright (C) 2010-2023 Oracle and/or its affiliates.
11
12This file is part of VirtualBox base platform packages, as
13available from https://www.virtualbox.org.
14
15This program is free software; you can redistribute it and/or
16modify it under the terms of the GNU General Public License
17as published by the Free Software Foundation, in version 3 of the
18License.
19
20This program is distributed in the hope that it will be useful, but
21WITHOUT ANY WARRANTY; without even the implied warranty of
22MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23General Public License for more details.
24
25You should have received a copy of the GNU General Public License
26along with this program; if not, see <https://www.gnu.org/licenses>.
27
28The contents of this file may alternatively be used under the terms
29of the Common Development and Distribution License Version 1.0
30(CDDL), a copy of it is provided in the "COPYING.CDDL" file included
31in the VirtualBox distribution, in which case the provisions of the
32CDDL are applicable instead of those of the GPL.
33
34You may elect to license modified versions of this file under the
35terms and conditions of either the GPL or the CDDL or both.
36
37SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
38"""
39__version__ = "$Revision: 99477 $"
40
41# Standard Python imports.
42import os
43import shutil
44import sys
45
46# Only the main script needs to modify the path.
47try: __file__ # pylint: disable=used-before-assignment
48except: __file__ = sys.argv[0];
49g_ksValidationKitDir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))));
50sys.path.append(g_ksValidationKitDir);
51
52# Validation Kit imports.
53from testdriver import reporter;
54from testdriver import base;
55from common import utils;
56
57
58class SubTstDrvAddSharedFolders1(base.SubTestDriverBase):
59 """
60 Sub-test driver for executing shared folders tests.
61 """
62
63 def __init__(self, oTstDrv):
64 base.SubTestDriverBase.__init__(self, oTstDrv, 'add-shared-folders', 'Shared Folders');
65
66 # Note: 'basic' acts as a placeholder, to be able to run w/o 'fsperf' or 'all'.
67 self.asTestsDef = [ 'basic', 'fsperf', ];
68 self.asTests = self.asTestsDef;
69 self.asExtraArgs = [];
70 self.asGstFsPerfPaths = [
71 '${CDROM}/vboxvalidationkit/${OS/ARCH}/FsPerf${EXESUFF}',
72 '${CDROM}/${OS/ARCH}/FsPerf${EXESUFF}',
73 '${TXSDIR}/${OS/ARCH}/FsPerf${EXESUFF}',
74 '${TXSDIR}/FsPerf${EXESUFF}',
75 'E:/vboxvalidationkit/${OS/ARCH}/FsPerf${EXESUFF}',
76 ];
77 self.sGuestSlash = '';
78
79 def parseOption(self, asArgs, iArg):
80 if asArgs[iArg] == '--add-shared-folders-tests': # 'add' as in 'additions', not the verb.
81 iArg += 1;
82 iNext = self.oTstDrv.requireMoreArgs(1, asArgs, iArg);
83 if asArgs[iArg] == 'all':
84 self.asTests = self.asTestsDef;
85 else:
86 self.asTests = asArgs[iArg].split(':');
87 for s in self.asTests:
88 if s not in self.asTestsDef:
89 raise base.InvalidOption('The "--add-shared-folders-tests" value "%s" is not valid; valid values are: %s'
90 % (s, ' '.join(self.asTestsDef)));
91 return iNext;
92 if asArgs[iArg] == '--add-shared-folders-quick':
93 self.asTests = [ 'basic' ];
94 return iArg + 1;
95 if asArgs[iArg] == '--add-shared-folders-extra-arg':
96 iArg += 1;
97 iNext = self.oTstDrv.requireMoreArgs(1, asArgs, iArg);
98 self.asExtraArgs.append(asArgs[iArg]);
99 return iNext;
100 return iArg;
101
102 def showUsage(self):
103 base.SubTestDriverBase.showUsage(self);
104 reporter.log(' --add-shared-folders-tests <t1[:t2[:]]>');
105 reporter.log(' Default: all (%s)' % (':'.join(self.asTestsDef)));
106 reporter.log(' --add-shared-folders-extra-arg <fsperf-arg>');
107 reporter.log(' Adds an extra FsPerf argument. Can be repeated.');
108 reporter.log(' --add-shared-folders-quick');
109 reporter.log(' Skips lengthly tests (such as FsPerf).');
110
111 return True;
112
113 def mountShareEx(self, oSession, oTxsSession, sShareName, sHostPath, sGuestMountPoint, fMustSucceed):
114 """
115 Automount a shared folder in the guest, extended version.
116
117 Returns success status, based on fMustSucceed.
118 """
119 reporter.testStart('Automounting "%s"' % (sShareName,));
120
121 reporter.log2('Creating shared folder "%s" at "%s" ...' % (sShareName, sGuestMountPoint));
122 try:
123 oConsole = oSession.o.console;
124 oConsole.createSharedFolder(sShareName, sHostPath, True, True, sGuestMountPoint);
125 except:
126 if fMustSucceed:
127 reporter.errorXcpt('createSharedFolder(%s,%s,True,True,%s)' % (sShareName, sHostPath, sGuestMountPoint));
128 else:
129 reporter.log('createSharedFolder(%s,%s,True,True,%s) failed, good' % (sShareName, sHostPath, sGuestMountPoint));
130 reporter.testDone();
131 return False is fMustSucceed;
132
133 # Check whether we can see the shared folder now. Retry for 30 seconds.
134 msStart = base.timestampMilli();
135 while True:
136 fRc = oTxsSession.syncIsDir(sGuestMountPoint + self.sGuestSlash + 'candle.dir');
137 reporter.log2('candle.dir check -> %s' % (fRc,));
138 if fRc is fMustSucceed:
139 break;
140 if base.timestampMilli() - msStart > 30000:
141 reporter.error('Shared folder mounting timed out!');
142 break;
143 self.oTstDrv.sleep(1);
144
145 reporter.testDone();
146
147 return fRc == fMustSucceed;
148
149 def mountShare(self, oSession, oTxsSession, sShareName, sHostPath, sGuestMountPoint):
150 """
151 Automount a shared folder in the guest.
152
153 Returns success status.
154 """
155 return self.mountShareEx(oSession, oTxsSession, sShareName, sHostPath, sGuestMountPoint, fMustSucceed = True);
156
157 def unmountShareEx(self, oSession, oTxsSession, sShareName, sGuestMountPoint, fMustSucceed):
158 """
159 Unmounts a shared folder in the guest.
160
161 Returns success status, based on fMustSucceed.
162 """
163 reporter.log2('Autounmount');
164 try:
165 oConsole = oSession.o.console;
166 oConsole.removeSharedFolder(sShareName);
167 except:
168 if fMustSucceed:
169 reporter.errorXcpt('removeSharedFolder(%s)' % (sShareName,));
170 else:
171 reporter.log('removeSharedFolder(%s)' % (sShareName,));
172 reporter.testDone();
173 return False is fMustSucceed;
174
175 # Check whether the shared folder is gone on the guest now. Retry for 30 seconds.
176 msStart = base.timestampMilli();
177 while True:
178 fRc = oTxsSession.syncIsDir(sGuestMountPoint + self.sGuestSlash + 'candle.dir');
179 reporter.log2('candle.dir check -> %s' % (fRc,));
180 if fRc is not fMustSucceed:
181 break;
182 if base.timestampMilli() - msStart > 30000:
183 reporter.error('Shared folder unmounting timed out!');
184 fRc = False;
185 break;
186 self.oTstDrv.sleep(1);
187
188 reporter.testDone();
189
190 return fRc is not fMustSucceed;
191
192 def unmountShare(self, oSession, oTxsSession, sShareName, sGuestMountPoint):
193 """
194 Unmounts a shared folder in the guest, extended version.
195
196 Returns success status, based on fMustSucceed.
197 """
198 return self.unmountShareEx(oSession, oTxsSession, sShareName, sGuestMountPoint, fMustSucceed = True);
199
200 def testIt(self, oTestVm, oSession, oTxsSession): #pylint: disable=too-many-statements
201 """
202 Executes the test.
203
204 Returns fRc, oTxsSession. The latter may have changed.
205 """
206 reporter.log("Active tests: %s" % (self.asTests,));
207
208 #
209 # Skip the test if before 6.0 or if the VM is NT4 or older.
210 #
211 if self.oTstDrv.fpApiVer < 6.0:
212 reporter.log('Requires 6.0 or later (for now)');
213 return (None, oTxsSession);
214 if oTestVm.isWindows() and oTestVm.sKind in ('WindowsNT3x', 'WindowsNT4', 'Windows2000',):
215 reporter.log('No shared folders on %s' % (oTestVm.sKind,));
216 return (None, oTxsSession);
217
218 # Guess a free mount point inside the guest.
219 if oTestVm.isWindows() or oTestVm.isOS2():
220 self.sGuestSlash = '\\';
221 else:
222 self.sGuestSlash = '/';
223
224 #
225 # Create the host directory to share. Empty except for a 'candle.dir' subdir
226 # that we use to check that it mounted correctly.
227 #
228 sShareName1 = 'shfl1';
229 sShareHostPath1 = os.path.join(self.oTstDrv.sScratchPath, sShareName1);
230 reporter.log2('Creating shared host folder "%s"...' % (sShareHostPath1,));
231 if os.path.exists(sShareHostPath1):
232 try: shutil.rmtree(sShareHostPath1);
233 except: return (reporter.errorXcpt('shutil.rmtree(%s)' % (sShareHostPath1,)), oTxsSession);
234 try: os.mkdir(sShareHostPath1);
235 except: return (reporter.errorXcpt('os.mkdir(%s)' % (sShareHostPath1,)), oTxsSession);
236 try: os.mkdir(os.path.join(sShareHostPath1, 'candle.dir'));
237 except: return (reporter.errorXcpt('os.mkdir(%s)' % (sShareHostPath1,)), oTxsSession);
238
239 # Guess a free mount point inside the guest.
240 if oTestVm.isWindows() or oTestVm.isOS2():
241 sMountPoint1 = 'V:';
242 else:
243 sMountPoint1 = '/mnt/' + sShareName1;
244
245 fRc = self.mountShare(oSession, oTxsSession, sShareName1, sShareHostPath1, sMountPoint1);
246 if fRc is not True:
247 return (False, oTxsSession); # skip the remainder if we cannot auto mount the folder.
248
249 #
250 # Run FsPerf inside the guest.
251 #
252 fSkip = 'fsperf' not in self.asTests;
253 if fSkip is False:
254 cMbFree = utils.getDiskUsage(sShareHostPath1);
255 if cMbFree >= 16:
256 reporter.log2('Free space: %u MBs' % (cMbFree,));
257 else:
258 reporter.log('Skipping FsPerf because only %u MB free on %s' % (cMbFree, sShareHostPath1,));
259 fSkip = True;
260 if fSkip is False:
261 # Common arguments:
262 asArgs = ['FsPerf', '-d', sMountPoint1 + self.sGuestSlash + 'fstestdir-1', '-s8'];
263
264 # Skip part of mmap on older windows systems without CcCoherencyFlushAndPurgeCache (>= w7).
265 reporter.log2('oTestVm.sGuestOsType=%s' % (oTestVm.sGuestOsType,));
266 if oTestVm.getNonCanonicalGuestOsType() \
267 in [ 'WindowsNT3x', 'WindowsNT4', 'Windows2000', 'WindowsXP', 'WindowsXP_64', 'Windows2003',
268 'Windows2003_64', 'WindowsVista', 'WindowsVista_64', 'Windows2008', 'Windows2008_64']:
269 asArgs.append('--no-mmap-coherency');
270
271 # Configure I/O block sizes according to guest memory size:
272 cbMbRam = 128;
273 try: cbMbRam = oSession.o.machine.memorySize;
274 except: reporter.errorXcpt();
275 reporter.log2('cbMbRam=%s' % (cbMbRam,));
276 asArgs.append('--set-block-size=1');
277 asArgs.append('--add-block-size=512');
278 asArgs.append('--add-block-size=4096');
279 asArgs.append('--add-block-size=16384');
280 asArgs.append('--add-block-size=65536');
281 asArgs.append('--add-block-size=1048576'); # 1 MiB
282 if cbMbRam >= 512:
283 asArgs.append('--add-block-size=33554432'); # 32 MiB
284 if cbMbRam >= 768:
285 asArgs.append('--add-block-size=134217728'); # 128 MiB
286
287 # Putting lots (10000) of files in a single directory causes issues on OS X
288 # (HFS+ presumably, though could be slow disks) and some linuxes (slow disks,
289 # maybe ext2/3?). So, generally reduce the file count to 4096 everywhere
290 # since we're not here to test the host file systems, and 3072 on macs.
291 if utils.getHostOs() in [ 'darwin', ]:
292 asArgs.append('--many-files=3072');
293 elif utils.getHostOs() in [ 'linux', ]:
294 asArgs.append('--many-files=4096');
295
296 # Add the extra arguments from the command line and kick it off:
297 asArgs.extend(self.asExtraArgs);
298
299 # Run FsPerf:
300 reporter.log2('Starting guest FsPerf (%s)...' % (asArgs,));
301 sFsPerfPath = self._locateGstFsPerf(oTxsSession);
302
303 ## @todo For some odd reason the combined GA/VaKit .ISO (by IPRT/fs/isomakercmd)
304 # sometimes (?) contains FsPerf as non-executable (-r--r--r-- 1 root root) on Linux.
305 #
306 # So work around this for now by copying the desired FsPerf binary to the temp directory,
307 # make it executable and execute it from there.
308 fISOMakerCmdIsBuggy = oTestVm.isLinux();
309 if fISOMakerCmdIsBuggy:
310 sFsPerfPathTemp = oTestVm.pathJoin(self.oTstDrv.getGuestTempDir(oTestVm), 'FsPerf${EXESUFF}');
311 if oTestVm.isWindows() \
312 or oTestVm.isOS2():
313 sCopy = self.oTstDrv.getGuestSystemShell();
314 sCopyArgs = ( sCopy, "/C", "copy", "/Y", sFsPerfPath, sFsPerfPathTemp );
315 else:
316 # Really old guests (like OL 6) have their coreutils in /bin instead of symlinking /bin to /usr/bin.
317 if self.oTstDrv.txsIsFile(oSession, oTxsSession, "/bin/cp", fIgnoreErrors = True):
318 sCopy = "/bin/cp";
319 else:
320 sCopy = oTestVm.pathJoin(self.oTstDrv.getGuestSystemDir(oTestVm), 'cp');
321 sCopyArgs = ( sCopy, "-a", "-v", sFsPerfPath, sFsPerfPathTemp );
322 fRc = self.oTstDrv.txsRunTest(oTxsSession, 'Copying FsPerf', 60 * 1000,
323 sCopy, sCopyArgs, fCheckSessionStatus = True);
324 fRc = fRc and oTxsSession.syncChMod(sFsPerfPathTemp, 0o755);
325 if fRc:
326 sFsPerfPath = sFsPerfPathTemp;
327
328 fRc = self.oTstDrv.txsRunTest(oTxsSession, 'Running FsPerf', 90 * 60 * 1000, sFsPerfPath, asArgs,
329 fCheckSessionStatus = True);
330 reporter.log2('FsPerf -> %s' % (fRc,));
331 if fRc:
332 # Do a bit of diagnosis to find out why this failed.
333 if not oTestVm.isWindows() \
334 and not oTestVm.isOS2():
335 # Really old guests (like OL 6) have their coreutils in /bin instead of symlinking /bin to /usr/bin.
336 if self.oTstDrv.txsIsFile(oSession, oTxsSession, "/bin/ls", fIgnoreErrors = True):
337 sCmdLs = "/bin/ls";
338 else:
339 sCmdLs = oTestVm.pathJoin(self.oTstDrv.getGuestSystemDir(oTestVm), 'ls');
340 oTxsSession.syncExec(sCmdLs, (sCmdLs, "-al", sFsPerfPath), fIgnoreErrors = True);
341 oTxsSession.syncExec(sCmdLs, (sCmdLs, "-al", "-R", "/opt"), fIgnoreErrors = True);
342 oTxsSession.syncExec(sCmdLs, (sCmdLs, "-al", "-R", "/media/cdrom"), fIgnoreErrors = True);
343
344 sTestDir = os.path.join(sShareHostPath1, 'fstestdir-1');
345 if os.path.exists(sTestDir):
346 fRc = reporter.errorXcpt('test directory lingers: %s' % (sTestDir,));
347 try: shutil.rmtree(sTestDir);
348 except: fRc = reporter.errorXcpt('shutil.rmtree(%s)' % (sTestDir,));
349 else:
350 reporter.testStart('FsPerf');
351 reporter.testDone(fSkip or fRc is None);
352
353 #
354 # Check if auto-unmounting works.
355 #
356 if fRc is True:
357 fRc = self.unmountShare(oSession, oTxsSession, sShareName1, sMountPoint1);
358
359 ## @todo Add tests for multiple automount shares, random unmounting, reboot test.
360
361 return (fRc, oTxsSession);
362
363 def _locateGstFsPerf(self, oTxsSession):
364 """
365 Returns guest side path to FsPerf.
366 """
367 for sFsPerfPath in self.asGstFsPerfPaths:
368 if oTxsSession.syncIsFile(sFsPerfPath):
369 reporter.log('Using FsPerf at "%s"' % (sFsPerfPath,));
370 return sFsPerfPath;
371 reporter.log('Unable to find guest FsPerf in any of these places: %s' % ('\n '.join(self.asGstFsPerfPaths),));
372 return self.asGstFsPerfPaths[0];
373
374
375
376if __name__ == '__main__':
377 reporter.error('Cannot run standalone, use tdAddBasic1.py');
378 sys.exit(1);
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