datadog-ci 1.11.0 → 1.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +20 -2
  3. data/lib/datadog/ci/configuration/components.rb +27 -15
  4. data/lib/datadog/ci/configuration/settings.rb +12 -0
  5. data/lib/datadog/ci/contrib/cucumber/instrumentation.rb +5 -2
  6. data/lib/datadog/ci/contrib/cuprite/configuration/settings.rb +34 -0
  7. data/lib/datadog/ci/contrib/cuprite/driver.rb +94 -0
  8. data/lib/datadog/ci/contrib/cuprite/ext.rb +15 -0
  9. data/lib/datadog/ci/contrib/cuprite/integration.rb +44 -0
  10. data/lib/datadog/ci/contrib/cuprite/patcher.rb +24 -0
  11. data/lib/datadog/ci/contrib/cuprite/script_executor.rb +32 -0
  12. data/lib/datadog/ci/contrib/minitest/test.rb +3 -3
  13. data/lib/datadog/ci/contrib/rspec/example.rb +3 -3
  14. data/lib/datadog/ci/contrib/selenium/capybara_driver.rb +4 -4
  15. data/lib/datadog/ci/contrib/selenium/configuration/settings.rb +3 -1
  16. data/lib/datadog/ci/contrib/selenium/driver.rb +4 -4
  17. data/lib/datadog/ci/contrib/selenium/ext.rb +0 -15
  18. data/lib/datadog/ci/contrib/selenium/navigation.rb +2 -2
  19. data/lib/datadog/ci/ext/app_types.rb +1 -1
  20. data/lib/datadog/ci/ext/environment/providers/github_actions.rb +3 -0
  21. data/lib/datadog/ci/ext/environment.rb +4 -0
  22. data/lib/datadog/ci/ext/rum.rb +26 -0
  23. data/lib/datadog/ci/ext/settings.rb +2 -0
  24. data/lib/datadog/ci/ext/telemetry.rb +17 -5
  25. data/lib/datadog/ci/ext/test.rb +42 -4
  26. data/lib/datadog/ci/ext/transport.rb +6 -0
  27. data/lib/datadog/ci/remote/component.rb +11 -1
  28. data/lib/datadog/ci/remote/library_settings.rb +31 -0
  29. data/lib/datadog/ci/remote/library_settings_client.rb +2 -1
  30. data/lib/datadog/ci/test.rb +67 -9
  31. data/lib/datadog/ci/test_management/component.rb +61 -0
  32. data/lib/datadog/ci/test_management/null_component.rb +25 -0
  33. data/lib/datadog/ci/test_management/tests_properties.rb +128 -0
  34. data/lib/datadog/ci/test_optimisation/component.rb +5 -3
  35. data/lib/datadog/ci/test_retries/component.rb +37 -7
  36. data/lib/datadog/ci/test_retries/driver/base.rb +5 -0
  37. data/lib/datadog/ci/test_retries/driver/retry_failed.rb +4 -0
  38. data/lib/datadog/ci/test_retries/driver/retry_flaky_fixed.rb +38 -0
  39. data/lib/datadog/ci/test_retries/driver/retry_new.rb +2 -7
  40. data/lib/datadog/ci/test_retries/strategy/retry_flaky_fixed.rb +43 -0
  41. data/lib/datadog/ci/test_retries/strategy/retry_new.rb +4 -46
  42. data/lib/datadog/ci/test_suite.rb +21 -2
  43. data/lib/datadog/ci/test_visibility/capabilities.rb +36 -0
  44. data/lib/datadog/ci/test_visibility/component.rb +70 -2
  45. data/lib/datadog/ci/test_visibility/context.rb +0 -4
  46. data/lib/datadog/ci/{test_retries/unique_tests_client.rb → test_visibility/known_tests.rb} +10 -10
  47. data/lib/datadog/ci/test_visibility/null_component.rb +3 -0
  48. data/lib/datadog/ci/test_visibility/serializers/factories/test_level.rb +1 -1
  49. data/lib/datadog/ci/test_visibility/telemetry.rb +11 -2
  50. data/lib/datadog/ci/test_visibility/transport.rb +29 -3
  51. data/lib/datadog/ci/utils/rum.rb +42 -0
  52. data/lib/datadog/ci/version.rb +1 -1
  53. data/lib/datadog/ci.rb +14 -5
  54. metadata +20 -10
  55. data/lib/datadog/ci/contrib/selenium/rum.rb +0 -43
