-
-
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.
feat(backup): Use model save (#55432)
Prior to this change, we used the `save()` method from the Django serializer. But this is a "raw" save - it performs no validaion, and triggers no signals. Instead, we now use the re-hydrated model's own save method, which does perform these actions. Because of this, a few tests have had to change to account for signal triggering. In particular, `User`, `Organization`, and `Project` writes now auto-create some models, so we account for this in tests as well.
- Loading branch information
1 parent
ac8e994
commit 38f4955
Showing
12 changed files
with
135 additions
and
45 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
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
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
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
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
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 |
---|---|---|
|
@@ -17,8 +17,14 @@ | |
from sentry.backup.scopes import ExportScope, RelocationScope | ||
from sentry.models.authenticator import Authenticator | ||
from sentry.models.email import Email | ||
from sentry.models.options.project_option import ProjectOption | ||
from sentry.models.organization import Organization | ||
from sentry.models.organizationmapping import OrganizationMapping | ||
from sentry.models.organizationmember import OrganizationMember | ||
from sentry.models.organizationmembermapping import OrganizationMemberMapping | ||
from sentry.models.orgauthtoken import OrgAuthToken | ||
from sentry.models.project import Project | ||
from sentry.models.projectkey import ProjectKey | ||
from sentry.models.user import User | ||
from sentry.models.useremail import UserEmail | ||
from sentry.models.userip import UserIP | ||
|
@@ -163,6 +169,61 @@ def export_to_tmp_file_and_clear_database(self, tmp_dir) -> Path: | |
return tmp_path | ||
|
||
|
||
@run_backup_tests_only_on_single_db | ||
class SignalingTests(ImportTestCase): | ||
""" | ||
Some models are automatically created via signals and similar automagic from related models. We test that behavior here. | ||
""" | ||
|
||
def test_import_signaling_user(self): | ||
self.create_exhaustive_user("user", email="[email protected]") | ||
|
||
with tempfile.TemporaryDirectory() as tmp_dir: | ||
tmp_path = self.export_to_tmp_file_and_clear_database(tmp_dir) | ||
with open(tmp_path) as tmp_file: | ||
import_in_user_scope(tmp_file, printer=NOOP_PRINTER) | ||
|
||
assert User.objects.count() == 1 | ||
assert User.objects.filter(email="[email protected]").exists() | ||
|
||
assert UserEmail.objects.count() == 1 | ||
assert UserEmail.objects.filter(email="[email protected]").exists() | ||
|
||
assert Email.objects.count() == 1 | ||
assert Email.objects.filter(email="[email protected]").exists() | ||
|
||
def test_import_signaling_organization(self): | ||
owner = self.create_exhaustive_user("owner") | ||
invited = self.create_exhaustive_user("invited") | ||
member = self.create_exhaustive_user("member") | ||
self.create_exhaustive_organization("some-org", owner, invited, [member]) | ||
|
||
with tempfile.TemporaryDirectory() as tmp_dir: | ||
tmp_path = self.export_to_tmp_file_and_clear_database(tmp_dir) | ||
with open(tmp_path) as tmp_file: | ||
import_in_organization_scope(tmp_file, printer=NOOP_PRINTER) | ||
|
||
assert Organization.objects.count() == 1 | ||
assert Organization.objects.filter(slug="some-org").exists() | ||
|
||
assert OrganizationMapping.objects.count() == 1 | ||
assert OrganizationMapping.objects.filter(slug="some-org").exists() | ||
|
||
assert OrganizationMember.objects.count() == 3 | ||
assert OrganizationMemberMapping.objects.count() == 3 | ||
|
||
# The exhaustive org has 2 projects which automatically get 1 key and 3 options each. | ||
assert Project.objects.count() == 2 | ||
assert Project.objects.filter(name="project-some-org").exists() | ||
assert Project.objects.filter(name="other-project-some-org").exists() | ||
|
||
assert ProjectKey.objects.count() == 2 | ||
assert ProjectOption.objects.count() == 6 | ||
assert ProjectOption.objects.filter(key="sentry:relay-rev").exists() | ||
assert ProjectOption.objects.filter(key="sentry:relay-rev-lastchange").exists() | ||
assert ProjectOption.objects.filter(key="sentry:option-epoch").exists() | ||
|
||
|
||
@run_backup_tests_only_on_single_db | ||
class ScopingTests(ImportTestCase): | ||
""" | ||
|
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