VirtualBox

Ignore:
Timestamp:
Feb 5, 2024 11:32:33 AM (12 months ago)
Author:
vboxsync
Message:

Validation Kit/tdAddGuestCtrl.py: Use the new VBoxGuestControlHelper binary to test in which Windows session guest processes are being started. Factored out the guest process execution code to a helper function so that it can be used also for VBoxGuestControlHelper. bugref:10586

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/ValidationKit/tests/additions/tdAddGuestCtrl.py

    r103079 r103200  
    14261426            '3d'
    14271427        ];
     1428
     1429        # Possible paths for the Guest Control Helper binary.
     1430        self.asGstCtlHelperPaths   = [
     1431            # Debugging stuff (SCP'd over to the guest).
     1432            '/tmp/VBoxGuestControlHelper',
     1433            'C:\\Temp\\VBoxGuestControlHelper',
     1434            # Validation Kit .ISO.
     1435            '${CDROM}/vboxvalidationkit/${OS/ARCH}/VBoxGuestControlHelper${EXESUFF}',
     1436            '${CDROM}/${OS/ARCH}/VBoxGuestControlHelper${EXESUFF}',
     1437            # Test VMs.
     1438            '/opt/apps/VBoxGuestControlHelper',
     1439            '/opt/apps/VBoxGuestControlHelper',
     1440            '/apps/VBoxGuestControlHelper',
     1441            'C:\\Apps\\VBoxGuestControlHelper${EXESUFF}'
     1442        ];
     1443        # Full path to the Guest Control Helper binary we're going to use. Only gets resolved once.
     1444        self.sGstCtlHelperExe       = '';
     1445
    14281446        self.asTests                = self.asTestsDef;
    14291447        self.fSkipKnownBugs         = False;
     
    15991617
    16001618        return True;
     1619
     1620    def locateGstBinary(self, oSession, oTxsSession, asPaths):
     1621        """
     1622        Locates a guest binary on the guest by checking the paths in \a asPaths.
     1623
     1624        Returns a tuple (success, path).
     1625        """
     1626        for sCurPath in asPaths:
     1627            reporter.log2('Checking for \"%s\" ...' % (sCurPath));
     1628            if self.txsIsFile(oSession, oTxsSession, sCurPath, fIgnoreErrors = True):
     1629                return (True, sCurPath);
     1630        reporter.error('Unable to find guest binary in any of these places:\n%s' % ('\n'.join(asPaths),));
     1631        return (False, "");
    16011632
    16021633    #
     
    23392370        return oProcess;
    23402371
    2341     def gctrlExecute(self, oTest, oGuestSession, fIsError):                     # pylint: disable=too-many-statements
    2342         """
    2343         Helper function to execute a program on a guest, specified in the current test.
    2344 
    2345         Note! This weirdo returns results (process exitcode and status) in oTest.
    2346         """
    2347         fRc = True; # Be optimistic.
    2348 
    2349         # Reset the weird result stuff:
    2350         oTest.cbStdOut    = 0;
    2351         oTest.cbStdErr    = 0;
    2352         oTest.sBuf        = '';
    2353         oTest.uExitStatus = 0;
    2354         oTest.iExitCode   = 0;
    2355 
    2356         ## @todo Compare execution timeouts!
    2357         #tsStart = base.timestampMilli();
    2358 
     2372    def processExecute(self, oGuestSession, sCmd, asArgs, sCwd, aEnv, afFlags, timeoutMS, fIsError = True):
     2373        """
     2374        Executes a process on the guest and deals with input/output + waiting flags.
     2375
     2376        Returns tuple (success, exit status, exit code, stdout len, stderr len, stdout / stderr output).
     2377        """
     2378
     2379        #
     2380        # Start the process:
     2381        #
    23592382        try:
    2360             reporter.log2('Using session user=%s, sDomain=%s, name=%s, timeout=%d'
    2361                           % (oGuestSession.user, oGuestSession.domain, oGuestSession.name, oGuestSession.timeout,));
     2383            oProcess = self.processCreateWrapper(oGuestSession, sCmd, asArgs, sCwd, aEnv, afFlags, timeoutMS);
    23622384        except:
    2363             return reporter.errorXcpt();
    2364 
    2365         #
    2366         # Start the process:
    2367         #
    2368 
    2369         try:
    2370             oProcess = self.processCreateWrapper(oGuestSession, oTest.sCmd, oTest.asArgs, oTest.sCwd,
    2371                                                  oTest.aEnv, oTest.afFlags, oTest.timeoutMS);
    2372         except:
    2373             reporter.maybeErrXcpt(fIsError, 'type=%s, asArgs=%s' % (type(oTest.asArgs), oTest.asArgs,));
     2385            reporter.maybeErrXcpt(fIsError, 'type=%s, asArgs=%s' % (type(asArgs), asArgs,));
    23742386            return False;
    23752387        if oProcess is None:
    2376             return reporter.error('oProcess is None! (%s)' % (oTest.asArgs,));
     2388            return reporter.error('oProcess is None! (%s)' % (asArgs,));
     2389
     2390        fRc = True;
    23772391
    23782392        #time.sleep(5); # try this if you want to see races here.
    23792393
    23802394        # Wait for the process to start properly:
    2381         reporter.log2('Process start requested, waiting for start (%dms) ...' % (oTest.timeoutMS,));
     2395        reporter.log2('Process start requested, waiting for start (%dms) ...' % (timeoutMS,));
    23822396        iPid = -1;
    23832397        aeWaitFor = [ vboxcon.ProcessWaitForFlag_Start, ];
    23842398        try:
    2385             eWaitResult = oProcess.waitForArray(aeWaitFor, oTest.timeoutMS);
     2399            eWaitResult = oProcess.waitForArray(aeWaitFor, timeoutMS);
    23862400        except:
    2387             reporter.maybeErrXcpt(fIsError, 'waitforArray failed for asArgs=%s' % (oTest.asArgs,));
     2401            reporter.maybeErrXcpt(fIsError, 'waitforArray failed for asArgs=%s' % (asArgs,));
    23882402            fRc = False;
    23892403        else:
     
    23922406                iPid    = oProcess.PID;
    23932407            except:
    2394                 fRc = reporter.errorXcpt('asArgs=%s' % (oTest.asArgs,));
     2408                fRc = reporter.errorXcpt('asArgs=%s' % (asArgs,));
    23952409            else:
    23962410                reporter.log2('Wait result returned: %d, current process status is: %d' % (eWaitResult, eStatus,));
     
    24062420                    # What to wait for:
    24072421                    aeWaitFor = [ vboxcon.ProcessWaitForFlag_Terminate, ];
    2408                     if vboxcon.ProcessCreateFlag_WaitForStdOut in oTest.afFlags:
     2422                    if vboxcon.ProcessCreateFlag_WaitForStdOut in afFlags:
    24092423                        aeWaitFor.append(vboxcon.ProcessWaitForFlag_StdOut);
    2410                     if vboxcon.ProcessCreateFlag_WaitForStdErr in oTest.afFlags:
     2424                    if vboxcon.ProcessCreateFlag_WaitForStdErr in afFlags:
    24112425                        aeWaitFor.append(vboxcon.ProcessWaitForFlag_StdErr);
    24122426                    ## @todo Add vboxcon.ProcessWaitForFlag_StdIn.
    24132427
    24142428                    reporter.log2('Process (PID %d) started, waiting for termination (%dms), aeWaitFor=%s ...'
    2415                                   % (iPid, oTest.timeoutMS, aeWaitFor));
     2429                                  % (iPid, timeoutMS, aeWaitFor));
    24162430                    acbFdOut = [0,0,0];
    24172431                    while True:
    24182432                        try:
    2419                             eWaitResult = oProcess.waitForArray(aeWaitFor, oTest.timeoutMS);
     2433                            eWaitResult = oProcess.waitForArray(aeWaitFor, timeoutMS);
    24202434                        except KeyboardInterrupt: # Not sure how helpful this is, but whatever.
    24212435                            reporter.error('Process (PID %d) execution interrupted' % (iPid,));
     
    24242438                            break;
    24252439                        except:
    2426                             fRc = reporter.errorXcpt('asArgs=%s' % (oTest.asArgs,));
     2440                            fRc = reporter.errorXcpt('asArgs=%s' % (asArgs,));
    24272441                            break;
    24282442                        #reporter.log2('Wait returned: %d' % (eWaitResult,));
     
    24332447                            if eWaitResult in (eFdResult, vboxcon.ProcessWaitResult_WaitFlagNotSupported):
    24342448                                try:
    2435                                     abBuf = oProcess.read(iFd, 64 * 1024, oTest.timeoutMS);
     2449                                    abBuf = oProcess.read(iFd, 64 * 1024, timeoutMS);
    24362450                                except KeyboardInterrupt: # Not sure how helpful this is, but whatever.
    24372451                                    reporter.error('Process (PID %d) execution interrupted' % (iPid,));
     
    24392453                                    except: pass;
    24402454                                except:
    2441                                     reporter.maybeErrXcpt(fIsError, 'asArgs=%s' % (oTest.asArgs,));
     2455                                    reporter.maybeErrXcpt(fIsError, 'asArgs=%s' % (asArgs,));
    24422456                                else:
    24432457                                    if abBuf:
     
    24452459                                                      % (iPid, len(abBuf), sFdNm, type(abBuf)));
    24462460                                        if reporter.getVerbosity() >= 4:
    2447                                             sBuf = '';
     2461                                            sBufOut = '';
    24482462                                            if sys.version_info >= (2, 7):
    24492463                                                if isinstance(abBuf, memoryview): ## @todo Why is this happening?
    2450                                                     abBuf = abBuf.tobytes();
    2451                                                     sBuf  = abBuf.decode("utf-8");
     2464                                                    abBuf   = abBuf.tobytes();
     2465                                                    sBufOut = abBuf.decode("utf-8");
    24522466                                            if sys.version_info <= (2, 7):
    24532467                                                if isinstance(abBuf, buffer):   # (for 3.0+) pylint: disable=undefined-variable
    2454                                                     sBuf = str(abBuf);
    2455                                             for sLine in sBuf.splitlines():
     2468                                                    sBufOut = str(abBuf);
     2469                                            for sLine in sBufOut.splitlines():
    24562470                                                reporter.log4('%s: %s' % (sFdNm, sLine));
    24572471                                        acbFdOut[iFd] += len(abBuf);
    2458                                         oTest.sBuf    = abBuf; ## @todo Figure out how to uniform + append!
     2472                                        sBufOut = abBuf; ## @todo Figure out how to uniform + append!
    24592473
    24602474                        ## Process input (todo):
     
    24672481                                           vboxcon.ProcessWaitResult_Timeout,):
    24682482                            try:    eStatus = oProcess.status;
    2469                             except: fRc = reporter.errorXcpt('asArgs=%s' % (oTest.asArgs,));
     2483                            except: fRc = reporter.errorXcpt('asArgs=%s' % (asArgs,));
    24702484                            reporter.log2('Process (PID %d) reported terminate/error/timeout: %d, status: %d'
    24712485                                          % (iPid, eWaitResult, eStatus,));
     
    24732487
    24742488                    # End of the wait loop.
    2475                     _, oTest.cbStdOut, oTest.cbStdErr = acbFdOut;
     2489                    _, cbStdOut, cbStdErr = acbFdOut;
    24762490
    24772491                    try:    eStatus = oProcess.status;
    2478                     except: fRc = reporter.errorXcpt('asArgs=%s' % (oTest.asArgs,));
     2492                    except: fRc = reporter.errorXcpt('asArgs=%s' % (asArgs,));
    24792493                    reporter.log2('Final process status (PID %d) is: %d' % (iPid, eStatus));
    2480                     reporter.log2('Process (PID %d) %d stdout, %d stderr' % (iPid, oTest.cbStdOut, oTest.cbStdErr));
     2494                    reporter.log2('Process (PID %d) %d stdout, %d stderr' % (iPid, cbStdOut, cbStdErr));
    24812495
    24822496        #
     
    24842498        #
    24852499        try:
    2486             oTest.uExitStatus = oProcess.status;
    2487             oTest.iExitCode   = oProcess.exitCode;
     2500            uExitStatus = oProcess.status;
     2501            iExitCode   = oProcess.exitCode;
    24882502        except:
    2489             fRc = reporter.errorXcpt('asArgs=%s' % (oTest.asArgs,));
    2490         reporter.log2('Process (PID %d) has exit code: %d; status: %d ' % (iPid, oTest.iExitCode, oTest.uExitStatus));
     2503            fRc = reporter.errorXcpt('asArgs=%s' % (asArgs,));
     2504        reporter.log2('Process (PID %d) has exit code: %d; status: %d ' % (iPid, iExitCode, uExitStatus));
     2505        return fRc, uExitStatus, iExitCode, cbStdOut, cbStdErr, sBufOut;
     2506
     2507    def gctrlExecute(self, oTest, oGuestSession, fIsError):                     # pylint: disable=too-many-statements
     2508        """
     2509        Helper function to execute a program on a guest, specified in the current test.
     2510
     2511        Note! This weirdo returns results (process exitcode and status) in oTest.
     2512        """
     2513        fRc = True; # Be optimistic.
     2514
     2515        # Reset the weird result stuff:
     2516        oTest.cbStdOut    = 0;
     2517        oTest.cbStdErr    = 0;
     2518        oTest.sBuf        = '';
     2519        oTest.uExitStatus = 0;
     2520        oTest.iExitCode   = 0;
     2521
     2522        ## @todo Compare execution timeouts!
     2523        #tsStart = base.timestampMilli();
     2524
     2525        try:
     2526            reporter.log2('Using session user=%s, sDomain=%s, name=%s, timeout=%d'
     2527                          % (oGuestSession.user, oGuestSession.domain, oGuestSession.name, oGuestSession.timeout,));
     2528        except:
     2529            return reporter.errorXcpt();
     2530
     2531        fRc, oTest.uExitStatus, oTest.iExitCode, oTest.cbStdOut, oTest.cbStdErr, oTest.sBuf = \
     2532            self.processExecute(oGuestSession, oTest.sCmd, oTest.asArgs, oTest.sCwd,
     2533                                oTest.aEnv, oTest.afFlags, oTest.timeoutMS, fIsError);
     2534
    24912535        return fRc;
     2536
     2537    def executeGstCtlHelper(self, oSession, oTxsSession, oGuestSession, asArgs, asEnv = [], sCwd = '', timeoutMS = 30 * 1000):
     2538        """
     2539        Wrapper to invoke the Guest Control Helper on the guest.
     2540
     2541        Returns tuple (success, exit status, exit code, stdout len, stderr len, stdout / stderr output).
     2542        """
     2543        fRc         = True;
     2544        eExitStatus = vboxcon.ProcessStatus_Undefined;
     2545        iExitCode   = -1;
     2546        cbStdOut    = 0;
     2547        cbStdErr    = 0;
     2548        sBuf        = '';
     2549
     2550        if not self.sGstCtlHelperExe:
     2551            fRc, self.sGstCtlHelperExe = self.locateGstBinary(oSession, oTxsSession, self.asGstCtlHelperPaths);
     2552            if fRc:
     2553                reporter.log('Using VBoxGuestControlHelper on guest at \"%s\"' % (self.sGstCtlHelperExe));
     2554
     2555        if fRc \
     2556        and self.sGstCtlHelperExe:
     2557            try:
     2558                asArgs2 = [ self.sGstCtlHelperExe ];
     2559                asArgs2.append(asArgs); # Always set argv0.
     2560                aeWaitFor = [ vboxcon.ProcessWaitForFlag_Terminate, \
     2561                              vboxcon.ProcessWaitForFlag_StdOut, \
     2562                              vboxcon.ProcessWaitForFlag_StdErr ];
     2563
     2564                fRc, eExitStatus, iExitCode, cbStdOut, cbStdErr, sBuf = \
     2565                    self.processExecute(oGuestSession, self.sGstCtlHelperExe, asArgs2, sCwd,
     2566                                        asEnv, aeWaitFor, timeoutMS);
     2567                if eExitStatus != vboxcon.TerminatedNormally:
     2568                    reporter.log('VBoxGuestControlHelper failed to run; got exit status %d' % (eExitStatus,));
     2569                    fRc = False;
     2570            except:
     2571                reporter.errorXcpt();
     2572
     2573        return fRc, eExitStatus, iExitCode, cbStdOut, cbStdErr, sBuf;
    24922574
    24932575    def testGuestCtrlSessionEnvironment(self, oSession, oTxsSession, oTestVm): # pylint: disable=too-many-locals
     
    26082690        return tdTestSessionEx.executeListTestSessions(aoTests, self.oTstDrv, oSession, oTxsSession, oTestVm, 'SessionEnv');
    26092691
    2610     def testGuestCtrlSessionSimple(self, oSession, oTestVm):
     2692    def testGuestCtrlSessionSimple(self, oSession, oTxsSession, oTestVm):
    26112693        """
    26122694        Tests simple session-based API calls.
     
    26272709            return False;
    26282710
    2629         fRc = True;
     2711        if  self.oTstDrv.fpApiVer >= 7.1 \
     2712        and oTestVm.isWindows():
     2713            reporter.testStart('Windows guest processes in session >= 1');
     2714            # Test in which Windows session Guest Control processes are being started.
     2715            # We don't want them to be started in session 0, as this would prevent desktop interaction and other stuff.
     2716            fRc, eExitStatus, iExitCode, cbStdOut, cbStdErr, sBuf = \
     2717                self.executeGstCtlHelper(oSession, oTxsSession, oGuestSession, [ "show", "win-session-id" ]);
     2718            if  fRc \
     2719            and eExitStatus == vboxcon.TerminatedNormally:
     2720                if iExitCode >= 1000: # We report 1000 + <session ID> as exit code.
     2721                    uSessionId = iExitCode - 1000;
     2722                    if uSessionId == 0:
     2723                        reporter.log('Guest processes start in session %d, good' % (uSessionId));
     2724                    else:
     2725                        reporter.error('Guest processes start in session %d, expected session 0' % (uSessionId));
     2726                else:
     2727                    reporter.error('Guest Control Helper returned error %d (exit code)' % (iExitCode));
     2728            reporter.testDone();
    26302729
    26312730        # User home.
     
    28052904        ## @todo Test session timeouts.
    28062905
    2807         fRc2 = self.testGuestCtrlSessionSimple(oSession, oTestVm);
     2906        fRc2 = self.testGuestCtrlSessionSimple(oSession, oTxsSession, oTestVm);
    28082907        if fRc:
    28092908            fRc = fRc2;
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