コード例 #1
0
def test_rcd():
    "`operations.rcd` causes the command to be executed to happen in a different directory"
    with patch("threadbare.operations._execute") as mockobj:
        with operations.rcd("/tmp"):
            mockobj.return_value = {
                "return_code": lambda: 0,
                "stdout": [],
                "stderr": [],
            }
            operations.remote("pwd",
                              host_string=HOST,
                              port=PORT,
                              user=USER,
                              key_filename=PEM)

    expected_kwargs = {
        "host_string": HOST,
        "port": PORT,
        "user": USER,
        "key_filename": PEM,
        "use_pty": True,
        "timeout": None,
        "command": '/bin/bash -l -c "cd \\"/tmp\\" && pwd"',
    }
    mockobj.assert_called_with(**expected_kwargs)
コード例 #2
0
ファイル: example.py プロジェクト: elifesciences/threadbare
def test_run_a_remote_command_non_zero_custom_exit():
    """`remote` commands, like `local` commands, may raise a custom exception if the command they execute fails.
    the results of the command are still available via the `result` attribute on the exception object"""
    with test_settings():
        with pytest.raises(ValueError) as err:
            remote("exit 123", abort_exception=ValueError)
        exc = err.value
        assert exc.result["return_code"] == 123
        assert exc.result["failed"]
        assert not exc.result["succeeded"]
コード例 #3
0
ファイル: example.py プロジェクト: elifesciences/threadbare
def test_run_a_remote_command_with_shell_interpolation():
    "run a simple `remote` command including shell variables"
    with test_settings(quiet=True):
        result = remote('foo=baz; echo "bar? $foo!"')
        assert result["succeeded"]
        assert ["bar? baz!"] == result["stdout"]

        result2 = remote('foo=baz; echo "bar? $foo!"', use_shell=False)
        assert result2["succeeded"]
        assert ["bar? baz!"] == result["stdout"]
コード例 #4
0
def test_remote_command_exception():
    kwargs = {
        "host_string": HOST,
        "port": PORT,
        "user": USER,
        "key_filename": PEM,
        "command": "echo hello",
    }
    m = mock.MagicMock()
    m.run_command = mock.Mock(side_effect=ValueError("earthshatteringkaboom"))
    with patch("threadbare.operations.SSHClient", return_value=m):
        with pytest.raises(operations.NetworkError):
            operations.remote(**kwargs)
コード例 #5
0
ファイル: example.py プロジェクト: elifesciences/threadbare
def test_run_script():
    "a simple shell script can be uploaded and executed and the results accessible"
    with empty_local_fixture() as local_env:
        with empty_remote_fixture() as remote_env:
            with test_settings():
                local_script = join(local_env["temp-dir"], "script.sh")
                open(local_script, "w").write(r"""#!/bin/bash
echo "hello, world"
""")
                remote_script = join(remote_env["temp-dir"], "script.sh")
                upload(local_script, remote_script)
                remote("chmod +x %s" % remote_script)
                with rcd(os.path.dirname(remote_script)):
                    result = remote("./script.sh")
                assert ["hello, world"] == result["stdout"]
コード例 #6
0
ファイル: example.py プロジェクト: elifesciences/threadbare
def test_download_to_extant_local_file():
    "the default policy is to overwrite files that exist."
    with local_fixture() as local_env:
        with empty_remote_fixture() as remote_env:
            with test_settings():
                local_file = local_env["temp-files"]["small-file"]
                assert os.path.exists(local_file)

                payload = "foo"
                remote_file = join(remote_env["temp-dir"], "foo.file")
                remote('printf %s > "%s"' % (payload, remote_file))
                assert remote_file_exists(remote_file)

                download(remote_file, local_file)
                result = open(local_file, "r").read()
                assert payload == result
コード例 #7
0
ファイル: example.py プロジェクト: elifesciences/threadbare
 def workerfn():
     iterations = 2
     cmd = 'for run in {1..%s}; do echo "I am %s, iteration $run"; done' % (
         iterations,
         state.ENV["worker_num"],
     )
     return remote(cmd)
コード例 #8
0
def test_remote_command_timeout_exception():
    kwargs = {
        "host_string": HOST,
        "port": PORT,
        "user": USER,
        "key_filename": PEM,
        "command": "echo hello",
    }
    m = mock.MagicMock()
    m.run_command = mock.Mock(side_effect=pssh_exceptions.Timeout("foobar"))
    with patch("threadbare.operations.SSHClient", return_value=m):
        with pytest.raises(operations.NetworkError) as err:
            operations.remote(**kwargs)
        err = err.value
        assert type(err.wrapped) == pssh_exceptions.Timeout
        assert str(err) == "Timed out trying to connect. foobar"
