示例#1
0
def test_task_will_invoke_provided_class():
    def foo():
        pass

    fake = Fake()
    fake.expects("__init__").with_args(foo)
    fudge.clear_calls()
    fudge.clear_expectations()

    foo = decorators.task(foo, task_class=fake)

    fudge.verify()
    def test_should_set_env_command_to_string_arg(self):
        """
        should set env.command to any string arg, if given
        """
        name = "foo"

        def command():
            self.assert_(env.command, name)

        task = Fake(callable=True, expect_call=True).calls(command)
        with patched_context(fabric.state, 'commands', {name: task}):
            execute(name)
示例#3
0
def test_silent_empty_page_error(table):
    request = build_request("/")
    paginator = (Fake("Paginator")
                 .has_attr(num_pages=987)
                 .expects("page").with_args(987))
    table = (table
             .has_attr(paginator=paginator)
             .expects("paginate").with_args(page=123)
             .raises(EmptyPage))

    RequestConfig(request, paginate={"page": 123,
                                     "silent": True}).configure(table)
示例#4
0
    def test_put_use_sudo(self):
        """
        put(use_sudo=True) works by uploading a the `local_path` to a temporary path and then moving it to a `remote_path`
        """
        fake_run = Fake('_run_command', callable=True,
                        expect_call=True).with_matching_args(
                            fudge_arg.startswith('mv "'),
                            True,
                            True,
                            None,
                        )
        fake_put = Fake('put', callable=True, expect_call=True)

        local_path = self.mkfile('foobar.txt', "baz")
        with hide('everything'):
            with patched_context('fabric.operations', '_run_command',
                                 fake_run):
                with patched_context(SFTPClient, 'put', fake_put):
                    retval = put(local_path, "/", use_sudo=True)
                    # check that the downloaded file has the same name as the one requested
                    assert retval[0].endswith('foobar.txt')
示例#5
0
    def test_silent_page_not_an_integer_error(self):
        table = self.table()
        request = build_request('/')
        paginator = (Fake('Paginator').expects('page').with_args(1))
        table = (table.has_attr(
            paginator=paginator).expects('paginate').with_args(
                page='abc').raises(PageNotAnInteger))

        RequestConfig(request, paginate={
            'page': 'abc',
            'silent': True
        }).configure(table)
示例#6
0
 def test_should_preserve_previous_settings(self):
     """
     should not overwrite env.user, etc after it finishes
     """
     outer = dict(user='******', host='localhost', port='123')
     inner = dict(user='******', host='fabfile.org', port='555')
     def command():
         dict_contains(superset=fabric.state.env, subset=inner)
     with settings(**outer):
         task = Fake(callable=True, expect_call=True).calls(command)
         execute(task, host=from_dict(inner))
         dict_contains(superset=fabric.state.env, subset=outer)
    def test_should_set_env_command_to_name_attr(self):
        """
        should set env.command to TaskSubclass.name if possible
        """
        name = "foo"

        def command():
            self.assertEqual(env.command, name)

        task = (Fake(callable=True,
                     expect_call=True).has_attr(name=name).calls(command))
        execute(task)
示例#8
0
 def test_should_honor_hosts_kwarg(self):
     """
     should use hosts kwarg to set run list
     """
     # Make two full copies of a host list
     hostlist = ['a', 'b', 'c']
     hosts = hostlist[:]
     # Side-effect which asserts the value of env.host_string when it runs
     def host_string():
         eq_(env.host_string, hostlist.pop(0))
     task = Fake(callable=True, expect_call=True).calls(host_string)
     execute(task, hosts=hosts)
示例#9
0
    def test_get_use_sudo_temp_dir(self):
        """
        get(use_sudo=True, temp_dir="/tmp") works by copying to /tmp/..., downloading it and then removing it at the end
        """
        fake_run = Fake('_run_command', callable=True,
                        expect_call=True).with_matching_args(
                            fudge_arg.startswith(
                                'cp -p "/etc/apache2/apache2.conf" "/tmp/'),
                            True,
                            True,
                            None,
                        ).next_call().with_matching_args(
                            fudge_arg.startswith('chown username "/tmp/'),
                            True,
                            True,
                            None,
                        ).next_call().with_matching_args(
                            fudge_arg.startswith('chmod 400 "/tmp/'),
                            True,
                            True,
                            None,
                        ).next_call().with_matching_args(
                            fudge_arg.startswith('rm -f "/tmp/'),
                            True,
                            True,
                            None,
                        )
        fake_get = Fake('get', callable=True, expect_call=True).with_args(
            fudge_arg.startswith('/tmp/'), fudge_arg.any_value())

        with hide('everything'):
            with patched_context('fabric.operations', '_run_command',
                                 fake_run):
                with patched_context(SFTPClient, 'get', fake_get):
                    retval = get('/etc/apache2/apache2.conf',
                                 self.path(),
                                 use_sudo=True,
                                 temp_dir="/tmp")
                    # check that the downloaded file has the same name as the one requested
                    assert retval[0].endswith('apache2.conf')
