VirtualBox

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

Last change on this file since 96407 was 96407, checked in by vboxsync, 2 years ago

scm copyright and license note update

  • Property svn:eol-style set to LF
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 15.3 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-2022 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: 96407 $"
40
41# Standard Python imports.
42import os
43import shutil
44import sys
45
46# Only the main script needs to modify the path.
47try: __file__
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):
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
204 #
205 if self.oTstDrv.fpApiVer < 6.0:
206 reporter.log('Requires 6.0 or later (for now)');
207 return (None, oTxsSession);
208
209 # Guess a free mount point inside the guest.
210 if oTestVm.isWindows() or oTestVm.isOS2():
211 self.sGuestSlash = '\\';
212 else:
213 self.sGuestSlash = '/';
214
215 #
216 # Create the host directory to share. Empty except for a 'candle.dir' subdir
217 # that we use to check that it mounted correctly.
218 #
219 sShareName1 = 'shfl1';
220 sShareHostPath1 = os.path.join(self.oTstDrv.sScratchPath, sShareName1);
221 reporter.log2('Creating shared host folder "%s"...' % (sShareHostPath1,));
222 if os.path.exists(sShareHostPath1):
223 try: shutil.rmtree(sShareHostPath1);
224 except: return (reporter.errorXcpt('shutil.rmtree(%s)' % (sShareHostPath1,)), oTxsSession);
225 try: os.mkdir(sShareHostPath1);
226 except: return (reporter.errorXcpt('os.mkdir(%s)' % (sShareHostPath1,)), oTxsSession);
227 try: os.mkdir(os.path.join(sShareHostPath1, 'candle.dir'));
228 except: return (reporter.errorXcpt('os.mkdir(%s)' % (sShareHostPath1,)), oTxsSession);
229
230 # Guess a free mount point inside the guest.
231 if oTestVm.isWindows() or oTestVm.isOS2():
232 sMountPoint1 = 'V:';
233 else:
234 sMountPoint1 = '/mnt/' + sShareName1;
235
236 fRc = self.mountShare(oSession, oTxsSession, sShareName1, sShareHostPath1, sMountPoint1);
237 if fRc is not True:
238 return (False, oTxsSession); # skip the remainder if we cannot auto mount the folder.
239
240 #
241 # Run FsPerf inside the guest.
242 #
243 fSkip = 'fsperf' not in self.asTests;
244 if fSkip is False:
245 cMbFree = utils.getDiskUsage(sShareHostPath1);
246 if cMbFree >= 16:
247 reporter.log2('Free space: %u MBs' % (cMbFree,));
248 else:
249 reporter.log('Skipping FsPerf because only %u MB free on %s' % (cMbFree, sShareHostPath1,));
250 fSkip = True;
251 if fSkip is False:
252 # Common arguments:
253 asArgs = ['FsPerf', '-d', sMountPoint1 + self.sGuestSlash + 'fstestdir-1', '-s8'];
254
255 # Skip part of mmap on older windows systems without CcCoherencyFlushAndPurgeCache (>= w7).
256 reporter.log2('oTestVm.sGuestOsType=%s' % (oTestVm.sGuestOsType,));
257 if oTestVm.getNonCanonicalGuestOsType() \
258 in [ 'WindowsNT3x', 'WindowsNT4', 'Windows2000', 'WindowsXP', 'WindowsXP_64', 'Windows2003',
259 'Windows2003_64', 'WindowsVista', 'WindowsVista_64', 'Windows2008', 'Windows2008_64']:
260 asArgs.append('--no-mmap-coherency');
261
262 # Configure I/O block sizes according to guest memory size:
263 cbMbRam = 128;
264 try: cbMbRam = oSession.o.machine.memorySize;
265 except: reporter.errorXcpt();
266 reporter.log2('cbMbRam=%s' % (cbMbRam,));
267 asArgs.append('--set-block-size=1');
268 asArgs.append('--add-block-size=512');
269 asArgs.append('--add-block-size=4096');
270 asArgs.append('--add-block-size=16384');
271 asArgs.append('--add-block-size=65536');
272 asArgs.append('--add-block-size=1048576'); # 1 MiB
273 if cbMbRam >= 512:
274 asArgs.append('--add-block-size=33554432'); # 32 MiB
275 if cbMbRam >= 768:
276 asArgs.append('--add-block-size=134217728'); # 128 MiB
277
278 # Putting lots (10000) of files in a single directory causes issues on OS X
279 # (HFS+ presumably, though could be slow disks) and some linuxes (slow disks,
280 # maybe ext2/3?). So, generally reduce the file count to 4096 everywhere
281 # since we're not here to test the host file systems, and 3072 on macs.
282 if utils.getHostOs() in [ 'darwin', ]:
283 asArgs.append('--many-files=3072');
284 elif utils.getHostOs() in [ 'linux', ]:
285 asArgs.append('--many-files=4096');
286
287 # Add the extra arguments from the command line and kick it off:
288 asArgs.extend(self.asExtraArgs);
289
290 # Run FsPerf:
291 reporter.log2('Starting guest FsPerf (%s)...' % (asArgs,));
292 sFsPerfPath = self._locateGstFsPerf(oTxsSession);
293
294 ## @todo For some odd reason the combined GA/VaKit .ISO (by IPRT/fs/isomakercmd)
295 # sometimes (?) contains FsPerf as non-executable (-r--r--r-- 1 root root) on Linux.
296 #
297 # So work around this for now by copying the desired FsPerf binary to the temp directory,
298 # make it executable and execute it from there.
299 fISOMakerCmdIsBuggy = oTestVm.isLinux();
300 if fISOMakerCmdIsBuggy:
301 sFsPerfPathTemp = oTestVm.pathJoin(self.oTstDrv.getGuestTempDir(oTestVm), 'FsPerf${EXESUFF}');
302 if oTestVm.isWindows() \
303 or oTestVm.isOS2():
304 sCopy = self.oTstDrv.getGuestSystemShell();
305 sCopyArgs = ( sCopy, "/C", "copy", "/Y", sFsPerfPath, sFsPerfPathTemp );
306 else:
307 sCopy = oTestVm.pathJoin(self.oTstDrv.getGuestSystemDir(oTestVm), 'cp');
308 sCopyArgs = ( sCopy, "-a", "-v", sFsPerfPath, sFsPerfPathTemp );
309 fRc = self.oTstDrv.txsRunTest(oTxsSession, 'Copying FsPerf', 60 * 1000,
310 sCopy, sCopyArgs, fCheckSessionStatus = True);
311 fRc = fRc and oTxsSession.syncChMod(sFsPerfPathTemp, 0o755);
312 if fRc:
313 sFsPerfPath = sFsPerfPathTemp;
314
315 fRc = self.oTstDrv.txsRunTest(oTxsSession, 'Running FsPerf', 90 * 60 * 1000, sFsPerfPath, asArgs,
316 fCheckSessionStatus = True);
317 reporter.log2('FsPerf -> %s' % (fRc,));
318 if fRc:
319 # Do a bit of diagnosis to find out why this failed.
320 if not oTestVm.isWindows() \
321 and not oTestVm.isOS2():
322 sCmdLs = oTestVm.pathJoin(self.oTstDrv.getGuestSystemDir(oTestVm), 'ls');
323 oTxsSession.syncExec(sCmdLs, (sCmdLs, "-al", sFsPerfPath), fIgnoreErrors = True);
324 oTxsSession.syncExec(sCmdLs, (sCmdLs, "-al", "-R", "/opt"), fIgnoreErrors = True);
325 oTxsSession.syncExec(sCmdLs, (sCmdLs, "-al", "-R", "/media/cdrom"), fIgnoreErrors = True);
326
327 sTestDir = os.path.join(sShareHostPath1, 'fstestdir-1');
328 if os.path.exists(sTestDir):
329 fRc = reporter.errorXcpt('test directory lingers: %s' % (sTestDir,));
330 try: shutil.rmtree(sTestDir);
331 except: fRc = reporter.errorXcpt('shutil.rmtree(%s)' % (sTestDir,));
332 else:
333 reporter.testStart('FsPerf');
334 reporter.testDone(fSkip or fRc is None);
335
336 #
337 # Check if auto-unmounting works.
338 #
339 if fRc is True:
340 fRc = self.unmountShare(oSession, oTxsSession, sShareName1, sMountPoint1);
341
342 ## @todo Add tests for multiple automount shares, random unmounting, reboot test.
343
344 return (fRc, oTxsSession);
345
346 def _locateGstFsPerf(self, oTxsSession):
347 """
348 Returns guest side path to FsPerf.
349 """
350 for sFsPerfPath in self.asGstFsPerfPaths:
351 if oTxsSession.syncIsFile(sFsPerfPath):
352 reporter.log('Using FsPerf at "%s"' % (sFsPerfPath,));
353 return sFsPerfPath;
354 reporter.log('Unable to find guest FsPerf in any of these places: %s' % ('\n '.join(self.asGstFsPerfPaths),));
355 return self.asGstFsPerfPaths[0];
356
357
358
359if __name__ == '__main__':
360 reporter.error('Cannot run standalone, use tdAddBasic1.py');
361 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