コード例 #9
0
ファイル: example.py プロジェクト: elifesciences/threadbare
def test_run_a_remote_command_non_zero_return_code_swallow_error():
    "`remote` commands, like `local` commands, can return the results of failed executions when `warn_only` is `True`"
    with test_settings(warn_only=True):
        result = remote("exit 123")
        assert result["return_code"] == 123
        assert result["failed"]
        assert not result["succeeded"]
コード例 #10
0
ファイル: example.py プロジェクト: elifesciences/threadbare
def test_run_a_remote_command_but_hide_output():
    "run a simple `remote` command but don't print anything"
    with test_settings():
        with hide():
            result = remote("echo hi!")
            # (nothing should have been emitted)
            assert result["succeeded"]
            assert result["stdout"] == ["hi!"]
コード例 #11
0
ファイル: example.py プロジェクト: elifesciences/threadbare
def test_run_a_remote_command_in_a_different_dir():
    "run a simple `remote` command in a different remote directory"
    with remote_fixture() as remote_env:
        with test_settings():
            remote_dir = remote_env["temp-dir"]
            with rcd(remote_dir):
                result = remote("pwd")
    assert result["succeeded"]
    assert [remote_dir] == result["stdout"]
コード例 #12
0
ファイル: example.py プロジェクト: elifesciences/threadbare
def test_run_a_remote_command_with_separate_streams():
    "run a simple `remote` command and capture stdout and stderr separately"
    with test_settings():
        result = remote(
            'echo "printed to standard out"; >&2 echo "printed to standard error"',
            combine_stderr=False,
        )
        assert result["succeeded"]
        assert ["printed to standard out"] == result["stdout"]
        assert ["printed to standard error"] == result["stderr"]
コード例 #13
0
ファイル: example.py プロジェクト: elifesciences/threadbare
def test_run_many_remote_commands_singly():
    "multiple commands can be concatenated into a single command"
    command_list = [
        "echo all",
        "echo these commands",
        "echo are executed",
        "echo together",
    ]
    with test_settings():
        result = remote(single_command(command_list))
        assert result["succeeded"]
コード例 #14
0
ファイル: example.py プロジェクト: elifesciences/threadbare
def test_run_many_remote_commands():
    "running many `remote` commands re-uses the established ssh session"
    command_list = [
        "echo all",
        "echo these commands",
        "echo share the same",
        "echo ssh session",
    ]
    with test_settings():
        for command in command_list:
            result = remote(command)
            assert result["succeeded"]
コード例 #15
0
ファイル: example.py プロジェクト: elifesciences/threadbare
def test_upload_to_extant_remote_file():
    "the default policy is to overwrite files that exist."
    with empty_local_fixture():
        with remote_fixture() as remote_env:
            with test_settings():
                payload = b"foo"
                remote_file = remote_env["temp-files"]["small-file"]

                # just to illustrate an overwrite *is* happening
                assert remote_file_exists(remote_file)
                upload(BytesIO(payload), remote_file)
                result = remote('cat "%s"' % (remote_file, ))
                assert [payload.decode("utf-8")] == result["stdout"]
コード例 #16
0
ファイル: example.py プロジェクト: elifesciences/threadbare
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
コード例 #17
0
def test_remote_args_to_execute():
    "`operations.remote` calls `operations._execute` with the correct arguments"
    with patch("threadbare.operations._execute") as mockobj:
        mockobj.return_value = {
            "return_code": lambda: 0,
            "stdout": [],
            "stderr": []
        }
        operations.remote("echo hello",
                          host_string=HOST,
                          port=PORT,
                          user=USER,
                          key_filename=PEM)

    expected_kwargs = {
        "host_string": HOST,
        "port": PORT,
        "user": USER,
        "key_filename": PEM,
        "use_pty": True,
        "timeout": None,
        "command": '/bin/bash -l -c "echo hello"',
    }
    mockobj.assert_called_with(**expected_kwargs)
コード例 #18
0
ファイル: example.py プロジェクト: elifesciences/threadbare
def test_upload_and_download_a_file_using_byte_buffers():
    """contents of a BytesIO buffer can be uploaded to a remote file,
    and the contents of a remote file can be downloaded to a BytesIO buffer"""
    with empty_remote_fixture() as remote_env:
        with test_settings(quiet=True):
            payload = b"foo-bar-baz"
            uploadable_unicode_buffer = BytesIO(payload)
            remote_file_name = join(remote_env["temp-dir"], "bytes-test")

            upload(uploadable_unicode_buffer, remote_file_name)
            assert remote_file_exists(remote_file_name)

            result = remote('cat "%s"' % remote_file_name)
            assert result["succeeded"]
            assert result["stdout"] == [payload.decode()]

            download_unicode_buffer = BytesIO()
            download(remote_file_name, download_unicode_buffer)
            assert download_unicode_buffer.getvalue() == payload
