-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
test(backup): Create first model test
This creates a second test file for tests of specific models. The eventual end-goal here is to test all models that have `__include_in_export = True` set. This is the first change supporting that work, focused mostly on adding a single proof-of-concept test (for organizations), along with the scaffolding that will make adding more such tests easier. Issue: getsentry/team-ospo/#156
- Loading branch information
1 parent
8839b6d
commit 0dec276
Showing
3 changed files
with
97 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
from __future__ import annotations | ||
|
||
from pathlib import Path | ||
|
||
from click.testing import CliRunner | ||
|
||
from sentry.runner.commands.backup import ComparatorFindings, export | ||
from sentry.utils import json | ||
|
||
|
||
class ValidationError(Exception): | ||
def __init__(self, info: ComparatorFindings): | ||
super().__init__(info.pretty()) | ||
self.info = info | ||
|
||
|
||
def tmp_export_to_file(tmp_path: Path) -> json.JSONData: | ||
"""Helper function that exports the current state of the database to the specified file.""" | ||
|
||
tmp_json_file_path = str(tmp_path) | ||
rv = CliRunner().invoke( | ||
export, [tmp_json_file_path], obj={"silent": True, "indent": 2, "exclude": None} | ||
) | ||
assert rv.exit_code == 0, rv.output | ||
|
||
with open(tmp_json_file_path) as tmp_file: | ||
output = json.load(tmp_file) | ||
return output |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
from __future__ import annotations | ||
|
||
import atexit | ||
import tempfile | ||
from pathlib import Path | ||
|
||
from click.testing import CliRunner | ||
from django.core.management import call_command | ||
|
||
from sentry.db.postgres.roles import in_test_psql_role_override | ||
from sentry.runner.commands.backup import import_, validate | ||
from sentry.testutils import TransactionTestCase | ||
from tests.sentry.backup import ValidationError, tmp_export_to_file | ||
|
||
|
||
class ModelBackupTests(TransactionTestCase): | ||
"""Test the JSON-ification of models marked `__include_in_export__ = True`. Each test here | ||
creates a fresh database, performs some writes to it, then exports that data into a temporary | ||
file (called the "expected" JSON). It then imports the "expected" JSON and re-exports it into | ||
the "actual" JSON file, and diffs the two to ensure that they match per the specified | ||
comparators.""" | ||
|
||
def setUp(self): | ||
# Create a temporary directory for JSON exports. | ||
self.tmp_dir = tempfile.TemporaryDirectory() | ||
atexit.register(self.tmp_dir.cleanup) | ||
|
||
# Reset the Django database. | ||
call_command("flush", verbosity=0, interactive=False) | ||
|
||
# Generate temporary filenames for the expected and actual JSON files. | ||
self.tmp_expect = Path(self.tmp_dir.name) / f"{self._testMethodName}.expect.json" | ||
self.tmp_actual = Path(self.tmp_dir.name) / f"{self._testMethodName}.actual.json" | ||
|
||
def tearDown(self): | ||
self.tmp_dir.cleanup() | ||
|
||
def import_export_then_validate(self): | ||
"""Test helper that validates that data imported from a temporary `.json` file correctly | ||
matches the actual outputted export data.""" | ||
|
||
# Export the current state of the database into the "expected" temporary file, then parse it | ||
# into a JSON object for comparison. | ||
expect = tmp_export_to_file(self.tmp_expect) | ||
|
||
# Reset the Django database. | ||
call_command("flush", verbosity=0, interactive=False) | ||
|
||
# Write the contents of the "expected" JSON file into the now clean database. | ||
with in_test_psql_role_override("postgres"): | ||
rv = CliRunner().invoke(import_, [str(self.tmp_expect)]) | ||
assert rv.exit_code == 0, rv.output | ||
|
||
# Validate that the "expected" and "actual" JSON matches. | ||
actual = tmp_export_to_file(self.tmp_actual) | ||
res = validate(expect, actual) | ||
if res.findings: | ||
raise ValidationError(res) | ||
|
||
def test_organization(self): | ||
user = self.create_user() | ||
self.create_organization(owner=user) | ||
self.import_export_then_validate() |