Kaydet (Commit) bf2c969e authored tarafından Aymeric Augustin's avatar Aymeric Augustin

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.
üst 326bc095
......@@ -6,8 +6,6 @@ from django.utils._os import upath
TEST_ROOT = os.path.dirname(upath(__file__))
TESTFILES_PATH = os.path.join(TEST_ROOT, 'apps', 'test', 'static', 'test')
TEST_SETTINGS = {
'DEBUG': True,
'MEDIA_URL': '/media/',
......
......@@ -3,6 +3,7 @@ from __future__ import unicode_literals
import codecs
import os
import shutil
import tempfile
import unittest
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.management import call_command
from django.test import override_settings
from django.test.utils import extend_sys_path
from django.utils import six
from django.utils._os import symlinks_supported
from django.utils.encoding import force_text
......@@ -197,31 +199,45 @@ class TestCollectionFilesOverride(CollectionTestCase):
Test overriding duplicated files by ``collectstatic`` management command.
Check for proper handling of apps order in installed apps even if file modification
dates are in different order:
'staticfiles_tests.apps.test',
'staticfiles_test_app',
'staticfiles_tests.apps.no_label',
"""
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
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_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
# 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
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:
f.write('duplicate of file2.txt')
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()
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()
self.settings_with_test_app.disable()
def test_ordering_override(self):
"""
......@@ -234,22 +250,11 @@ class TestCollectionFilesOverride(CollectionTestCase):
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
# 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,
# 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=[])
class TestCollectionOverwriteWarning(CollectionTestCase):
"""
......@@ -268,41 +273,37 @@ class TestCollectionOverwriteWarning(CollectionTestCase):
"""
out = six.StringIO()
call_command('collectstatic', interactive=False, verbosity=3, stdout=out, **kwargs)
out.seek(0)
return out.read()
return force_text(out.getvalue())
def test_no_warning(self):
"""
There isn't a warning if there isn't a duplicate destination.
"""
output = self._collectstatic_output(clear=True)
self.assertNotIn(self.warning_string, force_text(output))
self.assertNotIn(self.warning_string, output)
def test_warning(self):
"""
There is a warning when there are duplicate destinations.
"""
# Create new file in the no_label app that also exists in the test app.
test_dir = os.path.join(TEST_ROOT, 'apps', 'no_label', 'static', 'test')
if not os.path.exists(test_dir):
os.mkdir(test_dir)
static_dir = tempfile.mkdtemp()
self.addCleanup(shutil.rmtree, static_dir)
try:
duplicate_path = os.path.join(test_dir, 'file.txt')
with open(duplicate_path, 'w+') as f:
f.write('duplicate of file.txt')
duplicate = os.path.join(static_dir, 'test', 'file.txt')
os.mkdir(os.path.dirname(duplicate))
with open(duplicate, 'w+') as f:
f.write('duplicate of file.txt')
with self.settings(STATICFILES_DIRS=[static_dir]):
output = self._collectstatic_output(clear=True)
self.assertIn(self.warning_string, force_text(output))
finally:
if os.path.exists(duplicate_path):
os.unlink(duplicate_path)
self.assertIn(self.warning_string, output)
if os.path.exists(test_dir):
os.rmdir(test_dir)
os.remove(duplicate)
# Make sure the warning went away again.
output = self._collectstatic_output(clear=True)
self.assertNotIn(self.warning_string, force_text(output))
with self.settings(STATICFILES_DIRS=[static_dir]):
output = self._collectstatic_output(clear=True)
self.assertNotIn(self.warning_string, output)
@override_settings(STATICFILES_STORAGE='staticfiles_tests.storage.DummyStorage')
......
from __future__ import unicode_literals
import os
import shutil
import sys
import tempfile
import unittest
from django.conf import settings
......@@ -18,7 +20,7 @@ from django.utils.encoding import force_text
from .cases import (
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):
......@@ -252,15 +254,25 @@ class TestCollectionManifestStorage(TestHashedFiles, BaseCollectionTestCase,
def setUp(self):
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:
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):
super(TestCollectionManifestStorage, self).tearDown()
self.patched_settings.disable()
if os.path.exists(self._clear_filename):
os.unlink(self._clear_filename)
super(TestCollectionManifestStorage, self).tearDown()
def test_manifest_exists(self):
filename = storage.staticfiles_storage.manifest_name
path = storage.staticfiles_storage.path(filename)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment