Пример #1
0
def test_global_nested_state():
    "context managers can be nested for global state"
    assert state.ENV == {}
    with settings(foo="bar"):
        with settings(baz="bop"):
            assert state.ENV == {"foo": "bar", "baz": "bop"}
    assert state.ENV == {}
Пример #2
0
def test_nest_some_settings():
    "demonstrates how settings accumulate"
    with settings(foo="bar"):
        with settings(bar="baz"):
            with settings(baz="bup"):
                LOG.debug(
                    "after three nestings I have the cumulate state: %s" %
                    state.ENV)
                assert state.ENV == {"foo": "bar", "bar": "baz", "baz": "bup"}
Пример #3
0
def test_nested_global_state_is_unlocked_inside_context():
    "`state.ENV` is only writeable within the context manager, including nested context managers"
    assert isinstance(state.ENV, state.FreezeableDict)
    assert state.ENV.read_only
    with settings():
        assert not state.ENV.read_only
        state.ENV["foo"] = "bar"

        with settings():
            assert not state.ENV.read_only

        assert not state.ENV.read_only

    assert state.ENV.read_only
    assert state.ENV == {}
Пример #4
0
def test_stateful__ssh_client():
    "the SSHClient object factory is creating objects (or not) as expected"
    with state.settings():
        with patch("threadbare.operations.SSHClient") as m1:
            operations._ssh_client(
                user="******",
                host_string="localhost",
                key_filename="/foo/bar/baz.pem",
                port=123,
            )
            expected_initialised_with = {
                "user": "******",
                "pkey": "/foo/bar/baz.pem",
                "host": "localhost",
                "port": 123,
                "password": None,
            }
            m1.assert_called_with(**expected_initialised_with)

        with patch("threadbare.operations.SSHClient") as m2:
            operations._ssh_client(
                user="******",
                host_string="localhost",
                key_filename="/foo/bar/baz.pem",
                port=123,
            )
            m2.assert_not_called()
Пример #5
0
def test_set_defaults_settings():
    "global state defaults can be easily set"
    state.set_defaults({"foo": "bar"})
    with state.settings(foo="baz"):
        assert state.ENV == {"foo": "baz"}
    assert state.ENV == {"foo": "bar"}
    assert state.DEPTH == 0
Пример #6
0
def test_execute_many_parallel_with_params():
    "`parallel` will wrap a given function and run it `pool_size` times in parallel, but is ignored when `execute` is given a list of values"

    def fn():
        with settings() as local_env:
            return local_env

    parallel_fn = execute.parallel(fn, pool_size=1)
    param_key = "mykey"
    param_values = [1, 2, 3]

    expected = [
        {
            "parallel": True,
            "abort_on_prompts": True,
            "parent": "environment",
            "mykey": 1,
        },
        {
            "parallel": True,
            "abort_on_prompts": True,
            "parent": "environment",
            "mykey": 2,
        },
        {
            "parallel": True,
            "abort_on_prompts": True,
            "parent": "environment",
            "mykey": 3,
        },
    ]

    with settings(parent="environment"):
        assert expected == execute.execute(parallel_fn, param_key,
                                           param_values)
Пример #7
0
def test_formatted_output_display_running():
    "the 'print running' function obeys formatting rules"
    cases = [
        # command, expected output, more settings
        ("ls -l", "[1.2.3.4] run: ls -l\n", {
            "host_string": "1.2.3.4"
        }),
        ("ls -l", "ls -l\n", {
            "host_string": "1.2.3.4",
            "display_prefix": False
        }),
        ("ls -l", "", {
            "host_string": "1.2.3.4",
            "quiet": True
        }),
        (
            "ls -l",
            "<1.2.3.4> (run) ls -l\n",
            {
                "host_string": "1.2.3.4",
                "line_template": "<{host}> ({pipe}) {line}\n"
            },
        ),
    ]
    for command, expected, settings in cases:
        strbuffer = StringIO()
        with state.settings(**settings):
            operations._print_running(command,
                                      strbuffer,
                                      display_running=True,
                                      **settings)
        assert expected == strbuffer.getvalue()
