예제 #1
0
    def test_pipeerrors(self):
        """test piped stderrs """
        p = CmdPipe(readonly=False)
        err1 = []
        err2 = []
        err3 = []
        out = []
        p.add(["ls", "/nonexistent1"],
              stderr_handler=lambda line: err1.append(line))
        p.add(["ls", "/nonexistent2"],
              stderr_handler=lambda line: err2.append(line))
        p.add(["ls", "/nonexistent3"],
              stderr_handler=lambda line: err3.append(line))
        executed = p.execute(stdout_handler=lambda line: out.append(line))

        self.assertEqual(
            err1,
            ["ls: cannot access '/nonexistent1': No such file or directory"])
        self.assertEqual(
            err2,
            ["ls: cannot access '/nonexistent2': No such file or directory"])
        self.assertEqual(
            err3,
            ["ls: cannot access '/nonexistent3': No such file or directory"])
        self.assertEqual(out, [])
        self.assertTrue(executed)
        self.assertEqual(p.items[0]['process'].returncode, 2)
        self.assertEqual(p.items[1]['process'].returncode, 2)
        self.assertEqual(p.items[2]['process'].returncode, 2)
예제 #2
0
    def test_single(self):
        """single process stdout and stderr"""
        p=CmdPipe(readonly=False, inp=None)
        err=[]
        out=[]
        p.add(CmdItem(["ls", "-d", "/", "/", "/nonexistent"], stderr_handler=lambda line: err.append(line), exit_handler=lambda exit_code: self.assertEqual(exit_code,2)))
        executed=p.execute(stdout_handler=lambda line: out.append(line))

        self.assertEqual(err, ["ls: cannot access '/nonexistent': No such file or directory"])
        self.assertEqual(out, ["/","/"])
        self.assertIsNone(executed)
예제 #3
0
    def test_input(self):
        """test stdinput"""
        p=CmdPipe(readonly=False, inp="test")
        err=[]
        out=[]
        p.add(CmdItem(["cat"], stderr_handler=lambda line: err.append(line), exit_handler=lambda exit_code: self.assertEqual(exit_code,0)))
        executed=p.execute(stdout_handler=lambda line: out.append(line))

        self.assertEqual(err, [])
        self.assertEqual(out, ["test"])
        self.assertIsNone(executed)
예제 #4
0
    def test_input(self):
        """test stdinput"""
        p = CmdPipe(readonly=False, inp="test")
        err = []
        out = []
        p.add(["echo", "test"], stderr_handler=lambda line: err.append(line))
        executed = p.execute(stdout_handler=lambda line: out.append(line))

        self.assertEqual(err, [])
        self.assertEqual(out, ["test"])
        self.assertTrue(executed)
        self.assertEqual(p.items[0]['process'].returncode, 0)
예제 #5
0
    def test_readonly_execute(self):
        """everything readonly, just should execute"""

        p=CmdPipe(readonly=True)
        err1=[]
        err2=[]
        out=[]

        def true_exit(exit_code):
            return True

        p.add(CmdItem(["echo", "test1"], stderr_handler=lambda line: err1.append(line), exit_handler=true_exit, readonly=True))
        p.add(CmdItem(["echo", "test2"], stderr_handler=lambda line: err2.append(line), exit_handler=true_exit, readonly=True))
        executed=p.execute(stdout_handler=lambda line: out.append(line))

        self.assertEqual(err1, [])
        self.assertEqual(err2, [])
        self.assertEqual(out, ["test2"])
        self.assertTrue(executed)
예제 #6
0
    def test_readonly_skip(self):
        """one command not readonly, skip"""

        p=CmdPipe(readonly=True)
        err1=[]
        err2=[]
        out=[]
        p.add(CmdItem(["echo", "test1"], stderr_handler=lambda line: err1.append(line), readonly=False))
        p.add(CmdItem(["echo", "test2"], stderr_handler=lambda line: err2.append(line), readonly=True))
        executed=p.execute(stdout_handler=lambda line: out.append(line))

        self.assertEqual(err1, [])
        self.assertEqual(err2, [])
        self.assertEqual(out, [])
        self.assertTrue(executed)
예제 #7
0
    def test_exitcode(self):
        """test piped exitcodes """
        p=CmdPipe(readonly=False)
        err1=[]
        err2=[]
        err3=[]
        out=[]
        p.add(CmdItem(["bash", "-c", "exit 1"], stderr_handler=lambda line: err1.append(line), exit_handler=lambda exit_code: self.assertEqual(exit_code,1)))
        p.add(CmdItem(["bash", "-c", "exit 2"], stderr_handler=lambda line: err2.append(line), exit_handler=lambda exit_code: self.assertEqual(exit_code,2)))
        p.add(CmdItem(["bash", "-c", "exit 3"], stderr_handler=lambda line: err3.append(line), exit_handler=lambda exit_code: self.assertEqual(exit_code,3)))
        executed=p.execute(stdout_handler=lambda line: out.append(line))

        self.assertEqual(err1, [])
        self.assertEqual(err2, [])
        self.assertEqual(err3, [])
        self.assertEqual(out, [])
        self.assertIsNone(executed)
