diff --git a/lib/datadog/ci/contrib/rspec/patcher.rb b/lib/datadog/ci/contrib/rspec/patcher.rb index 80365e678..b2c155f38 100644 --- a/lib/datadog/ci/contrib/rspec/patcher.rb +++ b/lib/datadog/ci/contrib/rspec/patcher.rb @@ -2,6 +2,7 @@ require "datadog/tracing/contrib/patcher" require_relative "example" +require_relative "runner" module Datadog module CI @@ -19,6 +20,7 @@ def target_version def patch ::RSpec::Core::Example.include(Example) + ::RSpec::Core::Runner.include(Runner) end end end diff --git a/lib/datadog/ci/contrib/rspec/runner.rb b/lib/datadog/ci/contrib/rspec/runner.rb new file mode 100644 index 000000000..779852528 --- /dev/null +++ b/lib/datadog/ci/contrib/rspec/runner.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +require_relative "../../ext/test" +require_relative "ext" + +module Datadog + module CI + module Contrib + module RSpec + # Instrument RSpec::Core::Runner + module Runner + def self.included(base) + base.prepend(InstanceMethods) + end + + module InstanceMethods + def run(err, out) + return super unless configuration[:enabled] + + test_session = CI.start_test_session( + tags: { + CI::Ext::Test::TAG_FRAMEWORK => Ext::FRAMEWORK, + CI::Ext::Test::TAG_FRAMEWORK_VERSION => CI::Contrib::RSpec::Integration.version.to_s, + CI::Ext::Test::TAG_TYPE => Ext::TEST_TYPE + }, + service: configuration[:service_name] + ) + + result = super + + if result != 0 + test_session.failed! + else + test_session.passed! + end + test_session.finish + + result + end + + private + + def configuration + Datadog.configuration.ci[:rspec] + end + end + end + end + end + end +end diff --git a/sig/datadog/ci/contrib/rspec/runner.rbs b/sig/datadog/ci/contrib/rspec/runner.rbs new file mode 100644 index 000000000..ce1bebf4d --- /dev/null +++ b/sig/datadog/ci/contrib/rspec/runner.rbs @@ -0,0 +1,21 @@ +module Datadog + module CI + module Contrib + module RSpec + module Runner + def self.included: (untyped base) -> untyped + + module InstanceMethods + include ::RSpec::Core::Runner + + def run: (untyped err, untyped out) -> untyped + + private + + def configuration: () -> untyped + end + end + end + end + end +end diff --git a/spec/datadog/ci/contrib/rspec/instrumentation_spec.rb b/spec/datadog/ci/contrib/rspec/instrumentation_spec.rb index 2118f19be..5aef113f0 100644 --- a/spec/datadog/ci/contrib/rspec/instrumentation_spec.rb +++ b/spec/datadog/ci/contrib/rspec/instrumentation_spec.rb @@ -207,4 +207,68 @@ def expect_failure expect_failure end end + + context "with rspec runner" do + def devnull + File.new("/dev/null", "w") + end + + it "creates test session span" do + with_new_rspec_environment do + RSpec.describe "SomeTest" do + it "foo" do + # DO NOTHING + end + end + + options = ::RSpec::Core::ConfigurationOptions.new(%w[--pattern none]) + ::RSpec::Core::Runner.new(options).run(devnull, devnull) + end + + expect(test_session_span).not_to be_nil + + expect(test_session_span.span_type).to eq(Datadog::CI::Ext::AppTypes::TYPE_TEST_SESSION) + expect(test_session_span.get_tag(Datadog::CI::Ext::Test::TAG_SPAN_KIND)).to eq( + Datadog::CI::Ext::AppTypes::TYPE_TEST + ) + expect(test_session_span.get_tag(Datadog::CI::Ext::Test::TAG_TYPE)).to eq( + Datadog::CI::Contrib::RSpec::Ext::TEST_TYPE + ) + expect(test_session_span.get_tag(Datadog::CI::Ext::Test::TAG_FRAMEWORK)).to eq( + Datadog::CI::Contrib::RSpec::Ext::FRAMEWORK + ) + expect(test_session_span.get_tag(Datadog::CI::Ext::Test::TAG_FRAMEWORK_VERSION)).to eq( + Datadog::CI::Contrib::RSpec::Integration.version.to_s + ) + expect(test_session_span.get_tag(Datadog::CI::Ext::Test::TAG_STATUS)).to eq( + Datadog::CI::Ext::Test::Status::PASS + ) + end + + context "with failures" do + it "creates test session span with failed state" do + with_new_rspec_environment do + RSpec.describe "SomeTest" do + it "foo" do + # DO NOTHING + end + end + + RSpec.describe "SomeTestThatFailed" do + it "fails" do + expect(1).to eq(2) + end + end + + options = ::RSpec::Core::ConfigurationOptions.new(%w[--pattern none]) + ::RSpec::Core::Runner.new(options).run(devnull, devnull) + end + + expect(test_session_span).not_to be_nil + expect(test_session_span.get_tag(Datadog::CI::Ext::Test::TAG_STATUS)).to eq( + Datadog::CI::Ext::Test::Status::FAIL + ) + end + end + end end diff --git a/vendor/rbs/rspec/0/rspec.rbs b/vendor/rbs/rspec/0/rspec.rbs index e97f05f6c..59d8aab01 100644 --- a/vendor/rbs/rspec/0/rspec.rbs +++ b/vendor/rbs/rspec/0/rspec.rbs @@ -11,3 +11,7 @@ module RSpec::Core::Example def description: () -> String def full_description: () -> String end + +module RSpec::Core::Runner + def run: (untyped err, untyped out) -> untyped +end \ No newline at end of file