Пример #8
0
def test_global_deleted_state():
    "original global state is restored if a value is deleted"
    assert state.ENV == {}
    with settings(foo="bar", bar="baz") as env:
        assert state.ENV == env == {"foo": "bar", "bar": "baz"}
        del env["foo"]
        assert state.ENV == env == {"bar": "baz"}
    assert state.ENV == env == {}
Пример #9
0
def test_abort_display_aborts_message():
    "abort message is displayed when `settings.display_aborts` is `True`"
    result = {"foo": "bar"}
    with state.settings(display_aborts=True):
        with patch("threadbare.operations.LOG.error") as mock:
            with pytest.raises(RuntimeError):
                operations.abort(result, "failed to succeed")
            mock.assert_called_once_with("Fatal error: failed to succeed")
Пример #10
0
def test_abort_display_aborts_message_when_quiet():
    "abort message is *not* displayed when `settings.display_aborts` is `True` and `settings.quiet` is also `True`"
    result = {"foo": "bar"}
    with state.settings(display_aborts=True, quiet=True):
        with patch("threadbare.operations.LOG.error") as mock:
            with pytest.raises(RuntimeError):
                operations.abort(result, "failed to succeed")
            mock.assert_not_called()
Пример #11
0
def test_uncontrolled_global_state_modification_2():
    """modifications to global state that happen outside of the context manager's
    control (with ... as ...) are available as expected BUT are reverted on exit"""
    assert isinstance(state.ENV, state.FreezeableDict)
    assert state.ENV == {}
    with settings() as env:
        state.ENV["foo"] = {"bar": "bop"}
        assert env == {"foo": {"bar": "bop"}}
    assert state.ENV == env == {}
Пример #12
0
def test_global_overridden_state():
    "global overrides exist only for the scope of the context manager"
    assert state.ENV == {}
    with settings(foo="baz") as local_env:
        assert local_env == {"foo": "baz"}
    # python vagary that this can still be referenced
    # it should still be as we expect though.
    assert local_env == {}
    assert state.ENV == {}
Пример #13
0
def test_cleanup():
    "'cleanup' functions can be added that will be executed when the context manager is left"
    side_effects = {}

    def cleanup_fn():
        side_effects["?"] = "!"

    with settings():
        state.add_cleanup(cleanup_fn)
    assert side_effects["?"] == "!"
Пример #14
0
def test_nested_scopes_dont_cleanup_parent_scopes():
    "cleanup functions are only called for the scope they were added to"
    side_effects = {}

    def cleanup_fn_1():
        side_effects["1"] = "scope 1 cleaned up"

    def cleanup_fn_2():
        side_effects["2"] = "scope 2 cleaned up"

    with settings():
        state.add_cleanup(cleanup_fn_1)
        with settings():
            state.add_cleanup(cleanup_fn_2)
        assert side_effects == {"2": "scope 2 cleaned up"}
    assert side_effects == {
        "2": "scope 2 cleaned up",
        "1": "scope 1 cleaned up"
    }
Пример #15
0
def test_formatted_output_unicode():
    "unicode output is correctly encoded before being formatted to avoid UnicodeEncodeErrors in python2"
    line_template = "{line}"
    if not common.PY3:
        unicode_point = u"\u258e\u5b57 <-- omg, so fancy"
    else:
        unicode_point = "\u258e\u5b57 <-- omg, so fancy"
    expected_stdout = "▎字 <-- omg, so fancy"
    with state.settings(line_template=line_template):
        result = operations._print_line(StringIO(), unicode_point)
        assert expected_stdout == result
Пример #16
0
def test_parallel_with_prompts_custom__swallow_errors():
    "prompts issued while executing a worker function in parallel with `abort_exception` set returns the custom exception"

    @execute.parallel
    def workerfn():
        return operations.prompt("gimmie")

    with settings(abort_exception=ValueError):
        results = execute.execute(workerfn, raise_unhandled_errors=False)
        expected = "prompted with: gimmie"
        assert expected == str(results[0])
