diff --git a/lib/datadog/ci/contrib/knapsack/extension.rb b/lib/datadog/ci/contrib/knapsack/extension.rb new file mode 100644 index 00000000..c3fb3b47 --- /dev/null +++ b/lib/datadog/ci/contrib/knapsack/extension.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +require "knapsack_pro/extensions/rspec_extension" + +require_relative "runner" + +module Datadog + module CI + module Contrib + module Knapsack + module Extension + def self.included(base) + base.singleton_class.prepend(ClassMethods) + end + + module ClassMethods + def setup! + super + + ::RSpec::Core::Runner.include(Datadog::CI::Contrib::Knapsack::Runner) + end + end + end + end + end + end +end diff --git a/lib/datadog/ci/contrib/knapsack/integration.rb b/lib/datadog/ci/contrib/knapsack/integration.rb new file mode 100644 index 00000000..e41cc5af --- /dev/null +++ b/lib/datadog/ci/contrib/knapsack/integration.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +require_relative "../integration" +require_relative "patcher" + +module Datadog + module CI + module Contrib + module Knapsack + # Knapsack Pro test runner instrumentation + # https://github.com/KnapsackPro/knapsack_pro-ruby + class Integration + include Datadog::CI::Contrib::Integration + + Configuration = Struct.new(:enabled) + + MINIMUM_VERSION = Gem::Version.new("7.0.0") + + register_as :knapsack + + def self.version + Gem.loaded_specs["knapsack_pro"]&.version + end + + def self.loaded? + !defined?(::KnapsackPro).nil? && !defined?(::KnapsackPro::Extensions::RSpecExtension).nil? && + !defined?(::KnapsackPro::Extensions::RSpecExtension::Runner).nil? + end + + def self.compatible? + super && version >= MINIMUM_VERSION + end + + # test environments should not auto instrument test libraries + def auto_instrument? + false + end + + # TODO: not every integration needs a configuration + def new_configuration + Integration::Configuration.new(true) + end + + def patcher + Patcher + end + end + end + end + end +end diff --git a/lib/datadog/ci/contrib/knapsack/patcher.rb b/lib/datadog/ci/contrib/knapsack/patcher.rb new file mode 100644 index 00000000..f6265919 --- /dev/null +++ b/lib/datadog/ci/contrib/knapsack/patcher.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +require_relative "../patcher" + +module Datadog + module CI + module Contrib + module Knapsack + module Patcher + include Datadog::CI::Contrib::Patcher + + module_function + + def target_version + Integration.version + end + + def patch + if ::RSpec::Core::Runner.ancestors.include?(::KnapsackPro::Extensions::RSpecExtension::Runner) + # knapsack already patched rspec runner + require_relative "runner" + ::RSpec::Core::Runner.include(Datadog::CI::Contrib::Knapsack::Runner) + else + # knapsack didn't patch rspec runner yet + require_relative "extension" + ::KnapsackPro::Extensions::RSpecExtension.include(Datadog::CI::Contrib::Knapsack::Extension) + end + end + end + end + end + end +end diff --git a/lib/datadog/ci/contrib/knapsack/runner.rb b/lib/datadog/ci/contrib/knapsack/runner.rb new file mode 100644 index 00000000..6b2003fc --- /dev/null +++ b/lib/datadog/ci/contrib/knapsack/runner.rb @@ -0,0 +1,61 @@ +# frozen_string_literal: true + +require_relative "../../../ext/test" +require_relative "../ext" + +module Datadog + module CI + module Contrib + module Knapsack + module Runner + def self.included(base) + base.prepend(InstanceMethods) + end + + module InstanceMethods + # TODO: this is coupled to RSpec integration being present + def knapsack__run_specs(*args) + return super if ::RSpec.configuration.dry_run? && !datadog_configuration[:dry_run_enabled] + return super unless datadog_configuration[:enabled] + + test_session = test_visibility_component.start_test_session( + tags: { + CI::Ext::Test::TAG_FRAMEWORK => CI::Contrib::RSpec::Ext::FRAMEWORK, + CI::Ext::Test::TAG_FRAMEWORK_VERSION => CI::Contrib::RSpec::Integration.version.to_s + }, + service: datadog_configuration[:service_name] + ) + + test_module = test_visibility_component.start_test_module(CI::Contrib::RSpec::Ext::FRAMEWORK) + + result = super + return result unless test_module && test_session + + if result != 0 + test_module.failed! + test_session.failed! + else + test_module.passed! + test_session.passed! + end + test_module.finish + test_session.finish + + result + end + + private + + def datadog_configuration + Datadog.configuration.ci[:rspec] + end + + def test_visibility_component + Datadog.send(:components).test_visibility + end + end + end + end + end + end +end diff --git a/lib/datadog/ci/contrib/rspec/knapsack_pro/extension.rb b/lib/datadog/ci/contrib/rspec/knapsack_pro/extension.rb deleted file mode 100644 index f7fe2dcd..00000000 --- a/lib/datadog/ci/contrib/rspec/knapsack_pro/extension.rb +++ /dev/null @@ -1,29 +0,0 @@ -# frozen_string_literal: true - -require "knapsack_pro/extensions/rspec_extension" - -require_relative "runner" - -module Datadog - module CI - module Contrib - module RSpec - module KnapsackPro - module Extension - def self.included(base) - base.singleton_class.prepend(ClassMethods) - end - - module ClassMethods - def setup! - super - - ::RSpec::Core::Runner.include(Datadog::CI::Contrib::RSpec::KnapsackPro::Runner) - end - end - end - end - end - end - end -end diff --git a/lib/datadog/ci/contrib/rspec/knapsack_pro/patcher.rb b/lib/datadog/ci/contrib/rspec/knapsack_pro/patcher.rb deleted file mode 100644 index 3346f6da..00000000 --- a/lib/datadog/ci/contrib/rspec/knapsack_pro/patcher.rb +++ /dev/null @@ -1,26 +0,0 @@ -# frozen_string_literal: true - -module Datadog - module CI - module Contrib - module RSpec - module KnapsackPro - module Patcher - def self.patch - if defined?(::KnapsackPro::Extensions::RSpecExtension::Runner) && - ::RSpec::Core::Runner.ancestors.include?(::KnapsackPro::Extensions::RSpecExtension::Runner) - # knapsack already patched rspec runner - require_relative "runner" - ::RSpec::Core::Runner.include(KnapsackPro::Runner) - else - # knapsack didn't patch rspec runner yet - require_relative "extension" - ::KnapsackPro::Extensions::RSpecExtension.include(KnapsackPro::Extension) - end - end - end - end - end - end - end -end diff --git a/lib/datadog/ci/contrib/rspec/knapsack_pro/runner.rb b/lib/datadog/ci/contrib/rspec/knapsack_pro/runner.rb deleted file mode 100644 index c4a386f1..00000000 --- a/lib/datadog/ci/contrib/rspec/knapsack_pro/runner.rb +++ /dev/null @@ -1,62 +0,0 @@ -# frozen_string_literal: true - -require_relative "../../../ext/test" -require_relative "../ext" - -module Datadog - module CI - module Contrib - module RSpec - module KnapsackPro - module Runner - def self.included(base) - base.prepend(InstanceMethods) - end - - module InstanceMethods - def knapsack__run_specs(*args) - return super if ::RSpec.configuration.dry_run? && !datadog_configuration[:dry_run_enabled] - return super unless datadog_configuration[:enabled] - - test_session = test_visibility_component.start_test_session( - tags: { - CI::Ext::Test::TAG_FRAMEWORK => Ext::FRAMEWORK, - CI::Ext::Test::TAG_FRAMEWORK_VERSION => CI::Contrib::RSpec::Integration.version.to_s - }, - service: datadog_configuration[:service_name] - ) - - test_module = test_visibility_component.start_test_module(Ext::FRAMEWORK) - - result = super - return result unless test_module && test_session - - if result != 0 - test_module.failed! - test_session.failed! - else - test_module.passed! - test_session.passed! - end - test_module.finish - test_session.finish - - result - end - - private - - def datadog_configuration - Datadog.configuration.ci[:rspec] - end - - def test_visibility_component - Datadog.send(:components).test_visibility - end - end - end - end - end - end - end -end diff --git a/lib/datadog/ci/contrib/rspec/patcher.rb b/lib/datadog/ci/contrib/rspec/patcher.rb index 145ed035..fa698d83 100644 --- a/lib/datadog/ci/contrib/rspec/patcher.rb +++ b/lib/datadog/ci/contrib/rspec/patcher.rb @@ -27,13 +27,6 @@ def patch ::RSpec::Queue::Runner.include(Runner) end - if knapsack_pro? - # Knapsack Pro test runner instrumentation - # https://github.com/KnapsackPro/knapsack_pro-ruby - require_relative "knapsack_pro/patcher" - Datadog::CI::Contrib::RSpec::KnapsackPro::Patcher.patch - end - # default rspec test runner instrumentation ::RSpec::Core::Runner.include(Runner) @@ -44,14 +37,6 @@ def patch def ci_queue? !!defined?(::RSpec::Queue::Runner) end - - def knapsack_pro? - knapsack_version = Gem.loaded_specs["knapsack_pro"]&.version - - # additional instrumentation is needed for KnapsackPro version 7 and later - !!defined?(::KnapsackPro) && - !knapsack_version.nil? && knapsack_version >= Gem::Version.new("7") - end end end end diff --git a/sig/datadog/ci/contrib/knapsack/extension.rbs b/sig/datadog/ci/contrib/knapsack/extension.rbs new file mode 100644 index 00000000..92576fec --- /dev/null +++ b/sig/datadog/ci/contrib/knapsack/extension.rbs @@ -0,0 +1,17 @@ +module Datadog + module CI + module Contrib + module Knapsack + module Extension + def self.included: (untyped base) -> untyped + + module ClassMethods + include ::KnapsackPro::Extensions::RSpecExtension + + def setup!: () -> void + end + end + end + end + end +end diff --git a/sig/datadog/ci/contrib/knapsack/integration.rbs b/sig/datadog/ci/contrib/knapsack/integration.rbs new file mode 100644 index 00000000..cf19b5b7 --- /dev/null +++ b/sig/datadog/ci/contrib/knapsack/integration.rbs @@ -0,0 +1,30 @@ +module Datadog + module CI + module Contrib + module Knapsack + class Integration + extend Datadog::CI::Contrib::Integration::ClassMethods + include Datadog::CI::Contrib::Integration::InstanceMethods + + class Configuration + def initialize: (bool enabled) -> void + end + + MINIMUM_VERSION: Gem::Version + + def self.version: () -> untyped + + def self.loaded?: () -> bool + + def self.compatible?: () -> bool + + def auto_instrument?: () -> bool + + def new_configuration: () -> Configuration + + def patcher: () -> singleton(Patcher) + end + end + end + end +end diff --git a/sig/datadog/ci/contrib/knapsack/patcher.rbs b/sig/datadog/ci/contrib/knapsack/patcher.rbs new file mode 100644 index 00000000..48ef1611 --- /dev/null +++ b/sig/datadog/ci/contrib/knapsack/patcher.rbs @@ -0,0 +1,11 @@ +module Datadog + module CI + module Contrib + module Knapsack + module Patcher + def self.patch: () -> void + end + end + end + end +end diff --git a/sig/datadog/ci/contrib/knapsack/runner.rbs b/sig/datadog/ci/contrib/knapsack/runner.rbs new file mode 100644 index 00000000..f51cbb99 --- /dev/null +++ b/sig/datadog/ci/contrib/knapsack/runner.rbs @@ -0,0 +1,23 @@ +module Datadog + module CI + module Contrib + module Knapsack + module Runner + def self.included: (untyped base) -> untyped + + module InstanceMethods + include ::KnapsackPro::Runners::Queue::RSpecRunner + + def knapsack__run_specs: (untyped args) -> untyped + + private + + def datadog_configuration: () -> untyped + + def test_visibility_component: () -> Datadog::CI::TestVisibility::Component + end + end + end + end + end +end diff --git a/sig/datadog/ci/contrib/rspec/knapsack_pro/extension.rbs b/sig/datadog/ci/contrib/rspec/knapsack_pro/extension.rbs deleted file mode 100644 index f0aa363c..00000000 --- a/sig/datadog/ci/contrib/rspec/knapsack_pro/extension.rbs +++ /dev/null @@ -1,19 +0,0 @@ -module Datadog - module CI - module Contrib - module RSpec - module KnapsackPro - module Extension - def self.included: (untyped base) -> untyped - - module ClassMethods - include ::KnapsackPro::Extensions::RSpecExtension - - def setup!: () -> void - end - end - end - end - end - end -end diff --git a/sig/datadog/ci/contrib/rspec/knapsack_pro/patcher.rbs b/sig/datadog/ci/contrib/rspec/knapsack_pro/patcher.rbs deleted file mode 100644 index 11d34d86..00000000 --- a/sig/datadog/ci/contrib/rspec/knapsack_pro/patcher.rbs +++ /dev/null @@ -1,13 +0,0 @@ -module Datadog - module CI - module Contrib - module RSpec - module KnapsackPro - module Patcher - def self.patch: () -> void - end - end - end - end - end -end diff --git a/sig/datadog/ci/contrib/rspec/knapsack_pro/runner.rbs b/sig/datadog/ci/contrib/rspec/knapsack_pro/runner.rbs deleted file mode 100644 index f850b66e..00000000 --- a/sig/datadog/ci/contrib/rspec/knapsack_pro/runner.rbs +++ /dev/null @@ -1,25 +0,0 @@ -module Datadog - module CI - module Contrib - module RSpec - module KnapsackPro - module Runner - def self.included: (untyped base) -> untyped - - module InstanceMethods - include ::KnapsackPro::Runners::Queue::RSpecRunner - - def knapsack__run_specs: (untyped args) -> untyped - - private - - def datadog_configuration: () -> untyped - - def test_visibility_component: () -> Datadog::CI::TestVisibility::Component - end - end - end - end - end - end -end