Пример #1
0
    def _spawnChild(self, sAction):
        """
        Spawns the child process, returning success indicator + child object.
        """

        # Argument list.
        asArgs = self._assembleArguments(sAction)
        if asArgs is None:
            self._log('Malformed command line: "%s"' % (self._sScriptCmdLine,));
            return (False, None);

        # Spawn child.
        try:
            oChild = utils.processPopenSafe(asArgs,
                                            shell      = False,
                                            bufsize    = -1,
                                            stdout     = subprocess.PIPE,
                                            stderr     = subprocess.STDOUT,
                                            cwd        = self._oTestBoxScript.getPathSpill(),
                                            universal_newlines = True,
                                            close_fds  = (False if utils.getHostOs() == 'win' else True),
                                            preexec_fn = (None if utils.getHostOs() in ['win', 'os2']
                                                          else os.setsid)); # pylint: disable=E1101
        except Exception, oXcpt:
            self._log('Error creating child process %s: %s' % (asArgs, oXcpt));
            return (False, None);
Пример #2
0
    def _spawnChild(self, sAction):
        """
        Spawns the child process, returning success indicator + child object.
        """

        # Argument list.
        asArgs = self._assembleArguments(sAction)
        if asArgs is None:
            self._log('Malformed command line: "%s"' %
                      (self._sScriptCmdLine, ))
            return (False, None)

        # Spawn child.
        try:
            oChild = utils.processPopenSafe(
                asArgs,
                shell=False,
                bufsize=-1,
                stdout=subprocess.PIPE,
                stderr=subprocess.STDOUT,
                cwd=self._oTestBoxScript.getPathSpill(),
                universal_newlines=True,
                close_fds=(False if utils.getHostOs() == 'win' else True),
                preexec_fn=(None if utils.getHostOs() in ['win', 'os2'] else
                            os.setsid))
            # pylint: disable=E1101
        except Exception as oXcpt:
            self._log('Error creating child process %s: %s' % (asArgs, oXcpt))
            return (False, None)

        oChild.sTestBoxScriptAction = sAction

        # Start output thread, extending the child object to keep track of it.
        oChild.oOutputThread = threading.Thread(target=self._outputThreadProc,
                                                args=(oChild, oChild.stdout,
                                                      sAction))
        oChild.oOutputThread.daemon = True
        oChild.oOutputThread.fPleaseQuit = False
        # Our extension.
        oChild.oOutputThread.start()

        return (True, oChild)
Пример #3
0
    def executeHstLoop(self, sWhat, asArgs, asEnv=None, fAsAdmin=False):
        """
        Inner loop which handles the execution of a host binary.
        """
        fRc = False

        asEnvTmp = os.environ.copy()
        if asEnv:
            for sEnv in asEnv:
                sKey, sValue = sEnv.split('=')
                reporter.log2('Setting env var \"%s\" -> \"%s\"' %
                              (sKey, sValue))
                os.environ[sKey] = sValue
                # Also apply it to the current environment.
                asEnvTmp[sKey] = sValue

        if  fAsAdmin \
        and utils.getHostOs() != 'win':
            oProcess = utils.sudoProcessPopen(asArgs,
                                              env=asEnvTmp,
                                              stdout=sys.stdout,
                                              stderr=sys.stdout,
                                              close_fds=False)
        else:
            oProcess = utils.processPopenSafe(asArgs,
                                              env=asEnvTmp,
                                              stdout=sys.stdout,
                                              stderr=sys.stdout)
        if oProcess:
            self.pidFileAdd(oProcess.pid, sWhat, fSudo=fAsAdmin)
            iRc = oProcess.wait()
            self.pidFileRemove(oProcess.pid)

            if iRc == 0:
                reporter.log('*** %s: exit code %d' % (sWhat, iRc))
                fRc = True
            else:
                reporter.log('!*! %s: exit code %d' % (sWhat, iRc))

        return fRc
    def _spawnChild(self, sAction):
        """
        Spawns the child process, returning success indicator + child object.
        """

        # Argument list.
        asArgs = self._assembleArguments(sAction)
        if asArgs is None:
            self._log('Malformed command line: "%s"' % (self._sScriptCmdLine,));
            return (False, None);

        # Spawn child.
        try:
            oChild = utils.processPopenSafe(asArgs,
                                            shell      = False,
                                            bufsize    = -1,
                                            stdout     = subprocess.PIPE,
                                            stderr     = subprocess.STDOUT,
                                            cwd        = self._oTestBoxScript.getPathSpill(),
                                            universal_newlines = True,
                                            close_fds  = (False if utils.getHostOs() == 'win' else True),
                                            preexec_fn = (None if utils.getHostOs() in ['win', 'os2']
                                                          else os.setsid)); # pylint: disable=E1101
        except Exception as oXcpt:
            self._log('Error creating child process %s: %s' % (asArgs, oXcpt));
            return (False, None);

        oChild.sTestBoxScriptAction = sAction;

        # Start output thread, extending the child object to keep track of it.
        oChild.oOutputThread = threading.Thread(target=self._outputThreadProc, args=(oChild, oChild.stdout, sAction))
        oChild.oOutputThread.daemon = True;
        oChild.oOutputThread.fPleaseQuit = False; # Our extension.
        oChild.oOutputThread.start();

        return (True, oChild);
