From a0618d41486d6b7052211b936206679dfded1684 Mon Sep 17 00:00:00 2001 From: matt-codecov <137832199+matt-codecov@users.noreply.github.com> Date: Mon, 28 Apr 2025 02:29:03 -0700 Subject: [PATCH 1/8] add note to README about migrating to umbrella (#1301) --- apps/codecov-api/README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/apps/codecov-api/README.md b/apps/codecov-api/README.md index de8b96ec95..713e09cac7 100644 --- a/apps/codecov-api/README.md +++ b/apps/codecov-api/README.md @@ -1,3 +1,7 @@ +# PHASED OUT + +This project has been moved to [the `apps/codecov-api` folder in our `umbrella` repository](https://github.com/codecov/umbrella/tree/main/apps/codecov-api). Please contribute there instead. + ## Codecov API > We believe that everyone should have access to quality software (like Sentry), that’s why we have always offered Codecov for free to open source maintainers. From 50afb40e246e5b07005e61fad2b531e8fb085b9b Mon Sep 17 00:00:00 2001 From: RulaKhaled Date: Mon, 28 Apr 2025 12:50:55 +0200 Subject: [PATCH 2/8] first pass, intialize the method for failure rate: --- .../api/public/v2/test_results/serializers.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/apps/codecov-api/api/public/v2/test_results/serializers.py b/apps/codecov-api/api/public/v2/test_results/serializers.py index 161368567c..6b128b553d 100644 --- a/apps/codecov-api/api/public/v2/test_results/serializers.py +++ b/apps/codecov-api/api/public/v2/test_results/serializers.py @@ -13,15 +13,23 @@ class TestInstanceSerializer(serializers.ModelSerializer): outcome = serializers.CharField(label="outcome") branch = serializers.CharField(label="branch name") repoid = serializers.IntegerField(label="repo id") - failure_rate = serializers.FloatField( - source="test.failure_rate", read_only=True, label="failure rate" - ) + failure_rate = serializers.SerializerMethodField(label="failure rate") commits_where_fail = serializers.ListField( source="test.commits_where_fail", read_only=True, label="commits where test failed", ) + def get_failure_rate(self, obj): + test_instances = TestInstance.objects.filter(test=obj.test) + total_runs = test_instances.count() + if total_runs == 0: + return 0.0 + + fail_count = test_instances.filter(outcome=TestInstance.Outcome.FAILURE.value).count() + + return fail_count / total_runs + class Meta: model = TestInstance read_only_fields = ( From c9410386eed1029d194d25de542c50c3b1329d3f Mon Sep 17 00:00:00 2001 From: RulaKhaled Date: Mon, 28 Apr 2025 12:53:08 +0200 Subject: [PATCH 3/8] linting --- apps/codecov-api/api/public/v2/test_results/serializers.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/apps/codecov-api/api/public/v2/test_results/serializers.py b/apps/codecov-api/api/public/v2/test_results/serializers.py index 6b128b553d..f0a28a92ef 100644 --- a/apps/codecov-api/api/public/v2/test_results/serializers.py +++ b/apps/codecov-api/api/public/v2/test_results/serializers.py @@ -25,9 +25,7 @@ def get_failure_rate(self, obj): total_runs = test_instances.count() if total_runs == 0: return 0.0 - fail_count = test_instances.filter(outcome=TestInstance.Outcome.FAILURE.value).count() - return fail_count / total_runs class Meta: From f48fd24c52965de5f332b09dc9309d6af04a38d4 Mon Sep 17 00:00:00 2001 From: RulaKhaled Date: Mon, 28 Apr 2025 12:56:57 +0200 Subject: [PATCH 4/8] format doc --- .../api/public/v2/test_results/serializers.py | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/apps/codecov-api/api/public/v2/test_results/serializers.py b/apps/codecov-api/api/public/v2/test_results/serializers.py index f0a28a92ef..c9db7996e1 100644 --- a/apps/codecov-api/api/public/v2/test_results/serializers.py +++ b/apps/codecov-api/api/public/v2/test_results/serializers.py @@ -1,3 +1,4 @@ +from django.db.models import Count, Q from rest_framework import serializers from reports.models import TestInstance @@ -21,12 +22,24 @@ class TestInstanceSerializer(serializers.ModelSerializer): ) def get_failure_rate(self, obj): - test_instances = TestInstance.objects.filter(test=obj.test) - total_runs = test_instances.count() + """Calculate the failure rate for a test. + The failure rate is calculated as: + number of failed test runs / total number of test runs + Returns: + float: A value between 0.0 and 1.0 representing the failure rate + 0.0 means no failures + 1.0 means all runs failed + """ + stats = TestInstance.objects.filter(test=obj.test).aggregate( + total=Count("id"), + failures=Count("id", filter=Q(outcome=TestInstance.Outcome.FAILURE.value)), + ) + + total_runs = stats["total"] if total_runs == 0: return 0.0 - fail_count = test_instances.filter(outcome=TestInstance.Outcome.FAILURE.value).count() - return fail_count / total_runs + + return stats["failures"] / total_runs class Meta: model = TestInstance From 40a2fbd095be3c0bd6efe7ad71183fee1ebb9ba6 Mon Sep 17 00:00:00 2001 From: RulaKhaled Date: Mon, 28 Apr 2025 13:28:25 +0200 Subject: [PATCH 5/8] try this --- .../api/public/v2/tests/test_test_results_view.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/apps/codecov-api/api/public/v2/tests/test_test_results_view.py b/apps/codecov-api/api/public/v2/tests/test_test_results_view.py index aec5bcc6a7..6ed5df4199 100644 --- a/apps/codecov-api/api/public/v2/tests/test_test_results_view.py +++ b/apps/codecov-api/api/public/v2/tests/test_test_results_view.py @@ -53,6 +53,7 @@ def test_list(self): "outcome": self.test_instances[0].outcome, "branch": self.test_instances[0].branch, "repoid": self.test_instances[0].repoid, + "failure_rate": 0.0, }, { "id": self.test_instances[1].id, @@ -64,6 +65,7 @@ def test_list(self): "outcome": self.test_instances[1].outcome, "branch": self.test_instances[1].branch, "repoid": self.test_instances[1].repoid, + "failure_rate": 0.0, }, ], "total_pages": 1, @@ -95,6 +97,7 @@ def test_list_filters(self): "outcome": self.test_instances[0].outcome, "branch": self.test_instances[0].branch, "repoid": self.test_instances[0].repoid, + "failure_rate": 0.0, }, ], "total_pages": 1, @@ -125,6 +128,7 @@ def test_retrieve(self, get_repo_permissions): "outcome": self.test_instances[0].outcome, "branch": self.test_instances[0].branch, "repoid": self.test_instances[0].repoid, + "failure_rate": 0.0, } @patch("api.shared.permissions.RepositoryArtifactPermissions.has_permission") @@ -226,4 +230,5 @@ def test_result_with_valid_super_token( "outcome": self.test_instances[0].outcome, "branch": self.test_instances[0].branch, "repoid": self.test_instances[0].repoid, + "failure_rate": 0.0, } From 30822ab7cd6f4ad636bae4c769fe20ff2ed74002 Mon Sep 17 00:00:00 2001 From: RulaKhaled Date: Mon, 28 Apr 2025 13:36:14 +0200 Subject: [PATCH 6/8] fix failure rate percentage --- .../api/public/v2/tests/test_test_results_view.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/codecov-api/api/public/v2/tests/test_test_results_view.py b/apps/codecov-api/api/public/v2/tests/test_test_results_view.py index 6ed5df4199..b05a173917 100644 --- a/apps/codecov-api/api/public/v2/tests/test_test_results_view.py +++ b/apps/codecov-api/api/public/v2/tests/test_test_results_view.py @@ -53,7 +53,7 @@ def test_list(self): "outcome": self.test_instances[0].outcome, "branch": self.test_instances[0].branch, "repoid": self.test_instances[0].repoid, - "failure_rate": 0.0, + "failure_rate": 1.0, }, { "id": self.test_instances[1].id, @@ -65,7 +65,7 @@ def test_list(self): "outcome": self.test_instances[1].outcome, "branch": self.test_instances[1].branch, "repoid": self.test_instances[1].repoid, - "failure_rate": 0.0, + "failure_rate": 1.0, }, ], "total_pages": 1, @@ -97,7 +97,7 @@ def test_list_filters(self): "outcome": self.test_instances[0].outcome, "branch": self.test_instances[0].branch, "repoid": self.test_instances[0].repoid, - "failure_rate": 0.0, + "failure_rate": 1.0, }, ], "total_pages": 1, @@ -128,7 +128,7 @@ def test_retrieve(self, get_repo_permissions): "outcome": self.test_instances[0].outcome, "branch": self.test_instances[0].branch, "repoid": self.test_instances[0].repoid, - "failure_rate": 0.0, + "failure_rate": 1.0, } @patch("api.shared.permissions.RepositoryArtifactPermissions.has_permission") @@ -230,5 +230,5 @@ def test_result_with_valid_super_token( "outcome": self.test_instances[0].outcome, "branch": self.test_instances[0].branch, "repoid": self.test_instances[0].repoid, - "failure_rate": 0.0, + "failure_rate": 1.0, } From 1617bd259c92e5136b6103ce84793e0dc5db296c Mon Sep 17 00:00:00 2001 From: RulaKhaled Date: Tue, 29 Apr 2025 13:20:29 +0200 Subject: [PATCH 7/8] let's see if this is gonna work --- apps/codecov-api/README.md | 4 +++ .../api/public/v2/test_results/serializers.py | 25 ++++++++++++++++--- .../public/v2/tests/test_test_results_view.py | 5 ++++ 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/apps/codecov-api/README.md b/apps/codecov-api/README.md index de8b96ec95..713e09cac7 100644 --- a/apps/codecov-api/README.md +++ b/apps/codecov-api/README.md @@ -1,3 +1,7 @@ +# PHASED OUT + +This project has been moved to [the `apps/codecov-api` folder in our `umbrella` repository](https://github.com/codecov/umbrella/tree/main/apps/codecov-api). Please contribute there instead. + ## Codecov API > We believe that everyone should have access to quality software (like Sentry), that’s why we have always offered Codecov for free to open source maintainers. diff --git a/apps/codecov-api/api/public/v2/test_results/serializers.py b/apps/codecov-api/api/public/v2/test_results/serializers.py index 161368567c..c9db7996e1 100644 --- a/apps/codecov-api/api/public/v2/test_results/serializers.py +++ b/apps/codecov-api/api/public/v2/test_results/serializers.py @@ -1,3 +1,4 @@ +from django.db.models import Count, Q from rest_framework import serializers from reports.models import TestInstance @@ -13,15 +14,33 @@ class TestInstanceSerializer(serializers.ModelSerializer): outcome = serializers.CharField(label="outcome") branch = serializers.CharField(label="branch name") repoid = serializers.IntegerField(label="repo id") - failure_rate = serializers.FloatField( - source="test.failure_rate", read_only=True, label="failure rate" - ) + failure_rate = serializers.SerializerMethodField(label="failure rate") commits_where_fail = serializers.ListField( source="test.commits_where_fail", read_only=True, label="commits where test failed", ) + def get_failure_rate(self, obj): + """Calculate the failure rate for a test. + The failure rate is calculated as: + number of failed test runs / total number of test runs + Returns: + float: A value between 0.0 and 1.0 representing the failure rate + 0.0 means no failures + 1.0 means all runs failed + """ + stats = TestInstance.objects.filter(test=obj.test).aggregate( + total=Count("id"), + failures=Count("id", filter=Q(outcome=TestInstance.Outcome.FAILURE.value)), + ) + + total_runs = stats["total"] + if total_runs == 0: + return 0.0 + + return stats["failures"] / total_runs + class Meta: model = TestInstance read_only_fields = ( diff --git a/apps/codecov-api/api/public/v2/tests/test_test_results_view.py b/apps/codecov-api/api/public/v2/tests/test_test_results_view.py index aec5bcc6a7..b05a173917 100644 --- a/apps/codecov-api/api/public/v2/tests/test_test_results_view.py +++ b/apps/codecov-api/api/public/v2/tests/test_test_results_view.py @@ -53,6 +53,7 @@ def test_list(self): "outcome": self.test_instances[0].outcome, "branch": self.test_instances[0].branch, "repoid": self.test_instances[0].repoid, + "failure_rate": 1.0, }, { "id": self.test_instances[1].id, @@ -64,6 +65,7 @@ def test_list(self): "outcome": self.test_instances[1].outcome, "branch": self.test_instances[1].branch, "repoid": self.test_instances[1].repoid, + "failure_rate": 1.0, }, ], "total_pages": 1, @@ -95,6 +97,7 @@ def test_list_filters(self): "outcome": self.test_instances[0].outcome, "branch": self.test_instances[0].branch, "repoid": self.test_instances[0].repoid, + "failure_rate": 1.0, }, ], "total_pages": 1, @@ -125,6 +128,7 @@ def test_retrieve(self, get_repo_permissions): "outcome": self.test_instances[0].outcome, "branch": self.test_instances[0].branch, "repoid": self.test_instances[0].repoid, + "failure_rate": 1.0, } @patch("api.shared.permissions.RepositoryArtifactPermissions.has_permission") @@ -226,4 +230,5 @@ def test_result_with_valid_super_token( "outcome": self.test_instances[0].outcome, "branch": self.test_instances[0].branch, "repoid": self.test_instances[0].repoid, + "failure_rate": 1.0, } From 13622c9927b5e709e7a60afd8000a3911a9e59c1 Mon Sep 17 00:00:00 2001 From: Rola Abuhasna Date: Tue, 29 Apr 2025 13:21:22 +0200 Subject: [PATCH 8/8] Update README.md --- apps/codecov-api/README.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/apps/codecov-api/README.md b/apps/codecov-api/README.md index 713e09cac7..de8b96ec95 100644 --- a/apps/codecov-api/README.md +++ b/apps/codecov-api/README.md @@ -1,7 +1,3 @@ -# PHASED OUT - -This project has been moved to [the `apps/codecov-api` folder in our `umbrella` repository](https://github.com/codecov/umbrella/tree/main/apps/codecov-api). Please contribute there instead. - ## Codecov API > We believe that everyone should have access to quality software (like Sentry), that’s why we have always offered Codecov for free to open source maintainers.