datadog-ci 0.6.0 → 0.7.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 +45 -2
- data/README.md +1 -1
- data/lib/datadog/ci/codeowners/matcher.rb +102 -0
- data/lib/datadog/ci/codeowners/parser.rb +42 -0
- data/lib/datadog/ci/codeowners/rule.rb +33 -0
- data/lib/datadog/ci/concurrent_span.rb +2 -1
- data/lib/datadog/ci/configuration/components.rb +5 -5
- data/lib/datadog/ci/configuration/settings.rb +15 -0
- data/lib/datadog/ci/contrib/cucumber/configuration/settings.rb +4 -1
- data/lib/datadog/ci/contrib/cucumber/formatter.rb +68 -37
- data/lib/datadog/ci/contrib/cucumber/instrumentation.rb +2 -1
- data/lib/datadog/ci/contrib/minitest/configuration/settings.rb +4 -1
- data/lib/datadog/ci/contrib/minitest/helpers.rb +2 -1
- data/lib/datadog/ci/contrib/minitest/hooks.rb +9 -22
- data/lib/datadog/ci/contrib/minitest/patcher.rb +9 -6
- data/lib/datadog/ci/contrib/minitest/reporter.rb +50 -0
- data/lib/datadog/ci/contrib/minitest/runnable.rb +1 -1
- data/lib/datadog/ci/contrib/minitest/runner.rb +41 -0
- data/lib/datadog/ci/contrib/rspec/configuration/settings.rb +4 -1
- data/lib/datadog/ci/contrib/rspec/example.rb +55 -14
- data/lib/datadog/ci/contrib/rspec/example_group.rb +12 -7
- data/lib/datadog/ci/contrib/rspec/patcher.rb +10 -1
- data/lib/datadog/ci/contrib/rspec/runner.rb +7 -7
- data/lib/datadog/ci/ext/app_types.rb +2 -0
- data/lib/datadog/ci/ext/environment/providers/local_git.rb +8 -29
- data/lib/datadog/ci/ext/settings.rb +1 -0
- data/lib/datadog/ci/ext/test.rb +19 -8
- data/lib/datadog/ci/span.rb +9 -2
- data/lib/datadog/ci/test.rb +67 -2
- data/lib/datadog/ci/test_module.rb +1 -1
- data/lib/datadog/ci/test_session.rb +2 -2
- data/lib/datadog/ci/test_suite.rb +53 -2
- data/lib/datadog/ci/test_visibility/context/local.rb +3 -9
- data/lib/datadog/ci/test_visibility/null_recorder.rb +2 -22
- data/lib/datadog/ci/test_visibility/recorder.rb +25 -19
- data/lib/datadog/ci/test_visibility/serializers/base.rb +6 -5
- data/lib/datadog/ci/test_visibility/serializers/span.rb +1 -1
- data/lib/datadog/ci/test_visibility/serializers/test_module.rb +1 -1
- data/lib/datadog/ci/test_visibility/serializers/test_session.rb +1 -1
- data/lib/datadog/ci/test_visibility/serializers/test_suite.rb +1 -1
- data/lib/datadog/ci/test_visibility/serializers/test_v1.rb +1 -1
- data/lib/datadog/ci/utils/configuration.rb +15 -0
- data/lib/datadog/ci/utils/git.rb +70 -0
- data/lib/datadog/ci/version.rb +1 -1
- data/lib/datadog/ci.rb +40 -56
- metadata +9 -89
- data/lib/datadog/ci/contrib/minitest/plugin.rb +0 -73
- data/lib/datadog/ci/null_span.rb +0 -63
- data/sig/datadog/ci/concurrent_span.rbs +0 -23
- data/sig/datadog/ci/configuration/components.rbs +0 -21
- data/sig/datadog/ci/configuration/extensions.rbs +0 -9
- data/sig/datadog/ci/configuration/settings.rbs +0 -16
- data/sig/datadog/ci/contrib/cucumber/configuration/settings.rbs +0 -12
- data/sig/datadog/ci/contrib/cucumber/ext.rbs +0 -21
- data/sig/datadog/ci/contrib/cucumber/formatter.rbs +0 -48
- data/sig/datadog/ci/contrib/cucumber/instrumentation.rbs +0 -16
- data/sig/datadog/ci/contrib/cucumber/integration.rbs +0 -26
- data/sig/datadog/ci/contrib/cucumber/patcher.rbs +0 -15
- data/sig/datadog/ci/contrib/integration.rbs +0 -44
- data/sig/datadog/ci/contrib/minitest/configuration/settings.rbs +0 -12
- data/sig/datadog/ci/contrib/minitest/ext.rbs +0 -19
- data/sig/datadog/ci/contrib/minitest/helpers.rbs +0 -13
- data/sig/datadog/ci/contrib/minitest/hooks.rbs +0 -27
- data/sig/datadog/ci/contrib/minitest/integration.rbs +0 -26
- data/sig/datadog/ci/contrib/minitest/patcher.rbs +0 -15
- data/sig/datadog/ci/contrib/minitest/plugin.rbs +0 -31
- data/sig/datadog/ci/contrib/minitest/runnable.rbs +0 -24
- data/sig/datadog/ci/contrib/rspec/configuration/settings.rbs +0 -12
- data/sig/datadog/ci/contrib/rspec/example.rbs +0 -20
- data/sig/datadog/ci/contrib/rspec/example_group.rbs +0 -21
- data/sig/datadog/ci/contrib/rspec/ext.rbs +0 -17
- data/sig/datadog/ci/contrib/rspec/integration.rbs +0 -26
- data/sig/datadog/ci/contrib/rspec/patcher.rbs +0 -15
- data/sig/datadog/ci/contrib/rspec/runner.rbs +0 -21
- data/sig/datadog/ci/contrib/settings.rbs +0 -25
- data/sig/datadog/ci/ext/app_types.rbs +0 -14
- data/sig/datadog/ci/ext/environment/extractor.rbs +0 -25
- data/sig/datadog/ci/ext/environment/providers/appveyor.rbs +0 -48
- data/sig/datadog/ci/ext/environment/providers/aws_code_pipeline.rbs +0 -19
- data/sig/datadog/ci/ext/environment/providers/azure.rbs +0 -56
- data/sig/datadog/ci/ext/environment/providers/base.rbs +0 -71
- data/sig/datadog/ci/ext/environment/providers/bitbucket.rbs +0 -37
- data/sig/datadog/ci/ext/environment/providers/bitrise.rbs +0 -41
- data/sig/datadog/ci/ext/environment/providers/buddy.rbs +0 -37
- data/sig/datadog/ci/ext/environment/providers/buildkite.rbs +0 -45
- data/sig/datadog/ci/ext/environment/providers/circleci.rbs +0 -41
- data/sig/datadog/ci/ext/environment/providers/codefresh.rbs +0 -25
- data/sig/datadog/ci/ext/environment/providers/github_actions.rbs +0 -42
- data/sig/datadog/ci/ext/environment/providers/gitlab.rbs +0 -57
- data/sig/datadog/ci/ext/environment/providers/jenkins.rbs +0 -35
- data/sig/datadog/ci/ext/environment/providers/local_git.rbs +0 -66
- data/sig/datadog/ci/ext/environment/providers/teamcity.rbs +0 -17
- data/sig/datadog/ci/ext/environment/providers/travis.rbs +0 -35
- data/sig/datadog/ci/ext/environment/providers/user_defined_tags.rbs +0 -33
- data/sig/datadog/ci/ext/environment/providers.rbs +0 -13
- data/sig/datadog/ci/ext/environment.rbs +0 -44
- data/sig/datadog/ci/ext/git.rbs +0 -53
- data/sig/datadog/ci/ext/settings.rbs +0 -14
- data/sig/datadog/ci/ext/test.rbs +0 -60
- data/sig/datadog/ci/ext/transport.rbs +0 -29
- data/sig/datadog/ci/null_span.rbs +0 -37
- data/sig/datadog/ci/span.rbs +0 -47
- data/sig/datadog/ci/test.rbs +0 -12
- data/sig/datadog/ci/test_module.rbs +0 -6
- data/sig/datadog/ci/test_session.rbs +0 -9
- data/sig/datadog/ci/test_suite.rbs +0 -6
- data/sig/datadog/ci/test_visibility/context/global.rbs +0 -39
- data/sig/datadog/ci/test_visibility/context/local.rbs +0 -23
- data/sig/datadog/ci/test_visibility/flush.rbs +0 -17
- data/sig/datadog/ci/test_visibility/null_recorder.rbs +0 -45
- data/sig/datadog/ci/test_visibility/recorder.rbs +0 -85
- data/sig/datadog/ci/test_visibility/serializers/base.rbs +0 -94
- data/sig/datadog/ci/test_visibility/serializers/factories/test_level.rbs +0 -13
- data/sig/datadog/ci/test_visibility/serializers/factories/test_suite_level.rbs +0 -13
- data/sig/datadog/ci/test_visibility/serializers/span.rbs +0 -18
- data/sig/datadog/ci/test_visibility/serializers/test_module.rbs +0 -26
- data/sig/datadog/ci/test_visibility/serializers/test_session.rbs +0 -26
- data/sig/datadog/ci/test_visibility/serializers/test_suite.rbs +0 -26
- data/sig/datadog/ci/test_visibility/serializers/test_v1.rbs +0 -23
- data/sig/datadog/ci/test_visibility/serializers/test_v2.rbs +0 -25
- data/sig/datadog/ci/test_visibility/transport.rbs +0 -35
- data/sig/datadog/ci/transport/api/base.rbs +0 -21
- data/sig/datadog/ci/transport/api/builder.rbs +0 -12
- data/sig/datadog/ci/transport/api/ci_test_cycle.rbs +0 -21
- data/sig/datadog/ci/transport/api/evp_proxy.rbs +0 -19
- data/sig/datadog/ci/transport/gzip.rbs +0 -9
- data/sig/datadog/ci/transport/http.rbs +0 -36
- data/sig/datadog/ci/utils/git.rbs +0 -11
- data/sig/datadog/ci/utils/test_run.rbs +0 -11
- data/sig/datadog/ci/utils/url.rbs +0 -9
- data/sig/datadog/ci/version.rbs +0 -16
- data/sig/datadog/ci.rbs +0 -37
@@ -13,12 +13,63 @@ module Datadog
|
|
13
13
|
#
|
14
14
|
# @public_api
|
15
15
|
class TestSuite < ConcurrentSpan
|
16
|
+
def initialize(tracer_span)
|
17
|
+
super
|
18
|
+
|
19
|
+
@test_suite_stats = Hash.new(0)
|
20
|
+
end
|
21
|
+
|
16
22
|
# Finishes this test suite.
|
17
23
|
# @return [void]
|
18
24
|
def finish
|
19
|
-
|
25
|
+
synchronize do
|
26
|
+
# we try to derive test suite status from execution stats if no status was set explicitly
|
27
|
+
set_status_from_stats! if undefined?
|
28
|
+
|
29
|
+
super
|
30
|
+
|
31
|
+
recorder.deactivate_test_suite(name)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# @internal
|
36
|
+
def record_test_result(datadog_test_status)
|
37
|
+
synchronize do
|
38
|
+
@test_suite_stats[datadog_test_status] += 1
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# @internal
|
43
|
+
def passed_tests_count
|
44
|
+
synchronize do
|
45
|
+
@test_suite_stats[Ext::Test::Status::PASS]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# @internal
|
50
|
+
def skipped_tests_count
|
51
|
+
synchronize do
|
52
|
+
@test_suite_stats[Ext::Test::Status::SKIP]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# @internal
|
57
|
+
def failed_tests_count
|
58
|
+
synchronize do
|
59
|
+
@test_suite_stats[Ext::Test::Status::FAIL]
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
20
64
|
|
21
|
-
|
65
|
+
def set_status_from_stats!
|
66
|
+
if failed_tests_count > 0
|
67
|
+
failed!
|
68
|
+
elsif passed_tests_count == 0
|
69
|
+
skipped!
|
70
|
+
else
|
71
|
+
passed!
|
72
|
+
end
|
22
73
|
end
|
23
74
|
end
|
24
75
|
end
|
@@ -11,7 +11,7 @@ module Datadog
|
|
11
11
|
self.active_test = nil
|
12
12
|
end
|
13
13
|
|
14
|
-
def activate_test
|
14
|
+
def activate_test(test)
|
15
15
|
raise "Nested tests are not supported. Currently active test: #{active_test}" unless active_test.nil?
|
16
16
|
|
17
17
|
if block_given?
|
@@ -26,14 +26,8 @@ module Datadog
|
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
|
-
def deactivate_test
|
30
|
-
|
31
|
-
|
32
|
-
if active_test == test
|
33
|
-
self.active_test = nil
|
34
|
-
else
|
35
|
-
raise "Trying to deactivate test #{test}, but currently active test is #{active_test}"
|
36
|
-
end
|
29
|
+
def deactivate_test
|
30
|
+
self.active_test = nil
|
37
31
|
end
|
38
32
|
|
39
33
|
def active_test
|
@@ -23,7 +23,7 @@ module Datadog
|
|
23
23
|
skip_tracing(block)
|
24
24
|
end
|
25
25
|
|
26
|
-
def trace(
|
26
|
+
def trace(type, span_name, tags: {}, &block)
|
27
27
|
skip_tracing(block)
|
28
28
|
end
|
29
29
|
|
@@ -42,30 +42,10 @@ module Datadog
|
|
42
42
|
def active_test_suite(test_suite_name)
|
43
43
|
end
|
44
44
|
|
45
|
-
def deactivate_test(test)
|
46
|
-
end
|
47
|
-
|
48
|
-
def deactivate_test_session
|
49
|
-
end
|
50
|
-
|
51
|
-
def deactivate_test_module
|
52
|
-
end
|
53
|
-
|
54
|
-
def deactivate_test_suite(test_suite_name)
|
55
|
-
end
|
56
|
-
|
57
45
|
private
|
58
46
|
|
59
47
|
def skip_tracing(block = nil)
|
60
|
-
if block
|
61
|
-
block.call(null_span)
|
62
|
-
else
|
63
|
-
null_span
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
def null_span
|
68
|
-
@null_span ||= NullSpan.new
|
48
|
+
block.call(nil) if block
|
69
49
|
end
|
70
50
|
end
|
71
51
|
end
|
@@ -8,12 +8,13 @@ require "rbconfig"
|
|
8
8
|
require_relative "context/global"
|
9
9
|
require_relative "context/local"
|
10
10
|
|
11
|
+
require_relative "../codeowners/parser"
|
11
12
|
require_relative "../ext/app_types"
|
12
13
|
require_relative "../ext/test"
|
13
14
|
require_relative "../ext/environment"
|
15
|
+
require_relative "../utils/git"
|
14
16
|
|
15
17
|
require_relative "../span"
|
16
|
-
require_relative "../null_span"
|
17
18
|
require_relative "../test"
|
18
19
|
require_relative "../test_session"
|
19
20
|
require_relative "../test_module"
|
@@ -27,12 +28,16 @@ module Datadog
|
|
27
28
|
class Recorder
|
28
29
|
attr_reader :environment_tags, :test_suite_level_visibility_enabled
|
29
30
|
|
30
|
-
def initialize(
|
31
|
+
def initialize(
|
32
|
+
test_suite_level_visibility_enabled: false,
|
33
|
+
codeowners: Codeowners::Parser.new(Utils::Git.root).parse
|
34
|
+
)
|
31
35
|
@test_suite_level_visibility_enabled = test_suite_level_visibility_enabled
|
32
36
|
|
33
37
|
@environment_tags = Ext::Environment.tags(ENV).freeze
|
34
38
|
@local_context = Context::Local.new
|
35
39
|
@global_context = Context::Global.new
|
40
|
+
@codeowners = codeowners
|
36
41
|
end
|
37
42
|
|
38
43
|
def start_test_session(service: nil, tags: {})
|
@@ -88,6 +93,7 @@ module Datadog
|
|
88
93
|
set_suite_context(tags, name: test_suite_name)
|
89
94
|
|
90
95
|
tags[Ext::Test::TAG_NAME] = test_name
|
96
|
+
tags[Ext::Test::TAG_TYPE] ||= Ext::Test::Type::TEST
|
91
97
|
|
92
98
|
span_options = build_span_options(
|
93
99
|
service,
|
@@ -101,7 +107,7 @@ module Datadog
|
|
101
107
|
start_datadog_tracer_span(test_name, span_options) do |tracer_span|
|
102
108
|
test = build_test(tracer_span, tags)
|
103
109
|
|
104
|
-
@local_context.activate_test
|
110
|
+
@local_context.activate_test(test) do
|
105
111
|
block.call(test)
|
106
112
|
end
|
107
113
|
end
|
@@ -109,15 +115,15 @@ module Datadog
|
|
109
115
|
tracer_span = start_datadog_tracer_span(test_name, span_options)
|
110
116
|
|
111
117
|
test = build_test(tracer_span, tags)
|
112
|
-
@local_context.activate_test
|
118
|
+
@local_context.activate_test(test)
|
113
119
|
test
|
114
120
|
end
|
115
121
|
end
|
116
122
|
|
117
|
-
def trace(
|
123
|
+
def trace(span_name, type: "span", tags: {}, &block)
|
118
124
|
span_options = build_span_options(
|
119
125
|
nil, # service name is completely optional for custom spans
|
120
|
-
|
126
|
+
type,
|
121
127
|
{resource: span_name}
|
122
128
|
)
|
123
129
|
|
@@ -153,8 +159,8 @@ module Datadog
|
|
153
159
|
@global_context.active_test_suite(test_suite_name)
|
154
160
|
end
|
155
161
|
|
156
|
-
def deactivate_test
|
157
|
-
@local_context.deactivate_test
|
162
|
+
def deactivate_test
|
163
|
+
@local_context.deactivate_test
|
158
164
|
end
|
159
165
|
|
160
166
|
def deactivate_test_session
|
@@ -172,11 +178,7 @@ module Datadog
|
|
172
178
|
private
|
173
179
|
|
174
180
|
def skip_tracing(block = nil)
|
175
|
-
if block
|
176
|
-
block.call(null_span)
|
177
|
-
else
|
178
|
-
null_span
|
179
|
-
end
|
181
|
+
block.call(nil) if block
|
180
182
|
end
|
181
183
|
|
182
184
|
# Sets trace's origin to ciapp-test
|
@@ -206,6 +208,8 @@ module Datadog
|
|
206
208
|
test = Test.new(tracer_span)
|
207
209
|
set_initial_tags(test, tags)
|
208
210
|
validate_test_suite_level_visibility_correctness(test)
|
211
|
+
set_codeowners(test)
|
212
|
+
|
209
213
|
test
|
210
214
|
end
|
211
215
|
|
@@ -215,9 +219,9 @@ module Datadog
|
|
215
219
|
span
|
216
220
|
end
|
217
221
|
|
218
|
-
def build_span_options(service,
|
222
|
+
def build_span_options(service, type, other_options = {})
|
219
223
|
other_options[:service] = service || @global_context.service
|
220
|
-
other_options[:
|
224
|
+
other_options[:type] = type
|
221
225
|
|
222
226
|
other_options
|
223
227
|
end
|
@@ -251,6 +255,12 @@ module Datadog
|
|
251
255
|
end
|
252
256
|
end
|
253
257
|
|
258
|
+
def set_codeowners(test)
|
259
|
+
source = test.source_file
|
260
|
+
owners = @codeowners.list_owners(source) if source
|
261
|
+
test.set_tag(Ext::Test::TAG_CODEOWNERS, owners) unless owners.nil?
|
262
|
+
end
|
263
|
+
|
254
264
|
def set_suite_context(tags, span: nil, name: nil)
|
255
265
|
return if span.nil? && name.nil?
|
256
266
|
|
@@ -280,10 +290,6 @@ module Datadog
|
|
280
290
|
end
|
281
291
|
end
|
282
292
|
|
283
|
-
def null_span
|
284
|
-
@null_span ||= NullSpan.new
|
285
|
-
end
|
286
|
-
|
287
293
|
def validate_test_suite_level_visibility_correctness(test)
|
288
294
|
return unless test_suite_level_visibility_enabled
|
289
295
|
|
@@ -34,7 +34,7 @@ module Datadog
|
|
34
34
|
@trace = trace
|
35
35
|
@span = span
|
36
36
|
|
37
|
-
@meta = @span.meta.reject { |key, _| Ext::Test::
|
37
|
+
@meta = @span.meta.reject { |key, _| Ext::Test::TRANSIENT_TAGS.include?(key) }
|
38
38
|
|
39
39
|
@errors = {}
|
40
40
|
@validated = false
|
@@ -45,7 +45,7 @@ module Datadog
|
|
45
45
|
|
46
46
|
packer.write_map_header(3)
|
47
47
|
|
48
|
-
write_field(packer, "type")
|
48
|
+
write_field(packer, "type", "event_type")
|
49
49
|
write_field(packer, "version")
|
50
50
|
|
51
51
|
packer.write("content")
|
@@ -119,9 +119,6 @@ module Datadog
|
|
119
119
|
to_integer(@span.get_tag(Ext::Test::TAG_TEST_SUITE_ID))
|
120
120
|
end
|
121
121
|
|
122
|
-
def type
|
123
|
-
end
|
124
|
-
|
125
122
|
def version
|
126
123
|
1
|
127
124
|
end
|
@@ -130,6 +127,10 @@ module Datadog
|
|
130
127
|
@span.type
|
131
128
|
end
|
132
129
|
|
130
|
+
def event_type
|
131
|
+
"span"
|
132
|
+
end
|
133
|
+
|
133
134
|
def name
|
134
135
|
@span.name
|
135
136
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "git"
|
4
|
+
|
5
|
+
module Datadog
|
6
|
+
module CI
|
7
|
+
module Utils
|
8
|
+
module Configuration
|
9
|
+
def self.fetch_service_name(default)
|
10
|
+
Datadog.configuration.service_without_fallback || Git.repository_name || default
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/datadog/ci/utils/git.rb
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "open3"
|
4
|
+
require "pathname"
|
5
|
+
|
3
6
|
module Datadog
|
4
7
|
module CI
|
5
8
|
module Utils
|
@@ -16,6 +19,73 @@ module Datadog
|
|
16
19
|
def self.is_git_tag?(ref)
|
17
20
|
!ref.nil? && ref.include?("tags/")
|
18
21
|
end
|
22
|
+
|
23
|
+
def self.root
|
24
|
+
return @root if defined?(@root)
|
25
|
+
|
26
|
+
@root = exec_git_command("git rev-parse --show-toplevel")
|
27
|
+
rescue => e
|
28
|
+
Datadog.logger.debug(
|
29
|
+
"Unable to read git root: #{e.class.name} #{e.message} at #{Array(e.backtrace).first}"
|
30
|
+
)
|
31
|
+
@root = nil
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.relative_to_root(path)
|
35
|
+
return nil if path.nil?
|
36
|
+
|
37
|
+
git_root = root
|
38
|
+
return path if git_root.nil?
|
39
|
+
|
40
|
+
path = Pathname.new(File.expand_path(path))
|
41
|
+
git_root = Pathname.new(git_root)
|
42
|
+
|
43
|
+
path.relative_path_from(git_root).to_s
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.repository_name
|
47
|
+
return @repository_name if defined?(@repository_name)
|
48
|
+
|
49
|
+
git_remote_url = exec_git_command("git ls-remote --get-url origin")
|
50
|
+
|
51
|
+
# return git repository name from remote url without .git extension
|
52
|
+
last_path_segment = git_remote_url.split("/").last if git_remote_url
|
53
|
+
@repository_name = last_path_segment.gsub(".git", "") if last_path_segment
|
54
|
+
@repository_name ||= current_folder_name
|
55
|
+
rescue => e
|
56
|
+
Datadog.logger.debug(
|
57
|
+
"Unable to get git remote: #{e.class.name} #{e.message} at #{Array(e.backtrace).first}"
|
58
|
+
)
|
59
|
+
@repository_name = current_folder_name
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.current_folder_name
|
63
|
+
root_folder = root
|
64
|
+
if root_folder.nil?
|
65
|
+
File.basename(Dir.pwd)
|
66
|
+
else
|
67
|
+
File.basename(root_folder)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def self.exec_git_command(cmd)
|
72
|
+
out, status = Open3.capture2e(cmd)
|
73
|
+
|
74
|
+
raise "Failed to run git command #{cmd}: #{out}" unless status.success?
|
75
|
+
|
76
|
+
# Sometimes Encoding.default_external is somehow set to US-ASCII which breaks
|
77
|
+
# commit messages with UTF-8 characters like emojis
|
78
|
+
# We force output's encoding to be UTF-8 in this case
|
79
|
+
# This is safe to do as UTF-8 is compatible with US-ASCII
|
80
|
+
if Encoding.default_external == Encoding::US_ASCII
|
81
|
+
out = out.force_encoding(Encoding::UTF_8)
|
82
|
+
end
|
83
|
+
out.strip! # There's always a "\n" at the end of the command output
|
84
|
+
|
85
|
+
return nil if out.empty?
|
86
|
+
|
87
|
+
out
|
88
|
+
end
|
19
89
|
end
|
20
90
|
end
|
21
91
|
end
|
data/lib/datadog/ci/version.rb
CHANGED
data/lib/datadog/ci.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative "ci/version"
|
4
|
+
require_relative "ci/utils/configuration"
|
5
|
+
require_relative "ci/ext/app_types"
|
4
6
|
|
5
7
|
require "datadog/core"
|
6
8
|
|
@@ -9,6 +11,8 @@ module Datadog
|
|
9
11
|
#
|
10
12
|
# @public_api
|
11
13
|
module CI
|
14
|
+
class ReservedTypeError < StandardError; end
|
15
|
+
|
12
16
|
class << self
|
13
17
|
# Starts a {Datadog::CI::TestSession ci_test_session} that represents the whole test session run.
|
14
18
|
#
|
@@ -30,13 +34,11 @@ module Datadog
|
|
30
34
|
#
|
31
35
|
# Remember that calling {Datadog::CI::TestSession#finish} is mandatory.
|
32
36
|
#
|
33
|
-
# @param [String] service the service name for this session (optional, defaults to DD_SERVICE)
|
37
|
+
# @param [String] service the service name for this session (optional, defaults to DD_SERVICE or repository name)
|
34
38
|
# @param [Hash<String,String>] tags extra tags which should be added to the test session.
|
35
|
-
# @return [Datadog::CI::TestSession]
|
36
|
-
# @return [
|
37
|
-
|
38
|
-
def start_test_session(service: nil, tags: {})
|
39
|
-
service ||= Datadog.configuration.service
|
39
|
+
# @return [Datadog::CI::TestSession] the active, running {Datadog::CI::TestSession}.
|
40
|
+
# @return [nil] if test suite level visibility is disabled or CI mode is disabled.
|
41
|
+
def start_test_session(service: Utils::Configuration.fetch_service_name("test"), tags: {})
|
40
42
|
recorder.start_test_session(service: service, tags: tags)
|
41
43
|
end
|
42
44
|
|
@@ -88,9 +90,8 @@ module Datadog
|
|
88
90
|
# @param [String] test_module_name the name for this module
|
89
91
|
# @param [String] service the service name for this session (optional, inherited from test session if not provided)
|
90
92
|
# @param [Hash<String,String>] tags extra tags which should be added to the test module (optional, some tags are inherited from test session).
|
91
|
-
# @return [Datadog::CI::TestModule]
|
92
|
-
# @return [
|
93
|
-
# detected and test suite level visibility cannot be supported.
|
93
|
+
# @return [Datadog::CI::TestModule] the active, running {Datadog::CI::TestModule}.
|
94
|
+
# @return [nil] if test suite level visibility is disabled or CI mode is disabled.
|
94
95
|
def start_test_module(test_module_name, service: nil, tags: {})
|
95
96
|
recorder.start_test_module(test_module_name, service: service, tags: tags)
|
96
97
|
end
|
@@ -141,9 +142,8 @@ module Datadog
|
|
141
142
|
# @param [String] test_suite_name the name of the test suite
|
142
143
|
# @param [String] service the service name for this test suite (optional, inherited from test session if not provided)
|
143
144
|
# @param [Hash<String,String>] tags extra tags which should be added to the test module (optional, some tags are inherited from test session)
|
144
|
-
# @return [Datadog::CI::TestSuite]
|
145
|
-
# @return [
|
146
|
-
# detected and test suite level visibility cannot be supported.
|
145
|
+
# @return [Datadog::CI::TestSuite] the active, running {Datadog::CI::TestSuite}.
|
146
|
+
# @return [nil] if test suite level visibility is disabled or CI mode is disabled.
|
147
147
|
def start_test_suite(test_suite_name, service: nil, tags: {})
|
148
148
|
recorder.start_test_suite(test_suite_name, service: service, tags: tags)
|
149
149
|
end
|
@@ -217,10 +217,10 @@ module Datadog
|
|
217
217
|
# @return [Object] If a block is provided, returns the result of the block execution.
|
218
218
|
# @return [Datadog::CI::Test] If no block is provided, returns the active,
|
219
219
|
# unfinished {Datadog::CI::Test}.
|
220
|
-
# @return [
|
220
|
+
# @return [nil] if no block is provided and CI mode is disabled.
|
221
221
|
# @yield Optional block where newly created {Datadog::CI::Test} captures the execution.
|
222
222
|
# @yieldparam [Datadog::CI::Test] ci_test the newly created and active [Datadog::CI::Test]
|
223
|
-
# @yieldparam [
|
223
|
+
# @yieldparam [nil] if CI mode is disabled
|
224
224
|
def trace_test(test_name, test_suite_name, service: nil, tags: {}, &block)
|
225
225
|
recorder.trace_test(test_name, test_suite_name, service: service, tags: tags, &block)
|
226
226
|
end
|
@@ -245,8 +245,8 @@ module Datadog
|
|
245
245
|
# @param [String] test_suite_name name of test suite this test belongs to (example: "CalculatorTest").
|
246
246
|
# @param [String] service the service name for this span (optional, inherited from test session if not provided)
|
247
247
|
# @param [Hash<String,String>] tags extra tags which should be added to the test.
|
248
|
-
# @return [Datadog::CI::Test]
|
249
|
-
# @return [
|
248
|
+
# @return [Datadog::CI::Test] the active, unfinished {Datadog::CI::Test}.
|
249
|
+
# @return [nil] if CI mode is disabled.
|
250
250
|
def start_test(test_name, test_suite_name, service: nil, tags: {})
|
251
251
|
recorder.trace_test(test_name, test_suite_name, service: service, tags: tags)
|
252
252
|
end
|
@@ -260,8 +260,8 @@ module Datadog
|
|
260
260
|
#
|
261
261
|
# ```
|
262
262
|
# Datadog::CI.trace(
|
263
|
-
# "step",
|
264
263
|
# "Given I have 42 cucumbers",
|
264
|
+
# type: "step",
|
265
265
|
# tags: {}
|
266
266
|
# ) do
|
267
267
|
# run_operation
|
@@ -271,8 +271,8 @@ module Datadog
|
|
271
271
|
# The {.trace} method can also be used without a block in this way:
|
272
272
|
# ```
|
273
273
|
# ci_span = Datadog::CI.trace(
|
274
|
-
# "step",
|
275
274
|
# "Given I have 42 cucumbers",
|
275
|
+
# type: "step",
|
276
276
|
# tags: {}
|
277
277
|
# )
|
278
278
|
# # ... run test here ...
|
@@ -280,22 +280,31 @@ module Datadog
|
|
280
280
|
# ```
|
281
281
|
# Remember that in this case, calling {Datadog::CI::Span#finish} is mandatory.
|
282
282
|
#
|
283
|
-
# @param [String] span_type custom, user-defined span type (for example "step" or "query").
|
284
283
|
# @param [String] span_name the resource this span refers, or `test` if it's missing
|
284
|
+
# @param [String] type custom, user-defined span type (for example "step" or "query").
|
285
285
|
# @param [Hash<String,String>] tags extra tags which should be added to the span.
|
286
286
|
# @return [Object] If a block is provided, returns the result of the block execution.
|
287
287
|
# @return [Datadog::CI::Span] If no block is provided, returns the active,
|
288
288
|
# unfinished {Datadog::CI::Span}.
|
289
|
-
# @return [
|
289
|
+
# @return [nil] if CI visibility is disabled
|
290
|
+
# @raise [ReservedTypeError] if provided type is reserved for Datadog CI visibility
|
290
291
|
# @yield Optional block where newly created {Datadog::CI::Span} captures the execution.
|
291
292
|
# @yieldparam [Datadog::CI::Span] ci_span the newly created and active [Datadog::CI::Span]
|
292
|
-
# @yieldparam [
|
293
|
-
def trace(
|
294
|
-
|
293
|
+
# @yieldparam [nil] ci_span if CI visibility is disabled
|
294
|
+
def trace(span_name, type: "span", tags: {}, &block)
|
295
|
+
if Ext::AppTypes::CI_SPAN_TYPES.include?(type)
|
296
|
+
raise(
|
297
|
+
ReservedTypeError,
|
298
|
+
"Span type #{type} is reserved for Datadog CI visibility. " \
|
299
|
+
"Reserved types are: #{Ext::AppTypes::CI_SPAN_TYPES}"
|
300
|
+
)
|
301
|
+
end
|
302
|
+
|
303
|
+
recorder.trace(span_name, type: type, tags: tags, &block)
|
295
304
|
end
|
296
305
|
|
297
|
-
# The active, unfinished custom
|
298
|
-
# If no span is active, or if the active span is not a custom span
|
306
|
+
# The active, unfinished custom (i.e. not test/suite/module/session) span.
|
307
|
+
# If no span is active, or if the active span is not a custom span, returns nil.
|
299
308
|
#
|
300
309
|
# The active span belongs to an {.active_test}.
|
301
310
|
#
|
@@ -304,22 +313,21 @@ module Datadog
|
|
304
313
|
# ```
|
305
314
|
# # start span
|
306
315
|
# Datadog::CI.trace(
|
307
|
-
# "step",
|
308
316
|
# "Given I have 42 cucumbers",
|
317
|
+
# type: "step",
|
309
318
|
# tags: {}
|
310
319
|
# )
|
311
320
|
#
|
312
|
-
# # somewhere else, access the active
|
313
|
-
# step_span = Datadog::CI.active_span
|
321
|
+
# # somewhere else, access the active step span
|
322
|
+
# step_span = Datadog::CI.active_span
|
314
323
|
# step_span.finish()
|
315
324
|
# ```
|
316
325
|
#
|
317
|
-
# @param [String] span_type type of the span to retrieve (for example "step" or "query") that was provided to {.trace}
|
318
326
|
# @return [Datadog::CI::Span] the active span
|
319
|
-
# @return [nil] if no span is active, or if the active span is not a custom span
|
320
|
-
def active_span
|
327
|
+
# @return [nil] if no span is active, or if the active span is not a custom span
|
328
|
+
def active_span
|
321
329
|
span = recorder.active_span
|
322
|
-
span if span && span.
|
330
|
+
span if span && !Ext::AppTypes::CI_SPAN_TYPES.include?(span.type)
|
323
331
|
end
|
324
332
|
|
325
333
|
# The active, unfinished test span.
|
@@ -347,30 +355,6 @@ module Datadog
|
|
347
355
|
recorder.active_test
|
348
356
|
end
|
349
357
|
|
350
|
-
# Internal only, to finish a test use {Datadog::CI::Test#finish}
|
351
|
-
# @private
|
352
|
-
def deactivate_test(test)
|
353
|
-
recorder.deactivate_test(test)
|
354
|
-
end
|
355
|
-
|
356
|
-
# Internal only, to finish a test session use {Datadog::CI::TestSession#finish}
|
357
|
-
# @private
|
358
|
-
def deactivate_test_session
|
359
|
-
recorder.deactivate_test_session
|
360
|
-
end
|
361
|
-
|
362
|
-
# Internal only, to finish a test module use {Datadog::CI::TestModule#finish}
|
363
|
-
# @private
|
364
|
-
def deactivate_test_module
|
365
|
-
recorder.deactivate_test_module
|
366
|
-
end
|
367
|
-
|
368
|
-
# Internal only, to finish a test suite use {Datadog::CI::TestSuite#finish}
|
369
|
-
# @private
|
370
|
-
def deactivate_test_suite(test_suite_name)
|
371
|
-
recorder.deactivate_test_suite(test_suite_name)
|
372
|
-
end
|
373
|
-
|
374
358
|
private
|
375
359
|
|
376
360
|
def components
|