From 59c0ebd3cbd2502f0e3c4227ed860fb17ae0c841 Mon Sep 17 00:00:00 2001 From: Andrey Marchenko Date: Wed, 27 Dec 2023 16:56:52 +0100 Subject: [PATCH] require minitest plugin only when patching and avoid issues with referencing Minitest --- Steepfile | 1 - lib/datadog/ci/contrib/minitest/patcher.rb | 3 +- lib/datadog/ci/contrib/minitest/plugin.rb | 60 +++++++++---------- lib/datadog/ci/contrib/rspec/integration.rb | 2 +- lib/datadog/ci/contrib/settings.rb | 2 +- sig/datadog/ci/contrib/minitest/plugin.rbs | 9 ++- .../contrib/minitest/instrumentation_spec.rb | 2 +- 7 files changed, 42 insertions(+), 37 deletions(-) diff --git a/Steepfile b/Steepfile index dba07a3b..8707ad60 100644 --- a/Steepfile +++ b/Steepfile @@ -4,7 +4,6 @@ target :lib do check "lib" ignore "lib/datadog/ci/configuration/settings.rb" - ignore "lib/datadog/ci/contrib/minitest/plugin.rb" library "pathname" library "json" diff --git a/lib/datadog/ci/contrib/minitest/patcher.rb b/lib/datadog/ci/contrib/minitest/patcher.rb index e294d47a..0b51bec1 100644 --- a/lib/datadog/ci/contrib/minitest/patcher.rb +++ b/lib/datadog/ci/contrib/minitest/patcher.rb @@ -1,7 +1,6 @@ # frozen_string_literal: true require_relative "hooks" -require_relative "plugin" module Datadog module CI @@ -18,6 +17,8 @@ def target_version end def patch + require_relative "plugin" + ::Minitest::Test.include(Hooks) ::Minitest.include(Plugin) diff --git a/lib/datadog/ci/contrib/minitest/plugin.rb b/lib/datadog/ci/contrib/minitest/plugin.rb index 4e767d2a..0df4892c 100644 --- a/lib/datadog/ci/contrib/minitest/plugin.rb +++ b/lib/datadog/ci/contrib/minitest/plugin.rb @@ -14,6 +14,35 @@ def self.included(base) base.extend(ClassMethods) end + class DatadogReporter < ::Minitest::AbstractReporter + def initialize(minitest_reporter) + # This creates circular reference as minitest_reporter also holds reference to DatadogReporter. + # To make sure that minitest_reporter can be garbage collected, we use WeakRef. + @reporter = WeakRef.new(minitest_reporter) + end + + def report + active_test_session = CI.active_test_session + active_test_module = CI.active_test_module + + return unless @reporter.weakref_alive? + return if active_test_session.nil? || active_test_module.nil? + + if @reporter.passed? + active_test_module.passed! + active_test_session.passed! + else + active_test_module.failed! + active_test_session.failed! + end + + active_test_module.finish + active_test_session.finish + + nil + end + end + module ClassMethods def plugin_datadog_ci_init(*) return unless datadog_configuration[:enabled] @@ -28,36 +57,7 @@ def plugin_datadog_ci_init(*) ) CI.start_test_module(test_session.name) - # we create dynamic class here to avoid referencing ::Minitest constant - # in datadog-ci class definitions because Minitest is not always available - datadog_reporter_klass = Class.new(::Minitest::AbstractReporter) do - def initialize(reporter) - # This creates circular reference as reporter holds reference to this reporter. - # To make sure that reporter can be garbage collected, we use WeakRef. - @reporter = WeakRef.new(reporter) - end - - def report - active_test_session = CI.active_test_session - active_test_module = CI.active_test_module - - return unless @reporter.weakref_alive? - return if active_test_session.nil? || active_test_module.nil? - - if @reporter.passed? - active_test_module.passed! - active_test_session.passed! - else - active_test_module.failed! - active_test_session.failed! - end - - active_test_module.finish - active_test_session.finish - end - end - - reporter.reporters << datadog_reporter_klass.new(reporter) + reporter.reporters << DatadogReporter.new(reporter) end private diff --git a/lib/datadog/ci/contrib/rspec/integration.rb b/lib/datadog/ci/contrib/rspec/integration.rb index dbd625cc..339cf2be 100644 --- a/lib/datadog/ci/contrib/rspec/integration.rb +++ b/lib/datadog/ci/contrib/rspec/integration.rb @@ -22,7 +22,7 @@ def self.version end def self.loaded? - !defined?(::RSpec).nil? && !defined?(::RSpec::Core).nil? && \ + !defined?(::RSpec).nil? && !defined?(::RSpec::Core).nil? && !defined?(::RSpec::Core::Example).nil? end diff --git a/lib/datadog/ci/contrib/settings.rb b/lib/datadog/ci/contrib/settings.rb index 2947c8c0..77097c22 100644 --- a/lib/datadog/ci/contrib/settings.rb +++ b/lib/datadog/ci/contrib/settings.rb @@ -27,7 +27,7 @@ def [](name) end def []=(name, value) - respond_to?("#{name}=") ? send("#{name}=", value) : set_option(name, value) + respond_to?(:"#{name}=") ? send(:"#{name}=", value) : set_option(name, value) end end end diff --git a/sig/datadog/ci/contrib/minitest/plugin.rbs b/sig/datadog/ci/contrib/minitest/plugin.rbs index c6dfd431..b2c73996 100644 --- a/sig/datadog/ci/contrib/minitest/plugin.rbs +++ b/sig/datadog/ci/contrib/minitest/plugin.rbs @@ -5,16 +5,21 @@ module Datadog module Plugin def self.included: (untyped base) -> untyped - module ClassMethods - attr_reader reporter: WeakRef + class DatadogReporter < ::Minitest::AbstractReporter @reporter: WeakRef + def initialize: (Minitest::AbstractReporter reporter) -> void + end + + module ClassMethods def plugin_datadog_ci_init: (*untyped) -> (nil | untyped) def initialize: (untyped reporter) -> void def report: () -> (nil | untyped) + def reporter: () -> Minitest::CompositeReporter + private def datadog_configuration: () -> untyped diff --git a/spec/datadog/ci/contrib/minitest/instrumentation_spec.rb b/spec/datadog/ci/contrib/minitest/instrumentation_spec.rb index 1ae8c9d1..08591a64 100644 --- a/spec/datadog/ci/contrib/minitest/instrumentation_spec.rb +++ b/spec/datadog/ci/contrib/minitest/instrumentation_spec.rb @@ -53,7 +53,7 @@ def self.name end num_tests.times do |i| - define_method("test_#{i}") {} + define_method(:"test_#{i}") {} end end