datadog-ci 1.0.0.beta1 → 1.0.0.beta3
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 +105 -60
- data/README.md +37 -46
- data/lib/datadog/ci/configuration/components.rb +51 -9
- data/lib/datadog/ci/configuration/settings.rb +6 -0
- data/lib/datadog/ci/contrib/cucumber/formatter.rb +10 -5
- data/lib/datadog/ci/contrib/cucumber/patcher.rb +3 -0
- data/lib/datadog/ci/contrib/cucumber/step.rb +27 -0
- data/lib/datadog/ci/contrib/minitest/patcher.rb +2 -2
- data/lib/datadog/ci/contrib/minitest/test.rb +105 -0
- data/lib/datadog/ci/contrib/rspec/example.rb +11 -5
- data/lib/datadog/ci/ext/environment/providers/local_git.rb +8 -79
- data/lib/datadog/ci/ext/environment.rb +11 -16
- data/lib/datadog/ci/ext/settings.rb +1 -0
- data/lib/datadog/ci/ext/test.rb +8 -1
- data/lib/datadog/ci/ext/transport.rb +8 -0
- data/lib/datadog/ci/git/local_repository.rb +238 -0
- data/lib/datadog/ci/git/packfiles.rb +70 -0
- data/lib/datadog/ci/git/search_commits.rb +77 -0
- data/lib/datadog/ci/git/tree_uploader.rb +90 -0
- data/lib/datadog/ci/git/upload_packfile.rb +66 -0
- data/lib/datadog/ci/git/user.rb +29 -0
- data/lib/datadog/ci/itr/coverage/event.rb +18 -1
- data/lib/datadog/ci/itr/coverage/writer.rb +114 -0
- data/lib/datadog/ci/itr/runner.rb +134 -11
- data/lib/datadog/ci/itr/skippable.rb +108 -0
- data/lib/datadog/ci/span.rb +16 -0
- data/lib/datadog/ci/test.rb +37 -12
- data/lib/datadog/ci/test_module.rb +2 -2
- data/lib/datadog/ci/test_session.rb +2 -2
- data/lib/datadog/ci/test_suite.rb +2 -2
- data/lib/datadog/ci/test_visibility/null_recorder.rb +4 -1
- data/lib/datadog/ci/test_visibility/recorder.rb +47 -9
- data/lib/datadog/ci/test_visibility/serializers/base.rb +3 -2
- data/lib/datadog/ci/test_visibility/serializers/factories/test_level.rb +3 -3
- data/lib/datadog/ci/test_visibility/serializers/factories/test_suite_level.rb +6 -6
- data/lib/datadog/ci/test_visibility/serializers/test_v2.rb +14 -2
- data/lib/datadog/ci/test_visibility/transport.rb +6 -2
- data/lib/datadog/ci/transport/http.rb +24 -4
- data/lib/datadog/ci/transport/remote_settings_api.rb +14 -6
- data/lib/datadog/ci/utils/configuration.rb +2 -2
- data/lib/datadog/ci/utils/git.rb +6 -67
- data/lib/datadog/ci/utils/parsing.rb +16 -0
- data/lib/datadog/ci/utils/test_run.rb +25 -0
- data/lib/datadog/ci/version.rb +1 -1
- data/lib/datadog/ci/worker.rb +35 -0
- data/lib/datadog/ci.rb +4 -0
- metadata +17 -6
- data/lib/datadog/ci/contrib/minitest/hooks.rb +0 -75
@@ -0,0 +1,114 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "datadog/core/workers/async"
|
4
|
+
require "datadog/core/workers/queue"
|
5
|
+
require "datadog/core/workers/polling"
|
6
|
+
|
7
|
+
require "datadog/core/buffer/cruby"
|
8
|
+
require "datadog/core/buffer/thread_safe"
|
9
|
+
|
10
|
+
require "datadog/core/environment/ext"
|
11
|
+
|
12
|
+
module Datadog
|
13
|
+
module CI
|
14
|
+
module ITR
|
15
|
+
module Coverage
|
16
|
+
class Writer
|
17
|
+
include Core::Workers::Queue
|
18
|
+
include Core::Workers::Polling
|
19
|
+
|
20
|
+
attr_reader :transport
|
21
|
+
|
22
|
+
DEFAULT_BUFFER_MAX_SIZE = 10_000
|
23
|
+
DEFAULT_SHUTDOWN_TIMEOUT = 60
|
24
|
+
|
25
|
+
def initialize(transport:, options: {})
|
26
|
+
@transport = transport
|
27
|
+
|
28
|
+
# Workers::Polling settings
|
29
|
+
self.enabled = options.fetch(:enabled, true)
|
30
|
+
|
31
|
+
# Workers::Async::Thread settings
|
32
|
+
self.fork_policy = Core::Workers::Async::Thread::FORK_POLICY_RESTART
|
33
|
+
|
34
|
+
# Workers::IntervalLoop settings
|
35
|
+
self.loop_base_interval = options[:interval] if options.key?(:interval)
|
36
|
+
self.loop_back_off_ratio = options[:back_off_ratio] if options.key?(:back_off_ratio)
|
37
|
+
self.loop_back_off_max = options[:back_off_max] if options.key?(:back_off_max)
|
38
|
+
|
39
|
+
@buffer_size = options.fetch(:buffer_size, DEFAULT_BUFFER_MAX_SIZE)
|
40
|
+
|
41
|
+
self.buffer = buffer_klass.new(@buffer_size)
|
42
|
+
|
43
|
+
@shutdown_timeout = options.fetch(:shutdown_timeout, DEFAULT_SHUTDOWN_TIMEOUT)
|
44
|
+
|
45
|
+
@stopped = false
|
46
|
+
end
|
47
|
+
|
48
|
+
def write(event)
|
49
|
+
return if @stopped
|
50
|
+
|
51
|
+
# Start worker thread. If the process has forked, it will trigger #after_fork to
|
52
|
+
# reconfigure the worker accordingly.
|
53
|
+
perform
|
54
|
+
|
55
|
+
enqueue(event)
|
56
|
+
end
|
57
|
+
|
58
|
+
def perform(*events)
|
59
|
+
responses = transport.send_events(events)
|
60
|
+
|
61
|
+
if responses.find(&:server_error?)
|
62
|
+
loop_back_off!
|
63
|
+
Datadog.logger.warn { "Encountered server error while sending coverage events" }
|
64
|
+
end
|
65
|
+
|
66
|
+
nil
|
67
|
+
rescue => e
|
68
|
+
Datadog.logger.warn { "Error while sending coverage events: #{e}" }
|
69
|
+
loop_back_off!
|
70
|
+
end
|
71
|
+
|
72
|
+
def stop(force_stop = false, timeout = @shutdown_timeout)
|
73
|
+
@stopped = true
|
74
|
+
|
75
|
+
buffer.close if running?
|
76
|
+
|
77
|
+
super
|
78
|
+
end
|
79
|
+
|
80
|
+
def enqueue(event)
|
81
|
+
buffer.push(event)
|
82
|
+
end
|
83
|
+
|
84
|
+
def dequeue
|
85
|
+
buffer.pop
|
86
|
+
end
|
87
|
+
|
88
|
+
def work_pending?
|
89
|
+
!buffer.empty?
|
90
|
+
end
|
91
|
+
|
92
|
+
def async?
|
93
|
+
true
|
94
|
+
end
|
95
|
+
|
96
|
+
def after_fork
|
97
|
+
# In multiprocess environments, forks will share the same buffer until its written to.
|
98
|
+
# A.K.A. copy-on-write. We don't want forks to write events generated from another process.
|
99
|
+
# Instead, we reset it after the fork. (Make sure any enqueue operations happen after this.)
|
100
|
+
self.buffer = buffer_klass.new(@buffer_size)
|
101
|
+
end
|
102
|
+
|
103
|
+
def buffer_klass
|
104
|
+
if Core::Environment::Ext::RUBY_ENGINE == "ruby"
|
105
|
+
Core::Buffer::CRuby
|
106
|
+
else
|
107
|
+
Core::Buffer::ThreadSafe
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
@@ -1,9 +1,18 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "pp"
|
4
|
+
|
5
|
+
require "datadog/core/utils/forking"
|
6
|
+
|
3
7
|
require_relative "../ext/test"
|
4
8
|
require_relative "../ext/transport"
|
5
9
|
|
6
|
-
require_relative "../
|
10
|
+
require_relative "../git/local_repository"
|
11
|
+
|
12
|
+
require_relative "../utils/parsing"
|
13
|
+
|
14
|
+
require_relative "coverage/event"
|
15
|
+
require_relative "skippable"
|
7
16
|
|
8
17
|
module Datadog
|
9
18
|
module CI
|
@@ -12,26 +21,46 @@ module Datadog
|
|
12
21
|
# Integrates with backend to provide test impact analysis data and
|
13
22
|
# skip tests that are not impacted by the changes
|
14
23
|
class Runner
|
24
|
+
include Core::Utils::Forking
|
25
|
+
|
26
|
+
attr_reader :correlation_id, :skippable_tests, :skipped_tests_count
|
27
|
+
|
15
28
|
def initialize(
|
29
|
+
dd_env:,
|
30
|
+
config_tags: {},
|
31
|
+
api: nil,
|
32
|
+
coverage_writer: nil,
|
16
33
|
enabled: false
|
17
34
|
)
|
18
35
|
@enabled = enabled
|
36
|
+
@api = api
|
37
|
+
@dd_env = dd_env
|
38
|
+
@config_tags = config_tags || {}
|
39
|
+
|
19
40
|
@test_skipping_enabled = false
|
20
41
|
@code_coverage_enabled = false
|
21
42
|
|
43
|
+
@coverage_writer = coverage_writer
|
44
|
+
|
45
|
+
@correlation_id = nil
|
46
|
+
@skippable_tests = []
|
47
|
+
|
48
|
+
@skipped_tests_count = 0
|
49
|
+
@mutex = Mutex.new
|
50
|
+
|
22
51
|
Datadog.logger.debug("ITR Runner initialized with enabled: #{@enabled}")
|
23
52
|
end
|
24
53
|
|
25
|
-
def configure(remote_configuration, test_session)
|
54
|
+
def configure(remote_configuration, test_session:, git_tree_upload_worker:)
|
26
55
|
Datadog.logger.debug("Configuring ITR Runner with remote configuration: #{remote_configuration}")
|
27
56
|
|
28
|
-
@enabled = convert_to_bool(
|
57
|
+
@enabled = Utils::Parsing.convert_to_bool(
|
29
58
|
remote_configuration.fetch(Ext::Transport::DD_API_SETTINGS_RESPONSE_ITR_ENABLED_KEY, false)
|
30
59
|
)
|
31
|
-
@test_skipping_enabled = @enabled && convert_to_bool(
|
60
|
+
@test_skipping_enabled = @enabled && Utils::Parsing.convert_to_bool(
|
32
61
|
remote_configuration.fetch(Ext::Transport::DD_API_SETTINGS_RESPONSE_TESTS_SKIPPING_KEY, false)
|
33
62
|
)
|
34
|
-
@code_coverage_enabled = @enabled && convert_to_bool(
|
63
|
+
@code_coverage_enabled = @enabled && Utils::Parsing.convert_to_bool(
|
35
64
|
remote_configuration.fetch(Ext::Transport::DD_API_SETTINGS_RESPONSE_CODE_COVERAGE_KEY, false)
|
36
65
|
)
|
37
66
|
|
@@ -46,6 +75,8 @@ module Datadog
|
|
46
75
|
load_datadog_cov! if @code_coverage_enabled
|
47
76
|
|
48
77
|
Datadog.logger.debug("Configured ITR Runner with enabled: #{@enabled}, skipping_tests: #{@test_skipping_enabled}, code_coverage: #{@code_coverage_enabled}")
|
78
|
+
|
79
|
+
fetch_skippable_tests(test_session: test_session, git_tree_upload_worker: git_tree_upload_worker)
|
49
80
|
end
|
50
81
|
|
51
82
|
def enabled?
|
@@ -60,22 +91,93 @@ module Datadog
|
|
60
91
|
@code_coverage_enabled
|
61
92
|
end
|
62
93
|
|
63
|
-
def start_coverage
|
94
|
+
def start_coverage(test)
|
64
95
|
return if !enabled? || !code_coverage?
|
65
96
|
|
66
97
|
coverage_collector&.start
|
67
98
|
end
|
68
99
|
|
69
|
-
def stop_coverage(
|
100
|
+
def stop_coverage(test)
|
70
101
|
return if !enabled? || !code_coverage?
|
71
102
|
|
72
|
-
coverage_collector&.stop
|
103
|
+
coverage = coverage_collector&.stop
|
104
|
+
return if coverage.nil? || coverage.empty?
|
105
|
+
|
106
|
+
return if test.skipped?
|
107
|
+
|
108
|
+
test_source_file = test.source_file
|
109
|
+
|
110
|
+
# cucumber's gherkin files are not covered by the code coverage collector
|
111
|
+
ensure_test_source_covered(test_source_file, coverage) unless test_source_file.nil?
|
112
|
+
|
113
|
+
event = Coverage::Event.new(
|
114
|
+
test_id: test.id.to_s,
|
115
|
+
test_suite_id: test.test_suite_id.to_s,
|
116
|
+
test_session_id: test.test_session_id.to_s,
|
117
|
+
coverage: coverage
|
118
|
+
)
|
119
|
+
|
120
|
+
Datadog.logger.debug { "Writing coverage event \n #{event.pretty_inspect}" }
|
121
|
+
|
122
|
+
write(event)
|
123
|
+
|
124
|
+
event
|
125
|
+
end
|
126
|
+
|
127
|
+
def mark_if_skippable(test)
|
128
|
+
return if !enabled? || !skipping_tests?
|
129
|
+
|
130
|
+
skippable_test_id = Utils::TestRun.skippable_test_id(test.name, test.test_suite_name, test.parameters)
|
131
|
+
if @skippable_tests.include?(skippable_test_id)
|
132
|
+
if forked?
|
133
|
+
Datadog.logger.warn { "ITR is not supported for forking test runners yet" }
|
134
|
+
return
|
135
|
+
end
|
136
|
+
|
137
|
+
test.set_tag(Ext::Test::TAG_ITR_SKIPPED_BY_ITR, "true")
|
138
|
+
|
139
|
+
Datadog.logger.debug { "Marked test as skippable: #{skippable_test_id}" }
|
140
|
+
else
|
141
|
+
Datadog.logger.debug { "Test is not skippable: #{skippable_test_id}" }
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def count_skipped_test(test)
|
146
|
+
return if !test.skipped? || !test.skipped_by_itr?
|
147
|
+
|
148
|
+
if forked?
|
149
|
+
Datadog.logger.warn { "ITR is not supported for forking test runners yet" }
|
150
|
+
return
|
151
|
+
end
|
152
|
+
|
153
|
+
@mutex.synchronize do
|
154
|
+
@skipped_tests_count += 1
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def write_test_session_tags(test_session)
|
159
|
+
return if !enabled?
|
160
|
+
|
161
|
+
Datadog.logger.debug { "Finished ITR session with test skipping enabled: #{@test_skipping_enabled}" }
|
162
|
+
Datadog.logger.debug { "#{@skipped_tests_count} tests were skipped" }
|
163
|
+
|
164
|
+
test_session.set_tag(Ext::Test::TAG_ITR_TESTS_SKIPPED, @skipped_tests_count.positive?.to_s)
|
165
|
+
test_session.set_tag(Ext::Test::TAG_ITR_TEST_SKIPPING_COUNT, @skipped_tests_count)
|
166
|
+
end
|
167
|
+
|
168
|
+
def shutdown!
|
169
|
+
@coverage_writer&.stop
|
73
170
|
end
|
74
171
|
|
75
172
|
private
|
76
173
|
|
174
|
+
def write(event)
|
175
|
+
# skip sending events if writer is not configured
|
176
|
+
@coverage_writer&.write(event)
|
177
|
+
end
|
178
|
+
|
77
179
|
def coverage_collector
|
78
|
-
Thread.current[:dd_coverage_collector] ||= Coverage::DDCov.new(root:
|
180
|
+
Thread.current[:dd_coverage_collector] ||= Coverage::DDCov.new(root: Git::LocalRepository.root)
|
79
181
|
end
|
80
182
|
|
81
183
|
def load_datadog_cov!
|
@@ -86,8 +188,29 @@ module Datadog
|
|
86
188
|
@code_coverage_enabled = false
|
87
189
|
end
|
88
190
|
|
89
|
-
def
|
90
|
-
|
191
|
+
def ensure_test_source_covered(test_source_file, coverage)
|
192
|
+
absolute_test_source_file_path = File.join(Git::LocalRepository.root, test_source_file)
|
193
|
+
return if coverage.key?(absolute_test_source_file_path)
|
194
|
+
|
195
|
+
coverage[absolute_test_source_file_path] = true
|
196
|
+
end
|
197
|
+
|
198
|
+
def fetch_skippable_tests(test_session:, git_tree_upload_worker:)
|
199
|
+
return unless skipping_tests?
|
200
|
+
|
201
|
+
# we can only request skippable tests if git metadata is already uploaded
|
202
|
+
git_tree_upload_worker.wait_until_done
|
203
|
+
|
204
|
+
skippable_response =
|
205
|
+
Skippable.new(api: @api, dd_env: @dd_env, config_tags: @config_tags)
|
206
|
+
.fetch_skippable_tests(test_session)
|
207
|
+
|
208
|
+
@correlation_id = skippable_response.correlation_id
|
209
|
+
@skippable_tests = skippable_response.tests
|
210
|
+
|
211
|
+
Datadog.logger.debug { "Fetched skippable tests: \n #{@skippable_tests}" }
|
212
|
+
Datadog.logger.debug { "Found #{@skippable_tests.count} skippable tests." }
|
213
|
+
Datadog.logger.debug { "ITR correlation ID: #{@correlation_id}" }
|
91
214
|
end
|
92
215
|
end
|
93
216
|
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "json"
|
4
|
+
|
5
|
+
require_relative "../ext/transport"
|
6
|
+
require_relative "../ext/test"
|
7
|
+
require_relative "../utils/test_run"
|
8
|
+
|
9
|
+
module Datadog
|
10
|
+
module CI
|
11
|
+
module ITR
|
12
|
+
class Skippable
|
13
|
+
class Response
|
14
|
+
def initialize(http_response)
|
15
|
+
@http_response = http_response
|
16
|
+
@json = nil
|
17
|
+
end
|
18
|
+
|
19
|
+
def ok?
|
20
|
+
resp = @http_response
|
21
|
+
!resp.nil? && resp.ok?
|
22
|
+
end
|
23
|
+
|
24
|
+
def correlation_id
|
25
|
+
payload.dig("meta", "correlation_id")
|
26
|
+
end
|
27
|
+
|
28
|
+
def tests
|
29
|
+
res = Set.new
|
30
|
+
|
31
|
+
payload.fetch("data", [])
|
32
|
+
.each do |test_data|
|
33
|
+
next unless test_data["type"] == Ext::Test::ITR_TEST_SKIPPING_MODE
|
34
|
+
|
35
|
+
attrs = test_data["attributes"] || {}
|
36
|
+
res << Utils::TestRun.skippable_test_id(attrs["name"], attrs["suite"], attrs["parameters"])
|
37
|
+
end
|
38
|
+
|
39
|
+
res
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def payload
|
45
|
+
cached = @json
|
46
|
+
return cached unless cached.nil?
|
47
|
+
|
48
|
+
resp = @http_response
|
49
|
+
return @json = {} if resp.nil? || !ok?
|
50
|
+
|
51
|
+
begin
|
52
|
+
@json = JSON.parse(resp.payload)
|
53
|
+
rescue JSON::ParserError => e
|
54
|
+
Datadog.logger.error("Failed to parse skippable tests response payload: #{e}. Payload was: #{resp.payload}")
|
55
|
+
@json = {}
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def initialize(dd_env:, api: nil, config_tags: {})
|
61
|
+
@api = api
|
62
|
+
@dd_env = dd_env
|
63
|
+
@config_tags = config_tags
|
64
|
+
end
|
65
|
+
|
66
|
+
def fetch_skippable_tests(test_session)
|
67
|
+
api = @api
|
68
|
+
return Response.new(nil) unless api
|
69
|
+
|
70
|
+
request_payload = payload(test_session)
|
71
|
+
Datadog.logger.debug("Fetching skippable tests with request: #{request_payload}")
|
72
|
+
|
73
|
+
http_response = api.api_request(
|
74
|
+
path: Ext::Transport::DD_API_SKIPPABLE_TESTS_PATH,
|
75
|
+
payload: request_payload
|
76
|
+
)
|
77
|
+
|
78
|
+
Response.new(http_response)
|
79
|
+
end
|
80
|
+
|
81
|
+
private
|
82
|
+
|
83
|
+
def payload(test_session)
|
84
|
+
{
|
85
|
+
"data" => {
|
86
|
+
"type" => Ext::Transport::DD_API_SKIPPABLE_TESTS_TYPE,
|
87
|
+
"attributes" => {
|
88
|
+
"test_level" => Ext::Test::ITR_TEST_SKIPPING_MODE,
|
89
|
+
"service" => test_session.service,
|
90
|
+
"env" => @dd_env,
|
91
|
+
"repository_url" => test_session.git_repository_url,
|
92
|
+
"sha" => test_session.git_commit_sha,
|
93
|
+
"configurations" => {
|
94
|
+
Ext::Test::TAG_OS_PLATFORM => test_session.os_platform,
|
95
|
+
Ext::Test::TAG_OS_ARCHITECTURE => test_session.os_architecture,
|
96
|
+
Ext::Test::TAG_OS_VERSION => test_session.os_version,
|
97
|
+
Ext::Test::TAG_RUNTIME_NAME => test_session.runtime_name,
|
98
|
+
Ext::Test::TAG_RUNTIME_VERSION => test_session.runtime_version,
|
99
|
+
"custom" => @config_tags
|
100
|
+
}
|
101
|
+
}
|
102
|
+
}
|
103
|
+
}.to_json
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
data/lib/datadog/ci/span.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "datadog/core/environment/platform"
|
4
|
+
|
3
5
|
require_relative "ext/test"
|
4
6
|
require_relative "utils/test_run"
|
5
7
|
|
@@ -100,6 +102,13 @@ module Datadog
|
|
100
102
|
tracer_span.set_tag(key, value)
|
101
103
|
end
|
102
104
|
|
105
|
+
# Removes tag by key.
|
106
|
+
# @param [String] key the key of the tag.
|
107
|
+
# @return [void]
|
108
|
+
def clear_tag(key)
|
109
|
+
tracer_span.clear_tag(key)
|
110
|
+
end
|
111
|
+
|
103
112
|
# Sets metric value by key.
|
104
113
|
# @param [String] key the key of the metric.
|
105
114
|
# @param [Numeric] value the value of the metric.
|
@@ -151,6 +160,12 @@ module Datadog
|
|
151
160
|
tracer_span.get_tag(Ext::Test::TAG_OS_PLATFORM)
|
152
161
|
end
|
153
162
|
|
163
|
+
# Returns the OS version extracted from the environment.
|
164
|
+
# @return [String] OS version.
|
165
|
+
def os_version
|
166
|
+
tracer_span.get_tag(Ext::Test::TAG_OS_VERSION)
|
167
|
+
end
|
168
|
+
|
154
169
|
# Returns the runtime name extracted from the environment.
|
155
170
|
# @return [String] runtime name.
|
156
171
|
def runtime_name
|
@@ -166,6 +181,7 @@ module Datadog
|
|
166
181
|
def set_environment_runtime_tags
|
167
182
|
tracer_span.set_tag(Ext::Test::TAG_OS_ARCHITECTURE, ::RbConfig::CONFIG["host_cpu"])
|
168
183
|
tracer_span.set_tag(Ext::Test::TAG_OS_PLATFORM, ::RbConfig::CONFIG["host_os"])
|
184
|
+
tracer_span.set_tag(Ext::Test::TAG_OS_VERSION, Core::Environment::Platform.kernel_release)
|
169
185
|
tracer_span.set_tag(Ext::Test::TAG_RUNTIME_NAME, Core::Environment::Ext::LANG_ENGINE)
|
170
186
|
tracer_span.set_tag(Ext::Test::TAG_RUNTIME_VERSION, Core::Environment::Ext::ENGINE_VERSION)
|
171
187
|
tracer_span.set_tag(Ext::Test::TAG_COMMAND, Utils::TestRun.command)
|
data/lib/datadog/ci/test.rb
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
require "json"
|
4
4
|
|
5
5
|
require_relative "span"
|
6
|
+
require_relative "utils/test_run"
|
6
7
|
|
7
8
|
module Datadog
|
8
9
|
module CI
|
@@ -18,9 +19,9 @@ module Datadog
|
|
18
19
|
# Finishes the current test.
|
19
20
|
# @return [void]
|
20
21
|
def finish
|
21
|
-
super
|
22
|
-
|
23
22
|
recorder.deactivate_test
|
23
|
+
|
24
|
+
super
|
24
25
|
end
|
25
26
|
|
26
27
|
# Running test suite that this test is part of (if any).
|
@@ -62,6 +63,30 @@ module Datadog
|
|
62
63
|
get_tag(Ext::Test::TAG_SOURCE_FILE)
|
63
64
|
end
|
64
65
|
|
66
|
+
# Returns "true" if the test is skipped by the intelligent test runner.
|
67
|
+
# @return [Boolean] true if the test is skipped by the intelligent test runner, false otherwise.
|
68
|
+
def skipped_by_itr?
|
69
|
+
get_tag(Ext::Test::TAG_ITR_SKIPPED_BY_ITR) == "true"
|
70
|
+
end
|
71
|
+
|
72
|
+
# Marks this test as unskippable by the intelligent test runner.
|
73
|
+
# This must be done before the test execution starts.
|
74
|
+
#
|
75
|
+
# Examples of tests that should be unskippable:
|
76
|
+
# - tests that read files from disk
|
77
|
+
# - tests that make network requests
|
78
|
+
# - tests that call external processes
|
79
|
+
# - tests that use forking or threading
|
80
|
+
#
|
81
|
+
# @return [void]
|
82
|
+
def itr_unskippable!
|
83
|
+
set_tag(Ext::Test::TAG_ITR_UNSKIPPABLE, "true")
|
84
|
+
if skipped_by_itr?
|
85
|
+
clear_tag(Ext::Test::TAG_ITR_SKIPPED_BY_ITR)
|
86
|
+
set_tag(Ext::Test::TAG_ITR_FORCED_RUN, "true")
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
65
90
|
# Sets the status of the span to "pass".
|
66
91
|
# @return [void]
|
67
92
|
def passed!
|
@@ -89,7 +114,7 @@ module Datadog
|
|
89
114
|
record_test_result(Ext::Test::Status::SKIP)
|
90
115
|
end
|
91
116
|
|
92
|
-
# Sets the parameters for this test (e.g. Cucumber example or RSpec
|
117
|
+
# Sets the parameters for this test (e.g. Cucumber example or RSpec specs).
|
93
118
|
# Parameters are needed to compute test fingerprint to distinguish between different tests having same names.
|
94
119
|
#
|
95
120
|
# @param [Hash] arguments the arguments that test accepts as key-value hash
|
@@ -98,15 +123,15 @@ module Datadog
|
|
98
123
|
def set_parameters(arguments, metadata = {})
|
99
124
|
return if arguments.nil?
|
100
125
|
|
101
|
-
set_tag(
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
)
|
126
|
+
set_tag(Ext::Test::TAG_PARAMETERS, Utils::TestRun.test_parameters(arguments: arguments, metadata: metadata))
|
127
|
+
end
|
128
|
+
|
129
|
+
# Gets the parameters for this test (e.g. Cucumber example or RSpec specs) as a serialized JSON.
|
130
|
+
#
|
131
|
+
# @return [String] the serialized JSON of the parameters
|
132
|
+
# @return [nil] if this test does not have parameters
|
133
|
+
def parameters
|
134
|
+
get_tag(Ext::Test::TAG_PARAMETERS)
|
110
135
|
end
|
111
136
|
|
112
137
|
private
|
@@ -23,7 +23,7 @@ module Datadog
|
|
23
23
|
skip_tracing(block)
|
24
24
|
end
|
25
25
|
|
26
|
-
def trace(
|
26
|
+
def trace(span_name, type: "span", tags: {}, &block)
|
27
27
|
skip_tracing(block)
|
28
28
|
end
|
29
29
|
|
@@ -42,6 +42,9 @@ module Datadog
|
|
42
42
|
def active_test_suite(test_suite_name)
|
43
43
|
end
|
44
44
|
|
45
|
+
def shutdown!
|
46
|
+
end
|
47
|
+
|
45
48
|
private
|
46
49
|
|
47
50
|
def skip_tracing(block = nil)
|