Fixed #9199 -- We were erroneously only prepending "www" to the domain if we
[django.git] / tests / runtests.py
blobcc9594b5fef37b11d9a02e17b584193ab457ed91
1 #!/usr/bin/env python
3 import os, sys, traceback
4 import unittest
6 import django.contrib as contrib
8 try:
9 set
10 except NameError:
11 from sets import Set as set # For Python 2.3
14 CONTRIB_DIR_NAME = 'django.contrib'
15 MODEL_TESTS_DIR_NAME = 'modeltests'
16 REGRESSION_TESTS_DIR_NAME = 'regressiontests'
18 TEST_TEMPLATE_DIR = 'templates'
20 CONTRIB_DIR = os.path.dirname(contrib.__file__)
21 MODEL_TEST_DIR = os.path.join(os.path.dirname(__file__), MODEL_TESTS_DIR_NAME)
22 REGRESSION_TEST_DIR = os.path.join(os.path.dirname(__file__), REGRESSION_TESTS_DIR_NAME)
24 ALWAYS_INSTALLED_APPS = [
25 'django.contrib.contenttypes',
26 'django.contrib.auth',
27 'django.contrib.sites',
28 'django.contrib.flatpages',
29 'django.contrib.redirects',
30 'django.contrib.sessions',
31 'django.contrib.comments',
32 'django.contrib.admin',
35 def get_test_models():
36 models = []
37 for loc, dirpath in (MODEL_TESTS_DIR_NAME, MODEL_TEST_DIR), (REGRESSION_TESTS_DIR_NAME, REGRESSION_TEST_DIR), (CONTRIB_DIR_NAME, CONTRIB_DIR):
38 for f in os.listdir(dirpath):
39 if f.startswith('__init__') or f.startswith('.') or f.startswith('sql') or f.startswith('invalid'):
40 continue
41 models.append((loc, f))
42 return models
44 def get_invalid_models():
45 models = []
46 for loc, dirpath in (MODEL_TESTS_DIR_NAME, MODEL_TEST_DIR), (REGRESSION_TESTS_DIR_NAME, REGRESSION_TEST_DIR), (CONTRIB_DIR_NAME, CONTRIB_DIR):
47 for f in os.listdir(dirpath):
48 if f.startswith('__init__') or f.startswith('.') or f.startswith('sql'):
49 continue
50 if f.startswith('invalid'):
51 models.append((loc, f))
52 return models
54 class InvalidModelTestCase(unittest.TestCase):
55 def __init__(self, model_label):
56 unittest.TestCase.__init__(self)
57 self.model_label = model_label
59 def runTest(self):
60 from django.core.management.validation import get_validation_errors
61 from django.db.models.loading import load_app
62 from cStringIO import StringIO
64 try:
65 module = load_app(self.model_label)
66 except Exception, e:
67 self.fail('Unable to load invalid model module')
69 # Make sure sys.stdout is not a tty so that we get errors without
70 # coloring attached (makes matching the results easier). We restore
71 # sys.stderr afterwards.
72 orig_stdout = sys.stdout
73 s = StringIO()
74 sys.stdout = s
75 count = get_validation_errors(s, module)
76 sys.stdout = orig_stdout
77 s.seek(0)
78 error_log = s.read()
79 actual = error_log.split('\n')
80 expected = module.model_errors.split('\n')
82 unexpected = [err for err in actual if err not in expected]
83 missing = [err for err in expected if err not in actual]
85 self.assert_(not unexpected, "Unexpected Errors: " + '\n'.join(unexpected))
86 self.assert_(not missing, "Missing Errors: " + '\n'.join(missing))
88 def django_tests(verbosity, interactive, test_labels):
89 from django.conf import settings
91 old_installed_apps = settings.INSTALLED_APPS
92 old_test_database_name = settings.TEST_DATABASE_NAME
93 old_root_urlconf = getattr(settings, "ROOT_URLCONF", "")
94 old_template_dirs = settings.TEMPLATE_DIRS
95 old_use_i18n = settings.USE_I18N
96 old_login_url = settings.LOGIN_URL
97 old_language_code = settings.LANGUAGE_CODE
98 old_middleware_classes = settings.MIDDLEWARE_CLASSES
100 # Redirect some settings for the duration of these tests.
101 settings.INSTALLED_APPS = ALWAYS_INSTALLED_APPS
102 settings.ROOT_URLCONF = 'urls'
103 settings.TEMPLATE_DIRS = (os.path.join(os.path.dirname(__file__), TEST_TEMPLATE_DIR),)
104 settings.USE_I18N = True
105 settings.LANGUAGE_CODE = 'en'
106 settings.LOGIN_URL = '/accounts/login/'
107 settings.MIDDLEWARE_CLASSES = (
108 'django.contrib.sessions.middleware.SessionMiddleware',
109 'django.contrib.auth.middleware.AuthenticationMiddleware',
110 'django.middleware.common.CommonMiddleware',
112 settings.SITE_ID = 1
114 # Load all the ALWAYS_INSTALLED_APPS.
115 # (This import statement is intentionally delayed until after we
116 # access settings because of the USE_I18N dependency.)
117 from django.db.models.loading import get_apps, load_app
118 get_apps()
120 # Load all the test model apps.
121 for model_dir, model_name in get_test_models():
122 model_label = '.'.join([model_dir, model_name])
123 try:
124 # if the model was named on the command line, or
125 # no models were named (i.e., run all), import
126 # this model and add it to the list to test.
127 if not test_labels or model_name in set([label.split('.')[0] for label in test_labels]):
128 if verbosity >= 1:
129 print "Importing model %s" % model_name
130 mod = load_app(model_label)
131 if mod:
132 if model_label not in settings.INSTALLED_APPS:
133 settings.INSTALLED_APPS.append(model_label)
134 except Exception, e:
135 sys.stderr.write("Error while importing %s:" % model_name + ''.join(traceback.format_exception(*sys.exc_info())[1:]))
136 continue
138 # Add tests for invalid models.
139 extra_tests = []
140 for model_dir, model_name in get_invalid_models():
141 model_label = '.'.join([model_dir, model_name])
142 if not test_labels or model_name in test_labels:
143 extra_tests.append(InvalidModelTestCase(model_label))
144 try:
145 # Invalid models are not working apps, so we cannot pass them into
146 # the test runner with the other test_labels
147 test_labels.remove(model_name)
148 except ValueError:
149 pass
151 # Run the test suite, including the extra validation tests.
152 from django.test.simple import run_tests
153 failures = run_tests(test_labels, verbosity=verbosity, interactive=interactive, extra_tests=extra_tests)
154 if failures:
155 sys.exit(failures)
157 # Restore the old settings.
158 settings.INSTALLED_APPS = old_installed_apps
159 settings.ROOT_URLCONF = old_root_urlconf
160 settings.TEMPLATE_DIRS = old_template_dirs
161 settings.USE_I18N = old_use_i18n
162 settings.LANGUAGE_CODE = old_language_code
163 settings.LOGIN_URL = old_login_url
164 settings.MIDDLEWARE_CLASSES = old_middleware_classes
166 if __name__ == "__main__":
167 from optparse import OptionParser
168 usage = "%prog [options] [model model model ...]"
169 parser = OptionParser(usage=usage)
170 parser.add_option('-v','--verbosity', action='store', dest='verbosity', default='0',
171 type='choice', choices=['0', '1', '2'],
172 help='Verbosity level; 0=minimal output, 1=normal output, 2=all output')
173 parser.add_option('--noinput', action='store_false', dest='interactive', default=True,
174 help='Tells Django to NOT prompt the user for input of any kind.')
175 parser.add_option('--settings',
176 help='Python path to settings module, e.g. "myproject.settings". If this isn\'t provided, the DJANGO_SETTINGS_MODULE environment variable will be used.')
177 options, args = parser.parse_args()
178 if options.settings:
179 os.environ['DJANGO_SETTINGS_MODULE'] = options.settings
180 elif "DJANGO_SETTINGS_MODULE" not in os.environ:
181 parser.error("DJANGO_SETTINGS_MODULE is not set in the environment. "
182 "Set it or use --settings.")
183 django_tests(int(options.verbosity), options.interactive, args)