mirror of
https://github.com/django/django.git
synced 2025-03-31 19:46:42 +00:00
Prevented staticfiles test from colliding when run in parallel.
This requires that each test never alters files in static directories collected by other tests. The alternative is to add a temporary directory to STATICFILES_DIRS or a new app to INSTALLED_APPS.
This commit is contained in:
parent
326bc0955b
commit
bf2c969eb7
@ -6,8 +6,6 @@ from django.utils._os import upath
|
|||||||
|
|
||||||
TEST_ROOT = os.path.dirname(upath(__file__))
|
TEST_ROOT = os.path.dirname(upath(__file__))
|
||||||
|
|
||||||
TESTFILES_PATH = os.path.join(TEST_ROOT, 'apps', 'test', 'static', 'test')
|
|
||||||
|
|
||||||
TEST_SETTINGS = {
|
TEST_SETTINGS = {
|
||||||
'DEBUG': True,
|
'DEBUG': True,
|
||||||
'MEDIA_URL': '/media/',
|
'MEDIA_URL': '/media/',
|
||||||
|
@ -3,6 +3,7 @@ from __future__ import unicode_literals
|
|||||||
import codecs
|
import codecs
|
||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
|
import tempfile
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
@ -11,6 +12,7 @@ from django.contrib.staticfiles.management.commands import collectstatic
|
|||||||
from django.core.exceptions import ImproperlyConfigured
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
from django.core.management import call_command
|
from django.core.management import call_command
|
||||||
from django.test import override_settings
|
from django.test import override_settings
|
||||||
|
from django.test.utils import extend_sys_path
|
||||||
from django.utils import six
|
from django.utils import six
|
||||||
from django.utils._os import symlinks_supported
|
from django.utils._os import symlinks_supported
|
||||||
from django.utils.encoding import force_text
|
from django.utils.encoding import force_text
|
||||||
@ -197,31 +199,45 @@ class TestCollectionFilesOverride(CollectionTestCase):
|
|||||||
Test overriding duplicated files by ``collectstatic`` management command.
|
Test overriding duplicated files by ``collectstatic`` management command.
|
||||||
Check for proper handling of apps order in installed apps even if file modification
|
Check for proper handling of apps order in installed apps even if file modification
|
||||||
dates are in different order:
|
dates are in different order:
|
||||||
'staticfiles_tests.apps.test',
|
'staticfiles_test_app',
|
||||||
'staticfiles_tests.apps.no_label',
|
'staticfiles_tests.apps.no_label',
|
||||||
"""
|
"""
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.orig_path = os.path.join(TEST_ROOT, 'apps', 'no_label', 'static', 'file2.txt')
|
self.temp_dir = tempfile.mkdtemp()
|
||||||
|
self.addCleanup(shutil.rmtree, self.temp_dir)
|
||||||
|
|
||||||
# get modification and access times for no_label/static/file2.txt
|
# get modification and access times for no_label/static/file2.txt
|
||||||
|
self.orig_path = os.path.join(TEST_ROOT, 'apps', 'no_label', 'static', 'file2.txt')
|
||||||
self.orig_mtime = os.path.getmtime(self.orig_path)
|
self.orig_mtime = os.path.getmtime(self.orig_path)
|
||||||
self.orig_atime = os.path.getatime(self.orig_path)
|
self.orig_atime = os.path.getatime(self.orig_path)
|
||||||
|
|
||||||
# prepare duplicate of file2.txt from no_label app
|
# prepare duplicate of file2.txt from a temporary app
|
||||||
# this file will have modification time older than no_label/static/file2.txt
|
# this file will have modification time older than no_label/static/file2.txt
|
||||||
# anyway it should be taken to STATIC_ROOT because 'test' app is before
|
# anyway it should be taken to STATIC_ROOT because the temporary app is before
|
||||||
# 'no_label' app in installed apps
|
# 'no_label' app in installed apps
|
||||||
self.testfile_path = os.path.join(TEST_ROOT, 'apps', 'test', 'static', 'file2.txt')
|
self.temp_app_path = os.path.join(self.temp_dir, 'staticfiles_test_app')
|
||||||
|
self.testfile_path = os.path.join(self.temp_app_path, 'static', 'file2.txt')
|
||||||
|
|
||||||
|
os.makedirs(self.temp_app_path)
|
||||||
|
with open(os.path.join(self.temp_app_path, '__init__.py'), 'w+'):
|
||||||
|
pass
|
||||||
|
|
||||||
|
os.makedirs(os.path.dirname(self.testfile_path))
|
||||||
with open(self.testfile_path, 'w+') as f:
|
with open(self.testfile_path, 'w+') as f:
|
||||||
f.write('duplicate of file2.txt')
|
f.write('duplicate of file2.txt')
|
||||||
|
|
||||||
os.utime(self.testfile_path, (self.orig_atime - 1, self.orig_mtime - 1))
|
os.utime(self.testfile_path, (self.orig_atime - 1, self.orig_mtime - 1))
|
||||||
|
|
||||||
|
self.settings_with_test_app = self.modify_settings(
|
||||||
|
INSTALLED_APPS={'prepend': 'staticfiles_test_app'})
|
||||||
|
with extend_sys_path(self.temp_dir):
|
||||||
|
self.settings_with_test_app.enable()
|
||||||
|
|
||||||
super(TestCollectionFilesOverride, self).setUp()
|
super(TestCollectionFilesOverride, self).setUp()
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
if os.path.exists(self.testfile_path):
|
|
||||||
os.unlink(self.testfile_path)
|
|
||||||
# set back original modification time
|
|
||||||
os.utime(self.orig_path, (self.orig_atime, self.orig_mtime))
|
|
||||||
super(TestCollectionFilesOverride, self).tearDown()
|
super(TestCollectionFilesOverride, self).tearDown()
|
||||||
|
self.settings_with_test_app.disable()
|
||||||
|
|
||||||
def test_ordering_override(self):
|
def test_ordering_override(self):
|
||||||
"""
|
"""
|
||||||
@ -234,22 +250,11 @@ class TestCollectionFilesOverride(CollectionTestCase):
|
|||||||
|
|
||||||
self.assertFileContains('file2.txt', 'duplicate of file2.txt')
|
self.assertFileContains('file2.txt', 'duplicate of file2.txt')
|
||||||
|
|
||||||
# and now change modification time of no_label/static/file2.txt
|
|
||||||
# test app is first in installed apps so file2.txt should remain unmodified
|
|
||||||
mtime = os.path.getmtime(self.testfile_path)
|
|
||||||
atime = os.path.getatime(self.testfile_path)
|
|
||||||
os.utime(self.orig_path, (mtime + 1, atime + 1))
|
|
||||||
|
|
||||||
# run collectstatic again
|
|
||||||
self.run_collectstatic()
|
|
||||||
|
|
||||||
self.assertFileContains('file2.txt', 'duplicate of file2.txt')
|
|
||||||
|
|
||||||
|
|
||||||
# The collectstatic test suite already has conflicting files since both
|
# The collectstatic test suite already has conflicting files since both
|
||||||
# project/test/file.txt and apps/test/static/test/file.txt are collected. To
|
# project/test/file.txt and apps/test/static/test/file.txt are collected. To
|
||||||
# properly test for the warning not happening unless we tell it to explicitly,
|
# properly test for the warning not happening unless we tell it to explicitly,
|
||||||
# we only include static files from the default finders.
|
# we remove the project directory and will add back a conflicting file later.
|
||||||
@override_settings(STATICFILES_DIRS=[])
|
@override_settings(STATICFILES_DIRS=[])
|
||||||
class TestCollectionOverwriteWarning(CollectionTestCase):
|
class TestCollectionOverwriteWarning(CollectionTestCase):
|
||||||
"""
|
"""
|
||||||
@ -268,41 +273,37 @@ class TestCollectionOverwriteWarning(CollectionTestCase):
|
|||||||
"""
|
"""
|
||||||
out = six.StringIO()
|
out = six.StringIO()
|
||||||
call_command('collectstatic', interactive=False, verbosity=3, stdout=out, **kwargs)
|
call_command('collectstatic', interactive=False, verbosity=3, stdout=out, **kwargs)
|
||||||
out.seek(0)
|
return force_text(out.getvalue())
|
||||||
return out.read()
|
|
||||||
|
|
||||||
def test_no_warning(self):
|
def test_no_warning(self):
|
||||||
"""
|
"""
|
||||||
There isn't a warning if there isn't a duplicate destination.
|
There isn't a warning if there isn't a duplicate destination.
|
||||||
"""
|
"""
|
||||||
output = self._collectstatic_output(clear=True)
|
output = self._collectstatic_output(clear=True)
|
||||||
self.assertNotIn(self.warning_string, force_text(output))
|
self.assertNotIn(self.warning_string, output)
|
||||||
|
|
||||||
def test_warning(self):
|
def test_warning(self):
|
||||||
"""
|
"""
|
||||||
There is a warning when there are duplicate destinations.
|
There is a warning when there are duplicate destinations.
|
||||||
"""
|
"""
|
||||||
# Create new file in the no_label app that also exists in the test app.
|
static_dir = tempfile.mkdtemp()
|
||||||
test_dir = os.path.join(TEST_ROOT, 'apps', 'no_label', 'static', 'test')
|
self.addCleanup(shutil.rmtree, static_dir)
|
||||||
if not os.path.exists(test_dir):
|
|
||||||
os.mkdir(test_dir)
|
|
||||||
|
|
||||||
try:
|
duplicate = os.path.join(static_dir, 'test', 'file.txt')
|
||||||
duplicate_path = os.path.join(test_dir, 'file.txt')
|
os.mkdir(os.path.dirname(duplicate))
|
||||||
with open(duplicate_path, 'w+') as f:
|
with open(duplicate, 'w+') as f:
|
||||||
f.write('duplicate of file.txt')
|
f.write('duplicate of file.txt')
|
||||||
|
|
||||||
|
with self.settings(STATICFILES_DIRS=[static_dir]):
|
||||||
output = self._collectstatic_output(clear=True)
|
output = self._collectstatic_output(clear=True)
|
||||||
self.assertIn(self.warning_string, force_text(output))
|
self.assertIn(self.warning_string, output)
|
||||||
finally:
|
|
||||||
if os.path.exists(duplicate_path):
|
|
||||||
os.unlink(duplicate_path)
|
|
||||||
|
|
||||||
if os.path.exists(test_dir):
|
os.remove(duplicate)
|
||||||
os.rmdir(test_dir)
|
|
||||||
|
|
||||||
# Make sure the warning went away again.
|
# Make sure the warning went away again.
|
||||||
output = self._collectstatic_output(clear=True)
|
with self.settings(STATICFILES_DIRS=[static_dir]):
|
||||||
self.assertNotIn(self.warning_string, force_text(output))
|
output = self._collectstatic_output(clear=True)
|
||||||
|
self.assertNotIn(self.warning_string, output)
|
||||||
|
|
||||||
|
|
||||||
@override_settings(STATICFILES_STORAGE='staticfiles_tests.storage.DummyStorage')
|
@override_settings(STATICFILES_STORAGE='staticfiles_tests.storage.DummyStorage')
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import shutil
|
||||||
import sys
|
import sys
|
||||||
|
import tempfile
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
@ -18,7 +20,7 @@ from django.utils.encoding import force_text
|
|||||||
from .cases import (
|
from .cases import (
|
||||||
BaseCollectionTestCase, BaseStaticFilesTestCase, StaticFilesTestCase,
|
BaseCollectionTestCase, BaseStaticFilesTestCase, StaticFilesTestCase,
|
||||||
)
|
)
|
||||||
from .settings import TEST_ROOT, TEST_SETTINGS, TESTFILES_PATH
|
from .settings import TEST_ROOT, TEST_SETTINGS
|
||||||
|
|
||||||
|
|
||||||
def hashed_file_path(test, path):
|
def hashed_file_path(test, path):
|
||||||
@ -252,15 +254,25 @@ class TestCollectionManifestStorage(TestHashedFiles, BaseCollectionTestCase,
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestCollectionManifestStorage, self).setUp()
|
super(TestCollectionManifestStorage, self).setUp()
|
||||||
|
|
||||||
self._clear_filename = os.path.join(TESTFILES_PATH, 'cleared.txt')
|
temp_dir = tempfile.mkdtemp()
|
||||||
|
os.makedirs(os.path.join(temp_dir, 'test'))
|
||||||
|
self._clear_filename = os.path.join(temp_dir, 'test', 'cleared.txt')
|
||||||
with open(self._clear_filename, 'w') as f:
|
with open(self._clear_filename, 'w') as f:
|
||||||
f.write('to be deleted in one test')
|
f.write('to be deleted in one test')
|
||||||
|
|
||||||
|
self.patched_settings = self.settings(
|
||||||
|
STATICFILES_DIRS=settings.STATICFILES_DIRS + [temp_dir])
|
||||||
|
self.patched_settings.enable()
|
||||||
|
self.addCleanup(shutil.rmtree, six.text_type(temp_dir))
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
super(TestCollectionManifestStorage, self).tearDown()
|
self.patched_settings.disable()
|
||||||
|
|
||||||
if os.path.exists(self._clear_filename):
|
if os.path.exists(self._clear_filename):
|
||||||
os.unlink(self._clear_filename)
|
os.unlink(self._clear_filename)
|
||||||
|
|
||||||
|
super(TestCollectionManifestStorage, self).tearDown()
|
||||||
|
|
||||||
def test_manifest_exists(self):
|
def test_manifest_exists(self):
|
||||||
filename = storage.staticfiles_storage.manifest_name
|
filename = storage.staticfiles_storage.manifest_name
|
||||||
path = storage.staticfiles_storage.path(filename)
|
path = storage.staticfiles_storage.path(filename)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user