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

test(backup): Remove @targets decorator and improve assert message #61719

Merged
merged 2 commits into from
Dec 20, 2023

Conversation

azaslavsky
Copy link
Contributor

Two improvements to the backup test scaffolding are included in this PR:

  1. The @targets decorator is replaced with @expect_models, which is simpler and does not rely on test function returns, as these are deprecated in Python 3.11.
  2. The error message shown to developers (and in CI) when the new verify_models_in_output test function fails are much more detailed, providing an explanation of what went wrong and where to look to fix the problem.

Two improvements to the backup test scaffolding are included in this PR:

1. The `@targets` decorator is replaced with `@expect_models`, which is
   simpler and does not rely on test function returns, as these are
   deprecated in Python 3.11
2. The error message shown to developers (and in CI) when the new
   `verify_models_in_output` test function fails are much more detailed,
   providing an explanation of what went wrong and where to look to fix
   the problem.
the output, ensuring that we're actually testing the thing we think we are. Additionally, this
decorator is easily legible to static analysis, which allows for static checks to ensure that
all `__relocation_scope__ != RelocationScope.Excluded` models are being tested.
def verify_models_in_output(expected_models: list[Type[models.Model]], actual_json: JSONData):
Copy link
Member

Choose a reason for hiding this comment

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

this should be -> None (otherwise mypy doesn't opt this into type checking)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

def decorator(func: Callable):
@wraps(func)
def wrapper(*args, **kwargs):
return func(*args, target_models, **kwargs)
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 also discourage signature-modifying decorators -- they're still action-at-a-distance and it'd be much more explicit to use a context manager

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The reason I want to use a decorator here is because test_coverage.py checks these for completeness statically. If we use a context manager, the ..._TESTED globals only get populated at test runtime.

Copy link
Member

Choose a reason for hiding this comment

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

is there another way you can satisfy that without metaprogramming?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I suppose there always is, but it's a bigger lift than this change as constituted.

The main case we're trying to guard against is developers not thinking about backups when they add/modify models, thereby causing new models to be untested. If we tested all of the cases in a single large test then meta-programming would be unnecessary and we could just check at test runtime, but that would make for very large and unwieldy test cases (ex: we have ~10 collision tests that use COLLISION_TESTED, which make much more sense when split by model than if they were glued together into a single giga-test).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hi, just following up here. While the change as constituted may not be perfect, it is better than the current state of affairs (simpler decorator functionality), and fixes two relatively more pressing issues:

  1. Unblocking future python version bumps by not returning from tests.
  2. Providing devs with a clearer error message when they trip this check in CI.

Copy link

codecov bot commented Dec 13, 2023

Codecov Report

Merging #61719 (de7898d) into master (826538a) will increase coverage by 0.00%.
Report is 82 commits behind head on master.
The diff coverage is n/a.

Additional details and impacted files
@@           Coverage Diff            @@
##           master   #61719    +/-   ##
========================================
  Coverage   81.14%   81.14%            
========================================
  Files        5191     5188     -3     
  Lines      228313   228526   +213     
  Branches    38275    38330    +55     
========================================
+ Hits       185261   185441   +180     
- Misses      37432    37456    +24     
- Partials     5620     5629     +9     

see 89 files with indirect coverage changes

@azaslavsky azaslavsky merged commit bbd0230 into master Dec 20, 2023
48 checks passed
@azaslavsky azaslavsky deleted the az/test-improve branch December 20, 2023 18:38
Copy link

sentry-io bot commented Dec 20, 2023

Suspect Issues

This pull request was deployed and Sentry observed the following issues:

  • ‼️ ControlOption.DoesNotExist: ControlOption matching query does not exist. pytest.runtest.protocol tests/sentry/backup/tes... View Issue
  • ‼️ OutboxFlushError: Could not flush shard category=0 (USER_UPDATE) pytest.runtest.protocol tests/sentry/backup/tes... View Issue
  • ‼️ ConnectionError: HTTPConnectionPool(host='testserver', port=80): Max retries exceeded with url: /api/0/relays/proj... pytest.runtest.protocol tests/sentry/backup/tes... View Issue

Did you find this useful? React with a 👍 or 👎

@asottile-sentry
Copy link
Member

this regressed this:

FAILED tests/sentry/backup/test_models.py::DynamicRelocationScopeTests::test_api_auth - DeprecationWarning: It is deprecated to return a value that is not None from a test case (<bound method DynamicRelocationScopeTests.test_api_auth of <sentry.testutils.silo.DynamicRelocationScopeTests testMethod=test_api_auth>>)
FAILED tests/sentry/backup/test_models.py::DynamicRelocationScopeTests::test_notification_action - DeprecationWarning: It is deprecated to return a value that is not None from a test case (<bound method DynamicRelocationScopeTests.test_notification_action of <sentry.testutils.silo.DynamicRelocationScopeTests testMethod=test_notification_action>>)

@asottile-sentry asottile-sentry added the Trigger: Revert add to a merged PR to revert it (skips CI) label Dec 21, 2023
@getsentry-bot
Copy link
Contributor

PR reverted: 2f81e77

getsentry-bot added a commit that referenced this pull request Dec 21, 2023
…ssage (#61719)"

This reverts commit bbd0230.

Co-authored-by: asottile-sentry <[email protected]>
azaslavsky added a commit that referenced this pull request Jan 2, 2024
@github-actions github-actions bot locked and limited conversation to collaborators Jan 6, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Trigger: Revert add to a merged PR to revert it (skips CI)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants