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

[CIVIS-9951] add settings option to ignore code coverage for bundled gems location #174

Merged
merged 6 commits into from
May 13, 2024

Conversation

anmarchenko
Copy link
Member

@anmarchenko anmarchenko commented May 7, 2024

What does this PR do?
In CI environments bundled gems are often installed inside the project folder for caching purposes. Unfortunately, it makes per test code coverage for ITR extremely slow as we need to unnecessary track all the code files from the external gems.

This PR adds DD_CIVISIBILITY_ITR_CODE_COVERAGE_EXCLUDED_BUNDLE_PATH environment variable that allows us to set a certain path to be excluded from code coverage (supports both relative and absolute paths). Even better, for the most cases users won't have to use this configuration: we will locate bundle location and set it for them.

It works as following:

  • if bundler gem is available in the environment, we use Bundler.bundle_path and set this result as ignored path
  • otherwise we try to locate vendor/bundle or .bundle under the git root - if any of them exist, we ignore them

How to test the change?
Unit tests are provided.

I have run test-environment with gems bundled inside the project directory to confirm the fix:
https://github.com/DataDog/test-environment/pull/284

The overhead with bundling gems in the project folder in this case is insignificantly larger: 113% vs 106% for rubocop for example. Without this change, it would be 450% vs 106%.

@anmarchenko anmarchenko changed the title add settings option to ignore code coverage for certain paths [CIVIS-9951] add settings option to ignore code coverage for certain paths May 7, 2024
@anmarchenko anmarchenko added this to the 1.0 milestone May 7, 2024
@anmarchenko anmarchenko force-pushed the anmarchenko/skip_per_test_coverage_for_bundled_gems branch from a4961a4 to 16b04ed Compare May 8, 2024 08:25
@anmarchenko anmarchenko removed this from the 1.0 milestone May 8, 2024
…single itr_code_coverage_excluded_bundle_path
@codecov-commenter
Copy link

codecov-commenter commented May 8, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 98.98%. Comparing base (f295639) to head (6eddb65).
Report is 9 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #174      +/-   ##
==========================================
- Coverage   98.98%   98.98%   -0.01%     
==========================================
  Files         198      205       +7     
  Lines        9637     9816     +179     
  Branches      423      435      +12     
==========================================
+ Hits         9539     9716     +177     
- Misses         98      100       +2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@anmarchenko anmarchenko marked this pull request as ready for review May 8, 2024 13:40
@anmarchenko anmarchenko requested review from a team as code owners May 8, 2024 13:40
@anmarchenko anmarchenko requested a review from juan-fernandez May 8, 2024 13:40
Comment on lines +8 to +36
static int is_prefix(VALUE prefix, const char *str)
{
if (prefix == Qnil)
{
return 0;
}

const char *c_prefix = RSTRING_PTR(prefix);
if (c_prefix == NULL)
{
return 0;
}

long prefix_len = RSTRING_LEN(prefix);
if (strncmp(c_prefix, str, prefix_len) == 0)
{
return 1;
}
else
{
return 0;
}
}

// Data structure
struct dd_cov_data
{
VALUE root;
VALUE ignored_path;
Copy link
Member

Choose a reason for hiding this comment

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

So I guess the same suggestion from #171 would apply here -- keeping the prefix as a char * and caching its length would save us some per-line work.

Copy link
Member Author

Choose a reason for hiding this comment

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

I agree! If it's not blocking I would merge this one as is, and then optimized it together with everything else in #171

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, I don't think it's a blocker. I guess it's a slight performance regression until it's paired with #171, but I'm guessing the plan will be to release 'em together :)

Copy link
Member Author

Choose a reason for hiding this comment

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

I will have to release it earlier than the performance improvements, but there is an important customer value in this: we have a customer that evaluates ITR and current implementation that does not ignore bundled gems installed in project folder induces up to 400% code coverage overhead.

I measured ineffectiveness of this solution using test-environment: for the worst case it increases overhead by 7% (113 vs 106) if bundled gems are installed in project folder. When gems are not installed in project folder, this change does not induce any overhead.

Copy link
Member

Choose a reason for hiding this comment

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

Sounds reasonable, I'll defer to your wise judgment here :)

@anmarchenko anmarchenko changed the title [CIVIS-9951] add settings option to ignore code coverage for certain paths [CIVIS-9951] add settings option to ignore code coverage for bundled gems location May 8, 2024
lib/datadog/ci/configuration/settings.rb Outdated Show resolved Hide resolved
Comment on lines +8 to +36
static int is_prefix(VALUE prefix, const char *str)
{
if (prefix == Qnil)
{
return 0;
}

const char *c_prefix = RSTRING_PTR(prefix);
if (c_prefix == NULL)
{
return 0;
}

long prefix_len = RSTRING_LEN(prefix);
if (strncmp(c_prefix, str, prefix_len) == 0)
{
return 1;
}
else
{
return 0;
}
}

// Data structure
struct dd_cov_data
{
VALUE root;
VALUE ignored_path;
Copy link
Member Author

Choose a reason for hiding this comment

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

I will have to release it earlier than the performance improvements, but there is an important customer value in this: we have a customer that evaluates ITR and current implementation that does not ignore bundled gems installed in project folder induces up to 400% code coverage overhead.

I measured ineffectiveness of this solution using test-environment: for the worst case it increases overhead by 7% (113 vs 106) if bundled gems are installed in project folder. When gems are not installed in project folder, this change does not induce any overhead.

@anmarchenko anmarchenko merged commit 0c97a8c into main May 13, 2024
26 checks passed
@anmarchenko anmarchenko deleted the anmarchenko/skip_per_test_coverage_for_bundled_gems branch May 13, 2024 13:05
@github-actions github-actions bot added this to the 1.0 milestone May 13, 2024
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.

4 participants