VirtualBox

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

Last change on this file since 93889 was 93115, checked in by vboxsync, 3 years ago

scm --update-copyright-year

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