From 0f74894f2d06aaaf762b2dc7cf686eeaae5d919a Mon Sep 17 00:00:00 2001 From: Andrey Marchenko Date: Mon, 18 Mar 2024 15:25:43 +0100 Subject: [PATCH] assign the single running test suite for a test if none found by test suite name --- .../ci/test_visibility/context/global.rb | 8 ++++ lib/datadog/ci/test_visibility/recorder.rb | 23 ++++++++++++ .../ci/test_visibility/context/global.rbs | 2 + sig/datadog/ci/test_visibility/recorder.rbs | 2 + .../ci/test_visibility/context/global_spec.rb | 37 +++++++++++++++++++ .../ci/test_visibility/recorder_spec.rb | 26 +++++++++++++ 6 files changed, 98 insertions(+) diff --git a/lib/datadog/ci/test_visibility/context/global.rb b/lib/datadog/ci/test_visibility/context/global.rb index 0691c6e1..c87430fc 100644 --- a/lib/datadog/ci/test_visibility/context/global.rb +++ b/lib/datadog/ci/test_visibility/context/global.rb @@ -21,6 +21,14 @@ def fetch_or_activate_test_suite(test_suite_name, &block) end end + def fetch_single_test_suite + @mutex.synchronize do + return nil if @test_suites.empty? || @test_suites.size > 1 + + @test_suites.values.first + end + end + def fetch_or_activate_test_module(&block) @mutex.synchronize do @test_module ||= block.call diff --git a/lib/datadog/ci/test_visibility/recorder.rb b/lib/datadog/ci/test_visibility/recorder.rb index 29330254..249e3b05 100644 --- a/lib/datadog/ci/test_visibility/recorder.rb +++ b/lib/datadog/ci/test_visibility/recorder.rb @@ -227,6 +227,11 @@ def build_test_suite(tracer_span, tags) def build_test(tracer_span, tags) test = Test.new(tracer_span) set_initial_tags(test, tags) + + # sometimes test suite is not being assigned correctly + # fix it by fetching the one single running test suite from the global context + fix_test_suite!(test) if test.test_suite_id.nil? + validate_test_suite_level_visibility_correctness(test) set_codeowners(test) @@ -294,6 +299,24 @@ def set_suite_context(tags, span: nil, name: nil) end end + def fix_test_suite!(test) + test_suite = @global_context.fetch_single_test_suite + unless test_suite + Datadog.logger.debug do + "Trying to fix test suite for test [#{test.name}] but no single test suite is running." + end + return + end + + Datadog.logger.debug do + "For test [#{test.name}]: expected test suite [#{test.test_suite_name}] to be running, " \ + "but it was not found. Fixing it by assigning test suite [#{test_suite.name}] to the test." + end + + test.set_tag(Ext::Test::TAG_TEST_SUITE_ID, test_suite.id.to_s) + test.set_tag(Ext::Test::TAG_SUITE, test_suite.name) + end + def start_datadog_tracer_span(span_name, span_options, &block) if block Datadog::Tracing.trace(span_name, **span_options) do |tracer_span, trace| diff --git a/sig/datadog/ci/test_visibility/context/global.rbs b/sig/datadog/ci/test_visibility/context/global.rbs index 5dd3a1a9..04d4e404 100644 --- a/sig/datadog/ci/test_visibility/context/global.rbs +++ b/sig/datadog/ci/test_visibility/context/global.rbs @@ -13,6 +13,8 @@ module Datadog def fetch_or_activate_test_suite: (String test_suite_name) {() -> Datadog::CI::TestSuite} -> Datadog::CI::TestSuite + def fetch_single_test_suite: () -> Datadog::CI::TestSuite? + def fetch_or_activate_test_module: () {() -> Datadog::CI::TestModule} -> Datadog::CI::TestModule def fetch_or_activate_test_session: () {() -> Datadog::CI::TestSession} -> Datadog::CI::TestSession diff --git a/sig/datadog/ci/test_visibility/recorder.rbs b/sig/datadog/ci/test_visibility/recorder.rbs index 1f1c96a2..c2017750 100644 --- a/sig/datadog/ci/test_visibility/recorder.rbs +++ b/sig/datadog/ci/test_visibility/recorder.rbs @@ -73,6 +73,8 @@ module Datadog def set_suite_context: (Hash[untyped, untyped] tags, ?span: Datadog::Tracing::SpanOperation, ?name: String) -> void + def fix_test_suite!: (Datadog::CI::Test test) -> void + def set_module_context: (Hash[untyped, untyped] tags, ?Datadog::CI::TestModule | Datadog::Tracing::SpanOperation? test_module) -> void def set_codeowners: (Datadog::CI::Test test) -> void diff --git a/spec/datadog/ci/test_visibility/context/global_spec.rb b/spec/datadog/ci/test_visibility/context/global_spec.rb index 29732d02..72cc669f 100644 --- a/spec/datadog/ci/test_visibility/context/global_spec.rb +++ b/spec/datadog/ci/test_visibility/context/global_spec.rb @@ -182,6 +182,43 @@ end end end + describe "#fetch_single_test_suite" do + let(:test_suite_name) { "my.suite" } + let(:tracer_span) { double(Datadog::Tracing::SpanOperation, name: test_suite_name) } + let(:test_suite) { Datadog::CI::TestSuite.new(tracer_span) } + + context "when a single test suite is active" do + before do + subject.fetch_or_activate_test_suite(test_suite_name) { test_suite } + end + + it "returns the single active test suite" do + result = subject.fetch_single_test_suite + + expect(result).to be(test_suite) + end + end + + context "when no test suites are running" do + it "returns nil" do + expect(subject.fetch_single_test_suite).to be_nil + end + end + + context "when multiple test suites are running" do + before do + ["suite1", "suite2"].each do |test_suite_name| + subject.fetch_or_activate_test_suite(test_suite_name) do + Datadog::CI::TestSuite.new(double(Datadog::Tracing::SpanOperation)) + end + end + end + + it "returns nil" do + expect(subject.fetch_single_test_suite).to be_nil + end + end + end describe "#fetch_or_activate_test_module" do let(:test_module_name) { "my.module" } diff --git a/spec/datadog/ci/test_visibility/recorder_spec.rb b/spec/datadog/ci/test_visibility/recorder_spec.rb index da2d558e..34bdd013 100644 --- a/spec/datadog/ci/test_visibility/recorder_spec.rb +++ b/spec/datadog/ci/test_visibility/recorder_spec.rb @@ -310,6 +310,32 @@ expect(subject).to have_test_tag(:suite, test_suite_name) end end + + context "when there is a running test suite but with a different name" do + let(:test_suite) do + recorder.start_test_suite("other suite") + end + + before do + test_suite + end + + it "connects the test span to the running test suite" do + expect(subject).to have_test_tag(:test_suite_id, test_suite.id.to_s) + expect(subject).to have_test_tag(:suite, "other suite") + end + end + + context "when there are several running test suites with different names" do + before do + recorder.start_test_suite("other suite") + recorder.start_test_suite("other other suite") + end + + it "does not connect test to test suite" do + expect(subject).not_to have_test_tag(:test_suite_id) + end + end end end end