From 4e3bebe7720ba813c0c4c88696762003db68cdb7 Mon Sep 17 00:00:00 2001 From: Omar Selo Date: Fri, 1 Dec 2023 09:56:25 +0000 Subject: [PATCH 1/5] Rename jenkins_link to ci_link --- ...43821588_rename_jenkins_link_to_ci_link.py | 22 +++++++++++++++++++ .../controllers/artefacts/models.py | 2 +- .../test_executions/test_executions.py | 2 +- backend/test_observer/data_access/models.py | 4 ++-- .../controllers/artefacts/test_artefacts.py | 2 +- .../test_executions/test_test_executions.py | 2 +- 6 files changed, 28 insertions(+), 6 deletions(-) create mode 100644 backend/migrations/versions/2023_12_01_0949-8d8643821588_rename_jenkins_link_to_ci_link.py diff --git a/backend/migrations/versions/2023_12_01_0949-8d8643821588_rename_jenkins_link_to_ci_link.py b/backend/migrations/versions/2023_12_01_0949-8d8643821588_rename_jenkins_link_to_ci_link.py new file mode 100644 index 00000000..86373423 --- /dev/null +++ b/backend/migrations/versions/2023_12_01_0949-8d8643821588_rename_jenkins_link_to_ci_link.py @@ -0,0 +1,22 @@ +"""Rename jenkins_link to ci_link + +Revision ID: 8d8643821588 +Revises: 49221114815a +Create Date: 2023-12-01 09:49:44.849714+00:00 + +""" +from alembic import op + +# revision identifiers, used by Alembic. +revision = "8d8643821588" +down_revision = "49221114815a" +branch_labels = None +depends_on = None + + +def upgrade() -> None: + op.alter_column("test_execution", "jenkins_link", new_column_name="ci_link") + + +def downgrade() -> None: + op.alter_column("test_execution", "ci_link", new_column_name="jenkins_link") diff --git a/backend/test_observer/controllers/artefacts/models.py b/backend/test_observer/controllers/artefacts/models.py index 7578334e..ee334aec 100644 --- a/backend/test_observer/controllers/artefacts/models.py +++ b/backend/test_observer/controllers/artefacts/models.py @@ -47,7 +47,7 @@ class TestExecutionDTO(BaseModel): model_config = ConfigDict(from_attributes=True) id: int - jenkins_link: str | None + ci_link: str | None c3_link: str | None environment: EnvironmentDTO status: TestExecutionStatus diff --git a/backend/test_observer/controllers/test_executions/test_executions.py b/backend/test_observer/controllers/test_executions/test_executions.py index 0db6f17a..bf33a385 100644 --- a/backend/test_observer/controllers/test_executions/test_executions.py +++ b/backend/test_observer/controllers/test_executions/test_executions.py @@ -106,6 +106,6 @@ def patch_test_execution( ): test_execution = db.query(TestExecution).filter(TestExecution.id == id).one() test_execution.c3_link = request.c3_link - test_execution.jenkins_link = request.jenkins_link + test_execution.ci_link = request.jenkins_link test_execution.status = request.status db.commit() diff --git a/backend/test_observer/data_access/models.py b/backend/test_observer/data_access/models.py index 9cc2edf5..ec736bee 100644 --- a/backend/test_observer/data_access/models.py +++ b/backend/test_observer/data_access/models.py @@ -198,7 +198,7 @@ class TestExecution(Base): __tablename__ = "test_execution" - jenkins_link: Mapped[str] = mapped_column(String(200), nullable=True) + ci_link: Mapped[str] = mapped_column(String(200), nullable=True) c3_link: Mapped[str] = mapped_column(String(200), nullable=True) # Relationships artefact_build_id: Mapped[int] = mapped_column( @@ -222,6 +222,6 @@ def __repr__(self) -> str: "artefact_build_id", "environment_id", "status", - "jenkins_link", + "ci_link", "c3_link", ) diff --git a/backend/tests/controllers/artefacts/test_artefacts.py b/backend/tests/controllers/artefacts/test_artefacts.py index c3ea01f9..1c4648af 100644 --- a/backend/tests/controllers/artefacts/test_artefacts.py +++ b/backend/tests/controllers/artefacts/test_artefacts.py @@ -94,7 +94,7 @@ def test_get_artefact_builds(db_session: Session, test_client: TestClient): "test_executions": [ { "id": test_execution.id, - "jenkins_link": test_execution.jenkins_link, + "ci_link": test_execution.ci_link, "c3_link": test_execution.c3_link, "status": test_execution.status.value, "environment": { diff --git a/backend/tests/controllers/test_executions/test_test_executions.py b/backend/tests/controllers/test_executions/test_test_executions.py index 22df7ce9..a4f0688f 100644 --- a/backend/tests/controllers/test_executions/test_test_executions.py +++ b/backend/tests/controllers/test_executions/test_test_executions.py @@ -187,6 +187,6 @@ def test_updates_test_execution(db_session: Session, test_client: TestClient): ) db_session.refresh(test_execution) - assert test_execution.jenkins_link == "some jenkins link" + assert test_execution.ci_link == "some jenkins link" assert test_execution.c3_link == "some c3 link" assert test_execution.status == TestExecutionStatus.PASSED From ecf78ade09f188b7ebe098ed47ec66892f8851ec Mon Sep 17 00:00:00 2001 From: Omar Selo Date: Fri, 1 Dec 2023 10:40:20 +0000 Subject: [PATCH 2/5] Take ci_link from start of test execution --- backend/scripts/seed_data.py | 11 ++++++++++- .../controllers/test_executions/models.py | 3 ++- .../controllers/test_executions/test_executions.py | 1 + .../test_executions/test_test_executions.py | 6 +++++- 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/backend/scripts/seed_data.py b/backend/scripts/seed_data.py index 4cc33fa0..7e37151e 100644 --- a/backend/scripts/seed_data.py +++ b/backend/scripts/seed_data.py @@ -18,6 +18,7 @@ arch="armhf", execution_stage="beta", environment="rpi2", + ci_link="http://localhost", ), StartTestExecutionRequest( family=FamilyName.SNAP, @@ -29,6 +30,7 @@ arch="armhf", execution_stage="beta", environment="rpi2", + ci_link="http://localhost", ), StartTestExecutionRequest( family=FamilyName.SNAP, @@ -40,6 +42,7 @@ arch="armhf", execution_stage="beta", environment="rpi2", + ci_link="http://localhost", ), StartTestExecutionRequest( family=FamilyName.SNAP, @@ -51,6 +54,7 @@ arch="amd64", execution_stage="edge", environment="dawson-i", + ci_link="http://localhost", ), StartTestExecutionRequest( family=FamilyName.SNAP, @@ -62,6 +66,7 @@ arch="arm64", execution_stage="candidate", environment="cm3", + ci_link="http://localhost", ), StartTestExecutionRequest( family=FamilyName.SNAP, @@ -73,6 +78,7 @@ arch="arm64", execution_stage="stable", environment="cm3", + ci_link="http://localhost", ), StartTestExecutionRequest( family=FamilyName.SNAP, @@ -84,6 +90,7 @@ arch="arm64", execution_stage="stable", environment="dragonboard", + ci_link="http://localhost", ), StartTestExecutionRequest( family=FamilyName.DEB, @@ -94,6 +101,7 @@ arch="arm64", execution_stage="proposed", environment="rpi400", + ci_link="http://localhost", ), StartTestExecutionRequest( family=FamilyName.DEB, @@ -104,6 +112,7 @@ arch="arm64", execution_stage="updates", environment="rpi400", + ci_link="http://localhost", ), ] @@ -111,7 +120,7 @@ def seed_data(client: TestClient | requests.Session): for request in REQUESTS: client.put( - START_TEST_EXECUTION_URL, json=request.model_dump() + START_TEST_EXECUTION_URL, data=request.model_dump_json() ).raise_for_status() diff --git a/backend/test_observer/controllers/test_executions/models.py b/backend/test_observer/controllers/test_executions/models.py index 11906f61..f779716e 100644 --- a/backend/test_observer/controllers/test_executions/models.py +++ b/backend/test_observer/controllers/test_executions/models.py @@ -18,7 +18,7 @@ # Omar Selo -from pydantic import BaseModel, field_serializer, model_validator +from pydantic import BaseModel, HttpUrl, field_serializer, model_validator from test_observer.data_access.models_enums import FamilyName, TestExecutionStatus @@ -35,6 +35,7 @@ class StartTestExecutionRequest(BaseModel): arch: str execution_stage: str environment: str + ci_link: HttpUrl @field_serializer("family") def serialize_dt(self, family: FamilyName): diff --git a/backend/test_observer/controllers/test_executions/test_executions.py b/backend/test_observer/controllers/test_executions/test_executions.py index bf33a385..ad8a4edf 100644 --- a/backend/test_observer/controllers/test_executions/test_executions.py +++ b/backend/test_observer/controllers/test_executions/test_executions.py @@ -91,6 +91,7 @@ def start_test_execution( }, creation_kwargs={ "status": TestExecutionStatus.IN_PROGRESS, + "ci_link": request.ci_link, }, ) return {"id": test_execution.id} diff --git a/backend/tests/controllers/test_executions/test_test_executions.py b/backend/tests/controllers/test_executions/test_test_executions.py index a4f0688f..3a25098c 100644 --- a/backend/tests/controllers/test_executions/test_test_executions.py +++ b/backend/tests/controllers/test_executions/test_test_executions.py @@ -46,6 +46,7 @@ def test_creates_all_data_models(db_session: Session, test_client: TestClient): "arch": "arm64", "execution_stage": "beta", "environment": "cm3", + "ci_link": "http://localhost", }, ) @@ -109,6 +110,7 @@ def test_invalid_artefact_format(test_client: TestClient): "arch": "arm64", "execution_stage": "beta", "environment": "cm3", + "ci_link": "http://localhost", }, ) assert response.status_code == 422 @@ -125,6 +127,7 @@ def test_uses_existing_models(db_session: Session, test_client: TestClient): arch="arm64", execution_stage="beta", environment="cm3", + ci_link="http://localhost/", ) stage = ( db_session.query(Stage).filter(Stage.name == request.execution_stage).first() @@ -151,7 +154,7 @@ def test_uses_existing_models(db_session: Session, test_client: TestClient): test_execution_id = test_client.put( "/v1/test-executions/start-test", - json=request.model_dump(), + data=request.model_dump_json(), ).json()["id"] test_execution = ( @@ -163,6 +166,7 @@ def test_uses_existing_models(db_session: Session, test_client: TestClient): assert test_execution.artefact_build_id == artefact_build.id assert test_execution.environment_id == environment.id assert test_execution.status == TestExecutionStatus.IN_PROGRESS + assert test_execution.ci_link == "http://localhost/" def test_updates_test_execution(db_session: Session, test_client: TestClient): From 32944abebcccbf604227240c04fd8947567c2d2c Mon Sep 17 00:00:00 2001 From: Omar Selo Date: Fri, 1 Dec 2023 10:49:34 +0000 Subject: [PATCH 3/5] Optionally patch fields & rename jenkins to ci on TestExecution --- .../test_observer/controllers/test_executions/models.py | 6 +++--- .../controllers/test_executions/test_executions.py | 2 +- .../controllers/test_executions/test_test_executions.py | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/backend/test_observer/controllers/test_executions/models.py b/backend/test_observer/controllers/test_executions/models.py index f779716e..e7f1acf2 100644 --- a/backend/test_observer/controllers/test_executions/models.py +++ b/backend/test_observer/controllers/test_executions/models.py @@ -57,6 +57,6 @@ def validate_required_fields(self) -> "StartTestExecutionRequest": class TestExecutionsPatchRequest(BaseModel): - c3_link: str - jenkins_link: str - status: TestExecutionStatus + c3_link: HttpUrl | None + ci_link: HttpUrl | None + status: TestExecutionStatus | None diff --git a/backend/test_observer/controllers/test_executions/test_executions.py b/backend/test_observer/controllers/test_executions/test_executions.py index ad8a4edf..509c6191 100644 --- a/backend/test_observer/controllers/test_executions/test_executions.py +++ b/backend/test_observer/controllers/test_executions/test_executions.py @@ -107,6 +107,6 @@ def patch_test_execution( ): test_execution = db.query(TestExecution).filter(TestExecution.id == id).one() test_execution.c3_link = request.c3_link - test_execution.ci_link = request.jenkins_link + test_execution.ci_link = request.ci_link test_execution.status = request.status db.commit() diff --git a/backend/tests/controllers/test_executions/test_test_executions.py b/backend/tests/controllers/test_executions/test_test_executions.py index 3a25098c..01f393f3 100644 --- a/backend/tests/controllers/test_executions/test_test_executions.py +++ b/backend/tests/controllers/test_executions/test_test_executions.py @@ -184,13 +184,13 @@ def test_updates_test_execution(db_session: Session, test_client: TestClient): test_client.patch( f"/v1/test-executions/{test_execution.id}", json={ - "jenkins_link": "some jenkins link", - "c3_link": "some c3 link", + "ci_link": "http://ci_link/", + "c3_link": "http://c3_link/", "status": TestExecutionStatus.PASSED.name, }, ) db_session.refresh(test_execution) - assert test_execution.ci_link == "some jenkins link" - assert test_execution.c3_link == "some c3 link" + assert test_execution.ci_link == "http://ci_link/" + assert test_execution.c3_link == "http://c3_link/" assert test_execution.status == TestExecutionStatus.PASSED From bf0f0daeed37c27b71dc08cdfeb9681faf55a2e6 Mon Sep 17 00:00:00 2001 From: Omar Selo Date: Fri, 1 Dec 2023 14:07:23 +0300 Subject: [PATCH 4/5] Rename jenkins link to ci link --- frontend/lib/models/test_execution.dart | 2 +- frontend/lib/ui/dashboard/artefact_dialog.dart | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/frontend/lib/models/test_execution.dart b/frontend/lib/models/test_execution.dart index 034e6d40..476e6010 100644 --- a/frontend/lib/models/test_execution.dart +++ b/frontend/lib/models/test_execution.dart @@ -12,7 +12,7 @@ part 'test_execution.g.dart'; class TestExecution with _$TestExecution { const factory TestExecution({ required int id, - @JsonKey(name: 'jenkins_link') required String? jenkinsLink, + @JsonKey(name: 'ci_link') required String? ciLink, @JsonKey(name: 'c3_link') required String? c3Link, required TestExecutionStatus status, required Environment environment, diff --git a/frontend/lib/ui/dashboard/artefact_dialog.dart b/frontend/lib/ui/dashboard/artefact_dialog.dart index adf7899a..c0186e23 100644 --- a/frontend/lib/ui/dashboard/artefact_dialog.dart +++ b/frontend/lib/ui/dashboard/artefact_dialog.dart @@ -271,7 +271,7 @@ class _TestExecutionView extends StatelessWidget { @override Widget build(BuildContext context) { - final jenkinsLink = testExecution.jenkinsLink; + final ciLink = testExecution.ciLink; final c3Link = testExecution.c3Link; return YaruExpandable( @@ -286,10 +286,10 @@ class _TestExecutionView extends StatelessWidget { const Spacer(), Row( children: [ - if (jenkinsLink != null) + if (ciLink != null) InlineUrlText( - url: jenkinsLink, - urlText: 'Jenkins', + url: ciLink, + urlText: 'CI', ), const SizedBox(width: Spacing.level3), if (c3Link != null) From e5b62db50e40efad8fd986ee156b54157c35d46b Mon Sep 17 00:00:00 2001 From: Omar Selo Date: Fri, 1 Dec 2023 12:19:20 +0000 Subject: [PATCH 5/5] Fix mypy issues --- backend/scripts/seed_data.py | 2 +- .../controllers/test_executions/models.py | 4 +++- .../test_executions/test_executions.py | 18 ++++++++++++++---- backend/test_observer/data_access/models.py | 4 ++-- .../test_executions/test_test_executions.py | 2 +- 5 files changed, 21 insertions(+), 9 deletions(-) diff --git a/backend/scripts/seed_data.py b/backend/scripts/seed_data.py index 7e37151e..07100cc6 100644 --- a/backend/scripts/seed_data.py +++ b/backend/scripts/seed_data.py @@ -120,7 +120,7 @@ def seed_data(client: TestClient | requests.Session): for request in REQUESTS: client.put( - START_TEST_EXECUTION_URL, data=request.model_dump_json() + START_TEST_EXECUTION_URL, json=request.model_dump(mode="json") ).raise_for_status() diff --git a/backend/test_observer/controllers/test_executions/models.py b/backend/test_observer/controllers/test_executions/models.py index e7f1acf2..12cfc555 100644 --- a/backend/test_observer/controllers/test_executions/models.py +++ b/backend/test_observer/controllers/test_executions/models.py @@ -18,6 +18,8 @@ # Omar Selo +from typing import Annotated + from pydantic import BaseModel, HttpUrl, field_serializer, model_validator from test_observer.data_access.models_enums import FamilyName, TestExecutionStatus @@ -35,7 +37,7 @@ class StartTestExecutionRequest(BaseModel): arch: str execution_stage: str environment: str - ci_link: HttpUrl + ci_link: Annotated[str, HttpUrl] @field_serializer("family") def serialize_dt(self, family: FamilyName): diff --git a/backend/test_observer/controllers/test_executions/test_executions.py b/backend/test_observer/controllers/test_executions/test_executions.py index 509c6191..d56c2306 100644 --- a/backend/test_observer/controllers/test_executions/test_executions.py +++ b/backend/test_observer/controllers/test_executions/test_executions.py @@ -105,8 +105,18 @@ def patch_test_execution( request: TestExecutionsPatchRequest, db: Session = Depends(get_db), ): - test_execution = db.query(TestExecution).filter(TestExecution.id == id).one() - test_execution.c3_link = request.c3_link - test_execution.ci_link = request.ci_link - test_execution.status = request.status + test_execution = db.get(TestExecution, id) + + if test_execution is None: + raise HTTPException(status_code=404, detail="TestExecution not found") + + if request.c3_link is not None: + test_execution.c3_link = str(request.c3_link) + + if request.ci_link is not None: + test_execution.ci_link = str(request.ci_link) + + if request.status is not None: + test_execution.status = request.status + db.commit() diff --git a/backend/test_observer/data_access/models.py b/backend/test_observer/data_access/models.py index ec736bee..5d515359 100644 --- a/backend/test_observer/data_access/models.py +++ b/backend/test_observer/data_access/models.py @@ -198,8 +198,8 @@ class TestExecution(Base): __tablename__ = "test_execution" - ci_link: Mapped[str] = mapped_column(String(200), nullable=True) - c3_link: Mapped[str] = mapped_column(String(200), nullable=True) + ci_link: Mapped[str | None] = mapped_column(String(200), nullable=True) + c3_link: Mapped[str | None] = mapped_column(String(200), nullable=True) # Relationships artefact_build_id: Mapped[int] = mapped_column( ForeignKey("artefact_build.id", ondelete="CASCADE") diff --git a/backend/tests/controllers/test_executions/test_test_executions.py b/backend/tests/controllers/test_executions/test_test_executions.py index 01f393f3..b3fc7c35 100644 --- a/backend/tests/controllers/test_executions/test_test_executions.py +++ b/backend/tests/controllers/test_executions/test_test_executions.py @@ -154,7 +154,7 @@ def test_uses_existing_models(db_session: Session, test_client: TestClient): test_execution_id = test_client.put( "/v1/test-executions/start-test", - data=request.model_dump_json(), + json=request.model_dump(mode="json"), ).json()["id"] test_execution = (