datadog-ci 1.30.0 → 1.32.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 +29 -2
- data/ext/datadog_ci_native/ci.c +1 -1
- data/ext/datadog_ci_native/iseq_collector.c +1 -1
- data/ext/datadog_ci_native/iseq_collector.h +1 -1
- data/lib/datadog/ci/configuration/components.rb +15 -2
- data/lib/datadog/ci/configuration/settings.rb +21 -0
- data/lib/datadog/ci/contrib/minitest/helpers.rb +5 -2
- data/lib/datadog/ci/contrib/minitest/run_method_capture.rb +47 -0
- data/lib/datadog/ci/contrib/minitest/test.rb +72 -14
- data/lib/datadog/ci/ext/environment/providers/jenkins.rb +2 -1
- data/lib/datadog/ci/ext/test_discovery.rb +3 -1
- data/lib/datadog/ci/ext/test_optimization_cache.rb +31 -0
- data/lib/datadog/ci/git/tree_uploader.rb +6 -3
- data/lib/datadog/ci/remote/component.rb +4 -4
- data/lib/datadog/ci/remote/library_settings.rb +7 -1
- data/lib/datadog/ci/test_impact_analysis/component.rb +5 -65
- data/lib/datadog/ci/test_management/component.rb +4 -14
- data/lib/datadog/ci/test_optimization_cache/component.rb +82 -0
- data/lib/datadog/ci/test_optimization_cache/locator.rb +96 -0
- data/lib/datadog/ci/test_optimization_cache/null_component.rb +32 -0
- data/lib/datadog/ci/test_optimization_cache/readers/base.rb +39 -0
- data/lib/datadog/ci/test_optimization_cache/readers/legacy.rb +74 -0
- data/lib/datadog/ci/test_optimization_cache/readers/missing.rb +33 -0
- data/lib/datadog/ci/test_optimization_cache/readers/v1.rb +56 -0
- data/lib/datadog/ci/test_tracing/component.rb +4 -11
- data/lib/datadog/ci/test_tracing/serializers/base.rb +4 -1
- data/lib/datadog/ci/test_tracing/serializers/meta_truncation.rb +23 -0
- data/lib/datadog/ci/test_tracing/transport.rb +10 -7
- data/lib/datadog/ci/utils/json.rb +23 -0
- data/lib/datadog/ci/utils/stateful.rb +18 -20
- data/lib/datadog/ci/utils/test_run.rb +0 -6
- data/lib/datadog/ci/version.rb +1 -1
- metadata +12 -2
- data/lib/datadog/ci/ext/dd_test.rb +0 -18
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "../ext/test_optimization_cache"
|
|
4
|
+
require_relative "locator"
|
|
5
|
+
require_relative "readers/legacy"
|
|
6
|
+
require_relative "readers/missing"
|
|
7
|
+
require_relative "readers/v1"
|
|
8
|
+
|
|
9
|
+
module Datadog
|
|
10
|
+
module CI
|
|
11
|
+
module TestOptimizationCache
|
|
12
|
+
class Component
|
|
13
|
+
READER_BY_MANIFEST_VERSION = {
|
|
14
|
+
Ext::TestOptimizationCache::SUPPORTED_MANIFEST_VERSION => Readers::V1
|
|
15
|
+
}.freeze
|
|
16
|
+
|
|
17
|
+
def initialize(manifest_file:, runfiles_dir:, runfiles_manifest_file:, test_srcdir:)
|
|
18
|
+
@locator = Locator.new(
|
|
19
|
+
manifest_file: manifest_file,
|
|
20
|
+
runfiles_dir: runfiles_dir,
|
|
21
|
+
runfiles_manifest_file: runfiles_manifest_file,
|
|
22
|
+
test_srcdir: test_srcdir
|
|
23
|
+
)
|
|
24
|
+
@reader = build_reader
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def cache_available?
|
|
28
|
+
@reader.available?
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def load_settings
|
|
32
|
+
@reader.load_settings
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def load_known_tests
|
|
36
|
+
@reader.load_known_tests
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def load_test_management
|
|
40
|
+
@reader.load_test_management
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def load_skippable_tests
|
|
44
|
+
@reader.load_skippable_tests
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def shutdown!
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
private
|
|
51
|
+
|
|
52
|
+
def build_reader
|
|
53
|
+
manifest_path = @locator.manifest_path
|
|
54
|
+
|
|
55
|
+
if manifest_path
|
|
56
|
+
version = @locator.manifest_version(manifest_path)
|
|
57
|
+
reader_class = READER_BY_MANIFEST_VERSION[version] if version
|
|
58
|
+
if reader_class
|
|
59
|
+
test_optimization_path = File.dirname(manifest_path)
|
|
60
|
+
reader = reader_class.new(test_optimization_path)
|
|
61
|
+
return reader if reader.available?
|
|
62
|
+
|
|
63
|
+
Datadog.logger.debug do
|
|
64
|
+
"Test Optimization cache settings file not found under #{test_optimization_path}"
|
|
65
|
+
end
|
|
66
|
+
return Readers::Missing.new
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
Datadog.logger.debug do
|
|
70
|
+
"Unsupported Test Optimization cache manifest version #{version.inspect} at #{manifest_path}"
|
|
71
|
+
end
|
|
72
|
+
return Readers::Missing.new
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
return Readers::Legacy.new if Dir.exist?(Ext::TestOptimizationCache::TESTOPTIMIZATION_CACHE_PATH)
|
|
76
|
+
|
|
77
|
+
Readers::Missing.new
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "../ext/test_optimization_cache"
|
|
4
|
+
|
|
5
|
+
module Datadog
|
|
6
|
+
module CI
|
|
7
|
+
module TestOptimizationCache
|
|
8
|
+
class Locator
|
|
9
|
+
RUNFILES_MANIFEST_SEPARATOR = " "
|
|
10
|
+
|
|
11
|
+
def initialize(manifest_file:, runfiles_dir:, runfiles_manifest_file:, test_srcdir:)
|
|
12
|
+
@manifest_file = manifest_file
|
|
13
|
+
@runfiles_dir = runfiles_dir
|
|
14
|
+
@runfiles_manifest_file = runfiles_manifest_file
|
|
15
|
+
@test_srcdir = test_srcdir
|
|
16
|
+
@manifest_versions = {}
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def manifest_path
|
|
20
|
+
return @manifest_path if defined?(@manifest_path)
|
|
21
|
+
|
|
22
|
+
local_manifest = File.join(Ext::TestOptimizationCache::PLAN_FOLDER, Ext::TestOptimizationCache::MANIFEST_FILE_NAME)
|
|
23
|
+
if File.exist?(local_manifest)
|
|
24
|
+
@manifest_path = local_manifest
|
|
25
|
+
return @manifest_path
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
manifest_file = @manifest_file
|
|
29
|
+
if manifest_file && !manifest_file.empty?
|
|
30
|
+
env_path = resolve_bazel_runfile_path(manifest_file)
|
|
31
|
+
if File.exist?(env_path)
|
|
32
|
+
@manifest_path = env_path
|
|
33
|
+
return @manifest_path
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
@manifest_path = nil
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def manifest_version(manifest_path)
|
|
41
|
+
return @manifest_versions[manifest_path] if @manifest_versions.key?(manifest_path)
|
|
42
|
+
|
|
43
|
+
@manifest_versions[manifest_path] = File.read(manifest_path).delete_prefix("\uFEFF").strip
|
|
44
|
+
rescue => e
|
|
45
|
+
Datadog.logger.debug { "Failed to read Test Optimization cache manifest #{manifest_path}: #{e.message}" }
|
|
46
|
+
@manifest_versions[manifest_path] = nil
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def resolve_bazel_runfile_path(path)
|
|
50
|
+
return path if File.exist?(path)
|
|
51
|
+
|
|
52
|
+
runfiles_dir = @runfiles_dir
|
|
53
|
+
if runfiles_dir && !runfiles_dir.empty?
|
|
54
|
+
candidate = File.join(runfiles_dir, path)
|
|
55
|
+
return candidate if File.exist?(candidate)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
manifest_candidate = resolve_bazel_runfile_path_from_manifest(path)
|
|
59
|
+
return manifest_candidate if manifest_candidate
|
|
60
|
+
|
|
61
|
+
test_srcdir = @test_srcdir
|
|
62
|
+
if test_srcdir && !test_srcdir.empty?
|
|
63
|
+
candidate = File.join(test_srcdir, path)
|
|
64
|
+
return candidate if File.exist?(candidate)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
path
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Bazel can provide runfiles through a manifest file instead of a directory tree.
|
|
71
|
+
# Each line maps a logical runfile path to the actual path on disk.
|
|
72
|
+
def resolve_bazel_runfile_path_from_manifest(path)
|
|
73
|
+
runfiles_manifest = @runfiles_manifest_file
|
|
74
|
+
return nil if runfiles_manifest.nil? || runfiles_manifest.empty?
|
|
75
|
+
return nil unless File.exist?(runfiles_manifest)
|
|
76
|
+
|
|
77
|
+
File.foreach(runfiles_manifest) do |line|
|
|
78
|
+
separator_index = line.index(RUNFILES_MANIFEST_SEPARATOR)
|
|
79
|
+
next unless separator_index&.positive?
|
|
80
|
+
next unless line[0...separator_index] == path
|
|
81
|
+
|
|
82
|
+
resolved_path = line[(separator_index + 1)..]
|
|
83
|
+
return resolved_path.strip if resolved_path
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
nil
|
|
87
|
+
rescue => e
|
|
88
|
+
Datadog.logger.debug do
|
|
89
|
+
"Failed to resolve Test Optimization cache manifest from #{runfiles_manifest}: #{e.message}"
|
|
90
|
+
end
|
|
91
|
+
nil
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Datadog
|
|
4
|
+
module CI
|
|
5
|
+
module TestOptimizationCache
|
|
6
|
+
class NullComponent
|
|
7
|
+
def cache_available?
|
|
8
|
+
false
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def load_settings
|
|
12
|
+
nil
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def load_known_tests
|
|
16
|
+
nil
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def load_test_management
|
|
20
|
+
nil
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def load_skippable_tests
|
|
24
|
+
nil
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def shutdown!
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "../../utils/json"
|
|
4
|
+
|
|
5
|
+
module Datadog
|
|
6
|
+
module CI
|
|
7
|
+
module TestOptimizationCache
|
|
8
|
+
module Readers
|
|
9
|
+
class Base
|
|
10
|
+
def available?
|
|
11
|
+
true
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def load_settings
|
|
15
|
+
raise NotImplementedError, "#{self.class} must implement #load_settings"
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def load_known_tests
|
|
19
|
+
raise NotImplementedError, "#{self.class} must implement #load_known_tests"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def load_test_management
|
|
23
|
+
raise NotImplementedError, "#{self.class} must implement #load_test_management"
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def load_skippable_tests
|
|
27
|
+
raise NotImplementedError, "#{self.class} must implement #load_skippable_tests"
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
private
|
|
31
|
+
|
|
32
|
+
def read_json_file(file_path)
|
|
33
|
+
Utils::Json.read_file(file_path)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "../../ext/test"
|
|
4
|
+
require_relative "../../ext/test_optimization_cache"
|
|
5
|
+
require_relative "base"
|
|
6
|
+
|
|
7
|
+
module Datadog
|
|
8
|
+
module CI
|
|
9
|
+
module TestOptimizationCache
|
|
10
|
+
module Readers
|
|
11
|
+
class Legacy < Base
|
|
12
|
+
def load_settings
|
|
13
|
+
load_legacy_json(Ext::TestOptimizationCache::SETTINGS_FILE_NAME)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def load_known_tests
|
|
17
|
+
payload = load_legacy_json(Ext::TestOptimizationCache::KNOWN_TESTS_FILE_NAME)
|
|
18
|
+
backend_response(payload) if payload
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def load_test_management
|
|
22
|
+
payload = load_legacy_json(Ext::TestOptimizationCache::LEGACY_TEST_MANAGEMENT_TESTS_FILE_NAME)
|
|
23
|
+
backend_response(payload) if payload
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def load_skippable_tests
|
|
27
|
+
payload = load_legacy_json(Ext::TestOptimizationCache::SKIPPABLE_TESTS_FILE_NAME)
|
|
28
|
+
skippable_tests_response(payload) if payload
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
def load_legacy_json(file_name)
|
|
34
|
+
read_json_file(File.join(Ext::TestOptimizationCache::TESTOPTIMIZATION_CACHE_PATH, file_name))
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def backend_response(payload)
|
|
38
|
+
{
|
|
39
|
+
"data" => {
|
|
40
|
+
"attributes" => payload
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def skippable_tests_response(payload)
|
|
46
|
+
skippable_tests = payload.fetch("skippableTests", {}) || {}
|
|
47
|
+
|
|
48
|
+
data = skippable_tests.each_value.flat_map do |tests_hash|
|
|
49
|
+
tests_hash.each_value.flat_map do |test_configs|
|
|
50
|
+
test_configs.map do |test_config|
|
|
51
|
+
{
|
|
52
|
+
"type" => Ext::Test::ITR_TEST_SKIPPING_MODE,
|
|
53
|
+
"attributes" => {
|
|
54
|
+
"suite" => test_config["suite"],
|
|
55
|
+
"name" => test_config["name"],
|
|
56
|
+
"parameters" => test_config["parameters"]
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
{
|
|
64
|
+
"meta" => {
|
|
65
|
+
"correlation_id" => payload["correlationId"]
|
|
66
|
+
},
|
|
67
|
+
"data" => data
|
|
68
|
+
}
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "base"
|
|
4
|
+
|
|
5
|
+
module Datadog
|
|
6
|
+
module CI
|
|
7
|
+
module TestOptimizationCache
|
|
8
|
+
module Readers
|
|
9
|
+
class Missing < Base
|
|
10
|
+
def available?
|
|
11
|
+
false
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def load_settings
|
|
15
|
+
nil
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def load_known_tests
|
|
19
|
+
nil
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def load_test_management
|
|
23
|
+
nil
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def load_skippable_tests
|
|
27
|
+
nil
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "../../ext/test_optimization_cache"
|
|
4
|
+
require_relative "base"
|
|
5
|
+
|
|
6
|
+
module Datadog
|
|
7
|
+
module CI
|
|
8
|
+
module TestOptimizationCache
|
|
9
|
+
module Readers
|
|
10
|
+
class V1 < Base
|
|
11
|
+
def initialize(test_optimization_path)
|
|
12
|
+
@test_optimization_path = test_optimization_path
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def available?
|
|
16
|
+
File.exist?(settings_file_path)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def load_settings
|
|
20
|
+
load_http_json(Ext::TestOptimizationCache::SETTINGS_FILE_NAME)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def load_known_tests
|
|
24
|
+
load_http_json(Ext::TestOptimizationCache::KNOWN_TESTS_FILE_NAME)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def load_test_management
|
|
28
|
+
load_http_json(Ext::TestOptimizationCache::TEST_MANAGEMENT_FILE_NAME)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def load_skippable_tests
|
|
32
|
+
load_http_json(Ext::TestOptimizationCache::SKIPPABLE_TESTS_FILE_NAME)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
private
|
|
36
|
+
|
|
37
|
+
def load_http_json(file_name)
|
|
38
|
+
read_json_file(File.join(http_cache_path, file_name))
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def settings_file_path
|
|
42
|
+
File.join(http_cache_path, Ext::TestOptimizationCache::SETTINGS_FILE_NAME)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def http_cache_path
|
|
46
|
+
File.join(
|
|
47
|
+
@test_optimization_path,
|
|
48
|
+
Ext::TestOptimizationCache::CACHE_FOLDER_NAME,
|
|
49
|
+
Ext::TestOptimizationCache::HTTP_CACHE_FOLDER_NAME
|
|
50
|
+
)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -225,28 +225,21 @@ module Datadog
|
|
|
225
225
|
end
|
|
226
226
|
|
|
227
227
|
def restore_state_from_datadog_test_runner
|
|
228
|
-
Datadog.logger.debug { "Restoring known tests from
|
|
228
|
+
Datadog.logger.debug { "Restoring known tests from Test Optimization cache" }
|
|
229
229
|
|
|
230
|
-
known_tests_data =
|
|
230
|
+
known_tests_data = load_cached_known_tests
|
|
231
231
|
if known_tests_data.nil?
|
|
232
232
|
Datadog.logger.debug { "Restoring known tests failed, will request again" }
|
|
233
233
|
return false
|
|
234
234
|
end
|
|
235
235
|
|
|
236
|
-
Datadog.logger.debug { "Restored known tests from
|
|
237
|
-
|
|
238
|
-
# Use the KnownTests class method to parse the JSON data
|
|
239
|
-
known_tests_data = {
|
|
240
|
-
"data" => {
|
|
241
|
-
"attributes" => known_tests_data
|
|
242
|
-
}
|
|
243
|
-
}
|
|
236
|
+
Datadog.logger.debug { "Restored known tests from Test Optimization: #{known_tests_data}" }
|
|
244
237
|
|
|
245
238
|
@known_tests = KnownTests::Response.from_json(known_tests_data).tests
|
|
246
239
|
@known_tests_enabled = !@known_tests.empty?
|
|
247
240
|
|
|
248
241
|
unless @known_tests_enabled
|
|
249
|
-
Datadog.logger.debug("Empty set of known tests from the
|
|
242
|
+
Datadog.logger.debug("Empty set of known tests from the Test Optimization cache file")
|
|
250
243
|
end
|
|
251
244
|
|
|
252
245
|
Datadog.logger.debug { "Found [#{@known_tests.size}] known tests from context" }
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
require "set"
|
|
4
4
|
|
|
5
5
|
require_relative "../../ext/test"
|
|
6
|
+
require_relative "meta_truncation"
|
|
6
7
|
|
|
7
8
|
module Datadog
|
|
8
9
|
module CI
|
|
@@ -29,7 +30,9 @@ module Datadog
|
|
|
29
30
|
@span = span
|
|
30
31
|
@options = options
|
|
31
32
|
|
|
32
|
-
@meta =
|
|
33
|
+
@meta = MetaTruncation.truncate_string_values(
|
|
34
|
+
@span.meta.reject { |key, _| Ext::Test::TRANSIENT_TAGS.include?(key) }
|
|
35
|
+
)
|
|
33
36
|
|
|
34
37
|
@errors = {}
|
|
35
38
|
@validated = false
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Datadog
|
|
4
|
+
module CI
|
|
5
|
+
module TestTracing
|
|
6
|
+
module Serializers
|
|
7
|
+
module MetaTruncation
|
|
8
|
+
MAX_META_STRING_LENGTH = 5000
|
|
9
|
+
|
|
10
|
+
def self.truncate_value(value)
|
|
11
|
+
return value unless value.is_a?(String) && value.length > MAX_META_STRING_LENGTH
|
|
12
|
+
|
|
13
|
+
value[0, MAX_META_STRING_LENGTH]
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def self.truncate_string_values(tags)
|
|
17
|
+
tags.transform_values { |value| truncate_value(value) }
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -5,6 +5,7 @@ require "datadog/core/telemetry/logging"
|
|
|
5
5
|
require "datadog/core/utils/only_once"
|
|
6
6
|
|
|
7
7
|
require_relative "serializers/factories/test_level"
|
|
8
|
+
require_relative "serializers/meta_truncation"
|
|
8
9
|
|
|
9
10
|
require_relative "../ext/app_types"
|
|
10
11
|
require_relative "../ext/telemetry"
|
|
@@ -105,17 +106,17 @@ module Datadog
|
|
|
105
106
|
|
|
106
107
|
if dd_env
|
|
107
108
|
packer.write("env")
|
|
108
|
-
packer.write(dd_env)
|
|
109
|
+
packer.write(Serializers::MetaTruncation.truncate_value(dd_env))
|
|
109
110
|
end
|
|
110
111
|
|
|
111
112
|
packer.write("runtime-id")
|
|
112
|
-
packer.write(Datadog::Core::Environment::Identity.id)
|
|
113
|
+
packer.write(Serializers::MetaTruncation.truncate_value(Datadog::Core::Environment::Identity.id))
|
|
113
114
|
|
|
114
115
|
packer.write("language")
|
|
115
|
-
packer.write(Datadog::Core::Environment::Identity.lang)
|
|
116
|
+
packer.write(Serializers::MetaTruncation.truncate_value(Datadog::Core::Environment::Identity.lang))
|
|
116
117
|
|
|
117
118
|
packer.write("library_version")
|
|
118
|
-
packer.write(Datadog::CI::VERSION::STRING)
|
|
119
|
+
packer.write(Serializers::MetaTruncation.truncate_value(Datadog::CI::VERSION::STRING))
|
|
119
120
|
|
|
120
121
|
library_capabilities_tags = Ext::Test::LibraryCapabilities::CAPABILITY_VERSIONS
|
|
121
122
|
|
|
@@ -124,14 +125,16 @@ module Datadog
|
|
|
124
125
|
packer.write_map_header(2 + library_capabilities_tags.count)
|
|
125
126
|
|
|
126
127
|
packer.write(Ext::Test::TAG_TEST_SESSION_NAME)
|
|
127
|
-
packer.write(test_tracing&.logical_test_session_name)
|
|
128
|
+
packer.write(Serializers::MetaTruncation.truncate_value(test_tracing&.logical_test_session_name))
|
|
128
129
|
|
|
129
130
|
packer.write(Ext::Test::TAG_USER_PROVIDED_TEST_SERVICE)
|
|
130
|
-
packer.write(
|
|
131
|
+
packer.write(
|
|
132
|
+
Serializers::MetaTruncation.truncate_value(Utils::Configuration.service_name_provided_by_user?.to_s)
|
|
133
|
+
)
|
|
131
134
|
|
|
132
135
|
library_capabilities_tags.each do |tag, value|
|
|
133
136
|
packer.write(tag)
|
|
134
|
-
packer.write(value)
|
|
137
|
+
packer.write(Serializers::MetaTruncation.truncate_value(value))
|
|
135
138
|
end
|
|
136
139
|
end
|
|
137
140
|
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "json"
|
|
4
|
+
|
|
5
|
+
module Datadog
|
|
6
|
+
module CI
|
|
7
|
+
module Utils
|
|
8
|
+
module Json
|
|
9
|
+
def self.read_file(file_path)
|
|
10
|
+
unless File.exist?(file_path)
|
|
11
|
+
Datadog.logger.debug { "JSON file not found: #{file_path}" }
|
|
12
|
+
return nil
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
JSON.parse(File.read(file_path))
|
|
16
|
+
rescue JSON::ParserError, SystemCallError => e
|
|
17
|
+
Datadog.logger.debug { "Failed to load JSON file #{file_path}: #{e.message}" }
|
|
18
|
+
nil
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "json"
|
|
4
3
|
require_relative "file_storage"
|
|
5
|
-
require_relative "test_run"
|
|
6
|
-
require_relative "../ext/dd_test"
|
|
7
4
|
|
|
8
5
|
module Datadog
|
|
9
6
|
module CI
|
|
@@ -22,9 +19,8 @@ module Datadog
|
|
|
22
19
|
|
|
23
20
|
# Load component state
|
|
24
21
|
def load_component_state
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
Datadog.logger.debug { "DDTest cache found" }
|
|
22
|
+
if test_optimization_cache.cache_available?
|
|
23
|
+
Datadog.logger.debug { "Test Optimization cache found" }
|
|
28
24
|
return true if restore_state_from_datadog_test_runner
|
|
29
25
|
end
|
|
30
26
|
|
|
@@ -60,22 +56,24 @@ module Datadog
|
|
|
60
56
|
false
|
|
61
57
|
end
|
|
62
58
|
|
|
63
|
-
def
|
|
64
|
-
|
|
59
|
+
def load_cached_settings
|
|
60
|
+
test_optimization_cache.load_settings
|
|
61
|
+
end
|
|
65
62
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
63
|
+
def load_cached_known_tests
|
|
64
|
+
test_optimization_cache.load_known_tests
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def load_cached_test_management
|
|
68
|
+
test_optimization_cache.load_test_management
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def load_cached_skippable_tests
|
|
72
|
+
test_optimization_cache.load_skippable_tests
|
|
73
|
+
end
|
|
70
74
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
rescue JSON::ParserError => e
|
|
74
|
-
Datadog.logger.debug { "Failed to parse JSON file #{file_path}: #{e.message}" }
|
|
75
|
-
nil
|
|
76
|
-
rescue => e
|
|
77
|
-
Datadog.logger.debug { "Failed to load JSON file #{file_path}: #{e.message}" }
|
|
78
|
-
nil
|
|
75
|
+
def test_optimization_cache
|
|
76
|
+
Datadog.send(:components).test_optimization_cache
|
|
79
77
|
end
|
|
80
78
|
end
|
|
81
79
|
end
|
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
require "etc"
|
|
4
4
|
|
|
5
|
-
require_relative "../ext/dd_test"
|
|
6
|
-
|
|
7
5
|
module Datadog
|
|
8
6
|
module CI
|
|
9
7
|
module Utils
|
|
@@ -44,10 +42,6 @@ module Datadog
|
|
|
44
42
|
|
|
45
43
|
@virtual_cpu_count = ::Etc.nprocessors
|
|
46
44
|
end
|
|
47
|
-
|
|
48
|
-
def self.test_optimization_data_cached?
|
|
49
|
-
Dir.exist?(Ext::DDTest::TESTOPTIMIZATION_CACHE_PATH)
|
|
50
|
-
end
|
|
51
45
|
end
|
|
52
46
|
end
|
|
53
47
|
end
|