VirtualBox

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

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

Validation Kit/Shared Folders: Fixes for really old Linux guests (coreutils location) [pylint].

  • Property svn:eol-style set to LF
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 16.2 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: 99463 $"
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 self.asTestsDef = [ 'fsperf', ];
67 self.asTests = self.asTestsDef;
68 self.asExtraArgs = [];
69 self.asGstFsPerfPaths = [
70 '${CDROM}/vboxvalidationkit/${OS/ARCH}/FsPerf${EXESUFF}',
71 '${CDROM}/${OS/ARCH}/FsPerf${EXESUFF}',
72 '${TXSDIR}/${OS/ARCH}/FsPerf${EXESUFF}',
73 '${TXSDIR}/FsPerf${EXESUFF}',
74 'E:/vboxvalidationkit/${OS/ARCH}/FsPerf${EXESUFF}',
75 ];
76 self.sGuestSlash = '';
77
78 def parseOption(self, asArgs, iArg):
79 if asArgs[iArg] == '--add-shared-folders-tests': # 'add' as in 'additions', not the verb.
80 iArg += 1;
81 iNext = self.oTstDrv.requireMoreArgs(1, asArgs, iArg);
82 if asArgs[iArg] == 'all':
83 self.asTests = self.asTestsDef;
84 else:
85 self.asTests = asArgs[iArg].split(':');
86 for s in self.asTests:
87 if s not in self.asTestsDef:
88 raise base.InvalidOption('The "--add-shared-folders-tests" value "%s" is not valid; valid values are: %s'
89 % (s, ' '.join(self.asTestsDef)));
90 return iNext;
91 if asArgs[iArg] == '--add-shared-folders-extra-arg':
92 iArg += 1;
93 iNext = self.oTstDrv.requireMoreArgs(1, asArgs, iArg);
94 self.asExtraArgs.append(asArgs[iArg]);
95 return iNext;
96 return iArg;
97
98 def showUsage(self):
99 base.SubTestDriverBase.showUsage(self);
100 reporter.log(' --add-shared-folders-tests <t1[:t2[:]]>');
101 reporter.log(' Default: all (%s)' % (':'.join(self.asTestsDef)));
102 reporter.log(' --add-shared-folders-extra-arg <fsperf-arg>');
103 reporter.log(' Adds an extra FsPerf argument. Can be repeated.');
104
105 return True;
106
107 def mountShareEx(self, oSession, oTxsSession, sShareName, sHostPath, sGuestMountPoint, fMustSucceed):
108 """
109 Automount a shared folder in the guest, extended version.
110
111 Returns success status, based on fMustSucceed.
112 """
113 reporter.testStart('Automounting "%s"' % (sShareName,));
114
115 reporter.log2('Creating shared folder "%s" at "%s" ...' % (sShareName, sGuestMountPoint));
116 try:
117 oConsole = oSession.o.console;
118 oConsole.createSharedFolder(sShareName, sHostPath, True, True, sGuestMountPoint);
119 except:
120 if fMustSucceed:
121 reporter.errorXcpt('createSharedFolder(%s,%s,True,True,%s)' % (sShareName, sHostPath, sGuestMountPoint));
122 else:
123 reporter.log('createSharedFolder(%s,%s,True,True,%s) failed, good' % (sShareName, sHostPath, sGuestMountPoint));
124 reporter.testDone();
125 return False is fMustSucceed;
126
127 # Check whether we can see the shared folder now. Retry for 30 seconds.
128 msStart = base.timestampMilli();
129 while True:
130 fRc = oTxsSession.syncIsDir(sGuestMountPoint + self.sGuestSlash + 'candle.dir');
131 reporter.log2('candle.dir check -> %s' % (fRc,));
132 if fRc is fMustSucceed:
133 break;
134 if base.timestampMilli() - msStart > 30000:
135 reporter.error('Shared folder mounting timed out!');
136 break;
137 self.oTstDrv.sleep(1);
138
139 reporter.testDone();
140
141 return fRc == fMustSucceed;
142
143 def mountShare(self, oSession, oTxsSession, sShareName, sHostPath, sGuestMountPoint):
144 """
145 Automount a shared folder in the guest.
146
147 Returns success status.
148 """
149 return self.mountShareEx(oSession, oTxsSession, sShareName, sHostPath, sGuestMountPoint, fMustSucceed = True);
150
151 def unmountShareEx(self, oSession, oTxsSession, sShareName, sGuestMountPoint, fMustSucceed):
152 """
153 Unmounts a shared folder in the guest.
154
155 Returns success status, based on fMustSucceed.
156 """
157 reporter.log2('Autounmount');
158 try:
159 oConsole = oSession.o.console;
160 oConsole.removeSharedFolder(sShareName);
161 except:
162 if fMustSucceed:
163 reporter.errorXcpt('removeSharedFolder(%s)' % (sShareName,));
164 else:
165 reporter.log('removeSharedFolder(%s)' % (sShareName,));
166 reporter.testDone();
167 return False is fMustSucceed;
168
169 # Check whether the shared folder is gone on the guest now. Retry for 30 seconds.
170 msStart = base.timestampMilli();
171 while True:
172 fRc = oTxsSession.syncIsDir(sGuestMountPoint + self.sGuestSlash + 'candle.dir');
173 reporter.log2('candle.dir check -> %s' % (fRc,));
174 if fRc is not fMustSucceed:
175 break;
176 if base.timestampMilli() - msStart > 30000:
177 reporter.error('Shared folder unmounting timed out!');
178 fRc = False;
179 break;
180 self.oTstDrv.sleep(1);
181
182 reporter.testDone();
183
184 return fRc is not fMustSucceed;
185
186 def unmountShare(self, oSession, oTxsSession, sShareName, sGuestMountPoint):
187 """
188 Unmounts a shared folder in the guest, extended version.
189
190 Returns success status, based on fMustSucceed.
191 """
192 return self.unmountShareEx(oSession, oTxsSession, sShareName, sGuestMountPoint, fMustSucceed = True);
193
194 def testIt(self, oTestVm, oSession, oTxsSession): #pylint: disable=too-many-statements
195 """
196 Executes the test.
197
198 Returns fRc, oTxsSession. The latter may have changed.
199 """
200 reporter.log("Active tests: %s" % (self.asTests,));
201
202 #
203 # Skip the test if before 6.0 or if the VM is NT4 or older.
204 #
205 if self.oTstDrv.fpApiVer < 6.0:
206 reporter.log('Requires 6.0 or later (for now)');
207 return (None, oTxsSession);
208 if oTestVm.isWindows() and oTestVm.sKind in ('WindowsNT3x', 'WindowsNT4', 'Windows2000',):
209 reporter.log('No shared folders on %s' % (oTestVm.sKind,));
210 return (None, oTxsSession);
211
212 # Guess a free mount point inside the guest.
213 if oTestVm.isWindows() or oTestVm.isOS2():
214 self.sGuestSlash = '\\';
215 else:
216 self.sGuestSlash = '/';
217
218 #
219 # Create the host directory to share. Empty except for a 'candle.dir' subdir
220 # that we use to check that it mounted correctly.
221 #
222 sShareName1 = 'shfl1';
223 sShareHostPath1 = os.path.join(self.oTstDrv.sScratchPath, sShareName1);
224 reporter.log2('Creating shared host folder "%s"...' % (sShareHostPath1,));
225 if os.path.exists(sShareHostPath1):
226 try: shutil.rmtree(sShareHostPath1);
227 except: return (reporter.errorXcpt('shutil.rmtree(%s)' % (sShareHostPath1,)), oTxsSession);
228 try: os.mkdir(sShareHostPath1);
229 except: return (reporter.errorXcpt('os.mkdir(%s)' % (sShareHostPath1,)), oTxsSession);
230 try: os.mkdir(os.path.join(sShareHostPath1, 'candle.dir'));
231 except: return (reporter.errorXcpt('os.mkdir(%s)' % (sShareHostPath1,)), oTxsSession);
232
233 # Guess a free mount point inside the guest.
234 if oTestVm.isWindows() or oTestVm.isOS2():
235 sMountPoint1 = 'V:';
236 else:
237 sMountPoint1 = '/mnt/' + sShareName1;
238
239 fRc = self.mountShare(oSession, oTxsSession, sShareName1, sShareHostPath1, sMountPoint1);
240 if fRc is not True:
241 return (False, oTxsSession); # skip the remainder if we cannot auto mount the folder.
242
243 #
244 # Run FsPerf inside the guest.
245 #
246 fSkip = 'fsperf' not in self.asTests;
247 if fSkip is False:
248 cMbFree = utils.getDiskUsage(sShareHostPath1);
249 if cMbFree >= 16:
250 reporter.log2('Free space: %u MBs' % (cMbFree,));
251 else:
252 reporter.log('Skipping FsPerf because only %u MB free on %s' % (cMbFree, sShareHostPath1,));
253 fSkip = True;
254 if fSkip is False:
255 # Common arguments:
256 asArgs = ['FsPerf', '-d', sMountPoint1 + self.sGuestSlash + 'fstestdir-1', '-s8'];
257
258 # Skip part of mmap on older windows systems without CcCoherencyFlushAndPurgeCache (>= w7).
259 reporter.log2('oTestVm.sGuestOsType=%s' % (oTestVm.sGuestOsType,));
260 if oTestVm.getNonCanonicalGuestOsType() \
261 in [ 'WindowsNT3x', 'WindowsNT4', 'Windows2000', 'WindowsXP', 'WindowsXP_64', 'Windows2003',
262 'Windows2003_64', 'WindowsVista', 'WindowsVista_64', 'Windows2008', 'Windows2008_64']:
263 asArgs.append('--no-mmap-coherency');
264
265 # Configure I/O block sizes according to guest memory size:
266 cbMbRam = 128;
267 try: cbMbRam = oSession.o.machine.memorySize;
268 except: reporter.errorXcpt();
269 reporter.log2('cbMbRam=%s' % (cbMbRam,));
270 asArgs.append('--set-block-size=1');
271 asArgs.append('--add-block-size=512');
272 asArgs.append('--add-block-size=4096');
273 asArgs.append('--add-block-size=16384');
274 asArgs.append('--add-block-size=65536');
275 asArgs.append('--add-block-size=1048576'); # 1 MiB
276 if cbMbRam >= 512:
277 asArgs.append('--add-block-size=33554432'); # 32 MiB
278 if cbMbRam >= 768:
279 asArgs.append('--add-block-size=134217728'); # 128 MiB
280
281 # Putting lots (10000) of files in a single directory causes issues on OS X
282 # (HFS+ presumably, though could be slow disks) and some linuxes (slow disks,
283 # maybe ext2/3?). So, generally reduce the file count to 4096 everywhere
284 # since we're not here to test the host file systems, and 3072 on macs.
285 if utils.getHostOs() in [ 'darwin', ]:
286 asArgs.append('--many-files=3072');
287 elif utils.getHostOs() in [ 'linux', ]:
288 asArgs.append('--many-files=4096');
289
290 # Add the extra arguments from the command line and kick it off:
291 asArgs.extend(self.asExtraArgs);
292
293 # Run FsPerf:
294 reporter.log2('Starting guest FsPerf (%s)...' % (asArgs,));
295 sFsPerfPath = self._locateGstFsPerf(oTxsSession);
296
297 ## @todo For some odd reason the combined GA/VaKit .ISO (by IPRT/fs/isomakercmd)
298 # sometimes (?) contains FsPerf as non-executable (-r--r--r-- 1 root root) on Linux.
299 #
300 # So work around this for now by copying the desired FsPerf binary to the temp directory,
301 # make it executable and execute it from there.
302 fISOMakerCmdIsBuggy = oTestVm.isLinux();
303 if fISOMakerCmdIsBuggy:
304 sFsPerfPathTemp = oTestVm.pathJoin(self.oTstDrv.getGuestTempDir(oTestVm), 'FsPerf${EXESUFF}');
305 if oTestVm.isWindows() \
306 or oTestVm.isOS2():
307 sCopy = self.oTstDrv.getGuestSystemShell();
308 sCopyArgs = ( sCopy, "/C", "copy", "/Y", sFsPerfPath, sFsPerfPathTemp );
309 else:
310 # Really old guests (like OL 6) have their coreutils in /bin instead of symlinking /bin to /usr/bin.
311 if self.oTstDrv.txsIsFile(oSession, oTxsSession, "/bin/cp", fIgnoreErrors = True):
312 sCopy = "/bin/cp";
313 else:
314 sCopy = oTestVm.pathJoin(self.oTstDrv.getGuestSystemDir(oTestVm), 'cp');
315 sCopyArgs = ( sCopy, "-a", "-v", sFsPerfPath, sFsPerfPathTemp );
316 fRc = self.oTstDrv.txsRunTest(oTxsSession, 'Copying FsPerf', 60 * 1000,
317 sCopy, sCopyArgs, fCheckSessionStatus = True);
318 fRc = fRc and oTxsSession.syncChMod(sFsPerfPathTemp, 0o755);
319 if fRc:
320 sFsPerfPath = sFsPerfPathTemp;
321
322 fRc = self.oTstDrv.txsRunTest(oTxsSession, 'Running FsPerf', 90 * 60 * 1000, sFsPerfPath, asArgs,
323 fCheckSessionStatus = True);
324 reporter.log2('FsPerf -> %s' % (fRc,));
325 if fRc:
326 # Do a bit of diagnosis to find out why this failed.
327 if not oTestVm.isWindows() \
328 and not oTestVm.isOS2():
329 # Really old guests (like OL 6) have their coreutils in /bin instead of symlinking /bin to /usr/bin.
330 if self.oTstDrv.txsIsFile(oSession, oTxsSession, "/bin/ls", fIgnoreErrors = True):
331 sCmdLs = "/bin/ls";
332 else:
333 sCmdLs = oTestVm.pathJoin(self.oTstDrv.getGuestSystemDir(oTestVm), 'ls');
334 oTxsSession.syncExec(sCmdLs, (sCmdLs, "-al", sFsPerfPath), fIgnoreErrors = True);
335 oTxsSession.syncExec(sCmdLs, (sCmdLs, "-al", "-R", "/opt"), fIgnoreErrors = True);
336 oTxsSession.syncExec(sCmdLs, (sCmdLs, "-al", "-R", "/media/cdrom"), fIgnoreErrors = True);
337
338 sTestDir = os.path.join(sShareHostPath1, 'fstestdir-1');
339 if os.path.exists(sTestDir):
340 fRc = reporter.errorXcpt('test directory lingers: %s' % (sTestDir,));
341 try: shutil.rmtree(sTestDir);
342 except: fRc = reporter.errorXcpt('shutil.rmtree(%s)' % (sTestDir,));
343 else:
344 reporter.testStart('FsPerf');
345 reporter.testDone(fSkip or fRc is None);
346
347 #
348 # Check if auto-unmounting works.
349 #
350 if fRc is True:
351 fRc = self.unmountShare(oSession, oTxsSession, sShareName1, sMountPoint1);
352
353 ## @todo Add tests for multiple automount shares, random unmounting, reboot test.
354
355 return (fRc, oTxsSession);
356
357 def _locateGstFsPerf(self, oTxsSession):
358 """
359 Returns guest side path to FsPerf.
360 """
361 for sFsPerfPath in self.asGstFsPerfPaths:
362 if oTxsSession.syncIsFile(sFsPerfPath):
363 reporter.log('Using FsPerf at "%s"' % (sFsPerfPath,));
364 return sFsPerfPath;
365 reporter.log('Unable to find guest FsPerf in any of these places: %s' % ('\n '.join(self.asGstFsPerfPaths),));
366 return self.asGstFsPerfPaths[0];
367
368
369
370if __name__ == '__main__':
371 reporter.error('Cannot run standalone, use tdAddBasic1.py');
372 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