VirtualBox

Changeset 90741 in vbox for trunk/src


Ignore:
Timestamp:
Aug 19, 2021 10:24:06 AM (3 years ago)
Author:
vboxsync
Message:

Audio/ValKit: tdAudioTest.py: More adjustments / additions for Windows guests. ​bugref:10008

File:
1 edited

Legend:

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

    r90684 r90741  
    3434
    3535# Standard Python imports.
     36import asyncio
    3637import os
    3738import sys
     
    6667            '/tmp/vkat',
    6768            '/tmp/VBoxAudioTest',
     69            'C:\\Temp\\vkat',
     70            'C:\\Temp\\VBoxAudioTest',
    6871            # Validation Kit .ISO.
    6972            '${CDROM}/vboxvalidationkit/${OS/ARCH}/vkat${EXESUFF}',
    7073            '${CDROM}/${OS/ARCH}/vkat${EXESUFF}',
     74            # Test VMs.
     75            '/opt/apps/vkat',
     76            '/opt/apps/VBoxAudioTest',
     77            '/apps/vkat',
     78            '/apps/VBoxAudioTest',
     79            'C:\\Apps\\vkat${EXESUFF}',
     80            'C:\\Apps\\VBoxAudioTest${EXESUFF}',
    7181            ## @odo VBoxAudioTest on Guest Additions?
    7282        ];
     
    178188            if oSession:
    179189                # Tweak this to your likings.
    180                 oTestVm = vboxtestvms.TestVm('runningvm', sKind = 'Ubuntu_64');
     190                oTestVm = vboxtestvms.TestVm('runningvm', sKind = 'WindowsXP'); #sKind = 'WindowsXP' # sKind = 'Ubuntu_64'
    181191                (fRc, oTxsSession) = self.txsDoConnectViaTcp(oSession, 30 * 1000);
    182192                if fRc:
     
    194204        Returns the log file path of VKAT running on the guest (daemonized).
    195205        """
    196         return oTestVm.pathJoin(self.getGuestTempDir(oTestVm), 'vkat-guest-daemonized.log');
     206        return oTestVm.pathJoin(self.getGuestTempDir(oTestVm), 'vkat-guest.log');
    197207
    198208    def locateGstVkat(self, oSession, oTxsSession):
     
    207217        return (False, "");
    208218
    209     def executeHstBinaryAsAdmin(self, sWhat, asArgs):
    210         """
    211         Runs a binary (image) with admin (root) rights on the host.
     219    def executeHstLoop(self, sWhat, asArgs, fAsAdmin = False):
     220
     221        fRc = False;
     222
     223        if  fAsAdmin \
     224        and utils.getHostOs() != 'win':
     225            oProcess = utils.sudoProcessPopen(asArgs,
     226                                              stdout = subprocess.PIPE, stderr = subprocess.PIPE, shell = False,
     227                                              close_fds = False);
     228        else:
     229            oProcess = utils.processPopenSafe(asArgs,
     230                                              stdout = subprocess.PIPE, stderr = subprocess.PIPE);
     231        if oProcess:
     232            for line in iter(oProcess.stdout.readline, b''):
     233                reporter.log('[' + sWhat + '] ' + line.decode(sys.stdin.encoding));
     234            iExitCode = oProcess.poll();
     235            if iExitCode:
     236                if iExitCode == 0:
     237                    reporter.error('Executing \"%s\" was successful' % (sWhat));
     238                    fRc = True;
     239                else:
     240                    reporter.error('Executing \"%s\" on host returned exit code error %d' % (sWhat, iExitCode));
     241
     242        if not fRc:
     243            reporter.error('Executing \"%s\" on host failed' % (sWhat,));
     244
     245        return fRc;
     246
     247    # Only Python 3.x and up.
     248    async def execHstAsyncCallback(self, *aPositionalArgs):
     249        sWhat  = aPositionalArgs[0];
     250        asArgs = aPositionalArgs[1:];
     251        fRc = self.executeHstLoop(sWhat, asArgs);
     252        if not fRc:
     253            reporter.error('Asynchronous execution of \"%s\" on host failed' % (sWhat,));
     254
     255    def executeHst(self, sWhat, asArgs, fAsync = False, fAsAdmin = False):
     256        """
     257        Runs a binary (image) with optional admin (root) rights on the host and
     258        waits until it terminates.
     259
     260        Windows currently is not supported yet running stuff as Administrator.
    212261
    213262        Returns success status (exit code is 0).
    214263        """
    215         fRc      = False;
    216         oProcess = utils.sudoProcessPopen(asArgs, stdout=subprocess.PIPE, stdin=subprocess.PIPE,
    217                                           stderr=subprocess.PIPE, shell = False, close_fds = False);
    218         if oProcess:
    219             sOut, sErr = oProcess.communicate();
    220 
    221             sOut = sOut.decode(sys.stdin.encoding);
    222             for sLine in sOut.split('\n'):
    223                 reporter.log(sLine);
    224 
    225             sErr = sErr.decode(sys.stdin.encoding);
    226             for sLine in sErr.split('\n'):
    227                 reporter.log(sLine);
    228 
    229             iExitCode = oProcess.poll();
    230             if iExitCode == 0:
    231                 fRc = True;
    232             else:
    233                 reporter.error('%s on host returned exit code error %d' % (sWhat, iExitCode));
    234         else:
    235             fRc = False;
    236 
    237         if not fRc:
    238             reporter.error('%s on host failed' % (sWhat,));
     264        reporter.log('Executing \"%s\" on host (as admin = %s, async = %s)' % (sWhat, fAsAdmin, fAsync));
     265
     266        reporter.testStart(sWhat);
     267
     268        fRc = False;
     269
     270        if fAsync: # Only Python 3.x and up.
     271            asyncio.run(self.execHstAsyncCallback(sWhat, *asArgs));
     272            fRc = True;
     273        else:
     274            fRc = self.executeHstLoop(sWhat, asArgs);
     275
     276        if fRc:
     277            reporter.error('Executing \"%s\" on host done' % (sWhat,));
     278        else:
     279            reporter.error('Executing \"%s\" on host failed' % (sWhat,));
     280
     281        reporter.testDone();
    239282
    240283        return fRc;
     
    248291            sArgProcName = '\"%s.exe\"' % sProcName;
    249292            asArgs       = [ 'taskkill', '/IM', sArgProcName, '/F' ];
    250             self.executeHstBinaryAsAdmin('Killing process', asArgs);
     293            self.executeHst('Killing process', asArgs);
    251294        else: # Note: killall is not available on older Debians (requires psmisc).
    252295            # Using the BSD syntax here; MacOS also should understand this.
     
    256299                if sProcName in sLine:
    257300                    pid = int(sLine.split(None, 1)[0]);
    258                     reporter.log2('Killing PID %d' % (pid,));
     301                    reporter.log('Killing PID %d' % (pid,));
    259302                    os.kill(pid, signal.SIGKILL); # pylint: disable=no-member
    260303
     
    318361        return fRc;
    319362
     363    def setGstAudioBackend(self, oTestVm, asArgs):
     364        """
     365        Guesses guest OS, uses an alternative (non-default) audio backends if necessary
     366        and appends it to the given arguments sequence.
     367
     368        Returns the altered arguments sequence.
     369        """
     370        asArgsRet = asArgs;
     371
     372        # Note: Also works with the 64-bit variants (if any).
     373        sOsType = oTestVm.getNonCanonicalGuestOsType();
     374        if "Windows2000" in sOsType \
     375        or "WindowsXP"   in sOsType \
     376        or "Windows2003" in sOsType \
     377        or "Windows7"    in sOsType:
     378            ## @todo Some more here?
     379            asArgsRet.extend( [ '--backend', 'directsound' ]);
     380
     381        ## @todo Tweak old(er) Linux'es as well to use OSS instead of PulseAudio?
     382        return asArgsRet;
     383
    320384    def disableHstFirewall(self):
    321385        """
     
    338402            asArgs = self.getWinFirewallArgsDisable('vista');
    339403            if asArgs:
    340                 fRc = self.executeHstBinaryAsAdmin('Disabling firewall', asArgs);
     404                fRc = self.executeHst('Disabling host firewall', asArgs, fAsAdmin = True);
    341405        else:
    342406            reporter.log('Firewall not available on host, skipping');
     
    371435            reporter.log('Using VKAT on guest at \"%s\"' % (sVkatExe));
    372436
    373             aArgs     = [ sVkatExe, 'test', '-vvvv', '--mode', 'guest', \
    374                                     '--tempdir', sPathAudioTemp, '--outdir', sPathAudioOut ];
    375             #
    376             # Start VKAT in the background (daemonized) on the guest side, so that we
    377             # can continue starting VKAT on the host.
    378             #
    379             aArgs.extend(['--daemonize']);
     437            asArgs = [ sVkatExe, 'test', '-vv', '--mode', 'guest', \
     438                                 '--tempdir', sPathAudioTemp, '--outdir', sPathAudioOut ];
     439
     440            # Guess the guest backend and apply the new arguments (if any).
     441            asArgs = self.setGstAudioBackend(oTestVm, asArgs);
    380442
    381443            #
    382444            # Add own environment stuff.
    383445            #
    384             aEnv = [];
     446            asEnv = [];
    385447
    386448            # Write the log file to some deterministic place so TxS can retrieve it later.
    387449            sVkatLogFile = 'VKAT_RELEASE_LOG_DEST=file=' + self.getGstVkatLogFilePath(oTestVm);
    388             aEnv.extend([ sVkatLogFile ]);
     450            asEnv.extend([ sVkatLogFile ]);
    389451
    390452            #
    391             # Execute.
     453            # Execute asynchronously on the guest.
    392454            #
    393             fRc = self.txsRunTest(oTxsSession, 'Starting VKAT on guest', 15 * 60 * 1000,
    394                                   sVkatExe, aArgs, aEnv);
     455            fRc = oTxsSession.asyncExec(sVkatExe, asArgs, asEnv, cMsTimeout = 15 * 60 * 1000);
     456            if fRc:
     457                self.addTask(oTxsSession);
     458
    395459            if not fRc:
    396460                reporter.error('VKAT on guest returned exit code error %d' % (self.getLastRcFromTxs(oTxsSession)));
     
    400464        return fRc;
    401465
    402     def runTests(self, oTestVm, oSession, oTxsSession, sDesc, sTests):
     466    def runTests(self, oTestVm, oSession, oTxsSession, sDesc, asTests):
    403467        """
    404468        Runs one or more tests using VKAT on the host, which in turn will
     
    422486
    423487        # Build the base command line, exclude all tests by default.
    424         sArgs = '%s test -vvvv --mode host --tempdir %s --outdir %s -a' \
    425                 % (sVkatExe, sPathAudioTemp, sPathAudioOut);
     488        asArgs = [ sVkatExe, 'test', '-vv', '--mode', 'host', '--tempdir', sPathAudioTemp, '--outdir', sPathAudioOut, '-a' ];
    426489
    427490        # ... and extend it with wanted tests.
    428         sArgs += " " + sTests;
    429 
    430         fRc = True;
    431 
    432         reporter.testStart(sDesc);
     491        asArgs.extend(asTests);
    433492
    434493        #
    435494        # Let VKAT on the host run synchronously.
    436495        #
    437         procVkat = subprocess.Popen(sArgs, \
    438                                     stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True);
    439         if procVkat:
    440             reporter.log('VKAT on host started');
    441 
    442             out, err = procVkat.communicate();
    443             rc = procVkat.poll();
    444 
    445             out = out.decode(sys.stdin.encoding);
    446             for line in out.split('\n'):
    447                 reporter.log(line);
    448 
    449             err = err.decode(sys.stdin.encoding);
    450             for line in err.split('\n'):
    451                 reporter.log(line);
    452 
    453             reporter.log('VKAT on host ended with exit code %d' % rc);
    454             if rc != 0:
    455                 reporter.testFailure('VKAT on the host failed');
    456                 fRc = False;
    457         else:
    458             reporter.testFailure('VKAT on the host failed to start');
    459             fRc = False;
    460 
    461         reporter.testDone();
     496        fRc = self.executeHst("VKAT Host", asArgs, fAsync = False);
    462497
    463498        return fRc;
     
    487522            #
    488523            if "guest_tone_playback" in self.asTests:
    489                 fRc = self.runTests(oTestVm, oSession, oTxsSession, 'Guest audio playback', '-i0');
     524                fRc = self.runTests(oTestVm, oSession, oTxsSession, 'Guest audio playback', asTests = [ '-i0' ]);
    490525            if "guest_tone_recording" in self.asTests:
    491                 fRc = fRc and self.runTests(oTestVm, oSession, oTxsSession, 'Guest audio recording', '-i1');
     526                fRc = fRc and self.runTests(oTestVm, oSession, oTxsSession, 'Guest audio recording', asTests = [ '-i1' ]);
    492527
    493528        #
     
    496531        self.txsDownloadFiles(oSession, oTxsSession,
    497532                              [ ( self.getGstVkatLogFilePath(oTestVm),
    498                                   'vkat-guest-daemonized-%s.log' % (oTestVm.sVmName,),),
     533                                  'vkat-guest-%s.log' % (oTestVm.sVmName,),),
    499534                              ],
    500535                              fIgnoreErrors = True);
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