DataDog / datadog-ci-rb

Ruby library for Datadog test visibility
https://docs.datadoghq.com/continuous_integration/tests/ruby
Other
8 stars 4 forks source link

[SDTEST-523] Expand test impact analysis with allocation tracing #197

Closed anmarchenko closed 3 months ago

anmarchenko commented 3 months ago

Problem statement Using line coverage for test impact analysis has a major limitation in Ruby: consider the following examples:

# this class does not have any executable lines
class MyClass < OtherClass
end

test "instantiate MyClass" do
  assert MyClass.new != nil
end

The test "instantiate MyClass" does not cover MyClass because there are no executable lines in MyClass. If initializer was inherited from OtherClass, then this test will have other_class.rb in the list of covered files but not my_class.rb.

This leads to a major intelligent test runner bug: if we change initializer of MyClass like that:

class MyClass
  def initialize(arg)
    @arg = arg
  end
end

then the test above will start failing because MyClass.new expects argument now. But because my_class.rb is not covered by this test, intelligent test runner will skip test by default! It causes broken tests to be merged in the default branch.

If this example might seem artificial, unfortunately the same happens with ActiveRecord models or with ActiveModel classes:

# perfectly valid Rails model that is not covered by any test
class Account < ApplicationRecord
  belongs_to :user
end

Solution We cannot overcome this limitation by using line coverage: the code coverage approach works correctly in this case and this is just how line coverage works. We need to go deeper in Ruby VM tracing using techniques that are already used by continuous profiler.

For this limitation, I've chosen to reach out for heap allocation tracepoint: it is possible to spy on every new object allocation that happens in Ruby heap. Even if no code from this class is executed during the test, it is enough for us to know that the test instantiates instances of this class to add its filename to the list of impacted files.

Notes on implementation:

Known limitations

How to test the change? Tested using by running test suites of the following open source projects:

Unit tests reproducing the original problem are provided. See performance evaluation below.

Performance evaluation Median performance overhead for some OSS projects' test suites before this change:

image

Results from benchmarks after this change:

Overall this change increases code coverage overhead on test suites by 30-40% (compared to overhead before the change) in relative numbers. In absolute numbers depending on project's size and characteristics it means from 7% up to 30% more time spent in tests (the maximum overhead is from rubocop which is particularly challenging for profiling: 21k relatively fast tests).

codecov-commenter commented 3 months ago

Codecov Report

Attention: Patch coverage is 98.21429% with 2 lines in your changes missing coverage. Please review.

Project coverage is 98.86%. Comparing base (579867e) to head (aebb1bf).

Files Patch % Lines
lib/datadog/ci/configuration/components.rb 77.77% 2 Missing :warning:
Additional details and impacted files ```diff @@ Coverage Diff @@ ## main #197 +/- ## ========================================== - Coverage 98.87% 98.86% -0.01% ========================================== Files 231 235 +4 Lines 10368 10477 +109 Branches 475 481 +6 ========================================== + Hits 10251 10358 +107 - Misses 117 119 +2 ```

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.

devinburnette commented 3 months ago

just tested this branch as of the latest commit (0b1618c) and verified the segfault is gone and the test impact analysis is working as expected for models.

anmarchenko commented 3 months ago

Thank you for testing and your feedback @devinburnette! I'll do a couple more passes on Monday and will release soon

anmarchenko commented 3 months ago

@ivoanjo this is ready for another pass - seems to be working now