예제 #8
0
    def test_pipe(self):
        """test piped"""
        p=CmdPipe(readonly=False)
        err1=[]
        err2=[]
        err3=[]
        out=[]
        p.add(CmdItem(["echo", "test"], stderr_handler=lambda line: err1.append(line), exit_handler=lambda exit_code: self.assertEqual(exit_code,0)))
        p.add(CmdItem(["tr", "e", "E"], stderr_handler=lambda line: err2.append(line), exit_handler=lambda exit_code: self.assertEqual(exit_code,0)))
        p.add(CmdItem(["tr", "t", "T"], stderr_handler=lambda line: err3.append(line), exit_handler=lambda exit_code: self.assertEqual(exit_code,0)))
        executed=p.execute(stdout_handler=lambda line: out.append(line))

        self.assertEqual(err1, [])
        self.assertEqual(err2, [])
        self.assertEqual(err3, [])
        self.assertEqual(out, ["TEsT"])
        self.assertIsNone(executed)

        #test str representation as well
        self.assertEqual(str(p), "(echo test) | (tr e E) | (tr t T)")
예제 #9
0
    def test_readonly_execute(self):
        """everything readonly, just should execute"""

        p = CmdPipe(readonly=True)
        err1 = []
        err2 = []
        out = []
        p.add(["echo", "test1"],
              stderr_handler=lambda line: err1.append(line),
              readonly=True)
        p.add(["echo", "test2"],
              stderr_handler=lambda line: err2.append(line),
              readonly=True)
        executed = p.execute(stdout_handler=lambda line: out.append(line))

        self.assertEqual(err1, [])
        self.assertEqual(err2, [])
        self.assertEqual(out, ["test2"])
        self.assertTrue(executed)
        self.assertEqual(p.items[0]['process'].returncode, 0)
        self.assertEqual(p.items[1]['process'].returncode, 0)
예제 #10
0
    def test_pipe(self):
        """test piped"""
        p = CmdPipe(readonly=False)
        err1 = []
        err2 = []
        err3 = []
        out = []
        p.add(["echo", "test"], stderr_handler=lambda line: err1.append(line))
        p.add(["tr", "e", "E"], stderr_handler=lambda line: err2.append(line))
        p.add(["tr", "t", "T"], stderr_handler=lambda line: err3.append(line))
        executed = p.execute(stdout_handler=lambda line: out.append(line))

        self.assertEqual(err1, [])
        self.assertEqual(err2, [])
        self.assertEqual(err3, [])
        self.assertEqual(out, ["TEsT"])
        self.assertTrue(executed)
        self.assertEqual(p.items[0]['process'].returncode, 0)
        self.assertEqual(p.items[1]['process'].returncode, 0)
        self.assertEqual(p.items[2]['process'].returncode, 0)

        #test str representation as well
        self.assertEqual(str(p), "(echo test) | (tr e E) | (tr t T)")
예제 #11
0
    def run(self,
            cmd,
            inp=None,
            tab_split=False,
            valid_exitcodes=None,
            readonly=False,
            hide_errors=False,
            return_stderr=False,
            pipe=False):
        """run a command on the node , checks output and parses/handle output and returns it

        :param cmd: the actual command, should be a list, where the first item is the command
                    and the rest are parameters.
        :param pipe: return CmdPipe instead of executing it.
        :param inp: Can be None, a string or a CmdPipe that was previously returned.
        :param tab_split: split tabbed files in output into a list
        :param valid_exitcodes: list of valid exit codes for this command (checks exit code of both sides of a pipe)
                                Use [] to accept all exit codes. Default [0]
        :param readonly: make this True if the command doesn't make any changes and is safe to execute in testmode
        :param hide_errors: don't show stderr output as error, instead show it as debugging output (use to hide expected errors)
        :param return_stderr: return both stdout and stderr as a tuple. (normally only returns stdout)

        """

        # create new pipe?
        if not isinstance(inp, CmdPipe):
            p = CmdPipe(self.readonly, inp)
        else:
            # add stuff to existing pipe
            p = inp

        # stderr parser
        error_lines = []

        def stderr_handler(line):
            if tab_split:
                error_lines.append(line.rstrip().split('\t'))
            else:
                error_lines.append(line.rstrip())
            self._parse_stderr(line, hide_errors)

        # add command to pipe
        encoded_cmd = self._remote_cmd(cmd)
        p.add(cmd=encoded_cmd,
              readonly=readonly,
              stderr_handler=stderr_handler)

        # return pipe instead of executing?
        if pipe:
            return p

        # stdout parser
        output_lines = []

        def stdout_handler(line):
            if tab_split:
                output_lines.append(line.rstrip().split('\t'))
            else:
                output_lines.append(line.rstrip())
            self._parse_stdout(line)

        if p.should_execute():
            self.debug("CMD    > {}".format(p))
        else:
            self.debug("CMDSKIP> {}".format(p))

        # execute and verify exit codes
        if p.execute(
                stdout_handler=stdout_handler) and valid_exitcodes is not []:
            if valid_exitcodes is None:
                valid_exitcodes = [0]

            item_nr = 1
            for item in p.items:
                exit_code = item['process'].returncode

                if self.debug_output:
                    self.debug("EXIT{}  > {}".format(item_nr, exit_code))

                if exit_code not in valid_exitcodes:
                    raise (subprocess.CalledProcessError(
                        exit_code, " ".join(item['cmd'])))
                item_nr = item_nr + 1

        if return_stderr:
            return output_lines, error_lines
        else:
            return output_lines