Beispiel #1
0
    def test_run_external_command_fail_with_output(self):
        temp_dir = tempfile.mkdtemp()
        try:
            script = os.path.join(temp_dir, 'yo.py')

            # create a small python script that outputs args passed
            # in to standard out, writes error to standard error
            #  and exits with 0 exit code
            f = open(script, 'w')
            f.write('#! /usr/bin/env python\n\n')
            f.write('import sys\n')
            f.write('sys.stdout.write(sys.argv[1])\n')
            f.write('sys.stdout.write(sys.argv[2])\n')
            f.write('sys.stderr.write("2error")\n')
            f.write('sys.exit(2)\n')
            f.flush()
            f.close()
            os.chmod(script, stat.S_IRWXU)

            ecode, out, err = util.run_external_command(script + ' hi how')

            self.assertEqual(err, '2error')
            self.assertEqual(out, 'hihow')
            self.assertEqual(ecode, 2)

        finally:
            shutil.rmtree(temp_dir)
Beispiel #2
0
    def test_run_external_command_cmd_does_not_exist(self):
        temp_dir = tempfile.mkdtemp()
        try:
            try:
                noexist = os.path.join(temp_dir, 'noexist')
                ecode, out, err = util.run_external_command(noexist)
                self.fail('Expected OSError')
            except OSError:
                pass

        finally:
            shutil.rmtree(temp_dir)
Beispiel #3
0
    def run_external_command(self,
                             command_name,
                             cmd_to_run,
                             command_failure_is_fatal,
                             timeout=None,
                             kill_delay=10,
                             polling_sleep_time=1):
        """Runs external command line process

        Method runs external process logging the command
        run to email log.  Standard output and error are
        written to current working directory `command_name`.stdout
        and `command_name`.stderr respectively and if process.

        :param command_name: Name of command, human readable version
                             used as prefix for .stderr and .stdout
                             files
        :param cmd_to_run: command with arguments to run,
                        passed to subprocess.Popen
        :param command_failure_is_fatal: True means if process
               fails with nonzero exit code or there is an
               exception then status of task is set to
               D3RTask.ERROR_STATUS and failure message appended
               to email log and task.set_error is set
        :return: exit code of process
        :raise: UnsetNameError if command_name is None
        :raise: UnsetCommandError if cmd_to_run is None
        """
        if command_name is None:
            raise UnsetNameError('Command name must be set')

        if cmd_to_run is None:
            raise UnsetCommandError('Command must be set')

        if command_failure_is_fatal is None:
            command_failure_is_fatal = True

        logger.info("Running command " + cmd_to_run)

        self.append_to_email_log('Running command: ' + cmd_to_run + '\n')
        cmd_tmp_dir = None
        try:
            if timeout is not None:
                cmd_tmp_dir = os.path.join(
                    self.get_dir(),
                    command_name + str(uuid.uuid1()) + D3RTask.TMP_DIR_SUFFIX)
                os.makedirs(cmd_tmp_dir, mode=0o0775)
                pst = polling_sleep_time  # trying to make flake8 happy

                returncode, out, err = util.\
                    run_external_command_with_timeout(cmd_to_run,
                                                      cmd_tmp_dir,
                                                      timeout=timeout,
                                                      kill_delay=kill_delay,
                                                      polling_sleep_time=pst)
            else:
                returncode, out, err = util.run_external_command(cmd_to_run)
        except Exception as e:
            logger.exception("Error caught exception")
            self.set_status(D3RTask.ERROR_STATUS)
            self.set_error("Caught Exception trying to run " + cmd_to_run +
                           " : " + str(e))
            self.end()
            return 1
        finally:
            if cmd_tmp_dir is not None:
                shutil.rmtree(cmd_tmp_dir)

        self.write_to_file(err, command_name + D3RTask.STDERR_SUFFIX)
        self.write_to_file(out, command_name + D3RTask.STDOUT_SUFFIX)

        if returncode != 0:
            if command_failure_is_fatal:
                self.set_status(D3RTask.ERROR_STATUS)
                self.set_error("Non zero exit code: " + str(returncode) +
                               " received. Standard out: " + out +
                               " Standard error: " + err)
            else:
                max_chars = D3RTask.MAX_CHARS_FOR_EMAIL_STR
                trunc_out = self._get_email_truncated_string(out, max_chars)
                trunc_err = self._get_email_truncated_string(err, max_chars)

                self.append_to_email_log("Although considered non fatal " +
                                         "for processing of stage a " +
                                         "non zero exit code: " +
                                         str(returncode) +
                                         "received. Standard out: " +
                                         trunc_out + " Standard error : " +
                                         trunc_err)
        return returncode
Beispiel #4
0
 def test_run_external_command_command_not_set(self):
     ecode, out, err = util.run_external_command(None)
     self.assertEqual(ecode, 256)
     self.assertEqual(out, '')
     self.assertEqual(err, 'Command must be set')