示例#10
0
 def test_arg_diffs_are_not_shortened(self):
     fake = Fake("widget").provides("set_bits").with_args(
         "12345678910111213141516171819202122232425262728293031")
     try:
         # this should not be shortened but the above arg spec should:
         fake.set_bits(
             "99999999999999999999999999999999999999999999999999999999")
     except AssertionError, exc:
         eq_(
             str(exc),
             "fake:widget.set_bits('123456789101112131415161718192021222324252627...') "
             "was called unexpectedly with args "
             "('99999999999999999999999999999999999999999999999999999999')")
示例#11
0
def fake_function(*args, **kwargs):
    """
    Returns a ``fudge.Fake`` exhibiting function-like attributes.

    Passes in all args/kwargs to the ``fudge.Fake`` constructor. However, if
    ``callable`` or ``expect_call`` kwargs are not given, ``callable`` will be
    set to True by default.
    """
    # Must define __name__ to be compatible with function wrapping mechanisms
    # like @wraps().
    if 'callable' not in kwargs and 'expect_call' not in kwargs:
        kwargs['callable'] = True
    return Fake(*args, **kwargs).has_attr(__name__='fake')
示例#12
0
def test_task_passes_args_to_the_task_class():
    random_vars = ("some text", random.randint(100, 200))

    def foo():
        pass

    fake = Fake()
    fake.expects("__init__").with_args(foo, *random_vars)
    fudge.clear_calls()
    fudge.clear_expectations()

    foo = decorators.task(foo, task_class=fake, *random_vars)
    fudge.verify()
示例#13
0
    def test_silent_empty_page_error(self):
        table = self.table()
        request = build_request('/')
        paginator = (Fake('Paginator').has_attr(
            num_pages=987).expects('page').with_args(987))
        table = (table.has_attr(
            paginator=paginator).expects('paginate').with_args(
                page=123).raises(EmptyPage))

        RequestConfig(request, paginate={
            'page': 123,
            'silent': True
        }).configure(table)
示例#14
0
 def test_env_host_set_when_host_prompt_used(self):
     """
     Ensure env.host is set during host prompting
     """
     copied_host_string = str(env.host_string)
     fake = Fake('raw_input', callable=True).returns(copied_host_string)
     env.host_string = None
     env.host = None
     with settings(hide('everything'), patched_input(fake)):
         run("ls /")
     # Ensure it did set host_string back to old value
     eq_(env.host_string, copied_host_string)
     # Ensure env.host is correct
     eq_(env.host, normalize(copied_host_string)[1])
示例#15
0
    def test_incremental_order_assertion_ok(self):
        # need to drop down a level to bypass expected calls:
        fake = Fake()
        call_order = ExpectedCallOrder(fake)

        exp = ExpectedCall(fake, "one", call_order=call_order)
        call_order.add_expected_call(exp)
        exp()  # call this

        exp = ExpectedCall(fake, "two", call_order=call_order)
        call_order.add_expected_call(exp)

        # two() not called but assertion is not finalized:
        call_order.assert_order_met(finalize=False)
示例#16
0
    def test_get_use_sudo_temp_dir(self):
        """
        get(use_sudo=True, temp_dir="/tmp") works by copying to a /tmp/sha1_hash, downloading it and then removing it at the end
        """
        # the sha1 hash is the unique filename of the file being downloaded. sha1(<filename>)
        fake_run = Fake(
            '_run_command', callable=True, expect_call=True
        ).with_matching_args(
            'cp -p "/etc/apache2/apache2.conf" "/tmp/229a29e5693876645e39de0cb0532e43ad73311a"',
            True,
            True,
            None,
        ).next_call().with_matching_args(
            'chmod 404 "/tmp/229a29e5693876645e39de0cb0532e43ad73311a"',
            True,
            True,
            None,
        ).next_call().with_matching_args(
            'rm -f "/tmp/229a29e5693876645e39de0cb0532e43ad73311a"',
            True,
            True,
            None,
        )
        fake_get = Fake('get', callable=True, expect_call=True).with_args(
            '/tmp/229a29e5693876645e39de0cb0532e43ad73311a',
            fudge_arg.any_value())

        with hide('everything'):
            with patched_context('fabric.operations', '_run_command',
                                 fake_run):
                with patched_context(SFTPClient, 'get', fake_get):
                    retval = get('/etc/apache2/apache2.conf',
                                 self.path(),
                                 use_sudo=True,
                                 temp_dir="/tmp")
                    # check that the downloaded file has the same name as the one requested
                    assert retval[0].endswith('apache2.conf')
