diff --git a/compressor/storage.py b/compressor/storage.py index 81949a1..00adada 100644 --- a/compressor/storage.py +++ b/compressor/storage.py @@ -1,3 +1,4 @@ +import errno import gzip from os import path from datetime import datetime @@ -41,6 +42,17 @@ class CompressorFileStorage(FileSystemStorage): self.delete(name) return name + def delete(self, name): + """ + Handle deletion race condition present in Django prior to 1.4 + https://code.djangoproject.com/ticket/16108 + """ + try: + super(CompressorFileStorage, self).delete(name) + except OSError, e: + if e.errno != errno.ENOENT: + raise + compressor_file_storage = SimpleLazyObject( lambda: get_storage_class('compressor.storage.CompressorFileStorage')()) diff --git a/tests/tests/storages.py b/tests/tests/storages.py index 7311bae..ae43b85 100644 --- a/tests/tests/storages.py +++ b/tests/tests/storages.py @@ -1,5 +1,8 @@ from __future__ import with_statement +import errno +import os +from django.core.files.base import ContentFile from django.core.files.storage import get_storage_class from django.test import TestCase @@ -31,3 +34,20 @@ class StorageTestCase(TestCase): out = css_tag("/media/CACHE/css/1d4424458f88.css") self.assertEqual(out, render(template, context)) + def test_race_condition_handling(self): + # Hold on to original os.remove + original_remove = os.remove + + def race_remove(path): + "Patched os.remove to raise ENOENT (No such file or directory)" + original_remove(path) + raise OSError(errno.ENOENT, u'Fake ENOENT') + + try: + os.remove = race_remove + self._storage.save('race.file', ContentFile('Fake ENOENT')) + self._storage.delete('race.file') + self.assertFalse(self._storage.exists('race.file')) + finally: + # Restore os.remove + os.remove = original_remove