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);
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)
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);
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;