Skip to content

Commit

Permalink
test(backup): Ensure coverage of all exportable models
Browse files Browse the repository at this point in the history
The basic idea here is to include a test that finds all non-abstract
descendants of our `BaseModel`, filter down to just the exportable ones
(ie, those that set `__include_in_export__ = True`), and then ensure
that each of them is included in at least one of the tests seen in
`test_models.py`. This is done by introducing a new `mark` wrapper class
which ingests all of the "target" models used by the `@targets` test
decorator at init time, allowing us to create an exhaustive list of all
types passed to `@targets`.

Issue: getsentry/team-ospo#156
  • Loading branch information
azaslavsky committed Jul 21, 2023
1 parent a475a05 commit c057e81
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 49 deletions.
49 changes: 49 additions & 0 deletions tests/sentry/backup/test_coverage.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
from __future__ import annotations

from typing import Type

from sentry.db.models import BaseModel
from tests.sentry.backup.test_models import TESTED_MODELS


def get_final_derivations_of(model: Type):
"""A "final" derivation of the given `model` base class is any non-abstract class for the
"sentry" app with `BaseModel` as an ancestor. Top-level calls to this class should pass in `BaseModel` as the argument."""
out = set()
for sub in model.__subclasses__():
subs = sub.__subclasses__()
if subs:
out.update(get_final_derivations_of(sub))
if not sub._meta.abstract and sub._meta.db_table and sub._meta.app_label == "sentry":
out.add(sub)
return out


def get_exportable_final_derivations_of(model: Type):
"""Like `get_final_derivations_of`, except that it further filters the results to include only `__include_in_export__ = True`."""
return set(
filter(
lambda c: getattr(c, "__include_in_export__") is True,
get_final_derivations_of(model),
)
)


ALL_EXPORTABLE_MODELS = {c.__name__ for c in get_exportable_final_derivations_of(BaseModel)}


# Note: this gets checked at runtime, but better to avoid possible runtime errors and catch it early
# in CI.
def test_all_final_derivations_of_django_model_set_included_in_export():
missing = set(
filter(
lambda c: not hasattr(c, "__include_in_export__"),
get_final_derivations_of(BaseModel),
)
)
assert not missing


def test_exportable_final_derivations_of_django_model_are_tested():
untested = ALL_EXPORTABLE_MODELS - TESTED_MODELS
assert not untested
Loading

0 comments on commit c057e81

Please sign in to comment.