def test_errormsg(self): logging.debug('') logging.debug('test_errormsg') cmd = 'dir' if sys.platform == 'win32' else 'ls' try: proc = ShellProc(cmd, stdout='stdout', stderr='stderr') proc.wait() finally: if os.path.exists('stdout'): os.remove('stdout') if os.path.exists('stderr'): os.remove('stderr') msg = proc.error_message(-signal.SIGTERM) if sys.platform == 'win32': self.assertEqual(msg, '') else: self.assertEqual(msg, ': SIGTERM')
class ExternalCode(Component): """ Run an external code as a component Default stdin is the 'null' device, default stdout is the console, and default stderr is ``error.out``. Options ------- fd_options['force_fd'] : bool(False) Set to True to finite difference this system. fd_options['form'] : str('forward') Finite difference mode. (forward, backward, central) You can also set to 'complex_step' to peform the complex step method if your components support it. fd_options['step_size'] : float(1e-06) Default finite difference stepsize fd_options['step_type'] : str('absolute') Set to absolute, relative options['check_external_outputs'] : bool(True) Check that all input or output external files exist options['command'] : list([]) command to be executed options['env_vars'] : dict({}) Environment variables required by the command options['external_input_files'] : list([]) (optional) list of input file names to check the pressence of before solve_nonlinear options['external_output_files'] : list([]) (optional) list of input file names to check the pressence of after solve_nonlinear options['poll_delay'] : float(0.0) Delay between polling for command completion. A value of zero will use an internally computed default options['timeout'] : float(0.0) Maximum time to wait for command completion. A value of zero implies an infinite wait """ def __init__(self): super(ExternalCode, self).__init__() self.STDOUT = STDOUT self.DEV_NULL = DEV_NULL # Input options for this Component self.options = OptionsDictionary() self.options.add_option('command', [], desc='command to be executed') self.options.add_option('env_vars', {}, desc='Environment variables required by the command') self.options.add_option('poll_delay', 0.0, lower=0.0, desc='Delay between polling for command completion. A value of zero will use an internally computed default') self.options.add_option('timeout', 0.0, lower=0.0, desc='Maximum time to wait for command completion. A value of zero implies an infinite wait') self.options.add_option('check_external_outputs', True, desc='Check that all input or output external files exist') self.options.add_option( 'external_input_files', [], desc='(optional) list of input file names to check the pressence of before solve_nonlinear') self.options.add_option( 'external_output_files', [], desc='(optional) list of input file names to check the pressence of after solve_nonlinear') # Outputs of the run of the component or items that will not work with the OptionsDictionary self.return_code = 0 # Return code from the command self.timed_out = False # True if the command timed-out self.stdin = self.DEV_NULL self.stdout = None self.stderr = "error.out" def check_setup(self, out_stream=sys.stdout): """Write a report to the given stream indicating any potential problems found with the current configuration of this ``Problem``. Args ---- out_stream : a file-like object, optional """ # check for the command if not self.options['command']: out_stream.write( "The command cannot be empty") else: if isinstance(self.options['command'], str): program_to_execute = self.options['command'] else: program_to_execute = self.options['command'][0] command_full_path = find_executable( program_to_execute ) if not command_full_path: msg = "The command to be executed, '%s', cannot be found" % program_to_execute out_stream.write(msg) # Check for missing input files missing_files = self._check_for_files(input=True) for iotype, path in missing_files: msg = "The %s file %s is missing" % ( iotype, path ) out_stream.write(msg) def solve_nonlinear(self, params, unknowns, resids): """Runs the component """ self.return_code = -12345678 self.timed_out = False if not self.options['command']: raise ValueError('Empty command list') # self.check_files(inputs=True) return_code = None error_msg = '' try: return_code, error_msg = self._execute_local() if return_code is None: # if self._stop: # raise RuntimeError('Run stopped') # else: self.timed_out = True raise RuntimeError('Timed out') elif return_code: if isinstance(self.stderr, str): if os.path.exists(self.stderr): stderrfile = open(self.stderr, 'r') error_desc = stderrfile.read() stderrfile.close() err_fragment = "\nError Output:\n%s" % error_desc else: err_fragment = "\n[stderr %r missing]" % self.stderr else: err_fragment = error_msg raise RuntimeError('return_code = %d%s' % (return_code, err_fragment)) if self.options['check_external_outputs']: missing_files = self._check_for_files(input=False) msg = "" for iotype, path in missing_files: msg += "%s file %s is missing\n" % (iotype, path) if msg: raise RuntimeError( "Missing files: %s" % msg ) # self.check_files(inputs=False) finally: self.return_code = -999999 if return_code is None else return_code def _check_for_files(self, input=True): """ Check that all 'specific' input external files exist. input: bool If True, check inputs. Else check outputs """ missing_files = [] if input: files = self.options['external_input_files'] else: files = self.options['external_output_files'] for path in files: if not os.path.exists(path): missing_files.append(('input', path)) return missing_files def _execute_local(self): """ Run command. """ #self._logger.info('executing %s...', self.options['command']) # start_time = time.time() # check to make sure command exists if isinstance(self.options['command'], str): program_to_execute = self.options['command'] else: program_to_execute = self.options['command'][0] # suppress message from find_executable function, we'll handle it numpy.distutils.log.set_verbosity(-1) command_full_path = find_executable( program_to_execute ) if not command_full_path: raise ValueError("The command to be executed, '%s', cannot be found" % program_to_execute) command_for_shell_proc = self.options['command'] if sys.platform == 'win32': command_for_shell_proc = ['cmd.exe', '/c' ] + command_for_shell_proc self._process = \ ShellProc(command_for_shell_proc, self.stdin, self.stdout, self.stderr, self.options['env_vars']) #self._logger.debug('PID = %d', self._process.pid) try: return_code, error_msg = \ self._process.wait(self.options['poll_delay'], self.options['timeout']) finally: self._process.close_files() self._process = None # et = time.time() - start_time #if et >= 60: #pragma no cover #self._logger.info('elapsed time: %.1f sec.', et) return (return_code, error_msg)
class ExternalCode(Component): """ Run an external code as a component Default stdin is the 'null' device, default stdout is the console, and default stderr is ``error.out``. Options ------- fd_options['force_fd'] : bool(False) Set to True to finite difference this system. fd_options['form'] : str('forward') Finite difference mode. (forward, backward, central) You can also set to 'complex_step' to peform the complex step method if your components support it. fd_options['step_size'] : float(1e-06) Default finite difference stepsize fd_options['step_type'] : str('absolute') Set to absolute, relative fd_options['extra_check_partials_form'] : None or str Finite difference mode: ("forward", "backward", "central", "complex_step") During check_partial_derivatives, you can optionally do a second finite difference with a different mode. fd_options['linearize'] : bool(False) Set to True if you want linearize to be called even though you are using FD. options['command'] : list([]) Command to be executed. Command must be a list of command line args. options['env_vars'] : dict({}) Environment variables required by the command options['external_input_files'] : list([]) (optional) list of input file names to check the existence of before solve_nonlinear options['external_output_files'] : list([]) (optional) list of input file names to check the existence of after solve_nonlinear options['poll_delay'] : float(0.0) Delay between polling for command completion. A value of zero will use an internally computed default. options['timeout'] : float(0.0) Maximum time in seconds to wait for command completion. A value of zero implies an infinite wait. If the timeout interval is exceeded, an AnalysisError will be raised. options['fail_hard'] : bool(True) Behavior on error returned from code, either raise a 'hard' error (RuntimeError) if True or a 'soft' error (AnalysisError) if False. """ def __init__(self): super(ExternalCode, self).__init__() self.STDOUT = STDOUT self.DEV_NULL = DEV_NULL # Input options for this Component self.options = OptionsDictionary() self.options.add_option('command', [], desc='command to be executed') self.options.add_option( 'env_vars', {}, desc='Environment variables required by the command') self.options.add_option( 'poll_delay', 0.0, lower=0.0, desc= 'Delay between polling for command completion. A value of zero will use an internally computed default' ) self.options.add_option( 'timeout', 0.0, lower=0.0, desc= 'Maximum time to wait for command completion. A value of zero implies an infinite wait' ) self.options.add_option( 'external_input_files', [], desc= '(optional) list of input file names to check the existence of before solve_nonlinear' ) self.options.add_option( 'external_output_files', [], desc= '(optional) list of input file names to check the existence of after solve_nonlinear' ) self.options.add_option( 'fail_hard', True, desc= "If True, external code errors raise a 'hard' exception (RuntimeError). Otherwise raise a 'soft' exception (AnalysisError)." ) # Outputs of the run of the component or items that will not work with the OptionsDictionary self.return_code = 0 # Return code from the command self.stdin = self.DEV_NULL self.stdout = None self.stderr = "error.out" def check_setup(self, out_stream=sys.stdout): """Write a report to the given stream indicating any potential problems found with the current configuration of this ``Problem``. Args ---- out_stream : a file-like object, optional """ # check for the command cmd = [c for c in self.options['command'] if c.strip()] if not cmd: out_stream.write("The command cannot be empty") else: program_to_execute = self.options['command'][0] command_full_path = find_executable(program_to_execute) if not command_full_path: out_stream.write("The command to be executed, '%s', " "cannot be found" % program_to_execute) # Check for missing input files missing = self._check_for_files(self.options['external_input_files']) if missing: out_stream.write("The following input files are missing at setup " " time: %s" % missing) def solve_nonlinear(self, params, unknowns, resids): """Runs the component """ self.return_code = -12345678 if not self.options['command']: raise ValueError('Empty command list') if self.options['fail_hard']: err_class = RuntimeError else: err_class = AnalysisError return_code = None try: missing = self._check_for_files( self.options['external_input_files']) if missing: raise err_class("The following input files are missing: %s" % sorted(missing)) return_code, error_msg = self._execute_local() if return_code is None: raise AnalysisError('Timed out after %s sec.' % self.options['timeout']) elif return_code: if isinstance(self.stderr, str): if os.path.exists(self.stderr): stderrfile = open(self.stderr, 'r') error_desc = stderrfile.read() stderrfile.close() err_fragment = "\nError Output:\n%s" % error_desc else: err_fragment = "\n[stderr %r missing]" % self.stderr else: err_fragment = error_msg raise err_class('return_code = %d%s' % (return_code, err_fragment)) missing = self._check_for_files( self.options['external_output_files']) if missing: raise err_class("The following output files are missing: %s" % sorted(missing)) finally: self.return_code = -999999 if return_code is None else return_code def _check_for_files(self, files): """ Check that specified files exist. """ return [path for path in files if not os.path.exists(path)] def _execute_local(self): """ Run command. """ # check to make sure command exists if isinstance(self.options['command'], str): program_to_execute = self.options['command'] else: program_to_execute = self.options['command'][0] # suppress message from find_executable function, we'll handle it numpy.distutils.log.set_verbosity(-1) command_full_path = find_executable(program_to_execute) if not command_full_path: raise ValueError( "The command to be executed, '%s', cannot be found" % program_to_execute) command_for_shell_proc = self.options['command'] if sys.platform == 'win32': command_for_shell_proc = ['cmd.exe', '/c'] + command_for_shell_proc self._process = \ ShellProc(command_for_shell_proc, self.stdin, self.stdout, self.stderr, self.options['env_vars']) try: return_code, error_msg = \ self._process.wait(self.options['poll_delay'], self.options['timeout']) finally: self._process.close_files() self._process = None return (return_code, error_msg)
class ExternalCode(Component): """ Run an external code as a component Default stdin is the 'null' device, default stdout is the console, and default stderr is ``error.out``. Options ------- deriv_options['type'] : str('user') Derivative calculation type ('user', 'fd', 'cs') Default is 'user', where derivative is calculated from user-supplied derivatives. Set to 'fd' to finite difference this system. Set to 'cs' to perform the complex step if your components support it. deriv_options['form'] : str('forward') Finite difference mode. (forward, backward, central) deriv_options['step_size'] : float(1e-06) Default finite difference stepsize deriv_options['step_calc'] : str('absolute') Set to absolute, relative deriv_options['check_type'] : str('fd') Type of derivative check for check_partial_derivatives. Set to 'fd' to finite difference this system. Set to 'cs' to perform the complex step method if your components support it. deriv_options['check_form'] : str('forward') Finite difference mode: ("forward", "backward", "central") During check_partial_derivatives, the difference form that is used for the check. deriv_options['check_step_calc'] : str('absolute',) Set to 'absolute' or 'relative'. Default finite difference step calculation for the finite difference check in check_partial_derivatives. deriv_options['check_step_size'] : float(1e-06) Default finite difference stepsize for the finite difference check in check_partial_derivatives" deriv_options['linearize'] : bool(False) Set to True if you want linearize to be called even though you are using FD. options['command'] : list([]) Command to be executed. Command must be a list of command line args. options['env_vars'] : dict({}) Environment variables required by the command options['external_input_files'] : list([]) (optional) list of input file names to check the existence of before solve_nonlinear options['external_output_files'] : list([]) (optional) list of input file names to check the existence of after solve_nonlinear options['poll_delay'] : float(0.0) Delay between polling for command completion. A value of zero will use an internally computed default. options['timeout'] : float(0.0) Maximum time in seconds to wait for command completion. A value of zero implies an infinite wait. If the timeout interval is exceeded, an AnalysisError will be raised. options['fail_hard'] : bool(True) Behavior on error returned from code, either raise a 'hard' error (RuntimeError) if True or a 'soft' error (AnalysisError) if False. """ def __init__(self): super(ExternalCode, self).__init__() self.STDOUT = STDOUT self.DEV_NULL = DEV_NULL # Input options for this Component self.options = OptionsDictionary() self.options.add_option('command', [], desc='command to be executed') self.options.add_option('env_vars', {}, desc='Environment variables required by the command') self.options.add_option('poll_delay', 0.0, lower=0.0, desc='Delay between polling for command completion. A value of zero will use an internally computed default') self.options.add_option('timeout', 0.0, lower=0.0, desc='Maximum time to wait for command completion. A value of zero implies an infinite wait') self.options.add_option( 'external_input_files', [], desc='(optional) list of input file names to check the existence of before solve_nonlinear') self.options.add_option( 'external_output_files', [], desc='(optional) list of input file names to check the existence of after solve_nonlinear') self.options.add_option('fail_hard', True, desc="If True, external code errors raise a 'hard' exception (RuntimeError). Otherwise raise a 'soft' exception (AnalysisError).") # Outputs of the run of the component or items that will not work with the OptionsDictionary self.return_code = 0 # Return code from the command self.stdin = self.DEV_NULL self.stdout = None self.stderr = "error.out" def check_setup(self, out_stream=sys.stdout): """Write a report to the given stream indicating any potential problems found with the current configuration of this ``Problem``. Args ---- out_stream : a file-like object, optional """ # check for the command cmd = [c for c in self.options['command'] if c.strip()] if not cmd: out_stream.write( "The command cannot be empty") else: program_to_execute = self.options['command'][0] command_full_path = find_executable( program_to_execute ) if not command_full_path: out_stream.write("The command to be executed, '%s', " "cannot be found" % program_to_execute) # Check for missing input files missing = self._check_for_files(self.options['external_input_files']) if missing: out_stream.write("The following input files are missing at setup " " time: %s" % missing) def solve_nonlinear(self, params, unknowns, resids): """Runs the component """ self.return_code = -12345678 if not self.options['command']: raise ValueError('Empty command list') if self.options['fail_hard']: err_class = RuntimeError else: err_class = AnalysisError return_code = None try: missing = self._check_for_files(self.options['external_input_files']) if missing: raise err_class("The following input files are missing: %s" % sorted(missing)) return_code, error_msg = self._execute_local() if return_code is None: raise AnalysisError('Timed out after %s sec.' % self.options['timeout']) elif return_code: if isinstance(self.stderr, str): if os.path.exists(self.stderr): stderrfile = open(self.stderr, 'r') error_desc = stderrfile.read() stderrfile.close() err_fragment = "\nError Output:\n%s" % error_desc else: err_fragment = "\n[stderr %r missing]" % self.stderr else: err_fragment = error_msg raise err_class('return_code = %d%s' % (return_code, err_fragment)) missing = self._check_for_files(self.options['external_output_files']) if missing: raise err_class("The following output files are missing: %s" % sorted(missing)) finally: self.return_code = -999999 if return_code is None else return_code def _check_for_files(self, files): """ Check that specified files exist. """ return [path for path in files if not os.path.exists(path)] def _execute_local(self): """ Run command. """ # check to make sure command exists if isinstance(self.options['command'], str): program_to_execute = self.options['command'] else: program_to_execute = self.options['command'][0] # suppress message from find_executable function, we'll handle it numpy.distutils.log.set_verbosity(-1) command_full_path = find_executable( program_to_execute ) if not command_full_path: raise ValueError("The command to be executed, '%s', cannot be found" % program_to_execute) command_for_shell_proc = self.options['command'] if sys.platform == 'win32': command_for_shell_proc = ['cmd.exe', '/c' ] + command_for_shell_proc self._process = \ ShellProc(command_for_shell_proc, self.stdin, self.stdout, self.stderr, self.options['env_vars']) try: return_code, error_msg = \ self._process.wait(self.options['poll_delay'], self.options['timeout']) finally: self._process.close_files() self._process = None return (return_code, error_msg)