VirtualBox

source: vbox/trunk/src/VBox/ValidationKit/tests/storage/tdStorageRawDrive1.py@ 94836

Last change on this file since 94836 was 94123, checked in by vboxsync, 3 years ago

ValKit/utils.py,tests: Move crc32_of_file to common/utils.py as calcCrc32OfFile, no point in having two copies of it. pylint fixes.

  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 87.4 KB
Line 
1
2#!/usr/bin/env python
3# -*- coding: utf-8 -*-
4"""
5VirtualBox Validation Kit - VMDK raw disk tests.
6"""
7
8__copyright__ = \
9"""
10Copyright (C) 2013-2022 Oracle Corporation
11
12This file is part of VirtualBox Open Source Edition (OSE), as
13available from http://www.virtualbox.org. This file is free software;
14you can redistribute it and/or modify it under the terms of the GNU
15General Public License (GPL) as published by the Free Software
16Foundation, in version 2 as it comes in the "COPYING" file of the
17VirtualBox OSE distribution. VirtualBox OSE is distributed in the
18hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
19
20The contents of this file may alternatively be used under the terms
21of the Common Development and Distribution License Version 1.0
22(CDDL) only, as it comes in the "COPYING.CDDL" file of the
23VirtualBox OSE distribution, in which case the provisions of the
24CDDL are applicable instead of those of the GPL.
25
26You may elect to license modified versions of this file under the
27terms and conditions of either the GPL or the CDDL or both.
28"""
29__version__ = "$Id: tdStorageRawDrive1.py 94123 2022-03-08 13:51:26Z vboxsync $"
30
31# Standard Python imports.
32import os;
33import re;
34import sys;
35
36# Only the main script needs to modify the path.
37try: __file__
38except: __file__ = sys.argv[0];
39g_ksValidationKitDir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))));
40sys.path.append(g_ksValidationKitDir);
41
42# Validation Kit imports.
43from common import utils;
44from testdriver import reporter;
45from testdriver import base;
46from testdriver import vbox;
47from testdriver import vboxcon;
48from testdriver import vboxtestvms;
49from testdriver import vboxwrappers;
50
51
52class tdStorageRawDriveOs(vboxtestvms.BaseTestVm):
53 """
54 Base autostart helper class to provide common methods.
55 """
56 # pylint: disable=too-many-arguments
57 def __init__(self, oSet, oTstDrv, sVmName, sKind, sHdd, eNic0Type = None, cMbRam = None, \
58 cCpus = 1, fPae = None, sGuestAdditionsIso = None, sBootSector = None):
59 vboxtestvms.BaseTestVm.__init__(self, sVmName, oSet = oSet, sKind = sKind);
60 self.oTstDrv = oTstDrv;
61 self.sHdd = sHdd;
62 self.eNic0Type = eNic0Type;
63 self.cMbRam = cMbRam;
64 self.cCpus = cCpus;
65 self.fPae = fPae;
66 self.sGuestAdditionsIso = sGuestAdditionsIso;
67 self.asTestBuildDirs = oTstDrv.asTestBuildDirs;
68 self.sVBoxInstaller = "";
69 self.sVMDKPath='/home/vbox/vmdk';
70 self.asVirtModesSup = ['hwvirt-np',];
71 self.asParavirtModesSup = ['default',];
72 self.sBootSector = sBootSector;
73 self.sPathDelimiter = '/';
74
75 # Had to move it here from oTestDrv because the output is platform-dependent
76 self.asHdds = \
77 { '6.1/storage/t-mbr.vdi' :
78 {
79 'Header' :
80 {
81 #Drive: /dev/sdb
82 'Model' : '"ATA VBOX HARDDISK"',
83 'UUID' : '62d4f394-0000-0000-0000-000000000000',
84 'Size' : '2.0GiB',
85 'Sector Size' : '512 bytes',
86 'Scheme' : 'MBR',
87 },
88 'Partitions' :
89 {
90 'Partitions' :
91 [
92 '$(1) 07 10.0MiB 1.0MiB 0/ 32/33 1/102/37 no IFS',
93 '$(2) 83 10.0MiB 11.0MiB 5/ 93/33 11/ 29/14 no Linux',
94 '$(3) 07 10.0MiB 21.0MiB 2/172/43 3/242/47 no IFS',
95 '$(4) 07 10.0MiB 32.0MiB 4/ 20/17 5/ 90/21 no IFS',
96 '$(5) 83 10.0MiB 43.0MiB 5/122/54 6/192/58 no Linux',
97 '$(6) 07 10.0MiB 54.0MiB 6/225/28 8/ 40/32 no IFS',
98 '$(7) 83 10.0MiB 65.0MiB 8/ 73/ 2 9/143/ 6 no Linux',
99 '$(8) 07 1.9GiB 76.0MiB 9/175/39 260/243/47 no IFS',
100 ],
101 'PartitionNumbers' : [1, 2, 3, 5, 6, 7, 8, 9],
102 },
103 } ,
104 '6.1/storage/t-gpt.vdi' :
105 {
106 'Header' :
107 {
108 #Drive: /dev/sdc
109 'Model' : '"ATA VBOX HARDDISK"',
110 'UUID' : '7b642ab1-9d44-b844-a860-ce71e0686274',
111 'Size' : '2.0GiB',
112 'Sector Size' : '512 bytes',
113 'Scheme' : 'GPT',
114 },
115 'Partitions' :
116 {
117 'Partitions' :
118 [
119 '$(1) WindowsBasicData 560b261d-081f-fb4a-8df8-c64fffcb2bd1 10.0MiB 1.0MiB off',
120 '$(2) LinuxData 629f66be-0254-7c4f-a328-cc033e4de124 10.0MiB 11.0MiB off',
121 '$(3) WindowsBasicData d3f56c96-3b28-7f44-a53d-85b8bc93bd91 10.0MiB 21.0MiB off',
122 '$(4) LinuxData 27c0f5ad-74c8-d54f-835f-06e51b3f10ef 10.0MiB 31.0MiB off',
123 '$(5) WindowsBasicData 6cf1fdf0-b2ae-3849-9cfa-c056f9d8b722 10.0MiB 41.0MiB off',
124 '$(6) LinuxData 017bcbed-8b96-be4d-925a-2f872194fbe6 10.0MiB 51.0MiB off',
125 '$(7) WindowsBasicData af6c4f89-8fc3-5049-9d98-3e2e98061073 10.0MiB 61.0MiB off',
126 '$(8) LinuxData 9704d7cd-810f-4d44-ac78-432ebc16143f 10.0MiB 71.0MiB off',
127 '$(9) WindowsBasicData a05f8e09-f9e7-5b4e-bb4e-e9f8fde3110e 1.9GiB 81.0MiB off',
128 ],
129 'PartitionNumbers' : [1, 2, 3, 4, 5, 6, 7, 8, 9],
130 },
131
132 }
133 };
134 self.asActions = \
135 [
136 {
137 'action' : 'whole drive',
138 'options' : [],
139 'data-crc' : {},
140 'createType' : 'fullDevice',
141 'extents' : { '6.1/storage/t-mbr.vdi' : ['RW 0 FLAT "$(disk)" 0',],
142 '6.1/storage/t-gpt.vdi' : ['RW 0 FLAT "$(disk)" 0',],
143 },
144 },
145 {
146 'action' : '1 partition',
147 'options' : ['--property', 'Partitions=1'],
148 'data-crc' : {'6.1/storage/t-mbr.vdi' : 2681429243,
149 '6.1/storage/t-gpt.vdi' : 1391394051,
150 },
151 'createType' : 'partitionedDevice',
152 'extents' : { '6.1/storage/t-mbr.vdi' :
153 ['RW 2048 FLAT "vmdktest-pt.vmdk" 0',
154 'RW 20480 FLAT "$(disk)" 2048',
155 'RW 20480 ZERO',
156 'RW 20480 ZERO',
157 'RW 2048 FLAT "vmdktest-pt.vmdk" 2048',
158 'RW 20480 ZERO',
159 'RW 2048 FLAT "vmdktest-pt.vmdk" 4096',
160 'RW 20480 ZERO',
161 'RW 2048 FLAT "vmdktest-pt.vmdk" 6144',
162 'RW 20480 ZERO',
163 'RW 2048 FLAT "vmdktest-pt.vmdk" 8192',
164 'RW 20480 ZERO',
165 'RW 2048 FLAT "vmdktest-pt.vmdk" 10240',
166 'RW 4036608 ZERO',
167 'RW 36028797014771712 ZERO',
168 ],
169 '6.1/storage/t-gpt.vdi' :
170 ['RW 1 FLAT "vmdktest-pt.vmdk" 0',
171 'RW 2047 FLAT "vmdktest-pt.vmdk" 1',
172 'RW 20480 FLAT "$(disk)" 2048',
173 'RW 20480 ZERO',
174 'RW 20480 ZERO',
175 'RW 20480 ZERO',
176 'RW 20480 ZERO',
177 'RW 20480 ZERO',
178 'RW 20480 ZERO',
179 'RW 20480 ZERO',
180 'RW 4026368 ZERO',
181 'RW 36028797014771712 ZERO',
182 ],
183 },
184 },
185 {
186 'action' : '2 partitions',
187 'options' : ['--property', 'Partitions=1,$(4)'],
188 'data-crc' : {'6.1/storage/t-mbr.vdi' : 2681429243,
189 '6.1/storage/t-gpt.vdi' : 1391394051,
190 },
191 'createType' : 'partitionedDevice',
192 'extents' : { '6.1/storage/t-mbr.vdi' :
193 ['RW 2048 FLAT "vmdktest-pt.vmdk" 0',
194 'RW 20480 FLAT "$(disk)" 2048',
195 'RW 20480 ZERO',
196 'RW 20480 ZERO',
197 'RW 2048 FLAT "vmdktest-pt.vmdk" 2048',
198 'RW 20480 FLAT "$(disk)" 65536',
199 'RW 2048 FLAT "vmdktest-pt.vmdk" 4096',
200 'RW 20480 ZERO',
201 'RW 2048 FLAT "vmdktest-pt.vmdk" 6144',
202 'RW 20480 ZERO',
203 'RW 2048 FLAT "vmdktest-pt.vmdk" 8192',
204 'RW 20480 ZERO',
205 'RW 2048 FLAT "vmdktest-pt.vmdk" 10240',
206 'RW 4036608 ZERO',
207 'RW 36028797014771712 ZERO',
208 ],
209 '6.1/storage/t-gpt.vdi' :
210 ['RW 1 FLAT "vmdktest-pt.vmdk" 0',
211 'RW 2047 FLAT "vmdktest-pt.vmdk" 1',
212 'RW 20480 FLAT "$(disk)" 2048',
213 'RW 20480 ZERO',
214 'RW 20480 ZERO',
215 'RW 20480 FLAT "$(disk)" 63488',
216 'RW 20480 ZERO',
217 'RW 20480 ZERO',
218 'RW 20480 ZERO',
219 'RW 20480 ZERO',
220 'RW 4026368 ZERO',
221 'RW 36028797014771712 ZERO',
222 ],
223 },
224 },
225 {
226 'action' : '1 partition with boot sector',
227 'options' : ['--property', 'Partitions=1',
228 '--property-file', 'BootSector=$(bootsector)'],
229 'data-crc' : {'6.1/storage/t-mbr.vdi' : 3980784439,
230 '6.1/storage/t-gpt.vdi' : 1152317131,
231 },
232 'createType' : 'partitionedDevice',
233 'extents' : { '6.1/storage/t-mbr.vdi' :
234 ['RW 2048 FLAT "vmdktest-pt.vmdk" 0',
235 'RW 20480 FLAT "$(disk)" 2048',
236 'RW 20480 ZERO',
237 'RW 20480 ZERO',
238 'RW 2048 FLAT "vmdktest-pt.vmdk" 2048',
239 'RW 20480 ZERO',
240 'RW 2048 FLAT "vmdktest-pt.vmdk" 4096',
241 'RW 20480 ZERO',
242 'RW 2048 FLAT "vmdktest-pt.vmdk" 6144',
243 'RW 20480 ZERO',
244 'RW 2048 FLAT "vmdktest-pt.vmdk" 8192',
245 'RW 20480 ZERO',
246 'RW 2048 FLAT "vmdktest-pt.vmdk" 10240',
247 'RW 4036608 ZERO',
248 'RW 36028797014771712 ZERO',
249 ],
250 '6.1/storage/t-gpt.vdi' :
251 ['RW 1 FLAT "vmdktest-pt.vmdk" 0',
252 'RW 2047 FLAT "vmdktest-pt.vmdk" 1',
253 'RW 20480 FLAT "$(disk)" 2048',
254 'RW 20480 ZERO',
255 'RW 20480 ZERO',
256 'RW 20480 ZERO',
257 'RW 20480 ZERO',
258 'RW 20480 ZERO',
259 'RW 20480 ZERO',
260 'RW 20480 ZERO',
261 'RW 4026368 ZERO',
262 'RW 36028797014771712 ZERO',
263 ],
264 },
265 },
266 {
267 'action' : '2 partitions with boot sector',
268 'options' : ['--property', 'Partitions=1,$(4)',
269 '--property-file', 'BootSector=$(bootsector)'],
270 'data-crc' : {'6.1/storage/t-mbr.vdi' : 3980784439,
271 '6.1/storage/t-gpt.vdi' : 1152317131,
272 },
273 'createType' : 'partitionedDevice',
274 'extents' : { '6.1/storage/t-mbr.vdi' :
275 ['RW 2048 FLAT "vmdktest-pt.vmdk" 0',
276 'RW 20480 FLAT "$(disk)" 2048',
277 'RW 20480 ZERO',
278 'RW 20480 ZERO',
279 'RW 2048 FLAT "vmdktest-pt.vmdk" 2048',
280 'RW 20480 FLAT "$(disk)" 65536',
281 'RW 2048 FLAT "vmdktest-pt.vmdk" 4096',
282 'RW 20480 ZERO',
283 'RW 2048 FLAT "vmdktest-pt.vmdk" 6144',
284 'RW 20480 ZERO',
285 'RW 2048 FLAT "vmdktest-pt.vmdk" 8192',
286 'RW 20480 ZERO',
287 'RW 2048 FLAT "vmdktest-pt.vmdk" 10240',
288 'RW 4036608 ZERO',
289 'RW 36028797014771712 ZERO',
290 ],
291 '6.1/storage/t-gpt.vdi' :
292 ['RW 1 FLAT "vmdktest-pt.vmdk" 0',
293 'RW 2047 FLAT "vmdktest-pt.vmdk" 1',
294 'RW 20480 FLAT "$(disk)" 2048',
295 'RW 20480 ZERO',
296 'RW 20480 ZERO',
297 'RW 20480 FLAT "$(disk)" 63488',
298 'RW 20480 ZERO',
299 'RW 20480 ZERO',
300 'RW 20480 ZERO',
301 'RW 20480 ZERO',
302 'RW 4026368 ZERO',
303 'RW 36028797014771712 ZERO',
304 ],
305 },
306 },
307 {
308 'action' : '1 partition with relative names',
309 'options' : ['--property', 'Partitions=1', '--property', 'Relative=1'],
310 'data-crc' : {'6.1/storage/t-mbr.vdi' : 2681429243,
311 '6.1/storage/t-gpt.vdi' : 1391394051,
312 },
313 'createType' : 'partitionedDevice',
314 'extents' : { '6.1/storage/t-mbr.vdi' :
315 ['RW 2048 FLAT "vmdktest-pt.vmdk" 0',
316 'RW 20480 FLAT "$(part)1" 0',
317 'RW 20480 ZERO',
318 'RW 20480 ZERO',
319 'RW 2048 FLAT "vmdktest-pt.vmdk" 2048',
320 'RW 20480 ZERO',
321 'RW 2048 FLAT "vmdktest-pt.vmdk" 4096',
322 'RW 20480 ZERO',
323 'RW 2048 FLAT "vmdktest-pt.vmdk" 6144',
324 'RW 20480 ZERO',
325 'RW 2048 FLAT "vmdktest-pt.vmdk" 8192',
326 'RW 20480 ZERO',
327 'RW 2048 FLAT "vmdktest-pt.vmdk" 10240',
328 'RW 4036608 ZERO',
329 'RW 36028797014771712 ZERO',
330 ],
331 '6.1/storage/t-gpt.vdi' :
332 ['RW 1 FLAT "vmdktest-pt.vmdk" 0',
333 'RW 2047 FLAT "vmdktest-pt.vmdk" 1',
334 'RW 20480 FLAT "$(part)1" 0',
335 'RW 20480 ZERO',
336 'RW 20480 ZERO',
337 'RW 20480 ZERO',
338 'RW 20480 ZERO',
339 'RW 20480 ZERO',
340 'RW 20480 ZERO',
341 'RW 20480 ZERO',
342 'RW 4026368 ZERO',
343 'RW 36028797014771712 ZERO',
344 ],
345 },
346 },
347 {
348 'action' : '2 partitions with relative names',
349 'options' : ['--property', 'Partitions=1,$(4)', '--property', 'Relative=1'],
350 'data-crc' : {'6.1/storage/t-mbr.vdi' : 2681429243,
351 '6.1/storage/t-gpt.vdi' : 1391394051,
352 },
353 'createType' : 'partitionedDevice',
354 'extents' : { '6.1/storage/t-mbr.vdi' :
355 ['RW 2048 FLAT "vmdktest-pt.vmdk" 0',
356 'RW 20480 FLAT "$(part)1" 0',
357 'RW 20480 ZERO',
358 'RW 20480 ZERO',
359 'RW 2048 FLAT "vmdktest-pt.vmdk" 2048',
360 'RW 20480 FLAT "$(part)$(4)" 0',
361 'RW 2048 FLAT "vmdktest-pt.vmdk" 4096',
362 'RW 20480 ZERO',
363 'RW 2048 FLAT "vmdktest-pt.vmdk" 6144',
364 'RW 20480 ZERO',
365 'RW 2048 FLAT "vmdktest-pt.vmdk" 8192',
366 'RW 20480 ZERO',
367 'RW 2048 FLAT "vmdktest-pt.vmdk" 10240',
368 'RW 4036608 ZERO',
369 'RW 36028797014771712 ZERO',
370 ],
371 '6.1/storage/t-gpt.vdi' :
372 ['RW 1 FLAT "vmdktest-pt.vmdk" 0',
373 'RW 2047 FLAT "vmdktest-pt.vmdk" 1',
374 'RW 20480 FLAT "$(part)1" 0',
375 'RW 20480 ZERO',
376 'RW 20480 ZERO',
377 'RW 20480 FLAT "$(part)$(4)" 0',
378 'RW 20480 ZERO',
379 'RW 20480 ZERO',
380 'RW 20480 ZERO',
381 'RW 20480 ZERO',
382 'RW 4026368 ZERO',
383 'RW 36028797014771712 ZERO',
384 ],
385 },
386 },
387 ];
388
389
390 def _findFile(self, sRegExp, asTestBuildDirs):
391 """
392 Returns a filepath based on the given regex and paths to look into
393 or None if no matching file is found.
394 """
395 oRegExp = re.compile(sRegExp);
396 for sTestBuildDir in asTestBuildDirs:
397 try:
398 #return most recent file if there are several ones matching the pattern
399 asFiles = [s for s in os.listdir(sTestBuildDir)
400 if os.path.isfile(os.path.join(sTestBuildDir, s))];
401 asFiles = (s for s in asFiles
402 if oRegExp.match(os.path.basename(s))
403 and os.path.exists(sTestBuildDir + '/' + s));
404 asFiles = sorted(asFiles, reverse = True,
405 key = lambda s, sTstBuildDir = sTestBuildDir: os.path.getmtime(os.path.join(sTstBuildDir, s)));
406 if asFiles:
407 return sTestBuildDir + '/' + asFiles[0];
408 except:
409 pass;
410 reporter.error('Failed to find a file matching "%s" in %s.' % (sRegExp, ','.join(asTestBuildDirs)));
411 return None;
412
413 def _waitAdditionsIsRunning(self, oGuest, fWaitTrayControl):
414 """
415 Check is the additions running
416 """
417 cAttempt = 0;
418 fRc = False;
419 while cAttempt < 30:
420 fRc = oGuest.additionsRunLevel in [vboxcon.AdditionsRunLevelType_Userland,
421 vboxcon.AdditionsRunLevelType_Desktop];
422 if fRc:
423 eServiceStatus, _ = oGuest.getFacilityStatus(vboxcon.AdditionsFacilityType_VBoxService);
424 fRc = eServiceStatus == vboxcon.AdditionsFacilityStatus_Active;
425 if fRc and not fWaitTrayControl:
426 break;
427 if fRc:
428 eServiceStatus, _ = oGuest.getFacilityStatus(vboxcon.AdditionsFacilityType_VBoxTrayClient);
429 fRc = eServiceStatus == vboxcon.AdditionsFacilityStatus_Active;
430 if fRc:
431 break;
432 self.oTstDrv.sleep(10);
433 cAttempt += 1;
434 return fRc;
435
436 def createSession(self, oSession, sName, sUser, sPassword, cMsTimeout = 10 * 1000, fIsError = True):
437 """
438 Creates (opens) a guest session.
439 Returns (True, IGuestSession) on success or (False, None) on failure.
440 """
441 oGuest = oSession.o.console.guest;
442 if sName is None:
443 sName = "<untitled>";
444 reporter.log('Creating session "%s" ...' % (sName,));
445 try:
446 oGuestSession = oGuest.createSession(sUser, sPassword, '', sName);
447 except:
448 # Just log, don't assume an error here (will be done in the main loop then).
449 reporter.maybeErrXcpt(fIsError, 'Creating a guest session "%s" failed; sUser="%s", pw="%s"'
450 % (sName, sUser, sPassword));
451 return (False, None);
452 reporter.log('Waiting for session "%s" to start within %dms...' % (sName, cMsTimeout));
453 aeWaitFor = [ vboxcon.GuestSessionWaitForFlag_Start, ];
454 try:
455 waitResult = oGuestSession.waitForArray(aeWaitFor, cMsTimeout);
456 #
457 # Be nice to Guest Additions < 4.3: They don't support session handling and
458 # therefore return WaitFlagNotSupported.
459 #
460 if waitResult not in (vboxcon.GuestSessionWaitResult_Start, vboxcon.GuestSessionWaitResult_WaitFlagNotSupported):
461 # Just log, don't assume an error here (will be done in the main loop then).
462 reporter.maybeErr(fIsError, 'Session did not start successfully, returned wait result: %d' % (waitResult,));
463 return (False, None);
464 reporter.log('Session "%s" successfully started' % (sName,));
465 except:
466 # Just log, don't assume an error here (will be done in the main loop then).
467 reporter.maybeErrXcpt(fIsError, 'Waiting for guest session "%s" (usr=%s;pw=%s) to start failed:'
468 % (sName, sUser, sPassword,));
469 return (False, None);
470 return (True, oGuestSession);
471
472 def closeSession(self, oGuestSession, fIsError = True):
473 """
474 Closes the guest session.
475 """
476 if oGuestSession is not None:
477 try:
478 sName = oGuestSession.name;
479 except:
480 return reporter.errorXcpt();
481 reporter.log('Closing session "%s" ...' % (sName,));
482 try:
483 oGuestSession.close();
484 oGuestSession = None;
485 except:
486 # Just log, don't assume an error here (will be done in the main loop then).
487 reporter.maybeErrXcpt(fIsError, 'Closing guest session "%s" failed:' % (sName,));
488 return False;
489 return True;
490
491 def guestProcessExecute(self, oGuestSession, sTestName, cMsTimeout, sExecName, asArgs = (),
492 fGetStdOut = True, fIsError = True):
493 """
494 Helper function to execute a program on a guest, specified in the current test.
495 Returns (True, ProcessStatus, ProcessExitCode, ProcessStdOutBuffer) on success or (False, 0, 0, None) on failure.
496 """
497 _ = sTestName;
498 fRc = True; # Be optimistic.
499 reporter.log2('Using session user=%s, name=%s, timeout=%d'
500 % (oGuestSession.user, oGuestSession.name, oGuestSession.timeout,));
501 #
502 # Start the process:
503 #
504 reporter.log2('Executing sCmd=%s, timeoutMS=%d, asArgs=%s'
505 % (sExecName, cMsTimeout, asArgs, ));
506 fTaskFlags = [];
507 if fGetStdOut:
508 fTaskFlags = [vboxcon.ProcessCreateFlag_WaitForStdOut,
509 vboxcon.ProcessCreateFlag_WaitForStdErr];
510 try:
511 oProcess = oGuestSession.processCreate(sExecName,
512 asArgs if self.oTstDrv.fpApiVer >= 5.0 else asArgs[1:],
513 [], fTaskFlags, cMsTimeout);
514 except:
515 reporter.maybeErrXcpt(fIsError, 'asArgs=%s' % (asArgs,));
516 return (False, 0, 0, None);
517 if oProcess is None:
518 return (reporter.error('oProcess is None! (%s)' % (asArgs,)), 0, 0, None);
519 #time.sleep(5); # try this if you want to see races here.
520 # Wait for the process to start properly:
521 reporter.log2('Process start requested, waiting for start (%dms) ...' % (cMsTimeout,));
522 iPid = -1;
523 aeWaitFor = [ vboxcon.ProcessWaitForFlag_Start, ];
524 aBuf = None;
525 try:
526 eWaitResult = oProcess.waitForArray(aeWaitFor, cMsTimeout);
527 except:
528 reporter.maybeErrXcpt(fIsError, 'waitforArray failed for asArgs=%s' % (asArgs,));
529 fRc = False;
530 else:
531 try:
532 eStatus = oProcess.status;
533 iPid = oProcess.PID;
534 except:
535 fRc = reporter.errorXcpt('asArgs=%s' % (asArgs,));
536 else:
537 reporter.log2('Wait result returned: %d, current process status is: %d' % (eWaitResult, eStatus,));
538 #
539 # Wait for the process to run to completion if necessary.
540 #
541 # Note! The above eWaitResult return value can be ignored as it will
542 # (mostly) reflect the process status anyway.
543 #
544 if eStatus == vboxcon.ProcessStatus_Started:
545 # What to wait for:
546 aeWaitFor = [ vboxcon.ProcessWaitForFlag_Terminate,
547 vboxcon.ProcessWaitForFlag_StdOut,
548 vboxcon.ProcessWaitForFlag_StdErr];
549 reporter.log2('Process (PID %d) started, waiting for termination (%dms), aeWaitFor=%s ...'
550 % (iPid, cMsTimeout, aeWaitFor));
551 acbFdOut = [0,0,0];
552 while True:
553 try:
554 eWaitResult = oProcess.waitForArray(aeWaitFor, cMsTimeout);
555 except KeyboardInterrupt: # Not sure how helpful this is, but whatever.
556 reporter.error('Process (PID %d) execution interrupted' % (iPid,));
557 try: oProcess.close();
558 except: pass;
559 break;
560 except:
561 fRc = reporter.errorXcpt('asArgs=%s' % (asArgs,));
562 break;
563 reporter.log2('Wait returned: %d' % (eWaitResult,));
564 # Process output:
565 for eFdResult, iFd, sFdNm in [ (vboxcon.ProcessWaitResult_StdOut, 1, 'stdout'),
566 (vboxcon.ProcessWaitResult_StdErr, 2, 'stderr'), ]:
567 if eWaitResult in (eFdResult, vboxcon.ProcessWaitResult_WaitFlagNotSupported):
568 reporter.log2('Reading %s ...' % (sFdNm,));
569 try:
570 abBuf = oProcess.read(iFd, 64 * 1024, cMsTimeout);
571 except KeyboardInterrupt: # Not sure how helpful this is, but whatever.
572 reporter.error('Process (PID %d) execution interrupted' % (iPid,));
573 try: oProcess.close();
574 except: pass;
575 except:
576 pass; ## @todo test for timeouts and fail on anything else!
577 else:
578 if abBuf:
579 reporter.log2('Process (PID %d) got %d bytes of %s data' % (iPid, len(abBuf), sFdNm,));
580 acbFdOut[iFd] += len(abBuf);
581 ## @todo Figure out how to uniform + append!
582 sBuf = '';
583 if sys.version_info >= (2, 7) and isinstance(abBuf, memoryview):
584 abBuf = abBuf.tobytes();
585 sBuf = abBuf.decode("utf-8");
586 else:
587 sBuf = str(abBuf);
588 if aBuf:
589 aBuf += sBuf;
590 else:
591 aBuf = sBuf;
592 ## Process input (todo):
593 #if eWaitResult in (vboxcon.ProcessWaitResult_StdIn, vboxcon.ProcessWaitResult_WaitFlagNotSupported):
594 # reporter.log2('Process (PID %d) needs stdin data' % (iPid,));
595 # Termination or error?
596 if eWaitResult in (vboxcon.ProcessWaitResult_Terminate,
597 vboxcon.ProcessWaitResult_Error,
598 vboxcon.ProcessWaitResult_Timeout,):
599 try: eStatus = oProcess.status;
600 except: fRc = reporter.errorXcpt('asArgs=%s' % (asArgs,));
601 reporter.log2('Process (PID %d) reported terminate/error/timeout: %d, status: %d'
602 % (iPid, eWaitResult, eStatus,));
603 break;
604 # End of the wait loop.
605 _, cbStdOut, cbStdErr = acbFdOut;
606 try: eStatus = oProcess.status;
607 except: fRc = reporter.errorXcpt('asArgs=%s' % (asArgs,));
608 reporter.log2('Final process status (PID %d) is: %d' % (iPid, eStatus));
609 reporter.log2('Process (PID %d) %d stdout, %d stderr' % (iPid, cbStdOut, cbStdErr));
610 #
611 # Get the final status and exit code of the process.
612 #
613 try:
614 uExitStatus = oProcess.status;
615 iExitCode = oProcess.exitCode;
616 except:
617 fRc = reporter.errorXcpt('asArgs=%s' % (asArgs,));
618 reporter.log2('Process (PID %d) has exit code: %d; status: %d ' % (iPid, iExitCode, uExitStatus));
619 return (fRc, uExitStatus, iExitCode, aBuf);
620
621 def uploadString(self, oGuestSession, sSrcString, sDst):
622 """
623 Upload the string into guest.
624 """
625 fRc = True;
626 try:
627 oFile = oGuestSession.fileOpenEx(sDst, vboxcon.FileAccessMode_ReadWrite, vboxcon.FileOpenAction_CreateOrReplace,
628 vboxcon.FileSharingMode_All, 0, []);
629 except:
630 fRc = reporter.errorXcpt('Upload string failed. Could not create and open the file %s' % sDst);
631 else:
632 try:
633 oFile.write(bytearray(sSrcString), 60*1000);
634 except:
635 fRc = reporter.errorXcpt('Upload string failed. Could not write the string into the file %s' % sDst);
636 try:
637 oFile.close();
638 except:
639 fRc = reporter.errorXcpt('Upload string failed. Could not close the file %s' % sDst);
640 return fRc;
641
642 def uploadFile(self, oGuestSession, sSrc, sDst):
643 """
644 Upload the string into guest.
645 """
646 fRc = True;
647 try:
648 if self.oTstDrv.fpApiVer >= 5.0:
649 oCurProgress = oGuestSession.fileCopyToGuest(sSrc, sDst, [0]);
650 else:
651 oCurProgress = oGuestSession.copyTo(sSrc, sDst, [0]);
652 except:
653 reporter.maybeErrXcpt(True, 'Upload file exception for sSrc="%s":'
654 % (self.sGuestAdditionsIso,));
655 fRc = False;
656 else:
657 if oCurProgress is not None:
658 oWrapperProgress = vboxwrappers.ProgressWrapper(oCurProgress, self.oTstDrv.oVBoxMgr, self.oTstDrv, "uploadFile");
659 oWrapperProgress.wait();
660 if not oWrapperProgress.isSuccess():
661 oWrapperProgress.logResult(fIgnoreErrors = False);
662 fRc = False;
663 else:
664 fRc = reporter.error('No progress object returned');
665 return fRc;
666
667 def downloadFile(self, oGuestSession, sSrc, sDst, fIgnoreErrors = False):
668 """
669 Get a file (sSrc) from the guest storing it on the host (sDst).
670 """
671 fRc = True;
672 try:
673 if self.oTstDrv.fpApiVer >= 5.0:
674 oCurProgress = oGuestSession.fileCopyFromGuest(sSrc, sDst, [0]);
675 else:
676 oCurProgress = oGuestSession.copyFrom(sSrc, sDst, [0]);
677 except:
678 if not fIgnoreErrors:
679 reporter.errorXcpt('Download file exception for sSrc="%s":' % (sSrc,));
680 else:
681 reporter.log('warning: Download file exception for sSrc="%s":' % (sSrc,));
682 fRc = False;
683 else:
684 if oCurProgress is not None:
685 oWrapperProgress = vboxwrappers.ProgressWrapper(oCurProgress, self.oTstDrv.oVBoxMgr,
686 self.oTstDrv, "downloadFile");
687 oWrapperProgress.wait();
688 if not oWrapperProgress.isSuccess():
689 oWrapperProgress.logResult(fIgnoreErrors);
690 fRc = False;
691 else:
692 if not fIgnoreErrors:
693 reporter.error('No progress object returned');
694 else:
695 reporter.log('warning: No progress object returned');
696 fRc = False;
697 return fRc;
698
699 def downloadFiles(self, oGuestSession, asFiles, fIgnoreErrors = False):
700 """
701 Convenience function to get files from the guest and stores it
702 into the scratch directory for later (manual) review.
703 Returns True on success.
704 Returns False on failure, logged.
705 """
706 fRc = True;
707 for sGstFile in asFiles:
708 ## @todo r=bird: You need to use the guest specific path functions here.
709 ## Best would be to add basenameEx to common/pathutils.py. See how joinEx
710 ## is used by BaseTestVm::pathJoin and such.
711 sTmpFile = os.path.join(self.oTstDrv.sScratchPath, 'tmp-' + os.path.basename(sGstFile));
712 reporter.log2('Downloading file "%s" to "%s" ...' % (sGstFile, sTmpFile));
713 # First try to remove (unlink) an existing temporary file, as we don't truncate the file.
714 try: os.unlink(sTmpFile);
715 except: pass;
716 ## @todo Check for already existing files on the host and create a new
717 # name for the current file to download.
718 fRc = self.downloadFile(oGuestSession, sGstFile, sTmpFile, fIgnoreErrors);
719 if fRc:
720 reporter.addLogFile(sTmpFile, 'misc/other', 'guest - ' + sGstFile);
721 else:
722 if fIgnoreErrors is not True:
723 reporter.error('error downloading file "%s" to "%s"' % (sGstFile, sTmpFile));
724 return fRc;
725 reporter.log('warning: file "%s" was not downloaded, ignoring.' % (sGstFile,));
726 return True;
727
728 def _checkVmIsReady(self, oGuestSession):
729 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Start a guest process',
730 30 * 1000, '/sbin/ifconfig',
731 ['ifconfig',],
732 False, False);
733 return fRc;
734
735 def waitVmIsReady(self, oSession, fWaitTrayControl):
736 """
737 Waits the VM is ready after start or reboot.
738 Returns result (true or false) and guest session obtained
739 """
740 _ = fWaitTrayControl;
741 # Give the VM a time to reboot
742 self.oTstDrv.sleep(30);
743 # Waiting the VM is ready.
744 # To do it, one will try to open the guest session and start the guest process in loop
745 if not self._waitAdditionsIsRunning(oSession.o.console.guest, False):
746 return (False, None);
747 cAttempt = 0;
748 oGuestSession = None;
749 fRc = False;
750 while cAttempt < 30:
751 fRc, oGuestSession = self.createSession(oSession, 'Session for user: vbox',
752 'vbox', 'password', 10 * 1000, False);
753 if fRc:
754 fRc = self._checkVmIsReady(oGuestSession);
755 if fRc:
756 break;
757 self.closeSession(oGuestSession, False);
758 self.oTstDrv.sleep(10);
759 cAttempt += 1;
760 return (fRc, oGuestSession);
761
762 def _rebootVM(self, oGuestSession):
763 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Reboot the VM',
764 30 * 1000, '/usr/bin/sudo',
765 ['sudo', 'reboot'],
766 False, True);
767 if not fRc:
768 reporter.error('Calling the reboot utility failed');
769 return fRc;
770
771 def rebootVMAndCheckReady(self, oSession, oGuestSession):
772 """
773 Reboot the VM and wait the VM is ready.
774 Returns result and guest session obtained after reboot
775 """
776 reporter.testStart('Reboot VM and wait for readiness');
777 fRc = self._rebootVM(oGuestSession);
778 fRc = self.closeSession(oGuestSession, True) and fRc and True; # pychecker hack.
779 if fRc:
780 (fRc, oGuestSession) = self.waitVmIsReady(oSession, False);
781 if not fRc:
782 reporter.error('VM is not ready after reboot');
783 reporter.testDone();
784 return (fRc, oGuestSession);
785
786 def _powerDownVM(self, oGuestSession):
787 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Power down the VM',
788 30 * 1000, '/usr/bin/sudo',
789 ['sudo', 'poweroff'],
790 False, True);
791 if not fRc:
792 reporter.error('Calling the poweroff utility failed');
793 return fRc;
794
795 def powerDownVM(self, oGuestSession):
796 """
797 Power down the VM by calling guest process without wating
798 the VM is really powered off. Also, closes the guest session.
799 It helps the terminateBySession to stop the VM without aborting.
800 """
801 if oGuestSession is None:
802 return False;
803 reporter.testStart('Power down the VM');
804 fRc = self._powerDownVM(oGuestSession);
805 fRc = self.closeSession(oGuestSession, True) and fRc and True; # pychecker hack.
806 if not fRc:
807 reporter.error('Power down the VM failed');
808 reporter.testDone();
809 return fRc;
810
811 def installAdditions(self, oSession, oGuestSession, oVM):
812 """
813 Installs the Windows guest additions using the test execution service.
814 """
815 _ = oSession;
816 _ = oGuestSession;
817 _ = oVM;
818 reporter.error('Not implemented');
819 return False;
820
821 def installVirtualBox(self, oGuestSession):
822 """
823 Install VirtualBox in the guest.
824 """
825 _ = oGuestSession;
826 reporter.error('Not implemented');
827 return False;
828
829 def getResourceSet(self):
830 asRet = [];
831 if not os.path.isabs(self.sHdd):
832 asRet.append(self.sHdd);
833 return asRet;
834
835 def _createVmDoIt(self, oTestDrv, eNic0AttachType, sDvdImage):
836 """
837 Creates the VM.
838 Returns Wrapped VM object on success, None on failure.
839 """
840 _ = eNic0AttachType;
841 _ = sDvdImage;
842 return oTestDrv.createTestVM(self.sVmName, self.iGroup, self.sHdd, sKind = self.sKind, \
843 fIoApic = True, eNic0AttachType = vboxcon.NetworkAttachmentType_NAT, \
844 eNic0Type = self.eNic0Type, cMbRam = self.cMbRam, \
845 sHddControllerType = "SATA Controller", fPae = self.fPae, \
846 cCpus = self.cCpus, sDvdImage = self.sGuestAdditionsIso);
847
848 def _createVmPost(self, oTestDrv, oVM, eNic0AttachType, sDvdImage):
849 _ = eNic0AttachType;
850 _ = sDvdImage;
851 fRc = True;
852 oSession = oTestDrv.openSession(oVM);
853 if oSession is not None:
854 fRc = fRc and oSession.enableVirtEx(True);
855 # nested paging doesn't need for the test
856 #fRc = fRc and oSession.enableNestedPaging(True);
857 #fRc = fRc and oSession.enableNestedHwVirt(True);
858 # disable 3D until the error is fixed.
859 fRc = fRc and oSession.setAccelerate3DEnabled(False);
860 fRc = fRc and oSession.setVRamSize(256);
861 fRc = fRc and oSession.setVideoControllerType(vboxcon.GraphicsControllerType_VBoxSVGA);
862 fRc = fRc and oSession.enableUsbOhci(True);
863 fRc = fRc and oSession.enableUsbHid(True);
864 fRc = fRc and oSession.saveSettings();
865 fRc = oSession.close() and fRc and True; # pychecker hack.
866 oSession = None;
867 else:
868 fRc = False;
869 return oVM if fRc else None;
870
871 def getReconfiguredVm(self, oTestDrv, cCpus, sVirtMode, sParavirtMode = None):
872 #
873 # Current test uses precofigured VMs. This override disables any changes in the machine.
874 #
875 _ = cCpus;
876 _ = sVirtMode;
877 _ = sParavirtMode;
878 oVM = oTestDrv.getVmByName(self.sVmName);
879 if oVM is None:
880 return (False, None);
881 return (True, oVM);
882
883 def reattachHdd(self, oVM, sHdd, asHdds):
884 """
885 Attach required hdd and remove all others from asHdds list.
886 """
887 reporter.testStart("Reattach hdd");
888 oSession = self.oTstDrv.openSession(oVM);
889 fRc = False;
890 if oSession is not None:
891 # for simplicity and because we are using VMs having "SATA controller"
892 # we will add the hdds to only "SATA controller"
893 iPortNew = 0;
894 fFound = False;
895 try:
896 aoAttachments = self.oTstDrv.oVBox.oVBoxMgr.getArray(oVM, 'mediumAttachments');
897 except:
898 fRc = reporter.errorXcpt();
899 else:
900 for oAtt in aoAttachments:
901 try:
902 sCtrl = oAtt.controller
903 iPort = oAtt.port;
904 iDev = oAtt.device;
905 eType = oAtt.type;
906 except:
907 fRc = reporter.errorXcpt();
908 break;
909
910 fDetached = False;
911 if eType == vboxcon.DeviceType_HardDisk:
912 oMedium = oVM.getMedium(sCtrl, iPort, iDev);
913 if oMedium.location.endswith(sHdd):
914 fRc = True;
915 fFound = True;
916 break;
917 for sHddVar in asHdds:
918 if oMedium.location.endswith(sHddVar) \
919 or oMedium.parent is not None and oMedium.parent.location.endswith(sHddVar) :
920 (fRc, oOldHd) = oSession.detachHd(sCtrl, iPort, iDev);
921 if fRc and oOldHd is not None:
922 fRc = oSession.saveSettings();
923 if oMedium.parent is not None:
924 fRc = fRc and self.oTstDrv.oVBox.deleteHdByMedium(oOldHd);
925 else:
926 fRc = fRc and oOldHd.close();
927 fRc = fRc and oSession.saveSettings();
928 fDetached = True;
929 if not fDetached and sCtrl == 'SATA Controller' and iPort + 1 > iPortNew:
930 iPortNew = iPort + 1;
931 if not fFound:
932 fRc = oSession.attachHd(sHdd, 'SATA Controller', iPortNew, 0);
933 if fRc:
934 fRc = oSession.saveSettings();
935 else:
936 oSession.discadSettings();
937 fRc = oSession.close() and fRc and True; # pychecker hack
938 else:
939 reporter.error("Open session for '%s' failed" % self.sVmName);
940 fRc = False;
941 reporter.testDone();
942 return fRc;
943
944 def _callVBoxManage(self, oGuestSession, sTestName, cMsTimeout, asArgs = (),
945 fGetStdOut = True, fIsError = True):
946 return self.guestProcessExecute(oGuestSession, sTestName,
947 cMsTimeout, '/usr/bin/sudo',
948 ['/usr/bin/sudo', '/opt/VirtualBox/VBoxManage'] + asArgs, fGetStdOut, fIsError);
949
950 def listHostDrives(self, oGuestSession, sHdd):
951 """
952 Define path of the specified drive using 'VBoxManage list hostdrives'.
953 """
954 reporter.testStart("List host drives");
955 sDrive = None;
956 (fRc, _, _, aBuf) = self._callVBoxManage(oGuestSession, 'List host drives', 60 * 1000,
957 ['list', 'hostdrives'], True, True);
958 if not fRc:
959 reporter.error('List host drives in the VM %s failed' % (self.sVmName, ));
960 else:
961 if aBuf is None:
962 fRc = reporter.error('"List host drives" output is empty for the VM %s' % (self.sVmName, ));
963 else:
964 asHddData = self.asHdds[sHdd];
965
966 try: aBuf = str(aBuf); # pylint: disable=redefined-variable-type
967 except: pass;
968 asLines = aBuf.splitlines();
969 oRegExp = re.compile(r'^\s*([^:]+)\s*:\s*(.+)\s*$');
970
971 # pylint: disable=no-init
972 class ParseState(object):
973 kiNothing = 0;
974 kiDrive = 1;
975 kiPartition = 2;
976
977 iParseState = ParseState.kiNothing;
978 asKeysNotFound = asHddData['Header'].keys();
979 idxPartition = 0;
980 for sLine in asLines:
981 if not sLine or sLine.startswith('#') or sLine.startswith("\n"):
982 continue;
983 oMatch = oRegExp.match(sLine);
984 if oMatch is not None:
985 sKey = oMatch.group(1);
986 sValue = oMatch.group(2);
987 if sKey is not None and sKey == 'Drive':
988 # we found required disk if we found all required disk info and partitions
989 if sDrive and not asKeysNotFound and idxPartition >= len(asHddData['Partitions']['Partitions']):
990 break;
991 sDrive = sValue;
992 iParseState = ParseState.kiDrive;
993 asKeysNotFound = asKeysNotFound = asHddData['Header'].keys();
994 idxPartition = 0;
995 continue;
996 if iParseState == ParseState.kiDrive:
997 if sLine.strip().startswith('Partitions:'):
998 iParseState = ParseState.kiPartition;
999 continue;
1000 if oMatch is None or sKey is None:
1001 continue;
1002 if sKey in asHddData['Header'].keys() and asHddData['Header'][sKey] == sValue:
1003 asKeysNotFound.remove(sKey);
1004 continue;
1005 if iParseState == ParseState.kiPartition:
1006 if idxPartition < len(asHddData['Partitions']['Partitions']):
1007 sPart = asHddData['Partitions']['Partitions'][idxPartition];
1008 sPart = sPart.replace('$(' + str(idxPartition + 1) + ')',
1009 str(asHddData['Partitions']['PartitionNumbers'][idxPartition]));
1010 if sLine.strip() == sPart:
1011 idxPartition += 1;
1012 continue;
1013 fRc = sDrive and not asKeysNotFound and idxPartition >= len(asHddData['Partitions']['Partitions']);
1014 if fRc:
1015 reporter.log("Path to the drive '%s' in the VM '%s': %s " % (sHdd, self.sVmName, sDrive));
1016 else:
1017 reporter.error("Path to drive '%s' not found in the VM '%s'" % (sHdd, self.sVmName));
1018 reporter.testDone();
1019 return (fRc, sDrive);
1020
1021 def convertDiskToPartitionPrefix(self, sDisk):
1022 return sDisk;
1023
1024 def checkVMDKDescriptor(self, asDescriptor, sHdd, sRawDrive, asAction):
1025 """
1026 Check VMDK descriptor of the disk created
1027 """
1028 if asDescriptor is None \
1029 or asDescriptor[0] != '# Disk DescriptorFile' \
1030 and asDescriptor[0] != '# Disk Descriptor File' \
1031 and asDescriptor[0] != '#Disk Descriptor File' \
1032 and asDescriptor[0] != '#Disk DescriptorFile':
1033 return reporter.error("VMDK descriptor has invalid format");
1034
1035 # pylint: disable=no-init
1036 class DescriptorParseState(object):
1037 kiHeader = 1;
1038 kiExtent = 2;
1039 kiDatabase = 3;
1040
1041 asHddData = self.asHdds[sHdd];
1042 iParseState = DescriptorParseState.kiHeader;
1043
1044 asHeader = { 'version' : '1',
1045 'CID' : '*',
1046 'parentCID' : 'ffffffff',
1047 'createType' : '$'
1048 };
1049
1050 asDatabase = { 'ddb.virtualHWVersion' : '4',
1051 'ddb.adapterType' : 'ide',
1052 'ddb.uuid.image' : '*',
1053 'ddb.uuid.parent' : '00000000-0000-0000-0000-000000000000',
1054 'ddb.uuid.modification' : '00000000-0000-0000-0000-000000000000',
1055 'ddb.uuid.parentmodification' : '00000000-0000-0000-0000-000000000000'
1056 };
1057
1058 oRegExp = re.compile(r'^\s*([^=]+)\s*=\s*\"*([^\"]+)\"*\s*$');
1059 iExtentIdx = 0;
1060
1061 for sLine in asDescriptor:
1062 if not sLine or sLine.startswith('#') or sLine.startswith("\n"):
1063 continue;
1064
1065 if iParseState == DescriptorParseState.kiHeader:
1066 if sLine.startswith('ddb.'):
1067 return reporter.error("VMDK descriptor has invalid order of sections");
1068 if sLine.startswith("RW") \
1069 or sLine.startswith("RDONLY") \
1070 or sLine.startswith("NOACCESS"):
1071 iParseState = DescriptorParseState.kiExtent;
1072 else:
1073 oMatch = oRegExp.match(sLine);
1074 if oMatch is None:
1075 return reporter.error("VMDK descriptor contains lines in invalid form");
1076 sKey = oMatch.group(1).strip();
1077 sValue = oMatch.group(2).strip();
1078 if sKey not in asHeader.keys():
1079 return reporter.error("VMDK descriptor has invalid format");
1080 sDictValue = asHeader[sKey];
1081 if sDictValue == '$':
1082 sDictValue = asAction[sKey];
1083 if sDictValue not in ('*', sValue):
1084 return reporter.error("VMDK descriptor has value which was not expected");
1085 continue;
1086
1087 if iParseState == DescriptorParseState.kiExtent:
1088 if sLine.startswith('ddb.'):
1089 iParseState = DescriptorParseState.kiDatabase;
1090 else:
1091 if not sLine.startswith("RW") \
1092 and not sLine.startswith("RDONLY") \
1093 and not sLine.startswith("NOACCESS"):
1094 return reporter.error("VMDK descriptor has invalid order of sections");
1095 sExtent = asAction['extents'][sHdd][iExtentIdx];
1096 sExtent = sExtent.replace('$(disk)', sRawDrive);
1097 sExtent = sExtent.replace('$(part)', self.convertDiskToPartitionPrefix(sRawDrive));
1098 sExtent = re.sub(r'\$\((\d+)\)',
1099 lambda oMatch: str(asHddData['Partitions']['PartitionNumbers'][int(oMatch.group(1)) - 1]),
1100 sExtent);
1101 if sExtent != sLine.strip():
1102 return reporter.error("VMDK descriptor has invalid order of sections");
1103 iExtentIdx += 1;
1104 continue;
1105
1106 if iParseState == DescriptorParseState.kiDatabase:
1107 if not sLine.startswith('ddb.'):
1108 return reporter.error("VMDK descriptor has invalid order of sections");
1109 oMatch = oRegExp.match(sLine);
1110 if oMatch is None:
1111 return reporter.error("VMDK descriptor contains lines in invalid form");
1112 sKey = oMatch.group(1).strip();
1113 sValue = oMatch.group(2).strip();
1114 if sKey not in asDatabase.keys():
1115 return reporter.error("VMDK descriptor has invalid format");
1116 sDictValue = asDatabase[sKey];
1117 if sDictValue not in ('*', sValue):
1118 return reporter.error("VMDK descriptor has value which was not expected");
1119 continue;
1120 return iParseState == DescriptorParseState.kiDatabase;
1121
1122 def _setPermissionsToVmdkFiles(self, oGuestSession):
1123 """
1124 Sets 0644 permissions to all files in the self.sVMDKPath allowing reading them by 'vbox' user.
1125 """
1126 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession,
1127 'Allowing reading of the VMDK content by vbox user',
1128 30 * 1000, '/usr/bin/sudo',
1129 ['/usr/bin/sudo', '/bin/chmod', '644',
1130 self.sVMDKPath + '/vmdktest.vmdk', self.sVMDKPath + '/vmdktest-pt.vmdk'],
1131 False, True);
1132 return fRc;
1133
1134 def createDrives(self, oGuestSession, sHdd, sRawDrive):
1135 """
1136 Creates VMDK Raw file and check correctness
1137 """
1138 reporter.testStart("Create VMDK disks");
1139 asHddData = self.asHdds[sHdd];
1140 fRc = True;
1141 try: oGuestSession.directoryCreate(self.sVMDKPath, 0o777, (vboxcon.DirectoryCreateFlag_Parents,));
1142 except: fRc = reporter.errorXcpt('Create directory for VMDK files failed in the VM %s' % (self.sVmName));
1143 if fRc:
1144 sBootSectorGuestPath = self.sVMDKPath + self.sPathDelimiter + 't-bootsector.bin';
1145 try: fExists = oGuestSession.fileExists(sBootSectorGuestPath, False);
1146 except: fExists = False;
1147 if not fExists:
1148 sBootSectorPath = self.oTstDrv.getFullResourceName(self.sBootSector);
1149 fRc = self.uploadFile(oGuestSession, sBootSectorPath, sBootSectorGuestPath);
1150
1151 for action in self.asActions:
1152 reporter.testStart("Create VMDK disk: %s" % action["action"]);
1153 asOptions = action['options'];
1154 asOptions = [option.replace('$(bootsector)', sBootSectorGuestPath) for option in asOptions];
1155 asOptions = [re.sub(r'\$\((\d+)\)',
1156 lambda oMatch: str(asHddData['Partitions']['PartitionNumbers'][int(oMatch.group(1)) - 1]),
1157 option)
1158 for option in asOptions];
1159 (fRc, _, _, _) = self._callVBoxManage(oGuestSession, 'Create VMDK disk', 60 * 1000,
1160 ['createmedium', '--filename',
1161 self.sVMDKPath + self.sPathDelimiter + 'vmdktest.vmdk',
1162 '--format', 'VMDK', '--variant', 'RawDisk',
1163 '--property', 'RawDrive=%s' % (sRawDrive,) ] + asOptions,
1164 False, True);
1165 if not fRc:
1166 reporter.error('Create VMDK raw drive variant "%s" failed in the VM %s' % (action["action"], self.sVmName));
1167 else:
1168 fRc = self._setPermissionsToVmdkFiles(oGuestSession);
1169 if not fRc:
1170 reporter.error('Setting permissions to VMDK files failed');
1171 else:
1172 sSrcFile = self.sVMDKPath + self.sPathDelimiter + 'vmdktest.vmdk';
1173 sDstFile = os.path.join(self.oTstDrv.sScratchPath, 'guest-vmdktest.vmdk');
1174 reporter.log2('Downloading file "%s" to "%s" ...' % (sSrcFile, sDstFile));
1175 # First try to remove (unlink) an existing temporary file, as we don't truncate the file.
1176 try: os.unlink(sDstFile);
1177 except: pass;
1178 fRc = self.downloadFile(oGuestSession, sSrcFile, sDstFile, False);
1179 if not fRc:
1180 reporter.error('Download vmdktest.vmdk from guest to host failed');
1181 else:
1182 with open(sDstFile) as oFile:
1183 asDescriptor = [row.strip() for row in oFile];
1184 if not asDescriptor:
1185 fRc = reporter.error('Reading vmdktest.vmdk from guest filed');
1186 else:
1187 fRc = self.checkVMDKDescriptor(asDescriptor, sHdd, sRawDrive, action);
1188 if not fRc:
1189 reporter.error('Cheking vmdktest.vmdk from guest filed');
1190 elif action['data-crc']:
1191 sSrcFile = self.sVMDKPath + self.sPathDelimiter + 'vmdktest-pt.vmdk';
1192 sDstFile = os.path.join(self.oTstDrv.sScratchPath, 'guest-vmdktest-pt.vmdk');
1193 reporter.log2('Downloading file "%s" to "%s" ...' % (sSrcFile, sDstFile));
1194 # First try to remove (unlink) an existing temporary file, as we don't truncate the file.
1195 try: os.unlink(sDstFile);
1196 except: pass;
1197 fRc = self.downloadFile(oGuestSession, sSrcFile, sDstFile, False);
1198 if not fRc:
1199 reporter.error('Download vmdktest-pt.vmdk from guest to host failed');
1200 else:
1201 uResCrc32 = utils.calcCrc32OfFile(sDstFile);
1202 if uResCrc32 != action['data-crc'][sHdd]:
1203 fRc = reporter.error('vmdktest-pt.vmdk does not match what was expected');
1204 (fRc1, _, _, _) = self._callVBoxManage(oGuestSession, 'Delete VMDK disk', 60 * 1000,
1205 ['closemedium',
1206 self.sVMDKPath + self.sPathDelimiter + 'vmdktest.vmdk',
1207 '--delete'],
1208 False, True);
1209 if not fRc1:
1210 reporter.error('Delete VMDK raw drive variant "%s" failed in the VM %s' %
1211 (action["action"], self.sVmName));
1212 fRc = fRc and fRc1;
1213 reporter.testDone();
1214 if not fRc:
1215 break;
1216 else:
1217 reporter.error('Create %s dir failed in the VM %s' % (self.sVMDKPath, self.sVmName));
1218
1219 reporter.testDone();
1220 return fRc;
1221
1222
1223class tdStorageRawDriveOsLinux(tdStorageRawDriveOs):
1224 """
1225 Autostart support methods for Linux guests.
1226 """
1227 # pylint: disable=too-many-arguments
1228 def __init__(self, oSet, oTstDrv, sVmName, sKind, sHdd, eNic0Type = None, cMbRam = None, \
1229 cCpus = 1, fPae = None, sGuestAdditionsIso = None, sBootSector = None):
1230 tdStorageRawDriveOs.__init__(self, oSet, oTstDrv, sVmName, sKind, sHdd, eNic0Type, cMbRam, \
1231 cCpus, fPae, sGuestAdditionsIso, sBootSector);
1232 self.sVBoxInstaller = '^VirtualBox-.*\\.run$';
1233 return;
1234
1235 def installAdditions(self, oSession, oGuestSession, oVM):
1236 """
1237 Install guest additions in the guest.
1238 """
1239 reporter.testStart('Install Guest Additions');
1240 fRc = False;
1241 # Install Kernel headers, which are required for actually installing the Linux Additions.
1242 if oVM.OSTypeId.startswith('Debian') \
1243 or oVM.OSTypeId.startswith('Ubuntu'):
1244 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Installing Kernel headers',
1245 5 * 60 *1000, '/usr/bin/apt-get',
1246 ['/usr/bin/apt-get', 'install', '-y',
1247 'linux-headers-generic'],
1248 False, True);
1249 if not fRc:
1250 reporter.error('Error installing Kernel headers');
1251 else:
1252 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Installing Guest Additions depdendencies',
1253 5 * 60 *1000, '/usr/bin/apt-get',
1254 ['/usr/bin/apt-get', 'install', '-y', 'build-essential',
1255 'perl'], False, True);
1256 if not fRc:
1257 reporter.error('Error installing additional installer dependencies');
1258 elif oVM.OSTypeId.startswith('OL') \
1259 or oVM.OSTypeId.startswith('Oracle') \
1260 or oVM.OSTypeId.startswith('RHEL') \
1261 or oVM.OSTypeId.startswith('Redhat') \
1262 or oVM.OSTypeId.startswith('Cent'):
1263 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Installing Kernel headers',
1264 5 * 60 *1000, '/usr/bin/yum',
1265 ['/usr/bin/yum', '-y', 'install', 'kernel-headers'],
1266 False, True);
1267 if not fRc:
1268 reporter.error('Error installing Kernel headers');
1269 else:
1270 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Installing Guest Additions depdendencies',
1271 5 * 60 *1000, '/usr/bin/yum',
1272 ['/usr/bin/yum', '-y', 'install', 'make', 'automake', 'gcc',
1273 'kernel-devel', 'dkms', 'bzip2', 'perl'], False, True);
1274 if not fRc:
1275 reporter.error('Error installing additional installer dependencies');
1276 else:
1277 reporter.error('Installing Linux Additions for the "%s" is not supported yet' % oVM.OSTypeId);
1278 fRc = False;
1279 if fRc:
1280 #
1281 # The actual install.
1282 # Also tell the installer to produce the appropriate log files.
1283 #
1284 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Installing guest additions',
1285 10 * 60 *1000, '/usr/bin/sudo',
1286 ['/usr/bin/sudo', '/bin/sh',
1287 '/media/cdrom/VBoxLinuxAdditions.run'],
1288 False, True);
1289 if fRc:
1290 # Due to the GA updates as separate process the above function returns before
1291 # the actual installation finished. So just wait until the GA installed
1292 fRc = self.closeSession(oGuestSession);
1293 if fRc:
1294 (fRc, oGuestSession) = self.waitVmIsReady(oSession, False);
1295 # Download log files.
1296 # Ignore errors as all files above might not be present for whatever reason.
1297 #
1298 if fRc:
1299 asLogFile = [];
1300 asLogFile.append('/var/log/vboxadd-install.log');
1301 self.downloadFiles(oGuestSession, asLogFile, fIgnoreErrors = True);
1302 else:
1303 reporter.error('Installing guest additions failed: Error occured during vbox installer execution')
1304 if fRc:
1305 (fRc, oGuestSession) = self.rebootVMAndCheckReady(oSession, oGuestSession);
1306 if not fRc:
1307 reporter.error('Reboot after installing GuestAdditions failed');
1308 reporter.testDone();
1309 return (fRc, oGuestSession);
1310
1311 def installVirtualBox(self, oGuestSession):
1312 """
1313 Install VirtualBox in the guest.
1314 """
1315 reporter.testStart('Install Virtualbox into the guest VM');
1316 sTestBuild = self._findFile(self.sVBoxInstaller, self.asTestBuildDirs);
1317 reporter.log("Virtualbox install file: %s" % os.path.basename(sTestBuild));
1318 fRc = sTestBuild is not None;
1319 if fRc:
1320 fRc = self.uploadFile(oGuestSession, sTestBuild,
1321 '/tmp/' + os.path.basename(sTestBuild));
1322 else:
1323 reporter.error("VirtualBox install package is not defined");
1324
1325 if not fRc:
1326 reporter.error('Upload the vbox installer into guest VM failed');
1327 else:
1328 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession,
1329 'Allowing execution for the vbox installer',
1330 30 * 1000, '/usr/bin/sudo',
1331 ['/usr/bin/sudo', '/bin/chmod', '755',
1332 '/tmp/' + os.path.basename(sTestBuild)],
1333 False, True);
1334 if not fRc:
1335 reporter.error('Allowing execution for the vbox installer failed');
1336 if fRc:
1337 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Installing VBox',
1338 240 * 1000, '/usr/bin/sudo',
1339 ['/usr/bin/sudo',
1340 '/tmp/' + os.path.basename(sTestBuild),],
1341 False, True);
1342 if not fRc:
1343 reporter.error('Installing VBox failed');
1344 reporter.testDone();
1345 return fRc;
1346
1347class tdStorageRawDriveOsDarwin(tdStorageRawDriveOs):
1348 """
1349 Autostart support methods for Darwin guests.
1350 """
1351 # pylint: disable=too-many-arguments
1352 def __init__(self, oSet, oTstDrv, sVmName, sKind, sHdd, eNic0Type = None, cMbRam = None, \
1353 cCpus = 1, fPae = None, sGuestAdditionsIso = None, sBootSector = None):
1354 tdStorageRawDriveOs.__init__(self, oSet, oTstDrv, sVmName, sKind, sHdd, eNic0Type, cMbRam, \
1355 cCpus, fPae, sGuestAdditionsIso, sBootSector);
1356 raise base.GenError('Testing the autostart functionality for Darwin is not implemented');
1357
1358class tdStorageRawDriveOsSolaris(tdStorageRawDriveOs):
1359 """
1360 Autostart support methods for Solaris guests.
1361 """
1362 # pylint: disable=too-many-arguments
1363 def __init__(self, oSet, oTstDrv, sVmName, sKind, sHdd, eNic0Type = None, cMbRam = None, \
1364 cCpus = 1, fPae = None, sGuestAdditionsIso = None, sBootSector = None):
1365 tdStorageRawDriveOs.__init__(self, oSet, oTstDrv, sVmName, sKind, sHdd, eNic0Type, cMbRam, \
1366 cCpus, fPae, sGuestAdditionsIso, sBootSector);
1367 raise base.GenError('Testing the autostart functionality for Solaris is not implemented');
1368
1369class tdStorageRawDriveOsWin(tdStorageRawDriveOs):
1370 """
1371 Autostart support methods for Windows guests.
1372 """
1373 # pylint: disable=too-many-arguments
1374 def __init__(self, oSet, oTstDrv, sVmName, sKind, sHdd, eNic0Type = None, cMbRam = None, \
1375 cCpus = 1, fPae = None, sGuestAdditionsIso = None, sBootSector = None):
1376 tdStorageRawDriveOs.__init__(self, oSet, oTstDrv, sVmName, sKind, sHdd, eNic0Type, cMbRam, \
1377 cCpus, fPae, sGuestAdditionsIso, sBootSector);
1378 self.sVBoxInstaller = r'^VirtualBox-.*\.(exe|msi)$';
1379 self.sVMDKPath=r'C:\Temp\vmdk';
1380 self.sPathDelimiter = '\\';
1381 self.asHdds['6.1/storage/t-mbr.vdi']['Header']['Model'] = '"VBOX HARDDISK"';
1382 self.asHdds['6.1/storage/t-gpt.vdi']['Header']['Model'] = '"VBOX HARDDISK"';
1383 self.asHdds['6.1/storage/t-mbr.vdi']['Partitions']['PartitionNumbers'] = [1, 2, 3, 4, 5, 6, 7, 8];
1384 return;
1385
1386 def _checkVmIsReady(self, oGuestSession):
1387 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Start a guest process',
1388 30 * 1000, 'C:\\Windows\\System32\\ipconfig.exe',
1389 ['C:\\Windows\\System32\\ipconfig.exe',],
1390 False, False);
1391 return fRc;
1392
1393 def _rebootVM(self, oGuestSession):
1394 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Reboot the VM',
1395 30 * 1000, 'C:\\Windows\\System32\\shutdown.exe',
1396 ['C:\\Windows\\System32\\shutdown.exe', '/f',
1397 '/r', '/t', '0'],
1398 False, True);
1399 if not fRc:
1400 reporter.error('Calling the shutdown utility failed');
1401 return fRc;
1402
1403 def _powerDownVM(self, oGuestSession):
1404 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Power down the VM',
1405 30 * 1000, 'C:\\Windows\\System32\\shutdown.exe',
1406 ['C:\\Windows\\System32\\shutdown.exe', '/f',
1407 '/s', '/t', '0'],
1408 False, True);
1409 if not fRc:
1410 reporter.error('Calling the shutdown utility failed');
1411 return fRc;
1412
1413 def _callVBoxManage(self, oGuestSession, sTestName, cMsTimeout, asArgs = (),
1414 fGetStdOut = True, fIsError = True):
1415 return self.guestProcessExecute(oGuestSession, sTestName,
1416 cMsTimeout, r'C:\Program Files\Oracle\VirtualBox\VBoxManage.exe',
1417 [r'C:\Program Files\Oracle\VirtualBox\VBoxManage.exe',] + asArgs, fGetStdOut, fIsError);
1418
1419 def _setPermissionsToVmdkFiles(self, oGuestSession):
1420 """
1421 Sets 0644 permissions to all files in the self.sVMDKPath allowing reading them by 'vbox' user.
1422 """
1423 _ = oGuestSession;
1424 # It is not required in case of Windows
1425 return True;
1426
1427 def installAdditions(self, oSession, oGuestSession, oVM):
1428 """
1429 Installs the Windows guest additions using the test execution service.
1430 """
1431 _ = oVM;
1432 reporter.testStart('Install Guest Additions');
1433 asLogFiles = [];
1434 fRc = self.closeSession(oGuestSession, True); # pychecker hack.
1435 try:
1436 oCurProgress = oSession.o.console.guest.updateGuestAdditions(self.sGuestAdditionsIso, ['/l',], None);
1437 except:
1438 reporter.maybeErrXcpt(True, 'Updating Guest Additions exception for sSrc="%s":'
1439 % (self.sGuestAdditionsIso,));
1440 fRc = False;
1441 else:
1442 if oCurProgress is not None:
1443 oWrapperProgress = vboxwrappers.ProgressWrapper(oCurProgress, self.oTstDrv.oVBoxMgr,
1444 self.oTstDrv, "installAdditions");
1445 oWrapperProgress.wait(cMsTimeout = 10 * 60 * 1000);
1446 if not oWrapperProgress.isSuccess():
1447 oWrapperProgress.logResult(fIgnoreErrors = False);
1448 fRc = False;
1449 else:
1450 fRc = reporter.error('No progress object returned');
1451
1452 # Store the result and try download logs anyway.
1453 fGaRc = fRc;
1454 fRc, oGuestSession = self.createSession(oSession, 'Session for user: vbox',
1455 'vbox', 'password', 10 * 1000, True);
1456 if fRc is True:
1457 (fRc, oGuestSession) = self.rebootVMAndCheckReady(oSession, oGuestSession);
1458 if fRc is True:
1459 # Add the Windows Guest Additions installer files to the files we want to download
1460 # from the guest.
1461 sGuestAddsDir = 'C:/Program Files/Oracle/VirtualBox Guest Additions/';
1462 asLogFiles.append(sGuestAddsDir + 'install.log');
1463 # Note: There won't be a install_ui.log because of the silent installation.
1464 asLogFiles.append(sGuestAddsDir + 'install_drivers.log');
1465 # Download log files.
1466 # Ignore errors as all files above might not be present (or in different locations)
1467 # on different Windows guests.
1468 #
1469 self.downloadFiles(oGuestSession, asLogFiles, fIgnoreErrors = True);
1470 else:
1471 reporter.error('Reboot after installing GuestAdditions failed');
1472 else:
1473 reporter.error('Create session for user vbox after GA updating failed');
1474 reporter.testDone();
1475 return (fRc and fGaRc, oGuestSession);
1476
1477 def installVirtualBox(self, oGuestSession):
1478 """
1479 Install VirtualBox in the guest.
1480 """
1481 reporter.testStart('Install Virtualbox into the guest VM');
1482 # Used windows image already contains the C:\Temp
1483 sTestBuild = self._findFile(self.sVBoxInstaller, self.asTestBuildDirs);
1484 reporter.log("Virtualbox install file: %s" % os.path.basename(sTestBuild));
1485 fRc = sTestBuild is not None;
1486 if fRc:
1487 fRc = self.uploadFile(oGuestSession, sTestBuild,
1488 'C:\\Temp\\' + os.path.basename(sTestBuild));
1489 else:
1490 reporter.error("VirtualBox install package is not defined");
1491
1492 if not fRc:
1493 reporter.error('Upload the installing into guest VM failed');
1494 else:
1495 if sTestBuild.endswith('.msi'):
1496 sLogFile = 'C:/Temp/VBoxInstallLog.txt';
1497 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Installing VBox',
1498 600 * 1000, 'C:\\Windows\\System32\\msiexec.exe',
1499 ['msiexec', '/quiet', '/norestart', '/i',
1500 'C:\\Temp\\' + os.path.basename(sTestBuild),
1501 '/lv', sLogFile],
1502 False, True);
1503 if not fRc:
1504 reporter.error('Installing the VBox from msi installer failed');
1505 else:
1506 sLogFile = 'C:/Temp/Virtualbox/VBoxInstallLog.txt';
1507 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Installing VBox',
1508 600 * 1000, 'C:\\Temp\\' + os.path.basename(sTestBuild),
1509 ['C:\\Temp\\' + os.path.basename(sTestBuild), '-vvvv',
1510 '--silent', '--logging',
1511 '--msiparams', 'REBOOT=ReallySuppress'],
1512 False, True);
1513 if not fRc:
1514 reporter.error('Installing the VBox failed');
1515 else:
1516 (_, _, _, aBuf) = self.guestProcessExecute(oGuestSession, 'Check installation',
1517 240 * 1000, 'C:\\Windows\\System32\\cmd.exe',
1518 ['c:\\Windows\\System32\\cmd.exe', '/c',
1519 'dir', 'C:\\Program Files\\Oracle\\VirtualBox\\*.*'],
1520 True, True);
1521 reporter.log('Content of VirtualBxox folder:');
1522 reporter.log(str(aBuf));
1523 asLogFiles = [sLogFile,];
1524 self.downloadFiles(oGuestSession, asLogFiles, fIgnoreErrors = True);
1525 reporter.testDone();
1526 return fRc;
1527
1528 def convertDiskToPartitionPrefix(self, sDisk):
1529 # Convert \\.\PhysicalDriveX into \\.\HarddiskXPartition
1530 oMatch = re.match(r'^\\\\.\\PhysicalDrive(\d+)$', sDisk);
1531 if oMatch is None:
1532 return None;
1533 return r'\\.\Harddisk' + oMatch.group(1) + 'Partition';
1534
1535class tdStorageRawDrive(vbox.TestDriver): # pylint: disable=too-many-instance-attributes
1536 """
1537 Autostart testcase.
1538 """
1539 ksOsLinux = 'tst-linux';
1540 ksOsWindows = 'tst-win';
1541 ksOsDarwin = 'tst-darwin';
1542 ksOsSolaris = 'tst-solaris';
1543 ksOsFreeBSD = 'tst-freebsd';
1544 ksBootSectorPath = '6.1/storage/t-bootsector.bin';
1545 kasHdds = ['6.1/storage/t-gpt.vdi', '6.1/storage/t-mbr.vdi'];
1546
1547 def __init__(self):
1548 vbox.TestDriver.__init__(self);
1549 self.asRsrcs = None;
1550 self.asSkipVMs = [];
1551 ## @todo r=bird: The --test-build-dirs option as primary way to get the installation files to test
1552 ## is not an acceptable test practice as we don't know wtf you're testing. See defect for more.
1553 self.asTestBuildDirs = [os.path.join(self.sScratchPath, 'bin'),];
1554 self.sGuestAdditionsIso = None; #'D:/AlexD/TestBox/TestAdditionalFiles/VBoxGuestAdditions_6.1.2.iso';
1555 oSet = vboxtestvms.TestVmSet(self.oTestVmManager, acCpus = [2], asVirtModes = ['hwvirt-np',], fIgnoreSkippedVm = True);
1556 # pylint: disable=line-too-long
1557 self.asTestVmClasses = {
1558 'win' : None, #tdStorageRawDriveOsWin(oSet, self, self.ksOsWindows, 'Windows7_64', \
1559 #'6.0/windows7piglit/windows7piglit.vdi', eNic0Type = None, cMbRam = 2048, \
1560 #cCpus = 2, fPae = True, sGuestAdditionsIso = self.getGuestAdditionsIso(),
1561 #sBootSector = self.ksBootSectorPath),
1562 'linux' : tdStorageRawDriveOsLinux(oSet, self, self.ksOsLinux, 'Ubuntu_64', \
1563 '6.0/ub1804piglit/ub1804piglit.vdi', eNic0Type = None, \
1564 cMbRam = 2048, cCpus = 2, fPae = None, sGuestAdditionsIso = self.getGuestAdditionsIso(),
1565 sBootSector = self.ksBootSectorPath),
1566 'solaris' : None, #'tdAutostartOsSolaris',
1567 'darwin' : None #'tdAutostartOsDarwin'
1568 };
1569 oSet.aoTestVms.extend([oTestVm for oTestVm in self.asTestVmClasses.values() if oTestVm is not None]);
1570 sOs = self.getBuildOs();
1571 if sOs in self.asTestVmClasses.keys():
1572 for oTestVM in oSet.aoTestVms:
1573 if oTestVM is not None:
1574 oTestVM.fSkip = oTestVM != self.asTestVmClasses[sOs];
1575 # pylint: enable=line-too-long
1576 self.oTestVmSet = oSet;
1577
1578 #
1579 # Overridden methods.
1580 #
1581
1582 def showUsage(self):
1583 rc = vbox.TestDriver.showUsage(self);
1584 reporter.log('');
1585 reporter.log('tdAutostart Options:');
1586 reporter.log(' --test-build-dirs <path1[,path2[,...]]>');
1587 reporter.log(' The list of directories with VirtualBox distros. Overrides default path.');
1588 reporter.log(' Default path is $TESTBOX_SCRATCH_PATH/bin.');
1589 reporter.log(' --vbox-<os>-build <path>');
1590 reporter.log(' The path to vbox build for the specified OS.');
1591 reporter.log(' The OS can be one of "win", "linux", "solaris" and "darwin".');
1592 reporter.log(' This option alse enables corresponding VM for testing.');
1593 reporter.log(' (Default behaviour is testing only VM having host-like OS.)');
1594 return rc;
1595
1596 def parseOption(self, asArgs, iArg): # pylint: disable=too-many-branches,too-many-statements
1597 if asArgs[iArg] == '--test-build-dirs':
1598 iArg += 1;
1599 if iArg >= len(asArgs): raise base.InvalidOption('The "--test-build-dirs" takes a path argument');
1600 self.asTestBuildDirs = asArgs[iArg].split(',');
1601 for oTestVm in self.oTestVmSet.aoTestVms:
1602 oTestVm.asTestBuildDirs = self.asTestBuildDirs;
1603 elif asArgs[iArg] in [ '--vbox-%s-build' % sKey for sKey in self.asTestVmClasses]:
1604 iArg += 1;
1605 if iArg >= len(asArgs): raise base.InvalidOption('The "%s" take a path argument' % (asArgs[iArg - 1],));
1606 oMatch = re.match("--vbox-([^-]+)-build", asArgs[iArg - 1]);
1607 if oMatch is not None:
1608 sOs = oMatch.group(1);
1609 oTestVm = self.asTestVmClasses.get(sOs);
1610 if oTestVm is not None:
1611 oTestVm.sTestBuild = asArgs[iArg];
1612 oTestVm.fSkip = False;
1613 else:
1614 return vbox.TestDriver.parseOption(self, asArgs, iArg);
1615 return iArg + 1;
1616
1617 def getResourceSet(self):
1618 asRsrcs = self.kasHdds[:];
1619 asRsrcs.extend([self.ksBootSectorPath,]);
1620 asRsrcs.extend(vbox.TestDriver.getResourceSet(self));
1621 return asRsrcs;
1622
1623 def actionConfig(self):
1624 if not self.importVBoxApi(): # So we can use the constant below.
1625 return False;
1626 return self.oTestVmSet.actionConfig(self);
1627
1628 def actionExecute(self):
1629 """
1630 Execute the testcase.
1631 """
1632 return self.oTestVmSet.actionExecute(self, self.testAutostartOneVfg)
1633
1634 #
1635 # Test execution helpers.
1636 #
1637 def testAutostartOneVfg(self, oVM, oTestVm):
1638 fRc = True;
1639 self.logVmInfo(oVM);
1640
1641 for sHdd in self.kasHdds:
1642 reporter.testStart('%s with %s disk' % ( oTestVm.sVmName, sHdd))
1643 fRc = oTestVm.reattachHdd(oVM, sHdd, self.kasHdds);
1644 if fRc:
1645 oSession = self.startVmByName(oTestVm.sVmName);
1646 if oSession is not None:
1647 (fRc, oGuestSession) = oTestVm.waitVmIsReady(oSession, True);
1648 if fRc:
1649 if fRc:
1650 (fRc, oGuestSession) = oTestVm.installAdditions(oSession, oGuestSession, oVM);
1651 if fRc:
1652 fRc = oTestVm.installVirtualBox(oGuestSession);
1653 if fRc:
1654 (fRc, sRawDrive) = oTestVm.listHostDrives(oGuestSession, sHdd);
1655 if fRc:
1656 fRc = oTestVm.createDrives(oGuestSession, sHdd, sRawDrive);
1657 if not fRc:
1658 reporter.error('Create VMDK raw drives failed');
1659 else:
1660 reporter.error('List host drives failed');
1661 else:
1662 reporter.error('Installing VirtualBox in the guest failed');
1663 else:
1664 reporter.error('Creating Guest Additions failed');
1665 else:
1666 reporter.error('Waiting for start VM failed');
1667 if oGuestSession is not None:
1668 try: oTestVm.powerDownVM(oGuestSession);
1669 except: pass;
1670 try: self.terminateVmBySession(oSession);
1671 except: pass;
1672 fRc = oSession.close() and fRc and True; # pychecker hack.
1673 oSession = None;
1674 else:
1675 fRc = False;
1676 else:
1677 reporter.error('Attaching %s to %s failed' % (sHdd, oTestVm.sVmName));
1678 reporter.testDone();
1679 return fRc;
1680
1681if __name__ == '__main__':
1682 sys.exit(tdStorageRawDrive().main(sys.argv));
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette