-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
* Initial implementation of UI for showing percentage completed * Fix error when loading artefact builds * Update code to show exact counts * Fix import issues * Fix mypy errors * Fix issue with tests * Add doc-string to new helper methods * Implement new logic for fetching * Fix ruff issue * Remove unnecessary changes on frontend * Small improvements * Fix user avatar * Implement PR suggestions * Fix automated tests * Fix mypy errors
- Loading branch information
1 parent
e8b9fef
commit a339e5b
Showing
15 changed files
with
250 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
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 |
---|---|---|
|
@@ -18,6 +18,7 @@ | |
# Nadzeya Hutsko <[email protected]> | ||
# Omar Selo <[email protected]> | ||
|
||
from collections import defaultdict | ||
from datetime import date, datetime, timedelta | ||
from typing import TypeVar | ||
|
||
|
@@ -207,6 +208,28 @@ def is_kernel(self) -> bool: | |
"""Kernel artefacts start with 'linix-' or end with '-kernel'""" | ||
return self.name.startswith("linux-") or self.name.endswith("-kernel") | ||
|
||
def _get_latest_builds(self) -> list["ArtefactBuild"]: | ||
# Group builds by architecture | ||
grouped_builds = defaultdict(list) | ||
for build in self.builds: | ||
grouped_builds[build.architecture].append(build) | ||
|
||
return [ | ||
max(builds, key=lambda b: b.revision if b.revision else 0) | ||
for builds in grouped_builds.values() | ||
] | ||
|
||
@property | ||
def all_test_executions_count(self) -> int: | ||
return sum(len(ab.test_executions) for ab in self._get_latest_builds()) | ||
|
||
@property | ||
def completed_test_executions_count(self) -> int: | ||
return sum( | ||
len([te for te in ab.test_executions if te.review_decision]) | ||
for ab in self._get_latest_builds() | ||
) | ||
|
||
|
||
class ArtefactBuild(Base): | ||
"""A model to represent specific builds of artefact (e.g. arm64 revision 2)""" | ||
|
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 |
---|---|---|
|
@@ -19,6 +19,8 @@ | |
# Nadzeya Hutsko <[email protected]> | ||
from datetime import date, timedelta | ||
|
||
from sqlalchemy.orm import Session | ||
|
||
from fastapi.testclient import TestClient | ||
|
||
from test_observer.data_access.models import TestExecution | ||
|
@@ -64,6 +66,8 @@ def test_get_latest_artefacts_by_family( | |
else None | ||
), | ||
"bug_link": "", | ||
"all_test_executions_count": 0, | ||
"completed_test_executions_count": 0, | ||
} | ||
] | ||
|
||
|
@@ -100,9 +104,62 @@ def test_get_artefact(test_client: TestClient, generator: DataGenerator): | |
}, | ||
"due_date": "2024-12-24", | ||
"bug_link": a.bug_link, | ||
"all_test_executions_count": 0, | ||
"completed_test_executions_count": 0, | ||
} | ||
|
||
|
||
def test_get_artefact_test_execution_counts_only_latest_build( | ||
test_client: TestClient, generator: DataGenerator | ||
): | ||
a = generator.gen_artefact("beta") | ||
ab = generator.gen_artefact_build(artefact=a, revision=1) | ||
e = generator.gen_environment() | ||
# Test Execution for the first artefact build | ||
generator.gen_test_execution(ab, e) | ||
|
||
ab_second = generator.gen_artefact_build(artefact=a, revision=2) | ||
# Test Execution for the second artefact build | ||
generator.gen_test_execution( | ||
artefact_build=ab_second, | ||
environment=e, | ||
review_decision=[TestExecutionReviewDecision.APPROVED_ALL_TESTS_PASS], | ||
) | ||
|
||
response = test_client.get(f"/v1/artefacts/{a.id}") | ||
assert response.status_code == 200 | ||
# Verify only the counts of the latest build is returned | ||
assert response.json()["all_test_executions_count"] == 1 | ||
assert response.json()["completed_test_executions_count"] == 1 | ||
|
||
|
||
def test_get_artefact_test_execution_counts( | ||
test_client: TestClient, | ||
generator: DataGenerator, | ||
db_session: Session, | ||
): | ||
a = generator.gen_artefact("beta") | ||
ab = generator.gen_artefact_build(a) | ||
e = generator.gen_environment() | ||
te = generator.gen_test_execution(ab, e) | ||
|
||
# Verify completed test execution count is zero, it is not reviewed yet | ||
response = test_client.get(f"/v1/artefacts/{a.id}") | ||
assert response.status_code == 200 | ||
assert response.json()["all_test_executions_count"] == 1 | ||
assert response.json()["completed_test_executions_count"] == 0 | ||
|
||
te.review_decision = [TestExecutionReviewDecision.APPROVED_ALL_TESTS_PASS] | ||
db_session.commit() | ||
db_session.refresh(te) | ||
|
||
# Verify completed test execution count is one, it is reviewed | ||
response = test_client.get(f"/v1/artefacts/{a.id}") | ||
assert response.status_code == 200 | ||
assert response.json()["all_test_executions_count"] == 1 | ||
assert response.json()["completed_test_executions_count"] == 1 | ||
|
||
|
||
def test_get_artefact_builds(test_client: TestClient, generator: DataGenerator): | ||
a = generator.gen_artefact("beta") | ||
ab = generator.gen_artefact_build(a) | ||
|
@@ -268,6 +325,8 @@ def test_artefact_signoff_approve(test_client: TestClient, generator: DataGenera | |
artefact.due_date.strftime("%Y-%m-%d") if artefact.due_date else None | ||
), | ||
"bug_link": "", | ||
"all_test_executions_count": 0, | ||
"completed_test_executions_count": 0, | ||
} | ||
|
||
|
||
|
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 |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import 'package:riverpod_annotation/riverpod_annotation.dart'; | ||
|
||
import '../models/family_name.dart'; | ||
import '../models/test_execution.dart'; | ||
import 'artefact_builds.dart'; | ||
import 'family_artefacts.dart'; | ||
|
||
part 'review_test_execution.g.dart'; | ||
|
||
@riverpod | ||
class ReviewTestExecution extends _$ReviewTestExecution { | ||
@override | ||
Future<void> build() async { | ||
return; | ||
} | ||
|
||
Future<void> reviewTestExecution( | ||
int testExecutionId, | ||
String reviewComment, | ||
List<TestExecutionReviewDecision> reviewDecision, | ||
FamilyName familyName, | ||
int artefactId, | ||
) async { | ||
await ref | ||
.read(artefactBuildsProvider(artefactId).notifier) | ||
.changeReviewDecision( | ||
testExecutionId, | ||
reviewComment, | ||
reviewDecision, | ||
); | ||
|
||
final artefactBuilds = | ||
ref.read(artefactBuildsProvider(artefactId)).requireValue; | ||
|
||
final newCompletedTestExecutionsCount = artefactBuilds | ||
.map( | ||
(build) => build.testExecutions | ||
.where((testExecution) => testExecution.reviewDecision.isNotEmpty) | ||
.length, | ||
) | ||
.fold(0, (a, b) => a + b); | ||
|
||
await ref | ||
.read(familyArtefactsProvider(familyName).notifier) | ||
.updateCompletedTestExecutionsCount( | ||
artefactId, | ||
newCompletedTestExecutionsCount, | ||
); | ||
} | ||
} |
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
Oops, something went wrong.