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

feat: count difference of uploaded sessions #454

Merged
merged 2 commits into from
May 28, 2024

Conversation

giovanni-guidini
Copy link
Contributor

ticket: codecov/engineering-team#1622

These changes introduce a new capabiliy to ComparisonProxy. Namely, to get the
difference in the number of uploads reported per flag between HEAD and BASE.

The idea is to be able to give more actionable message in the PR comment on the following scenario:

  1. I have uploaded 5 reports to my base commit
  2. I upload 1 report to head commit
  3. I have NOT covered all lines of my patch
  4. I'm seeing project coverage go WAY down

Because typically coverage is uploaded via CI, and CI doesn't change often, a different
number of reports present could indicate issues in the coverage results.

We have to ignore carryforward sessions because different commits might upload different
sets of reports.

Legal Boilerplate

Look, I get it. The entity doing business as "Sentry" was incorporated in the State of Delaware in 2015 as Functional Software, Inc. In 2022 this entity acquired Codecov and as result Sentry is going to need some rights from me in order to utilize my contributions in this PR. So here's the deal: I retain all rights, title and interest in and to my contributions, and by keeping this boilerplate intact I confirm that Sentry can use, modify, copy, and redistribute my contributions, under Sentry's choice of terms.

@giovanni-guidini giovanni-guidini requested a review from a team May 16, 2024 12:38
@codecov-notifications
Copy link

codecov-notifications bot commented May 16, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

✅ All tests successful. No failed tests found.

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #454      +/-   ##
==========================================
- Coverage   97.34%   97.34%   -0.01%     
==========================================
  Files         399      402       +3     
  Lines       33616    33740     +124     
==========================================
+ Hits        32724    32844     +120     
- Misses        892      896       +4     
Flag Coverage Δ
integration 97.34% <100.00%> (-0.01%) ⬇️
latest-uploader-overall 97.34% <100.00%> (-0.01%) ⬇️
unit 97.34% <100.00%> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Components Coverage Δ
NonTestCode 94.58% <100.00%> (-0.01%) ⬇️
OutsideTasks 97.49% <100.00%> (-0.01%) ⬇️
Files Coverage Δ
services/comparison/__init__.py 97.27% <100.00%> (+0.48%) ⬆️
...son/tests/unit/test_reports_uploaded_count_diff.py 100.00% <100.00%> (ø)
services/comparison/types.py 100.00% <100.00%> (ø)

... and 8 files with indirect coverage changes

@codecov-qa
Copy link

codecov-qa bot commented May 16, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 97.25%. Comparing base (242e1a0) to head (bb893b1).
Report is 16 commits behind head on main.

✅ All tests successful. No failed tests found.

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #454      +/-   ##
==========================================
- Coverage   97.34%   97.25%   -0.09%     
==========================================
  Files         399      410      +11     
  Lines       33616    34070     +454     
