Class: Datadog::CI::Test
Overview
Represents a single part of a test run.
Instance Attribute Summary collapse
-
#context_ids ⇒ Array<String>
Context IDs for this test (used for TIA context coverage merging).
Attributes inherited from Span
Instance Method Summary collapse
-
#add_impacted_files(file_paths) ⇒ void
Adds custom files that Test Impact Analysis should consider capable of impacting this test.
- #all_executions_failed? ⇒ Boolean
- #all_executions_passed? ⇒ Boolean
- #any_retry_passed? ⇒ Boolean
-
#attempt_to_fix? ⇒ Boolean
Returns "true" if this flaky test has fixing attempts (determined by Datadog backend).
- #datadog_skip_reason ⇒ Object
-
#datadog_test_id ⇒ String
The test id according to Datadog's test impact analysis.
-
#disabled? ⇒ Boolean
Returns "true" if this test is disabled by Datadog test management.
-
#end_line ⇒ Integer?
Returns the ending line number of the test in the source file.
-
#failed!(exception: nil) ⇒ void
Sets the status of the span to "fail".
-
#finish ⇒ void
Finishes the current test.
-
#inherit_impacted_files(custom_impacted_files) ⇒ void
Inherits suite-level custom impacted files without copying them.
-
#initialize(tracer_span) ⇒ Test
constructor
A new instance of Test.
-
#is_new? ⇒ Boolean
Returns "true" if this span represents a test that wasn't known to Datadog before.
-
#is_retry? ⇒ Boolean
Returns "true" if test span represents a retry.
-
#itr_unskippable! ⇒ void
Marks this test as unskippable by the Test Impact Analysis.
-
#lock_custom_impacted_files ⇒ Array<String>
Locks custom impacted files against further changes and returns them to Test Impact Analysis.
-
#modified? ⇒ Boolean
Returns "true" if this test is marked as modified (e.g., impacted by code changes).
-
#name ⇒ String
The name of the test.
-
#parameters ⇒ String?
Gets the parameters for this test (e.g. Cucumber example or RSpec specs) as a serialized JSON.
-
#passed! ⇒ void
Sets the status of the span to "pass".
- #peek_duration ⇒ Object
-
#quarantined? ⇒ Boolean
Returns "true" if this test is quarantined by Datadog test management.
- #record_final_status ⇒ Object
-
#retry_reason ⇒ String
Returns string with a reason why test was retried.
-
#set_parameters(arguments, metadata = {}) ⇒ void
Sets the parameters for this test (e.g. Cucumber example or RSpec specs).
- #should_ignore_failures? ⇒ Boolean
- #should_skip? ⇒ Boolean
-
#skipped!(exception: nil, reason: nil) ⇒ void
Sets the status of the span to "skip".
- #skipped_by_test_impact_analysis? ⇒ Boolean
-
#start_line ⇒ Integer?
Returns the starting line number of the test in the source file.
-
#test_module_id ⇒ String
Span id of the running test module this test belongs to.
-
#test_module_name ⇒ String
Name of the running test module this test belongs to.
-
#test_session_id ⇒ String
Span id of the running test session this test belongs to.
-
#test_suite ⇒ Datadog::CI::TestSuite?
Running test suite that this test is part of (if any).
-
#test_suite_id ⇒ String
Span id of the running test suite this test belongs to.
-
#test_suite_name ⇒ String
Name of the running test suite this test belongs to.
Methods inherited from Span
#base_commit_sha, #clear_tag, #failed?, #get_metric, #get_tag, #git_branch, #git_commit_message, #git_commit_sha, #git_repository_url, #git_tag, #id, #original_git_commit_message, #original_git_commit_sha, #os_architecture, #os_platform, #os_version, #passed?, #runtime_name, #runtime_version, #service, #set_default_tags, #set_environment_runtime_tags, #set_metric, #set_tag, #set_tags, #skipped?, #source_file, #status, #to_s, #trace_id, #type, #undefined?
Constructor Details
#initialize(tracer_span) ⇒ Test
Returns a new instance of Test.
15 16 17 18 19 20 |
# File 'lib/datadog/ci/test.rb', line 15 def initialize(tracer_span) super @custom_impacted_files = [] @inherited_custom_impacted_files = [] end |
Instance Attribute Details
#context_ids ⇒ Array<String>
Context IDs for this test (used for TIA context coverage merging). Contains list of context identifiers from outermost to innermost.
25 26 27 |
# File 'lib/datadog/ci/test.rb', line 25 def context_ids @context_ids end |
Instance Method Details
#add_impacted_files(file_paths) ⇒ void
This method returns an undefined value.
Adds custom files that Test Impact Analysis should consider capable of impacting this test.
This is useful for files that Datadog's native Ruby coverage cannot observe, such as JavaScript executed in a browser during a Capybara test. Paths must resolve inside the Git repository. Relative paths must be relative to the repository root. Absolute paths are also accepted.
If paths are relative to the current working directory, convert them to
absolute paths with File.expand_path before calling this method.
Submitted paths must be lexically normalized without redundant . or
.. components.
Path resolution does not access the filesystem, so files do not need to exist when they are added. Paths outside the repository are ignored when the coverage event is serialized. Calls are incremental: every call adds files for the remainder of the test.
199 200 201 202 203 204 |
# File 'lib/datadog/ci/test.rb', line 199 def add_impacted_files(file_paths) raise ArgumentError, "file_paths must be an Array" unless file_paths.is_a?(Array) @custom_impacted_files.concat(file_paths) nil end |
#all_executions_failed? ⇒ Boolean
280 281 282 |
# File 'lib/datadog/ci/test.rb', line 280 def all_executions_failed? !!test_suite&.all_executions_failed?(datadog_test_id) end |
#all_executions_passed? ⇒ Boolean
285 286 287 |
# File 'lib/datadog/ci/test.rb', line 285 def all_executions_passed? !!test_suite&.all_executions_passed?(datadog_test_id) end |
#any_retry_passed? ⇒ Boolean
275 276 277 |
# File 'lib/datadog/ci/test.rb', line 275 def any_retry_passed? !!test_suite&.any_test_retry_passed?(datadog_test_id) end |
#attempt_to_fix? ⇒ Boolean
Returns "true" if this flaky test has fixing attempts (determined by Datadog backend).
135 136 137 |
# File 'lib/datadog/ci/test.rb', line 135 def attempt_to_fix? get_tag(Ext::Test::TAG_IS_ATTEMPT_TO_FIX) == "true" end |
#datadog_skip_reason ⇒ Object
290 291 292 293 294 295 296 |
# File 'lib/datadog/ci/test.rb', line 290 def datadog_skip_reason if skipped_by_test_impact_analysis? Ext::Test::SkipReason::TEST_IMPACT_ANALYSIS elsif disabled? || quarantined? Ext::Test::SkipReason::TEST_MANAGEMENT_DISABLED end end |
#datadog_test_id ⇒ String
Returns the test id according to Datadog's test impact analysis.
33 34 35 |
# File 'lib/datadog/ci/test.rb', line 33 def datadog_test_id @datadog_test_id ||= Utils::TestRun.datadog_test_id(name, test_suite_name, parameters) end |
#disabled? ⇒ Boolean
Returns "true" if this test is disabled by Datadog test management.
129 130 131 |
# File 'lib/datadog/ci/test.rb', line 129 def disabled? get_tag(Ext::Test::TAG_IS_TEST_DISABLED) == "true" end |
#end_line ⇒ Integer?
Returns the ending line number of the test in the source file.
98 99 100 101 |
# File 'lib/datadog/ci/test.rb', line 98 def end_line line = get_tag(Ext::Test::TAG_SOURCE_END) line&.to_i end |
#failed!(exception: nil) ⇒ void
This method returns an undefined value.
Sets the status of the span to "fail".
238 239 240 241 242 |
# File 'lib/datadog/ci/test.rb', line 238 def failed!(exception: nil) super record_test_result(Ext::Test::Status::FAIL) end |
#finish ⇒ void
This method returns an undefined value.
Finishes the current test.
39 40 41 42 43 44 45 46 47 |
# File 'lib/datadog/ci/test.rb', line 39 def finish if is_retry? && retry_reason.nil? set_tag(Ext::Test::TAG_RETRY_REASON, Ext::Test::RetryReason::RETRY_EXTERNAL) end test_tracing.deactivate_test super end |
#inherit_impacted_files(custom_impacted_files) ⇒ void
This method returns an undefined value.
Inherits suite-level custom impacted files without copying them.
210 211 212 213 |
# File 'lib/datadog/ci/test.rb', line 210 def inherit_impacted_files(custom_impacted_files) @inherited_custom_impacted_files = custom_impacted_files nil end |
#is_new? ⇒ Boolean
Returns "true" if this span represents a test that wasn't known to Datadog before.
117 118 119 |
# File 'lib/datadog/ci/test.rb', line 117 def is_new? get_tag(Ext::Test::TAG_IS_NEW) == "true" end |
#is_retry? ⇒ Boolean
Returns "true" if test span represents a retry.
105 106 107 |
# File 'lib/datadog/ci/test.rb', line 105 def is_retry? get_tag(Ext::Test::TAG_IS_RETRY) == "true" end |
#itr_unskippable! ⇒ void
This method returns an undefined value.
Marks this test as unskippable by the Test Impact Analysis. This must be done before the test execution starts.
Examples of tests that should be unskippable:
- tests that read files from disk
- tests that make network requests
- tests that call external processes
- tests that use forking
155 156 157 158 159 160 161 162 163 164 165 |
# File 'lib/datadog/ci/test.rb', line 155 def itr_unskippable! TestImpactAnalysis::Telemetry.itr_unskippable set_tag(Ext::Test::TAG_ITR_UNSKIPPABLE, "true") if skipped_by_test_impact_analysis? clear_tag(Ext::Test::TAG_ITR_SKIPPED_BY_ITR) TestImpactAnalysis::Telemetry.itr_forced_run set_tag(Ext::Test::TAG_ITR_FORCED_RUN, "true") end end |
#lock_custom_impacted_files ⇒ Array<String>
Locks custom impacted files against further changes and returns them to Test Impact Analysis.
220 221 222 223 224 225 |
# File 'lib/datadog/ci/test.rb', line 220 def lock_custom_impacted_files return @custom_impacted_files if @custom_impacted_files.frozen? @custom_impacted_files = (@inherited_custom_impacted_files | @custom_impacted_files).freeze end |
#modified? ⇒ Boolean
Returns "true" if this test is marked as modified (e.g., impacted by code changes).
141 142 143 |
# File 'lib/datadog/ci/test.rb', line 141 def modified? get_tag(Ext::Test::TAG_TEST_IS_MODIFIED) == "true" end |
#name ⇒ String
Returns the name of the test.
28 29 30 |
# File 'lib/datadog/ci/test.rb', line 28 def name get_tag(Ext::Test::TAG_NAME) end |
#parameters ⇒ String?
Gets the parameters for this test (e.g. Cucumber example or RSpec specs) as a serialized JSON.
270 271 272 |
# File 'lib/datadog/ci/test.rb', line 270 def parameters get_tag(Ext::Test::TAG_PARAMETERS) end |
#passed! ⇒ void
This method returns an undefined value.
Sets the status of the span to "pass".
229 230 231 232 233 |
# File 'lib/datadog/ci/test.rb', line 229 def passed! super record_test_result(Ext::Test::Status::PASS) end |
#peek_duration ⇒ Object
327 328 329 330 331 332 333 |
# File 'lib/datadog/ci/test.rb', line 327 def peek_duration end_time = Core::Utils::Time.now.utc start_time = tracer_span.start_time return 0.0 if start_time.nil? || end_time.nil? end_time - start_time end |
#quarantined? ⇒ Boolean
Returns "true" if this test is quarantined by Datadog test management.
123 124 125 |
# File 'lib/datadog/ci/test.rb', line 123 def quarantined? get_tag(Ext::Test::TAG_IS_QUARANTINED) == "true" end |
#record_final_status ⇒ Object
317 318 319 320 321 322 323 324 |
# File 'lib/datadog/ci/test.rb', line 317 def record_final_status status = get_tag(Ext::Test::TAG_STATUS) return if status.nil? final_status = compute_final_status(status) set_tag(Ext::Test::TAG_FINAL_STATUS, final_status) test_suite&.record_test_final_status(datadog_test_id, final_status) end |
#retry_reason ⇒ String
Returns string with a reason why test was retried
111 112 113 |
# File 'lib/datadog/ci/test.rb', line 111 def retry_reason get_tag(Ext::Test::TAG_RETRY_REASON) end |
#set_parameters(arguments, metadata = {}) ⇒ void
This method returns an undefined value.
Sets the parameters for this test (e.g. Cucumber example or RSpec specs). Parameters are needed to compute test fingerprint to distinguish between different tests having same names.
260 261 262 263 264 |
# File 'lib/datadog/ci/test.rb', line 260 def set_parameters(arguments, = {}) return if arguments.nil? set_tag(Ext::Test::TAG_PARAMETERS, Utils::TestRun.test_parameters(arguments: arguments, metadata: )) end |
#should_ignore_failures? ⇒ Boolean
304 305 306 307 308 309 |
# File 'lib/datadog/ci/test.rb', line 304 def should_ignore_failures? return false if attempt_to_fix? return true if quarantined? || disabled? any_retry_passed? end |
#should_skip? ⇒ Boolean
299 300 301 |
# File 'lib/datadog/ci/test.rb', line 299 def should_skip? skipped_by_test_impact_analysis? || (disabled? && !attempt_to_fix?) end |
#skipped!(exception: nil, reason: nil) ⇒ void
This method returns an undefined value.
Sets the status of the span to "skip".
248 249 250 251 252 |
# File 'lib/datadog/ci/test.rb', line 248 def skipped!(exception: nil, reason: nil) super record_test_result(Ext::Test::Status::SKIP) end |
#skipped_by_test_impact_analysis? ⇒ Boolean
312 313 314 |
# File 'lib/datadog/ci/test.rb', line 312 def skipped_by_test_impact_analysis? get_tag(Ext::Test::TAG_ITR_SKIPPED_BY_ITR) == "true" end |
#start_line ⇒ Integer?
Returns the starting line number of the test in the source file.
90 91 92 93 |
# File 'lib/datadog/ci/test.rb', line 90 def start_line line = get_tag(Ext::Test::TAG_SOURCE_START) line&.to_i end |
#test_module_id ⇒ String
Span id of the running test module this test belongs to.
71 72 73 |
# File 'lib/datadog/ci/test.rb', line 71 def test_module_id get_tag(Ext::Test::TAG_TEST_MODULE_ID) end |
#test_module_name ⇒ String
Name of the running test module this test belongs to.
77 78 79 |
# File 'lib/datadog/ci/test.rb', line 77 def test_module_name get_tag(Ext::Test::TAG_MODULE) end |
#test_session_id ⇒ String
Span id of the running test session this test belongs to.
83 84 85 |
# File 'lib/datadog/ci/test.rb', line 83 def test_session_id get_tag(Ext::Test::TAG_TEST_SESSION_ID) end |
#test_suite ⇒ Datadog::CI::TestSuite?
Running test suite that this test is part of (if any).
52 53 54 55 |
# File 'lib/datadog/ci/test.rb', line 52 def test_suite suite_name = test_suite_name CI.active_test_suite(suite_name) if suite_name end |
#test_suite_id ⇒ String
Span id of the running test suite this test belongs to.
59 60 61 |
# File 'lib/datadog/ci/test.rb', line 59 def test_suite_id get_tag(Ext::Test::TAG_TEST_SUITE_ID) end |