mirror of
https://github.com/hanzoai/sentinel.git
synced 2026-09-29 22:34:33 +00:00
235 lines
8.3 KiB
Python
235 lines
8.3 KiB
Python
from __future__ import annotations
|
|
|
|
from datetime import timedelta
|
|
from typing import Any
|
|
from unittest.mock import Mock, patch
|
|
|
|
import pytest
|
|
from django.utils import timezone
|
|
|
|
from sentry.exceptions import HookValidationError
|
|
from sentry.models.commit import Commit
|
|
from sentry.models.deploy import Deploy
|
|
from sentry.models.environment import Environment
|
|
from sentry.models.options.project_option import ProjectOption
|
|
from sentry.models.release import Release
|
|
from sentry.models.releasecommit import ReleaseCommit
|
|
from sentry.models.releaseheadcommit import ReleaseHeadCommit
|
|
from sentry.models.repository import Repository
|
|
from sentry.testutils.cases import TestCase
|
|
from sentry.testutils.silo import region_silo_test
|
|
from sentry.utils import json
|
|
from sentry_plugins.heroku.plugin import HerokuReleaseHook
|
|
|
|
|
|
@region_silo_test
|
|
class SetRefsTest(TestCase):
|
|
"""
|
|
tests that when finish_release is called on a release hook,
|
|
we try to get the previous commits based on the version ref
|
|
and that we create `ReleaseHeadCommit`s for the version
|
|
"""
|
|
|
|
@patch("sentry.tasks.commits.fetch_commits")
|
|
def test_minimal(self, mock_fetch_commits):
|
|
project = self.create_project()
|
|
version = "bbee5b51f84611e4b14834363b8514c2"
|
|
data_list = [
|
|
{
|
|
"id": "c7155651831549cf8a5e47889fce17eb",
|
|
"message": "foo",
|
|
"author_email": "[email protected]",
|
|
},
|
|
{
|
|
"id": "62de626b7c7cfb8e77efb4273b1a3df4123e6216",
|
|
"message": "hello",
|
|
"author_name": "Jess",
|
|
},
|
|
{
|
|
"id": "58de626b7c7cfb8e77efb4273b1a3df4123e6345",
|
|
"message": "bar",
|
|
"author_name": "Joe^^",
|
|
},
|
|
{
|
|
"id": "bbee5b51f84611e4b14834363b8514c2",
|
|
"message": "blah",
|
|
"author_email": "[email protected]",
|
|
},
|
|
]
|
|
user = self.create_user(email="[email protected]")
|
|
repo = Repository.objects.create(
|
|
organization_id=project.organization_id, name=project.name, provider="dummy"
|
|
)
|
|
ProjectOption.objects.set_value(key="heroku:repository", project=project, value=repo.name)
|
|
for data in data_list:
|
|
Commit.objects.create(
|
|
key=data["id"], organization_id=self.project.organization_id, repository_id=repo.id
|
|
)
|
|
|
|
old_release = Release.objects.create(
|
|
version="a" * 40,
|
|
organization_id=project.organization_id,
|
|
date_added=timezone.now() - timedelta(minutes=30),
|
|
)
|
|
old_release.add_project(project)
|
|
|
|
ReleaseCommit.objects.create(
|
|
organization_id=project.organization_id,
|
|
project_id=project.id,
|
|
release=old_release,
|
|
commit=Commit.objects.get(key="c7155651831549cf8a5e47889fce17eb"),
|
|
order=0,
|
|
)
|
|
ReleaseHeadCommit.objects.create(
|
|
organization_id=project.organization_id,
|
|
repository_id=repo.id,
|
|
release=old_release,
|
|
commit=Commit.objects.get(key="c7155651831549cf8a5e47889fce17eb"),
|
|
)
|
|
release_heads = ReleaseHeadCommit.objects.filter(
|
|
organization_id=project.organization_id,
|
|
repository_id=repo.id,
|
|
commit=Commit.objects.get(key="bbee5b51f84611e4b14834363b8514c2"),
|
|
)
|
|
|
|
assert len(release_heads) == 0
|
|
hook = HerokuReleaseHook(project)
|
|
hook.finish_release(version=version, owner_id=user.id)
|
|
|
|
release = Release.objects.get(projects=project, version=version)
|
|
|
|
new_release_heads = ReleaseHeadCommit.objects.filter(
|
|
organization_id=project.organization_id,
|
|
repository_id=repo.id,
|
|
release=release,
|
|
commit=Commit.objects.get(key="bbee5b51f84611e4b14834363b8514c2"),
|
|
)
|
|
assert len(new_release_heads) == 1
|
|
assert release.version == "bbee5b51f84611e4b14834363b8514c2"
|
|
|
|
deploy = Deploy.objects.filter(
|
|
organization_id=project.organization_id,
|
|
release=release,
|
|
environment_id=Environment.objects.get(
|
|
organization_id=project.organization_id, name="production"
|
|
).id,
|
|
)
|
|
assert len(deploy) == 1
|
|
|
|
mock_fetch_commits.apply_async.assert_called_with(
|
|
kwargs={
|
|
"release_id": release.id,
|
|
"user_id": user.id,
|
|
"refs": [{"commit": "bbee5b51f84611e4b14834363b8514c2", "repository": repo.name}],
|
|
"prev_release_id": old_release.id,
|
|
}
|
|
)
|
|
|
|
|
|
@region_silo_test
|
|
class HookHandleTest(TestCase):
|
|
@pytest.fixture(autouse=True)
|
|
def patch_is_valid_signature(self):
|
|
with patch.object(HerokuReleaseHook, "is_valid_signature"):
|
|
yield
|
|
|
|
@patch.object(HerokuReleaseHook, "set_refs")
|
|
def test_user_success(self, set_refs_mock):
|
|
user = self.create_user()
|
|
organization = self.create_organization(owner=user)
|
|
project = self.create_project(organization=organization)
|
|
hook = HerokuReleaseHook(project)
|
|
|
|
req = Mock()
|
|
body: dict[str, Any] = {
|
|
"data": {
|
|
"user": {"email": user.email},
|
|
"slug": {"commit": "abcd123"},
|
|
"app": {"name": "example"},
|
|
},
|
|
"action": "update",
|
|
}
|
|
req.body = bytes(json.dumps(body), "utf-8")
|
|
hook.handle(req)
|
|
assert Release.objects.filter(version=body["data"]["slug"]["commit"]).exists()
|
|
assert set_refs_mock.call_count == 1
|
|
|
|
@patch.object(HerokuReleaseHook, "set_refs")
|
|
def test_only_run_on_update(self, set_refs_mock):
|
|
user = self.create_user()
|
|
organization = self.create_organization(owner=user)
|
|
project = self.create_project(organization=organization)
|
|
hook = HerokuReleaseHook(project)
|
|
|
|
req = Mock()
|
|
body: dict[str, Any] = {
|
|
"data": {
|
|
"user": {"email": user.email},
|
|
"slug": {"commit": "abcd123"},
|
|
"app": {"name": "example"},
|
|
},
|
|
"action": "create",
|
|
}
|
|
req.body = bytes(json.dumps(body), "utf-8")
|
|
hook.handle(req)
|
|
assert not Release.objects.filter(version=body["data"]["slug"]["commit"]).exists()
|
|
assert set_refs_mock.call_count == 0
|
|
|
|
@patch.object(HerokuReleaseHook, "set_refs")
|
|
def test_actor_email_success(self, set_refs_mock):
|
|
user = self.create_user()
|
|
organization = self.create_organization(owner=user)
|
|
project = self.create_project(organization=organization)
|
|
hook = HerokuReleaseHook(project)
|
|
|
|
req = Mock()
|
|
body: dict[str, Any] = {
|
|
"data": {
|
|
"actor": {"email": user.email},
|
|
"slug": {"commit": "abcd123"},
|
|
"app": {"name": "example"},
|
|
},
|
|
"action": "update",
|
|
}
|
|
req.body = bytes(json.dumps(body), "utf-8")
|
|
hook.handle(req)
|
|
assert Release.objects.filter(version=body["data"]["slug"]["commit"]).exists()
|
|
assert set_refs_mock.call_count == 1
|
|
|
|
def test_email_mismatch(self):
|
|
user = self.create_user()
|
|
organization = self.create_organization(owner=user)
|
|
project = self.create_project(organization=organization)
|
|
hook = HerokuReleaseHook(project)
|
|
|
|
req = Mock()
|
|
body: dict[str, Any] = {
|
|
"data": {
|
|
"user": {"email": "[email protected]"},
|
|
"slug": {"commit": "v999"},
|
|
"app": {"name": "example"},
|
|
},
|
|
"action": "update",
|
|
}
|
|
req.body = bytes(json.dumps(body), "utf-8")
|
|
hook.handle(req)
|
|
assert Release.objects.filter(version=body["data"]["slug"]["commit"]).exists()
|
|
|
|
def test_bad_version(self):
|
|
project = self.create_project()
|
|
user = self.create_user()
|
|
hook = HerokuReleaseHook(project)
|
|
|
|
req = Mock()
|
|
body = {
|
|
"data": {
|
|
"actor": {"email": user.email},
|
|
"slug": {"commit": ""},
|
|
"app": {"name": "example"},
|
|
},
|
|
"action": "update",
|
|
}
|
|
req.body = bytes(json.dumps(body), "utf-8")
|
|
with pytest.raises(HookValidationError):
|
|
hook.handle(req)
|