Skip to content
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 #25415 -- Made DiscoverRunner run system checks. #6294

Closed
wants to merge 3 commits into from

Conversation

adamchainz
Copy link
Sponsor Member

Revival of #5293.

Ticket 25415

@adamchainz
Copy link
Sponsor Member Author

@timgraham I've fixed all but the "CommaSeparatedIntegerField has been deprecated." warnings. Is there a recommended way of fixing them? We could just ignore the warning in the tests, or we could subclass it to ignore the warning and use that subclass throughout the test suite

@timgraham
Copy link
Member

Can we use SILENCED_SYSTEM_CHECKS? I don't think we should change all instances of ForeignKey(unique=True) to OneToOneField, for example, as it's a valid scenario that should continue to be tested.

@adamchainz
Copy link
Sponsor Member Author

Although some instances are testing behaviour that might be dfiferent for OneToOneField, most of the ForeignKey(unique=True) instances seem to be more valid as OneToOneFields though.

Silencing across the entire test suite is potentially dangerous as it might prevent problems in future tests. Ideally we'd be able to silence for specific instances of warnings, though that sounds like a big yak shave...

@timgraham
Copy link
Member

The idea of silencing specific warnings has come up before. It would be a nice to have, but as you said, not quite sure of the best implementation and how much work it would be.

I don't see foresee any problems with silencing the warnings for CommaSeparatedIntegerField and ForeignKey(unique=True) but if you come up with some other solution, I'll be happy to look at it.

@adamchainz
Copy link
Sponsor Member Author

Updated to use SILENCED_SYSTEM_CHECKS - setting it in runtests.py seems to work, afaict this is the 'base' of the settings used in tests.

@adamchainz adamchainz force-pushed the ticket_25415 branch 3 times, most recently from 1eab279 to 5db2f8b Compare March 18, 2016 14:25
@adamchainz
Copy link
Sponsor Member Author

Added a release note, turned into two commits - one to fix discoverrunner, one to fix the errors 👍

@timgraham
Copy link
Member

There are some problems with the MySQL and MySQL GIS builds.

@adamchainz
Copy link
Sponsor Member Author

Both seem unrelated

MySQL:

  File "/home/jenkins/workspace/pull-requests-trusty/database/mysql/label/trusty-pr/python/python2.7/django/contrib/gis/db/models/fields.py", line 120, in db_type
    return connection.ops.geo_db_type(self)
AttributeError: 'DatabaseOperations' object has no attribute 'geo_db_type'

MySQL GIS:

  File "/home/jenkins/workspace/pull-requests-trusty/database/mysql_gis/label/trusty-pr/python/python2.7/django/contrib/gis/db/models/fields.py", line 420, in _check_connection
    raise ImproperlyConfigured('Raster fields require backends with raster support.')
django.core.exceptions.ImproperlyConfigured: Raster fields require backends with raster support.

Just rebased on master to retrigger builds, GIS error seems to have happened again.

@timgraham
Copy link
Member

In the first case, I think the problem is that the checks are run on GIS models when a GIS backend isn't in use.

@adamchainz
Copy link
Sponsor Member Author

Ah, that would do it

@charettes
Copy link
Member

Looks like you'll need to skip these checks if not all(getattr(connection.features, feature, False) for feature in field.model._meta.required_db_features)

@@ -9,7 +9,6 @@ class AbstractArticle(models.Model):
title = models.CharField(max_length=50)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this actually identify a regression in 3a47d42? The check error CustomArticle.on_site: (sites.E001) CurrentSiteManager could not find a field named 'sites'. seems to suggest that model's override of the parent manager isn't working. \cc @loic

Copy link
Sponsor Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought it might be but wasn't sure

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just tested it and I can confirm that this is no longer needed after applying #7115.

Copy link
Sponsor Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @loic

@@ -203,8 +203,6 @@ def test_ticket_17477(self):

class Sqlite3InMemoryTestDbs(TestCase):

available_apps = []
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is related to any check errors, is it?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see the exception if it's removed:

======================================================================
ERROR: test_transaction_support (test_runner.tests.Sqlite3InMemoryTestDbs)
Ticket #16329: sqlite3 in-memory test databases
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/tim/code/django/django/apps/registry.py", line 148, in get_app_config
    return self.app_configs[app_label]