示例#17
0
def test_fastprint_calls_puts():
    """
    fastprint() is just an alias to puts()
    """
    text = "Some output"
    fake_puts = Fake('puts', expect_call=True).with_args(text=text,
                                                         show_prefix=False,
                                                         end="",
                                                         flush=True)
    with patched_context(utils, 'puts', fake_puts):
        try:
            fastprint(text)
            verify()
        finally:
            clear_expectations()
示例#18
0
    def test_method_call(self):
        """
        Tests calling a method of the original object through the Proxy.
        """
        expected = 6
        args = 1, 4, 5
        kwargs = {"a": 2, "b": 3}
        self.foo.func = Fake("func").expects_call().returns(
            expected).with_args(*args, **kwargs)

        result = self.proxy.func(*args, **kwargs)

        self.assertEqual(
            result, expected,
            "Call to a function through Proxy returned an unexpected result")
示例#19
0
    def test_only_one_call(self):
        # need to drop down a level to bypass expected calls:
        r = Registry()
        fake = Fake()
        call_order = ExpectedCallOrder(fake)
        r.remember_expected_call_order(call_order)

        exp = ExpectedCall(fake, "one", call_order=call_order)
        call_order.add_expected_call(exp)
        exp()  # call this

        exp = ExpectedCall(fake, "two", call_order=call_order)
        call_order.add_expected_call(exp)

        r.verify()
示例#20
0
    def test_put_use_sudo(self):
        """
        put(use_sudo=True) works by uploading a the `local_path` to a temporary path and then moving it to a `remote_path`
        """
        # the sha1 hash is the unique filename of the file being downloaded. sha1(<filename>)
        fake_run = Fake(
            '_run_command', callable=True,
            expect_call=True).with_matching_args(
                'mv "7c91837ec0b3570264a325df6b7ef949ee22bc56" "/foobar.txt"',
                True,
                True,
                None,
            )
        fake_put = Fake('put', callable=True, expect_call=True).with_args(
            fudge_arg.any_value(), '7c91837ec0b3570264a325df6b7ef949ee22bc56')

        local_path = self.mkfile('foobar.txt', "baz")
        with hide('everything'):
            with patched_context('fabric.operations', '_run_command',
                                 fake_run):
                with patched_context(SFTPClient, 'put', fake_put):
                    retval = put(local_path, "/", use_sudo=True)
                    # check that the downloaded file has the same name as the one requested
                    assert retval[0].endswith('foobar.txt')
示例#21
0
 def test_should_set_all_hosts(self):
     """
     should set env.all_hosts to its derived host list
     """
     hosts = ['a', 'b']
     roledefs = {'r1': ['c', 'd']}
     roles = ['r1']
     exclude_hosts = ['a']
     def command():
         eq_(set(env.all_hosts), set(['b', 'c', 'd']))
     task = Fake(callable=True, expect_call=True).calls(command)
     with settings(hide('everything'), roledefs=roledefs):
         execute(
             task, hosts=hosts, roles=roles, exclude_hosts=exclude_hosts
         )
示例#22
0
 def check_connection_calls(host_strings, num_calls):
     # Clear Fudge call stack
     # Patch connect() with Fake obj set to expect num_calls calls
     patched_connect = patch_object('fabric.network', 'connect',
         Fake('connect', expect_call=True).times_called(num_calls)
     )
     try:
         # Make new cache object
         cache = HostConnectionCache()
         # Connect to all connection strings
         for host_string in host_strings:
             # Obtain connection from cache, potentially calling connect()
             cache[host_string]
     finally:
         # Restore connect()
         patched_connect.restore()
示例#23
0
 def test_connection_cache_deletion(self):
     """
     HostConnectionCache should delete correctly w/ non-full keys
     """
     hcc = HostConnectionCache()
     fake = Fake('connect', callable=True)
     with patched_context('fabric.network', 'connect', fake):
         for host_string in ('hostname', 'user@hostname',
             'user@hostname:222'):
             # Prime
             hcc[host_string]
             # Test
             ok_(host_string in hcc)
             # Delete
             del hcc[host_string]
             # Test
             ok_(host_string not in hcc)
