datadog-ci 1.4.1 → 1.6.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/README.md +1 -0
- data/lib/datadog/ci/configuration/components.rb +14 -7
- data/lib/datadog/ci/configuration/settings.rb +11 -0
- data/lib/datadog/ci/contrib/cucumber/filter.rb +40 -0
- data/lib/datadog/ci/contrib/cucumber/instrumentation.rb +15 -1
- data/lib/datadog/ci/contrib/cucumber/patcher.rb +0 -2
- data/lib/datadog/ci/contrib/minitest/runner.rb +6 -1
- data/lib/datadog/ci/contrib/minitest/test.rb +4 -0
- data/lib/datadog/ci/contrib/rspec/example.rb +11 -10
- data/lib/datadog/ci/contrib/rspec/runner.rb +2 -1
- data/lib/datadog/ci/ext/settings.rb +2 -0
- data/lib/datadog/ci/ext/telemetry.rb +9 -0
- data/lib/datadog/ci/ext/test.rb +12 -1
- data/lib/datadog/ci/ext/transport.rb +7 -0
- data/lib/datadog/ci/remote/component.rb +13 -2
- data/lib/datadog/ci/remote/library_settings.rb +48 -7
- data/lib/datadog/ci/remote/library_settings_client.rb +2 -1
- data/lib/datadog/ci/remote/slow_test_retries.rb +53 -0
- data/lib/datadog/ci/span.rb +7 -0
- data/lib/datadog/ci/test.rb +15 -2
- data/lib/datadog/ci/test_optimisation/component.rb +9 -6
- data/lib/datadog/ci/test_optimisation/skippable.rb +1 -1
- data/lib/datadog/ci/test_retries/component.rb +68 -39
- data/lib/datadog/ci/test_retries/driver/base.rb +25 -0
- data/lib/datadog/ci/test_retries/driver/no_retry.rb +16 -0
- data/lib/datadog/ci/test_retries/driver/retry_failed.rb +37 -0
- data/lib/datadog/ci/test_retries/driver/retry_new.rb +50 -0
- data/lib/datadog/ci/test_retries/null_component.rb +7 -6
- data/lib/datadog/ci/test_retries/strategy/base.rb +11 -4
- data/lib/datadog/ci/test_retries/strategy/no_retry.rb +0 -2
- data/lib/datadog/ci/test_retries/strategy/retry_failed.rb +30 -13
- data/lib/datadog/ci/test_retries/strategy/retry_new.rb +132 -0
- data/lib/datadog/ci/test_retries/unique_tests_client.rb +132 -0
- data/lib/datadog/ci/test_session.rb +20 -0
- data/lib/datadog/ci/test_suite.rb +8 -0
- data/lib/datadog/ci/test_visibility/component.rb +38 -15
- data/lib/datadog/ci/test_visibility/context.rb +4 -0
- data/lib/datadog/ci/test_visibility/null_component.rb +8 -1
- data/lib/datadog/ci/test_visibility/telemetry.rb +10 -3
- data/lib/datadog/ci/test_visibility/transport.rb +21 -3
- data/lib/datadog/ci/utils/test_run.rb +9 -1
- data/lib/datadog/ci/version.rb +2 -2
- data/lib/datadog/ci.rb +6 -3
- metadata +11 -5
- data/lib/datadog/ci/contrib/cucumber/configuration_override.rb +0 -37
- data/lib/datadog/ci/utils/identity.rb +0 -20
@@ -0,0 +1,132 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "json"
|
4
|
+
|
5
|
+
require_relative "../ext/telemetry"
|
6
|
+
require_relative "../ext/transport"
|
7
|
+
require_relative "../transport/telemetry"
|
8
|
+
require_relative "../utils/telemetry"
|
9
|
+
require_relative "../utils/test_run"
|
10
|
+
|
11
|
+
module Datadog
|
12
|
+
module CI
|
13
|
+
module TestRetries
|
14
|
+
# fetch a list of unique known tests from the backend
|
15
|
+
class UniqueTestsClient
|
16
|
+
class Response
|
17
|
+
def initialize(http_response)
|
18
|
+
@http_response = http_response
|
19
|
+
@json = nil
|
20
|
+
end
|
21
|
+
|
22
|
+
def ok?
|
23
|
+
resp = @http_response
|
24
|
+
!resp.nil? && resp.ok?
|
25
|
+
end
|
26
|
+
|
27
|
+
def tests
|
28
|
+
res = Set.new
|
29
|
+
|
30
|
+
payload
|
31
|
+
.fetch("data", {})
|
32
|
+
.fetch("attributes", {})
|
33
|
+
.fetch("tests", {})
|
34
|
+
.each do |_test_module, suites_hash|
|
35
|
+
suites_hash.each do |test_suite, tests|
|
36
|
+
tests.each do |test_name|
|
37
|
+
res << Utils::TestRun.datadog_test_id(test_name, test_suite)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
res
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def payload
|
48
|
+
cached = @json
|
49
|
+
return cached unless cached.nil?
|
50
|
+
|
51
|
+
resp = @http_response
|
52
|
+
return @json = {} if resp.nil? || !ok?
|
53
|
+
|
54
|
+
begin
|
55
|
+
@json = JSON.parse(resp.payload)
|
56
|
+
rescue JSON::ParserError => e
|
57
|
+
Datadog.logger.error("Failed to parse unique known tests response payload: #{e}. Payload was: #{resp.payload}")
|
58
|
+
@json = {}
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def initialize(dd_env:, api: nil, config_tags: {})
|
64
|
+
@api = api
|
65
|
+
@dd_env = dd_env
|
66
|
+
@config_tags = config_tags
|
67
|
+
end
|
68
|
+
|
69
|
+
def fetch_unique_tests(test_session)
|
70
|
+
api = @api
|
71
|
+
return Set.new unless api
|
72
|
+
|
73
|
+
request_payload = payload(test_session)
|
74
|
+
Datadog.logger.debug("Fetching unique known tests with request: #{request_payload}")
|
75
|
+
|
76
|
+
http_response = api.api_request(
|
77
|
+
path: Ext::Transport::DD_API_UNIQUE_TESTS_PATH,
|
78
|
+
payload: request_payload
|
79
|
+
)
|
80
|
+
|
81
|
+
Transport::Telemetry.api_requests(
|
82
|
+
Ext::Telemetry::METRIC_EFD_UNIQUE_TESTS_REQUEST,
|
83
|
+
1,
|
84
|
+
compressed: http_response.request_compressed
|
85
|
+
)
|
86
|
+
Utils::Telemetry.distribution(Ext::Telemetry::METRIC_EFD_UNIQUE_TESTS_REQUEST_MS, http_response.duration_ms)
|
87
|
+
Utils::Telemetry.distribution(
|
88
|
+
Ext::Telemetry::METRIC_EFD_UNIQUE_TESTS_RESPONSE_BYTES,
|
89
|
+
http_response.response_size.to_f,
|
90
|
+
{Ext::Telemetry::TAG_RESPONSE_COMPRESSED => http_response.gzipped_content?.to_s}
|
91
|
+
)
|
92
|
+
|
93
|
+
unless http_response.ok?
|
94
|
+
Transport::Telemetry.api_requests_errors(
|
95
|
+
Ext::Telemetry::METRIC_EFD_UNIQUE_TESTS_REQUEST_ERRORS,
|
96
|
+
1,
|
97
|
+
error_type: http_response.telemetry_error_type,
|
98
|
+
status_code: http_response.code
|
99
|
+
)
|
100
|
+
end
|
101
|
+
|
102
|
+
Response.new(http_response).tests
|
103
|
+
end
|
104
|
+
|
105
|
+
private
|
106
|
+
|
107
|
+
def payload(test_session)
|
108
|
+
{
|
109
|
+
"data" => {
|
110
|
+
"id" => Datadog::Core::Environment::Identity.id,
|
111
|
+
"type" => Ext::Transport::DD_API_UNIQUE_TESTS_TYPE,
|
112
|
+
"attributes" => {
|
113
|
+
"repository_url" => test_session.git_repository_url,
|
114
|
+
"service" => test_session.service,
|
115
|
+
"env" => @dd_env,
|
116
|
+
"sha" => test_session.git_commit_sha,
|
117
|
+
"configurations" => {
|
118
|
+
Ext::Test::TAG_OS_PLATFORM => test_session.os_platform,
|
119
|
+
Ext::Test::TAG_OS_ARCHITECTURE => test_session.os_architecture,
|
120
|
+
Ext::Test::TAG_OS_VERSION => test_session.os_version,
|
121
|
+
Ext::Test::TAG_RUNTIME_NAME => test_session.runtime_name,
|
122
|
+
Ext::Test::TAG_RUNTIME_VERSION => test_session.runtime_version,
|
123
|
+
"custom" => @config_tags
|
124
|
+
}
|
125
|
+
}
|
126
|
+
}
|
127
|
+
}.to_json
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
@@ -12,6 +12,8 @@ module Datadog
|
|
12
12
|
#
|
13
13
|
# @public_api
|
14
14
|
class TestSession < ConcurrentSpan
|
15
|
+
attr_accessor :total_tests_count
|
16
|
+
|
15
17
|
# Finishes the current test session.
|
16
18
|
# @return [void]
|
17
19
|
def finish
|
@@ -26,6 +28,24 @@ module Datadog
|
|
26
28
|
get_tag(Ext::Test::TAG_COMMAND)
|
27
29
|
end
|
28
30
|
|
31
|
+
# Return the test session's command used to run the tests
|
32
|
+
# @return [String] the command for this test session.
|
33
|
+
def test_command
|
34
|
+
get_tag(Ext::Test::TAG_COMMAND)
|
35
|
+
end
|
36
|
+
|
37
|
+
# Return the test session's CI provider name (e.g. "travis", "circleci", etc.)
|
38
|
+
# @return [String] the provider name for this test session.
|
39
|
+
def ci_provider
|
40
|
+
get_tag(Ext::Environment::TAG_PROVIDER_NAME)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Return the test session's CI job name (e.g. "build", "test", etc.)
|
44
|
+
# @return [String] the job name for this test session.
|
45
|
+
def ci_job_name
|
46
|
+
get_tag(Ext::Environment::TAG_JOB_NAME)
|
47
|
+
end
|
48
|
+
|
29
49
|
def skipping_tests?
|
30
50
|
get_tag(Ext::Test::TAG_ITR_TEST_SKIPPING_ENABLED) == "true"
|
31
51
|
end
|
@@ -51,6 +51,14 @@ module Datadog
|
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
54
|
+
# @internal
|
55
|
+
def any_test_retry_passed?(test_id)
|
56
|
+
synchronize do
|
57
|
+
stats = @execution_stats_per_test[test_id]
|
58
|
+
stats && stats[Ext::Test::Status::PASS] > 0
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
54
62
|
# @internal
|
55
63
|
def test_executed?(test_id)
|
56
64
|
synchronize do
|
@@ -17,23 +17,25 @@ module Datadog
|
|
17
17
|
module TestVisibility
|
18
18
|
# Common behavior for CI tests
|
19
19
|
class Component
|
20
|
-
attr_reader :test_suite_level_visibility_enabled
|
21
|
-
|
22
|
-
FIBER_LOCAL_TEST_FINISHED_CALLBACK_KEY = :__dd_test_finished_callback
|
20
|
+
attr_reader :test_suite_level_visibility_enabled, :logical_test_session_name
|
23
21
|
|
24
22
|
def initialize(
|
25
23
|
test_suite_level_visibility_enabled: false,
|
26
|
-
codeowners: Codeowners::Parser.new(Git::LocalRepository.root).parse
|
24
|
+
codeowners: Codeowners::Parser.new(Git::LocalRepository.root).parse,
|
25
|
+
logical_test_session_name: nil
|
27
26
|
)
|
28
27
|
@test_suite_level_visibility_enabled = test_suite_level_visibility_enabled
|
29
28
|
@context = Context.new
|
30
29
|
@codeowners = codeowners
|
30
|
+
@logical_test_session_name = logical_test_session_name
|
31
31
|
end
|
32
32
|
|
33
|
-
def start_test_session(service: nil, tags: {})
|
33
|
+
def start_test_session(service: nil, tags: {}, total_tests_count: 0)
|
34
34
|
return skip_tracing unless test_suite_level_visibility_enabled
|
35
35
|
|
36
36
|
test_session = @context.start_test_session(service: service, tags: tags)
|
37
|
+
test_session.total_tests_count = total_tests_count
|
38
|
+
|
37
39
|
on_test_session_started(test_session)
|
38
40
|
test_session
|
39
41
|
end
|
@@ -57,6 +59,8 @@ module Datadog
|
|
57
59
|
def trace_test(test_name, test_suite_name, service: nil, tags: {}, &block)
|
58
60
|
if block
|
59
61
|
@context.trace_test(test_name, test_suite_name, service: service, tags: tags) do |test|
|
62
|
+
subscribe_to_after_stop_event(test.tracer_span)
|
63
|
+
|
60
64
|
on_test_started(test)
|
61
65
|
res = block.call(test)
|
62
66
|
on_test_finished(test)
|
@@ -64,6 +68,7 @@ module Datadog
|
|
64
68
|
end
|
65
69
|
else
|
66
70
|
test = @context.trace_test(test_name, test_suite_name, service: service, tags: tags)
|
71
|
+
subscribe_to_after_stop_event(test.tracer_span)
|
67
72
|
on_test_started(test)
|
68
73
|
test
|
69
74
|
end
|
@@ -127,15 +132,6 @@ module Datadog
|
|
127
132
|
@context.deactivate_test_suite(test_suite_name)
|
128
133
|
end
|
129
134
|
|
130
|
-
# sets fiber-local callback to be called when test is finished
|
131
|
-
def set_test_finished_callback(callback)
|
132
|
-
Thread.current[FIBER_LOCAL_TEST_FINISHED_CALLBACK_KEY] = callback
|
133
|
-
end
|
134
|
-
|
135
|
-
def remove_test_finished_callback
|
136
|
-
Thread.current[FIBER_LOCAL_TEST_FINISHED_CALLBACK_KEY] = nil
|
137
|
-
end
|
138
|
-
|
139
135
|
def itr_enabled?
|
140
136
|
test_optimisation.enabled?
|
141
137
|
end
|
@@ -158,6 +154,9 @@ module Datadog
|
|
158
154
|
Telemetry.test_session_started(test_session)
|
159
155
|
Telemetry.event_created(test_session)
|
160
156
|
|
157
|
+
# sets logical test session name if none provided by the user
|
158
|
+
override_logical_test_session_name!(test_session) if logical_test_session_name.nil?
|
159
|
+
|
161
160
|
# signal Remote::Component to configure the library
|
162
161
|
remote.configure(test_session)
|
163
162
|
end
|
@@ -204,7 +203,11 @@ module Datadog
|
|
204
203
|
|
205
204
|
Telemetry.event_finished(test)
|
206
205
|
|
207
|
-
|
206
|
+
test_retries.record_test_finished(test)
|
207
|
+
end
|
208
|
+
|
209
|
+
def on_after_test_span_finished(tracer_span)
|
210
|
+
test_retries.record_test_span_duration(tracer_span)
|
208
211
|
end
|
209
212
|
|
210
213
|
# HELPERS
|
@@ -212,6 +215,14 @@ module Datadog
|
|
212
215
|
block&.call(nil)
|
213
216
|
end
|
214
217
|
|
218
|
+
def subscribe_to_after_stop_event(tracer_span)
|
219
|
+
events = tracer_span.send(:events)
|
220
|
+
|
221
|
+
events.after_stop.subscribe do |span|
|
222
|
+
on_after_test_span_finished(span)
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
215
226
|
def set_codeowners(test)
|
216
227
|
source = test.source_file
|
217
228
|
owners = @codeowners.list_owners(source) if source
|
@@ -263,10 +274,22 @@ module Datadog
|
|
263
274
|
end
|
264
275
|
end
|
265
276
|
|
277
|
+
def override_logical_test_session_name!(test_session)
|
278
|
+
@logical_test_session_name = test_session.test_command
|
279
|
+
ci_job_name = test_session.ci_job_name
|
280
|
+
if ci_job_name
|
281
|
+
@logical_test_session_name = "#{ci_job_name}-#{@logical_test_session_name}"
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
266
285
|
def test_optimisation
|
267
286
|
Datadog.send(:components).test_optimisation
|
268
287
|
end
|
269
288
|
|
289
|
+
def test_retries
|
290
|
+
Datadog.send(:components).test_retries
|
291
|
+
end
|
292
|
+
|
270
293
|
def git_tree_upload_worker
|
271
294
|
Datadog.send(:components).git_tree_upload_worker
|
272
295
|
end
|
@@ -11,6 +11,8 @@ require_relative "../ext/app_types"
|
|
11
11
|
require_relative "../ext/environment"
|
12
12
|
require_relative "../ext/test"
|
13
13
|
|
14
|
+
require_relative "../utils/test_run"
|
15
|
+
|
14
16
|
require_relative "../span"
|
15
17
|
require_relative "../test"
|
16
18
|
require_relative "../test_session"
|
@@ -203,6 +205,8 @@ module Datadog
|
|
203
205
|
|
204
206
|
ci_span.set_tags(tags)
|
205
207
|
ci_span.set_tags(@environment_tags)
|
208
|
+
|
209
|
+
ci_span.set_metric(Ext::Test::METRIC_CPU_COUNT, Utils::TestRun.virtual_cpu_count)
|
206
210
|
end
|
207
211
|
|
208
212
|
# PROPAGATING CONTEXT FROM TOP-LEVEL TO THE LOWER LEVELS
|
@@ -5,7 +5,7 @@ module Datadog
|
|
5
5
|
module TestVisibility
|
6
6
|
# Special test visibility component that does not record anything
|
7
7
|
class NullComponent
|
8
|
-
def start_test_session(service: nil, tags: {})
|
8
|
+
def start_test_session(service: nil, tags: {}, total_tests_count: 0)
|
9
9
|
skip_tracing
|
10
10
|
end
|
11
11
|
|
@@ -53,6 +53,13 @@ module Datadog
|
|
53
53
|
def remove_test_finished_callback
|
54
54
|
end
|
55
55
|
|
56
|
+
def test_suite_level_visibility_enabled
|
57
|
+
false
|
58
|
+
end
|
59
|
+
|
60
|
+
def logical_test_session_name
|
61
|
+
end
|
62
|
+
|
56
63
|
private
|
57
64
|
|
58
65
|
def skip_tracing(block = nil)
|
@@ -34,9 +34,7 @@ module Datadog
|
|
34
34
|
1,
|
35
35
|
{
|
36
36
|
Ext::Telemetry::TAG_AUTO_INJECTED => "false", # ruby doesn't support auto injection yet
|
37
|
-
Ext::Telemetry::TAG_PROVIDER =>
|
38
|
-
test_session.get_tag(Ext::Environment::TAG_PROVIDER_NAME) ||
|
39
|
-
Ext::Telemetry::Provider::UNSUPPORTED
|
37
|
+
Ext::Telemetry::TAG_PROVIDER => test_session.ci_provider || Ext::Telemetry::Provider::UNSUPPORTED
|
40
38
|
}
|
41
39
|
)
|
42
40
|
end
|
@@ -58,6 +56,15 @@ module Datadog
|
|
58
56
|
# set is_retry tag if span represents a retried test
|
59
57
|
tags[Ext::Telemetry::TAG_IS_RETRY] = "true" if span.get_tag(Ext::Test::TAG_IS_RETRY)
|
60
58
|
|
59
|
+
# is_new
|
60
|
+
tags[Ext::Telemetry::TAG_IS_NEW] = "true" if span.get_tag(Ext::Test::TAG_IS_NEW)
|
61
|
+
|
62
|
+
# session-level tag - early_flake_detection_abort_reason
|
63
|
+
early_flake_detection_abort_reason = span.get_tag(Ext::Test::TAG_EARLY_FLAKE_ABORT_REASON)
|
64
|
+
if early_flake_detection_abort_reason
|
65
|
+
tags[Ext::Telemetry::TAG_EARLY_FLAKE_DETECTION_ABORT_REASON] = early_flake_detection_abort_reason
|
66
|
+
end
|
67
|
+
|
61
68
|
tags
|
62
69
|
end
|
63
70
|
|
@@ -3,6 +3,7 @@
|
|
3
3
|
require "datadog/core/environment/identity"
|
4
4
|
|
5
5
|
require_relative "serializers/factories/test_level"
|
6
|
+
require_relative "../ext/app_types"
|
6
7
|
require_relative "../ext/telemetry"
|
7
8
|
require_relative "../ext/transport"
|
8
9
|
require_relative "../transport/event_platform_transport"
|
@@ -51,7 +52,12 @@ module Datadog
|
|
51
52
|
end
|
52
53
|
|
53
54
|
def encode_span(trace, span)
|
54
|
-
serializer = serializers_factory.serializer(
|
55
|
+
serializer = serializers_factory.serializer(
|
56
|
+
trace,
|
57
|
+
span,
|
58
|
+
options: {itr_correlation_id: test_optimisation&.correlation_id}
|
59
|
+
)
|
60
|
+
|
55
61
|
if serializer.valid?
|
56
62
|
encoded = encoder.encode(serializer)
|
57
63
|
return nil if event_too_large?(span, encoded)
|
@@ -75,7 +81,7 @@ module Datadog
|
|
75
81
|
packer.write(1)
|
76
82
|
|
77
83
|
packer.write("metadata")
|
78
|
-
packer.write_map_header(1)
|
84
|
+
packer.write_map_header(1 + Ext::AppTypes::CI_SPAN_TYPES.size)
|
79
85
|
|
80
86
|
packer.write("*")
|
81
87
|
metadata_fields_count = dd_env ? 4 : 3
|
@@ -95,12 +101,24 @@ module Datadog
|
|
95
101
|
packer.write("library_version")
|
96
102
|
packer.write(Datadog::CI::VERSION::STRING)
|
97
103
|
|
104
|
+
Ext::AppTypes::CI_SPAN_TYPES.each do |ci_span_type|
|
105
|
+
packer.write(ci_span_type)
|
106
|
+
packer.write_map_header(1)
|
107
|
+
|
108
|
+
packer.write(Ext::Test::METADATA_TAG_TEST_SESSION_NAME)
|
109
|
+
packer.write(test_visibility&.logical_test_session_name)
|
110
|
+
end
|
111
|
+
|
98
112
|
packer.write("events")
|
99
113
|
end
|
100
114
|
|
101
|
-
def
|
115
|
+
def test_optimisation
|
102
116
|
@test_optimisation ||= Datadog::CI.send(:test_optimisation)
|
103
117
|
end
|
118
|
+
|
119
|
+
def test_visibility
|
120
|
+
@test_visibility ||= Datadog::CI.send(:test_visibility)
|
121
|
+
end
|
104
122
|
end
|
105
123
|
end
|
106
124
|
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "etc"
|
4
|
+
|
3
5
|
module Datadog
|
4
6
|
module CI
|
5
7
|
module Utils
|
@@ -10,7 +12,7 @@ module Datadog
|
|
10
12
|
@command = "#{$0} #{ARGV.join(" ")}"
|
11
13
|
end
|
12
14
|
|
13
|
-
def self.
|
15
|
+
def self.datadog_test_id(test_name, suite, parameters = nil)
|
14
16
|
"#{suite}.#{test_name}.#{parameters}"
|
15
17
|
end
|
16
18
|
|
@@ -34,6 +36,12 @@ module Datadog
|
|
34
36
|
end
|
35
37
|
res
|
36
38
|
end
|
39
|
+
|
40
|
+
def self.virtual_cpu_count
|
41
|
+
return @virtual_cpu_count if defined?(@virtual_cpu_count)
|
42
|
+
|
43
|
+
@virtual_cpu_count = ::Etc.nprocessors
|
44
|
+
end
|
37
45
|
end
|
38
46
|
end
|
39
47
|
end
|
data/lib/datadog/ci/version.rb
CHANGED
data/lib/datadog/ci.rb
CHANGED
@@ -6,6 +6,7 @@ require_relative "ci/utils/telemetry"
|
|
6
6
|
require_relative "ci/ext/app_types"
|
7
7
|
require_relative "ci/ext/telemetry"
|
8
8
|
|
9
|
+
require "datadog"
|
9
10
|
require "datadog/core"
|
10
11
|
|
11
12
|
module Datadog
|
@@ -27,7 +28,8 @@ module Datadog
|
|
27
28
|
# ```
|
28
29
|
# Datadog::CI.start_test_session(
|
29
30
|
# service: "my-web-site-tests",
|
30
|
-
# tags: { Datadog::CI::Ext::Test::TAG_FRAMEWORK => "my-test-framework" }
|
31
|
+
# tags: { Datadog::CI::Ext::Test::TAG_FRAMEWORK => "my-test-framework" },
|
32
|
+
# total_tests_count: 100
|
31
33
|
# )
|
32
34
|
#
|
33
35
|
# # Somewhere else after test run has ended
|
@@ -38,15 +40,16 @@ module Datadog
|
|
38
40
|
#
|
39
41
|
# @param [String] service the service name for this session (optional, defaults to DD_SERVICE or repository name)
|
40
42
|
# @param [Hash<String,String>] tags extra tags which should be added to the test session.
|
43
|
+
# @param [Integer] total_tests_count the total number of tests in the test session (optional, defaults to 0) - it is used to limit the number of new tests retried within session if early flake detection is enabled
|
41
44
|
# @return [Datadog::CI::TestSession] the active, running {Datadog::CI::TestSession}.
|
42
45
|
# @return [nil] if test suite level visibility is disabled or CI mode is disabled.
|
43
|
-
def start_test_session(service: Utils::Configuration.fetch_service_name("test"), tags: {})
|
46
|
+
def start_test_session(service: Utils::Configuration.fetch_service_name("test"), tags: {}, total_tests_count: 0)
|
44
47
|
Utils::Telemetry.inc(
|
45
48
|
Ext::Telemetry::METRIC_MANUAL_API_EVENTS,
|
46
49
|
1,
|
47
50
|
{Ext::Telemetry::TAG_EVENT_TYPE => Ext::Telemetry::EventType::SESSION}
|
48
51
|
)
|
49
|
-
test_visibility.start_test_session(service: service, tags: tags)
|
52
|
+
test_visibility.start_test_session(service: service, tags: tags, total_tests_count: total_tests_count)
|
50
53
|
end
|
51
54
|
|
52
55
|
# The active, unfinished test session.
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: datadog-ci
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Datadog, Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-09-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: datadog
|
@@ -68,8 +68,8 @@ files:
|
|
68
68
|
- lib/datadog/ci/configuration/settings.rb
|
69
69
|
- lib/datadog/ci/contrib/contrib.rb
|
70
70
|
- lib/datadog/ci/contrib/cucumber/configuration/settings.rb
|
71
|
-
- lib/datadog/ci/contrib/cucumber/configuration_override.rb
|
72
71
|
- lib/datadog/ci/contrib/cucumber/ext.rb
|
72
|
+
- lib/datadog/ci/contrib/cucumber/filter.rb
|
73
73
|
- lib/datadog/ci/contrib/cucumber/formatter.rb
|
74
74
|
- lib/datadog/ci/contrib/cucumber/instrumentation.rb
|
75
75
|
- lib/datadog/ci/contrib/cucumber/integration.rb
|
@@ -139,6 +139,7 @@ files:
|
|
139
139
|
- lib/datadog/ci/remote/component.rb
|
140
140
|
- lib/datadog/ci/remote/library_settings.rb
|
141
141
|
- lib/datadog/ci/remote/library_settings_client.rb
|
142
|
+
- lib/datadog/ci/remote/slow_test_retries.rb
|
142
143
|
- lib/datadog/ci/span.rb
|
143
144
|
- lib/datadog/ci/test.rb
|
144
145
|
- lib/datadog/ci/test_module.rb
|
@@ -150,10 +151,16 @@ files:
|
|
150
151
|
- lib/datadog/ci/test_optimisation/skippable.rb
|
151
152
|
- lib/datadog/ci/test_optimisation/telemetry.rb
|
152
153
|
- lib/datadog/ci/test_retries/component.rb
|
154
|
+
- lib/datadog/ci/test_retries/driver/base.rb
|
155
|
+
- lib/datadog/ci/test_retries/driver/no_retry.rb
|
156
|
+
- lib/datadog/ci/test_retries/driver/retry_failed.rb
|
157
|
+
- lib/datadog/ci/test_retries/driver/retry_new.rb
|
153
158
|
- lib/datadog/ci/test_retries/null_component.rb
|
154
159
|
- lib/datadog/ci/test_retries/strategy/base.rb
|
155
160
|
- lib/datadog/ci/test_retries/strategy/no_retry.rb
|
156
161
|
- lib/datadog/ci/test_retries/strategy/retry_failed.rb
|
162
|
+
- lib/datadog/ci/test_retries/strategy/retry_new.rb
|
163
|
+
- lib/datadog/ci/test_retries/unique_tests_client.rb
|
157
164
|
- lib/datadog/ci/test_session.rb
|
158
165
|
- lib/datadog/ci/test_suite.rb
|
159
166
|
- lib/datadog/ci/test_visibility/component.rb
|
@@ -187,7 +194,6 @@ files:
|
|
187
194
|
- lib/datadog/ci/utils/bundle.rb
|
188
195
|
- lib/datadog/ci/utils/configuration.rb
|
189
196
|
- lib/datadog/ci/utils/git.rb
|
190
|
-
- lib/datadog/ci/utils/identity.rb
|
191
197
|
- lib/datadog/ci/utils/parsing.rb
|
192
198
|
- lib/datadog/ci/utils/telemetry.rb
|
193
199
|
- lib/datadog/ci/utils/test_run.rb
|
@@ -219,7 +225,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
219
225
|
- !ruby/object:Gem::Version
|
220
226
|
version: 2.0.0
|
221
227
|
requirements: []
|
222
|
-
rubygems_version: 3.5.
|
228
|
+
rubygems_version: 3.5.16
|
223
229
|
signing_key:
|
224
230
|
specification_version: 4
|
225
231
|
summary: Datadog CI visibility for your ruby application
|
@@ -1,37 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative "formatter"
|
4
|
-
|
5
|
-
module Datadog
|
6
|
-
module CI
|
7
|
-
module Contrib
|
8
|
-
module Cucumber
|
9
|
-
# Changes behaviour of Cucumber::Configuration class
|
10
|
-
module ConfigurationOverride
|
11
|
-
def self.included(base)
|
12
|
-
base.prepend(InstanceMethods)
|
13
|
-
end
|
14
|
-
|
15
|
-
# Instance methods for configuration
|
16
|
-
module InstanceMethods
|
17
|
-
def retry_attempts
|
18
|
-
super if !datadog_test_retries_component&.retry_failed_tests_enabled
|
19
|
-
|
20
|
-
datadog_test_retries_component&.retry_failed_tests_max_attempts
|
21
|
-
end
|
22
|
-
|
23
|
-
def retry_total_tests
|
24
|
-
super if !datadog_test_retries_component&.retry_failed_tests_enabled
|
25
|
-
|
26
|
-
datadog_test_retries_component&.retry_failed_tests_total_limit
|
27
|
-
end
|
28
|
-
|
29
|
-
def datadog_test_retries_component
|
30
|
-
Datadog.send(:components).test_retries
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
@@ -1,20 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Datadog
|
4
|
-
module CI
|
5
|
-
module Utils
|
6
|
-
module Identity
|
7
|
-
def self.included(base)
|
8
|
-
base.singleton_class.prepend(ClassMethods)
|
9
|
-
end
|
10
|
-
|
11
|
-
module ClassMethods
|
12
|
-
# return datadog-ci gem version instead of datadog gem version
|
13
|
-
def gem_datadog_version
|
14
|
-
Datadog::CI::VERSION::STRING
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|