VirtualBox

source: vbox/trunk/src/VBox/ValidationKit/tests/audio/tdAudioTest.py@ 91127

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

Audio/Validation Kit: Fixed wrong error reporting in case audio data verification was successful. ​bugref:10008

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 26.2 KB
Line 
1# -*- coding: utf-8 -*-
2# $Id: tdAudioTest.py 91127 2021-09-06 16:33:36Z vboxsync $
3
4"""
5AudioTest test driver which invokes the VKAT (Validation Kit Audio Test)
6binary to perform the actual audio tests.
7
8The generated test set archive on the guest will be downloaded by TXS
9to the host for later audio comparison / verification.
10"""
11
12__copyright__ = \
13"""
14Copyright (C) 2021 Oracle Corporation
15
16This file is part of VirtualBox Open Source Edition (OSE), as
17available from http://www.virtualbox.org. This file is free software;
18you can redistribute it and/or modify it under the terms of the GNU
19General Public License (GPL) as published by the Free Software
20Foundation, in version 2 as it comes in the "COPYING" file of the
21VirtualBox OSE distribution. VirtualBox OSE is distributed in the
22hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
23
24The contents of this file may alternatively be used under the terms
25of the Common Development and Distribution License Version 1.0
26(CDDL) only, as it comes in the "COPYING.CDDL" file of the
27VirtualBox OSE distribution, in which case the provisions of the
28CDDL are applicable instead of those of the GPL.
29
30You may elect to license modified versions of this file under the
31terms and conditions of either the GPL or the CDDL or both.
32"""
33__version__ = "$Revision: 91127 $"
34
35# Standard Python imports.
36from datetime import datetime
37import os
38import sys
39import signal
40import subprocess
41
42# Only the main script needs to modify the path.
43try: __file__
44except: __file__ = sys.argv[0];
45g_ksValidationKitDir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))));
46sys.path.append(g_ksValidationKitDir);
47
48# Validation Kit imports.
49from testdriver import reporter
50from testdriver import base
51from testdriver import vbox
52from testdriver import vboxtestvms
53from common import utils;
54
55# pylint: disable=unnecessary-semicolon
56
57class tdAudioTest(vbox.TestDriver):
58 """
59 Runs various audio tests.
60 """
61 def __init__(self):
62 vbox.TestDriver.__init__(self);
63 self.oTestVmSet = self.oTestVmManager.getSmokeVmSet('nat');
64 self.asGstVkatPaths = [
65 # Debugging stuff (SCP'd over to the guest).
66 '/tmp/vkat',
67 '/tmp/VBoxAudioTest',
68 'C:\\Temp\\vkat',
69 'C:\\Temp\\VBoxAudioTest',
70 # Validation Kit .ISO.
71 '${CDROM}/vboxvalidationkit/${OS/ARCH}/vkat${EXESUFF}',
72 '${CDROM}/${OS/ARCH}/vkat${EXESUFF}',
73 # Test VMs.
74 '/opt/apps/vkat',
75 '/opt/apps/VBoxAudioTest',
76 '/apps/vkat',
77 '/apps/VBoxAudioTest',
78 'C:\\Apps\\vkat${EXESUFF}',
79 'C:\\Apps\\VBoxAudioTest${EXESUFF}',
80 ## @odo VBoxAudioTest on Guest Additions?
81 ];
82 self.asTestsDef = [
83 'guest_tone_playback', 'guest_tone_recording'
84 ];
85 self.asTests = self.asTestsDef;
86
87 # Enable audio debug mode.
88 #
89 # This is needed in order to load and use the Validation Kit audio driver,
90 # which in turn is being used in conjunction with the guest side to record
91 # output (guest is playing back) and injecting input (guest is recording).
92 self.asOptExtraData = [
93 'VBoxInternal2/Audio/Debug/Enabled:true',
94 ];
95
96 # Name of the running VM to use for running the test driver. Optional, and None if not being used.
97 self.sRunningVmName = None;
98
99 def showUsage(self):
100 """
101 Shows the audio test driver-specific command line options.
102 """
103 fRc = vbox.TestDriver.showUsage(self);
104 reporter.log('');
105 reporter.log('tdAudioTest Options:');
106 reporter.log(' --runningvmname <vmname>');
107 reporter.log(' --audio-tests <s1[:s2[:]]>');
108 reporter.log(' Default: %s (all)' % (':'.join(self.asTestsDef)));
109 return fRc;
110
111 def parseOption(self, asArgs, iArg):
112 """
113 Parses the audio test driver-specific command line options.
114 """
115 if asArgs[iArg] == '--runningvmname':
116 iArg += 1;
117 if iArg >= len(asArgs):
118 raise base.InvalidOption('The "--runningvmname" needs VM name');
119
120 self.sRunningVmName = asArgs[iArg];
121 elif asArgs[iArg] == '--audio-tests':
122 iArg += 1;
123 if asArgs[iArg] == 'all': # Nice for debugging scripts.
124 self.asTests = self.asTestsDef;
125 else:
126 self.asTests = asArgs[iArg].split(':');
127 for s in self.asTests:
128 if s not in self.asTestsDef:
129 raise base.InvalidOption('The "--audio-tests" value "%s" is not valid; valid values are: %s'
130 % (s, ' '.join(self.asTestsDef)));
131 else:
132 return vbox.TestDriver.parseOption(self, asArgs, iArg);
133 return iArg + 1;
134
135 def actionVerify(self):
136 """
137 Verifies the test driver before running.
138 """
139 if self.sVBoxValidationKitIso is None or not os.path.isfile(self.sVBoxValidationKitIso):
140 reporter.error('Cannot find the VBoxValidationKit.iso! (%s)'
141 'Please unzip a Validation Kit build in the current directory or in some parent one.'
142 % (self.sVBoxValidationKitIso,) );
143 return False;
144 return vbox.TestDriver.actionVerify(self);
145
146 def actionConfig(self):
147 """
148 Configures the test driver before running.
149 """
150 if not self.importVBoxApi(): # So we can use the constant below.
151 return False;
152
153 # Make sure that the Validation Kit .ISO is mounted
154 # to find the VKAT (Validation Kit Audio Test) binary on it.
155 assert self.sVBoxValidationKitIso is not None;
156 return self.oTestVmSet.actionConfig(self, sDvdImage = self.sVBoxValidationKitIso);
157
158 def actionExecute(self):
159 """
160 Executes the test driver.
161 """
162 if self.sRunningVmName is None:
163 return self.oTestVmSet.actionExecute(self, self.testOneVmConfig);
164 return self.actionExecuteOnRunnigVM();
165
166 def actionExecuteOnRunnigVM(self):
167 """
168 Executes the tests in an already configured + running VM.
169 """
170 if not self.importVBoxApi():
171 return False;
172
173 fRc = True;
174
175 oVirtualBox = self.oVBoxMgr.getVirtualBox();
176 try:
177 oVM = oVirtualBox.findMachine(self.sRunningVmName);
178 if oVM.state != self.oVBoxMgr.constants.MachineState_Running:
179 reporter.error("Machine '%s' is not in Running state" % (self.sRunningVmName));
180 fRc = False;
181 except:
182 reporter.errorXcpt("Machine '%s' not found" % (self.sRunningVmName));
183 fRc = False;
184
185 if fRc:
186 oSession = self.openSession(oVM);
187 if oSession:
188 # Tweak this to your likings.
189 oTestVm = vboxtestvms.TestVm('runningvm', sKind = 'WindowsXP'); #sKind = 'WindowsXP' # sKind = 'Ubuntu_64'
190 (fRc, oTxsSession) = self.txsDoConnectViaTcp(oSession, 30 * 1000);
191 if fRc:
192 self.doTest(oTestVm, oSession, oTxsSession);
193 else:
194 reporter.error("Unable to open session for machine '%s'" % (self.sRunningVmName));
195 fRc = False;
196
197 del oVM;
198 del oVirtualBox;
199 return fRc;
200
201 def getGstVkatLogFilePath(self, oTestVm):
202 """
203 Returns the log file path of VKAT running on the guest (daemonized).
204 """
205 return oTestVm.pathJoin(self.getGuestTempDir(oTestVm), 'vkat-guest.log');
206
207 def locateGstBinary(self, oSession, oTxsSession, asPaths):
208 """
209 Locates a guest binary on the guest by checking the paths in \a asPaths.
210 """
211 for sCurPath in asPaths:
212 reporter.log2('Checking for \"%s\" ...' % (sCurPath));
213 if self.txsIsFile(oSession, oTxsSession, sCurPath, fIgnoreErrors = True):
214 return (True, sCurPath);
215 reporter.error('Unable to find guest binary in any of these places:\n%s' % ('\n'.join(asPaths),));
216 return (False, "");
217
218 def executeHstLoop(self, sWhat, asArgs, asEnv = None, fAsAdmin = False):
219 """
220 Inner loop which handles the execution of a host binary.
221 """
222 fRc = False;
223
224 asEnvTmp = os.environ.copy();
225 if asEnv:
226 for sEnv in asEnv:
227 sKey, sValue = sEnv.split('=');
228 reporter.log2('Setting env var \"%s\" -> \"%s\"' % (sKey, sValue));
229 os.environ[sKey] = sValue; # Also apply it to the current environment.
230 asEnvTmp[sKey] = sValue;
231
232 if fAsAdmin \
233 and utils.getHostOs() != 'win':
234 oProcess = utils.sudoProcessPopen(asArgs,
235 env = asEnvTmp,
236 stdout = subprocess.PIPE, stderr = subprocess.PIPE, shell = False,
237 close_fds = False);
238 else:
239 oProcess = utils.processPopenSafe(asArgs,
240 env = asEnvTmp,
241 stdout = subprocess.PIPE, stderr = subprocess.PIPE);
242 if oProcess:
243 for line in iter(oProcess.stdout.readline, b''):
244 reporter.log('[' + sWhat + '] ' + line.decode('utf-8'));
245 oProcess.communicate();
246 if oProcess.returncode == 0:
247 fRc = True;
248 else:
249 reporter.log2('Executing \"%s\" on host returned exit code error %d' % (sWhat, oProcess.returncode));
250
251 return fRc;
252
253 def executeHst(self, sWhat, asArgs, asEnv = None, fAsync = False, fAsAdmin = False):
254 """
255 Runs a binary (image) with optional admin (root) rights on the host and
256 waits until it terminates.
257
258 Windows currently is not supported yet running stuff as Administrator.
259
260 Returns success status (exit code is 0).
261 """
262 reporter.log('Executing \"%s\" on host (as admin = %s, async = %s)' % (sWhat, fAsAdmin, fAsync));
263
264 reporter.testStart(sWhat);
265
266 fRc = self.executeHstLoop(sWhat, asArgs, asEnv);
267 if fRc:
268 reporter.log('Executing \"%s\" on host done' % (sWhat,));
269 else:
270 reporter.log('Executing \"%s\" on host failed' % (sWhat,));
271
272 reporter.testDone();
273
274 return fRc;
275
276 def killHstProcessByName(self, sProcName):
277 """
278 Kills processes by their name.
279 """
280 reporter.log('Trying to kill processes named "%s"' % (sProcName,));
281 if sys.platform == 'win32':
282 sArgProcName = '\"%s.exe\"' % sProcName;
283 asArgs = [ 'taskkill', '/IM', sArgProcName, '/F' ];
284 self.executeHst('Killing process', asArgs);
285 else: # Note: killall is not available on older Debians (requires psmisc).
286 # Using the BSD syntax here; MacOS also should understand this.
287 procPs = subprocess.Popen(['ps', 'ax'], stdout=subprocess.PIPE);
288 out, err = procPs.communicate();
289 if err:
290 reporter.log('PS stderr:');
291 for sLine in err.decode('utf-8').splitlines():
292 reporter.log(sLine);
293 if out:
294 reporter.log4('PS stdout:');
295 for sLine in out.decode('utf-8').splitlines():
296 reporter.log4(sLine);
297 if sProcName in sLine:
298 pid = int(sLine.split(None, 1)[0]);
299 reporter.log('Killing PID %d' % (pid,));
300 os.kill(pid, signal.SIGKILL); # pylint: disable=no-member
301
302 def killHstVkat(self):
303 """
304 Kills VKAT (VBoxAudioTest) on the host side.
305 """
306 reporter.log('Killing stale/old VKAT processes ...');
307 self.killHstProcessByName("vkat");
308 self.killHstProcessByName("VBoxAudioTest");
309
310 def getWinFirewallArgsDisable(self, sOsType):
311 """
312 Returns the command line arguments for Windows OSes
313 to disable the built-in firewall (if any).
314
315 If not supported, returns an empty array.
316 """
317 if sOsType == 'vista': # pylint: disable=no-else-return
318 # Vista and up.
319 return (['netsh.exe', 'advfirewall', 'set', 'allprofiles', 'state', 'off']);
320 elif sOsType == 'xp': # Older stuff (XP / 2003).
321 return(['netsh.exe', 'firewall', 'set', 'opmode', 'mode=DISABLE']);
322 # Not supported / available.
323 return [];
324
325 def disableGstFirewall(self, oTestVm, oTxsSession):
326 """
327 Disables the firewall on a guest (if any).
328
329 Needs elevated / admin / root privileges.
330
331 Returns success status, not logged.
332 """
333 fRc = False;
334
335 asArgs = [];
336 sOsType = '';
337 if oTestVm.isWindows():
338 if oTestVm.sKind in ['WindowsNT4', 'WindowsNT3x']:
339 sOsType = 'nt3x'; # Not supported, but define it anyway.
340 elif oTestVm.sKind in ('Windows2000', 'WindowsXP', 'Windows2003'):
341 sOsType = 'xp';
342 else:
343 sOsType = 'vista';
344 asArgs = self.getWinFirewallArgsDisable(sOsType);
345 else:
346 sOsType = 'unsupported';
347
348 reporter.log('Disabling firewall on guest (type: %s) ...' % (sOsType,));
349
350 if asArgs:
351 fRc = self.txsRunTest(oTxsSession, 'Disabling guest firewall', 3 * 60 * 1000, \
352 oTestVm.pathJoin(self.getGuestSystemDir(oTestVm), asArgs[0]), asArgs);
353 if not fRc:
354 reporter.error('Disabling firewall on guest returned exit code error %d' % (self.getLastRcFromTxs(oTxsSession)));
355 else:
356 reporter.log('Firewall not available on guest, skipping');
357 fRc = True; # Not available, just skip.
358
359 return fRc;
360
361 def disableHstFirewall(self):
362 """
363 Disables the firewall on the host (if any).
364
365 Needs elevated / admin / root privileges.
366
367 Returns success status, not logged.
368 """
369 fRc = False;
370
371 asArgs = [];
372 sOsType = sys.platform;
373
374 if sOsType == 'win32':
375 reporter.log('Disabling firewall on host (type: %s) ...' % (sOsType));
376
377 ## @todo For now we ASSUME that we don't run (and don't support even) on old(er)
378 # Windows hosts than Vista.
379 asArgs = self.getWinFirewallArgsDisable('vista');
380 if asArgs:
381 fRc = self.executeHst('Disabling host firewall', asArgs, fAsAdmin = True);
382 else:
383 reporter.log('Firewall not available on host, skipping');
384 fRc = True; # Not available, just skip.
385
386 return fRc;
387
388 def getLastRcFromTxs(self, oTxsSession):
389 """
390 Extracts the last exit code reported by TXS from a run before.
391 Assumes that nothing else has been run on the same TXS session in the meantime.
392 """
393 iRc = 0;
394 (_, sOpcode, abPayload) = oTxsSession.getLastReply();
395 if sOpcode.startswith('PROC NOK '): # Extract process rc
396 iRc = abPayload[0]; # ASSUMES 8-bit rc for now.
397 return iRc;
398
399 def startVkatOnGuest(self, oTestVm, oSession, oTxsSession, sTag):
400 """
401 Starts VKAT on the guest (running in background).
402 """
403 sPathTemp = self.getGuestTempDir(oTestVm);
404 sPathAudioOut = oTestVm.pathJoin(sPathTemp, 'vkat-guest-out');
405 sPathAudioTemp = oTestVm.pathJoin(sPathTemp, 'vkat-guest-temp');
406
407 reporter.log('Guest audio test temp path is \"%s\"' % (sPathAudioOut));
408 reporter.log('Guest audio test output path is \"%s\"' % (sPathAudioTemp));
409 reporter.log('Guest audio test tag is \"%s\"' % (sTag));
410
411 fRc, sVkatExe = self.locateGstBinary(oSession, oTxsSession, self.asGstVkatPaths);
412 if fRc:
413 reporter.log('Using VKAT on guest at \"%s\"' % (sVkatExe));
414
415 sCmd = '';
416 asArgs = [];
417
418 asArgsVkat = [ sVkatExe, 'test', '--mode', 'guest', '--probe-backends', \
419 '--tempdir', sPathAudioTemp, '--outdir', sPathAudioOut, \
420 '--tag', sTag ];
421
422 asArgs.extend(asArgsVkat);
423
424 for _ in range(1, reporter.getVerbosity()): # Verbosity always is initialized at 1.
425 asArgs.extend([ '-v' ]);
426
427 # Needed for NATed VMs.
428 asArgs.extend(['--tcp-connect-addr', '10.0.2.2' ]);
429
430 if oTestVm.isLinux(): ## @todo Might need some more fine tuning later.
431 #
432 # Some Linux distros have a bug / are configured (?) so that processes started by init system
433 # cannot access the PulseAudio server ("Connection refused"), for example OL 8.1.
434 #
435 # To work around this, we use the (hopefully) configured user "vbox" and run it under its behalf,
436 # as the Test Execution Service (TxS) currently does not implement impersonation yet.
437 #
438 asSU = [ '/bin/su',
439 '/usr/bin/su',
440 '/usr/local/bin/su' ];
441 fRc, sCmd = self.locateGstBinary(oSession, oTxsSession, asSU);
442 if fRc:
443 sCmdArgs = '';
444 for sArg in asArgs:
445 sCmdArgs += sArg + " ";
446 asArgs = [ sCmd, 'vbox', '-c', sCmdArgs ];
447 else:
448 reporter.log('Unable to find SU on guest, falling back to regular starting ...')
449
450 if not sCmd: # Just start it with the same privileges as TxS.
451 sCmd = sVkatExe;
452
453 reporter.log2('startVkatOnGuest: sCmd=%s' % (sCmd,));
454 reporter.log2('startVkatOnGuest: asArgs=%s' % (asArgs,));
455
456 #
457 # Add own environment stuff.
458 #
459 asEnv = [];
460
461 # Write the log file to some deterministic place so TxS can retrieve it later.
462 sVkatLogFile = 'VKAT_RELEASE_LOG_DEST=file=' + self.getGstVkatLogFilePath(oTestVm);
463 asEnv.extend([ sVkatLogFile ]);
464
465 #
466 # Execute asynchronously on the guest.
467 #
468 fRc = oTxsSession.asyncExec(sCmd, asArgs, asEnv, cMsTimeout = 15 * 60 * 1000, sPrefix = '[VKAT Guest] ');
469 if fRc:
470 self.addTask(oTxsSession);
471
472 if not fRc:
473 reporter.error('VKAT on guest returned exit code error %d' % (self.getLastRcFromTxs(oTxsSession)));
474 else:
475 reporter.error('VKAT on guest not found');
476
477 return fRc;
478
479 def runTests(self, oTestVm, oSession, oTxsSession, sDesc, sTag, asTests):
480 """
481 Runs one or more tests using VKAT on the host, which in turn will
482 communicate with VKAT running on the guest and the Validation Kit
483 audio driver ATS (Audio Testing Service).
484 """
485 _ = oTestVm, oSession, oTxsSession;
486
487 sPathTemp = self.sScratchPath;
488 sPathAudioOut = os.path.join(sPathTemp, 'vkat-host-out-%s' % (sTag));
489 sPathAudioTemp = os.path.join(sPathTemp, 'vkat-host-temp-%s' % (sTag));
490
491 reporter.log('Host audio test temp path is \"%s\"' % (sPathAudioOut));
492 reporter.log('Host audio test output path is \"%s\"' % (sPathAudioTemp));
493 reporter.log('Host audio test tag is \"%s\"' % (sTag));
494
495 reporter.testStart(sDesc);
496
497 sVkatExe = self.getBinTool('vkat');
498
499 reporter.log('Using VKAT on host at: \"%s\"' % (sVkatExe));
500
501 # Build the base command line, exclude all tests by default.
502 asArgs = [ sVkatExe, 'test', '--mode', 'host', '--probe-backends', \
503 '--tempdir', sPathAudioTemp, '--outdir', sPathAudioOut, '-a', \
504 '--tag', sTag, \
505 '--no-verify' ]; # We do the verification separately in the step below.
506
507 for _ in range(1, reporter.getVerbosity()): # Verbosity always is initialized at 1.
508 asArgs.extend([ '-v' ]);
509
510 # ... and extend it with wanted tests.
511 asArgs.extend(asTests);
512
513 #
514 # Let VKAT on the host run synchronously.
515 #
516 fRc = self.executeHst("VKAT Host", asArgs);
517
518 reporter.testDone();
519
520 if fRc:
521 #
522 # When running the test(s) above were successful, do the verification step next.
523 # This gives us a bit more fine-grained test results in the test manager.
524 #
525 reporter.testStart('Verifying audio data');
526
527 sNameSetHst = '%s-host.tar.gz' % (sTag);
528 sPathSetHst = os.path.join(sPathAudioOut, sNameSetHst);
529 sNameSetGst = '%s-guest.tar.gz' % (sTag);
530 sPathSetGst = os.path.join(sPathAudioOut, sNameSetGst);
531
532 asArgs = [ sVkatExe, 'verify', sPathSetHst, sPathSetGst ];
533
534 for _ in range(1, reporter.getVerbosity()): # Verbosity always is initialized at 1.
535 asArgs.extend([ '-v' ]);
536
537 fRc = self.executeHst("VKAT Host Verify", asArgs);
538 if fRc:
539 reporter.log("Verification audio data successful");
540 else:
541 #
542 # Add the test sets to the test manager for later (manual) diagnosis.
543 #
544 reporter.addLogFile(sPathSetGst, 'misc/other', 'Guest audio test set');
545 reporter.addLogFile(sPathSetHst, 'misc/other', 'Host audio test set');
546
547 reporter.error("Verification of audio data failed");
548
549 reporter.testDone();
550
551 return fRc;
552
553 def doTest(self, oTestVm, oSession, oTxsSession):
554 """
555 Executes the specified audio tests.
556 """
557
558 # Disable any OS-specific firewalls preventing VKAT / ATS to run.
559 fRc = self.disableHstFirewall();
560 fRc = self.disableGstFirewall(oTestVm, oTxsSession) and fRc;
561
562 if not fRc:
563 return False;
564
565 # First try to kill any old VKAT / VBoxAudioTest processes lurking around on the host.
566 # Might happen because of former (aborted) runs.
567 self.killHstVkat();
568
569 reporter.log("Active tests: %s" % (self.asTests,));
570
571 # Define a tag for the whole run.
572 sTag = oTestVm.sVmName + "_" + datetime.now().strftime("%Y%m%d_%H%M%S");
573
574 fRc = self.startVkatOnGuest(oTestVm, oSession, oTxsSession, sTag);
575 if fRc:
576 #
577 # Execute the tests using VKAT on the guest side (in guest mode).
578 #
579 if "guest_tone_playback" in self.asTests:
580 fRc = self.runTests(oTestVm, oSession, oTxsSession, \
581 'Guest audio playback', sTag + "_test_playback", \
582 asTests = [ '-i0' ]);
583 if "guest_tone_recording" in self.asTests:
584 fRc = fRc and self.runTests(oTestVm, oSession, oTxsSession, \
585 'Guest audio recording', sTag + "_test_recording", \
586 asTests = [ '-i1' ]);
587
588 # Cancel guest VKAT execution task summoned by startVkatOnGuest().
589 oTxsSession.cancelTask();
590
591 #
592 # Retrieve log files for diagnosis.
593 #
594 self.txsDownloadFiles(oSession, oTxsSession,
595 [ ( self.getGstVkatLogFilePath(oTestVm),
596 'vkat-guest-%s.log' % (oTestVm.sVmName,),),
597 ],
598 fIgnoreErrors = True);
599 return fRc;
600
601 def testOneVmConfig(self, oVM, oTestVm):
602 """
603 Runs tests using one specific VM config.
604 """
605
606 self.logVmInfo(oVM);
607
608 reporter.testStart("Audio Testing");
609
610 fSkip = False;
611
612 if oTestVm.isWindows() \
613 and oTestVm.sKind in ('WindowsNT4', 'Windows2000'): # Too old for DirectSound and WASAPI backends.
614 reporter.log('Audio testing skipped, not implemented/available for that OS yet.');
615 fSkip = True;
616
617 if not fSkip \
618 and self.fpApiVer < 7.0:
619 reporter.log('Audio testing for non-trunk builds skipped.');
620 fSkip = True;
621
622 sVkatExe = self.getBinTool('vkat');
623 asArgs = [ sVkatExe, 'enum', '--probe-backends' ];
624 fRc = self.executeHst("VKAT Host Audio Probing", asArgs);
625 if not fSkip \
626 and not fRc:
627 reporter.log('Audio not available on host, skipping audio tests.');
628 fSkip = True;
629
630 if fSkip:
631 reporter.testDone(fSkipped = True);
632 return True;
633
634 # Reconfigure the VM.
635 oSession = self.openSession(oVM);
636 if oSession is not None:
637 # Set extra data.
638 for sExtraData in self.asOptExtraData:
639 sKey, sValue = sExtraData.split(':');
640 reporter.log('Set extradata: %s => %s' % (sKey, sValue));
641 fRc = oSession.setExtraData(sKey, sValue) and fRc;
642
643 # Make sure that the VM's audio adapter is configured the way we need it to.
644 if self.fpApiVer >= 4.0:
645 oOsType = oSession.getOsType();
646 ## @ŧdoo Make this configurable via driver opts (to use as a variant)?
647 oSession.setupAudio(oOsType.recommendedAudioController,
648 fEnable = True, fEnableIn = True, fEnableOut = True);
649
650 # Save the settings.
651 fRc = fRc and oSession.saveSettings();
652 fRc = oSession.close() and fRc;
653
654 reporter.testStart('Waiting for TXS');
655 oSession, oTxsSession = self.startVmAndConnectToTxsViaTcp(oTestVm.sVmName,
656 fCdWait = True,
657 cMsTimeout = 3 * 60 * 1000,
658 sFileCdWait = '${OS/ARCH}/vkat${EXESUFF}');
659 reporter.testDone();
660
661 if oSession is not None:
662 self.addTask(oTxsSession);
663
664 fRc = self.doTest(oTestVm, oSession, oTxsSession);
665
666 # Cleanup.
667 self.removeTask(oTxsSession);
668 self.terminateVmBySession(oSession);
669
670 reporter.testDone();
671 return fRc;
672
673 def onExit(self, iRc):
674 """
675 Exit handler for this test driver.
676 """
677 return vbox.TestDriver.onExit(self, iRc);
678
679if __name__ == '__main__':
680 sys.exit(tdAudioTest().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