Skip to content

Commit

Permalink
initial simplecov instrumentation to report total coverage percentage
Browse files Browse the repository at this point in the history
  • Loading branch information
anmarchenko committed Sep 24, 2024
1 parent 17b2e4f commit 9681ab4
Show file tree
Hide file tree
Showing 18 changed files with 298 additions and 0 deletions.
1 change: 1 addition & 0 deletions Steepfile
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,5 @@ target :lib do
library "capybara"
library "timecop"
library "webmock"
library "simplecov"
end
1 change: 1 addition & 0 deletions lib/datadog/ci.rb
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,7 @@ def test_optimisation
require_relative "ci/contrib/rspec/integration"
require_relative "ci/contrib/minitest/integration"
require_relative "ci/contrib/selenium/integration"
require_relative "ci/contrib/simplecov/integration"

# Configuration extensions
require_relative "ci/configuration/extensions"
Expand Down
26 changes: 26 additions & 0 deletions lib/datadog/ci/contrib/simplecov/configuration/settings.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# frozen_string_literal: true

require "datadog/core"

require_relative "../ext"
require_relative "../../settings"

module Datadog
module CI
module Contrib
module Simplecov
module Configuration
# Custom settings for the Simplecov integration
# @public_api
class Settings < Datadog::CI::Contrib::Settings
option :enabled do |o|
o.type :bool
o.env Ext::ENV_ENABLED
o.default true
end
end
end
end
end
end
end
15 changes: 15 additions & 0 deletions lib/datadog/ci/contrib/simplecov/ext.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# frozen_string_literal: true

module Datadog
module CI
module Contrib
module Simplecov
# Simplecov integration constants
# @public_api
module Ext
ENV_ENABLED = "DD_CIVISIBILITY_SIMPLECOV_INSTRUMENTATION_ENABLED"
end
end
end
end
end
47 changes: 47 additions & 0 deletions lib/datadog/ci/contrib/simplecov/integration.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# frozen_string_literal: true

require_relative "../integration"
require_relative "configuration/settings"
require_relative "patcher"

module Datadog
module CI
module Contrib
module Simplecov
# Description of Simplecov integration
class Integration
include Datadog::CI::Contrib::Integration

MINIMUM_VERSION = Gem::Version.new("0.18.0")

register_as :simplecov

def self.version
Gem.loaded_specs["simplecov"]&.version
end

def self.loaded?
!defined?(::SimpleCov).nil?
end

def self.compatible?
super && version >= MINIMUM_VERSION
end

# additional instrumentations for test helpers are auto instrumented on test session start
def auto_instrument?
true
end

def new_configuration
Configuration::Settings.new
end

def patcher
Patcher
end
end
end
end
end
end
28 changes: 28 additions & 0 deletions lib/datadog/ci/contrib/simplecov/patcher.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# frozen_string_literal: true

require "datadog/tracing/contrib/patcher"

require_relative "result_extractor"

module Datadog
module CI
module Contrib
module Simplecov
# Patcher enables patching of 'SimpleCov' module.
module Patcher
include Datadog::Tracing::Contrib::Patcher

module_function

def target_version
Integration.version
end

def patch
::SimpleCov.include(ResultExtractor)
end
end
end
end
end
end
33 changes: 33 additions & 0 deletions lib/datadog/ci/contrib/simplecov/result_extractor.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# frozen_string_literal: true

require "coverage"

module Datadog
module CI
module Contrib
module Simplecov
module ResultExtractor
def self.included(base)
base.singleton_class.prepend(ClassMethods)
end

module ClassMethods
def __dd_peek_result
return nil unless datadog_configuration[:enabled]

result = ::SimpleCov::UselessResultsRemover.call(
::SimpleCov::ResultAdapter.call(::Coverage.peek_result)
)

::SimpleCov::Result.new(add_not_loaded_files(result))
end

def datadog_configuration
Datadog.configuration.ci[:simplecov]
end
end
end
end
end
end
end
3 changes: 3 additions & 0 deletions lib/datadog/ci/ext/test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ module Test
TAG_EARLY_FLAKE_ENABLED = "test.early_flake.enabled" # true if early flake detection is enabled
TAG_EARLY_FLAKE_ABORT_REASON = "test.early_flake.abort_reason" # reason why early flake detection was aborted

# Tags for total code coverage
TAG_CODE_COVERAGE_LINES_PCT = "test.code_coverage.lines_pct"

