datadog-ci 1.4.1 → 1.6.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|