forked from third-party-mirrors/zfs_autobackup
working on unit tests, found and fixed escaping issue
This commit is contained in:
parent
e1344dd9da
commit
04971f2f29
67
bin/test_executenode.py
Normal file
67
bin/test_executenode.py
Normal file
@ -0,0 +1,67 @@
|
||||
|
||||
#default test stuff
|
||||
import unittest
|
||||
from zfs_autobackup import *
|
||||
|
||||
import subprocess
|
||||
|
||||
print("THIS TEST REQUIRES SSH TO LOCALHOST")
|
||||
|
||||
class TestExecuteNode(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
|
||||
return super().setUp()
|
||||
|
||||
def basics(self, node ):
|
||||
|
||||
#single line with spaces
|
||||
self.assertEqual(node.run(["echo","test test"]), ["test test"])
|
||||
|
||||
#error exit code
|
||||
with self.assertRaises(subprocess.CalledProcessError):
|
||||
node.run(["false"])
|
||||
|
||||
#multiline without tabsplit
|
||||
self.assertEqual(node.run(["echo","l1c1\tl1c2\nl2c1\tl2c2"], tab_split=False), ["l1c1\tl1c2", "l2c1\tl2c2"])
|
||||
# self.assertEqual(node.run(["echo","l1\nl2"]), ["l1", "l2"])
|
||||
|
||||
#multiline tabsplit
|
||||
self.assertEqual(node.run(["echo","l1c1\tl1c2\nl2c1\tl2c2"], tab_split=True), [['l1c1', 'l1c2'], ['l2c1', 'l2c2']])
|
||||
|
||||
|
||||
#escaping (shouldnt be a problem locally, single quotes can be a problem remote via ssh)
|
||||
s="><`'\"@&$()$bla\\//.*!#test"
|
||||
self.assertEqual(node.run(["echo",s]), [s])
|
||||
|
||||
#return std err
|
||||
# self.assertEqual(node.run(["echo","test test"], return_stderr=True), ["test test"])
|
||||
|
||||
|
||||
def test_basicslocal(self):
|
||||
node=ExecuteNode(debug_output=True)
|
||||
self.basics(node)
|
||||
|
||||
def test_basicsremote(self):
|
||||
node=ExecuteNode(ssh_to="localhost", debug_output=True)
|
||||
self.basics(node)
|
||||
|
||||
|
||||
# def test_remoteecho(self):
|
||||
# node=ExecuteNode(ssh_to="localhost", debug_output=True)
|
||||
# self.assertEqual(node.run(["echo","test"]), ["test"])
|
||||
|
||||
# def test_exitlocal(self):
|
||||
# node=ExecuteNode(debug_output=True)
|
||||
|
||||
# def test_exitremote(self):
|
||||
# node=ExecuteNode(ssh_to="localhost", debug_output=True)
|
||||
# with self.assertRaises(subprocess.CalledProcessError):
|
||||
# self.remote1.run(["false"])
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
@ -26,7 +26,7 @@ if sys.stdout.isatty():
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
VERSION="3.0-rc10"
|
||||
VERSION="3.0-rc11"
|
||||
HEADER="zfs-autobackup v{} - Copyright 2020 E.H.Eefting (edwin@datux.nl)\n".format(VERSION)
|
||||
|
||||
class Log:
|
||||
@ -299,6 +299,15 @@ class ExecuteNode:
|
||||
else:
|
||||
self.error("STDERR|> "+line.rstrip())
|
||||
|
||||
#simple logging stubs
|
||||
def debug(self, txt):
|
||||
print("DEBUG : "+txt)
|
||||
|
||||
def verbose(self, txt):
|
||||
print("VERBOSE: "+txt)
|
||||
|
||||
def error(self, txt):
|
||||
print("ERROR : "+txt)
|
||||
|
||||
def run(self, cmd, input=None, tab_split=False, valid_exitcodes=[ 0 ], readonly=False, hide_errors=False, pipe=False, return_stderr=False):
|
||||
"""run a command on the node
|
||||
@ -324,7 +333,9 @@ class ExecuteNode:
|
||||
#(this is necessary if LC_ALL=en_US.utf8 is not set in the environment)
|
||||
for arg in cmd:
|
||||
#add single quotes for remote commands to support spaces and other weird stuff (remote commands are executed in a shell)
|
||||
encoded_cmd.append( ("'"+arg+"'").encode('utf-8'))
|
||||
#and escape existing single quotes (bash needs ' to end the quoted string, then a \' for the actual quote and then another ' to start a new quoted string)
|
||||
#(and then python needs the double \ to get a single \)
|
||||
encoded_cmd.append( ("'" + arg.replace("'","'\\''") + "'").encode('utf-8'))
|
||||
|
||||
else:
|
||||
for arg in cmd:
|
||||
@ -369,6 +380,7 @@ class ExecuteNode:
|
||||
if isinstance(input,str) or type(input)=='unicode':
|
||||
p.stdin.write(input)
|
||||
|
||||
#return pipe
|
||||
if pipe:
|
||||
return(p)
|
||||
|
||||
@ -427,10 +439,11 @@ class ExecuteNode:
|
||||
if valid_exitcodes and input.returncode not in valid_exitcodes:
|
||||
raise(subprocess.CalledProcessError(input.returncode, "(pipe)"))
|
||||
|
||||
|
||||
if valid_exitcodes and p.returncode not in valid_exitcodes:
|
||||
raise(subprocess.CalledProcessError(p.returncode, encoded_cmd))
|
||||
|
||||
|
||||
|
||||
if return_stderr:
|
||||
return ( output_lines, error_lines )
|
||||
else:
|
||||
|
Loading…
x
Reference in New Issue
Block a user