VirtualBox

Changeset 90099 in vbox


Ignore:
Timestamp:
Jul 8, 2021 2:29:28 PM (4 years ago)
Author:
vboxsync
Message:

Audio/ValKit: First working version of the VKAT Validation Kit test driver. bugref:10008

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/ValidationKit/tests/audio/tdAudioTest.py

    r89317 r90099  
    33
    44"""
    5 AudioTest test driver which invokes the AudioTest (VKAT) binary to
    6 perform the actual audio tests.
     5AudioTest test driver which invokes the VKAT (Validation Kit Audio Test)
     6binary to perform the actual audio tests.
    77
    88The generated test set archive on the guest will be downloaded by TXS
     
    3636import os
    3737import sys
    38 import re
    3938import subprocess
    40 import time
    4139import uuid
     40
     41# Only the main script needs to modify the path.
     42try:    __file__
     43except: __file__ = sys.argv[0];
     44g_ksValidationKitDir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))));
     45sys.path.append(g_ksValidationKitDir);
    4246
    4347# Validation Kit imports.
     
    5155
    5256class tdAudioTest(vbox.TestDriver):
    53 
     57    """
     58    Runs various audio tests.
     59    """
    5460    def __init__(self):
    5561        vbox.TestDriver.__init__(self);
     62        self.oTestVmSet       = self.oTestVmManager.getSmokeVmSet('nat');
     63        self.asGstVkatPaths   = [
     64            # Debugging stuff (SCP'd over to the guest).
     65            '/tmp/vkat',
     66            '/tmp/VBoxAudioTest',
     67            # Validation Kit .ISO.
     68            '${CDROM}/vboxvalidationkit/${OS/ARCH}/vkat${EXESUFF}',
     69            '${CDROM}/${OS/ARCH}/vkat${EXESUFF}',
     70            ## @odo VBoxAudioTest on Guest Additions?
     71        ];
     72
     73        # Enable audio debug mode.
     74        #
     75        # This is needed in order to load and use the Validation Kit audio driver,
     76        # which in turn is being used in conjunction with the guest side to record
     77        # output (guest is playing back) and injecting input (guest is recording).
     78        self.asOptExtraData   = [
     79            'VBoxInternal2/Audio/Debug/Enabled:true',
     80        ];
     81
     82        self.sRunningVmName = None
    5683
    5784    def showUsage(self):
    58         return vbox.TestDriver.showUsage(self);
     85        """
     86        Shows the audio test driver-specific command line options.
     87        """
     88        fRc = vbox.TestDriver.showUsage(self);
     89        reporter.log('');
     90        reporter.log('tdAudioTest Options:');
     91        reporter.log(' --runningvmname <vmname>');
     92        return fRc;
     93
     94    def parseOption(self, asArgs, iArg):
     95        """
     96        Parses the audio test driver-specific command line options.
     97        """
     98        if asArgs[iArg] == '--runningvmname':
     99            iArg += 1;
     100            if iArg >= len(asArgs):
     101                raise base.InvalidOption('The "--runningvmname" needs VM name');
     102
     103            self.sRunningVmName = asArgs[iArg];
     104        else:
     105            return vbox.TestDriver.parseOption(self, asArgs, iArg);
     106        return iArg + 1;
    59107
    60108    def actionConfig(self):
     109        """
     110        Configures the test driver before running.
     111        """
    61112        return True
    62113
    63114    def actionExecute(self):
    64         if self.sVMname is None:
     115        """
     116        Executes the test driver.
     117        """
     118        if self.sRunningVmName is None:
    65119            return self.oTestVmSet.actionExecute(self, self.testOneVmConfig);
    66120        return self.actionExecuteOnRunnigVM();
    67121
     122    def actionExecuteOnRunnigVM(self):
     123        """
     124        Executes the tests in an already configured + running VM.
     125        """
     126        if not self.importVBoxApi():
     127            return False;
     128
     129        fRc = True;
     130
     131        oVirtualBox = self.oVBoxMgr.getVirtualBox();
     132        try:
     133            oVM = oVirtualBox.findMachine(self.sRunningVmName);
     134            if oVM.state != self.oVBoxMgr.constants.MachineState_Running:
     135                reporter.error("Machine '%s' is not in Running state" % (self.sRunningVmName));
     136                fRc = False;
     137        except:
     138            reporter.errorXcpt("Machine '%s' not found" % (self.sRunningVmName));
     139            fRc = False;
     140
     141        if fRc:
     142            oSession = self.openSession(oVM);
     143            if oSession:
     144                # Tweak this to your likings.
     145                oTestVm = vboxtestvms.TestVm('runningvm', sKind = 'Ubuntu_64');
     146                (fRc, oTxsSession) = self.txsDoConnectViaTcp(oSession, 30 * 1000);
     147                if fRc:
     148                    self.doTest(oTestVm, oSession, oTxsSession);
     149            else:
     150                reporter.error("Unable to open session for machine '%s'" % (self.sRunningVmName));
     151                fRc = False;
     152
     153        del oVM;
     154        del oVirtualBox;
     155        return fRc;
     156
     157    def _locateGstVkat(self, oSession, oTxsSession):
     158        """
     159        Returns guest side path to VKAT.
     160        """
     161        for sVkatPath in self.asGstVkatPaths:
     162            reporter.log2('Checking for VKAT at: %s ...' % (sVkatPath));
     163            if self.txsIsFile(oSession, oTxsSession, sVkatPath):
     164                return (True, sVkatPath);
     165        reporter.error('Unable to find guest VKAT in any of these places:\n%s' % ('\n'.join(self.asGstVkatPaths),));
     166        return (False, "");
     167
     168    def _getVkatResult(self, oTxsSession):
     169        """
     170        Extracts the VKAT exit code from a run before.
     171        Assumes that nothing else has been run on the same TXS session in the meantime.
     172        """
     173        iRc = 0;
     174        (_, sOpcode, abPayload) = oTxsSession.getLastReply();
     175        if sOpcode.startswith('PROC NOK '): # Extract process rc
     176            iRc = abPayload[0]; # ASSUMES 8-bit rc for now.
     177        return iRc;
     178
     179    def startVkatOnGuest(self, oTestVm, oSession, oTxsSession):
     180        """
     181        Starts VKAT on the guest (running in background).
     182        """
     183        sDesc          = 'Starting VKAT on guest';
     184
     185        sPathTemp      = self.getGuestTempDir(oTestVm);
     186        sPathAudioOut  = oTestVm.pathJoin(sPathTemp, 'vkat-guest-out');
     187        sPathAudioTemp = oTestVm.pathJoin(sPathTemp, 'vkat-guest-temp');
     188
     189        reporter.log('Guest audio test temp path is \"%s\"' % (sPathAudioOut));
     190        reporter.log('Guest audio test output path is \"%s\"' % (sPathAudioTemp));
     191
     192        fRc, sVkatExe = self._locateGstVkat(oSession, oTxsSession);
     193        if fRc:
     194            reporter.log('Using VKAT on guest at \"%s\"' % (sVkatExe));
     195
     196            aArgs     = [ sVkatExe, 'test', '-vvvv', '--mode', 'guest', \
     197                                    '--tempdir', sPathAudioTemp, '--outdir', sPathAudioOut ];
     198            #
     199            # Start VKAT in the background (daemonized) on the guest side, so that we
     200            # can continue starting VKAT on the host.
     201            #
     202            aArgs.extend(['--daemonize']);
     203
     204            fRc = self.txsRunTest(oTxsSession, sDesc, 15 * 60 * 1000,
     205                                  sVkatExe, aArgs);
     206            if not fRc:
     207                reporter.error('VKAT on guest returned exit code error %d' % (self._getVkatResult(oTxsSession)));
     208
     209        return fRc;
     210
     211    def runTests(self, oTestVm, oSession, oTxsSession, sDesc, sTests):
     212        """
     213        Runs one or more tests using VKAT on the host, which in turn will
     214        communicate with VKAT running on the guest and the Validation Kit
     215        audio driver ATS (Audio Testing Service).
     216        """
     217        _              = oSession, oTxsSession;
     218        sTag           = uuid.uuid4();
     219
     220        sPathTemp      = self.sScratchPath;
     221        sPathAudioOut  = oTestVm.pathJoin(sPathTemp, 'vkat-host-out-%s' % (sTag));
     222        sPathAudioTemp = oTestVm.pathJoin(sPathTemp, 'vkat-host-temp-%s' % (sTag));
     223
     224        reporter.log('Host audio test temp path is \"%s\"' % (sPathAudioOut));
     225        reporter.log('Host audio test output path is \"%s\"' % (sPathAudioTemp));
     226        reporter.log('Host audio test tag is \"%s\"' % (sTag));
     227
     228        sVkatExe = self.getBinTool('vkat');
     229
     230        reporter.log('Using VKAT on host at: \"%s\"' % (sVkatExe));
     231
     232        # Build the base command line, exclude all tests by default.
     233        sArgs = '%s test -vvvv --mode host --tempdir %s --outdir %s -a' \
     234                % (sVkatExe, sPathAudioTemp, sPathAudioOut);
     235
     236        # ... and extend it with wanted tests.
     237        sArgs += " " + sTests;
     238
     239        fRc = True;
     240
     241        reporter.testStart(sDesc);
     242
     243        #
     244        # Let VKAT on the host run synchronously.
     245        #
     246        procVkat = subprocess.Popen(sArgs, \
     247                                    stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True);
     248        if procVkat:
     249            while procVkat.poll() is None:
     250                sLine = procVkat.stdout.readline().rstrip();
     251                if sLine:
     252                    reporter.log(sLine);
     253
     254            if procVkat.returncode != 0:
     255                reporter.testFailure('VKAT on the host failed with exit code %d' % (procVkat.returncode));
     256                fRc = False;
     257        else:
     258            reporter.testFailure('VKAT on the host failed to start');
     259            fRc = False;
     260
     261        reporter.testDone();
     262
     263        return fRc;
     264
     265    def doTest(self, oTestVm, oSession, oTxsSession):
     266        """
     267        Executes the specified audio tests.
     268        """
     269        fRc = self.startVkatOnGuest(oTestVm, oSession, oTxsSession);
     270        if fRc:
     271            #
     272            # Execute the tests using VKAT on the guest side (in guest mode).
     273            #
     274            fRc = self.runTests(oTestVm, oSession, oTxsSession, 'Guest audio playback', '-i0');
     275            fRc = fRc and self.runTests(oTestVm, oSession, oTxsSession, 'Guest audio recording', '-i1');
     276
     277        return fRc;
     278
    68279    def testOneVmConfig(self, oVM, oTestVm):
    69 
     280        """
     281        Runs tests using one specific VM config.
     282        """
    70283        fRc = False;
    71284
     
    76289        and oTestVm.sKind in ('WindowsNT4', 'Windows2000'): # Too old for DirectSound and WASAPI backends.
    77290            fSkip = True;
    78         elif oTestVm.isLinux():
    79             pass;
    80         else: # Implement others first.
    81             fSkip = True;
    82291
    83292        if not fSkip:
    84293            reporter.testStart('Waiting for TXS');
    85             sPathAutoTestExe = '${CDROM}/vboxvalidationkit/${OS/ARCH}/vkat${EXESUFF}';
    86294            oSession, oTxsSession = self.startVmAndConnectToTxsViaTcp(oTestVm.sVmName,
    87295                                                                    fCdWait = True,
     
    89297                                                                    sFileCdWait = self.sFileCdWait);
    90298            reporter.testDone();
    91             if oSession is not None and oTxsSession is not None:
     299            if  oSession    is not None \
     300            and oTxsSession is not None:
    92301                self.addTask(oTxsSession);
    93302
    94                 sPathTemp      = self.getGuestTempDir(oTestVm);
    95                 sPathAudioOut  = oTestVm.pathJoin(sPathTemp, 'vkat-out');
    96                 sPathAudioTemp = oTestVm.pathJoin(sPathTemp, 'vkat-temp');
    97                 reporter.log("Audio test temp path is '%s'" % (sPathAudioOut));
    98                 reporter.log("Audio test output path is '%s'" % (sPathAudioTemp));
    99                 sTag           = uuid.uuid4();
    100                 reporter.log("Audio test tag is %s'" % (sTag));
    101 
    102                 reporter.testStart('Running vkat (Validation Kit Audio Test)');
    103                 fRc = self.txsRunTest(oTxsSession, 'vkat', 5 * 60 * 1000,
    104                                       self.getGuestSystemShell(oTestVm),
    105                                       (self.getGuestSystemShell(oTestVm),
    106                                        sPathAutoTestExe, '-vvv', 'test', '--tag ' + sTag,
    107                                        '--tempdir ' + sPathAudioTemp, '--outdir ' + sPathAudioOut));
    108                 reporter.testDone()
    109 
    110                 if fRc:
    111                     sFileAudioTestArchive = oTestVm.pathJoin(sPathTemp, 'vkat-%s.tar.gz' % (sTag));
    112                     fRc = self.txsDownloadFiles(oSession, oTxsSession,
    113                                                 [( sFileAudioTestArchive ), ], fIgnoreErrors = False);
    114                     if fRc:
    115                         ## @todo Add "AudioTest verify" here.
    116                         pass;
     303            fRc = self.doTest(oTestVm, oSessionWrapper.o, oTxsSession);
    117304
    118305            if oSession is not None:
     
    137324
    138325        self.logVmInfo(oVM);
     326
     327        # Reconfigure the VM.
     328        oSession = self.openSession(oVM);
     329        if oSession is not None:
     330            # Set extra data.
     331            for sExtraData in self.asOptExtraData:
     332                sKey, sValue = sExtraData.split(':');
     333                reporter.log('Set extradata: %s => %s' % (sKey, sValue))
     334                fRc = oSession.setExtraData(sKey, sValue) and fRc;
     335
     336            # Save the settings.
     337            fRc = fRc and oSession.saveSettings()
     338            fRc = oSession.close() and fRc;
    139339
    140340        fRc = True;
     
    155355
    156356    def onExit(self, iRc):
    157         if self.aoSubTstDrvs[0].oDebug.fNoExit:
    158             return True
     357        """
     358        Exit handler for this test driver.
     359        """
    159360        return vbox.TestDriver.onExit(self, iRc);
    160361
Note: See TracChangeset for help on using the changeset viewer.

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