diff --git a/lib/datadog/ci/configuration/components.rb b/lib/datadog/ci/configuration/components.rb index 06433074..5b8b4686 100644 --- a/lib/datadog/ci/configuration/components.rb +++ b/lib/datadog/ci/configuration/components.rb @@ -7,6 +7,7 @@ require_relative "../ext/settings" require_relative "../test_visibility/flush" require_relative "../test_visibility/recorder" +require_relative "../test_visibility/null_recorder" require_relative "../test_visibility/serializers/factories/test_level" require_relative "../test_visibility/serializers/factories/test_suite_level" require_relative "../test_visibility/transport" @@ -21,14 +22,12 @@ module Components def initialize(settings) # Activate CI mode if enabled - activate_ci!(settings) if settings.ci.enabled - - @ci_recorder = TestVisibility::Recorder.new( - enabled: settings.ci.enabled, - test_suite_level_visibility_enabled: settings.ci.experimental_test_suite_level_visibility_enabled - ) + if settings.ci.enabled + activate_ci!(settings) + else + @ci_recorder = TestVisibility::NullRecorder.new + end - # Initialize normally super end @@ -70,6 +69,10 @@ def activate_ci!(settings) end settings.tracing.test_mode.writer_options = writer_options + + @ci_recorder = TestVisibility::Recorder.new( + test_suite_level_visibility_enabled: settings.ci.experimental_test_suite_level_visibility_enabled + ) end def can_use_evp_proxy?(settings, agent_settings) diff --git a/lib/datadog/ci/test_visibility/null_recorder.rb b/lib/datadog/ci/test_visibility/null_recorder.rb new file mode 100644 index 00000000..3024c50d --- /dev/null +++ b/lib/datadog/ci/test_visibility/null_recorder.rb @@ -0,0 +1,73 @@ +# frozen_string_literal: true + +require_relative "recorder" + +module Datadog + module CI + module TestVisibility + # Special recorder that does not record anything + class NullRecorder + def start_test_session(service: nil, tags: {}) + skip_tracing + end + + def start_test_module(test_module_name, service: nil, tags: {}) + skip_tracing + end + + def start_test_suite(test_suite_name, service: nil, tags: {}) + skip_tracing + end + + def trace_test(test_name, test_suite_name, service: nil, tags: {}, &block) + skip_tracing(block) + end + + def trace(span_type, span_name, tags: {}, &block) + skip_tracing(block) + end + + def active_span + end + + def active_test + end + + def active_test_session + end + + def active_test_module + end + + def active_test_suite(test_suite_name) + end + + def deactivate_test(test) + end + + def deactivate_test_session + end + + def deactivate_test_module + end + + def deactivate_test_suite(test_suite_name) + end + + private + + def skip_tracing(block = nil) + if block + block.call(null_span) + else + null_span + end + end + + def null_span + @null_span ||= NullSpan.new + end + end + end + end +end diff --git a/lib/datadog/ci/test_visibility/recorder.rb b/lib/datadog/ci/test_visibility/recorder.rb index e7019338..74b264fa 100644 --- a/lib/datadog/ci/test_visibility/recorder.rb +++ b/lib/datadog/ci/test_visibility/recorder.rb @@ -25,13 +25,12 @@ module TestVisibility # Common behavior for CI tests # Note: this class has too many responsibilities and should be split into multiple classes class Recorder - attr_reader :environment_tags, :test_suite_level_visibility_enabled, :enabled + attr_reader :environment_tags, :test_suite_level_visibility_enabled - def initialize(enabled: true, test_suite_level_visibility_enabled: false) - @enabled = enabled - @test_suite_level_visibility_enabled = enabled && test_suite_level_visibility_enabled + def initialize(test_suite_level_visibility_enabled: false) + @test_suite_level_visibility_enabled = test_suite_level_visibility_enabled - @environment_tags = @enabled ? Ext::Environment.tags(ENV).freeze : {} + @environment_tags = Ext::Environment.tags(ENV).freeze @local_context = Context::Local.new @global_context = Context::Global.new end @@ -83,8 +82,6 @@ def start_test_suite(test_suite_name, service: nil, tags: {}) end def trace_test(test_name, test_suite_name, service: nil, tags: {}, &block) - return skip_tracing(block) unless enabled - set_inherited_globals(tags) set_session_context(tags) set_module_context(tags) @@ -118,8 +115,6 @@ def trace_test(test_name, test_suite_name, service: nil, tags: {}, &block) end def trace(span_type, span_name, tags: {}, &block) - return skip_tracing(block) unless enabled - span_options = build_span_options( nil, # service name is completely optional for custom spans span_type, diff --git a/sig/datadog/ci/test_visibility/null_recorder.rbs b/sig/datadog/ci/test_visibility/null_recorder.rbs new file mode 100644 index 00000000..3b2a84e9 --- /dev/null +++ b/sig/datadog/ci/test_visibility/null_recorder.rbs @@ -0,0 +1,45 @@ +module Datadog + module CI + module TestVisibility + class NullRecorder + @null_span: Datadog::CI::NullSpan + + def initialize: (?untyped args) -> void + + def trace_test: (String span_name, String test_suite_name, ?service: String?, ?tags: Hash[untyped, untyped]) ?{ (Datadog::CI::Span span) -> untyped } -> untyped + + def trace: (String span_type, String span_name, ?tags: Hash[untyped, untyped]) ?{ (Datadog::CI::Span span) -> untyped } -> untyped + + def start_test_session: (?service: String?, ?tags: Hash[untyped, untyped]) -> Datadog::CI::Span + + def start_test_module: (String test_module_name, ?service: String?, ?tags: Hash[untyped, untyped]) -> Datadog::CI::Span + + def start_test_suite: (String test_suite_name, ?service: String?, ?tags: Hash[untyped, untyped]) -> Datadog::CI::Span + + def active_test_session: () -> Datadog::CI::TestSession? + + def active_test_module: () -> Datadog::CI::TestModule? + + def active_test_suite: (String test_suite_name) -> Datadog::CI::TestSuite? + + def active_test: () -> Datadog::CI::Test? + + def active_span: () -> Datadog::CI::Span? + + def deactivate_test: (Datadog::CI::Test test) -> void + + def deactivate_test_session: () -> void + + def deactivate_test_module: () -> void + + def deactivate_test_suite: (String test_suite_name) -> void + + private + + def null_span: () -> Datadog::CI::Span + + def skip_tracing: (?untyped block) -> untyped + end + end + end +end diff --git a/sig/datadog/ci/test_visibility/recorder.rbs b/sig/datadog/ci/test_visibility/recorder.rbs index a948d959..ab56cffc 100644 --- a/sig/datadog/ci/test_visibility/recorder.rbs +++ b/sig/datadog/ci/test_visibility/recorder.rbs @@ -3,7 +3,6 @@ module Datadog module TestVisibility class Recorder @test_suite_level_visibility_enabled: bool - @enabled: bool @environment_tags: Hash[String, String] @local_context: Datadog::CI::TestVisibility::Context::Local @@ -13,9 +12,8 @@ module Datadog attr_reader environment_tags: Hash[String, String] attr_reader test_suite_level_visibility_enabled: bool - attr_reader enabled: bool - def initialize: (?enabled: bool, ?test_suite_level_visibility_enabled: bool) -> void + def initialize: (?test_suite_level_visibility_enabled: bool) -> void def trace_test: (String span_name, String test_suite_name, ?service: String?, ?tags: Hash[untyped, untyped]) ?{ (Datadog::CI::Span span) -> untyped } -> untyped @@ -45,12 +43,12 @@ module Datadog def deactivate_test_suite: (String test_suite_name) -> void + private + def create_datadog_span: (String span_name, ?span_options: Hash[untyped, untyped], ?tags: Hash[untyped, untyped]) ?{ (Datadog::CI::Span span) -> untyped } -> untyped def set_trace_origin: (Datadog::Tracing::TraceOperation trace) -> untyped - private - def build_test: (Datadog::Tracing::SpanOperation tracer_span, Hash[untyped, untyped] tags) -> Datadog::CI::Test def build_test_session: (Datadog::Tracing::SpanOperation tracer_span, Hash[untyped, untyped] tags) -> Datadog::CI::TestSession diff --git a/spec/datadog/ci/configuration/components_spec.rb b/spec/datadog/ci/configuration/components_spec.rb index 404cec57..c280a5d9 100644 --- a/spec/datadog/ci/configuration/components_spec.rb +++ b/spec/datadog/ci/configuration/components_spec.rb @@ -93,6 +93,9 @@ allow(Datadog.logger) .to receive(:error) + allow(Datadog::CI::Ext::Environment) + .to receive(:tags).and_return({}) + components end @@ -106,6 +109,10 @@ context "is enabled" do let(:enabled) { true } + it "collects environment tags" do + expect(Datadog::CI::Ext::Environment).to have_received(:tags).with(ENV) + end + context "when #experimental_test_suite_level_visibility_enabled" do context "is false" do it "creates a CI recorder with test_suite_level_visibility_enabled=false" do @@ -237,6 +244,10 @@ expect(settings.tracing.test_mode) .to_not have_received(:writer_options=) end + + it "does not collect tags" do + expect(Datadog::CI::Ext::Environment).not_to have_received(:tags) + end end end end diff --git a/spec/datadog/ci/test_visibility/null_recorder_spec.rb b/spec/datadog/ci/test_visibility/null_recorder_spec.rb new file mode 100644 index 00000000..2f8b1c81 --- /dev/null +++ b/spec/datadog/ci/test_visibility/null_recorder_spec.rb @@ -0,0 +1,141 @@ +RSpec.describe Datadog::CI::TestVisibility::NullRecorder do + let(:recorder) { described_class.new } + + describe "#trace_test_session" do + subject { recorder.start_test_session } + + it { is_expected.to be_kind_of(Datadog::CI::NullSpan) } + + it "does not activate session" do + expect(recorder.active_test_session).to be_nil + end + end + + describe "#trace_test_module" do + let(:module_name) { "my-module" } + + subject { recorder.start_test_module(module_name) } + + it { is_expected.to be_kind_of(Datadog::CI::NullSpan) } + + it "does not activate module" do + expect(recorder.active_test_module).to be_nil + end + end + + describe "#trace_test_suite" do + let(:suite_name) { "my-module" } + + subject { recorder.start_test_suite(suite_name) } + + it { is_expected.to be_kind_of(Datadog::CI::NullSpan) } + + it "does not activate test suite" do + expect(recorder.active_test_suite(suite_name)).to be_nil + end + end + + describe "#trace_test" do + context "when given a block" do + let(:spy_under_test) { spy("spy") } + + before do + recorder.trace_test("my test", "my suite") do |test_span| + spy_under_test.call + + test_span.passed! + end + end + + it "does not create spans" do + expect(spans.count).to eq(0) + end + + it "executes the test code" do + expect(spy_under_test).to have_received(:call) + end + end + + context "without a block" do + subject { recorder.trace_test("my test", "my suite") } + + it { is_expected.to be_kind_of(Datadog::CI::NullSpan) } + end + end + + describe "#trace" do + context "when given a block" do + let(:spy_under_test) { spy("spy") } + + before do + recorder.trace("step", "my step") do |span| + spy_under_test.call + + span.set_metric("my.metric", 42) + end + end + + it "does not create spans" do + expect(spans.count).to eq(0) + end + + it "executes the test code" do + expect(spy_under_test).to have_received(:call) + end + end + + context "without a block" do + subject { recorder.trace("step", "my step") } + + it { is_expected.to be_kind_of(Datadog::CI::NullSpan) } + end + end + + describe "#active_test_session" do + subject { recorder.active_test_session } + + it { is_expected.to be_nil } + end + + describe "#active_test_module" do + subject { recorder.active_test_module } + it { is_expected.to be_nil } + end + + describe "#active_test" do + subject { recorder.active_test } + + it { is_expected.to be_nil } + end + + describe "#active_span" do + subject { recorder.active_span } + + it { is_expected.to be_nil } + end + + describe "#deactivate_test" do + let(:ci_test) { double } + + subject { recorder.deactivate_test(ci_test) } + + it { is_expected.to be_nil } + end + + describe "#deactivate_test_session" do + subject { recorder.deactivate_test_session } + it { is_expected.to be_nil } + end + + describe "#deactivate_test_module" do + subject { recorder.deactivate_test_module } + + it { is_expected.to be_nil } + end + + describe "#deactivate_test_suite" do + subject { recorder.deactivate_test_suite("my suite") } + + it { is_expected.to be_nil } + end +end diff --git a/spec/datadog/ci/test_visibility/recorder_spec.rb b/spec/datadog/ci/test_visibility/recorder_spec.rb index d34e69ae..25f971d1 100644 --- a/spec/datadog/ci/test_visibility/recorder_spec.rb +++ b/spec/datadog/ci/test_visibility/recorder_spec.rb @@ -44,84 +44,6 @@ end end - context "when CI mode is disabled" do - include_context "CI mode activated" do - let(:experimental_test_suite_level_visibility_enabled) { false } - let(:ci_enabled) { false } - end - - describe "#initialize" do - subject do - described_class.new( - enabled: ci_enabled, - test_suite_level_visibility_enabled: experimental_test_suite_level_visibility_enabled - ) - end - - it "doesn't collect environment tags" do - expect(Datadog::CI::Ext::Environment).not_to receive(:tags) - - subject - end - end - - describe "#trace_test" do - context "when given a block" do - let(:spy_under_test) { spy("spy") } - - before do - recorder.trace_test("my test", "my suite") do |test_span| - spy_under_test.call - - test_span.passed! - end - end - - it "does not create spans" do - expect(spans.count).to eq(0) - end - - it "executes the test code" do - expect(spy_under_test).to have_received(:call) - end - end - - context "without a block" do - subject { recorder.trace_test("my test", "my suite") } - - it { is_expected.to be_kind_of(Datadog::CI::NullSpan) } - end - end - - describe "#trace" do - context "when given a block" do - let(:spy_under_test) { spy("spy") } - - before do - recorder.trace("step", "my step") do |span| - spy_under_test.call - - span.set_metric("my.metric", 42) - end - end - - it "does not create spans" do - expect(spans.count).to eq(0) - end - - it "executes the test code" do - expect(spy_under_test).to have_received(:call) - end - end - - context "without a block" do - subject { recorder.trace("step", "my step") } - - it { is_expected.to be_kind_of(Datadog::CI::NullSpan) } - end - end - end - context "when test suite level visibility is disabled" do let(:service) { "my-service" } let(:tags) { {"test.framework" => "my-framework", "my.tag" => "my_value"} } diff --git a/spec/datadog/ci_spec.rb b/spec/datadog/ci_spec.rb index 7d2c819a..b6539f6f 100644 --- a/spec/datadog/ci_spec.rb +++ b/spec/datadog/ci_spec.rb @@ -1,227 +1,280 @@ RSpec.describe Datadog::CI do - let(:recorder) { instance_double(Datadog::CI::TestVisibility::Recorder) } - - before do - allow(Datadog::CI).to receive(:recorder).and_return(recorder) - end - - describe "::trace_test" do - subject(:trace_test) { described_class.trace_test(test_name, test_suite_name, **options, &block) } - - let(:test_name) { "test name" } - let(:test_suite_name) { "test suite name" } - let(:options) do - { - service: "my-serivce", - tags: {"foo" => "bar"} - } - end - let(:block) { proc {} } - - let(:ci_test) { instance_double(Datadog::CI::Test) } + context "with recorder stubbed" do + let(:recorder) { instance_double(Datadog::CI::TestVisibility::Recorder) } before do - allow(recorder).to receive(:trace_test).with(test_name, test_suite_name, **options, &block).and_return(ci_test) + allow(Datadog::CI).to receive(:recorder).and_return(recorder) end - it { is_expected.to be(ci_test) } - end + describe "::trace_test" do + subject(:trace_test) { described_class.trace_test(test_name, test_suite_name, **options, &block) } - describe "::start_test" do - subject(:start_test) { described_class.start_test(test_name, test_suite_name, **options) } + let(:test_name) { "test name" } + let(:test_suite_name) { "test suite name" } + let(:options) do + { + service: "my-serivce", + tags: {"foo" => "bar"} + } + end + let(:block) { proc {} } - let(:test_name) { "test name" } - let(:test_suite_name) { "test suite name" } - let(:options) do - { - service: "my-serivce", - tags: {"foo" => "bar"} - } - end + let(:ci_test) { instance_double(Datadog::CI::Test) } - let(:ci_test) { instance_double(Datadog::CI::Test) } + before do + allow(recorder).to receive(:trace_test).with(test_name, test_suite_name, **options, &block).and_return(ci_test) + end - before do - allow(recorder).to receive(:trace_test).with(test_name, test_suite_name, **options).and_return(ci_test) + it { is_expected.to be(ci_test) } end - it { is_expected.to be(ci_test) } - end + describe "::start_test" do + subject(:start_test) { described_class.start_test(test_name, test_suite_name, **options) } - describe "::trace" do - subject(:trace) { described_class.trace(span_type, span_name, **options, &block) } + let(:test_name) { "test name" } + let(:test_suite_name) { "test suite name" } + let(:options) do + { + service: "my-serivce", + tags: {"foo" => "bar"} + } + end - let(:span_type) { "span type" } - let(:span_name) { "span name" } - let(:options) { {tags: {"foo" => "bar"}} } - let(:block) { proc {} } + let(:ci_test) { instance_double(Datadog::CI::Test) } - let(:ci_span) { instance_double(Datadog::CI::Span) } + before do + allow(recorder).to receive(:trace_test).with(test_name, test_suite_name, **options).and_return(ci_test) + end - before do - allow(recorder).to receive(:trace).with(span_type, span_name, **options, &block).and_return(ci_span) + it { is_expected.to be(ci_test) } end - it { is_expected.to be(ci_span) } - end + describe "::trace" do + subject(:trace) { described_class.trace(span_type, span_name, **options, &block) } - describe "::active_span" do - subject(:active_span) { described_class.active_span(span_type) } + let(:span_type) { "span type" } + let(:span_name) { "span name" } + let(:options) { {tags: {"foo" => "bar"}} } + let(:block) { proc {} } - let(:span_type) { "span type" } - - context "when span type matches current active span" do - let(:ci_span) { instance_double(Datadog::CI::Span, span_type: span_type) } + let(:ci_span) { instance_double(Datadog::CI::Span) } before do - allow(recorder).to receive(:active_span).and_return(ci_span) + allow(recorder).to receive(:trace).with(span_type, span_name, **options, &block).and_return(ci_span) end it { is_expected.to be(ci_span) } end - context "when span type does not match current active span" do - let(:ci_span) { instance_double(Datadog::CI::Span, span_type: "other span type") } + describe "::active_span" do + subject(:active_span) { described_class.active_span(span_type) } - before do - allow(recorder).to receive(:active_span).and_return(ci_span) - end + let(:span_type) { "span type" } - it { is_expected.to be_nil } - end + context "when span type matches current active span" do + let(:ci_span) { instance_double(Datadog::CI::Span, span_type: span_type) } - context "when no active span" do - before do - allow(recorder).to receive(:active_span).and_return(nil) + before do + allow(recorder).to receive(:active_span).and_return(ci_span) + end + + it { is_expected.to be(ci_span) } end - it { is_expected.to be_nil } - end - end + context "when span type does not match current active span" do + let(:ci_span) { instance_double(Datadog::CI::Span, span_type: "other span type") } - describe "::start_test_session" do - let(:service) { nil } - subject(:start_test_session) { described_class.start_test_session(service: service) } + before do + allow(recorder).to receive(:active_span).and_return(ci_span) + end - let(:ci_test_session) { instance_double(Datadog::CI::TestSession) } + it { is_expected.to be_nil } + end - context "when service is provided" do - let(:service) { "my-service" } + context "when no active span" do + before do + allow(recorder).to receive(:active_span).and_return(nil) + end - before do - allow(recorder).to receive(:start_test_session).with(service: service, tags: {}).and_return(ci_test_session) + it { is_expected.to be_nil } end - - it { is_expected.to be(ci_test_session) } end - context "when service is not provided" do - context "when service is configured on library level" do + describe "::start_test_session" do + let(:service) { nil } + subject(:start_test_session) { described_class.start_test_session(service: service) } + + let(:ci_test_session) { instance_double(Datadog::CI::TestSession) } + + context "when service is provided" do + let(:service) { "my-service" } + before do - allow(Datadog.configuration).to receive(:service).and_return("configured-service") - allow(recorder).to receive(:start_test_session).with( - service: "configured-service", tags: {} - ).and_return(ci_test_session) + allow(recorder).to receive(:start_test_session).with(service: service, tags: {}).and_return(ci_test_session) end it { is_expected.to be(ci_test_session) } end + + context "when service is not provided" do + context "when service is configured on library level" do + before do + allow(Datadog.configuration).to receive(:service).and_return("configured-service") + allow(recorder).to receive(:start_test_session).with( + service: "configured-service", tags: {} + ).and_return(ci_test_session) + end + + it { is_expected.to be(ci_test_session) } + end + end end - end - describe "::active_test_session" do - subject(:active_test_session) { described_class.active_test_session } + describe "::active_test_session" do + subject(:active_test_session) { described_class.active_test_session } - let(:ci_test_session) { instance_double(Datadog::CI::TestSession) } + let(:ci_test_session) { instance_double(Datadog::CI::TestSession) } - before do - allow(recorder).to receive(:active_test_session).and_return(ci_test_session) + before do + allow(recorder).to receive(:active_test_session).and_return(ci_test_session) + end + + it { is_expected.to be(ci_test_session) } end - it { is_expected.to be(ci_test_session) } - end + describe "::deactivate_test_session" do + subject(:deactivate_test_session) { described_class.deactivate_test_session } - describe "::deactivate_test_session" do - subject(:deactivate_test_session) { described_class.deactivate_test_session } + before do + allow(recorder).to receive(:deactivate_test_session) + end - before do - allow(recorder).to receive(:deactivate_test_session) + it { is_expected.to be_nil } end - it { is_expected.to be_nil } - end + describe "::start_test_module" do + subject(:start_test_module) { described_class.start_test_module("my-module") } - describe "::start_test_module" do - subject(:start_test_module) { described_class.start_test_module("my-module") } + let(:ci_test_module) { instance_double(Datadog::CI::TestModule) } - let(:ci_test_module) { instance_double(Datadog::CI::TestModule) } + before do + allow(recorder).to( + receive(:start_test_module).with("my-module", service: nil, tags: {}).and_return(ci_test_module) + ) + end - before do - allow(recorder).to( - receive(:start_test_module).with("my-module", service: nil, tags: {}).and_return(ci_test_module) - ) + it { is_expected.to be(ci_test_module) } end - it { is_expected.to be(ci_test_module) } - end + describe "::active_test_module" do + subject(:active_test_module) { described_class.active_test_module } - describe "::active_test_module" do - subject(:active_test_module) { described_class.active_test_module } + let(:ci_test_module) { instance_double(Datadog::CI::TestModule) } - let(:ci_test_module) { instance_double(Datadog::CI::TestModule) } + before do + allow(recorder).to receive(:active_test_module).and_return(ci_test_module) + end - before do - allow(recorder).to receive(:active_test_module).and_return(ci_test_module) + it { is_expected.to be(ci_test_module) } end - it { is_expected.to be(ci_test_module) } - end + describe "::deactivate_test_module" do + subject(:deactivate_test_module) { described_class.deactivate_test_module } - describe "::deactivate_test_module" do - subject(:deactivate_test_module) { described_class.deactivate_test_module } + before do + allow(recorder).to receive(:deactivate_test_module) + end - before do - allow(recorder).to receive(:deactivate_test_module) + it { is_expected.to be_nil } end - it { is_expected.to be_nil } - end + describe "::start_test_suite" do + subject(:start_test_suite) { described_class.start_test_suite("my-suite") } - describe "::start_test_suite" do - subject(:start_test_suite) { described_class.start_test_suite("my-suite") } + let(:ci_test_suite) { instance_double(Datadog::CI::TestSuite) } - let(:ci_test_suite) { instance_double(Datadog::CI::TestSuite) } + before do + allow(recorder).to( + receive(:start_test_suite).with("my-suite", service: nil, tags: {}).and_return(ci_test_suite) + ) + end - before do - allow(recorder).to( - receive(:start_test_suite).with("my-suite", service: nil, tags: {}).and_return(ci_test_suite) - ) + it { is_expected.to be(ci_test_suite) } end - it { is_expected.to be(ci_test_suite) } - end + describe "::active_test_suite" do + let(:test_suite_name) { "my-suite" } + subject(:active_test_suite) { described_class.active_test_suite(test_suite_name) } - describe "::active_test_suite" do - let(:test_suite_name) { "my-suite" } - subject(:active_test_suite) { described_class.active_test_suite(test_suite_name) } + let(:ci_test_suite) { instance_double(Datadog::CI::TestSuite) } - let(:ci_test_suite) { instance_double(Datadog::CI::TestSuite) } + before do + allow(recorder).to receive(:active_test_suite).with(test_suite_name).and_return(ci_test_suite) + end - before do - allow(recorder).to receive(:active_test_suite).with(test_suite_name).and_return(ci_test_suite) + it { is_expected.to be(ci_test_suite) } end - it { is_expected.to be(ci_test_suite) } + describe "::deactivate_test_suite" do + let(:test_suite_name) { "my-suite" } + subject(:deactivate_test_suite) { described_class.deactivate_test_suite(test_suite_name) } + + before do + allow(recorder).to receive(:deactivate_test_suite).with(test_suite_name) + end + + it { is_expected.to be_nil } + end end - describe "::deactivate_test_suite" do - let(:test_suite_name) { "my-suite" } - subject(:deactivate_test_suite) { described_class.deactivate_test_suite(test_suite_name) } + context "integration testing the manual API" do + context "when CI mode is disabled" do + include_context "CI mode activated" do + let(:experimental_test_suite_level_visibility_enabled) { false } + let(:ci_enabled) { false } + end - before do - allow(recorder).to receive(:deactivate_test_suite).with(test_suite_name) + before do + produce_test_session_trace(with_http_span: true) + end + + it "doesn't record spans via Datadog::CI interface" do + expect(spans.count).to eq(1) # http span only + end end - it { is_expected.to be_nil } + context "when CI mode is enabled" do + context "when test suite level visibility is enabled" do + include_context "CI mode activated" do + let(:experimental_test_suite_level_visibility_enabled) { true } + let(:ci_enabled) { true } + end + + before do + produce_test_session_trace(with_http_span: true) + end + + it "records test suite level spans" do + expect(spans.count).to eq(5) # session + module + suite + test + http span + expect(test_session_span).not_to be_nil + end + end + + context "when test suite level visibility is disabled" do + include_context "CI mode activated" do + let(:experimental_test_suite_level_visibility_enabled) { false } + let(:ci_enabled) { true } + end + + before do + produce_test_session_trace(with_http_span: true) + end + + it "does not record test suite level spans" do + expect(spans.count).to eq(2) # test + http span + expect(test_session_span).to be_nil + end + end + end end end diff --git a/spec/support/tracer_helpers.rb b/spec/support/tracer_helpers.rb index 5a9c37dc..ff1460af 100644 --- a/spec/support/tracer_helpers.rb +++ b/spec/support/tracer_helpers.rb @@ -39,8 +39,8 @@ def produce_test_trace( end end - Datadog::CI.active_test.set_tag("test_owner", "my_team") - Datadog::CI.active_test.set_metric("memory_allocations", 16) + Datadog::CI.active_test.set_tag("test_owner", "my_team") if Datadog::CI.active_test + Datadog::CI.active_test.set_metric("memory_allocations", 16) if Datadog::CI.active_test set_result(test, result: result, exception: exception, skip_reason: skip_reason)