datadog-ci 1.14.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 +20 -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/runner.rb +4 -1
- 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 +2 -0
- 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/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 +31 -5
- data/lib/datadog/ci/test_session.rb +7 -1
- data/lib/datadog/ci/test_visibility/component.rb +82 -28
- data/lib/datadog/ci/test_visibility/context.rb +77 -29
- data/lib/datadog/ci/test_visibility/null_component.rb +4 -0
- 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} +23 -18
- 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 +4 -3
- metadata +14 -5
- data/lib/datadog/ci/test_visibility/capabilities.rb +0 -36
@@ -1,11 +1,16 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative "../../readonly_test_session"
|
4
|
+
require_relative "../../readonly_test_module"
|
5
|
+
|
3
6
|
module Datadog
|
4
7
|
module CI
|
5
8
|
module TestVisibility
|
6
9
|
module Store
|
7
10
|
# This context is shared between threads and represents the current test session and test module.
|
8
|
-
class
|
11
|
+
class Process
|
12
|
+
attr_reader :readonly_test_session, :readonly_test_module
|
13
|
+
|
9
14
|
def initialize
|
10
15
|
# we are using Monitor instead of Mutex because it is reentrant
|
11
16
|
@mutex = Monitor.new
|
@@ -13,6 +18,11 @@ module Datadog
|
|
13
18
|
@test_session = nil
|
14
19
|
@test_module = nil
|
15
20
|
@test_suites = {}
|
21
|
+
|
22
|
+
# small copies of id, name and some tags: store them in the current process to set session/module context
|
23
|
+
# for any spans faster
|
24
|
+
@readonly_test_session = nil
|
25
|
+
@readonly_test_module = nil
|
16
26
|
end
|
17
27
|
|
18
28
|
def fetch_or_activate_test_suite(test_suite_name, &block)
|
@@ -53,12 +63,6 @@ module Datadog
|
|
53
63
|
@mutex.synchronize { @test_suites[test_suite_name] }
|
54
64
|
end
|
55
65
|
|
56
|
-
def service
|
57
|
-
@mutex.synchronize do
|
58
|
-
@test_session&.service
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
66
|
def stop_all_test_suites
|
63
67
|
@mutex.synchronize do
|
64
68
|
@test_suites.each_value(&:finish)
|
@@ -66,17 +70,6 @@ module Datadog
|
|
66
70
|
end
|
67
71
|
end
|
68
72
|
|
69
|
-
def inheritable_session_tags
|
70
|
-
@mutex.synchronize do
|
71
|
-
test_session = @test_session
|
72
|
-
if test_session
|
73
|
-
test_session.inheritable_tags
|
74
|
-
else
|
75
|
-
{}
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
73
|
def deactivate_test_session!
|
81
74
|
@mutex.synchronize { @test_session = nil }
|
82
75
|
end
|
@@ -88,6 +81,18 @@ module Datadog
|
|
88
81
|
def deactivate_test_suite!(test_suite_name)
|
89
82
|
@mutex.synchronize { @test_suites.delete(test_suite_name) }
|
90
83
|
end
|
84
|
+
|
85
|
+
def set_readonly_test_session(remote_test_session)
|
86
|
+
return if remote_test_session.nil?
|
87
|
+
|
88
|
+
@readonly_test_session = Datadog::CI::ReadonlyTestSession.new(remote_test_session)
|
89
|
+
end
|
90
|
+
|
91
|
+
def set_readonly_test_module(remote_test_module)
|
92
|
+
return if remote_test_module.nil?
|
93
|
+
|
94
|
+
@readonly_test_module = Datadog::CI::ReadonlyTestModule.new(remote_test_module)
|
95
|
+
end
|
91
96
|
end
|
92
97
|
end
|
93
98
|
end
|
@@ -4,7 +4,6 @@ require "datadog/core/environment/identity"
|
|
4
4
|
require "datadog/core/telemetry/logging"
|
5
5
|
require "datadog/core/utils/only_once"
|
6
6
|
|
7
|
-
require_relative "capabilities"
|
8
7
|
require_relative "serializers/factories/test_level"
|
9
8
|
|
10
9
|
require_relative "../ext/app_types"
|
@@ -117,7 +116,7 @@ module Datadog
|
|
117
116
|
packer.write("library_version")
|
118
117
|
packer.write(Datadog::CI::VERSION::STRING)
|
119
118
|
|
120
|
-
library_capabilities_tags =
|
119
|
+
library_capabilities_tags = Ext::Test::LibraryCapabilities::CAPABILITY_VERSIONS
|
121
120
|
|
122
121
|
Ext::AppTypes::CI_SPAN_TYPES.each do |ci_span_type|
|
123
122
|
packer.write(ci_span_type)
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "fileutils"
|
4
|
+
require "tempfile"
|
5
|
+
|
6
|
+
module Datadog
|
7
|
+
module CI
|
8
|
+
module Utils
|
9
|
+
# FileStorage module provides functionality for storing and retrieving arbitrary Ruby objects in a temp file
|
10
|
+
# to share them between processes.
|
11
|
+
module FileStorage
|
12
|
+
TEMP_DIR = File.join(Dir.tmpdir, "datadog-ci-storage")
|
13
|
+
|
14
|
+
def self.store(key, value)
|
15
|
+
ensure_temp_dir_exists
|
16
|
+
file_path = file_path_for(key)
|
17
|
+
|
18
|
+
File.binwrite(file_path, Marshal.dump(value))
|
19
|
+
|
20
|
+
true
|
21
|
+
rescue => e
|
22
|
+
Datadog.logger.error("Failed to store data for key '#{key}': #{e.class} - #{e.message}")
|
23
|
+
false
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.retrieve(key)
|
27
|
+
file_path = file_path_for(key)
|
28
|
+
return nil unless File.exist?(file_path)
|
29
|
+
|
30
|
+
Marshal.load(File.binread(file_path))
|
31
|
+
rescue => e
|
32
|
+
Datadog.logger.error("Failed to retrieve data for key '#{key}': #{e.class} - #{e.message}")
|
33
|
+
nil
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.cleanup
|
37
|
+
return false unless Dir.exist?(TEMP_DIR)
|
38
|
+
|
39
|
+
FileUtils.rm_rf(TEMP_DIR)
|
40
|
+
true
|
41
|
+
rescue => e
|
42
|
+
Datadog.logger.error("Failed to cleanup storage directory: #{e.class} - #{e.message}")
|
43
|
+
false
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.ensure_temp_dir_exists
|
47
|
+
FileUtils.mkdir_p(TEMP_DIR) unless Dir.exist?(TEMP_DIR)
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.file_path_for(key)
|
51
|
+
sanitized_key = key.to_s.gsub(/[^a-zA-Z0-9_-]/, "_")
|
52
|
+
File.join(TEMP_DIR, "dd-ci-#{sanitized_key}.dat")
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "file_storage"
|
4
|
+
|
5
|
+
module Datadog
|
6
|
+
module CI
|
7
|
+
module Utils
|
8
|
+
# Module for components that need to persist and restore state
|
9
|
+
module Stateful
|
10
|
+
# Store component state
|
11
|
+
def store_component_state
|
12
|
+
state = serialize_state
|
13
|
+
|
14
|
+
res = Utils::FileStorage.store(storage_key, state)
|
15
|
+
Datadog.logger.debug { "Stored component state (key=#{storage_key}): #{res}" }
|
16
|
+
|
17
|
+
res
|
18
|
+
end
|
19
|
+
|
20
|
+
# Load component state
|
21
|
+
def load_component_state
|
22
|
+
test_visibility_component = Datadog.send(:components).test_visibility
|
23
|
+
return false unless test_visibility_component.client_process?
|
24
|
+
|
25
|
+
state = Utils::FileStorage.retrieve(storage_key)
|
26
|
+
unless state
|
27
|
+
Datadog.logger.debug { "No component state found in file storage (key=#{storage_key})" }
|
28
|
+
return false
|
29
|
+
end
|
30
|
+
|
31
|
+
restore_state(state)
|
32
|
+
Datadog.logger.debug { "Loaded component state from file storage (key=#{storage_key})" }
|
33
|
+
|
34
|
+
true
|
35
|
+
end
|
36
|
+
|
37
|
+
# These methods must be implemented by including classes
|
38
|
+
def serialize_state
|
39
|
+
raise NotImplementedError, "Components must implement #serialize_state"
|
40
|
+
end
|
41
|
+
|
42
|
+
def restore_state(state)
|
43
|
+
raise NotImplementedError, "Components must implement #restore_state"
|
44
|
+
end
|
45
|
+
|
46
|
+
def storage_key
|
47
|
+
raise NotImplementedError, "Components must implement #storage_key"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/lib/datadog/ci/version.rb
CHANGED
data/lib/datadog/ci.rb
CHANGED
@@ -415,16 +415,17 @@ end
|
|
415
415
|
|
416
416
|
# Integrations
|
417
417
|
|
418
|
-
# Test frameworks
|
418
|
+
# Test frameworks
|
419
419
|
require_relative "ci/contrib/cucumber/integration"
|
420
420
|
require_relative "ci/contrib/minitest/integration"
|
421
421
|
require_relative "ci/contrib/rspec/integration"
|
422
422
|
|
423
|
-
# Test runners
|
423
|
+
# Test runners
|
424
424
|
require_relative "ci/contrib/knapsack/integration"
|
425
425
|
require_relative "ci/contrib/ciqueue/integration"
|
426
|
+
require_relative "ci/contrib/parallel_tests/integration"
|
426
427
|
|
427
|
-
# Additional test libraries (auto instrumented
|
428
|
+
# Additional test libraries (auto instrumented on test session start)
|
428
429
|
require_relative "ci/contrib/selenium/integration"
|
429
430
|
require_relative "ci/contrib/cuprite/integration"
|
430
431
|
require_relative "ci/contrib/simplecov/integration"
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: datadog-ci
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.15.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Datadog, Inc.
|
8
8
|
bindir: exe
|
9
9
|
cert_chain: []
|
10
|
-
date: 2025-03-
|
10
|
+
date: 2025-03-25 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: datadog
|
@@ -117,11 +117,17 @@ files:
|
|
117
117
|
- lib/datadog/ci/contrib/minitest/runnable.rb
|
118
118
|
- lib/datadog/ci/contrib/minitest/runner.rb
|
119
119
|
- lib/datadog/ci/contrib/minitest/test.rb
|
120
|
+
- lib/datadog/ci/contrib/parallel_tests/cli.rb
|
121
|
+
- lib/datadog/ci/contrib/parallel_tests/configuration/settings.rb
|
122
|
+
- lib/datadog/ci/contrib/parallel_tests/ext.rb
|
123
|
+
- lib/datadog/ci/contrib/parallel_tests/integration.rb
|
124
|
+
- lib/datadog/ci/contrib/parallel_tests/patcher.rb
|
120
125
|
- lib/datadog/ci/contrib/patcher.rb
|
121
126
|
- lib/datadog/ci/contrib/rspec/configuration/settings.rb
|
122
127
|
- lib/datadog/ci/contrib/rspec/example.rb
|
123
128
|
- lib/datadog/ci/contrib/rspec/example_group.rb
|
124
129
|
- lib/datadog/ci/contrib/rspec/ext.rb
|
130
|
+
- lib/datadog/ci/contrib/rspec/helpers.rb
|
125
131
|
- lib/datadog/ci/contrib/rspec/integration.rb
|
126
132
|
- lib/datadog/ci/contrib/rspec/patcher.rb
|
127
133
|
- lib/datadog/ci/contrib/rspec/runner.rb
|
@@ -172,6 +178,8 @@ files:
|
|
172
178
|
- lib/datadog/ci/git/tree_uploader.rb
|
173
179
|
- lib/datadog/ci/git/upload_packfile.rb
|
174
180
|
- lib/datadog/ci/git/user.rb
|
181
|
+
- lib/datadog/ci/readonly_test_module.rb
|
182
|
+
- lib/datadog/ci/readonly_test_session.rb
|
175
183
|
- lib/datadog/ci/remote/component.rb
|
176
184
|
- lib/datadog/ci/remote/library_settings.rb
|
177
185
|
- lib/datadog/ci/remote/library_settings_client.rb
|
@@ -206,7 +214,6 @@ files:
|
|
206
214
|
- lib/datadog/ci/test_retries/strategy/retry_new.rb
|
207
215
|
- lib/datadog/ci/test_session.rb
|
208
216
|
- lib/datadog/ci/test_suite.rb
|
209
|
-
- lib/datadog/ci/test_visibility/capabilities.rb
|
210
217
|
- lib/datadog/ci/test_visibility/component.rb
|
211
218
|
- lib/datadog/ci/test_visibility/context.rb
|
212
219
|
- lib/datadog/ci/test_visibility/flush.rb
|
@@ -222,8 +229,8 @@ files:
|
|
222
229
|
- lib/datadog/ci/test_visibility/serializers/test_suite.rb
|
223
230
|
- lib/datadog/ci/test_visibility/serializers/test_v1.rb
|
224
231
|
- lib/datadog/ci/test_visibility/serializers/test_v2.rb
|
225
|
-
- lib/datadog/ci/test_visibility/store/
|
226
|
-
- lib/datadog/ci/test_visibility/store/
|
232
|
+
- lib/datadog/ci/test_visibility/store/fiber_local.rb
|
233
|
+
- lib/datadog/ci/test_visibility/store/process.rb
|
227
234
|
- lib/datadog/ci/test_visibility/telemetry.rb
|
228
235
|
- lib/datadog/ci/test_visibility/total_coverage.rb
|
229
236
|
- lib/datadog/ci/test_visibility/transport.rb
|
@@ -240,9 +247,11 @@ files:
|
|
240
247
|
- lib/datadog/ci/transport/telemetry.rb
|
241
248
|
- lib/datadog/ci/utils/bundle.rb
|
242
249
|
- lib/datadog/ci/utils/configuration.rb
|
250
|
+
- lib/datadog/ci/utils/file_storage.rb
|
243
251
|
- lib/datadog/ci/utils/git.rb
|
244
252
|
- lib/datadog/ci/utils/parsing.rb
|
245
253
|
- lib/datadog/ci/utils/rum.rb
|
254
|
+
- lib/datadog/ci/utils/stateful.rb
|
246
255
|
- lib/datadog/ci/utils/telemetry.rb
|
247
256
|
- lib/datadog/ci/utils/test_run.rb
|
248
257
|
- lib/datadog/ci/version.rb
|
@@ -1,36 +0,0 @@
|
|
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
|