#15903 closed Bug (fixed)
Changeset r16053 breaks a few views tests
Reported by: | Jannis Leidel | Owned by: | Carl Meyer |
---|---|---|---|
Component: | Testing framework | Version: | 1.3 |
Severity: | Release blocker | Keywords: | |
Cc: | Carl Meyer | Triage Stage: | Accepted |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Traceback:
(django-dev)~/Code/git/django/tests [git:master] $ python runtests.py --settings=test_sqlite views Creating test database for alias 'default'... Creating test database for alias 'other'... ..........EEE.......................................................................... ====================================================================== ERROR: test_template_exceptions (regressiontests.views.tests.debug.DebugViewTests) ---------------------------------------------------------------------- Traceback (most recent call last): File "/Users/jezdez/Code/git/django/tests/regressiontests/views/tests/debug.py", line 48, in test_template_exceptions self.client.get(reverse('template_exception', args=(n,))) File "/Users/jezdez/Code/git/django/django/core/urlresolvers.py", line 391, in reverse *args, **kwargs))) File "/Users/jezdez/Code/git/django/django/core/urlresolvers.py", line 312, in reverse possibilities = self.reverse_dict.getlist(lookup_view) File "/Users/jezdez/Code/git/django/django/core/urlresolvers.py", line 229, in _get_reverse_dict self._populate() File "/Users/jezdez/Code/git/django/django/core/urlresolvers.py", line 208, in _populate for name in pattern.reverse_dict: File "/Users/jezdez/Code/git/django/django/core/urlresolvers.py", line 229, in _get_reverse_dict self._populate() File "/Users/jezdez/Code/git/django/django/core/urlresolvers.py", line 197, in _populate for pattern in reversed(self.url_patterns): File "/Users/jezdez/Code/git/django/django/core/urlresolvers.py", line 279, in _get_url_patterns patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module) File "/Users/jezdez/Code/git/django/django/core/urlresolvers.py", line 274, in _get_urlconf_module self._urlconf_module = import_module(self.urlconf_name) File "/Users/jezdez/Code/git/django/django/utils/importlib.py", line 35, in import_module __import__(name) File "/Users/jezdez/Code/git/django/tests/regressiontests/admin_views/urls.py", line 4, in <module> import customadmin File "/Users/jezdez/Code/git/django/tests/regressiontests/admin_views/customadmin.py", line 8, in <module> import models, forms File "/Users/jezdez/Code/git/django/tests/regressiontests/admin_views/models.py", line 860, in <module> admin.site.register(ChapterXtra1, ChapterXtra1Admin) File "/Users/jezdez/Code/git/django/django/contrib/admin/sites.py", line 98, in register validate(admin_class, model) File "/Users/jezdez/Code/git/django/django/contrib/admin/validation.py", line 63, in validate cls.__name__, idx, fpath ImproperlyConfigured: 'ChapterXtra1Admin.list_filter[4]' refers to 'chap__book__promo' which does not refer to a Field. ====================================================================== ERROR: test_template_loader_postmortem (regressiontests.views.tests.debug.DebugViewTests) ---------------------------------------------------------------------- Traceback (most recent call last): File "/Users/jezdez/Code/git/django/tests/regressiontests/views/tests/debug.py", line 56, in test_template_loader_postmortem response = self.client.get(reverse('raises_template_does_not_exist')) File "/Users/jezdez/Code/git/django/django/core/urlresolvers.py", line 391, in reverse *args, **kwargs))) File "/Users/jezdez/Code/git/django/django/core/urlresolvers.py", line 312, in reverse possibilities = self.reverse_dict.getlist(lookup_view) File "/Users/jezdez/Code/git/django/django/core/urlresolvers.py", line 229, in _get_reverse_dict self._populate() File "/Users/jezdez/Code/git/django/django/core/urlresolvers.py", line 208, in _populate for name in pattern.reverse_dict: File "/Users/jezdez/Code/git/django/django/core/urlresolvers.py", line 229, in _get_reverse_dict self._populate() File "/Users/jezdez/Code/git/django/django/core/urlresolvers.py", line 197, in _populate for pattern in reversed(self.url_patterns): File "/Users/jezdez/Code/git/django/django/core/urlresolvers.py", line 279, in _get_url_patterns patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module) File "/Users/jezdez/Code/git/django/django/core/urlresolvers.py", line 274, in _get_urlconf_module self._urlconf_module = import_module(self.urlconf_name) File "/Users/jezdez/Code/git/django/django/utils/importlib.py", line 35, in import_module __import__(name) File "/Users/jezdez/Code/git/django/tests/regressiontests/admin_views/urls.py", line 4, in <module> import customadmin File "/Users/jezdez/Code/git/django/tests/regressiontests/admin_views/customadmin.py", line 8, in <module> import models, forms File "/Users/jezdez/Code/git/django/tests/regressiontests/admin_views/models.py", line 806, in <module> admin.site.register(Article, ArticleAdmin) File "/Users/jezdez/Code/git/django/django/contrib/admin/sites.py", line 86, in register raise AlreadyRegistered('The model %s is already registered' % model.__name__) AlreadyRegistered: The model Article is already registered ====================================================================== ERROR: test_view_exceptions (regressiontests.views.tests.debug.DebugViewTests) ---------------------------------------------------------------------- Traceback (most recent call last): File "/Users/jezdez/Code/git/django/tests/regressiontests/views/tests/debug.py", line 43, in test_view_exceptions reverse('view_exception', args=(n,))) File "/Users/jezdez/Code/git/django/django/core/urlresolvers.py", line 391, in reverse *args, **kwargs))) File "/Users/jezdez/Code/git/django/django/core/urlresolvers.py", line 312, in reverse possibilities = self.reverse_dict.getlist(lookup_view) File "/Users/jezdez/Code/git/django/django/core/urlresolvers.py", line 229, in _get_reverse_dict self._populate() File "/Users/jezdez/Code/git/django/django/core/urlresolvers.py", line 208, in _populate for name in pattern.reverse_dict: File "/Users/jezdez/Code/git/django/django/core/urlresolvers.py", line 229, in _get_reverse_dict self._populate() File "/Users/jezdez/Code/git/django/django/core/urlresolvers.py", line 197, in _populate for pattern in reversed(self.url_patterns): File "/Users/jezdez/Code/git/django/django/core/urlresolvers.py", line 279, in _get_url_patterns patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module) File "/Users/jezdez/Code/git/django/django/core/urlresolvers.py", line 274, in _get_urlconf_module self._urlconf_module = import_module(self.urlconf_name) File "/Users/jezdez/Code/git/django/django/utils/importlib.py", line 35, in import_module __import__(name) File "/Users/jezdez/Code/git/django/tests/regressiontests/admin_views/urls.py", line 4, in <module> import customadmin File "/Users/jezdez/Code/git/django/tests/regressiontests/admin_views/customadmin.py", line 8, in <module> import models, forms File "/Users/jezdez/Code/git/django/tests/regressiontests/admin_views/models.py", line 806, in <module> admin.site.register(Article, ArticleAdmin) File "/Users/jezdez/Code/git/django/django/contrib/admin/sites.py", line 86, in register raise AlreadyRegistered('The model %s is already registered' % model.__name__) AlreadyRegistered: The model Article is already registered ---------------------------------------------------------------------- Ran 87 tests in 2.260s FAILED (errors=3) Destroying test database for alias 'default'... Destroying test database for alias 'other'... (django-dev)~/Code/git/django/tests [git:master] $
Change History (10)
comment:1 by , 14 years ago
Summary: | Changeset 16053 breaks a few views tests → Changeset r16053 breaks a few views tests |
---|
comment:2 by , 14 years ago
Owner: | changed from | to
---|
comment:3 by , 14 years ago
Has patch: | set |
---|
Ok, two separate problems here. Both are fixed by this github branch, one in each commit: https://github.com/carljm/django/compare/master...t15903
First problem is that I missed a case in r16053, and not-installed models were being left out of any related models' related-objects cache. Meaning that two related models would look different (no reverse relation introspectable through _meta) if not installed than if installed. First commit fixes this, with a test (and adds a couple tests to flesh out the r16053 tests).
Second problem is that the views tests, when run standalone, were causing various other test apps to be imported due to url-reversing. This caused the first problem to show up in admin_views (because its models were being imported although it wasn't installed) only when the views tests were run without the admin_views tests. The second commit in the above branch fixes that particular test-app coupling by using the "urls" parameter of a TestCase
.
I'll commit these separately for clarity, but I'll wait for a review from jezdez first, since this touches the app-cache and may affect work on the app-loading branch.
follow-up: 7 comment:6 by , 14 years ago
Carl:
I think there is still an issue with this. I've experienced some very difficult to debug problems with a project of mine, since [16053]. The problem only occurs when running the devserver with DEBUG=True (which cause the validation routines to run, I think this is connected), and appears to be some ManyToMany
fields missing from the model ._meta
definition. All of the models involved are installed AFAICS, but span a number of apps. The behaviour changes if I change the order of items in INSTALLED_APPS. Since the latest change, [16107], things have improved, in that with the right order of INSTALLED_APPS I can actually get things to work, but it should work in any order.
(I haven't been able to produce a minimal test case yet - I think that will require a lot of work).
But based on your last change, I tried the following in the _fill_related_many_to_many_cache()
method:
--- a/django/db/models/options.py Wed Apr 27 15:47:16 2011 +0000 +++ b/django/db/models/options.py Wed Apr 27 18:18:58 2011 +0100 @@ -420,7 +420,7 @@ cache[obj] = parent else: cache[obj] = model - for klass in get_models(): + for klass in get_models(include_auto_created=True, only_installed=False): for f in klass._meta.local_many_to_many: if f.rel and not isinstance(f.rel.to, str) and self == f.rel.to._meta: cache[RelatedObject(f.rel.to, klass, f)] = None
and it did fix my problem. It also worked with get_models(only_installed=False)
.
However, I haven't had the time to really understand your changes here or what is going on to know if this is the correct fix (or indeed, if it is actually a problem with my project's code).
comment:7 by , 14 years ago
Hi Luke,
Replying to lukeplant:
I think there is still an issue with this. I've experienced some very difficult to debug problems with a project of mine, since [16053]. The problem only occurs when running the devserver with DEBUG=True (which cause the validation routines to run, I think this is connected), and appears to be some
ManyToMany
fields missing from the model._meta
definition. All of the models involved are installed AFAICS, but span a number of apps. The behaviour changes if I change the order of items in INSTALLED_APPS. Since the latest change, [16107], things have improved, in that with the right order of INSTALLED_APPS I can actually get things to work, but it should work in any order.
(I haven't been able to produce a minimal test case yet - I think that will require a lot of work).
Sorry about this, and thanks for the report. It is indeed just another call to get_models that should be using only_installed=False that I missed; your one-line fix is correct (without changing include_auto_created, which isn't related). I thought I'd grepped for all these calls and checked them, but clearly I failed - I've done so again and this time I think I've got them all for real!
I'm not sure why this is showing up in your code with all the relevant apps in INSTALLED_APPS, or why it would be dependent on order of INSTALLED_APPS. The app-cache fully populates itself at the beginning of get_models, so any models whose app is in INSTALLED_APPS should be present in the return value of get_models(only_installed=True). Filling the related cache should use only_installed=False regardless, so these relationships are still reported in _meta even for not-installed models, which makes it a moot issue (although it would still be interesting to know why those related models weren't being returned with only_installed=True if they are in INSTALLED_APPS, if you can narrow it down at all).
comment:8 by , 14 years ago
Fixed this additional case in r16108, fat-fingered the Refs in the commit message.
comment:9 by , 11 years ago
UI/UX: | unset |
---|
get_models(only_installed=False)
is next on my list of things to refactor -- read: remove -- in the new app loading. I'd like to get rid of this complexity (#21677) and eventually deprecate the ability to use models that aren't in an installed application (#21680).
There's no conclusive answer on why Luke hit that last problem, but I believe it has to do with a complex import sequence, where get_models
was called on a partially populated app cache. Our best chance to improve the situation is to move the population of the app cache earlier (#21676) so that all models get imported from populate_models() -- rather than having populate_models() triggered by the import of a models module.
Interesting, these tests pass when the full suite is run, but fail when just the view tests are run. Suggests a problem with the tests, I'll take a look.