Пример #17
0
def test_rsync_download_command():
    "rsync invocations are generated correctly"
    expected = "rsync --rsh='ssh -i /example/path/id_rsa -p 23 -o StrictHostKeyChecking=no' [email protected]:/remote/bar /local/foo"
    settings = {
        "user": "******",
        "port": 23,
        "host_string": "1.2.3.4",
        "key_filename": "/example/path/id_rsa",
    }
    with state.settings(**settings):
        actual = operations._rsync_download("/remote/bar", "/local/foo")
        assert expected == actual
Пример #18
0
def test_formatted_output():
    "`_print_line`, called by `remote`, can have it's output string customised and still return the original string for processing"
    expected_stdout = "hello, world!"
    expected_buffer = "[35.153.232.132] out: hello, world!"

    line_template = "[{host}] {pipe}: {line}"
    strbuffer = StringIO()
    with state.settings(host_string="35.153.232.132",
                        line_template=line_template):
        result = operations._print_line(strbuffer, "hello, world!")
        assert expected_stdout == result
        assert expected_buffer == strbuffer.getvalue()
Пример #19
0
def test_parallel_with_prompts_custom__raise_errors():
    "prompts issued while executing a worker function in parallel with `abort_exception` return a custom exception"

    @execute.parallel
    def workerfn():
        return operations.prompt("gimmie")

    with settings(abort_exception=ValueError):
        with pytest.raises(ValueError) as e:
            execute.execute(workerfn)
            expected = "prompted with: gimmie"
            assert expected == str(e)
Пример #20
0
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
Пример #21
0
def test_formatted_output_display_prefix():
    "a line of output can have it's prefix stripped"
    cases = [
        # (line template, what is printed to given pipe (stringbuffer, stdout, stderr, etc), what is returned to user)
        ("{line}", "hello, world", "hello, world"),
        ("{host} {pipe}: {line}", "hello, world", "hello, world"),
        ("{host} {pipe}: ", "1.2.3.4 out: ", "hello, world"),
        ("{line} {host}", "hello, world 1.2.3.4", "hello, world"),
        ("{line} {line}", "hello, world hello, world", "hello, world"),
    ]
    for given_template, expected_stdout, expected_return in cases:
        strbuffer = StringIO()
        settings = {
            "host_string": "1.2.3.4",
            "line_template": given_template,
            "display_prefix": False,
        }
        # suppress warning about a missing '{line}' in `line_template` (case 3)
        with patch("threadbare.operations.LOG.warn"):
            with state.settings(**settings):
                result = operations._print_line(strbuffer, "hello, world")
                assert expected_stdout == strbuffer.getvalue()
                assert expected_return == result
Пример #22
0
 def fn():
     with settings() as local_env:
         return "foo" + local_env["mykey"]
Пример #23
0
 def workerfn():
     with settings(abort_on_prompts=False):
         return operations.prompt("gimmie")
Пример #24
0
 def workerfn():
     with settings() as env:
         return env["host_string"] + "host"
Пример #25
0
 def fn():
     with settings() as env:
         return env
Пример #26
0
 def fn():
     with settings() as local_env:
         return local_env
Пример #27
0
 def workerfn():
     with state.settings() as env:
         return remote_file_exists(env["remote_file"], use_sudo=True)
Пример #28
0
 def workerfn():
     with state.settings():
         return remote("exit 1")
Пример #29
0
def test_abort_sysexit():
    "attempt to exit application when `abort_exception` is disabled."
    result = {"foo": "bar"}
    with state.settings(abort_exception=None):
        with pytest.raises(SystemExit):
            operations.abort(result, "failed to succeed")
Пример #30
0
def test_abort_warn_only():
    "return given result if `settings.warn_only` is `True`"
    expected = result = {"foo": "bar"}
    with state.settings(warn_only=True):
        actual = operations.abort(result, "failed to succeed")
        assert expected == actual