VirtualBox

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

Last change on this file since 87672 was 87672, checked in by vboxsync, 4 years ago

Main: bugref:9224: Added testcase for the task

  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 87.5 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-2020 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 87672 2021-02-10 09:57:14Z 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' : None,
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("^\s*([^:]+)\s*:\s*(.+)\s*$");
983
984 class ParseState:
985 Nothing = 0;
986 Drive = 1;
987 Partition = 2;
988
989 iParseState = ParseState.Nothing;
990 asKeysNotFound = asHddData['Header'].keys();
991 idxPartition = 0;
992 for sLine in asLines:
993 if not sLine or sLine.startswith('#') or sLine.startswith("\n"):
994 continue;
995 oMatch = oRegExp.match(sLine);
996 if oMatch is not None:
997 sKey = oMatch.group(1);
998 sValue = oMatch.group(2);
999 if sKey is not None and sKey == 'Drive':
1000 # we found required disk if we found all required disk info and partitions
1001 if sDrive and not asKeysNotFound and idxPartition >= len(asHddData['Partitions']['Partitions']):
1002 break;
1003 sDrive = sValue;
1004 iParseState = ParseState.Drive;
1005 asKeysNotFound = asKeysNotFound = asHddData['Header'].keys();
1006 idxPartition = 0;
1007 continue;
1008 if iParseState == ParseState.Drive:
1009 if sLine.strip().startswith('Partitions:'):
1010 iParseState = ParseState.Partition;
1011 continue;
1012 if oMatch is None or sKey is None:
1013 continue;
1014 if sKey in asHddData['Header'].keys() and asHddData['Header'][sKey] == sValue:
1015 asKeysNotFound.remove(sKey);
1016 continue;
1017 if iParseState == ParseState.Partition:
1018 if idxPartition < len(asHddData['Partitions']['Partitions']):
1019 sPart = asHddData['Partitions']['Partitions'][idxPartition];
1020 sPart = sPart.replace('$(' + str(idxPartition + 1) + ')',
1021 str(asHddData['Partitions']['PartitionNumbers'][idxPartition]));
1022 if (sLine.strip() == sPart):
1023 idxPartition += 1;
1024 continue;
1025 fRc = sDrive and not asKeysNotFound and idxPartition >= len(asHddData['Partitions']['Partitions']);
1026 if fRc:
1027 reporter.log("Path to the drive '%s' in the VM '%s': %s " % (sHdd, self.sVmName, sDrive));
1028 else:
1029 reporter.error("Path to drive '%s' not found in the VM '%s'" % (sHdd, self.sVmName));
1030 reporter.testDone();
1031 return (fRc, sDrive);
1032
1033 def convertDiskToPartitionPrefix(self, sDisk):
1034 return sDisk;
1035
1036 def checkVMDKDescriptor(self, asDescriptor, sHdd, sRawDrive, asAction):
1037 """
1038 Check VMDK descriptor of the disk created
1039 """
1040 if asDescriptor is None \
1041 or asDescriptor[0] != '# Disk DescriptorFile' \
1042 and asDescriptor[0] != '# Disk Descriptor File' \
1043 and asDescriptor[0] != '#Disk Descriptor File' \
1044 and asDescriptor[0] != '#Disk DescriptorFile':
1045 return reporter.error("VMDK descriptor has invalid format");
1046
1047 class DescriptorParseState:
1048 Header = 1,
1049 Extent = 2,
1050 Database = 3
1051
1052 asHddData = self.asHdds[sHdd];
1053 iParseState = DescriptorParseState.Header;
1054
1055 asHeader = { 'version' : '1',
1056 'CID' : '*',
1057 'parentCID' : 'ffffffff',
1058 'createType' : '$'
1059 };
1060
1061 asDatabase = { 'ddb.virtualHWVersion' : '4',
1062 'ddb.adapterType' : 'ide',
1063 'ddb.uuid.image' : '*',
1064 'ddb.uuid.parent' : '00000000-0000-0000-0000-000000000000',
1065 'ddb.uuid.modification' : '00000000-0000-0000-0000-000000000000',
1066 'ddb.uuid.parentmodification' : '00000000-0000-0000-0000-000000000000'
1067 };
1068
1069 oRegExp = re.compile('^\s*([^=]+)\s*=\s*\"*([^\"]+)\"*\s*$');
1070 iExtentIdx = 0;
1071
1072 for sLine in asDescriptor:
1073 if not sLine or sLine.startswith('#') or sLine.startswith("\n"):
1074 continue;
1075
1076 if iParseState == DescriptorParseState.Header:
1077 if sLine.startswith('ddb.'):
1078 return reporter.error("VMDK descriptor has invalid order of sections");
1079 if sLine.startswith("RW") \
1080 or sLine.startswith("RDONLY") \
1081 or sLine.startswith("NOACCESS"):
1082 iParseState = DescriptorParseState.Extent;
1083 else:
1084 oMatch = oRegExp.match(sLine);
1085 if oMatch is None:
1086 return reporter.error("VMDK descriptor contains lines in invalid form");
1087 sKey = oMatch.group(1).strip();
1088 sValue = oMatch.group(2).strip();
1089 if sKey not in asHeader.keys():
1090 return reporter.error("VMDK descriptor has invalid format");
1091 sDictValue = asHeader[sKey];
1092 if sDictValue == '$':
1093 sDictValue = asAction[sKey];
1094 if sDictValue != '*' and sDictValue != sValue:
1095 return reporter.error("VMDK descriptor has value which was not expected");
1096 continue;
1097
1098 if iParseState == DescriptorParseState.Extent:
1099 if sLine.startswith('ddb.'):
1100 iParseState = DescriptorParseState.Database;
1101 else:
1102 if not sLine.startswith("RW") \
1103 and not sLine.startswith("RDONLY") \
1104 and not sLine.startswith("NOACCESS"):
1105 return reporter.error("VMDK descriptor has invalid order of sections");
1106 sExtent = asAction['extents'][sHdd][iExtentIdx];
1107 sExtent = sExtent.replace('$(disk)', sRawDrive);
1108 sExtent = sExtent.replace('$(part)', self.convertDiskToPartitionPrefix(sRawDrive));
1109 sExtent = re.sub(r'\$\((\d+)\)',
1110 lambda oMatch: str(asHddData['Partitions']['PartitionNumbers'][int(oMatch.group(1)) - 1]),
1111 sExtent);
1112 if sExtent != sLine.strip():
1113 return reporter.error("VMDK descriptor has invalid order of sections");
1114 iExtentIdx += 1;
1115 continue;
1116
1117 if iParseState == DescriptorParseState.Database:
1118 if not sLine.startswith('ddb.'):
1119 return reporter.error("VMDK descriptor has invalid order of sections");
1120 oMatch = oRegExp.match(sLine);
1121 if oMatch is None:
1122 return reporter.error("VMDK descriptor contains lines in invalid form");
1123 sKey = oMatch.group(1).strip();
1124 sValue = oMatch.group(2).strip();
1125 if sKey not in asDatabase.keys():
1126 return reporter.error("VMDK descriptor has invalid format");
1127 sDictValue = asDatabase[sKey];
1128 if sDictValue != '*' and sDictValue != sValue:
1129 return reporter.error("VMDK descriptor has value which was not expected");
1130 continue;
1131 return iParseState == DescriptorParseState.Database;
1132
1133 def _setPermissionsToVmdkFiles(self, oGuestSession):
1134 """
1135 Sets 0644 permissions to all files in the self.sVMDKPath allowing reading them by 'vbox' user.
1136 """
1137 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession,
1138 'Allowing reading of the VMDK content by vbox user',
1139 30 * 1000, '/usr/bin/sudo',
1140 ['/usr/bin/sudo', '/bin/chmod', '644',
1141 self.sVMDKPath + '/vmdktest.vmdk', self.sVMDKPath + '/vmdktest-pt.vmdk'],
1142 False, True);
1143 return fRc;
1144
1145 def createDrives(self, oGuestSession, sHdd, sRawDrive):
1146 """
1147 Creates VMDK Raw file and check correctness
1148 """
1149 reporter.testStart("Create VMDK disks");
1150 asHddData = self.asHdds[sHdd];
1151 fRc = True;
1152 try: oGuestSession.directoryCreate(self.sVMDKPath, 0777, (vboxcon.DirectoryCreateFlag_Parents,));
1153 except: fRc = reporter.errorXcpt('Create directory for VMDK files failed in the VM %s' % (self.sVmName));
1154 if fRc:
1155 sBootSectorGuestPath = self.sVMDKPath + self.sPathDelimiter + 't-bootsector.bin';
1156 try: fExists = oGuestSession.fileExists(sBootSectorGuestPath, False);
1157 except: fExists = False;
1158 if not fExists:
1159 sBootSectorPath = self.oTstDrv.getFullResourceName(self.sBootSector);
1160 fRc = self.uploadFile(oGuestSession, sBootSectorPath, sBootSectorGuestPath);
1161
1162 for action in self.asActions:
1163 reporter.testStart("Create VMDK disk: %s" % action["action"]);
1164 asOptions = action['options'];
1165 asOptions = [option.replace('$(bootsector)', sBootSectorGuestPath) for option in asOptions];
1166 asOptions = [re.sub(r'\$\((\d+)\)',
1167 lambda oMatch: str(asHddData['Partitions']['PartitionNumbers'][int(oMatch.group(1)) - 1]),
1168 option)
1169 for option in asOptions];
1170 (fRc, _, _, _) = self._callVBoxManage(oGuestSession, 'Create VMDK disk', 60 * 1000,
1171 ['createmedium', '--filename',
1172 self.sVMDKPath + self.sPathDelimiter + 'vmdktest.vmdk',
1173 '--format', 'VMDK', '--variant', 'RawDisk',
1174 '--property', 'RawDrive=%s' % (sRawDrive,) ] + asOptions,
1175 False, True);
1176 if not fRc:
1177 reporter.error('Create VMDK raw drive variant "%s" failed in the VM %s' % (action["action"], self.sVmName));
1178 else:
1179 fRc = self._setPermissionsToVmdkFiles(oGuestSession);
1180 if not fRc:
1181 reporter.error('Setting permissions to VMDK files failed');
1182 else:
1183 sSrcFile = self.sVMDKPath + self.sPathDelimiter + 'vmdktest.vmdk';
1184 sDstFile = os.path.join(self.oTstDrv.sScratchPath, 'guest-vmdktest.vmdk');
1185 reporter.log2('Downloading file "%s" to "%s" ...' % (sSrcFile, sDstFile));
1186 # First try to remove (unlink) an existing temporary file, as we don't truncate the file.
1187 try: os.unlink(sDstFile);
1188 except: pass;
1189 fRc = self.downloadFile(oGuestSession, sSrcFile, sDstFile, False);
1190 if not fRc:
1191 reporter.error('Download vmdktest.vmdk from guest to host failed');
1192 else:
1193 with open(sDstFile) as oFile:
1194 asDescriptor = [row.strip() for row in oFile];
1195 if not asDescriptor:
1196 fRc = reporter.error('Reading vmdktest.vmdk from guest filed');
1197 else:
1198 fRc = self.checkVMDKDescriptor(asDescriptor, sHdd, sRawDrive, action);
1199 if not fRc:
1200 reporter.error('Cheking vmdktest.vmdk from guest filed');
1201 elif action['data-crc'] is not None:
1202 sSrcFile = self.sVMDKPath + self.sPathDelimiter + 'vmdktest-pt.vmdk';
1203 sDstFile = os.path.join(self.oTstDrv.sScratchPath, 'guest-vmdktest-pt.vmdk');
1204 reporter.log2('Downloading file "%s" to "%s" ...' % (sSrcFile, sDstFile));
1205 # First try to remove (unlink) an existing temporary file, as we don't truncate the file.
1206 try: os.unlink(sDstFile);
1207 except: pass;
1208 fRc = self.downloadFile(oGuestSession, sSrcFile, sDstFile, False);
1209 if not fRc:
1210 reporter.error('Download vmdktest-pt.vmdk from guest to host failed');
1211 else:
1212 uResCrc32 = crc32_of_file(sDstFile);
1213 if uResCrc32 != action['data-crc'][sHdd]:
1214 fRc = reporter.error('vmdktest-pt.vmdk does not match what was expected');
1215 (fRc1, _, _, _) = self._callVBoxManage(oGuestSession, 'Delete VMDK disk', 60 * 1000,
1216 ['closemedium',
1217 self.sVMDKPath + self.sPathDelimiter + 'vmdktest.vmdk',
1218 '--delete'],
1219 False, True);
1220 if not fRc1:
1221 reporter.error('Delete VMDK raw drive variant "%s" failed in the VM %s' %
1222 (action["action"], self.sVmName));
1223 fRc = fRc and fRc1;
1224 reporter.testDone();
1225 if not fRc:
1226 break;
1227 else:
1228 reporter.error('Create %s dir failed in the VM %s' % (self.sVMDKPath, self.sVmName));
1229
1230 reporter.testDone();
1231 return fRc;
1232
1233
1234class tdStorageRawDriveOsLinux(tdStorageRawDriveOs):
1235 """
1236 Autostart support methods for Linux guests.
1237 """
1238 # pylint: disable=too-many-arguments
1239 def __init__(self, oSet, oTstDrv, sVmName, sKind, sHdd, eNic0Type = None, cMbRam = None, \
1240 cCpus = 1, fPae = None, sGuestAdditionsIso = None, sBootSector = None):
1241 tdStorageRawDriveOs.__init__(self, oSet, oTstDrv, sVmName, sKind, sHdd, eNic0Type, cMbRam, \
1242 cCpus, fPae, sGuestAdditionsIso, sBootSector);
1243 self.sVBoxInstaller = '^VirtualBox-.*\\.run$';
1244 return;
1245
1246 def installAdditions(self, oSession, oGuestSession, oVM):
1247 """
1248 Install guest additions in the guest.
1249 """
1250 reporter.testStart('Install Guest Additions');
1251 fRc = False;
1252 # Install Kernel headers, which are required for actually installing the Linux Additions.
1253 if oVM.OSTypeId.startswith('Debian') \
1254 or oVM.OSTypeId.startswith('Ubuntu'):
1255 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Installing Kernel headers',
1256 5 * 60 *1000, '/usr/bin/apt-get',
1257 ['/usr/bin/apt-get', 'install', '-y',
1258 'linux-headers-generic'],
1259 False, True);
1260 if not fRc:
1261 reporter.error('Error installing Kernel headers');
1262 else:
1263 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Installing Guest Additions depdendencies',
1264 5 * 60 *1000, '/usr/bin/apt-get',
1265 ['/usr/bin/apt-get', 'install', '-y', 'build-essential',
1266 'perl'], False, True);
1267 if not fRc:
1268 reporter.error('Error installing additional installer dependencies');
1269 elif oVM.OSTypeId.startswith('OL') \
1270 or oVM.OSTypeId.startswith('Oracle') \
1271 or oVM.OSTypeId.startswith('RHEL') \
1272 or oVM.OSTypeId.startswith('Redhat') \
1273 or oVM.OSTypeId.startswith('Cent'):
1274 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Installing Kernel headers',
1275 5 * 60 *1000, '/usr/bin/yum',
1276 ['/usr/bin/yum', '-y', 'install', 'kernel-headers'],
1277 False, True);
1278 if not fRc:
1279 reporter.error('Error installing Kernel headers');
1280 else:
1281 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Installing Guest Additions depdendencies',
1282 5 * 60 *1000, '/usr/bin/yum',
1283 ['/usr/bin/yum', '-y', 'install', 'make', 'automake', 'gcc',
1284 'kernel-devel', 'dkms', 'bzip2', 'perl'], False, True);
1285 if not fRc:
1286 reporter.error('Error installing additional installer dependencies');
1287 else:
1288 reporter.error('Installing Linux Additions for the "%s" is not supported yet' % oVM.OSTypeId);
1289 fRc = False;
1290 if fRc:
1291 #
1292 # The actual install.
1293 # Also tell the installer to produce the appropriate log files.
1294 #
1295 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Installing guest additions',
1296 10 * 60 *1000, '/usr/bin/sudo',
1297 ['/usr/bin/sudo', '/bin/sh',
1298 '/media/cdrom/VBoxLinuxAdditions.run'],
1299 False, True);
1300 if fRc:
1301 # Due to the GA updates as separate process the above function returns before
1302 # the actual installation finished. So just wait until the GA installed
1303 fRc = self.closeSession(oGuestSession);
1304 if fRc:
1305 (fRc, oGuestSession) = self.waitVmIsReady(oSession, False);
1306 # Download log files.
1307 # Ignore errors as all files above might not be present for whatever reason.
1308 #
1309 if fRc:
1310 asLogFile = [];
1311 asLogFile.append('/var/log/vboxadd-install.log');
1312 self.downloadFiles(oGuestSession, asLogFile, fIgnoreErrors = True);
1313 else:
1314 reporter.error('Installing guest additions failed: Error occured during vbox installer execution')
1315 if fRc:
1316 (fRc, oGuestSession) = self.rebootVMAndCheckReady(oSession, oGuestSession);
1317 if not fRc:
1318 reporter.error('Reboot after installing GuestAdditions failed');
1319 reporter.testDone();
1320 return (fRc, oGuestSession);
1321
1322 def installVirtualBox(self, oGuestSession):
1323 """
1324 Install VirtualBox in the guest.
1325 """
1326 reporter.testStart('Install Virtualbox into the guest VM');
1327 sTestBuild = self._findFile(self.sVBoxInstaller, self.asTestBuildDirs);
1328 reporter.log("Virtualbox install file: %s" % os.path.basename(sTestBuild));
1329 fRc = sTestBuild is not None;
1330 if fRc:
1331 fRc = self.uploadFile(oGuestSession, sTestBuild,
1332 '/tmp/' + os.path.basename(sTestBuild));
1333 else:
1334 reporter.error("VirtualBox install package is not defined");
1335
1336 if not fRc:
1337 reporter.error('Upload the vbox installer into guest VM failed');
1338 else:
1339 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession,
1340 'Allowing execution for the vbox installer',
1341 30 * 1000, '/usr/bin/sudo',
1342 ['/usr/bin/sudo', '/bin/chmod', '755',
1343 '/tmp/' + os.path.basename(sTestBuild)],
1344 False, True);
1345 if not fRc:
1346 reporter.error('Allowing execution for the vbox installer failed');
1347 if fRc:
1348 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Installing VBox',
1349 240 * 1000, '/usr/bin/sudo',
1350 ['/usr/bin/sudo',
1351 '/tmp/' + os.path.basename(sTestBuild),],
1352 False, True);
1353 if not fRc:
1354 reporter.error('Installing VBox failed');
1355 reporter.testDone();
1356 return fRc;
1357
1358class tdStorageRawDriveOsDarwin(tdStorageRawDriveOs):
1359 """
1360 Autostart support methods for Darwin guests.
1361 """
1362 # pylint: disable=too-many-arguments
1363 def __init__(self, oSet, oTstDrv, sVmName, sKind, sHdd, eNic0Type = None, cMbRam = None, \
1364 cCpus = 1, fPae = None, sGuestAdditionsIso = None, sBootSector = None):
1365 tdStorageRawDriveOs.__init__(self, oSet, oTstDrv, sVmName, sKind, sHdd, eNic0Type, cMbRam, \
1366 cCpus, fPae, sGuestAdditionsIso, sBootSector);
1367 raise base.GenError('Testing the autostart functionality for Darwin is not implemented');
1368
1369class tdStorageRawDriveOsSolaris(tdStorageRawDriveOs):
1370 """
1371 Autostart support methods for Solaris guests.
1372 """
1373 # pylint: disable=too-many-arguments
1374 def __init__(self, oSet, oTstDrv, sVmName, sKind, sHdd, eNic0Type = None, cMbRam = None, \
1375 cCpus = 1, fPae = None, sGuestAdditionsIso = None, sBootSector = None):
1376 tdStorageRawDriveOs.__init__(self, oSet, oTstDrv, sVmName, sKind, sHdd, eNic0Type, cMbRam, \
1377 cCpus, fPae, sGuestAdditionsIso, sBootSector);
1378 raise base.GenError('Testing the autostart functionality for Solaris is not implemented');
1379
1380class tdStorageRawDriveOsWin(tdStorageRawDriveOs):
1381 """
1382 Autostart support methods for Windows guests.
1383 """
1384 # pylint: disable=too-many-arguments
1385 def __init__(self, oSet, oTstDrv, sVmName, sKind, sHdd, eNic0Type = None, cMbRam = None, \
1386 cCpus = 1, fPae = None, sGuestAdditionsIso = None, sBootSector = None):
1387 tdStorageRawDriveOs.__init__(self, oSet, oTstDrv, sVmName, sKind, sHdd, eNic0Type, cMbRam, \
1388 cCpus, fPae, sGuestAdditionsIso, sBootSector);
1389 self.sVBoxInstaller = r'^VirtualBox-.*\.(exe|msi)$';
1390 self.sVMDKPath=r'C:\Temp\vmdk';
1391 self.sPathDelimiter = '\\';
1392 self.asHdds['6.1/storage/t-mbr.vdi']['Header']['Model'] = '"VBOX HARDDISK"';
1393 self.asHdds['6.1/storage/t-gpt.vdi']['Header']['Model'] = '"VBOX HARDDISK"';
1394 self.asHdds['6.1/storage/t-mbr.vdi']['Partitions']['PartitionNumbers'] = [1, 2, 3, 4, 5, 6, 7, 8];
1395 return;
1396
1397 def _checkVmIsReady(self, oGuestSession):
1398 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Start a guest process',
1399 30 * 1000, 'C:\\Windows\\System32\\ipconfig.exe',
1400 ['C:\\Windows\\System32\\ipconfig.exe',],
1401 False, False);
1402 return fRc;
1403
1404 def _rebootVM(self, oGuestSession):
1405 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Reboot the VM',
1406 30 * 1000, 'C:\\Windows\\System32\\shutdown.exe',
1407 ['C:\\Windows\\System32\\shutdown.exe', '/f',
1408 '/r', '/t', '0'],
1409 False, True);
1410 if not fRc:
1411 reporter.error('Calling the shutdown utility failed');
1412 return fRc;
1413
1414 def _powerDownVM(self, oGuestSession):
1415 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Power down the VM',
1416 30 * 1000, 'C:\\Windows\\System32\\shutdown.exe',
1417 ['C:\\Windows\\System32\\shutdown.exe', '/f',
1418 '/s', '/t', '0'],
1419 False, True);
1420 if not fRc:
1421 reporter.error('Calling the shutdown utility failed');
1422 return fRc;
1423
1424 def _callVBoxManage(self, oGuestSession, sTestName, cMsTimeout, asArgs = (),
1425 fGetStdOut = True, fIsError = True):
1426 return self.guestProcessExecute(oGuestSession, sTestName,
1427 cMsTimeout, r'C:\Program Files\Oracle\VirtualBox\VBoxManage.exe',
1428 [r'C:\Program Files\Oracle\VirtualBox\VBoxManage.exe',] + asArgs, fGetStdOut, fIsError);
1429
1430 def _setPermissionsToVmdkFiles(self, oGuestSession):
1431 """
1432 Sets 0644 permissions to all files in the self.sVMDKPath allowing reading them by 'vbox' user.
1433 """
1434 _ = oGuestSession;
1435 # It is not required in case of Windows
1436 return True;
1437
1438 def installAdditions(self, oSession, oGuestSession, oVM):
1439 """
1440 Installs the Windows guest additions using the test execution service.
1441 """
1442 _ = oVM;
1443 reporter.testStart('Install Guest Additions');
1444 asLogFiles = [];
1445 fRc = self.closeSession(oGuestSession, True); # pychecker hack.
1446 try:
1447 oCurProgress = oSession.o.console.guest.updateGuestAdditions(self.sGuestAdditionsIso, ['/l',], None);
1448 except:
1449 reporter.maybeErrXcpt(True, 'Updating Guest Additions exception for sSrc="%s":'
1450 % (self.sGuestAdditionsIso,));
1451 fRc = False;
1452 else:
1453 if oCurProgress is not None:
1454 oWrapperProgress = vboxwrappers.ProgressWrapper(oCurProgress, self.oTstDrv.oVBoxMgr,
1455 self.oTstDrv, "installAdditions");
1456 oWrapperProgress.wait(cMsTimeout = 10 * 60 * 1000);
1457 if not oWrapperProgress.isSuccess():
1458 oWrapperProgress.logResult(fIgnoreErrors = False);
1459 fRc = False;
1460 else:
1461 fRc = reporter.error('No progress object returned');
1462
1463 # Store the result and try download logs anyway.
1464 fGaRc = fRc;
1465 fRc, oGuestSession = self.createSession(oSession, 'Session for user: vbox',
1466 'vbox', 'password', 10 * 1000, True);
1467 if fRc is True:
1468 (fRc, oGuestSession) = self.rebootVMAndCheckReady(oSession, oGuestSession);
1469 if fRc is True:
1470 # Add the Windows Guest Additions installer files to the files we want to download
1471 # from the guest.
1472 sGuestAddsDir = 'C:/Program Files/Oracle/VirtualBox Guest Additions/';
1473 asLogFiles.append(sGuestAddsDir + 'install.log');
1474 # Note: There won't be a install_ui.log because of the silent installation.
1475 asLogFiles.append(sGuestAddsDir + 'install_drivers.log');
1476 # Download log files.
1477 # Ignore errors as all files above might not be present (or in different locations)
1478 # on different Windows guests.
1479 #
1480 self.downloadFiles(oGuestSession, asLogFiles, fIgnoreErrors = True);
1481 else:
1482 reporter.error('Reboot after installing GuestAdditions failed');
1483 else:
1484 reporter.error('Create session for user vbox after GA updating failed');
1485 reporter.testDone();
1486 return (fRc and fGaRc, oGuestSession);
1487
1488 def installVirtualBox(self, oGuestSession):
1489 """
1490 Install VirtualBox in the guest.
1491 """
1492 reporter.testStart('Install Virtualbox into the guest VM');
1493 # Used windows image already contains the C:\Temp
1494 sTestBuild = self._findFile(self.sVBoxInstaller, self.asTestBuildDirs);
1495 reporter.log("Virtualbox install file: %s" % os.path.basename(sTestBuild));
1496 fRc = sTestBuild is not None;
1497 if fRc:
1498 fRc = self.uploadFile(oGuestSession, sTestBuild,
1499 'C:\\Temp\\' + os.path.basename(sTestBuild));
1500 else:
1501 reporter.error("VirtualBox install package is not defined");
1502
1503 if not fRc:
1504 reporter.error('Upload the installing into guest VM failed');
1505 else:
1506 if sTestBuild.endswith('.msi'):
1507 sLogFile = 'C:/Temp/VBoxInstallLog.txt';
1508 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Installing VBox',
1509 600 * 1000, 'C:\\Windows\\System32\\msiexec.exe',
1510 ['msiexec', '/quiet', '/norestart', '/i',
1511 'C:\\Temp\\' + os.path.basename(sTestBuild),
1512 '/lv', sLogFile],
1513 False, True);
1514 if not fRc:
1515 reporter.error('Installing the VBox from msi installer failed');
1516 else:
1517 sLogFile = 'C:/Temp/Virtualbox/VBoxInstallLog.txt';
1518 (fRc, _, _, _) = self.guestProcessExecute(oGuestSession, 'Installing VBox',
1519 600 * 1000, 'C:\\Temp\\' + os.path.basename(sTestBuild),
1520 ['C:\\Temp\\' + os.path.basename(sTestBuild), '-vvvv',
1521 '--silent', '--logging',
1522 '--msiparams', 'REBOOT=ReallySuppress'],
1523 False, True);
1524 if not fRc:
1525 reporter.error('Installing the VBox failed');
1526 else:
1527 (_, _, _, aBuf) = self.guestProcessExecute(oGuestSession, 'Check installation',
1528 240 * 1000, 'C:\\Windows\\System32\\cmd.exe',
1529 ['c:\\Windows\\System32\\cmd.exe', '/c',
1530 'dir', 'C:\\Program Files\\Oracle\\VirtualBox\\*.*'],
1531 True, True);
1532 reporter.log('Content of VirtualBxox folder:');
1533 reporter.log(str(aBuf));
1534 asLogFiles = [sLogFile,];
1535 self.downloadFiles(oGuestSession, asLogFiles, fIgnoreErrors = True);
1536 reporter.testDone();
1537 return fRc;
1538
1539 def convertDiskToPartitionPrefix(self, sDisk):
1540 # Convert \\.\PhysicalDriveX into \\.\HarddiskXPartition
1541 oMatch = re.match(r'^\\\\.\\PhysicalDrive(\d+)$', sDisk);
1542 if oMatch is None:
1543 return None;
1544 return r'\\.\Harddisk' + oMatch.group(1) + 'Partition';
1545
1546class tdStorageRawDrive(vbox.TestDriver): # pylint: disable=too-many-instance-attributes
1547 """
1548 Autostart testcase.
1549 """
1550 ksOsLinux = 'tst-linux';
1551 ksOsWindows = 'tst-win';
1552 ksOsDarwin = 'tst-darwin';
1553 ksOsSolaris = 'tst-solaris';
1554 ksOsFreeBSD = 'tst-freebsd';
1555
1556 BootSectorPath = '6.1/storage/t-bootsector.bin';
1557 asHdds = ['6.1/storage/t-gpt.vdi', '6.1/storage/t-mbr.vdi'];
1558
1559 def __init__(self):
1560 vbox.TestDriver.__init__(self);
1561 self.asRsrcs = None;
1562 self.asSkipVMs = [];
1563 ## @todo r=bird: The --test-build-dirs option as primary way to get the installation files to test
1564 ## is not an acceptable test practice as we don't know wtf you're testing. See defect for more.
1565 self.asTestBuildDirs = [os.path.join(self.sScratchPath, 'bin'),];
1566 self.sGuestAdditionsIso = None; #'D:/AlexD/TestBox/TestAdditionalFiles/VBoxGuestAdditions_6.1.2.iso';
1567 oSet = vboxtestvms.TestVmSet(self.oTestVmManager, acCpus = [2], asVirtModes = ['hwvirt-np',], fIgnoreSkippedVm = True);
1568 # pylint: disable=line-too-long
1569 self.asTestVmClasses = {
1570 'win' : tdStorageRawDriveOsWin(oSet, self, self.ksOsWindows, 'Windows7_64', \
1571 '6.0/windows7piglit/windows7piglit.vdi', eNic0Type = None, cMbRam = 2048, \
1572 cCpus = 2, fPae = True, sGuestAdditionsIso = self.getGuestAdditionsIso(),
1573 sBootSector = self.BootSectorPath),
1574 'linux' : tdStorageRawDriveOsLinux(oSet, self, self.ksOsLinux, 'Ubuntu_64', \
1575 '6.0/ub1804piglit/ub1804piglit.vdi', eNic0Type = None, \
1576 cMbRam = 2048, cCpus = 2, fPae = None, sGuestAdditionsIso = self.getGuestAdditionsIso(),
1577 sBootSector = self.BootSectorPath),
1578 'solaris' : None, #'tdAutostartOsSolaris',
1579 'darwin' : None #'tdAutostartOsDarwin'
1580 };
1581 oSet.aoTestVms.extend([oTestVm for oTestVm in self.asTestVmClasses.values() if oTestVm is not None]);
1582 sOs = self.getBuildOs();
1583 if sOs in self.asTestVmClasses.keys():
1584 for oTestVM in oSet.aoTestVms:
1585 if oTestVM is not None:
1586 oTestVM.fSkip = oTestVM != self.asTestVmClasses[sOs];
1587 # pylint: enable=line-too-long
1588 self.oTestVmSet = oSet;
1589
1590 #
1591 # Overridden methods.
1592 #
1593
1594 def showUsage(self):
1595 rc = vbox.TestDriver.showUsage(self);
1596 reporter.log('');
1597 reporter.log('tdAutostart Options:');
1598 reporter.log(' --test-build-dirs <path1[,path2[,...]]>');
1599 reporter.log(' The list of directories with VirtualBox distros. Overrides default path.');
1600 reporter.log(' Default path is $TESTBOX_SCRATCH_PATH/bin.');
1601 reporter.log(' --vbox-<os>-build <path>');
1602 reporter.log(' The path to vbox build for the specified OS.');
1603 reporter.log(' The OS can be one of "win", "linux", "solaris" and "darwin".');
1604 reporter.log(' This option alse enables corresponding VM for testing.');
1605 reporter.log(' (Default behaviour is testing only VM having host-like OS.)');
1606 return rc;
1607
1608 def parseOption(self, asArgs, iArg): # pylint: disable=too-many-branches,too-many-statements
1609 if asArgs[iArg] == '--test-build-dirs':
1610 iArg += 1;
1611 if iArg >= len(asArgs): raise base.InvalidOption('The "--test-build-dirs" takes a path argument');
1612 self.asTestBuildDirs = asArgs[iArg].split(',');
1613 for oTestVm in self.oTestVmSet.aoTestVms:
1614 oTestVm.asTestBuildDirs = self.asTestBuildDirs;
1615 elif asArgs[iArg] in [ '--vbox-%s-build' % sKey for sKey in self.asTestVmClasses]:
1616 iArg += 1;
1617 if iArg >= len(asArgs): raise base.InvalidOption('The "%s" take a path argument' % (asArgs[iArg - 1],));
1618 oMatch = re.match("--vbox-([^-]+)-build", asArgs[iArg - 1]);
1619 if oMatch is not None:
1620 sOs = oMatch.group(1);
1621 oTestVm = self.asTestVmClasses.get(sOs);
1622 if oTestVm is not None:
1623 oTestVm.sTestBuild = asArgs[iArg];
1624 oTestVm.fSkip = False;
1625 else:
1626 return vbox.TestDriver.parseOption(self, asArgs, iArg);
1627 return iArg + 1;
1628
1629 def getResourceSet(self):
1630 asRsrcs = self.asHdds[:];
1631 asRsrcs.extend([self.BootSectorPath,]);
1632 asRsrcs.extend(vbox.TestDriver.getResourceSet(self));
1633 return asRsrcs;
1634
1635 def actionConfig(self):
1636 if not self.importVBoxApi(): # So we can use the constant below.
1637 return False;
1638 return self.oTestVmSet.actionConfig(self);
1639
1640 def actionExecute(self):
1641 """
1642 Execute the testcase.
1643 """
1644 return self.oTestVmSet.actionExecute(self, self.testAutostartOneVfg)
1645
1646 #
1647 # Test execution helpers.
1648 #
1649 def testAutostartOneVfg(self, oVM, oTestVm):
1650 fRc = True;
1651 self.logVmInfo(oVM);
1652
1653 for sHdd in self.asHdds:
1654 reporter.testStart('%s with %s disk' % ( oTestVm.sVmName, sHdd))
1655 fRc = oTestVm.reattachHdd(oVM, sHdd, self.asHdds);
1656 if fRc:
1657 oSession = self.startVmByName(oTestVm.sVmName);
1658 if oSession is not None:
1659 (fRc, oGuestSession) = oTestVm.waitVmIsReady(oSession, True);
1660 if fRc:
1661 if fRc:
1662 (fRc, oGuestSession) = oTestVm.installAdditions(oSession, oGuestSession, oVM);
1663 if fRc:
1664 fRc = oTestVm.installVirtualBox(oGuestSession);
1665 if fRc:
1666 (fRc, sRawDrive) = oTestVm.listHostDrives(oGuestSession, sHdd);
1667 if fRc:
1668 fRc = oTestVm.createDrives(oGuestSession, sHdd, sRawDrive);
1669 if not fRc:
1670 reporter.error('Create VMDK raw drives failed');
1671 else:
1672 reporter.error('List host drives failed');
1673 else:
1674 reporter.error('Installing VirtualBox in the guest failed');
1675 else:
1676 reporter.error('Creating Guest Additions failed');
1677 else:
1678 reporter.error('Waiting for start VM failed');
1679 if oGuestSession is not None:
1680 try: oTestVm.powerDownVM(oGuestSession);
1681 except: pass;
1682 try: self.terminateVmBySession(oSession);
1683 except: pass;
1684 fRc = oSession.close() and fRc and True; # pychecker hack.
1685 oSession = None;
1686 else:
1687 fRc = False;
1688 else:
1689 reporter.error('Attaching %s to %s failed' % (sHdd, oTestVm.sVmName));
1690 reporter.testDone();
1691 return fRc;
1692
1693if __name__ == '__main__':
1694 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