コード例 #19
0
ファイル: example.py プロジェクト: elifesciences/threadbare
 def workerfn():
     upload(local_script, remote_script)
     remote("chmod +x %s" % remote_script)
     with rcd(os.path.dirname(remote_script)):
         return remote("./script.sh")
コード例 #20
0
ファイル: example.py プロジェクト: elifesciences/threadbare
def test_run_a_remote_command():
    "run a simple `remote` command"
    with test_settings(quiet=True):
        result = remote(r'echo -e "\e[31mRed Text!!\e[0m"')
        assert result["succeeded"]
コード例 #21
0
def test_remote_non_default_args():
    "`operations.remote` calls `operations._execute` with the correct arguments"
    base = {
        "host_string": HOST,
        "port": PORT,
        "user": USER,
        "key_filename": PEM,
        "command": "echo hello",
        "timeout": None,
    }

    # given args, expected args
    cases = [
        # non-shell regular command
        [{
            "use_shell": False
        }, {
            "use_pty": True,
            "command": "echo hello"
        }],
        # non-shell, non-tty command
        [
            {
                "use_shell": False,
                "combine_stderr": False
            },
            {
                "use_pty": False,
                "command": "echo hello"
            },
        ],
        # non-shell sudo command
        [
            {
                "use_shell": False,
                "use_sudo": True
            },
            {
                "use_pty": True,
                "command": "sudo --non-interactive echo hello"
            },
        ],
        # shell, regular command
        [
            {
                "use_shell": True
            },
            {
                "use_pty": True,
                "command": '/bin/bash -l -c "echo hello"'
            },
        ],
        # shell, sudo command
        [
            {
                "use_shell": True,
                "use_sudo": True
            },
            {
                "use_pty": True,
                "command":
                'sudo --non-interactive /bin/bash -l -c "echo hello"',
            },
        ],
        # shell escaped operations
        [
            {
                "command": 'foo=bar; echo "bar? $foo!"'
            },
            {
                "use_pty": True,
                "command":
                '/bin/bash -l -c "foo=bar; echo \\"bar? \\$foo!\\""',
            },
        ],
        # shell escaped operations, non-shell
        [
            {
                "command": 'foo=bar; echo "bar? $foo!"',
                "use_shell": False
            },
            {
                "use_pty": True,
                "command": 'foo=bar; echo "bar? $foo!"'
            },
        ],
        # specific directory
        [
            {
                "remote_working_dir": "/tmp",
                "command": "pwd",
                "use_shell": False
            },
            {
                "use_pty": True,
                "command": 'cd "/tmp" && pwd'
            },
        ],
        [
            {
                "remote_working_dir": "/tmp",
                "command": "pwd",
                "use_shell": True
            },
            {
                "use_pty": True,
                "command": '/bin/bash -l -c "cd \\"/tmp\\" && pwd"'
            },
        ],
        # timeout
        [
            {
                "command": "sleep 5",
                "timeout": 1
            },
            {
                "use_pty": True,
                "command": '/bin/bash -l -c "sleep 5"',
                "timeout": 1
            },
        ],
        # edge cases
        # shell, non-tty command
        # in order to combine output streams, `pty` must be off
        [
            {
                "use_pty": False
            },
            {
                "use_pty": True,
                "command": '/bin/bash -l -c "echo hello"'
            },  # !!
        ],
        # if you really need a `pty`, you'll have to handle separate stdout/stderr streams
        [
            {
                "use_pty": False,
                "combine_stderr": False
            },
            {
                "use_pty": False,
                "command": '/bin/bash -l -c "echo hello"'
            },
        ],
    ]
    for given_kwargs, expected_kwargs in cases:
        with patch("threadbare.operations._execute") as mockobj:
            mockobj.return_value = {
                "return_code": lambda: 0,
                "stdout": [],
                "stderr": [],
            }
            operations.remote(**merge(base, given_kwargs))
            mockobj.assert_called_with(**merge(base, expected_kwargs))
コード例 #22
0
ファイル: example.py プロジェクト: elifesciences/threadbare
 def myfn():
     return remote(state.ENV["cmd"], capture=True)
コード例 #23
0
ファイル: example.py プロジェクト: elifesciences/threadbare
 def workerfn():
     with state.settings():
         return remote("exit 1")