Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SDTEST-301] add source location info to test suites #239

Merged
merged 5 commits into from
Sep 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 25 additions & 3 deletions lib/datadog/ci/contrib/cucumber/formatter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,12 @@ def on_test_case_started(event)
tags[CI::Ext::Test::TAG_PARAMETERS] = Utils::TestRun.test_parameters(arguments: parameters)
end

start_test_suite(test_suite_name) unless same_test_suite_as_current?(test_suite_name)
unless same_test_suite_as_current?(test_suite_name)
start_test_suite(
test_suite_name,
tags: test_suite_source_file_tags(event.test_case)
)
end

test_span = test_visibility_component.trace_test(
event.test_case.name,
Expand Down Expand Up @@ -146,10 +151,10 @@ def finish_session(result)
test_session.finish
end

def start_test_suite(test_suite_name)
def start_test_suite(test_suite_name, tags: {})
finish_current_test_suite

@current_test_suite = test_visibility_component.start_test_suite(test_suite_name)
@current_test_suite = test_visibility_component.start_test_suite(test_suite_name, tags: tags)
end

def finish_current_test_suite
Expand Down Expand Up @@ -201,6 +206,23 @@ def configuration
def test_visibility_component
Datadog.send(:components).test_visibility
end

def test_suite_source_file_tags(test_case)
if test_case.respond_to?(:parent_locations)
# supported in cucumber >= 9.0
source_file = test_case.parent_locations.file
line_number = test_case.parent_locations.line.to_s
else
# fallback for cucumber < 9.0
source_file = test_case.location.file
line_number = "1"
end

{
CI::Ext::Test::TAG_SOURCE_FILE => Git::LocalRepository.relative_to_root(source_file),
CI::Ext::Test::TAG_SOURCE_START => line_number.to_s
}
end
end
end
end
Expand Down
8 changes: 4 additions & 4 deletions lib/datadog/ci/contrib/minitest/helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ module Contrib
module Minitest
module Helpers
def self.test_suite_name(klass, method_name)
source_location = extract_source_location_from_class(klass)
source_location = extract_source_location_from_class(klass)&.first
# if we are in anonymous class, fallback to the method source location
if source_location.nil?
source_location, = klass.instance_method(method_name).source_location
Expand All @@ -23,11 +23,11 @@ def self.parallel?(klass)
end

def self.extract_source_location_from_class(klass)
return nil if klass.nil? || klass.name.nil?
return [] if klass.nil? || klass.name.nil?

klass.const_source_location(klass.name)&.first
klass.const_source_location(klass.name)
rescue
nil
[]
end
end
end
Expand Down
17 changes: 15 additions & 2 deletions lib/datadog/ci/contrib/minitest/runnable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,21 @@ def run(*args)
return super if method.nil?

test_suite_name = Helpers.test_suite_name(self, method)

test_suite = test_visibility_component.start_test_suite(test_suite_name)
source_file, line_number = Helpers.extract_source_location_from_class(self)

test_suite_tags = if source_file
{
CI::Ext::Test::TAG_SOURCE_FILE => (Git::LocalRepository.relative_to_root(source_file) if source_file),
CI::Ext::Test::TAG_SOURCE_START => line_number&.to_s
}
else
{}
end

test_suite = test_visibility_component.start_test_suite(
test_suite_name,
tags: test_suite_tags
)

results = super
return results unless test_suite
Expand Down
8 changes: 7 additions & 1 deletion lib/datadog/ci/contrib/rspec/example_group.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,13 @@ def run(reporter = ::RSpec::Core::NullReporter)
return super unless top_level?

suite_name = "#{description} at #{file_path}"
test_suite = test_visibility_component.start_test_suite(suite_name)
test_suite = test_visibility_component.start_test_suite(
suite_name,
tags: {
CI::Ext::Test::TAG_SOURCE_FILE => Git::LocalRepository.relative_to_root(metadata[:file_path]),
CI::Ext::Test::TAG_SOURCE_START => metadata[:line_number].to_s
}
)

success = super
return success unless test_suite
Expand Down
7 changes: 7 additions & 0 deletions lib/datadog/ci/span.rb
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,13 @@ def runtime_version
tracer_span.get_tag(Ext::Test::TAG_RUNTIME_VERSION)
end

# Source file path where the test or test suite defined (relative to git repository root).
# @return [String] the source file path of the test
# @return [nil] if the source file path is not found
def source_file
get_tag(Ext::Test::TAG_SOURCE_FILE)
end

def set_environment_runtime_tags
tracer_span.set_tag(Ext::Test::TAG_OS_ARCHITECTURE, ::RbConfig::CONFIG["host_cpu"])
tracer_span.set_tag(Ext::Test::TAG_OS_PLATFORM, ::RbConfig::CONFIG["host_os"])
Expand Down
7 changes: 0 additions & 7 deletions lib/datadog/ci/test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,6 @@ def test_session_id
get_tag(Ext::Test::TAG_TEST_SESSION_ID)
end

# Source file path of the test relative to git repository root.
# @return [String] the source file path of the test
# @return [nil] if the source file path is not found
def source_file
get_tag(Ext::Test::TAG_SOURCE_FILE)
end

# Returns "true" if the test is skipped by the intelligent test runner.
# @return [Boolean] true if the test is skipped by the intelligent test runner, false otherwise.
def skipped_by_itr?
Expand Down
8 changes: 5 additions & 3 deletions lib/datadog/ci/test_visibility/component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,8 @@ def on_test_module_started(test_module)
end

def on_test_suite_started(test_suite)
set_codeowners(test_suite)

Telemetry.event_created(test_suite)
end

Expand Down Expand Up @@ -223,10 +225,10 @@ def subscribe_to_after_stop_event(tracer_span)
end
end

def set_codeowners(test)
source = test.source_file
def set_codeowners(span)
source = span.source_file
owners = @codeowners.list_owners(source) if source
test.set_tag(Ext::Test::TAG_CODEOWNERS, owners) unless owners.nil?
span.set_tag(Ext::Test::TAG_CODEOWNERS, owners) unless owners.nil?
end

def fix_test_suite!(test)
Expand Down
4 changes: 3 additions & 1 deletion sig/datadog/ci/contrib/cucumber/formatter.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ module Datadog

def test_suite_name: (untyped test_case) -> String

def start_test_suite: (String test_suite_name) -> void
def start_test_suite: (String test_suite_name, ?tags: Hash[String, String]) -> void

def finish_current_test_suite: () -> void

Expand All @@ -52,6 +52,8 @@ module Datadog
def configuration: () -> untyped

def test_visibility_component: () -> Datadog::CI::TestVisibility::Component

def test_suite_source_file_tags: (untyped test_case) -> Hash[String, String]
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion sig/datadog/ci/contrib/minitest/helpers.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ module Datadog

def self.parallel?: (untyped klass) -> bool

def self.extract_source_location_from_class: (untyped klass) -> String?
def self.extract_source_location_from_class: (untyped klass) -> Array[::String]
end
end
end
Expand Down
2 changes: 2 additions & 0 deletions sig/datadog/ci/span.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ module Datadog

def runtime_version: () -> String?

def source_file: () -> String?

private

def test_visibility: () -> Datadog::CI::TestVisibility::Component
Expand Down
1 change: 0 additions & 1 deletion sig/datadog/ci/test.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ module Datadog
def test_session_id: () -> String?
def skipped_by_itr?: () -> bool
def itr_unskippable!: () -> void
def source_file: () -> String?
def parameters: () -> String?
def is_retry?: () -> bool
def any_retry_passed?: () -> bool
Expand Down
2 changes: 1 addition & 1 deletion sig/datadog/ci/test_visibility/component.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ module Datadog

def fix_test_suite!: (Datadog::CI::Test test) -> void

def set_codeowners: (Datadog::CI::Test test) -> void
def set_codeowners: (Datadog::CI::Span span) -> void

def null_span: () -> Datadog::CI::Span

Expand Down
12 changes: 12 additions & 0 deletions spec/datadog/ci/contrib/cucumber/instrumentation_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,18 @@
:framework_version,
Datadog::CI::Contrib::Cucumber::Integration.version.to_s
)