==========================================
+ Hits        32724    33136     +412     
- Misses        892      934      +42     
Flag Coverage Δ
integration 97.25% <100.00%> (-0.09%) ⬇️
latest-uploader-overall 97.25% <100.00%> (-0.09%) ⬇️
unit 97.25% <100.00%> (-0.09%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Components Coverage Δ
NonTestCode 94.36% <100.00%> (-0.22%) ⬇️
OutsideTasks 97.50% <100.00%> (+<0.01%) ⬆️
Files Coverage Δ
services/comparison/__init__.py 97.26% <100.00%> (+0.46%) ⬆️
...son/tests/unit/test_reports_uploaded_count_diff.py 100.00% <100.00%> (ø)
services/comparison/types.py 100.00% <100.00%> (ø)

... and 43 files with indirect coverage changes

Copy link

codecov-public-qa bot commented May 16, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 97.25%. Comparing base (242e1a0) to head (bb893b1).
Report is 16 commits behind head on main.

✅ All tests successful. No failed tests found ☺️

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #454      +/-   ##
==========================================
- Coverage   97.34%   97.25%   -0.09%     
==========================================
  Files         399      410      +11     
  Lines       33616    34070     +454     
==========================================
+ Hits        32724    33136     +412     
- Misses        892      934      +42     
Flag Coverage Δ
integration 97.25% <100.00%> (-0.09%) ⬇️
latest-uploader-overall 97.25% <100.00%> (-0.09%) ⬇️
unit 97.25% <100.00%> (-0.09%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Components Coverage Δ
NonTestCode 94.36% <100.00%> (-0.22%) ⬇️
OutsideTasks 97.50% <100.00%> (+<0.01%) ⬆️
Files Coverage Δ
services/comparison/__init__.py 97.26% <100.00%> (+0.46%) ⬆️
...son/tests/unit/test_reports_uploaded_count_diff.py 100.00% <100.00%> (ø)
services/comparison/types.py 100.00% <100.00%> (ø)

... and 43 files with indirect coverage changes

Copy link

codecov bot commented May 16, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 97.33%. Comparing base (242e1a0) to head (bb893b1).
Report is 16 commits behind head on main.

Changes have been made to critical files, which contain lines commonly executed in production. Learn more

✅ All tests successful. No failed tests found.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #454      +/-   ##
==========================================
- Coverage   97.37%   97.33%   -0.04%     
==========================================
  Files         430      442      +12     
  Lines       34306    35883    +1577     
==========================================
+ Hits        33405    34928    +1523     
- Misses        901      955      +54     
Flag Coverage Δ
integration 97.25% <100.00%> (-0.09%) ⬇️
latest-uploader-overall 97.25% <100.00%> (-0.09%) ⬇️
unit 97.25% <100.00%> (-0.09%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Components Coverage Δ
NonTestCode 94.59% <100.00%> (-0.02%) ⬇️
OutsideTasks 97.50% <100.00%> (+<0.01%) ⬆️
Files Coverage Δ
services/comparison/__init__.py 97.27% <100.00%> (+0.46%) ⬆️
...son/tests/unit/test_reports_uploaded_count_diff.py 100.00% <100.00%> (ø)
services/comparison/types.py 100.00% <100.00%> (ø)

... and 43 files with indirect coverage changes

This change has been scanned for critical changes. Learn more

ticket: codecov/engineering-team#1622

These changes introduce a new capabiliy to `ComparisonProxy`. Namely, to get the
difference in the number of uploads reported per flag between HEAD and BASE.

The idea is to be able to give more actionable message in the PR comment on the following scenario:
1. I have uploaded 5 reports to my base commit
2. I upload 1 report to head commit
3. I have NOT covered all lines of my patch
4. I'm seeing project coverage go WAY down

Because typically coverage is uploaded via CI, and CI doesn't change often, a different
number of reports present could indicate issues in the coverage results.

We have to ignore carryforward sessions because different commits might upload different
sets of reports.

There are 2 functions so that we can also get the _total_ number of reports uploaded per flag, not only the diff
Copy link
Contributor

@michelletran-codecov michelletran-codecov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a few comments

# We ignore carryforward sessions
# Because not all commits would upload all flags (potentially)
# But they are still carried forward
if session.session_type == SessionType.uploaded:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This matches the comment a bit better.

Suggested change
if session.session_type == SessionType.uploaded:
if session.session_type != SessionType.carriedforward:

# But they are still carried forward
if session.session_type == SessionType.uploaded:
if session.flags == []:
session.flags = [""]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does a session with no flags mean? Is there a possibility for "" to be a session flag? And if it can be an existing string, then do we want to differentiate no flags with the actual "" flag?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A session with no flag is one that is uploaded without using the (optional) --flag argument in the CLI or uploader. They are not incommon if you have only a simple project and don't separates your tests.

I think it's extremely unlikely that "" is used as an actual flag because it doesn't carry any information in it. In essence there's little difference uploading with a "" flag and no flag. I don't think we need to handle it separately.
A good callout though.

Comment on lines 313 to 321
existing = per_flag_dict.get(flag)
if existing:
existing[curr_counter] += 1
else:
new_entry = ReportUploadedCount(
flag=flag, base_count=0, head_count=0
)
new_entry[curr_counter] += 1
per_flag_dict[flag] = new_entry
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Python collections module contains a Counter class that does something similar. One advantage of counter is that it doesn't require the existing check (for both adding and retrieving data). The main downside of using a counter is that we would have to recast it into List[ReportUploadedCount] if that's the type we want we want to return.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After some reflecting I decided to not use Counters... The main reason is that I think we should keep the ReportUploadedCount type.

idk exactly what you had in mind, but the way I see it we'd need 2 counters (one for head_count, one for base_count). The main loop wouldn't change too much, and the casting to ReportUploadedCount would be an extra process. So I justed reworked the if / else but of this main loop a little bit.

Open to suggestions tho, of course

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That sounds good! I was also thinking of keeping 2 counters, but as mentioned, I wasn't sure about recasting it into ReportUploadedCount. I liked the newly added simplification! 👍

Comment on lines 141 to 158
def test_get_reports_uploaded_count_per_flag_diff(
head_sessions, base_sessions, expected_diff
):
head_report = Report()
head_report.sessions = head_sessions
base_report = Report()
base_report.sessions = base_sessions
comparison_proxy = ComparisonProxy(
comparison=Comparison(
head=FullCommit(report=head_report, commit=None),
project_coverage_base=FullCommit(report=base_report, commit=None),
patch_coverage_base_commitid=None,
enriched_pull=None,
)
)
# Python Dicts preserve order, so we can actually test this equality
# See more https://stackoverflow.com/a/39537308
assert comparison_proxy.get_reports_uploaded_count_per_flag_diff() == expected_diff
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These tests almost look the same as the ones on line 65 (including the parametrized valuses). Can we just add a the results and the extra assert call for get_reports_uploaded_count_per_flag_diff?

from services.comparison.types import Comparison, FullCommit, ReportUploadedCount


@pytest.mark.parametrize(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When adding parametrize tests, I like to add ids for each test case to more clearly communicate what the test is checking.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is so cool... I didn't know about that. Thanks for sharing, will add and ID on those

bundle tests together.
slight refactor of dict buildup
Copy link
Contributor

@michelletran-codecov michelletran-codecov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@giovanni-guidini giovanni-guidini added this pull request to the merge queue May 28, 2024
Merged via the queue into main with commit d6168c2 May 28, 2024
19 of 26 checks passed
@giovanni-guidini giovanni-guidini deleted the gio/count-report-uploaded-diff branch May 28, 2024 14:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants