def test_has_attr_fail(self): class Config(object): color = 'red' widget = Fake("widget").expects("configure")\ .with_args(arg.has_attr(size=12)) widget.configure(Config())
def test_has_attr_fail_wrong_value(self): class Config(object): color = 'red' widget = Fake("widget").expects("configure")\ .with_args(arg.has_attr(color="green")) widget.configure(Config())
def test_connect_does_not_prompt_password_when_ssh_raises_channel_exception(self): def raise_channel_exception_once(*args, **kwargs): if raise_channel_exception_once.should_raise_channel_exception: raise_channel_exception_once.should_raise_channel_exception = False raise ssh.ChannelException(2, 'Connect failed') raise_channel_exception_once.should_raise_channel_exception = True def generate_fake_client(): fake_client = Fake('SSHClient', allows_any_call=True, expect_call=True) fake_client.provides('connect').calls(raise_channel_exception_once) return fake_client fake_ssh = Fake('ssh', allows_any_call=True) fake_ssh.provides('SSHClient').calls(generate_fake_client) # We need the real exceptions here to preserve the inheritence structure fake_ssh.SSHException = ssh.SSHException fake_ssh.ChannelException = ssh.ChannelException patched_connect = patch_object('fabric.network', 'ssh', fake_ssh) patched_password = patch_object('fabric.network', 'prompt_for_password', Fake('prompt_for_password', callable = True).times_called(0)) try: connect('user', 'localhost', 22, HostConnectionCache()) finally: # Restore ssh patched_connect.restore() patched_password.restore()
def test_expectations_with_multiple_return_values(self): db = Fake("db").expects("get_id").returns(1).expects("set_id").next_call(for_method="get_id").returns(2) eq_(db.get_id(), 1) eq_(db.set_id(), None) eq_(db.get_id(), 2) fudge.verify()
def test_settings_read_attribute_as_int(): clear_expectations() fake_config = Fake("config") fake_config.expects("get").with_args("name", "setting").returns("10") ss = SettingsSection(None, "name", fake_config) assert ss.as_int("setting") == 10
def test_too_many_calls(self): db = Fake("db")\ .remember_order()\ .expects("get_id").returns(1)\ .expects("set_id") eq_(db.get_id(), 1) eq_(db.set_id(), None) # extra : eq_(db.get_id(), 1)
def test_returns(self): db = Fake("db")\ .provides("get_id").returns(1)\ .provides("set_id")\ .next_call(for_method="get_id").returns(2) # print [c.return_val for c in db._declared_calls["get_id"]._calls] eq_(db.get_id(), 1) eq_(db.set_id(), None) eq_(db.get_id(), 2)
def test_contains_list(self): db = Fake("db").expects("execute_statements").with_args( arg.contains("select * from foo")) db.execute_statements([ "update foo", "select * from foo", "drop table foo" ]) fudge.verify()
def test_chained_fakes_honor_order(self): Thing = Fake("thing").remember_order().expects("__init__") holder = Thing.expects("get_holder").returns_fake() holder = holder.expects("init") thing = Thing() holder = thing.get_holder() # missing thing.init() fudge.verify()
def test_has_attr_ok(self): class Config(object): size = 12 color = 'red' weight = 'heavy' widget = Fake("widget").expects("configure")\ .with_args(arg.has_attr(size=12,color='red')) widget.configure(Config())
def test_repr_shortens_long_values(self): fake = Fake("widget").provides("set_bits").with_args( "12345678910111213141516171819202122232425262728293031" ) try: fake.set_bits() except AssertionError, exc: eq_(str(exc), "fake:widget.set_bits('123456789101112131415161718192021222324252627...') " "was called unexpectedly with args ()")
def test_multiple_returns_affect_order(self): db = Fake("db")\ .remember_order()\ .expects("get_id").returns(1)\ .expects("set_id")\ .next_call(for_method="get_id").returns(2) eq_(db.get_id(), 1) eq_(db.set_id(), None) eq_(db.get_id(), 2) fudge.verify()
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_settings_read_attribute_with_no_section_returns_none(): clear_expectations() fake_config = Fake("config") fake_config.expects("get").with_args("name", "setting_true_1").raises(NoSectionError("name")) fake_config.next_call("get").with_args("name", "setting_true_2").raises(NoOptionError("name", "setting_true_2")) ss = SettingsSection(None, "name", fake_config) assert not ss.as_bool("setting_true_1") assert not ss.as_bool("setting_true_2")
def test_controller_cache_is_server_cache(): clear_expectations() clear() fake_server = Fake('server') fake_server.cache = "cache" controller = Controller() controller.server = fake_server assert controller.cache == "cache"
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()
def test_kwarg_diffs_are_not_shortened(self): fake = Fake("widget").provides("set_bits").with_args( newbits="12345678910111213141516171819202122232425262728293031" ) try: # this should not be shortened but the above arg spec should: fake.set_bits(newbits="99999999999999999999999999999999999999999999999999999999") except AssertionError, exc: eq_(str(exc), "fake:widget.set_bits(newbits='123456789101112131415161718192021222324252627...') " "was called unexpectedly with args " "(newbits='99999999999999999999999999999999999999999999999999999999')")
def test_healthcheck_action_returns_working_if_no_text_in_config(): clear_expectations() clear() settings_health_check.Ion = Fake('Ion') settings_health_check.Ion.healthcheck_text = None fake_server_health_check = Fake('server') fake_server_health_check.expects('test_connection').returns(True) controller = Controller() controller.server = fake_server_health_check assert controller.healthcheck() == "WORKING"
def test_wrapped_column_has_sort_url(): meta = Fake().has_attr(order_by="nu") table = Fake().has_attr(_meta=meta) column_a = Fake().has_attr(name="nu") column_b = Fake().has_attr(name="xi") # mock out url building, to avoid awakening django. table.provides("get_url").calls(lambda order_by: ["omicron", order_by]) wrapped_column_a = WrappedColumn(table, column_a) wrapped_column_b = WrappedColumn(table, column_b) assert wrapped_column_a.sort_url == ["omicron", "-nu"] assert wrapped_column_b.sort_url == ["omicron", "xi"]
def test_healthcheck_action(): clear_expectations() clear() settings_health_check.Ion = Fake('Ion') settings_health_check.Ion.healthcheck_text = "CUSTOMTEXT" fake_server_health_check = Fake('server') fake_server_health_check.expects('test_connection').returns(True) controller = Controller() controller.server = fake_server_health_check assert controller.healthcheck() == "CUSTOMTEXT"
def test_render_template_uses_all_server_template_filters(): clear_expectations() clear() fake_server = Fake('server') fake_server.template_path = "template_path" fake_server.template_filters = {"some":lambda x: "y"} controller = Controller() controller.server = fake_server controller.server.apps = [] result = controller.render_template("template_file") assert result == "expected"
def test_healthcheck_action_fails_if_database_not_found(): clear_expectations() clear() settings_health_check.Ion = Fake('Ion') settings_health_check.Ion.healthcheck_text = None fake_server_health_check = Fake('server') controller = Controller() controller.server = fake_server_health_check fake_server_health_check.expects('test_connection').returns(False) fake_server_health_check.test_connection_error = ValueError('Fake error') try: controller.healthcheck() except RuntimeError, err: assert str(err) == "The connection to the database failed with error: Fake error" return
def test_wrapped_column_is_sorted_via_table(): meta = Fake().has_attr(order_by="kappa") table = Fake().has_attr(_meta=meta) column_a = Fake().has_attr(name="kappa") column_b = Fake().has_attr(name="mu") wrapped_column_a = WrappedColumn(table, column_a) # sorted wrapped_column_b = WrappedColumn(table, column_b) # unsorted assert wrapped_column_a.is_sorted == True assert wrapped_column_b.is_sorted == False assert wrapped_column_a.sort_direction == "asc" assert wrapped_column_b.sort_direction == None meta.has_attr(order_by="-mu") assert wrapped_column_a.is_sorted == False assert wrapped_column_b.is_sorted == True assert wrapped_column_a.sort_direction == None assert wrapped_column_b.sort_direction == "desc"
def test_settings_read_attribute_as_bool(): clear_expectations() fake_config = Fake("config") fake_config.expects("get").with_args("name", "setting_true_1").returns("True") fake_config.next_call("get").with_args("name", "setting_true_2").returns("true") fake_config.next_call("get").with_args("name", "setting_false_1").returns("False") fake_config.next_call("get").with_args("name", "setting_false_2").returns("false") ss = SettingsSection(None, "name", fake_config) assert ss.as_bool("setting_true_1") assert ss.as_bool("setting_true_2") assert not ss.as_bool("setting_false_1") assert not ss.as_bool("setting_false_2")
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, StringTypes): 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)
def table(self): return Fake('Table').has_attr(prefixed_page_field='page', prefixed_per_page_field='per_page', prefixed_order_by_field='sort')
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())
def test_passes_fail(self): counter = Fake("counter").expects("set_name").with_args(arg.isinstance(str)) counter.set_name(25)
def test_passes_fail(self): def is_str(v): return isinstance(v,str) counter = Fake("counter").expects("set_name").with_args(arg.passes_test(is_str)) counter.set_name(25)
def test_endswith_ok(self): db = Fake("db").expects("execute").with_args( arg.endswith("values (1,2,3,4)")) db.execute("insert into foo values (1,2,3,4)")
def test_calls_task_function_objects(self): """ should execute the passed-in function object """ execute(Fake(callable=True, expect_call=True))
def test_expects_call_shortcut_ok(self): remove = Fake("os.remove").expects_call() remove() fudge.verify() assert isinstance(remove, Fake)
class MyTask(Task): run = Fake(callable=True, expect_call=True)
class TestSSHConfig(FabricTest): def env_setup(self): super(TestSSHConfig, self).env_setup() env.use_ssh_config = True env.ssh_config_path = support("ssh_config") # Undo the changes FabricTest makes to env for server support env.user = env.local_user env.port = env.default_port def test_global_user_with_default_env(self): """ Global User should override default env.user """ eq_(normalize("localhost")[0], "satan") def test_global_user_with_nondefault_env(self): """ Global User should NOT override nondefault env.user """ with settings(user="******"): eq_(normalize("localhost")[0], "foo") def test_specific_user_with_default_env(self): """ Host-specific User should override default env.user """ eq_(normalize("myhost")[0], "neighbor") def test_user_vs_host_string_value(self): """ SSH-config derived user should NOT override host-string user value """ eq_(normalize("myuser@localhost")[0], "myuser") eq_(normalize("myuser@myhost")[0], "myuser") def test_global_port_with_default_env(self): """ Global Port should override default env.port """ eq_(normalize("localhost")[2], "666") def test_global_port_with_nondefault_env(self): """ Global Port should NOT override nondefault env.port """ with settings(port="777", use_ssh_config=False): eq_(normalize("localhost")[2], "777") def test_specific_port_with_default_env(self): """ Host-specific Port should override default env.port """ eq_(normalize("myhost")[2], "664") def test_port_vs_host_string_value(self): """ SSH-config derived port should NOT override host-string port value """ eq_(normalize("localhost:123")[2], "123") eq_(normalize("myhost:123")[2], "123") def test_hostname_alias(self): """ Hostname setting overrides host string's host value """ eq_(normalize("localhost")[1], "localhost") eq_(normalize("myalias")[1], "otherhost") @with_patched_object(utils, 'warn', Fake('warn', callable=True, expect_call=True)) def test_warns_with_bad_config_file_path(self): # use_ssh_config is already set in our env_setup() with settings(hide('everything'), ssh_config_path="nope_bad_lol"): normalize('foo') @server() def test_real_connection(self): """ Test-server connection using ssh_config values """ with settings( hide('everything'), ssh_config_path=support("testserver_ssh_config"), host_string='testserver', ): ok_(run("ls /simple").succeeded)
def generate_fake_client(): fake_client = Fake('SSHClient', allows_any_call=True, expect_call=True) fake_client.provides('connect').calls(raise_channel_exception_once) return fake_client
def table(self): return Fake("Table").has_attr( prefixed_page_field="page", prefixed_per_page_field="per_page", prefixed_order_by_field="sort", )
def test_datecolumn_formats_dates(): date = datetime.date(2010, 1, 1) cell = Fake().has_attr(value=date) column = DateColumn(format="D d M Y") assert column.render(cell) == "Fri 01 Jan 2010"
def test_startswith_ok_uni(self): db = Fake("db").expects("execute").with_args( arg.startswith(u"Ivan_Krsti\u0107")) db.execute(u"Ivan_Krsti\u0107(); foo();")
def test_contains_fail(self): db = Fake("db").expects("execute").with_args(arg.contains("table foo")) db.execute("select into table notyourmama;") fudge.verify()
def test_datecolumn_defaults_to_DATE_FORMAT(): date = datetime.date(2010, 1, 1) cell = Fake().has_attr(value=date) column = DateColumn() assert column.render(cell) == "2010-01-01"
def test_endswith_ok_uni(self): db = Fake("db").expects("execute").with_args( arg.endswith(u"Ivan Krsti\u0107")) db.execute(u"select Ivan Krsti\u0107")
def faketable(): yield (Fake("Table").has_attr(prefixed_page_field="page", prefixed_per_page_field="per_page", prefixed_order_by_field="sort"))
def table(): yield (Fake('Table').has_attr(prefixed_page_field='page', prefixed_per_page_field='per_page', prefixed_order_by_field='sort'))
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())
def test_passes(self): counter = Fake("counter").expects("increment").with_args(arg.isinstance(int)) counter.increment(25)
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))
def test_passes_fail(self): counter = Fake("counter").expects("set_name").with_args( arg.isinstance(str)) counter.set_name(25)
def test_contains_str(self): db = Fake("db").expects("execute").with_args(arg.contains("table foo")) db.execute("select into table foo;") db.execute("select * from table foo where bar = 1") fudge.verify()
def test_passes(self): counter = Fake("counter").expects("increment").with_args( arg.isinstance(int)) counter.increment(25)
class MyTask(Task): name = "mytask" run = Fake(callable=True, expect_call=True)
def save(self): self.__class__.index.register(self) self.__node__ = Fake('__node__').has_attr(id=self._id) return self
def test_startswith_fail(self): db = Fake("db").expects("execute").with_args( arg.startswith("insert into")) db.execute("select from")
def test_multiple_expects_on_chained_fakes_ok(self): db = Fake("db").expects("insert").returns_fake().expects("insert")
def test_provides_call_shortcut(self): remove = Fake("os.remove").is_callable() remove() assert isinstance(remove, Fake)
def test_contains_list(self): db = Fake("db").expects("execute_statements").with_args( arg.contains("select * from foo")) db.execute_statements( ["update foo", "select * from foo", "drop table foo"]) fudge.verify()
def test_too_many_args(self): db = Fake("db").expects("execute").with_args(bind={'one':1}) db.execute("select foozilate()", bind={'one':1}) # unexpected statement arg
def test_too_many_args(self): db = Fake("db").expects("execute").with_args(bind={'one': 1}) db.execute("select foozilate()", bind={'one': 1}) # unexpected statement arg
def test_multiple_provides_on_chained_fakes_ok(self): db = Fake("db").provides("insert").returns_fake().provides("insert")
def test_any_value(self): db = Fake("db").expects("execute").with_args(arg.any()) db.execute("delete from foo where 1")