Пример #5
0
    def _executeTestCase(self, sName, sFullPath, sTestCaseSubDir, oDevNull):  # pylint: disable=R0914
        """
        Executes a test case.
        """

        fSkipped = False

        #
        # If hardening is enabled, some test cases and their dependencies
        # needs to be copied to and execute from the sVBoxInstallRoot
        # directory in order to work. They also have to be executed as
        # root, i.e. via sudo.
        #
        fHardened = False
        asFilesToRemove = []
        # Stuff to clean up.
        asDirsToRemove = []
        # Ditto.
        if    sName in self.kasHardened \
          and self.sUnitTestsPathBase != self.sVBoxInstallRoot:

            sDstDir = os.path.join(self.sVBoxInstallRoot, sTestCaseSubDir)
            if not os.path.exists(sDstDir):
                self._hardenedMkDir(sDstDir)
                asDirsToRemove.append(sDstDir)

            sDst = os.path.join(sDstDir, os.path.basename(sFullPath))
            self._hardenedCopyFile(sFullPath, sDst, 0o755)
            asFilesToRemove.append(sDst)

            # Copy any associated .dll/.so/.dylib.
            for sSuff in ['.dll', '.so', '.dylib']:
                sSrc = os.path.splitext(sFullPath)[0] + sSuff
                if os.path.exists(sSrc):
                    sDst = os.path.join(sDstDir, os.path.basename(sSrc))
                    self._hardenedCopyFile(sSrc, sDst, 0o644)
                    asFilesToRemove.append(sDst)

            # Copy any associated .r0, .rc and .gc modules.
            offDriver = sFullPath.rfind('Driver')
            if offDriver > 0:
                for sSuff in ['.r0', 'RC.rc', 'RC.gc']:
                    sSrc = sFullPath[:offDriver] + sSuff
                    if os.path.exists(sSrc):
                        sDst = os.path.join(sDstDir, os.path.basename(sSrc))
                        self._hardenedCopyFile(sSrc, sDst, 0o644)
                        asFilesToRemove.append(sDst)

            sFullPath = os.path.join(sDstDir, os.path.basename(sFullPath))
            fHardened = True

        #
        # Set up arguments and environment.
        #
        asArgs = [
            sFullPath,
        ]
        if sName in self.kdArguments:
            asArgs.extend(self.kdArguments[sName])

        os.environ['IPRT_TEST_OMIT_TOP_TEST'] = '1'
        os.environ['IPRT_TEST_FILE'] = sXmlFile = os.path.join(
            self.sScratchPath, 'result.xml')
        if os.path.exists(sXmlFile):
            try:
                os.unlink(sXmlFile)
            except:
                self._hardenedDeleteFile(sXmlFile)

        #
        # Execute the test case.
        #
        # Windows is confusing output.  Trying a few things to get rid of this.
        # First, flush both stderr and stdout before running the child.  Second,
        # assign the child stderr to stdout.  If this doesn't help, we'll have
        # to capture the child output.
        #
        reporter.log('*** Executing %s%s...' %
                     (asArgs, ' [hardened]' if fHardened else ''))
        try:
            sys.stdout.flush()
        except:
            pass
        try:
            sys.stderr.flush()
        except:
            pass
        if not self.fDryRun:
            try:
                if fHardened:
                    oChild = utils.sudoProcessPopen(asArgs,
                                                    stdin=oDevNull,
                                                    stdout=sys.stdout,
                                                    stderr=sys.stdout)
                else:
                    oChild = utils.processPopenSafe(asArgs,
                                                    stdin=oDevNull,
                                                    stdout=sys.stdout,
                                                    stderr=sys.stdout)
            except:
                if sName in [
                        'tstAsmStructsRC',  # 32-bit, may fail to start on 64-bit linux. Just ignore.
                ]:
                    reporter.logXcpt()
                    fSkipped = True
                else:
                    reporter.errorXcpt()
                iRc = 1023
                oChild = None

            if oChild is not None:
                self.pidFileAdd(oChild.pid, sName, fSudo=fHardened)
                iRc = oChild.wait()
                self.pidFileRemove(oChild.pid)
        else:
            iRc = 0

        #
        # Clean up
        #
        for sPath in asFilesToRemove:
            self._hardenedDeleteFile(sPath)
        for sPath in asDirsToRemove:
            self._hardenedRemoveDir(sPath)

        #
        # Report.
        #
        if os.path.exists(sXmlFile):
            reporter.addSubXmlFile(sXmlFile)
            if fHardened:
                self._hardenedDeleteFile(sXmlFile)
            else:
                os.unlink(sXmlFile)

        if iRc == 0:
            reporter.log('*** %s: exit code %d' % (sFullPath, iRc))
            self.cPassed += 1

        elif iRc == 4:  # RTEXITCODE_SKIPPED
            reporter.log('*** %s: exit code %d (RTEXITCODE_SKIPPED)' %
                         (sFullPath, iRc))
            fSkipped = True
            self.cSkipped += 1

        elif fSkipped:
            reporter.log('*** %s: exit code %d (Skipped)' % (sFullPath, iRc))
            self.cSkipped += 1

        else:
            sName = self.kdExitCodeNames.get(iRc, '')
            if iRc in self.kdExitCodeNamesWin and utils.getHostOs() == 'win':
                sName = self.kdExitCodeNamesWin[iRc]
            if sName != '':
                sName = ' (%s)' % (sName)

            if iRc != 1:
                reporter.testFailure('Exit status: %d%s' % (iRc, sName))
                reporter.log('!*! %s: exit code %d%s' %
                             (sFullPath, iRc, sName))
            else:
                reporter.error('!*! %s: exit code %d%s' %
                               (sFullPath, iRc, sName))
            self.cFailed += 1

        return fSkipped
    def _executeTestCase(self, sName, sFullPath, sTestCaseSubDir, oDevNull): # pylint: disable=R0914
        """
        Executes a test case.
        """

        fSkipped = False;

        #
        # If hardening is enabled, some test cases and their dependencies
        # needs to be copied to and execute from the sVBoxInstallRoot
        # directory in order to work. They also have to be executed as
        # root, i.e. via sudo.
        #
        fHardened       = False;
        asFilesToRemove = []; # Stuff to clean up.
        asDirsToRemove  = []; # Ditto.
        if    sName in self.kasHardened \
          and self.sUnitTestsPathBase != self.sVBoxInstallRoot:

            sDstDir = os.path.join(self.sVBoxInstallRoot, sTestCaseSubDir);
            if not os.path.exists(sDstDir):
                self._hardenedMkDir(sDstDir);
                asDirsToRemove.append(sDstDir);

            sDst = os.path.join(sDstDir, os.path.basename(sFullPath));
            self._hardenedCopyFile(sFullPath, sDst, 0o755);
            asFilesToRemove.append(sDst);

            # Copy any associated .dll/.so/.dylib.
            for sSuff in [ '.dll', '.so', '.dylib' ]:
                sSrc = os.path.splitext(sFullPath)[0] + sSuff;
                if os.path.exists(sSrc):
                    sDst = os.path.join(sDstDir, os.path.basename(sSrc));
                    self._hardenedCopyFile(sSrc, sDst, 0o644);
                    asFilesToRemove.append(sDst);

            # Copy any associated .r0, .rc and .gc modules.
            offDriver = sFullPath.rfind('Driver')
            if offDriver > 0:
                for sSuff in [ '.r0', 'RC.rc', 'RC.gc' ]:
                    sSrc = sFullPath[:offDriver] + sSuff;
                    if os.path.exists(sSrc):
                        sDst = os.path.join(sDstDir, os.path.basename(sSrc));
                        self._hardenedCopyFile(sSrc, sDst, 0o644);
                        asFilesToRemove.append(sDst);

            sFullPath = os.path.join(sDstDir, os.path.basename(sFullPath));
            fHardened = True;

        #
        # Set up arguments and environment.
        #
        asArgs = [sFullPath,]
        if sName in self.kdArguments:
            asArgs.extend(self.kdArguments[sName]);

        os.environ['IPRT_TEST_OMIT_TOP_TEST'] = '1';
        os.environ['IPRT_TEST_FILE'] = sXmlFile = os.path.join(self.sScratchPath, 'result.xml');
        if os.path.exists(sXmlFile):
            try:    os.unlink(sXmlFile);
            except: self._hardenedDeleteFile(sXmlFile);

        #
        # Execute the test case.
        #
        # Windows is confusing output.  Trying a few things to get rid of this.
        # First, flush both stderr and stdout before running the child.  Second,
        # assign the child stderr to stdout.  If this doesn't help, we'll have
        # to capture the child output.
        #
        reporter.log('*** Executing %s%s...' % (asArgs, ' [hardened]' if fHardened else ''));
        try:    sys.stdout.flush();
        except: pass;
        try:    sys.stderr.flush();
        except: pass;
        if not self.fDryRun:
            try:
                if fHardened:
                    oChild = utils.sudoProcessPopen(asArgs, stdin = oDevNull, stdout = sys.stdout, stderr = sys.stdout);
                else:
                    oChild = utils.processPopenSafe(asArgs, stdin = oDevNull, stdout = sys.stdout, stderr = sys.stdout);
            except:
                if sName in [ 'tstAsmStructsRC',    # 32-bit, may fail to start on 64-bit linux. Just ignore.
                            ]:
                    reporter.logXcpt();
                    fSkipped = True;
                else:
                    reporter.errorXcpt();
                iRc    = 1023;
                oChild = None;

            if oChild is not None:
                self.pidFileAdd(oChild.pid, sName, fSudo = fHardened);
                iRc = oChild.wait();
                self.pidFileRemove(oChild.pid);
        else:
            iRc = 0;

        #
        # Clean up
        #
        for sPath in asFilesToRemove:
            self._hardenedDeleteFile(sPath);
        for sPath in asDirsToRemove:
            self._hardenedRemoveDir(sPath);

        #
        # Report.
        #
        if os.path.exists(sXmlFile):
            reporter.addSubXmlFile(sXmlFile);
            if fHardened:
                self._hardenedDeleteFile(sXmlFile);
            else:
                os.unlink(sXmlFile);

        if iRc == 0:
            reporter.log('*** %s: exit code %d' % (sFullPath, iRc));
            self.cPassed += 1

        elif iRc == 4: # RTEXITCODE_SKIPPED
            reporter.log('*** %s: exit code %d (RTEXITCODE_SKIPPED)' % (sFullPath, iRc));
            fSkipped = True;
            self.cSkipped += 1;

        elif fSkipped:
            reporter.log('*** %s: exit code %d (Skipped)' % (sFullPath, iRc));
            self.cSkipped += 1;

        else:
            sName = self.kdExitCodeNames.get(iRc, '');
            if iRc in self.kdExitCodeNamesWin and utils.getHostOs() == 'win':
                sName = self.kdExitCodeNamesWin[iRc];
            if sName != '':
                sName = ' (%s)' % (sName);

            if iRc != 1:
                reporter.testFailure('Exit status: %d%s' % (iRc, sName));
                reporter.log(  '!*! %s: exit code %d%s' % (sFullPath, iRc, sName));
            else:
                reporter.error('!*! %s: exit code %d%s' % (sFullPath, iRc, sName));
            self.cFailed += 1

        return fSkipped;