示例#24
0
def password_response(password, times_called=None, silent=True):
    """
    Context manager which patches ``getpass.getpass`` to return ``password``.

    ``password`` may be a single string or an iterable of strings:

    * If single string, given password is returned every time ``getpass`` is
      called.
    * If iterable, iterated over for each call to ``getpass``, after which
      ``getpass`` will error.

    If ``times_called`` is given, it is used to add a ``Fake.times_called``
    clause to the mock object, e.g. ``.times_called(1)``. Specifying
    ``times_called`` alongside an iterable ``password`` list is unsupported
    (see Fudge docs on ``Fake.next_call``).

    If ``silent`` is True, no prompt will be printed to ``sys.stderr``.
    """
    fake = Fake('getpass', callable=True)
    # Assume stringtype or iterable, turn into mutable iterable
    if isinstance(password, six.string_types):
        passwords = [password]
    else:
        passwords = list(password)
    # Optional echoing of prompt to mimic real behavior of getpass
    # NOTE: also echo a newline if the prompt isn't a "passthrough" from the
    # server (as it means the server won't be sending its own newline for us).
    echo = lambda x, y: y.write(x + ("\n" if x != " " else ""))
    # Always return first (only?) password right away
    fake = fake.returns(passwords.pop(0))
    if not silent:
        fake = fake.calls(echo)
    # If we had >1, return those afterwards
    for pw in passwords:
        fake = fake.next_call().returns(pw)
        if not silent:
            fake = fake.calls(echo)
    # Passthrough times_called
    if times_called:
        fake = fake.times_called(times_called)
    return patched_context(getpass, 'getpass', fake)
示例#25
0
 class MyTask(Task):
     name = "mytask"
     run = Fake(callable=True, expect_call=True)
示例#26
0
 class MyTask(Task):
     run = Fake(callable=True, expect_call=True)
示例#27
0
 def test_calls_task_function_objects(self):
     """
     should execute the passed-in function object
     """
     execute(Fake(callable=True, expect_call=True))
示例#28
0
 def test_error_calls_given_func_if_func_not_None(self):
     """
     error(func=callable) => calls callable()
     """
     error('foo', func=Fake(callable=True, expect_call=True))
示例#29
0
class TestErrorHandling(FabricTest):
    dummy_string = 'test1234!'

    @with_patched_object(utils, 'warn',
                         Fake('warn', callable=True, expect_call=True))
    def test_error_warns_if_warn_only_True_and_func_None(self):
        """
        warn_only=True, error(func=None) => calls warn()
        """
        with settings(warn_only=True):
            error('foo')

    @with_patched_object(utils, 'abort',
                         Fake('abort', callable=True, expect_call=True))
    def test_error_aborts_if_warn_only_False_and_func_None(self):
        """
        warn_only=False, error(func=None) => calls abort()
        """
        with settings(warn_only=False):
            error('foo')

    def test_error_calls_given_func_if_func_not_None(self):
        """
        error(func=callable) => calls callable()
        """
        error('foo', func=Fake(callable=True, expect_call=True))

    @mock_streams('stdout')
    @with_patched_object(
        utils, 'abort',
        Fake('abort', callable=True,
             expect_call=True).calls(lambda x: sys.stdout.write(x + "\n")))
    def test_error_includes_stdout_if_given_and_hidden(self):
        """
        error() correctly prints stdout if it was previously hidden
        """
        # Mostly to catch regression bug(s)
        stdout = "this is my stdout"
        with hide('stdout'):
            error("error message", func=utils.abort, stdout=stdout)
        assert_contains(stdout, sys.stdout.getvalue())

    @mock_streams('stdout')
    @with_patched_object(
        utils, 'abort',
        Fake('abort', callable=True,
             expect_call=True).calls(lambda x: sys.stdout.write(x + "\n")))
    @with_patched_object(output, 'exceptions', True)
    @with_patched_object(utils, 'format_exc',
                         Fake('format_exc', callable=True,
                              expect_call=True).returns(dummy_string))
    def test_includes_traceback_if_exceptions_logging_is_on(self):
        """
        error() includes traceback in message if exceptions logging is on
        """
        error("error message", func=utils.abort, stdout=error)
        assert_contains(self.dummy_string, sys.stdout.getvalue())

    @mock_streams('stdout')
    @with_patched_object(
        utils, 'abort',
        Fake('abort', callable=True,
             expect_call=True).calls(lambda x: sys.stdout.write(x + "\n")))
    @with_patched_object(output, 'debug', True)
    @with_patched_object(utils, 'format_exc',
                         Fake('format_exc', callable=True,
                              expect_call=True).returns(dummy_string))
    def test_includes_traceback_if_debug_logging_is_on(self):
        """
        error() includes traceback in message if debug logging is on (backwardis compatibility)
        """
        error("error message", func=utils.abort, stdout=error)
        assert_contains(self.dummy_string, sys.stdout.getvalue())

    @mock_streams('stdout')
    @with_patched_object(
        utils, 'abort',
        Fake('abort', callable=True,
             expect_call=True).calls(lambda x: sys.stdout.write(x + "\n")))
    @with_patched_object(output, 'exceptions', True)
    @with_patched_object(utils, 'format_exc',
                         Fake('format_exc', callable=True,
                              expect_call=True).returns(None))
    def test_doesnt_print_None_when_no_traceback_present(self):
        """
        error() doesn't include None in message if there is no traceback
        """
        error("error message", func=utils.abort, stdout=error)
        assert_not_contains('None', sys.stdout.getvalue())

    @mock_streams('stderr')
    @with_patched_object(
        utils, 'abort',
        Fake('abort', callable=True,
             expect_call=True).calls(lambda x: sys.stderr.write(x + "\n")))
    def test_error_includes_stderr_if_given_and_hidden(self):
        """
        error() correctly prints stderr if it was previously hidden
        """
        # Mostly to catch regression bug(s)
        stderr = "this is my stderr"
        with hide('stderr'):
            error("error message", func=utils.abort, stderr=stderr)
        assert_contains(stderr, sys.stderr.getvalue())

    @mock_streams('stderr')
    def test_warnings_print_magenta_if_colorize_on(self):
        with settings(colorize_errors=True):
            error("oh god", func=utils.warn, stderr="oops")
        # can't use assert_contains as ANSI codes contain regex specialchars
        eq_(magenta("\nWarning: oh god\n\n"), sys.stderr.getvalue())

    @mock_streams('stderr')
    @raises(SystemExit)
    def test_errors_print_red_if_colorize_on(self):
        with settings(colorize_errors=True):
            error("oh god", func=utils.abort, stderr="oops")
        # can't use assert_contains as ANSI codes contain regex specialchars
        eq_(red("\Error: oh god\n\n"), sys.stderr.getvalue())
