datadog-ci 1.12.0 → 1.14.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +27 -2
- data/lib/datadog/ci/configuration/components.rb +27 -15
- data/lib/datadog/ci/configuration/settings.rb +12 -0
- data/lib/datadog/ci/contrib/cucumber/instrumentation.rb +5 -2
- data/lib/datadog/ci/contrib/minitest/helpers.rb +26 -0
- data/lib/datadog/ci/contrib/minitest/runnable.rb +1 -19
- data/lib/datadog/ci/contrib/minitest/runner.rb +9 -5
- data/lib/datadog/ci/contrib/minitest/test.rb +5 -12
- data/lib/datadog/ci/contrib/rspec/example.rb +3 -3
- data/lib/datadog/ci/contrib/rspec/runner.rb +1 -1
- data/lib/datadog/ci/ext/app_types.rb +1 -1
- data/lib/datadog/ci/ext/settings.rb +2 -0
- data/lib/datadog/ci/ext/telemetry.rb +17 -5
- data/lib/datadog/ci/ext/test.rb +42 -4
- data/lib/datadog/ci/ext/transport.rb +6 -0
- data/lib/datadog/ci/remote/component.rb +11 -1
- data/lib/datadog/ci/remote/library_settings.rb +31 -0
- data/lib/datadog/ci/remote/library_settings_client.rb +2 -1
- data/lib/datadog/ci/span.rb +4 -0
- data/lib/datadog/ci/test.rb +67 -9
- data/lib/datadog/ci/test_management/component.rb +61 -0
- data/lib/datadog/ci/test_management/null_component.rb +25 -0
- data/lib/datadog/ci/test_management/tests_properties.rb +128 -0
- data/lib/datadog/ci/test_optimisation/component.rb +9 -30
- data/lib/datadog/ci/test_optimisation/skippable_percentage/base.rb +4 -0
- data/lib/datadog/ci/test_optimisation/skippable_percentage/calculator.rb +3 -3
- data/lib/datadog/ci/test_retries/component.rb +37 -7
- data/lib/datadog/ci/test_retries/driver/base.rb +5 -0
- data/lib/datadog/ci/test_retries/driver/retry_failed.rb +4 -0
- data/lib/datadog/ci/test_retries/driver/retry_flaky_fixed.rb +38 -0
- data/lib/datadog/ci/test_retries/driver/retry_new.rb +2 -7
- data/lib/datadog/ci/test_retries/strategy/retry_flaky_fixed.rb +43 -0
- data/lib/datadog/ci/test_retries/strategy/retry_new.rb +5 -47
- data/lib/datadog/ci/test_session.rb +1 -1
- data/lib/datadog/ci/test_suite.rb +39 -2
- data/lib/datadog/ci/test_visibility/capabilities.rb +36 -0
- data/lib/datadog/ci/test_visibility/component.rb +127 -13
- data/lib/datadog/ci/test_visibility/context.rb +26 -17
- data/lib/datadog/ci/{test_retries/unique_tests_client.rb → test_visibility/known_tests.rb} +10 -10
- data/lib/datadog/ci/test_visibility/null_component.rb +4 -1
- data/lib/datadog/ci/test_visibility/serializers/factories/test_level.rb +1 -1
- data/lib/datadog/ci/test_visibility/store/global.rb +7 -0
- data/lib/datadog/ci/test_visibility/telemetry.rb +11 -2
- data/lib/datadog/ci/test_visibility/transport.rb +15 -2
- data/lib/datadog/ci/version.rb +1 -1
- data/lib/datadog/ci.rb +14 -6
- metadata +25 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 694421f4e4621608a9aa6d8deb0b1407fa348fec68820a28ced1a567c56ed289
|
4
|
+
data.tar.gz: 12b586d1eabe233af428c7294564f8b7a46ff8bbb64d44f222762afd371a2c1c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 81c173cb2b22a8e0e3853d21d4e1ac023569142d51bb266c287ef7d4c7c5f2dfd97d2f3914acd1ac766d3e60ac15929cbee849b7284d300644113e6a14dea331
|
7
|
+
data.tar.gz: c1f1f93f35850cf9b6d1e360d53f2a26e2e46961aeed8e69f216327513e4001c45a42c363c20609ad0b525a4aeaf0fdec59e32f38d9302289c9e256ccf5aa81c
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,23 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## [1.14.0] - 2025-03-11
|
4
|
+
|
5
|
+
### Added
|
6
|
+
|
7
|
+
* Test impact analysis: add rails parallel testing support ([#294][])
|
8
|
+
* Add parallel testing support to minitest framework ([#295][])
|
9
|
+
|
10
|
+
### Changed
|
11
|
+
|
12
|
+
* Test knapsack_pro v8 ([#292][])
|
13
|
+
|
14
|
+
## [1.13.0] - 2025-02-25
|
15
|
+
|
16
|
+
### Added
|
17
|
+
|
18
|
+
* Flaky test management support ([#289][])
|
19
|
+
* Always request the list of known tests and mark new tests ([#286][])
|
20
|
+
|
3
21
|
## [1.12.0] - 2025-01-23
|
4
22
|
|
5
23
|
### Added
|
@@ -386,7 +404,9 @@ Currently test suite level visibility is not used by our instrumentation: it wil
|
|
386
404
|
|
387
405
|
- Ruby versions < 2.7 no longer supported ([#8][])
|
388
406
|
|
389
|
-
[Unreleased]: https://github.com/DataDog/datadog-ci-rb/compare/v1.
|
407
|
+
[Unreleased]: https://github.com/DataDog/datadog-ci-rb/compare/v1.14.0...main
|
408
|
+
[1.14.0]: https://github.com/DataDog/datadog-ci-rb/compare/v1.13.0...v1.14.0
|
409
|
+
[1.13.0]: https://github.com/DataDog/datadog-ci-rb/compare/v1.12.0...v1.13.0
|
390
410
|
[1.12.0]: https://github.com/DataDog/datadog-ci-rb/compare/v1.11.0...v1.12.0
|
391
411
|
[1.11.0]: https://github.com/DataDog/datadog-ci-rb/compare/v1.10.0...v1.11.0
|
392
412
|
[1.10.0]: https://github.com/DataDog/datadog-ci-rb/compare/v1.9.0...v1.10.0
|
@@ -554,4 +574,9 @@ Currently test suite level visibility is not used by our instrumentation: it wil
|
|
554
574
|
[#271]: https://github.com/DataDog/datadog-ci-rb/issues/271
|
555
575
|
[#272]: https://github.com/DataDog/datadog-ci-rb/issues/272
|
556
576
|
[#275]: https://github.com/DataDog/datadog-ci-rb/issues/275
|
557
|
-
[#283]: https://github.com/DataDog/datadog-ci-rb/issues/283
|
577
|
+
[#283]: https://github.com/DataDog/datadog-ci-rb/issues/283
|
578
|
+
[#286]: https://github.com/DataDog/datadog-ci-rb/issues/286
|
579
|
+
[#289]: https://github.com/DataDog/datadog-ci-rb/issues/289
|
580
|
+
[#292]: https://github.com/DataDog/datadog-ci-rb/issues/292
|
581
|
+
[#294]: https://github.com/DataDog/datadog-ci-rb/issues/294
|
582
|
+
[#295]: https://github.com/DataDog/datadog-ci-rb/issues/295
|
@@ -6,14 +6,17 @@ require_relative "../ext/settings"
|
|
6
6
|
require_relative "../git/tree_uploader"
|
7
7
|
require_relative "../remote/component"
|
8
8
|
require_relative "../remote/library_settings_client"
|
9
|
+
require_relative "../test_management/component"
|
10
|
+
require_relative "../test_management/null_component"
|
11
|
+
require_relative "../test_management/tests_properties"
|
9
12
|
require_relative "../test_optimisation/component"
|
10
13
|
require_relative "../test_optimisation/coverage/transport"
|
11
14
|
require_relative "../test_optimisation/coverage/writer"
|
12
15
|
require_relative "../test_retries/component"
|
13
16
|
require_relative "../test_retries/null_component"
|
14
|
-
require_relative "../test_retries/unique_tests_client"
|
15
17
|
require_relative "../test_visibility/component"
|
16
18
|
require_relative "../test_visibility/flush"
|
19
|
+
require_relative "../test_visibility/known_tests"
|
17
20
|
require_relative "../test_visibility/null_component"
|
18
21
|
require_relative "../test_visibility/serializers/factories/test_level"
|
19
22
|
require_relative "../test_visibility/serializers/factories/test_suite_level"
|
@@ -30,7 +33,7 @@ module Datadog
|
|
30
33
|
module Configuration
|
31
34
|
# Adds CI behavior to Datadog trace components
|
32
35
|
module Components
|
33
|
-
attr_reader :test_visibility, :test_optimisation, :git_tree_upload_worker, :ci_remote, :test_retries
|
36
|
+
attr_reader :test_visibility, :test_optimisation, :git_tree_upload_worker, :ci_remote, :test_retries, :test_management
|
34
37
|
|
35
38
|
def initialize(settings)
|
36
39
|
@test_optimisation = nil
|
@@ -38,6 +41,7 @@ module Datadog
|
|
38
41
|
@git_tree_upload_worker = DummyWorker.new
|
39
42
|
@ci_remote = nil
|
40
43
|
@test_retries = TestRetries::NullComponent.new
|
44
|
+
@test_management = TestManagement::NullComponent.new
|
41
45
|
|
42
46
|
# Activate CI mode if enabled
|
43
47
|
if settings.ci.enabled
|
@@ -58,7 +62,7 @@ module Datadog
|
|
58
62
|
def activate_ci!(settings)
|
59
63
|
unless settings.tracing.enabled
|
60
64
|
Datadog.logger.error(
|
61
|
-
"
|
65
|
+
"Test Optimization requires tracing to be enabled. Disabling Test Optimization. " \
|
62
66
|
"NOTE: if you didn't disable tracing intentionally, add `c.tracing.enabled = true` to " \
|
63
67
|
"your Datadog.configure block."
|
64
68
|
)
|
@@ -111,13 +115,21 @@ module Datadog
|
|
111
115
|
retry_failed_tests_max_attempts: settings.ci.retry_failed_tests_max_attempts,
|
112
116
|
retry_failed_tests_total_limit: settings.ci.retry_failed_tests_total_limit,
|
113
117
|
retry_new_tests_enabled: settings.ci.retry_new_tests_enabled,
|
114
|
-
|
118
|
+
retry_flaky_fixed_tests_enabled: settings.ci.test_management_enabled,
|
119
|
+
retry_flaky_fixed_tests_max_attempts: settings.ci.test_management_attempt_to_fix_retries_count
|
115
120
|
)
|
121
|
+
|
122
|
+
@test_management = TestManagement::Component.new(
|
123
|
+
enabled: settings.ci.test_management_enabled,
|
124
|
+
tests_properties_client: TestManagement::TestsProperties.new(api: test_visibility_api)
|
125
|
+
)
|
126
|
+
|
116
127
|
# @type ivar @test_optimisation: Datadog::CI::TestOptimisation::Component
|
117
128
|
@test_optimisation = build_test_optimisation(settings, test_visibility_api)
|
118
129
|
@test_visibility = TestVisibility::Component.new(
|
119
130
|
test_suite_level_visibility_enabled: !settings.ci.force_test_level_visibility,
|
120
|
-
logical_test_session_name: settings.ci.test_session_name
|
131
|
+
logical_test_session_name: settings.ci.test_session_name,
|
132
|
+
known_tests_client: build_known_tests_client(settings, test_visibility_api)
|
121
133
|
)
|
122
134
|
end
|
123
135
|
|
@@ -125,7 +137,7 @@ module Datadog
|
|
125
137
|
if settings.ci.itr_code_coverage_use_single_threaded_mode &&
|
126
138
|
settings.ci.itr_test_impact_analysis_use_allocation_tracing
|
127
139
|
Datadog.logger.warn(
|
128
|
-
"
|
140
|
+
"Test Impact Analysis: Single threaded coverage mode is incompatible with allocation tracing. " \
|
129
141
|
"Allocation tracing will be disabled. It means that test impact analysis will not be able to detect " \
|
130
142
|
"instantiations of objects in your code, which is important for ActiveRecord models. " \
|
131
143
|
"Please add your app/model folder to the list of tracked files or disable single threaded coverage mode."
|
@@ -137,7 +149,7 @@ module Datadog
|
|
137
149
|
if RUBY_VERSION.start_with?("3.2.") && RUBY_VERSION < "3.2.3" &&
|
138
150
|
settings.ci.itr_test_impact_analysis_use_allocation_tracing
|
139
151
|
Datadog.logger.warn(
|
140
|
-
"
|
152
|
+
"Test Impact Analysis: Allocation tracing is not supported in Ruby versions 3.2.0, 3.2.1 and 3.2.2 and will be forcibly " \
|
141
153
|
"disabled. This is due to a VM bug that can lead to crashes (https://bugs.ruby-lang.org/issues/19482). " \
|
142
154
|
"Please update your Ruby version or add your app/model folder to the list of tracked files." \
|
143
155
|
"Set env variable DD_CIVISIBILITY_ITR_TEST_IMPACT_ANALYSIS_USE_ALLOCATION_TRACING to 0 to disable this warning."
|
@@ -161,21 +173,21 @@ module Datadog
|
|
161
173
|
if settings.ci.agentless_mode_enabled
|
162
174
|
check_dd_site(settings)
|
163
175
|
|
164
|
-
Datadog.logger.debug("
|
176
|
+
Datadog.logger.debug("Test Optimization configured to use agentless transport")
|
165
177
|
|
166
178
|
api = Transport::Api::Builder.build_agentless_api(settings)
|
167
179
|
if api.nil?
|
168
180
|
Datadog.logger.error do
|
169
|
-
"DATADOG CONFIGURATION -
|
170
|
-
"Agentless mode was enabled but DD_API_KEY is not set:
|
181
|
+
"DATADOG CONFIGURATION - TEST OPTIMIZATION - ATTENTION - " \
|
182
|
+
"Agentless mode was enabled but DD_API_KEY is not set: Test Optimization is disabled. " \
|
171
183
|
"Please make sure to set valid api key in DD_API_KEY environment variable"
|
172
184
|
end
|
173
185
|
|
174
|
-
# Tests are running without
|
186
|
+
# Tests are running without Test Optimization enabled
|
175
187
|
settings.ci.enabled = false
|
176
188
|
end
|
177
189
|
else
|
178
|
-
Datadog.logger.debug("
|
190
|
+
Datadog.logger.debug("Test Optimization configured to use agent transport via EVP proxy")
|
179
191
|
|
180
192
|
api = Transport::Api::Builder.build_evp_proxy_api(settings)
|
181
193
|
if api.nil?
|
@@ -235,8 +247,8 @@ module Datadog
|
|
235
247
|
)
|
236
248
|
end
|
237
249
|
|
238
|
-
def
|
239
|
-
|
250
|
+
def build_known_tests_client(settings, api)
|
251
|
+
TestVisibility::KnownTests.new(
|
240
252
|
api: api,
|
241
253
|
dd_env: settings.env,
|
242
254
|
config_tags: custom_configuration(settings)
|
@@ -262,7 +274,7 @@ module Datadog
|
|
262
274
|
return if Ext::Settings::DD_SITE_ALLOWLIST.include?(settings.site)
|
263
275
|
|
264
276
|
Datadog.logger.warn do
|
265
|
-
"
|
277
|
+
"TEST OPTIMIZATION CONFIGURATION " \
|
266
278
|
"Agentless mode was enabled but DD_SITE is not set to one of the following: #{Ext::Settings::DD_SITE_ALLOWLIST.join(", ")}. " \
|
267
279
|
"Please make sure to set valid site in DD_SITE environment variable"
|
268
280
|
end
|
@@ -116,6 +116,18 @@ module Datadog
|
|
116
116
|
o.default true
|
117
117
|
end
|
118
118
|
|
119
|
+
option :test_management_enabled do |o|
|
120
|
+
o.type :bool
|
121
|
+
o.env CI::Ext::Settings::ENV_TEST_MANAGEMENT_ENABLED
|
122
|
+
o.default true
|
123
|
+
end
|
124
|
+
|
125
|
+
option :test_management_attempt_to_fix_retries_count do |o|
|
126
|
+
o.type :int
|
127
|
+
o.env CI::Ext::Settings::ENV_TEST_MANAGEMENT_ATTEMPT_TO_FIX_RETRIES
|
128
|
+
o.default 20
|
129
|
+
end
|
130
|
+
|
119
131
|
# internal only
|
120
132
|
option :discard_traces do |o|
|
121
133
|
o.type :bool
|
@@ -37,8 +37,11 @@ module Datadog
|
|
37
37
|
end
|
38
38
|
|
39
39
|
def begin_scenario(test_case)
|
40
|
-
|
41
|
-
|
40
|
+
datadog_test = Datadog::CI.active_test
|
41
|
+
|
42
|
+
# special case for cucumber-ruby: we skip quarantined tests, thus for cucumber quarantined is the same as disabled
|
43
|
+
if datadog_test&.should_skip? || datadog_test&.quarantined?
|
44
|
+
raise ::Cucumber::Core::Test::Result::Skipped, datadog_test.datadog_skip_reason
|
42
45
|
end
|
43
46
|
|
44
47
|
super
|
@@ -5,6 +5,32 @@ module Datadog
|
|
5
5
|
module Contrib
|
6
6
|
module Minitest
|
7
7
|
module Helpers
|
8
|
+
def self.start_test_suite(klass)
|
9
|
+
method = klass.runnable_methods.first
|
10
|
+
return nil if method.nil?
|
11
|
+
|
12
|
+
test_suite_name = test_suite_name(klass, method)
|
13
|
+
source_file, line_number = extract_source_location_from_class(klass)
|
14
|
+
|
15
|
+
test_suite_tags = if source_file
|
16
|
+
{
|
17
|
+
CI::Ext::Test::TAG_SOURCE_FILE => (Git::LocalRepository.relative_to_root(source_file) if source_file),
|
18
|
+
CI::Ext::Test::TAG_SOURCE_START => line_number&.to_s
|
19
|
+
}
|
20
|
+
else
|
21
|
+
{}
|
22
|
+
end
|
23
|
+
|
24
|
+
test_visibility_component = Datadog.send(:components).test_visibility
|
25
|
+
test_suite = test_visibility_component.start_test_suite(
|
26
|
+
test_suite_name,
|
27
|
+
tags: test_suite_tags
|
28
|
+
)
|
29
|
+
test_suite&.set_expected_tests!(klass.runnable_methods)
|
30
|
+
|
31
|
+
test_suite
|
32
|
+
end
|
33
|
+
|
8
34
|
def self.test_suite_name(klass, method_name)
|
9
35
|
source_location = extract_source_location_from_class(klass)&.first
|
10
36
|
# if we are in anonymous class, fallback to the method source location
|
@@ -14,25 +14,7 @@ module Datadog
|
|
14
14
|
return super unless datadog_configuration[:enabled]
|
15
15
|
return super if Helpers.parallel?(self)
|
16
16
|
|
17
|
-
|
18
|
-
return super if method.nil?
|
19
|
-
|
20
|
-
test_suite_name = Helpers.test_suite_name(self, method)
|
21
|
-
source_file, line_number = Helpers.extract_source_location_from_class(self)
|
22
|
-
|
23
|
-
test_suite_tags = if source_file
|
24
|
-
{
|
25
|
-
CI::Ext::Test::TAG_SOURCE_FILE => (Git::LocalRepository.relative_to_root(source_file) if source_file),
|
26
|
-
CI::Ext::Test::TAG_SOURCE_START => line_number&.to_s
|
27
|
-
}
|
28
|
-
else
|
29
|
-
{}
|
30
|
-
end
|
31
|
-
|
32
|
-
test_suite = test_visibility_component.start_test_suite(
|
33
|
-
test_suite_name,
|
34
|
-
tags: test_suite_tags
|
35
|
-
)
|
17
|
+
test_suite = Helpers.start_test_suite(self)
|
36
18
|
|
37
19
|
results = super
|
38
20
|
return results unless test_suite
|
@@ -9,8 +9,6 @@ module Datadog
|
|
9
9
|
module Contrib
|
10
10
|
module Minitest
|
11
11
|
module Runner
|
12
|
-
DD_ESTIMATED_TESTS_PER_SUITE = 5
|
13
|
-
|
14
12
|
def self.included(base)
|
15
13
|
base.singleton_class.prepend(ClassMethods)
|
16
14
|
end
|
@@ -21,15 +19,15 @@ module Datadog
|
|
21
19
|
|
22
20
|
return unless datadog_configuration[:enabled]
|
23
21
|
|
24
|
-
|
25
|
-
|
22
|
+
tests_count = ::Minitest::Runnable.runnables.sum { |runnable| runnable.runnable_methods.size }
|
23
|
+
|
26
24
|
test_visibility_component.start_test_session(
|
27
25
|
tags: {
|
28
26
|
CI::Ext::Test::TAG_FRAMEWORK => Ext::FRAMEWORK,
|
29
27
|
CI::Ext::Test::TAG_FRAMEWORK_VERSION => datadog_integration.version.to_s
|
30
28
|
},
|
31
29
|
service: datadog_configuration[:service_name],
|
32
|
-
|
30
|
+
estimated_total_tests_count: tests_count
|
33
31
|
)
|
34
32
|
test_visibility_component.start_test_module(Ext::FRAMEWORK)
|
35
33
|
end
|
@@ -43,6 +41,12 @@ module Datadog
|
|
43
41
|
result = super
|
44
42
|
end
|
45
43
|
|
44
|
+
# get the current test suite and mark this method as done, so we can check if all tests were executed
|
45
|
+
# for this test suite
|
46
|
+
test_suite_name = Helpers.test_suite_name(klass, method_name)
|
47
|
+
test_suite = test_visibility_component.active_test_suite(test_suite_name)
|
48
|
+
test_suite&.expected_test_done!(method_name)
|
49
|
+
|
46
50
|
result
|
47
51
|
end
|
48
52
|
|
@@ -22,14 +22,11 @@ module Datadog
|
|
22
22
|
super
|
23
23
|
return unless datadog_configuration[:enabled]
|
24
24
|
|
25
|
-
test_suite_name = Helpers.test_suite_name(self.class, name)
|
26
25
|
if Helpers.parallel?(self.class)
|
27
|
-
|
28
|
-
|
29
|
-
# for parallel execution we need to start a new test suite for each test
|
30
|
-
test_visibility_component.start_test_suite(test_suite_name)
|
26
|
+
Helpers.start_test_suite(self.class)
|
31
27
|
end
|
32
28
|
|
29
|
+
test_suite_name = Helpers.test_suite_name(self.class, name)
|
33
30
|
source_file, line_number = method(name).source_location
|
34
31
|
|
35
32
|
test_span = test_visibility_component.trace_test(
|
@@ -44,7 +41,7 @@ module Datadog
|
|
44
41
|
service: datadog_configuration[:service_name]
|
45
42
|
)
|
46
43
|
test_span&.itr_unskippable! if self.class.dd_suite_unskippable? || self.class.dd_test_unskippable?(name)
|
47
|
-
skip(
|
44
|
+
skip(test_span&.datadog_skip_reason) if test_span&.should_skip?
|
48
45
|
end
|
49
46
|
|
50
47
|
def after_teardown
|
@@ -53,12 +50,8 @@ module Datadog
|
|
53
50
|
|
54
51
|
finish_with_result(test_span, result_code)
|
55
52
|
|
56
|
-
# remove failures if test passed at least once on retries
|
57
|
-
self.failures = [] if test_span.
|
58
|
-
|
59
|
-
if Helpers.parallel?(self.class)
|
60
|
-
finish_with_result(test_span.test_suite, result_code)
|
61
|
-
end
|
53
|
+
# remove failures if test passed at least once on retries or quarantined
|
54
|
+
self.failures = [] if test_span.should_ignore_failures?
|
62
55
|
|
63
56
|
super
|
64
57
|
end
|
@@ -41,7 +41,7 @@ module Datadog
|
|
41
41
|
) do |test_span|
|
42
42
|
test_span&.itr_unskippable! if datadog_unskippable?
|
43
43
|
|
44
|
-
metadata[:skip] =
|
44
|
+
metadata[:skip] = test_span&.datadog_skip_reason if test_span&.should_skip?
|
45
45
|
|
46
46
|
# before each run remove any previous exception
|
47
47
|
@exception = nil
|
@@ -58,8 +58,8 @@ module Datadog
|
|
58
58
|
test_span&.passed!
|
59
59
|
when :failed
|
60
60
|
test_span&.failed!(exception: execution_result.exception)
|
61
|
-
# if any of the retries passed, we don't fail the test run
|
62
|
-
@exception = nil if test_span&.
|
61
|
+
# if any of the retries passed or test is quarantined, we don't fail the test run
|
62
|
+
@exception = nil if test_span&.should_ignore_failures?
|
63
63
|
else
|
64
64
|
# :pending or nil
|
65
65
|
test_span&.skipped!(
|
@@ -25,7 +25,7 @@ module Datadog
|
|
25
25
|
CI::Ext::Test::TAG_FRAMEWORK_VERSION => datadog_integration.version.to_s
|
26
26
|
},
|
27
27
|
service: datadog_configuration[:service_name],
|
28
|
-
|
28
|
+
estimated_total_tests_count: ::RSpec.world.example_count
|
29
29
|
)
|
30
30
|
|
31
31
|
test_module = test_visibility_component.start_test_module(Ext::FRAMEWORK)
|
@@ -20,6 +20,8 @@ module Datadog
|
|
20
20
|
ENV_RETRY_FAILED_TESTS_TOTAL_LIMIT = "DD_CIVISIBILITY_TOTAL_FLAKY_RETRY_COUNT"
|
21
21
|
ENV_RETRY_NEW_TESTS_ENABLED = "DD_CIVISIBILITY_EARLY_FLAKE_DETECTION_ENABLED"
|
22
22
|
ENV_TEST_SESSION_NAME = "DD_TEST_SESSION_NAME"
|
23
|
+
ENV_TEST_MANAGEMENT_ENABLED = "DD_TEST_MANAGEMENT_ENABLED"
|
24
|
+
ENV_TEST_MANAGEMENT_ATTEMPT_TO_FIX_RETRIES = "DD_TEST_MANAGEMENT_ATTEMPT_TO_FIX_RETRIES"
|
23
25
|
|
24
26
|
# Source: https://docs.datadoghq.com/getting_started/site/
|
25
27
|
DD_SITE_ALLOWLIST = %w[
|
@@ -54,11 +54,17 @@ module Datadog
|
|
54
54
|
METRIC_CODE_COVERAGE_IS_EMPTY = "code_coverage.is_empty"
|
55
55
|
METRIC_CODE_COVERAGE_FILES = "code_coverage.files"
|
56
56
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
57
|
+
METRIC_KNOWN_TESTS_REQUEST = "known_tests.request"
|
58
|
+
METRIC_KNOWN_TESTS_REQUEST_MS = "known_tests.request_ms"
|
59
|
+
METRIC_KNOWN_TESTS_REQUEST_ERRORS = "known_tests.request_errors"
|
60
|
+
METRIC_KNOWN_TESTS_RESPONSE_BYTES = "known_tests.response_bytes"
|
61
|
+
METRIC_KNOWN_TESTS_RESPONSE_TESTS = "known_tests.response_tests"
|
62
|
+
|
63
|
+
METRIC_TEST_MANAGEMENT_TESTS_REQUEST = "test_management_tests.request"
|
64
|
+
METRIC_TEST_MANAGEMENT_TESTS_REQUEST_MS = "test_management_tests.request_ms"
|
65
|
+
METRIC_TEST_MANAGEMENT_TESTS_REQUEST_ERRORS = "test_management_tests.request_errors"
|
66
|
+
METRIC_TEST_MANAGEMENT_TESTS_RESPONSE_BYTES = "test_management_tests.response_bytes"
|
67
|
+
METRIC_TEST_MANAGEMENT_TESTS_RESPONSE_TESTS = "test_management_tests.response_tests"
|
62
68
|
|
63
69
|
METRIC_TEST_SESSION = "test_session"
|
64
70
|
|
@@ -69,6 +75,7 @@ module Datadog
|
|
69
75
|
TAG_BROWSER_DRIVER = "browser_driver"
|
70
76
|
TAG_IS_RUM = "is_rum"
|
71
77
|
TAG_IS_RETRY = "is_retry"
|
78
|
+
TAG_RETRY_REASON = "retry_reason"
|
72
79
|
TAG_EARLY_FLAKE_DETECTION_ABORT_REASON = "early_flake_detection_abort_reason"
|
73
80
|
TAG_IS_NEW = "is_new"
|
74
81
|
TAG_LIBRARY = "library"
|
@@ -79,6 +86,10 @@ module Datadog
|
|
79
86
|
TAG_REQUEST_COMPRESSED = "rq_compressed"
|
80
87
|
TAG_RESPONSE_COMPRESSED = "rs_compressed"
|
81
88
|
TAG_COMMAND = "command"
|
89
|
+
TAG_IS_ATTEMPT_TO_FIX = "is_attempt_to_fix"
|
90
|
+
TAG_IS_QUARANTINED = "is_quarantined"
|
91
|
+
TAG_IS_TEST_DISABLED = "is_disabled"
|
92
|
+
TAG_HAS_FAILED_ALL_RETRIES = "has_failed_all_retries"
|
82
93
|
# tags for git_requests.settings_response metric
|
83
94
|
TAG_COVERAGE_ENABLED = "coverage_enabled"
|
84
95
|
TAG_ITR_ENABLED = "itr_enabled"
|
@@ -86,6 +97,7 @@ module Datadog
|
|
86
97
|
TAG_REQUIRE_GIT = "require_git"
|
87
98
|
TAG_EARLY_FLAKE_DETECTION_ENABLED = "early_flake_detection_enabled"
|
88
99
|
TAG_FLAKY_TEST_RETRIES_ENABLED = "flaky_test_retries_enabled"
|
100
|
+
TAG_KNOWN_TESTS_ENABLED = "known_tests_enabled"
|
89
101
|
# tags for test_session metric
|
90
102
|
TAG_PROVIDER = "provider"
|
91
103
|
TAG_AUTO_INJECTED = "auto_injected"
|
data/lib/datadog/ci/ext/test.rb
CHANGED
@@ -58,21 +58,42 @@ module Datadog
|
|
58
58
|
# version of the browser, if multiple browsers or multiple versions then this tag is empty
|
59
59
|
TAG_BROWSER_VERSION = "test.browser.version"
|
60
60
|
|
61
|
+
# known and new tests
|
62
|
+
TAG_IS_NEW = "test.is_new" # true if test is new (it was not known to Datadog before)
|
63
|
+
|
61
64
|
# Tags for retries
|
62
65
|
TAG_IS_RETRY = "test.is_retry" # true if test was retried by datadog-ci library
|
63
|
-
|
66
|
+
TAG_RETRY_REASON = "test.retry_reason" # reason why test was retried
|
64
67
|
TAG_EARLY_FLAKE_ENABLED = "test.early_flake.enabled" # true if early flake detection is enabled
|
65
68
|
TAG_EARLY_FLAKE_ABORT_REASON = "test.early_flake.abort_reason" # reason why early flake detection was aborted
|
66
69
|
|
67
70
|
# Tags for total code coverage
|
68
71
|
TAG_CODE_COVERAGE_LINES_PCT = "test.code_coverage.lines_pct"
|
69
72
|
|
73
|
+
# Tags for test managament
|
74
|
+
TAG_TEST_MANAGEMENT_ENABLED = "test.test_management.enabled" # true if test management is enabled, set on test_session_end event
|
75
|
+
TAG_IS_ATTEMPT_TO_FIX = "test.test_management.is_attempt_to_fix" # true if test is marked as "attempted to fix"
|
76
|
+
TAG_IS_TEST_DISABLED = "test.test_management.is_test_disabled" # true if test is marked as disabled in test management view
|
77
|
+
TAG_IS_QUARANTINED = "test.test_management.is_quarantined" # true if test is quarantined in test management view
|
78
|
+
TAG_HAS_FAILED_ALL_RETRIES = "test.has_failed_all_retries" # true if test was retried and none of the retries passed
|
79
|
+
TAG_ATTEMPT_TO_FIX_PASSED = "test.test_management.attempt_to_fix_passed" # true if test was marked as "attempted to fix" and all of the retries passed
|
80
|
+
|
81
|
+
# a set of tag indicating which capabilities (features) are supported by the library
|
82
|
+
module LibraryCapabilities
|
83
|
+
TAG_TEST_IMPACT_ANALYSIS = "_dd.library_capabilities.test_impact_analysis"
|
84
|
+
TAG_EARLY_FLAKE_DETECTION = "_dd.library_capabilities.early_flake_detection"
|
85
|
+
TAG_AUTO_TEST_RETRIES = "_dd.library_capabilities.auto_test_retries"
|
86
|
+
TAG_TEST_MANAGEMENT_QUARANTINE = "_dd.library_capabilities.test_management.quarantine"
|
87
|
+
TAG_TEST_MANAGEMENT_DISABLE = "_dd.library_capabilities.test_management.disable"
|
88
|
+
TAG_TEST_MANAGEMENT_ATTEMPT_TO_FIX = "_dd.library_capabilities.test_management.attempt_to_fix"
|
89
|
+
end
|
90
|
+
|
70
91
|
# internal APM tag to mark a span as a test span
|
71
92
|
TAG_SPAN_KIND = "span.kind"
|
72
93
|
SPAN_KIND_TEST = "test"
|
73
94
|
|
74
|
-
#
|
75
|
-
|
95
|
+
# DD_TEST_SESSION_NAME value
|
96
|
+
TAG_TEST_SESSION_NAME = "test_session.name"
|
76
97
|
|
77
98
|
# internal tag indicating if datadog service was configured by the user
|
78
99
|
TAG_USER_PROVIDED_TEST_SERVICE = "_dd.test.is_user_provided_service"
|
@@ -85,7 +106,6 @@ module Datadog
|
|
85
106
|
|
86
107
|
# could be either "test" or "suite" depending on whether we skip individual tests or whole suites
|
87
108
|
ITR_TEST_SKIPPING_MODE = "test" # we always skip tests (not suites) in Ruby
|
88
|
-
ITR_TEST_SKIP_REASON = "Skipped by Datadog's intelligent test runner"
|
89
109
|
ITR_UNSKIPPABLE_OPTION = :datadog_itr_unskippable
|
90
110
|
|
91
111
|
EARLY_FLAKE_FAULTY = "faulty"
|
@@ -97,12 +117,30 @@ module Datadog
|
|
97
117
|
SKIP = "skip"
|
98
118
|
end
|
99
119
|
|
120
|
+
# test statuses that we use for execution stats but don't report to Datadog (e.g. fail_ignored)
|
121
|
+
module ExecutionStatsStatus
|
122
|
+
FAIL_IGNORED = "fail_ignored"
|
123
|
+
end
|
124
|
+
|
100
125
|
# test types (e.g. test, benchmark, browser)
|
101
126
|
module Type
|
102
127
|
TEST = "test"
|
103
128
|
BROWSER = "browser"
|
104
129
|
BENCHMARK = "benchmark" # DEV: not used yet, will be used when benchmarks are supported
|
105
130
|
end
|
131
|
+
|
132
|
+
# possible reasons why a test was retried
|
133
|
+
module RetryReason
|
134
|
+
RETRY_NEW = "efd"
|
135
|
+
RETRY_FAILED = "atr"
|
136
|
+
RETRY_FLAKY_FIXED = "attempt_to_fix"
|
137
|
+
end
|
138
|
+
|
139
|
+
# possible reasons why a test was skipped
|
140
|
+
module SkipReason
|
141
|
+
TEST_IMPACT_ANALYSIS = "Skipped by Datadog's Test Impact Analysis"
|
142
|
+
TEST_MANAGEMENT_DISABLED = "Flaky test is disabled by Datadog"
|
143
|
+
end
|
106
144
|
end
|
107
145
|
end
|
108
146
|
end
|
@@ -38,10 +38,13 @@ module Datadog
|
|
38
38
|
DD_API_SETTINGS_RESPONSE_TESTS_SKIPPING_KEY = "tests_skipping"
|
39
39
|
DD_API_SETTINGS_RESPONSE_REQUIRE_GIT_KEY = "require_git"
|
40
40
|
DD_API_SETTINGS_RESPONSE_FLAKY_TEST_RETRIES_KEY = "flaky_test_retries_enabled"
|
41
|
+
DD_API_SETTINGS_RESPONSE_KNOWN_TESTS_ENABLED_KEY = "known_tests_enabled"
|
41
42
|
DD_API_SETTINGS_RESPONSE_EARLY_FLAKE_DETECTION_KEY = "early_flake_detection"
|
42
43
|
DD_API_SETTINGS_RESPONSE_ENABLED_KEY = "enabled"
|
43
44
|
DD_API_SETTINGS_RESPONSE_SLOW_TEST_RETRIES_KEY = "slow_test_retries"
|
44
45
|
DD_API_SETTINGS_RESPONSE_FAULTY_SESSION_THRESHOLD_KEY = "faulty_session_threshold"
|
46
|
+
DD_API_SETTINGS_RESPONSE_TEST_MANAGEMENT_KEY = "test_management"
|
47
|
+
DD_API_SETTINGS_RESPONSE_ATTEMPT_TO_FIX_RETRIES_KEY = "attempt_to_fix_retries"
|
45
48
|
DD_API_SETTINGS_RESPONSE_DEFAULT = {DD_API_SETTINGS_RESPONSE_ITR_ENABLED_KEY => false}.freeze
|
46
49
|
|
47
50
|
DD_API_GIT_SEARCH_COMMITS_PATH = "/api/v2/git/repository/search_commits"
|
@@ -54,6 +57,9 @@ module Datadog
|
|
54
57
|
DD_API_UNIQUE_TESTS_PATH = "/api/v2/ci/libraries/tests"
|
55
58
|
DD_API_UNIQUE_TESTS_TYPE = "ci_app_libraries_tests_request"
|
56
59
|
|
60
|
+
DD_API_TEST_MANAGEMENT_TESTS_PATH = "/api/v2/test/libraries/test-management/tests"
|
61
|
+
DD_API_TEST_MANAGEMENT_TESTS_TYPE = "ci_app_libraries_tests_request"
|
62
|
+
|
57
63
|
CONTENT_TYPE_MESSAGEPACK = "application/msgpack"
|
58
64
|
CONTENT_TYPE_JSON = "application/json"
|
59
65
|
CONTENT_TYPE_MULTIPART_FORM_DATA = "multipart/form-data"
|
@@ -32,7 +32,9 @@ module Datadog
|
|
32
32
|
# configure different components in parallel because they might block on HTTP requests
|
33
33
|
configuration_workers = [
|
34
34
|
Worker.new { test_optimisation.configure(library_configuration, test_session) },
|
35
|
-
Worker.new { test_retries.configure(library_configuration, test_session) }
|
35
|
+
Worker.new { test_retries.configure(library_configuration, test_session) },
|
36
|
+
Worker.new { test_visibility.configure(library_configuration, test_session) },
|
37
|
+
Worker.new { test_management.configure(library_configuration, test_session) }
|
36
38
|
]
|
37
39
|
|
38
40
|
# launch configuration workers
|
@@ -44,6 +46,14 @@ module Datadog
|
|
44
46
|
|
45
47
|
private
|
46
48
|
|
49
|
+
def test_management
|
50
|
+
Datadog.send(:components).test_management
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_visibility
|
54
|
+
Datadog.send(:components).test_visibility
|
55
|
+
end
|
56
|
+
|
47
57
|
def test_optimisation
|
48
58
|
Datadog.send(:components).test_optimisation
|
49
59
|
end
|
@@ -98,6 +98,14 @@ module Datadog
|
|
98
98
|
)
|
99
99
|
end
|
100
100
|
|
101
|
+
def known_tests_enabled?
|
102
|
+
return @known_tests_enabled if defined?(@known_tests_enabled)
|
103
|
+
|
104
|
+
@known_tests_enabled = Utils::Parsing.convert_to_bool(
|
105
|
+
payload.fetch(Ext::Transport::DD_API_SETTINGS_RESPONSE_KNOWN_TESTS_ENABLED_KEY, false)
|
106
|
+
)
|
107
|
+
end
|
108
|
+
|
101
109
|
def slow_test_retries
|
102
110
|
return @slow_test_retries if defined?(@slow_test_retries)
|
103
111
|
|
@@ -114,8 +122,31 @@ module Datadog
|
|
114
122
|
)
|
115
123
|
end
|
116
124
|
|
125
|
+
def test_management_enabled?
|
126
|
+
return @test_management_enabled if defined?(@test_management_enabled)
|
127
|
+
|
128
|
+
@test_management_enabled = Utils::Parsing.convert_to_bool(
|
129
|
+
test_management_payload.fetch(Ext::Transport::DD_API_SETTINGS_RESPONSE_ENABLED_KEY, false)
|
130
|
+
)
|
131
|
+
end
|
132
|
+
|
133
|
+
def attempt_to_fix_retries_count
|
134
|
+
return @attempt_to_fix_retries_count if defined?(@attempt_to_fix_retries_count)
|
135
|
+
|
136
|
+
@attempt_to_fix_retries_count = test_management_payload.fetch(
|
137
|
+
Ext::Transport::DD_API_SETTINGS_RESPONSE_ATTEMPT_TO_FIX_RETRIES_KEY, nil
|
138
|
+
)
|
139
|
+
end
|
140
|
+
|
117
141
|
private
|
118
142
|
|
143
|
+
def test_management_payload
|
144
|
+
payload.fetch(
|
145
|
+
Ext::Transport::DD_API_SETTINGS_RESPONSE_TEST_MANAGEMENT_KEY,
|
146
|
+
{}
|
147
|
+
)
|
148
|
+
end
|
149
|
+
|
119
150
|
def early_flake_detection_payload
|
120
151
|
payload.fetch(
|
121
152
|
Ext::Transport::DD_API_SETTINGS_RESPONSE_EARLY_FLAKE_DETECTION_KEY,
|