Implement runScript in cls_cmd for LocalCmd/RemoteCmd, add test

A lot of CI code is python mixed with bash, e.g.,

    ssh = getConnection(host)
    ssh.run('ls')
    ssh.run('echo')

At least some of this CI code would benefit if it was written in a
simple bash script, returning error codes and potentially other
information either through stdout/stderr or files, to the calling Python
code:

    ssh = runScript(host, script)
    # script does: ls; echo

This commit introduces the possibility to run entire scripts. The idea
is that the executor has a script (on localhost), which is either
executed locally or on a remote host. For the remote host, the script is
not copied but piped into a remotely executed bash. In both cases,
output is either returned like the Cmd.run() function with returncode
and mixed stdout/stderr, or optionally redirected into a file on the
(remote) host, which can be treated further by the Python code in later
steps.
This commit is contained in:
Robert Schmidt
2024-09-28 12:52:59 +02:00
parent fc0bc2357c
commit e541aee49e
2 changed files with 104 additions and 4 deletions
+43
View File
@@ -35,6 +35,27 @@ class TestCmd(unittest.TestCase):
self.assertEqual(ret.returncode, 0)
self.assertEqual(ret.stdout, "test")
def test_local_script(self):
ret = cls_cmd.runScript("localhost", "tests/scripts/hello-world.sh", 1)
self.assertEqual(ret.args, "tests/scripts/hello-world.sh")
self.assertEqual(ret.returncode, 0)
self.assertEqual(ret.stdout, "+ echo hello, world\nhello, world")
ret = cls_cmd.runScript("localhost", "tests/scripts/hello-fail.sh", 1, "TESTFAIL")
self.assertEqual(ret.args, "tests/scripts/hello-fail.sh TESTFAIL")
self.assertEqual(ret.returncode, 1)
self.assertEqual(ret.stdout, "TESTFAIL")
ret = cls_cmd.runScript("localhost", "tests/scripts/hello-fail.sh", 1, "TESTFAIL2", "/tmp/result")
self.assertEqual(ret.args, "tests/scripts/hello-fail.sh TESTFAIL2 &> /tmp/result")
self.assertEqual(ret.returncode, 1)
self.assertEqual(ret.stdout, "")
with cls_cmd.getConnection("localhost") as ssh:
ret = ssh.run("cat /tmp/result")
self.assertEqual(ret.args, "cat /tmp/result")
self.assertEqual(ret.returncode, 0)
self.assertEqual(ret.stdout, "TESTFAIL2")
@unittest.skip("need to be able to passwordlessly SSH to localhost, also disable stty -ixon")
def test_remote_cmd(self):
with cls_cmd.getConnection("127.0.0.1") as cmd:
@@ -52,5 +73,27 @@ class TestCmd(unittest.TestCase):
self.assertEqual(ret.returncode, 0)
self.assertEqual(ret.stdout, "test")
@unittest.skip("need to be able to passwordlessly SSH to localhost, also disable stty -ixon")
def test_remote_script(self):
ret = cls_cmd.runScript("127.0.0.1", "tests/scripts/hello-world.sh", 1)
self.assertEqual(ret.args, "tests/scripts/hello-world.sh")
self.assertEqual(ret.returncode, 0)
self.assertEqual(ret.stdout, "+ echo hello, world\nhello, world")
ret = cls_cmd.runScript("127.0.0.1", "tests/scripts/hello-fail.sh", 1, "TESTFAIL")
self.assertEqual(ret.args, "tests/scripts/hello-fail.sh TESTFAIL")
self.assertEqual(ret.returncode, 1)
self.assertEqual(ret.stdout, "TESTFAIL")
ret = cls_cmd.runScript("127.0.0.1", "tests/scripts/hello-fail.sh", 1, "TESTFAIL2", "/tmp/result")
self.assertEqual(ret.args, "tests/scripts/hello-fail.sh TESTFAIL2 &> /tmp/result")
self.assertEqual(ret.returncode, 1)
self.assertEqual(ret.stdout, "")
with cls_cmd.getConnection("localhost") as ssh:
ret = ssh.run("cat /tmp/result")
self.assertEqual(ret.args, "cat /tmp/result")
self.assertEqual(ret.returncode, 0)
self.assertEqual(ret.stdout, "TESTFAIL2")
if __name__ == '__main__':
unittest.main()