New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fixed #20483 -- Made TransactionTestCase faster. #1240
Conversation
How much faster? |
I have to say this whole thing scares me quite a bit. Why isn't |
The entire test suite passes in about 150 seconds with this patch. See the ticket for more information. |
@alex the |
I don't believe using @override_settings would actually change anything. You still have to change global state (the used app-cache, or what the cache contains), so there is zero gain in that respect. And as mentioned in the ticket, you still have the problem that imports happen only once. Using override_settings so that we don't have two things that do almost the same thing could be a good idea. |
I think you can get rid of the nastiest parts of this changeset by requiring that all "cascades" are included in installed_apps. That is, all models which will need to be truncated or cascaded into by delete are included, and thus you will not need to do any changes there. It is true that this is trading code complexity for testing speed. On my machine PostgreSQL tests are 4500s vs 300s between master and the original isolated_apps branch. IMO important enough to have some complexity. |
try: | ||
get_model('auth', 'Permission') | ||
except UnavailableApp: | ||
return |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Presumably we don't actually want this to fail silently? If for some reason some end user code was managing to make this throw UnavailableApp
I don't think it should hide it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reason this is done is that flush sends post_syncdb, and permission & contenttype creation are listening for the signal.
This seems to be one point more for override_settings() based approach. If done that way, permissions & contenttypes could register a listener for settings_changed and add/remove the signal listener as needed. No need to know about "app mask" at all.
Is it possible we may be able to speed things up even more by setting The speed improvements are very impressive though! |
@@ -15,6 +15,8 @@ | |||
__all__ = ('get_apps', 'get_app', 'get_models', 'get_model', 'register_models', | |||
'load_app', 'app_cache_ready') | |||
|
|||
class UnavailableApp(ValueError): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minor - but any reason to subclass ValueError instead of Exception?
This allows using flush on a subset of the tables without having to manually cascade to all tables with foreign keys to the tables being truncated, when they're known to be empty. On databases where truncate is implemented with DELETE FROM, this doesn't make a difference. The cascade is allowed, not mandatory.
This makes Django's test suite significantly faster by reducing the number of models for which content types and permissions must be created and tables must be flushed in each non-transactional test. Most of the credit goes to Anssi. He got the idea and did the research. It's documented for Django contributors and committers but it's branded as a private API to preserve our freedom to change it in the future. Refs #20483.
Fixed #20483.
Merged |
No description provided.