# internal APM tag to mark a span as a test span
TAG_SPAN_KIND = "span.kind"
SPAN_KIND_TEST = "test"
Expand Down
3 changes: 3 additions & 0 deletions lib/datadog/ci/test_visibility/component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

require_relative "context"
require_relative "telemetry"
require_relative "total_coverage"

require_relative "../codeowners/parser"
require_relative "../contrib/contrib"
Expand Down Expand Up @@ -188,6 +189,8 @@ def on_test_started(test)
def on_test_session_finished(test_session)
test_optimisation.write_test_session_tags(test_session)

TotalCoverage.extract_lines_pct(test_session)

Telemetry.event_finished(test_session)
end

Expand Down
22 changes: 22 additions & 0 deletions lib/datadog/ci/test_visibility/total_coverage.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# frozen_string_literal: true

require_relative "../ext/test"

module Datadog
module CI
module TestVisibility
module TotalCoverage
def self.extract_lines_pct(test_session)
return unless defined?(::SimpleCov)
return unless ::SimpleCov.running
return unless ::SimpleCov.respond_to?(:__dd_peek_result)

result = ::SimpleCov.__dd_peek_result
return unless result

test_session.set_tag(Ext::Test::TAG_CODE_COVERAGE_LINES_PCT, result.covered_percent)
end
end
end
end
end
12 changes: 12 additions & 0 deletions sig/datadog/ci/contrib/simplecov/configuration/settings.rbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module Datadog
module CI
module Contrib
module Simplecov
module Configuration
class Settings < Datadog::CI::Contrib::Settings
end
end
end
end
end
end
11 changes: 11 additions & 0 deletions sig/datadog/ci/contrib/simplecov/ext.rbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module Datadog
module CI
module Contrib
module Simplecov
module Ext
ENV_ENABLED: "DD_CIVISIBILITY_SIMPLECOV_INSTRUMENTATION_ENABLED"
end
end
end
end
end
26 changes: 26 additions & 0 deletions sig/datadog/ci/contrib/simplecov/integration.rbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
module Datadog
module CI
module Contrib
module Simplecov
class Integration
extend Datadog::CI::Contrib::Integration::ClassMethods
include Datadog::CI::Contrib::Integration::InstanceMethods

MINIMUM_VERSION: Gem::Version

def self.version: () -> untyped

def self.loaded?: () -> bool

def self.compatible?: () -> bool

def auto_instrument?: () -> bool

def new_configuration: () -> untyped

def patcher: () -> untyped
end
end
end
end
end
15 changes: 15 additions & 0 deletions sig/datadog/ci/contrib/simplecov/patcher.rbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module Datadog
module CI
module Contrib
module Simplecov
module Patcher
include Datadog::Tracing::Contrib::Patcher

def self?.target_version: () -> untyped

def self?.patch: () -> untyped
end
end
end
end
end
23 changes: 23 additions & 0 deletions sig/datadog/ci/contrib/simplecov/result_extractor.rbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
module Coverage
def self.peek_result: () -> untyped
end

module Datadog
module CI
module Contrib
module Simplecov
module ResultExtractor
def self.included: (untyped base) -> untyped

module ClassMethods
include ::SimpleCov

def __dd_peek_result: () -> ::SimpleCov::Result?

def datadog_configuration: () -> untyped
end
end
end
end
end
end
2 changes: 2 additions & 0 deletions sig/datadog/ci/ext/test.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ module Datadog

METRIC_CPU_COUNT: "_dd.host.vcpu_count"

TAG_CODE_COVERAGE_LINES_PCT: "test.code_coverage.lines_pct"

module Status
PASS: "pass"

Expand Down
9 changes: 9 additions & 0 deletions sig/datadog/ci/test_visibility/total_coverage.rbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module Datadog
module CI
module TestVisibility
module TotalCoverage
def self.extract_lines_pct: (Datadog::CI::TestSession test_session) -> void
end
end
end
end
21 changes: 21 additions & 0 deletions vendor/rbs/simplecov/0/simplecov.rbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
module SimpleCov
def self.running: () -> bool

def add_not_loaded_files: (untyped result) -> untyped

def self.__dd_peek_result: () -> SimpleCov::Result?
end

class SimpleCov::Result
def initialize: (untyped result) -> void

def covered_percent: () -> Float
end

class SimpleCov::UselessResultsRemover
def self.call: (untyped result) -> untyped
end

class SimpleCov::ResultAdapter
def self.call: (untyped result) -> untyped
end

0 comments on commit 9681ab4

Please sign in to comment.