@@ -7,6 +7,7 @@ require_relative "driver/retry_new"
7
7
  require_relative "strategy/no_retry"
8
8
  require_relative "strategy/retry_failed"
9
9
  require_relative "strategy/retry_new"
10
+ require_relative "strategy/retry_flaky_fixed"
10
11
 
11
12
  require_relative "../ext/telemetry"
12
13
  require_relative "../utils/telemetry"
@@ -25,23 +26,33 @@ module Datadog
25
26
  retry_failed_tests_max_attempts:,
26
27
  retry_failed_tests_total_limit:,
27
28
  retry_new_tests_enabled:,
28
- unique_tests_client:
29
+ retry_flaky_fixed_tests_enabled:,
30
+ retry_flaky_fixed_tests_max_attempts:
29
31
  )
30
32
  no_retries_strategy = Strategy::NoRetry.new
31
33
 
32
- retry_failed_strategy = Strategy::RetryFailed.new(
34
+ @retry_failed_strategy = Strategy::RetryFailed.new(
33
35
  enabled: retry_failed_tests_enabled,
34
36
  max_attempts: retry_failed_tests_max_attempts,
35
37
  total_limit: retry_failed_tests_total_limit
36
38
  )
37
39
 
38
- retry_new_strategy = Strategy::RetryNew.new(
39
- enabled: retry_new_tests_enabled,
40
- unique_tests_client: unique_tests_client
40
+ @retry_new_strategy = Strategy::RetryNew.new(
41
+ enabled: retry_new_tests_enabled
41
42
  )
42
43
 
43
- # order is important, we should try to retry new tests first
44
- @retry_strategies = [retry_new_strategy, retry_failed_strategy, no_retries_strategy]
44
+ retry_flaky_fixed_strategy = Strategy::RetryFlakyFixed.new(
45
+ enabled: retry_flaky_fixed_tests_enabled,
46
+ max_attempts: retry_flaky_fixed_tests_max_attempts
47
+ )
48
+
49
+ # order is important, we apply the first matching strategy
50
+ @retry_strategies = [
51
+ retry_flaky_fixed_strategy,
52
+ @retry_new_strategy,
53
+ @retry_failed_strategy,
54
+ no_retries_strategy
55
+ ]
45
56
  @mutex = Mutex.new
46
57
  end
47
58
 
@@ -82,6 +93,8 @@ module Datadog
82
93
  else
83
94
  # after each retry we record the result, the driver will decide if we should retry again
84
95
  current_retry_driver&.record_retry(test_span)
96
+
97
+ tag_last_retry(test_span) unless should_retry?
85
98
  end
86
99
  end
87
100
 
@@ -94,10 +107,27 @@ module Datadog
94
107
  self.current_retry_driver = nil
95
108
  end
96
109
 
110
+ def tag_last_retry(test_span)
111
+ test_span&.set_tag(Ext::Test::TAG_HAS_FAILED_ALL_RETRIES, "true") if test_span&.all_executions_failed?
112
+
113
+ # if we are attempting to fix the test and all retries passed, we indicate that the fix might have worked
114
+ if test_span&.attempt_to_fix? && test_span.all_executions_passed?
115
+ test_span&.set_tag(Ext::Test::TAG_ATTEMPT_TO_FIX_PASSED, "true")
116
+ end
117
+ end
118
+
97
119
  def should_retry?
98
120
  !!current_retry_driver&.should_retry?
99
121
  end
100
122
 
123
+ def auto_test_retries_feature_enabled
124
+ @retry_failed_strategy.enabled
125
+ end
126
+
127
+ def early_flake_detection_feature_enabled
128
+ @retry_new_strategy.enabled
129
+ end
130
+
101
131
  private
102
132
 
103
133
  def current_retry_driver
@@ -13,11 +13,16 @@ module Datadog
13
13
 
14
14
  def record_retry(test_span)
15
15
  test_span&.set_tag(Ext::Test::TAG_IS_RETRY, "true")
16
+ test_span&.set_tag(Ext::Test::TAG_RETRY_REASON, retry_reason)
16
17
  end
17
18
 
18
19
  # duration in float seconds
19
20
  def record_duration(duration)
20
21
  end
22
+
23
+ def retry_reason
24
+ "unknown"
25
+ end
21
26
  end
22
27
  end
23
28
  end
@@ -30,6 +30,10 @@ module Datadog
30
30
 
31
31
  Datadog.logger.debug { "Retry Attempts [#{@attempts} / #{@max_attempts}], Passed: [#{@passed_once}]" }
32
32
  end
33
+
34
+ def retry_reason
35
+ Ext::Test::RetryReason::RETRY_FAILED
36
+ end
33
37
  end
34
38
  end
35
39
  end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base"
4
+
5
+ require_relative "../../ext/test"
6
+
7
+ module Datadog
8
+ module CI
9
+ module TestRetries
10
+ module Driver
11
+ class RetryFlakyFixed < Base
12
+ attr_reader :max_attempts
13
+
14
+ def initialize(max_attempts:)
15
+ @attempts = 0
16
+ @max_attempts = max_attempts
17
+ end
18
+
19
+ def should_retry?
20
+ @attempts < @max_attempts
21
+ end
22
+
23
+ def record_retry(test_span)
24
+ super
25
+
26
+ @attempts += 1
27
+
28
+ Datadog.logger.debug { "Retry Attempts [#{@attempts} / #{@max_attempts}]" }
29
+ end
30
+
31
+ def retry_reason
32
+ Ext::Test::RetryReason::RETRY_FLAKY_FIXED
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -15,8 +15,6 @@ module Datadog
15
15
  @attempts = 0
16
16
  # will be changed based on test span duration
17
17
  @max_attempts = 10
18
-
19
- mark_new_test(test_span)
20
18
  end
21
19
 
22
20
  def should_retry?
@@ -27,7 +25,6 @@ module Datadog
27
25
  super
28
26
 
29
27
  @attempts += 1
30
- mark_new_test(test_span)
31
28
 
32
29
  Datadog.logger.debug { "Retry Attempts [#{@attempts} / #{@max_attempts}]" }
33
30
  end
@@ -38,10 +35,8 @@ module Datadog
38
35
  Datadog.logger.debug { "Recorded test duration of [#{duration}], new Max Attempts value is [#{@max_attempts}]" }
39
36
  end
40
37
 
41
- private
42
-
43
- def mark_new_test(test_span)
44
- test_span.set_tag(Ext::Test::TAG_IS_NEW, "true")
38
+ def retry_reason
39
+ Ext::Test::RetryReason::RETRY_NEW
45
40
  end
46
41
  end
47
42
  end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base"
4
+
5
+ require_relative "../driver/retry_flaky_fixed"
6
+
7
+ module Datadog
8
+ module CI
9
+ module TestRetries
10
+ module Strategy
11
+ # This strategy retries tests that are flaky and were marked as attempted to be fixed in Datadog Test Management UI.
12
+ class RetryFlakyFixed < Base
13
+ attr_reader :enabled, :max_attempts
14
+
15
+ def initialize(
16
+ enabled:,
17
+ max_attempts:
18
+ )
19
+ @enabled = enabled
20
+ @max_attempts = max_attempts
21
+ end
22
+
23
+ def configure(library_settings, test_session)
24
+ @enabled &&= library_settings.test_management_enabled?
25
+ @max_attempts = library_settings.attempt_to_fix_retries_count || @max_attempts
26
+ end
27
+
28
+ def covers?(test_span)
29
+ return false unless @enabled
30
+
31
+ !!test_span&.attempt_to_fix?
32
+ end
33
+
34
+ def build_driver(test_span)
35
+ Datadog.logger.debug { "#{test_span.name} is attempt_to_fix, will be retried" }
36
+
37
+ Driver::RetryFlakyFixed.new(max_attempts: max_attempts)
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -11,19 +11,13 @@ module Datadog
11
11
  class RetryNew < Base
12
12
  DEFAULT_TOTAL_TESTS_COUNT = 100
13
13
 
14
- attr_reader :enabled, :max_attempts_thresholds, :unique_tests_set, :total_limit, :retried_count
14
+ attr_reader :enabled, :max_attempts_thresholds, :total_limit, :retried_count
15
15
 
16
- def initialize(
17
- enabled:,
18
- unique_tests_client:
19
- )
16
+ def initialize(enabled:)
20
17
  @enabled = enabled
21
- @unique_tests_set = Set.new
22
18
  # total maximum number of new tests to retry (will be set based on the total number of tests in the session)
23
19
  @total_limit = 0
24
20
  @retried_count = 0
25
-
26
- @unique_tests_client = unique_tests_client
27
21
  end
28
22
 
29
23
  def covers?(test_span)
@@ -37,11 +31,11 @@ module Datadog
37
31
  mark_test_session_faulty(Datadog::CI.active_test_session)
38
32
  end
39
33
 
40
- @enabled && !test_span.skipped? && is_new_test?(test_span)
34
+ @enabled && !test_span.skipped? && test_span.is_new?
41
35
  end
42
36
 
43
37
  def configure(library_settings, test_session)
44
- @enabled &&= library_settings.early_flake_detection_enabled?
38
+ @enabled &&= library_settings.early_flake_detection_enabled? && library_settings.known_tests_enabled?
45
39
 
46
40
  return unless @enabled
47
41
 
@@ -50,7 +44,6 @@ module Datadog
50
44
 
51
45
  set_max_attempts_thresholds(library_settings)
52
46
  calculate_total_retries_limit(library_settings, test_session)
53
- fetch_known_unique_tests(test_session)
54
47
  end
55
48
 
56
49
  def build_driver(test_span)
@@ -68,20 +61,6 @@ module Datadog
68
61
  test_session&.set_tag(Ext::Test::TAG_EARLY_FLAKE_ABORT_REASON, Ext::Test::EARLY_FLAKE_FAULTY)
69
62
  end
70
63
 
71
- def is_new_test?(test_span)
72
- test_id = Utils::TestRun.datadog_test_id(test_span.name, test_span.test_suite_name)
73
-
74
- result = !@unique_tests_set.include?(test_id)
75
-
76
- if result
77
- Datadog.logger.debug do
78
- "#{test_id} is not found in the unique tests set, it is a new test"
79
- end
80
- end
81
-
82
- result
83
- end
84
-
85
64
  def set_max_attempts_thresholds(library_settings)
86
65
  @max_attempts_thresholds = library_settings.slow_test_retries
87
66
  Datadog.logger.debug do
@@ -104,27 +83,6 @@ module Datadog
104
83
  "Retry new tests total limit is [#{@total_limit}] (#{percentage_limit}% of #{tests_count})"
105
84
  end
106
85
  end
107
-
108
- def fetch_known_unique_tests(test_session)
109
- @unique_tests_set = @unique_tests_client.fetch_unique_tests(test_session)
110
- if @unique_tests_set.empty?
111
- @enabled = false
112
- mark_test_session_faulty(test_session)
113
-
114
- Datadog.logger.warn(
115
- "Disabling early flake detection because there are no known tests (possible reason: no test runs in default branch)"
116
- )
117
- end
118
-
119
- # report how many unique tests were found
120
- Datadog.logger.debug do
121
- "Found [#{@unique_tests_set.size}] known unique tests"
122
- end
123
- Utils::Telemetry.distribution(
124
- Ext::Telemetry::METRIC_EFD_UNIQUE_TESTS_RESPONSE_TESTS,
125
- @unique_tests_set.size.to_f
126
- )
127
- end
128
86
  end
129
87
  end
130
88
  end
@@ -59,6 +59,24 @@ module Datadog
59
59
  end
60
60
  end
61
61
 
62
+ # @internal
63
+ def all_executions_failed?(test_id)
64
+ synchronize do
65
+ stats = @execution_stats_per_test[test_id]
66
+ stats && (stats[Ext::Test::Status::FAIL] > 0 || stats[Ext::Test::ExecutionStatsStatus::FAIL_IGNORED] > 0) &&
67
+ stats[Ext::Test::Status::PASS] == 0
68
+ end
69
+ end
70
+
71
+ # @internal
72
+ def all_executions_passed?(test_id)
73
+ synchronize do
74
+ stats = @execution_stats_per_test[test_id]
75
+ stats && stats[Ext::Test::Status::PASS] > 0 && stats[Ext::Test::Status::FAIL] == 0 &&
76
+ stats[Ext::Test::ExecutionStatsStatus::FAIL_IGNORED] == 0
77
+ end
78
+ end
79
+
62
80
  # @internal
63
81
  def test_executed?(test_id)
64
82
  synchronize do
@@ -89,8 +107,9 @@ module Datadog
89
107
  end
90
108
 
91
109
  def derive_test_status_from_execution_stats(test_execution_stats)
92
- # test is passed if it passed at least once
93
- if test_execution_stats[Ext::Test::Status::PASS] > 0
110
+ # test is passed if it passed at least once or it failed but fail was ignored
111
+ if test_execution_stats[Ext::Test::Status::PASS] > 0 ||
112
+ test_execution_stats[Ext::Test::ExecutionStatsStatus::FAIL_IGNORED] > 0
94
113
  Ext::Test::Status::PASS
95
114
  # if test was never passed, it is failed if it failed at least once
96
115
  elsif test_execution_stats[Ext::Test::Status::FAIL] > 0
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../ext/test"
4
+
5
+ module Datadog
6
+ module CI
7
+ module TestVisibility
8
+ # Generates internal tags for library capabilities
9
+ module Capabilities
10
+ def self.tags
11
+ tags = {}
12
+
13
+ test_optimisation = Datadog::CI.send(:test_optimisation)
14
+ tags[Ext::Test::LibraryCapabilities::TAG_TEST_IMPACT_ANALYSIS] = test_optimisation.enabled.to_s
15
+
16
+ test_management = Datadog::CI.send(:test_management)
17
+ test_management_tag_value = test_management.enabled.to_s
18
+
19
+ [
20
+ Ext::Test::LibraryCapabilities::TAG_TEST_MANAGEMENT_ATTEMPT_TO_FIX,
21
+ Ext::Test::LibraryCapabilities::TAG_TEST_MANAGEMENT_QUARANTINE,
22
+ Ext::Test::LibraryCapabilities::TAG_TEST_MANAGEMENT_DISABLE
23
+ ].each do |tag|
24
+ tags[tag] = test_management_tag_value
25
+ end
26
+
27
+ test_retries = Datadog::CI.send(:test_retries)
28
+ tags[Ext::Test::LibraryCapabilities::TAG_AUTO_TEST_RETRIES] = test_retries.auto_test_retries_feature_enabled.to_s
29
+ tags[Ext::Test::LibraryCapabilities::TAG_EARLY_FLAKE_DETECTION] = test_retries.early_flake_detection_feature_enabled.to_s
30
+
31
+ tags
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -18,9 +18,10 @@ module Datadog
18
18
  module TestVisibility
19
19
  # Common behavior for CI tests
20
20
  class Component
21
- attr_reader :test_suite_level_visibility_enabled, :logical_test_session_name
21
+ attr_reader :test_suite_level_visibility_enabled, :logical_test_session_name, :known_tests, :known_tests_enabled
22
22
 
23
23
  def initialize(
24
+ known_tests_client:,
24
25
  test_suite_level_visibility_enabled: false,
25
26
  codeowners: Codeowners::Parser.new(Git::LocalRepository.root).parse,
26
27
  logical_test_session_name: nil
@@ -29,6 +30,21 @@ module Datadog
29
30
  @context = Context.new
30
31
  @codeowners = codeowners
31
32
  @logical_test_session_name = logical_test_session_name
33
+
34
+ # "Known tests" feature fetches a list of all tests known to Datadog for this repository
35
+ # and uses this list to determine if a test is new or not. New tests are marked with "test.is_new" tag.
36
+ @known_tests_enabled = false
37
+ @known_tests_client = known_tests_client
38
+ @known_tests = Set.new
39
+ end
40
+
41
+ def configure(library_configuration, test_session)
42
+ return unless test_suite_level_visibility_enabled
43
+
44
+ if library_configuration.known_tests_enabled?
45
+ @known_tests_enabled = true
46
+ fetch_known_tests(test_session)
47
+ end
32
48
  end
33
49
 
34
50
  def start_test_session(service: nil, tags: {}, total_tests_count: 0)
@@ -158,7 +174,8 @@ module Datadog
158
174
  # sets logical test session name if none provided by the user
159
175
  override_logical_test_session_name!(test_session) if logical_test_session_name.nil?
160
176
 
161
- # signal Remote::Component to configure the library
177
+ # Signal Remote::Component to configure the library.
178
+ # Note that it will call this component back (unfortunate circular dependency).
162
179
  remote.configure(test_session)
163
180
  end
164
181
 
@@ -182,6 +199,10 @@ module Datadog
182
199
 
183
200
  Telemetry.event_created(test)
184
201
 
202
+ mark_test_as_new(test) if new_test?(test)
203
+
204
+ test_management.tag_test_from_properties(test)
205
+
185
206
  test_optimisation.mark_if_skippable(test)
186
207
  test_optimisation.start_coverage(test)
187
208
  end
@@ -287,6 +308,49 @@ module Datadog
287
308
  end
288
309
  end
289
310
 
311
+ def new_test?(test_span)
312
+ return false unless @known_tests_enabled
313
+
314
+ test_id = Utils::TestRun.datadog_test_id(test_span.name, test_span.test_suite_name)
315
+ result = !@known_tests.include?(test_id)
316
+
317
+ if result
318
+ Datadog.logger.debug do
319
+ "#{test_id} is not found in the known tests set, it is a new test"
320
+ end
321
+ end
322
+
323
+ result
324
+ end
325
+
326
+ def fetch_known_tests(test_session)
327
+ @known_tests = @known_tests_client.fetch(test_session)
328
+
329
+ if @known_tests.empty?
330
+ @known_tests_enabled = false
331
+
332
+ # this adds unfortunate knowledge on EFD from Testvisibility, rethink this
333
+ test_session&.set_tag(Ext::Test::TAG_EARLY_FLAKE_ABORT_REASON, Ext::Test::EARLY_FLAKE_FAULTY)
334
+
335
+ Datadog.logger.warn("Empty set of tests known to Datadog")
336
+ end
337
+
338
+ # report how many known tests were found
339
+ Datadog.logger.debug do
340
+ "Found [#{@known_tests.size}] known tests"
341
+ end
342
+ Utils::Telemetry.distribution(
343
+ Ext::Telemetry::METRIC_KNOWN_TESTS_RESPONSE_TESTS,
344
+ @known_tests.size.to_f
345
+ )
346
+
347
+ @known_tests
348
+ end
349
+
350
+ def mark_test_as_new(test_span)
351
+ test_span.set_tag(Ext::Test::TAG_IS_NEW, "true")
352
+ end
353
+
290
354
  def test_optimisation
291
355
  Datadog.send(:components).test_optimisation
292
356
  end
@@ -302,6 +366,10 @@ module Datadog
302
366
  def remote
303
367
  Datadog.send(:components).ci_remote
304
368
  end
369
+
370
+ def test_management
371
+ Datadog.send(:components).test_management
372
+ end
305
373
  end
306
374
  end
307
375
  end
@@ -208,10 +208,6 @@ module Datadog
208
208
  ci_span.set_tags(@environment_tags)
209
209
 
210
210
  ci_span.set_metric(Ext::Test::METRIC_CPU_COUNT, Utils::TestRun.virtual_cpu_count)
211
- ci_span.set_tag(
212
- Ext::Test::TAG_USER_PROVIDED_TEST_SERVICE,
213
- Utils::Configuration.service_name_provided_by_user?.to_s
214
- )
215
211
  end
216
212
 
217
213
  # PROPAGATING CONTEXT FROM TOP-LEVEL TO THE LOWER LEVELS
@@ -10,9 +10,9 @@ require_relative "../utils/test_run"
10
10
 
11
11
  module Datadog
12
12
  module CI
13
- module TestRetries
14
- # fetch a list of unique known tests from the backend
15
- class UniqueTestsClient
13
+ module TestVisibility
14
+ # fetches and stores a list of known tests from the backend
15
+ class KnownTests
16
16
  class Response
17
17
  def initialize(http_response)
18
18
  @http_response = http_response
@@ -66,7 +66,7 @@ module Datadog
66
66
  @config_tags = config_tags
67
67
  end
68
68
 
69
- def fetch_unique_tests(test_session)
69
+ def fetch(test_session)
70
70
  api = @api
71
71
  return Set.new unless api
72
72
 
@@ -78,21 +78,21 @@ module Datadog
78
78
  payload: request_payload
79
79
  )
80
80
 
81
- Transport::Telemetry.api_requests(
82
- Ext::Telemetry::METRIC_EFD_UNIQUE_TESTS_REQUEST,
81
+ CI::Transport::Telemetry.api_requests(
82
+ Ext::Telemetry::METRIC_KNOWN_TESTS_REQUEST,
83
83
  1,
84
84
  compressed: http_response.request_compressed
85
85
  )
86
- Utils::Telemetry.distribution(Ext::Telemetry::METRIC_EFD_UNIQUE_TESTS_REQUEST_MS, http_response.duration_ms)
86
+ Utils::Telemetry.distribution(Ext::Telemetry::METRIC_KNOWN_TESTS_REQUEST_MS, http_response.duration_ms)
87
87
  Utils::Telemetry.distribution(
88
- Ext::Telemetry::METRIC_EFD_UNIQUE_TESTS_RESPONSE_BYTES,
88
+ Ext::Telemetry::METRIC_KNOWN_TESTS_RESPONSE_BYTES,
89
89
  http_response.response_size.to_f,
90
90
  {Ext::Telemetry::TAG_RESPONSE_COMPRESSED => http_response.gzipped_content?.to_s}
91
91
  )
92
92
 
93
93
  unless http_response.ok?
94
- Transport::Telemetry.api_requests_errors(
95
- Ext::Telemetry::METRIC_EFD_UNIQUE_TESTS_REQUEST_ERRORS,
94
+ CI::Transport::Telemetry.api_requests_errors(
95
+ Ext::Telemetry::METRIC_KNOWN_TESTS_REQUEST_ERRORS,
96
96
  1,
97
97
  error_type: http_response.telemetry_error_type,
98
98
  status_code: http_response.code
@@ -5,6 +5,9 @@ module Datadog
5
5
  module TestVisibility
6
6
  # Special test visibility component that does not record anything
7
7
  class NullComponent
8
+ def configure(_, _)
9
+ end
10
+
8
11
  def start_test_session(service: nil, tags: {}, total_tests_count: 0)
9
12
  skip_tracing
10
13
  end
@@ -9,7 +9,7 @@ module Datadog
9
9
  module Serializers
10
10
  module Factories
11
11
  # This factory takes care of creating msgpack serializers when test-level visibility is enabled
12
- # NOTE: citestcycle is a protocol Datadog uses to submit test execution tracing information to CI visibility
12
+ # NOTE: citestcycle is a protocol Datadog uses to submit test execution tracing information to Test Optimization
13
13
  # backend
14
14
  module TestLevel
15
15
  module_function
@@ -54,8 +54,11 @@ module Datadog
54
54
  # codeowner tag
55
55
  tags[Ext::Telemetry::TAG_HAS_CODEOWNER] = "true" if span.get_tag(Ext::Test::TAG_CODEOWNERS)
56
56
 
57
- # set is_retry tag if span represents a retried test
58
- tags[Ext::Telemetry::TAG_IS_RETRY] = "true" if span.get_tag(Ext::Test::TAG_IS_RETRY)
57
+ # set is_retry and retry_reason tags if span represents a retried test
58
+ if span.get_tag(Ext::Test::TAG_IS_RETRY)
59
+ tags[Ext::Telemetry::TAG_IS_RETRY] = "true"
60
+ tags[Ext::Telemetry::TAG_RETRY_REASON] = span.get_tag(Ext::Test::TAG_RETRY_REASON)
61
+ end
59
62
 
60
63
  # is_new
61
64
  tags[Ext::Telemetry::TAG_IS_NEW] = "true" if span.get_tag(Ext::Test::TAG_IS_NEW)
@@ -66,6 +69,12 @@ module Datadog
66
69
  tags[Ext::Telemetry::TAG_EARLY_FLAKE_DETECTION_ABORT_REASON] = early_flake_detection_abort_reason
67
70
  end
68
71
 
72
+ # test management tags
73
+ tags[Ext::Telemetry::TAG_IS_ATTEMPT_TO_FIX] = "true" if span.get_tag(Ext::Test::TAG_IS_ATTEMPT_TO_FIX)
74
+ tags[Ext::Telemetry::TAG_IS_QUARANTINED] = "true" if span.get_tag(Ext::Test::TAG_IS_QUARANTINED)
75
+ tags[Ext::Telemetry::TAG_IS_TEST_DISABLED] = "true" if span.get_tag(Ext::Test::TAG_IS_TEST_DISABLED)
76
+ tags[Ext::Telemetry::TAG_HAS_FAILED_ALL_RETRIES] = "true" if span.get_tag(Ext::Test::TAG_HAS_FAILED_ALL_RETRIES)
77
+
69
78
  tags
70
79
  end
71
80