expect(first_test_suite_span).to have_test_tag(
:source_file,
"passing.feature"
)
expect(first_test_suite_span).to have_test_tag(:source_start, "1")

expect(first_test_suite_span).to have_test_tag(
:codeowners,
"[\"@test-owner\"]"
)

expect(first_test_suite_span).to have_pass_status
end

Expand Down
11 changes: 11 additions & 0 deletions spec/datadog/ci/contrib/minitest/instrumentation_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,17 @@ def test_pass_other
:framework_version,
Datadog::CI::Contrib::Minitest::Integration.version.to_s
)

expect(first_test_suite_span).to have_test_tag(
:source_file,
"spec/datadog/ci/contrib/minitest/instrumentation_spec.rb"
)
expect(first_test_suite_span).to have_test_tag(:source_start, "415")
expect(first_test_suite_span).to have_test_tag(
:codeowners,
"[\"@DataDog/ruby-guild\", \"@DataDog/ci-app-libraries\"]"
)

expect(first_test_suite_span).to have_pass_status
end

Expand Down
13 changes: 12 additions & 1 deletion spec/datadog/ci/contrib/rspec/instrumentation_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -506,7 +506,7 @@ def expect_failure

context "with git root changed" do
before do
expect(Datadog::CI::Git::LocalRepository).to receive(:root).and_return("#{Dir.pwd}/spec")
allow(Datadog::CI::Git::LocalRepository).to receive(:root).and_return("#{Dir.pwd}/spec")
end

it "provides source file path relative to git root" do
Expand Down Expand Up @@ -588,6 +588,17 @@ def expect_failure
:framework_version,
Datadog::CI::Contrib::RSpec::Integration.version.to_s
)

expect(first_test_suite_span).to have_test_tag(
:source_file,
"spec/datadog/ci/contrib/rspec/instrumentation_spec.rb"
)
expect(first_test_suite_span).to have_test_tag(:source_start, "57")
expect(first_test_suite_span).to have_test_tag(
:codeowners,
"[\"@DataDog/ruby-guild\", \"@DataDog/ci-app-libraries\"]"
)

expect(first_test_suite_span).to have_pass_status
end

Expand Down
1 change: 1 addition & 0 deletions vendor/rbs/rspec/0/rspec.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ module RSpec::Core::ExampleGroup
def top_level?: () -> bool
def file_path: () -> String
def description: () -> String
def metadata: () -> untyped
end
end

Expand Down
Loading