def wrapper(): tempdir = tempfile.mkdtemp(prefix="threadbare-" + prefix) try: yield {"temp-dir": tempdir} finally: # permissions on temp dir may have changed. make sure we can still remove it. local('chown %s:%s -R "%s"' % (USER, USER, tempdir), use_sudo=True) shutil.rmtree(tempdir)
def test_run_a_local_command_but_hide_output(): "presumably for side effects" with hide(): result = local("cat /etc/passwd", capture=False) # (nothing should be emitted) assert result["succeeded"] assert result["stdout"] == [] assert result["stderr"] == []
def test_local_command_non_zero_custom_exit(): "`local` commands may raise a specific exception if the command they execute exits with a non-zero result" with pytest.raises(ValueError) as err: operations.local("exit 1", abort_exception=ValueError) exc = err.value expected_err_msg = "local() encountered an error (return code 1) while executing '/bin/bash -l -c \"exit 1\"'" assert expected_err_msg == str(exc) expected_err_payload = { "command": '/bin/bash -l -c "exit 1"', "failed": True, "return_code": 1, "stderr": [], "stdout": [], "succeeded": False, } assert expected_err_payload == exc.result
def test_local_command_non_zero_exit_swallowed(): "`local` commands that exit with a non-zero result do not raise an exception if `warn_only` is `True`" expected_result = { "command": '/bin/bash -l -c "exit 1"', "failed": True, "return_code": 1, "stderr": [], "stdout": [], "succeeded": False, } command = "exit 1" with state.settings(warn_only=True): result = operations.local(command) assert expected_result == result # ... and again, but as a parameter result = operations.local(command, warn_only=True) assert expected_result == result
def test_local_command(): "non-shell commands must pass their command as a list of arguments" command = ["echo", "hello world"] expected = { "succeeded": True, "failed": False, "return_code": 0, "command": command, "stdout": [], "stderr": [], } actual = operations.local(command, use_shell=False) assert expected == actual
def test_local_sudo_command(): "non-shell sudo commands have 'sudo' added to the command argument list" command = ["echo", "hello world"] expected = { "succeeded": True, "failed": False, "return_code": 0, "command": ["sudo", "--non-interactive", "echo", "hello world"], "stdout": [], "stderr": [], } actual = operations.local(command, use_shell=False, use_sudo=True) assert expected == actual
def test_local_command_capture(): "when output is being captured, non-shell command output on stdout is available" command = ["echo", "hello world"] expected = { "succeeded": True, "failed": False, "return_code": 0, "command": command, "stdout": ["hello world"], "stderr": [], } actual = operations.local(command, capture=True, use_shell=False) assert expected == actual
def test_local_shell_command_capture(): "when output is being captured, shell command output on stdout is available" command = 'echo "hello world"' expected = { "return_code": 0, "succeeded": True, "failed": False, "command": '/bin/bash -l -c "echo \\"hello world\\""', "stdout": ["hello world"], "stderr": [], } actual = operations.local(command, capture=True) assert expected == actual
def test_local_shell_command(): "commands are run within a shell successfully" command = 'echo "hello world"' expected = { "return_code": 0, "succeeded": True, "failed": False, "command": '/bin/bash -l -c "echo \\"hello world\\""', "stdout": [], "stderr": [], } actual = operations.local(command) assert expected == actual
def test_local_command_split_stderr(): "when output is being captured, output on stderr is also available when `combine_stderr` is False" command = 'echo "standard out"; >&2 echo "standard error"' expected = { "succeeded": True, "failed": False, "return_code": 0, "command": '/bin/bash -l -c "echo \\"standard out\\"; >&2 echo \\"standard error\\""', "stdout": ["standard out"], "stderr": ["standard error"], } actual = operations.local(command, combine_stderr=False, capture=True) assert expected == actual
def test_local_command_stderr(): "when output is being captured, stderr is combined with stdout by default" command = 'echo "standard out"; >&2 echo "standard error"' expected = { "succeeded": True, "failed": False, "return_code": 0, "command": '/bin/bash -l -c "echo \\"standard out\\"; >&2 echo \\"standard error\\""', "stdout": ["standard out", "standard error"], "stderr": [], } actual = operations.local(command, capture=True) # default is to combine assert expected == actual
def test_local_shell_sudo_command_capture(): "local sudo commands have their output captured as expected" command = 'sudo echo "hello world"' expected = { "succeeded": True, "failed": False, "return_code": 0, "command": 'sudo --non-interactive /bin/bash -l -c "sudo echo \\"hello world\\""', "stdout": ["hello world"], "stderr": [], } actual = operations.local(command, capture=True, use_sudo=True) assert expected == actual
def test_local_shell_sudo_command(): "local commands are run as root when `use_sudo` is `True`" command = 'sudo echo "hello world"' expected = { "succeeded": True, "failed": False, "return_code": 0, "command": 'sudo --non-interactive /bin/bash -l -c "sudo echo \\"hello world\\""', "stdout": [], "stderr": [], } actual = operations.local(command, use_sudo=True) assert expected == actual
def wrapper(): tempdir = tempfile.mkdtemp(prefix="threadbare-" + prefix) # create some empty files of specific sizes path_map = { "small-file": join(tempdir, "small-file.temp"), "medium-file": join(tempdir, "medium-file.temp"), # "large-file": join(tempdir, "large-file.temp") # unused } file_size_map = { "small-file": "1KiB", "medium-file": "1MiB", "large-file": "25MiB", } for path_name, path in path_map.items(): file_size = file_size_map[path_name] local("fallocate -l %s %s" % (file_size, path)) try: yield {"temp-dir": tempdir, "temp-files": path_map} finally: # permissions on temp dir may have changed. make sure we can still remove it. local('chown %s:%s -R "%s"' % (USER, USER, tempdir), use_sudo=True) shutil.rmtree(tempdir)
def _test_upload_and_download_a_file(transfer_protocol): """write a local file, upload it to the remote server, modify it remotely, download it, modify it locally, assert it's contents are as expected""" with empty_local_fixture() as local_env: with empty_remote_fixture() as remote_env: with test_settings(transfer_protocol=transfer_protocol): LOG.debug("modifying local file ...") local_file_name = join(local_env["temp-dir"], "foo") local('printf "foo" > %s' % local_file_name) LOG.debug("uploading file ...") remote_file_name = join(remote_env["temp-dir"], "foobar") upload(local_file_name, remote_file_name) # verify contents assert remote_file_exists(remote_file_name) assert remote("cat %s" % remote_file_name)["stdout"] == ["foo"] LOG.debug("modifying remote file ...") remote('printf "bar" >> %s' % remote_file_name) # verify contents assert remote("cat %s" % remote_file_name)["stdout"] == ["foobar"] LOG.debug("downloading file ...") new_local_file_name = join(local_env["temp-dir"], "foobarbaz") download(remote_file_name, new_local_file_name) # verify contents assert open(new_local_file_name, "r").read() == "foobar" LOG.debug("modifying local file (again) ...") local('printf "baz" >> %s' % new_local_file_name) LOG.debug("testing local file ...") data = open(new_local_file_name, "r").read() assert "foobarbaz" == data
def test_local_command_timeout(): "`local` commands can be killed if their execution exceeds a timeout threshold" command = "sleep 5" expected = { "succeeded": False, "failed": True, "return_code": -9, # SIGKILL "command": '/bin/bash -l -c "sleep 5"', "stdout": [], "stderr": [], } actual = operations.local(command, capture=True, timeout=0.1, warn_only=True) assert expected == actual
def test_local_quiet_param(): "when quiet=True, nothing is sent to stdout or stderr" cmd = lambda: operations.local( 'echo "hi!"; >&2 echo "hello!"', capture=False, combine_stderr=False) result = cmd() # with `local` it's either captured or printed. # if the results are empty it's because it was printed. # but how do we test? sys.stdout/sys.stderr are bypassed ... this test needs improving somehow. assert result["stdout"] == [] assert result["stderr"] == [] with operations.hide(): result = cmd() assert result["stdout"] == [] assert result["stderr"] == []
def test_local_sudo_command_capture(): "non-shell sudo commands continue to capture output as expected" command = ["echo", "hello world"] expected = { "succeeded": True, "failed": False, "return_code": 0, "command": ["sudo", "--non-interactive", "echo", "hello world"], "stdout": ["hello world"], "stderr": [], } actual = operations.local(command, capture=True, use_shell=False, use_sudo=True) assert expected == actual
def myfn(): return local(state.ENV["cmd"], capture=True)
def test_run_a_local_command_in_a_different_dir(): "switch to a different local directory to run a command" with lcd("/tmp"): result = local("pwd", capture=True) assert result["succeeded"] assert result["stdout"] == ["/tmp"]
def test_run_a_local_command_with_separate_streams(): "run a simple local command but capture the output" result = local("echo hello, world!", capture=True) assert result["succeeded"]
def test_run_a_local_command(): "run a simple local command" result = local("echo hello, world!") assert result["succeeded"]
def test_local_command_non_arg_list(): "non-shell commands must pass their command as a list of arguments" with pytest.raises(ValueError): operations.local("echo foo", use_shell=False)