class TestVersionsCache(SharedCacheTests, TestCase): """Test cache functions when multiple versions are defined.""" def setUp(self): """Setup environment for an enabled cache.""" self.cache = SampleCache() self.cache.versions = ['default', 'v2'] self.cache.cache.clear() self.mock_delete = mock.Mock() self.cache.cache.delete = self.mock_delete def test_update_instance_unhandled_model(self): """An error is raised update a model defined as None in the Cache.""" self.cache.bar_v2_serializer = None self.cache.bar_v2_loader = None self.cache.bar_v2_invalidator = None super(TestVersionsCache, self).test_update_instance_unhandled_model() def test_delete_all_versions_two_versions(self): """Delete all cached instances with multiple versions.""" self.cache.delete_all_versions("Model", 86) self.mock_delete.assert_has_calls([ mock.call("drfc_default_Model_86"), mock.call("drfc_v2_Model_86")])
def setUp(self): """Setup environment for an enabled cache.""" self.cache = SampleCache() self.cache.versions = ['default', 'v2'] self.cache.cache.clear() self.mock_delete = mock.Mock() self.cache.cache.delete = self.mock_delete
class TestCacheDisabled(SharedCacheTests, TestCase): """Test cache functions when the instance cache is disabled.""" def setUp(self): """Setup environment for a disabled cache.""" self.cache = SampleCache() def test_cache_is_none(self): """When USE_DRF_INSTANCE_CACHE is False, cache is None.""" self.assertIsNone(self.cache.cache) def test_invalidate_returns_none(self): """When cache is disabled, updating is skipped.""" with self.assertNumQueries(0): invalid = self.cache.update_instance('User', 123) self.assertEqual([], invalid) def test_delete_all_versions(self): """No error when requesting to delete all cached instances.""" self.cache.delete_all_versions("Model", 86)
def setUp(self): """Shared objects for testing.""" self.cache = SampleCache() self.cache.cache.clear()
def setUp(self): """Setup environment for an enabled cache.""" self.cache = SampleCache() self.cache.cache.clear() self.mock_delete = mock.Mock() self.cache.cache.delete = self.mock_delete
class TestCache(SharedCacheTests, TestCase): """Test cache functions when the instance cache is enabled.""" def setUp(self): """Setup environment for an enabled cache.""" self.cache = SampleCache() self.cache.cache.clear() self.mock_delete = mock.Mock() self.cache.cache.delete = self.mock_delete def test_cache_is_available(self): """When USE_DRF_INSTANCE_CACHE is True, cache is available.""" self.assertTrue(self.cache.cache) def test_get_instance_cache_hit(self): """When instance is cached, the database is not queried.""" key = self.cache.key_for('default', 'User', 123) self.assertEqual('drfc_default_User_123', key) data = {'id': 123, 'foo': 'bar'} self.cache.cache.set(key, dumps(data)) with self.assertNumQueries(0): instances = self.cache.get_instances([('User', 123, None)]) expected = {('User', 123): (data, key, None)} self.assertEqual(expected, instances) def test_update_instance_invalidator_only(self): """A model can have no serializer but a defined invalidator.""" user = User.objects.create(username='******') group = Group.objects.create() group.user_set.add(user) invalid = self.cache.update_instance('Group', group.pk) self.assertEqual([('User', user.pk, 'default')], invalid) def test_update_instance_deleted_model(self): """A deleted instance can still invalidate related instances.""" self.assertFalse(User.objects.filter(pk=666).exists()) invalid = self.cache.update_instance('User', 666) self.assertEqual([], invalid) self.mock_delete.assert_called_once_with('drfc_default_User_666') def test_update_instance_cache_string(self): """A invalidator can delete cache entries by name.""" user = User.objects.create(username='******') invalid = self.cache.update_instance('User', user.pk) self.assertEqual([], invalid) self.mock_delete.assert_called_once_with('drfc_user_count') def test_update_instance_no_changes(self): """When the representation is unchanged, updates do not cascade.""" user = User.objects.create(username='******', date_joined=datetime( 2014, 11, 5, 22, 2, 16, 735772, UTC)) key = self.cache.key_for('default', 'User', user.pk) representation = { 'id': user.id, 'username': '******', 'date_joined:DateTime': '1415224936.735772', 'votes:PKList': { 'app': 'sample_poll_app', 'model': 'choice', 'pks': [], }, } self.cache.cache.set(key, dumps(representation)) self.mock_delete.side_effect = Exception('Not Called') invalid = self.cache.update_instance('User', user.pk, user) self.assertEqual([], invalid) def test_update_instance_with_raw_instance(self): """An invalidator loads related PKs with a raw instance.""" # Create user, then delete auto-created cache User.objects.create(username='******') self.cache.cache.clear() self.mock_delete.reset_mock() user = User.objects.get(username='******') with self.assertNumQueries(1): invalid = self.cache.update_instance('User', user.pk, user) self.assertEqual([], invalid) self.mock_delete.assert_called_once_with('drfc_user_count') def test_update_instance_with_loaded_instance(self): """An invalidator skips the database with a loaded instance.""" # Create user, then delete auto-created cache user_pk = User.objects.create(username='******').pk user = self.cache.user_default_loader(user_pk) self.cache.cache.clear() self.mock_delete.reset_mock() with self.assertNumQueries(0): invalid = self.cache.update_instance('User', user_pk, user) self.assertEqual([], invalid) self.mock_delete.assert_called_once_with('drfc_user_count') def test_delete_called_on_immediate_invalidate(self): """An invalidator can ask for immediate invalidation.""" user = User.objects.create(username='******') question = Question.objects.create( question_text='What is your favorite color?', pub_date=datetime(2014, 11, 6, 8, 45, 49, 538232, UTC)) choice = Choice.objects.create(question=question, choice_text="Blue. No, Green!") choice.voters.add(user) invalid = self.cache.choice_default_invalidator(choice) expected = [ ('Question', question.pk, True), ('User', user.pk, False), ] self.assertEqual(expected, invalid) to_update = self.cache.update_instance('Choice', choice.pk) expected_update = [ ('Question', question.pk, 'default'), ('User', user.pk, 'default'), ] self.assertEqual(expected_update, to_update) self.mock_delete.assert_has_calls([ mock.call('drfc_user_count'), mock.call('drfc_default_Question_%s' % question.pk), mock.call('drfc_user_count'), mock.call('drfc_default_Question_%s' % question.pk) ]) self.assertEqual(4, self.mock_delete.call_count) def test_update_instance_cache_miss_update_only(self): """With update_only, cache misses don't update or cascade.""" user = User.objects.create(username='******') question = Question.objects.create( question_text='What is your favorite color?', pub_date=datetime(2014, 11, 6, 8, 45, 49, 538232, UTC)) choice = Choice.objects.create(question=question, choice_text="Blue. No, Green!") choice.voters.add(user) self.cache.cache.clear() to_update = self.cache.update_instance('Choice', choice.pk, update_only=True) self.assertEqual([], to_update) self.mock_delete.assert_has_calls([ mock.call('drfc_user_count'), mock.call('drfc_default_Question_%s' % question.pk), mock.call('drfc_user_count') ]) self.assertEqual(3, self.mock_delete.call_count) def test_delete_all_versions_one_version(self): """Delete all cached instances for a model and ID.""" self.cache.delete_all_versions("Model", 86) self.mock_delete.assert_called_once_with("drfc_default_Model_86")
def setUp(self): """Setup environment for a disabled cache.""" self.cache = SampleCache()
class TestCache(SharedCacheTests, TestCase): """Test cache functions when the instance cache is enabled.""" def setUp(self): """Setup environment for an enabled cache.""" self.cache = SampleCache() self.cache.cache.clear() self.mock_delete = mock.Mock() self.cache.cache.delete = self.mock_delete def test_cache_is_available(self): """When USE_DRF_INSTANCE_CACHE is True, cache is available.""" self.assertTrue(self.cache.cache) def test_get_instance_cache_hit(self): """When instance is cached, the database is not queried.""" key = self.cache.key_for('default', 'User', 123) self.assertEqual('drfc_default_User_123', key) data = {'id': 123, 'foo': 'bar'} self.cache.cache.set(key, dumps(data)) with self.assertNumQueries(0): instances = self.cache.get_instances([('User', 123, None)]) expected = {('User', 123): (data, key, None)} self.assertEqual(expected, instances) def test_update_instance_invalidator_only(self): """A model can have no serializer but a defined invalidator.""" user = User.objects.create(username='******') group = Group.objects.create() group.user_set.add(user) invalid = self.cache.update_instance('Group', group.pk) self.assertEqual([('User', user.pk, 'default')], invalid) def test_update_instance_deleted_model(self): """A deleted instance can still invalidate related instances.""" self.assertFalse(User.objects.filter(pk=666).exists()) invalid = self.cache.update_instance('User', 666) self.assertEqual([], invalid) self.mock_delete.assert_called_once_with('drfc_default_User_666') def test_update_instance_cache_string(self): """A invalidator can delete cache entries by name.""" user = User.objects.create(username='******') invalid = self.cache.update_instance('User', user.pk) self.assertEqual([], invalid) self.mock_delete.assert_called_once_with('drfc_user_count') def test_update_instance_no_changes(self): """When the representation is unchanged, updates do not cascade.""" user = User.objects.create( username='******', date_joined=datetime(2014, 11, 5, 22, 2, 16, 735772, UTC)) key = self.cache.key_for('default', 'User', user.pk) representation = { 'id': user.id, 'username': '******', 'date_joined:DateTime': '1415224936.735772', 'votes:PKList': { 'app': 'sample_poll_app', 'model': 'choice', 'pks': [], }, } self.cache.cache.set(key, dumps(representation)) self.mock_delete.side_effect = Exception('Not Called') invalid = self.cache.update_instance('User', user.pk, user) self.assertEqual([], invalid) def test_update_instance_with_raw_instance(self): """An invalidator loads related PKs with a raw instance.""" # Create user, then delete auto-created cache User.objects.create(username='******') self.cache.cache.clear() self.mock_delete.reset_mock() user = User.objects.get(username='******') with self.assertNumQueries(1): invalid = self.cache.update_instance('User', user.pk, user) self.assertEqual([], invalid) self.mock_delete.assert_called_once_with('drfc_user_count') def test_update_instance_with_loaded_instance(self): """An invalidator skips the database with a loaded instance.""" # Create user, then delete auto-created cache user_pk = User.objects.create(username='******').pk user = self.cache.user_default_loader(user_pk) self.cache.cache.clear() self.mock_delete.reset_mock() with self.assertNumQueries(0): invalid = self.cache.update_instance('User', user_pk, user) self.assertEqual([], invalid) self.mock_delete.assert_called_once_with('drfc_user_count') def test_delete_called_on_immediate_invalidate(self): """An invalidator can ask for immediate invalidation.""" user = User.objects.create(username='******') question = Question.objects.create( question_text='What is your favorite color?', pub_date=datetime(2014, 11, 6, 8, 45, 49, 538232, UTC)) choice = Choice.objects.create( question=question, choice_text="Blue. No, Green!") choice.voters.add(user) invalid = self.cache.choice_default_invalidator(choice) expected = [ ('Question', question.pk, True), ('User', user.pk, False), ] self.assertEqual(expected, invalid) to_update = self.cache.update_instance('Choice', choice.pk) expected_update = [ ('Question', question.pk, 'default'), ('User', user.pk, 'default'), ] self.assertEqual(expected_update, to_update) self.mock_delete.assertEqual('drf_default_question_%s' % question.pk) def test_update_instance_cache_miss_update_only(self): """With update_only, cache misses don't update or cascade.""" user = User.objects.create(username='******') question = Question.objects.create( question_text='What is your favorite color?', pub_date=datetime(2014, 11, 6, 8, 45, 49, 538232, UTC)) choice = Choice.objects.create( question=question, choice_text="Blue. No, Green!") choice.voters.add(user) self.cache.cache.clear() to_update = self.cache.update_instance( 'Choice', choice.pk, update_only=True) self.assertEqual([], to_update) self.mock_delete.assertEqual('drf_default_question_%s' % question.pk) def test_delete_all_versions_one_version(self): """Delete all cached instances for a model and ID.""" self.cache.delete_all_versions("Model", 86) self.mock_delete.assert_called_once_with("drfc_default_Model_86")