datadog-ci 1.13.0 → 1.15.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 +35 -2
- data/lib/datadog/ci/configuration/components.rb +2 -1
- data/lib/datadog/ci/configuration/settings.rb +6 -0
- 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 +12 -5
- data/lib/datadog/ci/contrib/minitest/test.rb +2 -9
- data/lib/datadog/ci/contrib/parallel_tests/cli.rb +84 -0
- data/lib/datadog/ci/contrib/parallel_tests/configuration/settings.rb +32 -0
- data/lib/datadog/ci/contrib/parallel_tests/ext.rb +16 -0
- data/lib/datadog/ci/contrib/parallel_tests/integration.rb +42 -0
- data/lib/datadog/ci/contrib/parallel_tests/patcher.rb +24 -0
- data/lib/datadog/ci/contrib/rspec/example.rb +7 -0
- data/lib/datadog/ci/contrib/rspec/example_group.rb +18 -8
- data/lib/datadog/ci/contrib/rspec/helpers.rb +18 -0
- data/lib/datadog/ci/contrib/rspec/runner.rb +3 -1
- data/lib/datadog/ci/ext/settings.rb +1 -0
- data/lib/datadog/ci/ext/test.rb +20 -0
- data/lib/datadog/ci/git/local_repository.rb +1 -1
- data/lib/datadog/ci/git/tree_uploader.rb +9 -0
- data/lib/datadog/ci/readonly_test_module.rb +28 -0
- data/lib/datadog/ci/readonly_test_session.rb +31 -0
- data/lib/datadog/ci/remote/component.rb +43 -16
- data/lib/datadog/ci/span.rb +4 -0
- data/lib/datadog/ci/test_management/component.rb +34 -1
- data/lib/datadog/ci/test_management/tests_properties.rb +2 -1
- data/lib/datadog/ci/test_optimisation/component.rb +38 -33
- 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/strategy/retry_new.rb +1 -1
- data/lib/datadog/ci/test_session.rb +7 -1
- data/lib/datadog/ci/test_suite.rb +18 -0
- data/lib/datadog/ci/test_visibility/component.rb +130 -30
- data/lib/datadog/ci/test_visibility/context.rb +102 -41
- data/lib/datadog/ci/test_visibility/null_component.rb +5 -1
- data/lib/datadog/ci/test_visibility/store/{local.rb → fiber_local.rb} +1 -1
- data/lib/datadog/ci/test_visibility/store/{global.rb → process.rb} +26 -14
- data/lib/datadog/ci/test_visibility/transport.rb +1 -2
- data/lib/datadog/ci/transport/http.rb +1 -1
- data/lib/datadog/ci/utils/file_storage.rb +57 -0
- data/lib/datadog/ci/utils/stateful.rb +52 -0
- data/lib/datadog/ci/version.rb +1 -1
- data/lib/datadog/ci.rb +5 -4
- metadata +28 -5
- data/lib/datadog/ci/test_visibility/capabilities.rb +0 -36
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c4507da31359cd997cb38e73190a4e6514ad8c69d86f9ce1b0c47fd7764e5dbd
|
4
|
+
data.tar.gz: 515872f426f95492fed9d1577f14bb7b1e447b0c011edf2bbfbb7ea23992d9cc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3d0db7cb6a13a4c2f0b38b22c8dc2470a9ec760c38312c929a7b6224b118e18b279addf76901f7f094f60123a9e65d9afef06c15970bf01b247bc031bf80725d
|
7
|
+
data.tar.gz: f731bc7979a69ae63362d06d0313754bd825a22baf934cb682c1dc2a16a8584d0c3ece806f2bfb75d42924c09fff6296bf8c5c1be142afbe3ab7716bcb753815
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,29 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## [1.15.0] - 2025-03-25
|
4
|
+
|
5
|
+
|
6
|
+
### Added
|
7
|
+
|
8
|
+
* parallel tests gem support ([#299][])
|
9
|
+
* implemented attempt to fix flow V2 ([#298][])
|
10
|
+
|
11
|
+
### Fixed
|
12
|
+
|
13
|
+
* Fix: prevent test impact analysis from skipping flaky tests that are attempted to be fixed ([#301][])
|
14
|
+
* Fix git commit message extraction to extract multiline commit messages correctly ([#300][])
|
15
|
+
|
16
|
+
## [1.14.0] - 2025-03-11
|
17
|
+
|
18
|
+
### Added
|
19
|
+
|
20
|
+
* Test impact analysis: add rails parallel testing support ([#294][])
|
21
|
+
* Add parallel testing support to minitest framework ([#295][])
|
22
|
+
|
23
|
+
### Changed
|
24
|
+
|
25
|
+
* Test knapsack_pro v8 ([#292][])
|
26
|
+
|
3
27
|
## [1.13.0] - 2025-02-25
|
4
28
|
|
5
29
|
### Added
|
@@ -393,7 +417,9 @@ Currently test suite level visibility is not used by our instrumentation: it wil
|
|
393
417
|
|
394
418
|
- Ruby versions < 2.7 no longer supported ([#8][])
|
395
419
|
|
396
|
-
[Unreleased]: https://github.com/DataDog/datadog-ci-rb/compare/v1.
|
420
|
+
[Unreleased]: https://github.com/DataDog/datadog-ci-rb/compare/v1.15.0...main
|
421
|
+
[1.15.0]: https://github.com/DataDog/datadog-ci-rb/compare/v1.14.0...v1.15.0
|
422
|
+
[1.14.0]: https://github.com/DataDog/datadog-ci-rb/compare/v1.13.0...v1.14.0
|
397
423
|
[1.13.0]: https://github.com/DataDog/datadog-ci-rb/compare/v1.12.0...v1.13.0
|
398
424
|
[1.12.0]: https://github.com/DataDog/datadog-ci-rb/compare/v1.11.0...v1.12.0
|
399
425
|
[1.11.0]: https://github.com/DataDog/datadog-ci-rb/compare/v1.10.0...v1.11.0
|
@@ -564,4 +590,11 @@ Currently test suite level visibility is not used by our instrumentation: it wil
|
|
564
590
|
[#275]: https://github.com/DataDog/datadog-ci-rb/issues/275
|
565
591
|
[#283]: https://github.com/DataDog/datadog-ci-rb/issues/283
|
566
592
|
[#286]: https://github.com/DataDog/datadog-ci-rb/issues/286
|
567
|
-
[#289]: https://github.com/DataDog/datadog-ci-rb/issues/289
|
593
|
+
[#289]: https://github.com/DataDog/datadog-ci-rb/issues/289
|
594
|
+
[#292]: https://github.com/DataDog/datadog-ci-rb/issues/292
|
595
|
+
[#294]: https://github.com/DataDog/datadog-ci-rb/issues/294
|
596
|
+
[#295]: https://github.com/DataDog/datadog-ci-rb/issues/295
|
597
|
+
[#298]: https://github.com/DataDog/datadog-ci-rb/issues/298
|
598
|
+
[#299]: https://github.com/DataDog/datadog-ci-rb/issues/299
|
599
|
+
[#300]: https://github.com/DataDog/datadog-ci-rb/issues/300
|
600
|
+
[#301]: https://github.com/DataDog/datadog-ci-rb/issues/301
|
@@ -129,7 +129,8 @@ module Datadog
|
|
129
129
|
@test_visibility = TestVisibility::Component.new(
|
130
130
|
test_suite_level_visibility_enabled: !settings.ci.force_test_level_visibility,
|
131
131
|
logical_test_session_name: settings.ci.test_session_name,
|
132
|
-
known_tests_client: build_known_tests_client(settings, test_visibility_api)
|
132
|
+
known_tests_client: build_known_tests_client(settings, test_visibility_api),
|
133
|
+
context_service_uri: settings.ci.test_visibility_drb_server_uri
|
133
134
|
)
|
134
135
|
end
|
135
136
|
|
@@ -134,6 +134,12 @@ module Datadog
|
|
134
134
|
o.default false
|
135
135
|
end
|
136
136
|
|
137
|
+
# internal only
|
138
|
+
option :test_visibility_drb_server_uri do |o|
|
139
|
+
o.type :string, nilable: true
|
140
|
+
o.env CI::Ext::Settings::ENV_TEST_VISIBILITY_DRB_SERVER_URI
|
141
|
+
end
|
142
|
+
|
137
143
|
define_method(:instrument) do |integration_name, options = {}, &block|
|
138
144
|
return unless enabled
|
139
145
|
|
@@ -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,18 @@ 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,
|
31
|
+
# if minitest is being used with a parallel runner, then tests split will happen by example, not by test suite
|
32
|
+
# we need to always start/stop test suites in the parent process in this case
|
33
|
+
local_test_suites_mode: false
|
33
34
|
)
|
34
35
|
test_visibility_component.start_test_module(Ext::FRAMEWORK)
|
35
36
|
end
|
@@ -43,6 +44,12 @@ module Datadog
|
|
43
44
|
result = super
|
44
45
|
end
|
45
46
|
|
47
|
+
# get the current test suite and mark this method as done, so we can check if all tests were executed
|
48
|
+
# for this test suite
|
49
|
+
test_suite_name = Helpers.test_suite_name(klass, method_name)
|
50
|
+
test_suite = test_visibility_component.active_test_suite(test_suite_name)
|
51
|
+
test_suite&.expected_test_done!(method_name)
|
52
|
+
|
46
53
|
result
|
47
54
|
end
|
48
55
|
|
@@ -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(
|
@@ -56,10 +53,6 @@ module Datadog
|
|
56
53
|
# remove failures if test passed at least once on retries or quarantined
|
57
54
|
self.failures = [] if test_span.should_ignore_failures?
|
58
55
|
|
59
|
-
if Helpers.parallel?(self.class)
|
60
|
-
finish_with_result(test_span.test_suite, result_code)
|
61
|
-
end
|
62
|
-
|
63
56
|
super
|
64
57
|
end
|
65
58
|
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../../ext/test"
|
4
|
+
require_relative "../rspec/ext"
|
5
|
+
|
6
|
+
module Datadog
|
7
|
+
module CI
|
8
|
+
module Contrib
|
9
|
+
module ParallelTests
|
10
|
+
module CLI
|
11
|
+
def self.included(base)
|
12
|
+
base.prepend(InstanceMethods)
|
13
|
+
end
|
14
|
+
|
15
|
+
module InstanceMethods
|
16
|
+
def run_tests_in_parallel(num_processes, options)
|
17
|
+
# only rspec runner is supported for now
|
18
|
+
return super if @runner != ::ParallelTests::RSpec::Runner
|
19
|
+
|
20
|
+
begin
|
21
|
+
test_session = test_visibility_component.start_test_session(
|
22
|
+
tags: {
|
23
|
+
CI::Ext::Test::TAG_FRAMEWORK => CI::Contrib::RSpec::Ext::FRAMEWORK,
|
24
|
+
CI::Ext::Test::TAG_FRAMEWORK_VERSION => datadog_extract_rspec_version
|
25
|
+
},
|
26
|
+
service: datadog_configuration[:service_name],
|
27
|
+
estimated_total_tests_count: 10_000, # temporary value, updated by child processes
|
28
|
+
distributed: true
|
29
|
+
)
|
30
|
+
test_module = test_visibility_component.start_test_module("rspec")
|
31
|
+
|
32
|
+
options[:env] ||= {}
|
33
|
+
options[:env][CI::Ext::Settings::ENV_TEST_VISIBILITY_DRB_SERVER_URI] = test_visibility_component.context_service_uri
|
34
|
+
|
35
|
+
super
|
36
|
+
ensure
|
37
|
+
test_module&.finish
|
38
|
+
test_session&.finish
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def any_test_failed?(test_results)
|
43
|
+
res = super
|
44
|
+
|
45
|
+
test_session = test_visibility_component.active_test_session
|
46
|
+
test_module = test_visibility_component.active_test_module
|
47
|
+
if res
|
48
|
+
test_module&.failed!
|
49
|
+
test_session&.failed!
|
50
|
+
else
|
51
|
+
test_module&.passed!
|
52
|
+
test_session&.passed!
|
53
|
+
end
|
54
|
+
|
55
|
+
res
|
56
|
+
end
|
57
|
+
|
58
|
+
def datadog_extract_rspec_version
|
59
|
+
# Try to find either 'rspec' or 'rspec-core' gem
|
60
|
+
if Gem.loaded_specs["rspec"]
|
61
|
+
Gem.loaded_specs["rspec"].version.to_s
|
62
|
+
elsif Gem.loaded_specs["rspec-core"]
|
63
|
+
Gem.loaded_specs["rspec-core"].version.to_s
|
64
|
+
else
|
65
|
+
"0.0.0"
|
66
|
+
end
|
67
|
+
rescue => e
|
68
|
+
Datadog.logger.debug("Error extracting RSpec version: #{e.class.name} - #{e.message}")
|
69
|
+
"0.0.0"
|
70
|
+
end
|
71
|
+
|
72
|
+
def datadog_configuration
|
73
|
+
Datadog.configuration.ci[:paralleltests]
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_visibility_component
|
77
|
+
Datadog.send(:components).test_visibility
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../ext"
|
4
|
+
require_relative "../../settings"
|
5
|
+
require_relative "../../../utils/configuration"
|
6
|
+
|
7
|
+
module Datadog
|
8
|
+
module CI
|
9
|
+
module Contrib
|
10
|
+
module ParallelTests
|
11
|
+
module Configuration
|
12
|
+
# Custom settings for the ParallelTests integration
|
13
|
+
# @public_api
|
14
|
+
class Settings < Datadog::CI::Contrib::Settings
|
15
|
+
option :enabled do |o|
|
16
|
+
o.type :bool
|
17
|
+
o.env Ext::ENV_ENABLED
|
18
|
+
o.default true
|
19
|
+
end
|
20
|
+
|
21
|
+
option :service_name do |o|
|
22
|
+
o.type :string
|
23
|
+
o.default do
|
24
|
+
Utils::Configuration.fetch_service_name(Ext::DEFAULT_SERVICE_NAME)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Datadog
|
4
|
+
module CI
|
5
|
+
module Contrib
|
6
|
+
module ParallelTests
|
7
|
+
# Datadog ParallelTests integration constants
|
8
|
+
module Ext
|
9
|
+
ENV_ENABLED = "DD_TRACE_PARALLEL_TESTS_ENABLED"
|
10
|
+
|
11
|
+
DEFAULT_SERVICE_NAME = "parallel_tests"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../integration"
|
4
|
+
require_relative "configuration/settings"
|
5
|
+
require_relative "patcher"
|
6
|
+
|
7
|
+
module Datadog
|
8
|
+
module CI
|
9
|
+
module Contrib
|
10
|
+
module ParallelTests
|
11
|
+
# Description of ParallelTests integration
|
12
|
+
class Integration < Datadog::CI::Contrib::Integration
|
13
|
+
MINIMUM_VERSION = Gem::Version.new("4.0")
|
14
|
+
|
15
|
+
def version
|
16
|
+
Gem.loaded_specs["parallel_tests"]&.version
|
17
|
+
end
|
18
|
+
|
19
|
+
def loaded?
|
20
|
+
!defined?(::ParallelTests).nil? && !defined?(::ParallelTests::CLI).nil?
|
21
|
+
end
|
22
|
+
|
23
|
+
def compatible?
|
24
|
+
super && version >= MINIMUM_VERSION
|
25
|
+
end
|
26
|
+
|
27
|
+
def late_instrument?
|
28
|
+
false
|
29
|
+
end
|
30
|
+
|
31
|
+
def new_configuration
|
32
|
+
Configuration::Settings.new
|
33
|
+
end
|
34
|
+
|
35
|
+
def patcher
|
36
|
+
Patcher
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "cli"
|
4
|
+
require_relative "integration"
|
5
|
+
require_relative "../patcher"
|
6
|
+
|
7
|
+
module Datadog
|
8
|
+
module CI
|
9
|
+
module Contrib
|
10
|
+
module ParallelTests
|
11
|
+
# Patcher enables patching of parallel_tests module
|
12
|
+
module Patcher
|
13
|
+
include Datadog::CI::Contrib::Patcher
|
14
|
+
|
15
|
+
module_function
|
16
|
+
|
17
|
+
def patch
|
18
|
+
::ParallelTests::CLI.include(CLI)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -97,6 +97,13 @@ module Datadog
|
|
97
97
|
)
|
98
98
|
end
|
99
99
|
|
100
|
+
def datadog_fqn_test_id
|
101
|
+
@datadog_fqn_test_id ||= Utils::TestRun.datadog_test_id(
|
102
|
+
datadog_test_name,
|
103
|
+
datadog_test_suite_name
|
104
|
+
)
|
105
|
+
end
|
106
|
+
|
100
107
|
def datadog_unskippable?
|
101
108
|
!!metadata[CI::Ext::Test::ITR_UNSKIPPABLE_OPTION]
|
102
109
|
end
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require_relative "../../ext/test"
|
4
4
|
require_relative "ext"
|
5
|
+
require_relative "helpers"
|
5
6
|
|
6
7
|
module Datadog
|
7
8
|
module CI
|
@@ -28,13 +29,17 @@ module Datadog
|
|
28
29
|
return super unless top_level?
|
29
30
|
|
30
31
|
suite_name = "#{description} at #{file_path}"
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
32
|
+
suite_tags = {
|
33
|
+
CI::Ext::Test::TAG_SOURCE_FILE => Git::LocalRepository.relative_to_root(metadata[:file_path]),
|
34
|
+
CI::Ext::Test::TAG_SOURCE_START => metadata[:line_number].to_s
|
35
|
+
}
|
36
|
+
|
37
|
+
test_suite =
|
38
|
+
test_visibility_component&.start_test_suite(
|
39
|
+
suite_name,
|
40
|
+
tags: suite_tags,
|
41
|
+
service: datadog_configuration[:service_name]
|
42
|
+
)
|
38
43
|
|
39
44
|
success = super
|
40
45
|
return success unless test_suite
|
@@ -56,7 +61,8 @@ module Datadog
|
|
56
61
|
|
57
62
|
def all_examples_skipped_by_datadog?
|
58
63
|
descendant_filtered_examples.all? do |example|
|
59
|
-
!example.datadog_unskippable? && test_optimisation_component&.skippable?(example)
|
64
|
+
!example.datadog_unskippable? && test_optimisation_component&.skippable?(example.datadog_test_id) &&
|
65
|
+
!test_management_component&.attempt_to_fix?(example.datadog_fqn_test_id)
|
60
66
|
end
|
61
67
|
end
|
62
68
|
|
@@ -71,6 +77,10 @@ module Datadog
|
|
71
77
|
def test_optimisation_component
|
72
78
|
Datadog.send(:components).test_optimisation
|
73
79
|
end
|
80
|
+
|
81
|
+
def test_management_component
|
82
|
+
Datadog.send(:components).test_management
|
83
|
+
end
|
74
84
|
end
|
75
85
|
end
|
76
86
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Datadog
|
4
|
+
module CI
|
5
|
+
module Contrib
|
6
|
+
module RSpec
|
7
|
+
# Helper methods for RSpec instrumentation
|
8
|
+
module Helpers
|
9
|
+
module_function
|
10
|
+
|
11
|
+
def parallel_tests?
|
12
|
+
!!ENV.fetch("TEST_ENV_NUMBER", nil) && !!ENV.fetch("PARALLEL_TEST_GROUPS", nil)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -3,6 +3,7 @@
|
|
3
3
|
require_relative "../../ext/test"
|
4
4
|
require_relative "../instrumentation"
|
5
5
|
require_relative "ext"
|
6
|
+
require_relative "helpers"
|
6
7
|
|
7
8
|
module Datadog
|
8
9
|
module CI
|
@@ -25,13 +26,14 @@ module Datadog
|
|
25
26
|
CI::Ext::Test::TAG_FRAMEWORK_VERSION => datadog_integration.version.to_s
|
26
27
|
},
|
27
28
|
service: datadog_configuration[:service_name],
|
28
|
-
|
29
|
+
estimated_total_tests_count: ::RSpec.world.example_count
|
29
30
|
)
|
30
31
|
|
31
32
|
test_module = test_visibility_component.start_test_module(Ext::FRAMEWORK)
|
32
33
|
|
33
34
|
result = super
|
34
35
|
return result unless test_module && test_session
|
36
|
+
return result if Helpers.parallel_tests?
|
35
37
|
|
36
38
|
if result != 0
|
37
39
|
test_module.failed!
|
@@ -22,6 +22,7 @@ module Datadog
|
|
22
22
|
ENV_TEST_SESSION_NAME = "DD_TEST_SESSION_NAME"
|
23
23
|
ENV_TEST_MANAGEMENT_ENABLED = "DD_TEST_MANAGEMENT_ENABLED"
|
24
24
|
ENV_TEST_MANAGEMENT_ATTEMPT_TO_FIX_RETRIES = "DD_TEST_MANAGEMENT_ATTEMPT_TO_FIX_RETRIES"
|
25
|
+
ENV_TEST_VISIBILITY_DRB_SERVER_URI = "DD_TEST_VISIBILITY_DRB_SERVER_URI"
|
25
26
|
|
26
27
|
# Source: https://docs.datadoghq.com/getting_started/site/
|
27
28
|
DD_SITE_ALLOWLIST = %w[
|
data/lib/datadog/ci/ext/test.rb
CHANGED
@@ -86,6 +86,26 @@ module Datadog
|
|
86
86
|
TAG_TEST_MANAGEMENT_QUARANTINE = "_dd.library_capabilities.test_management.quarantine"
|
87
87
|
TAG_TEST_MANAGEMENT_DISABLE = "_dd.library_capabilities.test_management.disable"
|
88
88
|
TAG_TEST_MANAGEMENT_ATTEMPT_TO_FIX = "_dd.library_capabilities.test_management.attempt_to_fix"
|
89
|
+
|
90
|
+
# Version numbers for library capabilities
|
91
|
+
module Versions
|
92
|
+
TEST_IMPACT_ANALYSIS_VERSION = "1"
|
93
|
+
EARLY_FLAKE_DETECTION_VERSION = "1"
|
94
|
+
AUTO_TEST_RETRIES_VERSION = "1"
|
95
|
+
TEST_MANAGEMENT_QUARANTINE_VERSION = "1"
|
96
|
+
TEST_MANAGEMENT_DISABLE_VERSION = "1"
|
97
|
+
TEST_MANAGEMENT_ATTEMPT_TO_FIX_VERSION = "2"
|
98
|
+
end
|
99
|
+
|
100
|
+
# Map of capabilities to their versions
|
101
|
+
CAPABILITY_VERSIONS = {
|
102
|
+
TAG_TEST_IMPACT_ANALYSIS => Versions::TEST_IMPACT_ANALYSIS_VERSION,
|
103
|
+
TAG_EARLY_FLAKE_DETECTION => Versions::EARLY_FLAKE_DETECTION_VERSION,
|
104
|
+
TAG_AUTO_TEST_RETRIES => Versions::AUTO_TEST_RETRIES_VERSION,
|
105
|
+
TAG_TEST_MANAGEMENT_QUARANTINE => Versions::TEST_MANAGEMENT_QUARANTINE_VERSION,
|
106
|
+
TAG_TEST_MANAGEMENT_DISABLE => Versions::TEST_MANAGEMENT_DISABLE_VERSION,
|
107
|
+
TAG_TEST_MANAGEMENT_ATTEMPT_TO_FIX => Versions::TEST_MANAGEMENT_ATTEMPT_TO_FIX_VERSION
|
108
|
+
}.freeze
|
89
109
|
end
|
90
110
|
|
91
111
|
# internal APM tag to mark a span as a test span
|
@@ -27,6 +27,11 @@ module Datadog
|
|
27
27
|
return
|
28
28
|
end
|
29
29
|
|
30
|
+
if test_visibility_component.client_process?
|
31
|
+
Datadog.logger.debug("Test visibility component is running in client process, aborting git upload")
|
32
|
+
return
|
33
|
+
end
|
34
|
+
|
30
35
|
Datadog.logger.debug { "Uploading git tree for repository #{repository_url}" }
|
31
36
|
|
32
37
|
latest_commits = LocalRepository.git_commits
|
@@ -91,6 +96,10 @@ module Datadog
|
|
91
96
|
backend_commits.include?(commit)
|
92
97
|
end
|
93
98
|
end
|
99
|
+
|
100
|
+
def test_visibility_component
|
101
|
+
Datadog.send(:components).test_visibility
|
102
|
+
end
|
94
103
|
end
|
95
104
|
end
|
96
105
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "test_module"
|
4
|
+
|
5
|
+
module Datadog
|
6
|
+
module CI
|
7
|
+
# @internal_api
|
8
|
+
class ReadonlyTestModule < TestModule
|
9
|
+
def initialize(test_module)
|
10
|
+
@id = test_module.id
|
11
|
+
@name = test_module.name
|
12
|
+
end
|
13
|
+
attr_reader :id, :name
|
14
|
+
|
15
|
+
def finish
|
16
|
+
raise "ReadonlyTestModule cannot be finished"
|
17
|
+
end
|
18
|
+
|
19
|
+
def set_tag(key, value)
|
20
|
+
raise "ReadonlyTestModule cannot be modified"
|
21
|
+
end
|
22
|
+
|
23
|
+
def set_metric(key, value)
|
24
|
+
raise "ReadonlyTestModule cannot be modified"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "test_session"
|
4
|
+
|
5
|
+
module Datadog
|
6
|
+
module CI
|
7
|
+
# @internal_api
|
8
|
+
class ReadonlyTestSession < TestSession
|
9
|
+
def initialize(test_session)
|
10
|
+
@id = test_session.id
|
11
|
+
@name = test_session.name
|
12
|
+
@inheritable_tags = test_session.inheritable_tags
|
13
|
+
@service = test_session.service
|
14
|
+
end
|
15
|
+
|
16
|
+
attr_reader :id, :name, :inheritable_tags, :service
|
17
|
+
|
18
|
+
def finish
|
19
|
+
raise "ReadonlyTestSession cannot be finished"
|
20
|
+
end
|
21
|
+
|
22
|
+
def set_tag(key, value)
|
23
|
+
raise "ReadonlyTestSession cannot be modified"
|
24
|
+
end
|
25
|
+
|
26
|
+
def set_metric(key, value)
|
27
|
+
raise "ReadonlyTestSession cannot be modified"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|