KeyError: 'auth'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/tim/code/django/tests/test_runner/tests.py", line 227, in test_transaction_support
    DiscoverRunner(verbosity=0).setup_databases()
  File "/home/tim/code/django/django/test/runner.py", line 537, in setup_databases
    self.parallel, **kwargs
  File "/home/tim/code/django/django/test/utils.py", line 205, in setup_databases
    call_command('check')
  File "/home/tim/code/django/django/core/management/__init__.py", line 130, in call_command
    return command.execute(*args, **defaults)
  File "/home/tim/code/django/django/core/management/base.py", line 345, in execute
    output = self.handle(*args, **options)
  File "/home/tim/code/django/django/core/management/commands/check.py", line 68, in handle
    fail_level=getattr(checks, options['fail_level']),
  File "/home/tim/code/django/django/core/management/base.py", line 374, in check
    include_deployment_checks=include_deployment_checks,
  File "/home/tim/code/django/django/core/management/base.py", line 361, in _run_checks
    return checks.run_checks(**kwargs)
  File "/home/tim/code/django/django/core/checks/registry.py", line 81, in run_checks
    new_errors = check(app_configs=app_configs)
  File "/home/tim/code/django/django/contrib/auth/checks.py", line 16, in check_user_model
    cls = apps.get_model(settings.AUTH_USER_MODEL)
  File "/home/tim/code/django/django/apps/registry.py", line 195, in get_model
    return self.get_app_config(app_label).get_model(model_name.lower())
  File "/home/tim/code/django/django/apps/registry.py", line 155, in get_app_config
    raise LookupError(message)
LookupError: No installed app with label 'auth'.

We should check if this is the proper fix or if this reveals some other problem, I'm not sure offhand.

Copy link
Sponsor Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried running the tests without it but they fail (only on Windows for some reason)

Afaict it was added just as an optimization. Starting a new DiscoverRunner inside the test suite re-runs the checks, one of which has been registered from auth and fails because auth is no longer in INSTALLED_APPS. So I think just removing the available_apps line is legit.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@adamchainz, did you investigate this?

@timgraham
Copy link
Member

To address the new clashing table errors, I think we should modify that check to ignore unmanaged models. The patched I attached to https://code.djangoproject.com/ticket/27204 fixes the check errors that popped up in model_options and unmanaged_models.

@timgraham
Copy link
Member

Some additional output capturing might be needed. I see several "System check identified no issues (21 silenced)." in the test output.

@charettes
Copy link
Member

@timgraham , Model (and fields) checks must not be run if all not all required db features are available on all connections. We should make Model.check() abort immediately if not all(getattr(connection.features, feature, False) for feature in self._meta.required_db_features).

@charettes
Copy link
Member

@timgraham, that's what I had in mind: #7227.