class TestErrorHandling(FabricTest):
    @with_patched_object(utils, 'warn', Fake('warn', callable=True,
        expect_call=True))
    def test_error_warns_if_warn_only_True_and_func_None(self):
        """
        warn_only=True, error(func=None) => calls warn()
        """
        with settings(warn_only=True):
            error('foo')

    @with_patched_object(utils, 'abort', Fake('abort', callable=True,
        expect_call=True))
    def test_error_aborts_if_warn_only_False_and_func_None(self):
        """
        warn_only=False, error(func=None) => calls abort()
        """
        with settings(warn_only=False):
            error('foo')

    def test_error_calls_given_func_if_func_not_None(self):
        """
        error(func=callable) => calls callable()
        """
        error('foo', func=Fake(callable=True, expect_call=True))

    @mock_streams('stdout')
    @with_patched_object(utils, 'abort', Fake('abort', callable=True,
        expect_call=True).calls(lambda x: sys.stdout.write(x + "\n")))
    def test_error_includes_stdout_if_given_and_hidden(self):
        """
        error() correctly prints stdout if it was previously hidden
        """
        # Mostly to catch regression bug(s)
        stdout = "this is my stdout"
        with hide('stdout'):
            error("error message", func=utils.abort, stdout=stdout)
        assert_contains(stdout, sys.stdout.getvalue())

    @mock_streams('stderr')
    @with_patched_object(utils, 'abort', Fake('abort', callable=True,
        expect_call=True).calls(lambda x: sys.stderr.write(x + "\n")))
    def test_error_includes_stderr_if_given_and_hidden(self):
        """
        error() correctly prints stderr if it was previously hidden
        """
        # Mostly to catch regression bug(s)
        stderr = "this is my stderr"
        with hide('stderr'):
            error("error message", func=utils.abort, stderr=stderr)
        assert_contains(stderr, sys.stderr.getvalue())

    @mock_streams('stderr')
    def test_warnings_print_magenta_if_colorize_on(self):
        with settings(colorize_errors=True):
            error("oh god", func=utils.warn, stderr="oops")
        # can't use assert_contains as ANSI codes contain regex specialchars
        eq_(magenta("\nWarning: oh god\n\n"), sys.stderr.getvalue())

    @mock_streams('stderr')
    @raises(SystemExit)
    def test_errors_print_red_if_colorize_on(self):
        with settings(colorize_errors=True):
            error("oh god", func=utils.abort, stderr="oops")
        # can't use assert_contains as ANSI codes contain regex specialchars
        eq_(red("\Error: oh god\n\n"), sys.stderr.getvalue())