def test_invalidate_row_succeeds_on_cache_delete_failure(self): cache = pretend.stub(delete=lambda key: fail(Exception()), ) d = Driver(FormattingKeyMaker({"foo_table": ["bar"]}), cache, DummyLogger()) invalidate_d = d.invalidate_row("foo_table", {}) res = self.successResultOf(invalidate_d) self.assertIs(res, None)
def test_invalidate_row_calls_cache_delete(self): cache = pretend.stub( delete=pretend.call_recorder(lambda key: succeed(None))) d = Driver(FormattingKeyMaker({"foo_table": ["bar", "baz"]}), cache, DummyLogger()) d.invalidate_row("foo_table", {}) self.assertEqual( cache.delete.calls, [pretend.call("bar"), pretend.call("baz")])
def test_invalidate_row_logs_on_cache_delete_failure(self): f = Failure(Exception()) cache = pretend.stub(delete=lambda key: fail(f), ) logger = pretend.stub( msg=lambda s, **kwargs: None, err=pretend.call_recorder(lambda failure, table, key: None)) d = Driver(FormattingKeyMaker({"foo_table": ["bar"]}), cache, logger) d.invalidate_row("foo_table", {}) self.assertEqual(logger.err.calls, [pretend.call(f, table="foo_table", key="bar")])
def test_invalidate_row_waits_for_cache_delete(self): d1 = Deferred() cache = pretend.stub(delete=lambda key: d1, ) d = Driver(FormattingKeyMaker({"foo_table": ["bar"]}), cache, DummyLogger()) invalidate_d = d.invalidate_row("foo_table", {}) self.assertNoResult(invalidate_d) d1.callback(None) res = self.successResultOf(invalidate_d) self.assertIs(res, None)
def test_invalidate_row_logs_nonexistant_counts(self): cache = pretend.stub(delete=lambda key: succeed(False)) logger = pretend.stub( err=None, msg=pretend.call_recorder(lambda *args, **kwargs: None)) d = Driver(FormattingKeyMaker({"foo_table": ["bar"]}), cache, logger) d.invalidate_row("foo_table", {}) self.assertEqual(logger.msg.calls, [ pretend.call( "cache_buster.driver.invalidated_rows", deletes=0, nonexistant=1, failures=0, ) ])
def makeService(options): from twisted.internet import task as cooperator from twisted.internet import reactor from twisted.python import log with open(options['config']) as f: data = f.read() config = yaml.safe_load(data) key_maker = FormattingKeyMaker(data["on_update"]) cache_backend = MultiCache([ MemcachedCache(TCP4ClientEndpoint(reactor, cache, DEFAULT_PORT)) for cache in config['caches'] ]) driver = Driver(key_maker, cache_backend, log) connection = BinLogStreamReader(connection_settings=config['database']) listener = MySQLDatabaseListener(reactor, connection, driver, log) return DatabaseListenerService(cooperator, listener, log)
def test_invalidate_row_returns_deferred(self): d = Driver(FormattingKeyMaker({}), None, DummyLogger()) res = self.successResultOf(d.invalidate_row("foo_table", {})) self.assertIs(res, None)
def test_construct(self): Driver(FormattingKeyMaker({}), None, None)
def test_keys_for_row_multiple_keys(self): key_maker = FormattingKeyMaker({"foo": ["abc", "def"]}) self.assertEqual( list(key_maker.keys_for_row("foo", {})), ["abc", "def"] )
def test_keys_for_row_does_not_stop_on_invalid_format(self): key_maker = FormattingKeyMaker({"foo": ["{user_id}", "bar"]}) self.assertEqual(list(key_maker.keys_for_row("foo", {})), ["bar"])
def test_keys_for_row_invalid_format_key(self): key_maker = FormattingKeyMaker({"foo": ["{user_id}"]}) self.assertEqual(list(key_maker.keys_for_row("foo", {})), [])
def test_keys_for_row_format_pattern(self): key_maker = FormattingKeyMaker({"foo": ["{user_id}"]}) self.assertEqual( list(key_maker.keys_for_row("foo", {"user_id": "bob"})), ["bob"] )
def test_keys_for_row_constant_string(self): key_maker = FormattingKeyMaker({"foo": ["the_big_cache"]}) self.assertEqual( list(key_maker.keys_for_row("foo", {})), ["the_big_cache"] )