@@ -200,6 +201,9 @@ def setup_databases(verbosity, interactive, keepdb=False, debug_sql=False, paral
for alias in connections:
connections[alias].force_debug_cursor = True

# Now run the system checks. They aren't run until now since some checks require database access.
call_command('check')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pass the verbosity argument here.

@adamchainz adamchainz force-pushed the ticket_25415 branch 2 times, most recently from 62fb973 to 986da7a Compare September 23, 2016 07:09
@adamchainz adamchainz force-pushed the ticket_25415 branch 2 times, most recently from 41d2189 to b70375e Compare November 5, 2016 10:57
@adamchainz
Copy link
Sponsor Member Author

I've merged in something similar to #7227 but only for the failing models. In the process I also found and removed some import hacks from the GIS tests which were missed when making GDAL a required dependency. Tests are green, ready for re-review 🎉

from django.db import connections


class SkipChecksIfNotDBFeaturesMixin(object):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like this could be useful in other tests at some point. Rather than burying it here, it might be useful to put it somewhere more reusable/discoverable (even if it's not public API at this point). Maybe django.core.checks.tests.py? Any opinion @charettes?

Copy link
Sponsor Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like it's a bit specific?

Copy link
Sponsor Member Author

@adamchainz adamchainz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's a comment I wrote during DUTH github didn't post because the new review UI is unclear

@adamchainz adamchainz changed the title Fixed #25415 -- made test runner perform system checks Fixed #25415 -- Made test runner perform system checks Nov 26, 2016
@adamchainz adamchainz changed the title Fixed #25415 -- Made test runner perform system checks Fixed #25415 -- Made DisoverRunner run system checks Nov 26, 2016
@timgraham timgraham changed the title Fixed #25415 -- Made DisoverRunner run system checks Fixed #25415 -- Made DiscoverRunner run system checks. Nov 29, 2016
Copy link
Member

@timgraham timgraham left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MySQL fails with:

django/contrib/gis/db/models/fields.py", line 123, in db_type
    return connection.ops.geo_db_type(self)
AttributeError: 'DatabaseOperations' object has no attribute 'geo_db_type'


class SkipChecksIfNotDBFeaturesMixin(object):
"""
Required because we make the models but then skip the tests for them
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd say, "Skip system checks on models that don't have all the required_db_features."

@@ -200,6 +201,9 @@ def setup_databases(verbosity, interactive, keepdb=False, debug_sql=False, paral
for alias in connections:
connections[alias].force_debug_cursor = True

# Now run the system checks. They aren't run until now since some checks require database access.
call_command('check', verbosity=verbosity)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if this is the best place for this -- doesn't seem like "running system checks" is related to "setting up databases". Anyway, this function is documented in topics/testing/advanced.txt and the docs should be updated if this change happens.

Copy link
Sponsor Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The main reason I put it here is because this is where it was implicitly being run in 1.7, as part of migrate. Will try put it later in the flow.

Copy link
Sponsor Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I remember - another reason I did this was so that nose, my test runner at the time, would automatically run them, because it calls setup_databases. I now use pytest which also has this behaviour, but I'm making pytest-django run the checks itself in pytest-dev/pytest-django#414 .

@@ -397,6 +397,8 @@ Tests
* Added support for :meth:`python:unittest.TestCase.subTest`’s when using the
:option:`test --parallel` option.

* Tests now run checks at the start of the test run, as they did in Django 1.7.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think "as they did in Django 1.7" needn't be mentioned at this point. For third-party test runners, it's probably also useful to mention exactly where the check are run from.

Copy link
Sponsor Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure.

@@ -200,6 +201,9 @@ def setup_databases(verbosity, interactive, keepdb=False, debug_sql=False, paral
for alias in connections:
connections[alias].force_debug_cursor = True

# Now run the system checks. They aren't run until now since some checks require database access.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please wrap comments at 79 characters.

@@ -8,6 +8,7 @@
class Command(BaseCommand):
help = 'Discover and run tests in the specified modules or the current directory.'

# Tests do run the checks, but only after databases have been set up
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use periods

@adamchainz
Copy link
Sponsor Member Author

Will fix MySQL failure. That's annoying, tests were passing before my rebase yesterday.

@adamchainz adamchainz force-pushed the ticket_25415 branch 2 times, most recently from 8e53c42 to 5bf7ece Compare November 30, 2016 21:16
@adamchainz
Copy link
Sponsor Member Author

I found that there were more problem models in other parts of gis_tests that have started failing checks, idk why exactly though. Since it was only the MySQL check_field that was actually failing when it called db_type, I've moved the check for 'model enabled' there. It's not the most logical place but it 'works for now'. In other news its check_field needed updating anyway because it was using django.db.connection instead of self.connection, meaning it'd start using the wrong connection if you had e.g. postgres as your default DB and mysql as a secondary.

@adamchainz
Copy link
Sponsor Member Author

More check failures following 7cddd8a 😄 :

ERRORS:
max_lengths.PersonWithCustomMaxLengths.vcard: (fields.E202) FileField's 'upload_to' argument must be a relative path, not an absolute path.
	HINT: Remove the leading slash.
max_lengths.PersonWithDefaultMaxLengths.vcard: (fields.E202) FileField's 'upload_to' argument must be a relative path, not an absolute path.
	HINT: Remove the leading slash.
serializers.FileData.data: (fields.E202) FileField's 'upload_to' argument must be a relative path, not an absolute path.
	HINT: Remove the leading slash.

@charettes
Copy link
Member

@adamchainz hopefully we can ship this before introducing yet another failing check 😄

@@ -402,6 +402,8 @@ Tests
* Added support for :meth:`python:unittest.TestCase.subTest`’s when using the
:option:`test --parallel` option.

* Tests now run checks at the start of the test run.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you explain that it's DiscoverRunner that does this. Perhaps the docs for DiscoverRunner should also be updated.

@@ -8,6 +8,7 @@
class Command(BaseCommand):
help = 'Discover and run tests in the specified modules or the current directory.'

# Tests do run the checks, but only after databases have been set up.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DiscoverRunner runs checks after databases are set up.

@timgraham
Copy link
Member

merged in 6d947e8, 391c450, 5eff8a7, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
4 participants