Index: /trunk/src/VBox/ValidationKit/tests/audio/tdAudioTest.py
===================================================================
--- /trunk/src/VBox/ValidationKit/tests/audio/tdAudioTest.py	(revision 103385)
+++ /trunk/src/VBox/ValidationKit/tests/audio/tdAudioTest.py	(revision 103386)
@@ -301,6 +301,9 @@
 
         Might be called synchronously in main thread or via the thread exeuction helper (asynchronous).
+
+        Returns (success status, exit code).
         """
         fRc = False;
+        iRc = -42;
 
         asEnvTmp = os.environ.copy();
@@ -322,10 +325,8 @@
             if not oProcess:
                 reporter.error('Starting process for "%s" failed!' % (sWhat));
-                return False;
+                return fRc, iRc;
 
             iPid = oProcess.pid;
             self.pidFileAdd(iPid, sWhat);
-
-            iRc  = 0;
 
             while True if sys.version_info[0] < 3 else oProcess.stdout.readable(): # pylint: disable=no-member
@@ -341,18 +342,14 @@
             if iRc == 0:
                 reporter.log('*** %s: exit code %d' % (sWhat, iRc));
-                fRc = True;
             else:
                 reporter.log('!*! %s: exit code %d' % (sWhat, iRc));
 
+            fRc = True;
             self.pidFileRemove(iPid);
-
-            # Save thread result code.
-            self.iThreadHstProcRc = iRc;
-
         except:
             reporter.logXcpt('Executing "%s" failed!' % (sWhat));
 
         reporter.log('Executing \"%s\" on host %s' % (sWhat, 'done' if fRc else 'failed',));
-        return fRc;
+        return (fRc, iRc);
 
     def executeHstThread(self, sWhat, asArgs, asEnv = None, fAsAdmin = False):
@@ -360,7 +357,10 @@
         Thread execution helper to run a process on the host.
         """
-        return self.executeHstLoop(sWhat, asArgs, asEnv, fAsAdmin);
-
-    def executeHst(self, sWhat, asArgs, asEnv = None, fAsAdmin = False, fBlocking = True):
+        _, iRc = self.executeHstLoop(sWhat, asArgs, asEnv, fAsAdmin);
+
+        # Save thread result code.
+        self.iThreadHstProcRc = iRc;
+
+    def executeHst(self, sWhat, asArgs, asEnv = None, fAsAdmin = False, fBlocking = True, iExpectedRc = None):
         """
         Runs a binary (image) with optional admin (root) rights on the host and
@@ -369,7 +369,8 @@
         Windows currently is not supported yet running stuff as Administrator.
 
-        Returns success status (exit code is 0).
-        """
-        reporter.log('Executing \"%s\" on host (as admin = %s, blocking = %s)' % (sWhat, fAsAdmin, fBlocking));
+        Returns (success status, exit code).
+        """
+        reporter.log('Executing \"%s\" on host (as admin = %s, blocking = %s, expected rc = %d)'
+                     % (sWhat, fAsAdmin, fBlocking, iExpectedRc));
         reporter.log2('Arguments: %s' % (asArgs,));
         if asEnv:
@@ -381,6 +382,9 @@
         except: pass;
 
+        fRc = False;
+        iRc = -42;
+
         if fBlocking: # Run in same thread (blocking).
-            fRc = self.executeHstLoop(sWhat, asArgs, asEnv, fAsAdmin);
+            fRc, iRc = self.executeHstLoop(sWhat, asArgs, asEnv, fAsAdmin);
         else: # Run in separate thread (asynchronous).
             self.iThreadHstProcRc = -42; # Initialize thread rc.
@@ -393,9 +397,17 @@
                     self.processEvents(0);
                 reporter.log2('Thread returned exit code for "%s": %d' % (sWhat, self.iThreadHstProcRc));
+                fRc = True;
+                iRc = self.iThreadHstProcRc;
             except:
                 reporter.logXcpt('Starting thread for "%s" failed' % (sWhat,));
-            fRc = self.iThreadHstProcRc == 0;
-
-        return fRc;
+
+        # Adjust fRc if caller expected a specific exit code.
+        if  iExpectedRc \
+        and iRc is not iExpectedRc:
+            reporter.error('Executing \"%s\" on host failed (got exit code %d, expected %d'
+                           % (sWhat, iRc, iExpectedRc,));
+            fRc = False;
+
+        return fRc, iRc;
 
     def getWinFirewallArgsDisable(self, sOsType):
@@ -470,5 +482,5 @@
             asArgs = self.getWinFirewallArgsDisable('vista');
             if asArgs:
-                fRc = self.executeHst('Disabling host firewall', asArgs, fAsAdmin = True);
+                fRc, _ = self.executeHst('Disabling host firewall', asArgs, fAsAdmin = True);
         else:
             reporter.log('Firewall not available on host, skipping');
@@ -609,5 +621,5 @@
         # Let VKAT on the host run synchronously.
         #
-        fRc = self.executeHst("VKAT Host", asArgs);
+        fRc, _ = self.executeHst("VKAT Host", asArgs);
 
         reporter.testDone();
@@ -633,5 +645,5 @@
                 asArgs += self.asVkatVerifyArgs;
 
-            fRc = self.executeHst("VKAT Host Verify", asArgs);
+            fRc, _ = self.executeHst("VKAT Host Verify", asArgs, iExpectedRc = 0);
             if fRc:
                 reporter.log("Verification audio data successful");
@@ -736,5 +748,5 @@
         # Doesn't take long and gives us some more clue if it flies on the testboxes.
         reporter.testStart('VKAT Selftest');
-        fRc = self.executeHst("VKAT Host Selftest", [ sVkatExe, 'selftest' ]);
+        fRc, _ = self.executeHst("VKAT Host Selftest", [ sVkatExe, 'selftest' ], iExpectedRc = 0);
         reporter.testDone();
         if not fRc:
@@ -742,11 +754,13 @@
 
         # Now probe the backends.
+        reporter.testStart('VKAT Probing');
         asArgs   = [ sVkatExe, 'enum', '--probe-backends' ];
         for _ in range(1, reporter.getVerbosity()): # Verbosity always is initialized at 1.
             asArgs.extend([ '-v' ]);
-        fRc      = self.executeHst("VKAT Host Audio Probing", asArgs);
-        if not fRc:
+        fRc, iRc = self.executeHst("VKAT Host Audio Probing", asArgs);
+        if iRc != 0:
             # Not fatal, as VBox then should fall back to the NULL audio backend (also worth having as a test case).
             reporter.log('Warning: Backend probing on host failed, no audio available (pure server installation?)');
+        reporter.testDone();
 
         # Reconfigure the VM.
