def test_force_returns_new_value(self): fun = CB(retvalue=1) cc = CachedCall('key', fun) cc() fun.retvalue = 2 self.assertEqual(2, cc.force())
def test_force_updates_cached_value(self): fun = CB(retvalue=1) cc = CachedCall('key', fun) cc() fun.retvalue = 2 cc.force() self.assertEqual(2, cc())
def test_multiple_callables_get_called(self): bgwork = WorkQueue() cb1 = CB() cb2 = CB() bgwork.defer(cb1) bgwork.defer(cb2) bgwork.perform() self.assertEqual(1, cb1.called) self.assertEqual(1, cb2.called)
def test_two_cachedcalls_with_same_key_use_same_cache(self): fun = CB(retvalue='bar') cc1 = CachedCall('qix', fun) cc2 = CachedCall('qix', fun) self.assertEqual(cc1(), cc2()) self.assertEqual(1, fun.called)
def test_callable_gets_called(self): bgwork = WorkQueue() cb = CB() bgwork.defer(cb) bgwork.perform() self.assertEqual(1, cb.called)
def test_cache_stores_json_correctly(self): fun = CB(retvalue={'foo': ['bar']}) cc = CachedCall('key', fun) self.assertEquals(fun.retvalue, cc()) self.assertEquals(fun.retvalue, cc()) self.assertEquals(1, fun.called)
def test_inprocess_cache_prevents_multiple_calls_multiple_fetch(self): fun = CB() cc = CachedCall('key', fun) self.assertEqual(fun.retvalue, cc()) cache.delete('key') self.assertEqual(fun.retvalue, cc()) self.assertEqual(1, fun.called)
def test_second_call_returns_value_without_calling_underlying_function( self): fun = CB() cc = CachedCall('key', fun) cc() self.assertEquals(fun.retvalue, cc()) self.assertEquals(1, fun.called)
def test_performing_clears_deferred_jobs(self): bgwork = WorkQueue() cb = CB() bgwork.defer(cb) bgwork.perform() bgwork.perform() self.assertEqual(1, cb.called)
def test_skip_decorator(self): def decorator(self): raise Exception fun = CB() cc = CachedCall('key', fun, decorator=decorator) self.assertEquals(fun.retvalue, cc(skip_decorator=True)) self.assertEquals(fun.retvalue, cc.force(skip_decorator=True))
def test_many_multicall(self): f1, f2, f3, f4, f5, f6 = [ CachedCall('key_%s' % n, CB(retvalue=n)) for n in [1, 2, 3, 4, 5, 6] ] self.assertEquals([[1], [2, 3], [4, 5, 6]], CachedCall.many_multicall([f1], [f2, f3], [f4, f5, f6]))
def test_multicall_half_cached_returns_results(self): funs = [CB(retvalue=n) for n in [1, 2, 3, 4, 5]] calls = [CachedCall("key_%s" % e, fun) for e, fun in enumerate(funs)] # Uncached self.assertEquals([1, 2, 3], CachedCall.multicall(calls[:3])) # Half cached self.assertEquals([1, 2, 3, 4, 5], CachedCall.multicall(calls)) self.assertEquals([1] * len(funs), [fun.called for fun in funs])
def test_deferred_bgwork_can_create_more_deferred_bgwork(self): bgwork = WorkQueue() final_cb = CB() @bgwork.defer def create_more_work(): bgwork.defer(final_cb) bgwork.perform() self.assertEqual(1, final_cb.called)
def test_deferred_method_not_called_on_failure(self): dwm = DeferredWorkMiddleware() request = HttpRequest() cb = CB() dwm.process_request(request) request.on_success.defer(cb) dwm.process_response(request, HttpResponse(status=500)) bgwork.perform() self.assertEqual(cb.called, 0)
def test_decorator(self): tocache = {'animals': 2} toadd = {'people': 3} decorator = lambda c: dict(c, **toadd) expected = dict(tocache, **toadd) fun = CB(retvalue=tocache) cc = CachedCall('key', fun, decorator=decorator) self.assertEquals(expected, cc()) # Now test cached. cc = CachedCall('key', fun, decorator=decorator) self.assertEquals(expected, cc()) self.assertEquals(1, fun.called)
def test_exceptions_are_isolated(self): bgwork = WorkQueue() def fail(): raise Exception( 'Just testing bgwork exceptions - not a real error.') after_exception = CB() bgwork.defer(fail) bgwork.defer(after_exception) bgwork.perform() self.assertEqual(1, after_exception.called)
def test_inprocess_cached_prevents_multiple_fetches_in_multicall(self): funs = [CB(retvalue=n) for n in [1, 2, 3, 4, 5]] calls = [CachedCall("key_%s" % e, fun) for e, fun in enumerate(funs)] # Uncached self.assertEquals([1, 2, 3], CachedCall.multicall(calls[:3])) # Remove some of the backing stores cache.delete('key_0') cache.delete('key_1') CachedCall.inprocess_cache.delete('key_2') # 1,2 in-process only, 3 in redis only, 4,5 uncached self.assertEquals([1, 2, 3, 4, 5], CachedCall.multicall(calls)) self.assertEquals([1] * len(funs), [fun.called for fun in funs])
def test_two_cachedcalls_with_different_keys_dont_interfere(self): f1 = CB(retvalue=1) f2 = CB(retvalue=2)
def test_first_call_returns_value(self): fun = CB() cc = CachedCall('key', fun) self.assertEquals(fun.retvalue, cc()) self.assertEquals(1, fun.called)
def test_uncached_call_returns_jsonlike_result(self): fun = CB(retvalue={1: 'bar'}) cc = CachedCall('key', fun) self.assertEquals({'1': 'bar'}, cc()) self.assertEquals({'1': 'bar'}, cc.force())