Skip to content
This repository was archived by the owner on Jun 13, 2025. It is now read-only.

Commit fedbc0f

Browse files
committed
Remove report_builder feature
1 parent a4d04bc commit fedbc0f

File tree

5 files changed

+24
-184
lines changed

5 files changed

+24
-184
lines changed

api/internal/tests/views/test_compare_viewset.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,11 @@
1717

1818
class MockSerializableReport(SerializableReport):
1919
"""
20-
Stubs the 'file_reports' and 'get' methods of SerializableReport, which usually constructs
20+
Stubs the 'get' method of SerializableReport, which usually constructs
2121
report files on the fly from information not provided by these test, like the chunks
2222
for example.
2323
"""
2424

25-
def file_reports(self):
26-
return [report_file for name, report_file in self.mocked_files.items()]
27-
2825
def get(self, file_name):
2926
return self.mocked_files.get(file_name)
3027

api/public/v2/tests/test_api_compare_viewset.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,14 +78,11 @@ def sample_report2():
7878

7979
class MockSerializableReport(SerializableReport):
8080
"""
81-
Stubs the 'file_reports' and 'get' methods of SerializableReport, which usually constructs
81+
Stubs the 'get' method of SerializableReport, which usually constructs
8282
report files on the fly from information not provided by these test, like the chunks
8383
for example.
8484
"""
8585

86-
def file_reports(self):
87-
return [report_file for name, report_file in self.mocked_files.items()]
88-
8986
def get(self, file_name):
9087
return self.mocked_files.get(file_name)
9188

codecov/settings_base.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -374,10 +374,6 @@
374374

375375
SHELTER_SHARED_SECRET = get_config("setup", "shelter_shared_secret", default=None)
376376

377-
# list of repo IDs that will use the new-style report builder
378-
# TODO: we can eventually get rid of this once it's confirmed working well for many repos
379-
REPORT_BUILDER_REPO_IDS = get_config("setup", "report_builder", "repo_ids", default=[])
380-
381377
SENTRY_ENV = os.environ.get("CODECOV_ENV", False)
382378
SENTRY_DSN = os.environ.get("SERVICES__SENTRY__SERVER_DSN", None)
383379
SENTRY_DENY_LIST = DEFAULT_DENYLIST + ["_headers", "token_to_use"]

services/report.py

Lines changed: 12 additions & 167 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,22 @@
11
import logging
2-
from typing import List, Optional
32

43
import sentry_sdk
5-
from django.conf import settings
6-
from django.db.models import Prefetch, Q
74
from django.utils.functional import cached_property
85
from shared.helpers.flag import Flag
96
from shared.reports.readonly import ReadOnlyReport as SharedReadOnlyReport
107
from shared.reports.resources import Report
11-
from shared.reports.types import ReportFileSummary, ReportTotals
128
from shared.storage.exceptions import FileNotInStorageError
13-
from shared.utils.sessions import Session, SessionType
9+
from shared.utils.sessions import Session
1410

1511
from core.models import Commit
16-
from reports.models import AbstractTotals, CommitReport, ReportSession
1712
from services.archive import ArchiveService
18-
from utils.config import RUN_ENV
1913

2014
log = logging.getLogger(__name__)
2115

2216

2317
class ReportMixin:
24-
def file_reports(self):
25-
for f in self.files:
26-
yield self.get(f)
27-
2818
@cached_property
29-
def flags(self):
19+
def flags(self) -> dict:
3020
"""returns dict(:name=<Flag>)"""
3121
flags_dict = {}
3222
for session in self.sessions.values():
@@ -61,42 +51,20 @@ def build_report(chunks, files, sessions, totals, report_class=None):
6151

6252

6353
@sentry_sdk.trace
64-
def build_report_from_commit(commit: Commit, report_class=None):
54+
def build_report_from_commit(commit: Commit, report_class=None) -> Report | None:
6555
"""
6656
Builds a `shared.reports.resources.Report` from a given commit.
67-
68-
Chunks are fetched from archive storage and the rest of the data is sourced
69-
from various `reports_*` tables in the database.
7057
"""
7158

72-
# TODO: this can be removed once confirmed working well on prod
73-
new_report_builder_enabled = (
74-
RUN_ENV == "DEV"
75-
or RUN_ENV == "STAGING"
76-
or RUN_ENV == "TESTING"
77-
or commit.repository_id in settings.REPORT_BUILDER_REPO_IDS
78-
)
79-
80-
with sentry_sdk.start_span(description="Fetch files/sessions/totals"):
81-
commit_report = fetch_commit_report(commit)
82-
if commit_report and new_report_builder_enabled:
83-
files = build_files(commit_report)
84-
sessions = build_sessions(commit_report)
85-
try:
86-
totals = build_totals(commit_report.reportleveltotals)
87-
except CommitReport.reportleveltotals.RelatedObjectDoesNotExist:
88-
totals = None
89-
else:
90-
if not commit.report:
91-
return None
59+
if not commit.report:
60+
return None
9261

