VirtualBox

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

Last change on this file was 106061, checked in by vboxsync, 3 months ago

Copyright year updates by scm.

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