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

Fix artefact build uniqueness #30

Merged
merged 7 commits into from
Jun 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
"""Use nulls not distinct

Revision ID: b33ee8dd41b1
Revises: 6a80dad01d24
Create Date: 2023-06-20 10:00:07.676129+00:00

"""
from alembic import op


# revision identifiers, used by Alembic.
revision = "b33ee8dd41b1"
down_revision = "6a80dad01d24"
branch_labels = None
depends_on = None


def upgrade() -> None:
op.execute(
"ALTER TABLE artefact_build "
"DROP CONSTRAINT IF EXISTS artefact_build_artefact_id_architecture_revision_key"
", ADD CONSTRAINT unique_artefact_build "
"UNIQUE NULLS NOT DISTINCT (artefact_id, architecture, revision);"
)


def downgrade() -> None:
op.execute(
"ALTER TABLE artefact_build "
"DROP CONSTRAINT IF EXISTS unique_artefact_build"
", ADD CONSTRAINT artefact_build_artefact_id_architecture_revision_key "
"UNIQUE (artefact_id, architecture, revision);"
)
399 changes: 200 additions & 199 deletions backend/poetry.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion backend/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ authors = []
python = "^3.10"
fastapi = "^0.95.0"
uvicorn = {extras = ["standard"], version = "^0.21.1"}
sqlalchemy = "^2.0.9"
sqlalchemy = "^2.0.16"
pg8000 = "^1.29.4"
alembic = "^1.10.3"
poetry-dynamic-versioning = {extras = ["plugin"], version = "^0.22.0"}
Expand Down
10 changes: 9 additions & 1 deletion backend/test_observer/data_access/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,15 @@ class ArtefactBuild(Base):
back_populates="artefact_build", cascade="all, delete-orphan"
)

__table_args__ = (UniqueConstraint("artefact_id", "architecture", "revision"),)
__table_args__ = (
UniqueConstraint(
"artefact_id",
"architecture",
"revision",
name="unique_artefact_build",
postgresql_nulls_not_distinct=True,
),
)


class Environment(Base):
Expand Down
6 changes: 3 additions & 3 deletions backend/tests/controllers/artefacts/test_artefacts.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,19 @@
from sqlalchemy.orm import Session
from test_observer.data_access.models import ArtefactBuild, Environment, TestExecution

from tests.helpers import create_artefact, create_artefact_builds
from tests.helpers import create_artefact


def test_get_artefact_builds(db_session: Session, test_client: TestClient):
artefact = create_artefact(db_session, "beta")
artefact_build = create_artefact_builds(db_session, artefact, 1)[0]
artefact_build = ArtefactBuild(architecture="amd64", artefact=artefact, revision=1)
environment = Environment(
name="some-environment", architecture=artefact_build.architecture
)
test_execution = TestExecution(
artefact_build=artefact_build, environment=environment
)
db_session.add_all([environment, test_execution])
db_session.add_all([environment, test_execution, artefact_build])
db_session.commit()

response = test_client.get(f"/v1/artefacts/{artefact.id}/builds")
Expand Down
16 changes: 13 additions & 3 deletions backend/tests/controllers/promoter/test_promoter.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@
from fastapi.testclient import TestClient
from requests_mock import Mocker
from sqlalchemy.orm import Session
from test_observer.data_access.models import ArtefactBuild

from tests.helpers import create_artefact, create_artefact_builds
from tests.helpers import create_artefact


def test_run_to_move_artefact_snap(
Expand All @@ -45,7 +46,6 @@ def test_run_to_move_artefact_snap(
source={"store": "ubuntu"},
created_at=datetime.utcnow(),
)
create_artefact_builds(db_session, artefact)
omar-selo marked this conversation as resolved.
Show resolved Hide resolved
create_artefact(
db_session,
"edge",
Expand All @@ -54,6 +54,15 @@ def test_run_to_move_artefact_snap(
source={"store": "ubuntu"},
created_at=datetime.utcnow() - timedelta(days=1),
)
db_session.add_all(
[
ArtefactBuild(architecture="amd64", artefact=artefact, revision=1),
ArtefactBuild(architecture="amd64", artefact=artefact, revision=2),
ArtefactBuild(architecture="arm64", artefact=artefact, revision=1),
]
)
db_session.commit()

requests_mock.get(
"https://api.snapcraft.io/v2/snaps/info/core20",
json={
Expand Down Expand Up @@ -106,7 +115,6 @@ def test_run_to_move_artefact_deb(
source={"series": "kinetic", "repo": "main"},
created_at=datetime.utcnow(),
)
create_artefact_builds(db_session, artefact)
create_artefact(
db_session,
"proposed",
Expand All @@ -115,6 +123,8 @@ def test_run_to_move_artefact_deb(
source={"series": "kinetic", "repo": "main"},
created_at=datetime.utcnow() - timedelta(days=1),
)
db_session.add(ArtefactBuild(architecture="amd64", artefact=artefact))
db_session.commit()

with open("tests/test_data/Packages-proposed.gz", "rb") as f:
proposed_content = f.read()
Expand Down
32 changes: 1 addition & 31 deletions backend/tests/helpers.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
from random import choice
from datetime import datetime

from sqlalchemy.orm import Session
from test_observer.data_access.models import Artefact, Stage, ArtefactBuild
from test_observer.data_access.models_enums import FamilyName
from test_observer.data_access.models import Artefact, Stage


def create_artefact(db_session: Session, stage_name: str, **kwargs) -> Artefact:
Expand All @@ -19,31 +17,3 @@ def create_artefact(db_session: Session, stage_name: str, **kwargs) -> Artefact:
db_session.add(artefact)
db_session.commit()
return artefact


def create_artefact_builds(
db_session: Session, artefact: Artefact, num_builds: int = 5
) -> list[ArtefactBuild]:
"""
Create a number of ArtefactBuild instances for an Artefact and add them
to the database
"""
architectures = ["arm64", "x86", "amd64"]
nadzyah marked this conversation as resolved.
Show resolved Hide resolved

for i in range(num_builds):
architecture = choice(architectures)

build = ArtefactBuild(
architecture=architecture,
revision=i + 1
if artefact.stage.family.name == FamilyName.SNAP.value
else None,
artefact_id=artefact.id,
)

# Add the build to the artefact's builds
artefact.builds.append(build)

# Commit the changes to the database
db_session.commit()
return artefact.builds