93-
files = commit.report["files"]
94-
sessions = commit.report["sessions"]
95-
totals = commit.totals
62+
files = commit.report["files"]
63+
sessions = commit.report["sessions"]
64+
totals = commit.totals
9665

9766
try:
98-
with sentry_sdk.start_span(description="Fetch chunks"):
99-
chunks = ArchiveService(commit.repository).read_chunks(commit.commitid)
67+
chunks = ArchiveService(commit.repository).read_chunks(commit.commitid)
10068
return build_report(chunks, files, sessions, totals, report_class=report_class)
10169
except FileNotInStorageError:
10270
log.warning(
@@ -109,130 +77,7 @@ def build_report_from_commit(commit: Commit, report_class=None):
10977
return None
11078

11179

112-
def fetch_commit_report(commit: Commit) -> Optional[CommitReport]:
113-
"""
114-
Fetch a single `CommitReport` for the given commit.
115-
All the necessary report relations are prefetched.
116-
"""
117-
return (
118-
commit.reports.coverage_reports()
119-
.filter(code=None)
120-
.prefetch_related(
121-
Prefetch(
122-
"sessions",
123-
queryset=ReportSession.objects.prefetch_related("flags").select_related(
124-
"uploadleveltotals"
125-
),
126-
),
127-
)
128-
.select_related("reportdetails", "reportleveltotals")
129-
.first()
130-
)
131-
132-
133-
def build_totals(totals: AbstractTotals) -> ReportTotals:
134-
"""
135-
Build a `shared.reports.types.ReportTotals` instance from one of the
136-
various database totals records.
137-
"""
138-
return ReportTotals(
139-
files=totals.files,
140-
lines=totals.lines,
141-
hits=totals.hits,
142-
misses=totals.misses,
143-
partials=totals.partials,
144-
coverage=totals.coverage,
145-
branches=totals.branches,
146-
methods=totals.methods,
147-
)
148-
149-
150-
def build_session(upload: ReportSession) -> Session:
151-
"""
152-
Build a `shared.utils.sessions.Session` from a database `reports_upload` record.
153-
"""
154-
try:
155-
upload_totals = build_totals(upload.uploadleveltotals)
156-
except ReportSession.uploadleveltotals.RelatedObjectDoesNotExist:
157-
# upload does not have any totals - maybe the processing failed
158-
# or the upload was empty?
159-
upload_totals = None
160-
flags = [flag.flag_name for flag in upload.flags.all()]
161-
162-
return Session(
163-
id=upload.id,
164-
totals=upload_totals,
165-
time=upload.created_at.timestamp,
166-
archive=upload.storage_path,
167-
flags=flags,
168-
provider=upload.provider,
169-
build=upload.build_code,
170-
job=upload.job_code,
171-
url=upload.build_url,
172-
state=upload.state,
173-
env=upload.env,
174-
name=upload.name,
175-
session_type=SessionType.get_from_string(upload.upload_type),
176-
session_extras=upload.upload_extras,
177-
)
178-
179-
180-
def build_sessions(commit_report: CommitReport) -> dict[int, Session]:
181-
"""
182-
Build mapping of report number -> session that can be passed to the report class.
183-
Does not include CF sessions if there is also an upload session with the same
184-
flag name.
185-
"""
186-
sessions = {}
187-
188-
carryforward_sessions = {}
189-
uploaded_flags = set()
190-
191-
for upload in commit_report.sessions.filter(
192-
Q(state="complete") | Q(state="processed")
193-
):
194-
session = build_session(upload)
195-
if session.session_type == SessionType.carriedforward:
196-
carryforward_sessions[upload.order_number] = session
197-
else:
198-
sessions[upload.order_number] = session
199-
uploaded_flags |= set(session.flags)
200-
201-
for sid, session in carryforward_sessions.items():
202-
# we only ever expect 1 flag for CF sessions
203-
overlapping_flags = uploaded_flags & set(session.flags)
204-
205-
if len(overlapping_flags) == 0:
206-
# we can include this CF session since there are no direct uploads
207-
# with the same flag name
208-
sessions[sid] = session
209-
210-
return sessions
211-
212-
213-
def build_files(commit_report: CommitReport) -> dict[str, ReportFileSummary]:
214-
"""
215-
Construct a files dictionary in a format compatible with `shared.reports.resources.Report`
216-
from data in the `reports_reportdetails.files_array` column in the database.
217-
"""
218-
try:
219-
report_details = commit_report.reportdetails
220-
except CommitReport.reportdetails.RelatedObjectDoesNotExist:
221-
# we don't expect this but something could have gone wrong in the worker
222-
# we can't really recover here
223-
return {}
224-
225-
return {
226-
file["filename"]: ReportFileSummary(
227-
file_index=file["file_index"],
228-
file_totals=ReportTotals(*file["file_totals"]),
229-
diff_totals=file["diff_totals"],
230-
)
231-
for file in report_details.files_array
232-
}
233-
234-
235-
def files_belonging_to_flags(commit_report: Report, flags: List[str]) -> List[str]:
80+
def files_belonging_to_flags(commit_report: Report, flags: list[str]) -> list[str]:
23681
sessions_for_specific_flags = sessions_with_specific_flags(
23782
commit_report=commit_report, flags=flags
23883
)
@@ -244,7 +89,7 @@ def files_belonging_to_flags(commit_report: Report, flags: List[str]) -> List[st
24489

24590

24691
def sessions_with_specific_flags(
247-
commit_report: Report, flags: List[str]
92+
commit_report: Report, flags: list[str]
24893
) -> dict[int, Session]:
24994
sessions = [
25095
(sid, session)
@@ -254,7 +99,7 @@ def sessions_with_specific_flags(
25499
return dict(sessions)
255100

256101

257-
def files_in_sessions(commit_report: Report, session_ids: List[int]) -> List[str]:
102+
def files_in_sessions(commit_report: Report, session_ids: list[int]) -> list[str]:
258103
files, session_ids = [], set(session_ids)
259104
for file in commit_report:
260105
found = False

services/tests/test_report.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@ def flags_report():
3939
return report
4040

4141

42+
def sorted_files(report: Report) -> list[ReportFile]:
43+
files = [report.get(file) for file in report.files]
44+
return sorted(files, key=lambda x: x.name)
45+
46+
4247
class ReportServiceTest(TestCase):
4348
def test_report_generator(self):
4449
data = {
@@ -116,7 +121,7 @@ def test_build_report_from_commit(self, read_chunks_mock):
116121
res = build_report_from_commit(commit)
117122
assert len(res._chunks) == 3
118123
assert len(res.files) == 3
119-
file_1, file_2, file_3 = sorted(res.file_reports(), key=lambda x: x.name)
124+
file_1, file_2, file_3 = sorted_files(res)
120125
assert file_1.name == "awesome/__init__.py"
121126
assert tuple(file_1.totals) == (0, 10, 8, 2, 0, "80.00000", 0, 0, 0, 0, 0, 0, 0)
122127
assert file_2.name == "tests/__init__.py"
@@ -180,7 +185,7 @@ def test_build_report_from_commit_null_session_totals(self, read_chunks_mock):
180185
res = build_report_from_commit(commit)
181186
assert len(res._chunks) == 3
182187
assert len(res.files) == 3
183-
file_1, file_2, file_3 = sorted(res.file_reports(), key=lambda x: x.name)
188+
file_1, file_2, file_3 = sorted_files(res)
184189
assert file_1.name == "awesome/__init__.py"
185190
assert tuple(file_1.totals) == (0, 10, 8, 2, 0, "80.00000", 0, 0, 0, 0, 0, 0, 0)
186191
assert file_2.name == "tests/__init__.py"
@@ -213,7 +218,7 @@ def test_build_report_from_commit_with_flags(self, read_chunks_mock):
213218
res = report.flags["integrations"].report
214219
assert len(res.report._chunks) == 3
215220
assert len(res.files) == 3
216-
file_1, file_2, file_3 = sorted(res.file_reports(), key=lambda x: x.name)
221+
file_1, file_2, file_3 = sorted_files(res)
217222
assert file_1.name == "awesome/__init__.py"
218223
assert tuple(file_1.totals) == (0, 10, 1, 9, 0, "10.00000", 0, 0, 0, 0, 0, 0, 0)
219224
assert file_2.name == "tests/__init__.py"
@@ -245,7 +250,7 @@ def test_build_report_from_commit_with_non_carried_forward_flags(
245250
res = report.flags["integrations"].report
246251
assert len(res.report._chunks) == 3
247252
assert len(res.files) == 3
248-
file_1, file_2, file_3 = sorted(res.file_reports(), key=lambda x: x.name)
253+
file_1, file_2, file_3 = sorted_files(res)
249254
assert file_1.name == "awesome/__init__.py"
250255
assert tuple(file_1.totals) == (0, 10, 1, 9, 0, "10.00000", 0, 0, 0, 0, 0, 0, 0)
251256
assert file_2.name == "tests/__init__.py"
@@ -330,7 +335,7 @@ def test_build_report_from_commit_fallback(self, read_chunks_mock):
330335

331336
assert len(res._chunks) == 3
332337
assert len(res.files) == 3
333-
file_1, file_2, file_3 = sorted(res.file_reports(), key=lambda x: x.name)
338+
file_1, file_2, file_3 = sorted_files(res)
334339
assert file_1.name == "awesome/__init__.py"
335340
assert tuple(file_1.totals) == (0, 10, 8, 2, 0, "80.00000", 0, 0, 0, 0, 0, 0, 0)
336341
assert file_2.name == "tests/__init__.py"

0 commit comments

Comments
 (0)