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
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../../ext/test"
|
4
|
+
require_relative "ext"
|
5
|
+
|
6
|
+
module Datadog
|
7
|
+
module CI
|
8
|
+
module Contrib
|
9
|
+
module Minitest
|
10
|
+
module Reporter
|
11
|
+
def self.included(base)
|
12
|
+
base.prepend(InstanceMethods)
|
13
|
+
end
|
14
|
+
|
15
|
+
module InstanceMethods
|
16
|
+
def report(*)
|
17
|
+
return super unless datadog_configuration[:enabled]
|
18
|
+
|
19
|
+
res = super
|
20
|
+
|
21
|
+
active_test_session = CI.active_test_session
|
22
|
+
active_test_module = CI.active_test_module
|
23
|
+
|
24
|
+
return res if active_test_session.nil? || active_test_module.nil?
|
25
|
+
|
26
|
+
if passed?
|
27
|
+
active_test_module.passed!
|
28
|
+
active_test_session.passed!
|
29
|
+
else
|
30
|
+
active_test_module.failed!
|
31
|
+
active_test_session.failed!
|
32
|
+
end
|
33
|
+
|
34
|
+
active_test_module.finish
|
35
|
+
active_test_session.finish
|
36
|
+
|
37
|
+
res
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def datadog_configuration
|
43
|
+
Datadog.configuration.ci[:minitest]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -20,9 +20,9 @@ module Datadog
|
|
20
20
|
test_suite_name = Helpers.test_suite_name(self, method)
|
21
21
|
|
22
22
|
test_suite = Datadog::CI.start_test_suite(test_suite_name)
|
23
|
-
test_suite.passed! # will be overridden if any test fails
|
24
23
|
|
25
24
|
results = super
|
25
|
+
return results unless test_suite
|
26
26
|
|
27
27
|
test_suite.finish
|
28
28
|
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../../ext/test"
|
4
|
+
require_relative "ext"
|
5
|
+
|
6
|
+
module Datadog
|
7
|
+
module CI
|
8
|
+
module Contrib
|
9
|
+
module Minitest
|
10
|
+
module Runner
|
11
|
+
def self.included(base)
|
12
|
+
base.singleton_class.prepend(ClassMethods)
|
13
|
+
end
|
14
|
+
|
15
|
+
module ClassMethods
|
16
|
+
def init_plugins(*)
|
17
|
+
super
|
18
|
+
|
19
|
+
return unless datadog_configuration[:enabled]
|
20
|
+
|
21
|
+
test_session = CI.start_test_session(
|
22
|
+
tags: {
|
23
|
+
CI::Ext::Test::TAG_FRAMEWORK => Ext::FRAMEWORK,
|
24
|
+
CI::Ext::Test::TAG_FRAMEWORK_VERSION => CI::Contrib::Minitest::Integration.version.to_s
|
25
|
+
},
|
26
|
+
service: datadog_configuration[:service_name]
|
27
|
+
)
|
28
|
+
CI.start_test_module(test_session.name) if test_session
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def datadog_configuration
|
34
|
+
Datadog.configuration.ci[:minitest]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require_relative "../ext"
|
4
4
|
require_relative "../../settings"
|
5
|
+
require_relative "../../../utils/configuration"
|
5
6
|
|
6
7
|
module Datadog
|
7
8
|
module CI
|
@@ -19,7 +20,9 @@ module Datadog
|
|
19
20
|
|
20
21
|
option :service_name do |o|
|
21
22
|
o.type :string
|
22
|
-
o.default
|
23
|
+
o.default do
|
24
|
+
Utils::Configuration.fetch_service_name(Ext::DEFAULT_SERVICE_NAME)
|
25
|
+
end
|
23
26
|
end
|
24
27
|
|
25
28
|
# @deprecated Will be removed in 1.0
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative "../../ext/test"
|
4
|
+
require_relative "../../utils/git"
|
4
5
|
require_relative "ext"
|
5
6
|
|
6
7
|
module Datadog
|
@@ -13,10 +14,9 @@ module Datadog
|
|
13
14
|
base.prepend(InstanceMethods)
|
14
15
|
end
|
15
16
|
|
16
|
-
# Instance methods for configuration
|
17
17
|
module InstanceMethods
|
18
|
-
def run(
|
19
|
-
return super unless
|
18
|
+
def run(*)
|
19
|
+
return super unless datadog_configuration[:enabled]
|
20
20
|
|
21
21
|
test_name = full_description.strip
|
22
22
|
if metadata[:description].empty?
|
@@ -24,36 +24,77 @@ module Datadog
|
|
24
24
|
test_name += " #{description}"
|
25
25
|
end
|
26
26
|
|
27
|
+
test_suite_description = fetch_top_level_example_group[:description]
|
28
|
+
suite_name = "#{test_suite_description} at #{metadata[:example_group][:rerun_file_path]}"
|
29
|
+
|
30
|
+
# remove example group description from test name to avoid duplication
|
31
|
+
test_name = test_name.sub(test_suite_description, "").strip
|
32
|
+
|
33
|
+
if ci_queue?
|
34
|
+
suite_name += " (ci-queue running example [#{test_name}])"
|
35
|
+
test_suite_span = CI.start_test_suite(suite_name)
|
36
|
+
end
|
37
|
+
|
27
38
|
CI.trace_test(
|
28
39
|
test_name,
|
29
|
-
|
40
|
+
suite_name,
|
30
41
|
tags: {
|
31
42
|
CI::Ext::Test::TAG_FRAMEWORK => Ext::FRAMEWORK,
|
32
43
|
CI::Ext::Test::TAG_FRAMEWORK_VERSION => CI::Contrib::RSpec::Integration.version.to_s,
|
33
|
-
CI::Ext::Test::
|
44
|
+
CI::Ext::Test::TAG_SOURCE_FILE => Utils::Git.relative_to_root(metadata[:file_path]),
|
45
|
+
CI::Ext::Test::TAG_SOURCE_START => metadata[:line_number].to_s
|
34
46
|
},
|
35
|
-
service:
|
47
|
+
service: datadog_configuration[:service_name]
|
36
48
|
) do |test_span|
|
37
49
|
result = super
|
38
50
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
51
|
+
if test_span
|
52
|
+
test_span.set_parameters({}, {"scoped_id" => metadata[:scoped_id]})
|
53
|
+
|
54
|
+
case execution_result.status
|
55
|
+
when :passed
|
56
|
+
test_span.passed!
|
57
|
+
test_suite_span.passed! if test_suite_span
|
58
|
+
when :failed
|
59
|
+
test_span.failed!(exception: execution_result.exception)
|
60
|
+
test_suite_span.failed! if test_suite_span
|
61
|
+
else
|
62
|
+
# :pending or nil
|
63
|
+
test_span.skipped!(
|
64
|
+
reason: execution_result.pending_message,
|
65
|
+
exception: execution_result.pending_exception
|
66
|
+
)
|
67
|
+
|
68
|
+
test_suite_span.skipped! if test_suite_span
|
69
|
+
end
|
46
70
|
end
|
47
71
|
|
72
|
+
test_suite_span.finish if test_suite_span
|
73
|
+
|
48
74
|
result
|
49
75
|
end
|
50
76
|
end
|
51
77
|
|
52
78
|
private
|
53
79
|
|
54
|
-
def
|
80
|
+
def fetch_top_level_example_group
|
81
|
+
return metadata[:example_group] unless metadata[:example_group][:parent_example_group]
|
82
|
+
|
83
|
+
res = metadata[:example_group][:parent_example_group]
|
84
|
+
while (parent = res[:parent_example_group])
|
85
|
+
res = parent
|
86
|
+
end
|
87
|
+
res
|
88
|
+
end
|
89
|
+
|
90
|
+
def datadog_configuration
|
55
91
|
Datadog.configuration.ci[:rspec]
|
56
92
|
end
|
93
|
+
|
94
|
+
def ci_queue?
|
95
|
+
defined?(::RSpec::Queue::ExampleExtension) &&
|
96
|
+
self.class.ancestors.include?(::RSpec::Queue::ExampleExtension)
|
97
|
+
end
|
57
98
|
end
|
58
99
|
end
|
59
100
|
end
|
@@ -7,7 +7,7 @@ module Datadog
|
|
7
7
|
module CI
|
8
8
|
module Contrib
|
9
9
|
module RSpec
|
10
|
-
# Instrument RSpec::Core::
|
10
|
+
# Instrument RSpec::Core::ExampleGroup
|
11
11
|
module ExampleGroup
|
12
12
|
def self.included(base)
|
13
13
|
base.singleton_class.prepend(ClassMethods)
|
@@ -16,26 +16,31 @@ module Datadog
|
|
16
16
|
# Instance methods for configuration
|
17
17
|
module ClassMethods
|
18
18
|
def run(reporter = ::RSpec::Core::NullReporter)
|
19
|
-
return super unless
|
19
|
+
return super unless datadog_configuration[:enabled]
|
20
20
|
return super unless top_level?
|
21
21
|
|
22
|
-
|
22
|
+
suite_name = "#{description} at #{file_path}"
|
23
|
+
test_suite = Datadog::CI.start_test_suite(suite_name)
|
23
24
|
|
24
|
-
|
25
|
+
success = super
|
26
|
+
return success unless test_suite
|
25
27
|
|
26
|
-
if
|
28
|
+
if success && test_suite.passed_tests_count > 0
|
27
29
|
test_suite.passed!
|
30
|
+
elsif success
|
31
|
+
test_suite.skipped!
|
28
32
|
else
|
29
33
|
test_suite.failed!
|
30
34
|
end
|
35
|
+
|
31
36
|
test_suite.finish
|
32
37
|
|
33
|
-
|
38
|
+
success
|
34
39
|
end
|
35
40
|
|
36
41
|
private
|
37
42
|
|
38
|
-
def
|
43
|
+
def datadog_configuration
|
39
44
|
Datadog.configuration.ci[:rspec]
|
40
45
|
end
|
41
46
|
end
|
@@ -21,10 +21,19 @@ module Datadog
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def patch
|
24
|
-
|
24
|
+
if ci_queue?
|
25
|
+
::RSpec::Queue::Runner.include(Runner)
|
26
|
+
end
|
27
|
+
|
25
28
|
::RSpec::Core::Runner.include(Runner)
|
29
|
+
::RSpec::Core::Example.include(Example)
|
26
30
|
::RSpec::Core::ExampleGroup.include(ExampleGroup)
|
27
31
|
end
|
32
|
+
|
33
|
+
def ci_queue?
|
34
|
+
# ::RSpec::Queue::Runner is a ci-queue runner
|
35
|
+
defined?(::RSpec::Queue::Runner)
|
36
|
+
end
|
28
37
|
end
|
29
38
|
end
|
30
39
|
end
|
@@ -14,21 +14,21 @@ module Datadog
|
|
14
14
|
end
|
15
15
|
|
16
16
|
module InstanceMethods
|
17
|
-
def run_specs(
|
18
|
-
return super unless
|
17
|
+
def run_specs(*)
|
18
|
+
return super unless datadog_configuration[:enabled]
|
19
19
|
|
20
20
|
test_session = CI.start_test_session(
|
21
21
|
tags: {
|
22
22
|
CI::Ext::Test::TAG_FRAMEWORK => Ext::FRAMEWORK,
|
23
|
-
CI::Ext::Test::TAG_FRAMEWORK_VERSION => CI::Contrib::RSpec::Integration.version.to_s
|
24
|
-
CI::Ext::Test::TAG_TYPE => CI::Ext::Test::TEST_TYPE
|
23
|
+
CI::Ext::Test::TAG_FRAMEWORK_VERSION => CI::Contrib::RSpec::Integration.version.to_s
|
25
24
|
},
|
26
|
-
service:
|
25
|
+
service: datadog_configuration[:service_name]
|
27
26
|
)
|
28
27
|
|
29
|
-
test_module = CI.start_test_module(test_session.name)
|
28
|
+
test_module = CI.start_test_module(test_session.name) if test_session
|
30
29
|
|
31
30
|
result = super
|
31
|
+
return result unless test_module && test_session
|
32
32
|
|
33
33
|
if result != 0
|
34
34
|
# TODO: repeating this twice feels clunky, we need to remove test_module API before GA
|
@@ -46,7 +46,7 @@ module Datadog
|
|
46
46
|
|
47
47
|
private
|
48
48
|
|
49
|
-
def
|
49
|
+
def datadog_configuration
|
50
50
|
Datadog.configuration.ci[:rspec]
|
51
51
|
end
|
52
52
|
end
|
@@ -1,9 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "open3"
|
4
|
-
|
5
3
|
require_relative "base"
|
6
|
-
require_relative "
|
4
|
+
require_relative "../../../utils/git"
|
7
5
|
|
8
6
|
module Datadog
|
9
7
|
module CI
|
@@ -13,7 +11,7 @@ module Datadog
|
|
13
11
|
# As a fallback we try to fetch git information from the local git repository
|
14
12
|
class LocalGit < Base
|
15
13
|
def git_repository_url
|
16
|
-
exec_git_command("git ls-remote --get-url")
|
14
|
+
Utils::Git.exec_git_command("git ls-remote --get-url")
|
17
15
|
rescue => e
|
18
16
|
Datadog.logger.debug(
|
19
17
|
"Unable to read git repository url: #{e.class.name} #{e.message} at #{Array(e.backtrace).first}"
|
@@ -22,7 +20,7 @@ module Datadog
|
|
22
20
|
end
|
23
21
|
|
24
22
|
def git_commit_sha
|
25
|
-
exec_git_command("git rev-parse HEAD")
|
23
|
+
Utils::Git.exec_git_command("git rev-parse HEAD")
|
26
24
|
rescue => e
|
27
25
|
Datadog.logger.debug(
|
28
26
|
"Unable to read git commit SHA: #{e.class.name} #{e.message} at #{Array(e.backtrace).first}"
|
@@ -31,7 +29,7 @@ module Datadog
|
|
31
29
|
end
|
32
30
|
|
33
31
|
def git_branch
|
34
|
-
exec_git_command("git rev-parse --abbrev-ref HEAD")
|
32
|
+
Utils::Git.exec_git_command("git rev-parse --abbrev-ref HEAD")
|
35
33
|
rescue => e
|
36
34
|
Datadog.logger.debug(
|
37
35
|
"Unable to read git branch: #{e.class.name} #{e.message} at #{Array(e.backtrace).first}"
|
@@ -40,7 +38,7 @@ module Datadog
|
|
40
38
|
end
|
41
39
|
|
42
40
|
def git_tag
|
43
|
-
exec_git_command("git tag --points-at HEAD")
|
41
|
+
Utils::Git.exec_git_command("git tag --points-at HEAD")
|
44
42
|
rescue => e
|
45
43
|
Datadog.logger.debug(
|
46
44
|
"Unable to read git tag: #{e.class.name} #{e.message} at #{Array(e.backtrace).first}"
|
@@ -49,7 +47,7 @@ module Datadog
|
|
49
47
|
end
|
50
48
|
|
51
49
|
def git_commit_message
|
52
|
-
exec_git_command("git show -s --format=%s")
|
50
|
+
Utils::Git.exec_git_command("git show -s --format=%s")
|
53
51
|
rescue => e
|
54
52
|
Datadog.logger.debug(
|
55
53
|
"Unable to read git commit message: #{e.class.name} #{e.message} at #{Array(e.backtrace).first}"
|
@@ -82,7 +80,7 @@ module Datadog
|
|
82
80
|
end
|
83
81
|
|
84
82
|
def workspace_path
|
85
|
-
exec_git_command("git rev-parse --show-toplevel")
|
83
|
+
Utils::Git.exec_git_command("git rev-parse --show-toplevel")
|
86
84
|
rescue => e
|
87
85
|
Datadog.logger.debug(
|
88
86
|
"Unable to read git base directory: #{e.class.name} #{e.message} at #{Array(e.backtrace).first}"
|
@@ -92,25 +90,6 @@ module Datadog
|
|
92
90
|
|
93
91
|
private
|
94
92
|
|
95
|
-
def exec_git_command(cmd)
|
96
|
-
out, status = Open3.capture2e(cmd)
|
97
|
-
|
98
|
-
raise "Failed to run git command #{cmd}: #{out}" unless status.success?
|
99
|
-
|
100
|
-
# Sometimes Encoding.default_external is somehow set to US-ASCII which breaks
|
101
|
-
# commit messages with UTF-8 characters like emojis
|
102
|
-
# We force output's encoding to be UTF-8 in this case
|
103
|
-
# This is safe to do as UTF-8 is compatible with US-ASCII
|
104
|
-
if Encoding.default_external == Encoding::US_ASCII
|
105
|
-
out = out.force_encoding(Encoding::UTF_8)
|
106
|
-
end
|
107
|
-
out.strip! # There's always a "\n" at the end of the command output
|
108
|
-
|
109
|
-
return nil if out.empty?
|
110
|
-
|
111
|
-
out
|
112
|
-
end
|
113
|
-
|
114
93
|
def author
|
115
94
|
return @author if defined?(@author)
|
116
95
|
|
@@ -127,7 +106,7 @@ module Datadog
|
|
127
106
|
|
128
107
|
def set_git_commit_users
|
129
108
|
# Get committer and author information in one command.
|
130
|
-
output = exec_git_command("git show -s --format='%an\t%ae\t%at\t%cn\t%ce\t%ct'")
|
109
|
+
output = Utils::Git.exec_git_command("git show -s --format='%an\t%ae\t%at\t%cn\t%ce\t%ct'")
|
131
110
|
unless output
|
132
111
|
Datadog.logger.debug(
|
133
112
|
"Unable to read git commit users: git command output is nil"
|
@@ -9,6 +9,7 @@ module Datadog
|
|
9
9
|
ENV_AGENTLESS_MODE_ENABLED = "DD_CIVISIBILITY_AGENTLESS_ENABLED"
|
10
10
|
ENV_AGENTLESS_URL = "DD_CIVISIBILITY_AGENTLESS_URL"
|
11
11
|
ENV_EXPERIMENTAL_TEST_SUITE_LEVEL_VISIBILITY_ENABLED = "DD_CIVISIBILITY_EXPERIMENTAL_TEST_SUITE_LEVEL_VISIBILITY_ENABLED"
|
12
|
+
ENV_FORCE_TEST_LEVEL_VISIBILITY = "DD_CIVISIBILITY_FORCE_TEST_LEVEL_VISIBILITY"
|
12
13
|
|
13
14
|
# Source: https://docs.datadoghq.com/getting_started/site/
|
14
15
|
DD_SITE_ALLOWLIST = [
|
data/lib/datadog/ci/ext/test.rb
CHANGED
@@ -12,24 +12,26 @@ module Datadog
|
|
12
12
|
TAG_FRAMEWORK = "test.framework"
|
13
13
|
TAG_FRAMEWORK_VERSION = "test.framework_version"
|
14
14
|
TAG_NAME = "test.name"
|
15
|
-
TAG_SKIP_REASON = "test.skip_reason"
|
15
|
+
TAG_SKIP_REASON = "test.skip_reason"
|
16
16
|
TAG_STATUS = "test.status"
|
17
17
|
TAG_SUITE = "test.suite"
|
18
18
|
TAG_MODULE = "test.module"
|
19
|
-
TAG_TRAITS = "test.traits"
|
20
19
|
TAG_TYPE = "test.type"
|
21
20
|
TAG_COMMAND = "test.command"
|
21
|
+
TAG_SOURCE_FILE = "test.source.file"
|
22
|
+
TAG_SOURCE_START = "test.source.start"
|
23
|
+
TAG_CODEOWNERS = "test.codeowners"
|
24
|
+
TAG_PARAMETERS = "test.parameters"
|
22
25
|
|
23
|
-
|
24
|
-
|
25
|
-
# those tags are special and they are used to correlate tests with the test sessions, suites, and modules
|
26
|
+
# those tags are special and used to correlate tests with the test sessions, suites, and modules
|
27
|
+
# they are transient and not sent to the backend
|
26
28
|
TAG_TEST_SESSION_ID = "_test.session_id"
|
27
29
|
TAG_TEST_MODULE_ID = "_test.module_id"
|
28
30
|
TAG_TEST_SUITE_ID = "_test.suite_id"
|
29
|
-
|
31
|
+
TRANSIENT_TAGS = [TAG_TEST_SESSION_ID, TAG_TEST_MODULE_ID, TAG_TEST_SUITE_ID].freeze
|
30
32
|
|
31
|
-
# tags that can be inherited from the test session
|
32
|
-
INHERITABLE_TAGS = [TAG_FRAMEWORK, TAG_FRAMEWORK_VERSION
|
33
|
+
# tags that are common for the whole session and can be inherited from the test session
|
34
|
+
INHERITABLE_TAGS = [TAG_FRAMEWORK, TAG_FRAMEWORK_VERSION].freeze
|
33
35
|
|
34
36
|
# Environment runtime tags
|
35
37
|
TAG_OS_ARCHITECTURE = "os.architecture"
|
@@ -37,13 +39,22 @@ module Datadog
|
|
37
39
|
TAG_RUNTIME_NAME = "runtime.name"
|
38
40
|
TAG_RUNTIME_VERSION = "runtime.version"
|
39
41
|
|
42
|
+
# internal APM tag to mark a span as a test span
|
40
43
|
TAG_SPAN_KIND = "span.kind"
|
44
|
+
SPAN_KIND_TEST = "test"
|
41
45
|
|
46
|
+
# test status as recognized by Datadog
|
42
47
|
module Status
|
43
48
|
PASS = "pass"
|
44
49
|
FAIL = "fail"
|
45
50
|
SKIP = "skip"
|
46
51
|
end
|
52
|
+
|
53
|
+
# test types (e.g. test, benchmark, browser)
|
54
|
+
module Type
|
55
|
+
TEST = "test"
|
56
|
+
BENCHMARK = "benchmark" # DEV: not used yet, will be used when benchmarks are supported
|
57
|
+
end
|
47
58
|
end
|
48
59
|
end
|
49
60
|
end
|
data/lib/datadog/ci/span.rb
CHANGED
@@ -32,7 +32,7 @@ module Datadog
|
|
32
32
|
end
|
33
33
|
|
34
34
|
# @return [String] the type of the span (for example "test" or type that was provided to [Datadog::CI.trace]).
|
35
|
-
def
|
35
|
+
def type
|
36
36
|
tracer_span.type
|
37
37
|
end
|
38
38
|
|
@@ -130,12 +130,19 @@ module Datadog
|
|
130
130
|
end
|
131
131
|
|
132
132
|
def set_default_tags
|
133
|
-
tracer_span.set_tag(Ext::Test::TAG_SPAN_KIND, Ext::
|
133
|
+
tracer_span.set_tag(Ext::Test::TAG_SPAN_KIND, Ext::Test::SPAN_KIND_TEST)
|
134
134
|
end
|
135
135
|
|
136
136
|
def to_s
|
137
137
|
"#{self.class}(name:#{name},tracer_span:#{@tracer_span})"
|
138
138
|
end
|
139
|
+
|
140
|
+
private
|
141
|
+
|
142
|
+
# provides access to global CI recorder for CI models to deactivate themselves
|
143
|
+
def recorder
|
144
|
+
Datadog.send(:components).ci_recorder
|
145
|
+
end
|
139
146
|
end
|
140
147
|
end
|
141
148
|
end
|
data/lib/datadog/ci/test.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "json"
|
4
|
+
|
3
5
|
require_relative "span"
|
4
6
|
|
5
7
|
module Datadog
|
@@ -18,7 +20,7 @@ module Datadog
|
|
18
20
|
def finish
|
19
21
|
super
|
20
22
|
|
21
|
-
|
23
|
+
recorder.deactivate_test
|
22
24
|
end
|
23
25
|
|
24
26
|
# Running test suite that this test is part of (if any).
|
@@ -35,6 +37,8 @@ module Datadog
|
|
35
37
|
get_tag(Ext::Test::TAG_TEST_SUITE_ID)
|
36
38
|
end
|
37
39
|
|
40
|
+
# Name of the running test suite this test belongs to.
|
41
|
+
# @return [String] the name of the test suite.
|
38
42
|
def test_suite_name
|
39
43
|
get_tag(Ext::Test::TAG_SUITE)
|
40
44
|
end
|
@@ -45,11 +49,72 @@ module Datadog
|
|
45
49
|
get_tag(Ext::Test::TAG_TEST_MODULE_ID)
|
46
50
|
end
|
47
51
|
|
48
|
-
# Span id of the running test
|
52
|
+
# Span id of the running test session this test belongs to.
|
49
53
|
# @return [String] the span id of the test session.
|
50
54
|
def test_session_id
|
51
55
|
get_tag(Ext::Test::TAG_TEST_SESSION_ID)
|
52
56
|
end
|
57
|
+
|
58
|
+
# Source file path of the test relative to git repository root.
|
59
|
+
# @return [String] the source file path of the test
|
60
|
+
# @return [nil] if the source file path is not found
|
61
|
+
def source_file
|
62
|
+
get_tag(Ext::Test::TAG_SOURCE_FILE)
|
63
|
+
end
|
64
|
+
|
65
|
+
# Sets the status of the span to "pass".
|
66
|
+
# @return [void]
|
67
|
+
def passed!
|
68
|
+
super
|
69
|
+
|
70
|
+
record_test_result(Ext::Test::Status::PASS)
|
71
|
+
end
|
72
|
+
|
73
|
+
# Sets the status of the span to "fail".
|
74
|
+
# @param [Exception] exception the exception that caused the test to fail.
|
75
|
+
# @return [void]
|
76
|
+
def failed!(exception: nil)
|
77
|
+
super
|
78
|
+
|
79
|
+
record_test_result(Ext::Test::Status::FAIL)
|
80
|
+
end
|
81
|
+
|
82
|
+
# Sets the status of the span to "skip".
|
83
|
+
# @param [Exception] exception the exception that caused the test to fail.
|
84
|
+
# @param [String] reason the reason why the test was skipped.
|
85
|
+
# @return [void]
|
86
|
+
def skipped!(exception: nil, reason: nil)
|
87
|
+
super
|
88
|
+
|
89
|
+
record_test_result(Ext::Test::Status::SKIP)
|
90
|
+
end
|
91
|
+
|
92
|
+
# Sets the parameters for this test (e.g. Cucumber example or RSpec shared specs).
|
93
|
+
# Parameters are needed to compute test fingerprint to distinguish between different tests having same names.
|
94
|
+
#
|
95
|
+
# @param [Hash] arguments the arguments that test accepts as key-value hash
|
96
|
+
# @param [Hash] metadata optional metadata
|
97
|
+
# @return [void]
|
98
|
+
def set_parameters(arguments, metadata = {})
|
99
|
+
return if arguments.nil?
|
100
|
+
|
101
|
+
set_tag(
|
102
|
+
Ext::Test::TAG_PARAMETERS,
|
103
|
+
JSON.generate(
|
104
|
+
{
|
105
|
+
arguments: arguments,
|
106
|
+
metadata: metadata
|
107
|
+
}
|
108
|
+
)
|
109
|
+
)
|
110
|
+
end
|
111
|
+
|
112
|
+
private
|
113
|
+
|
114
|
+
def record_test_result(datadog_status)
|
115
|
+
suite = test_suite
|
116
|
+
suite.record_test_result(datadog_status) if suite
|
117
|
+
end
|
53
118
|
end
|
54
119
|
end
|
55
120
|
end
|
@@ -17,7 +17,7 @@ module Datadog
|
|
17
17
|
def finish
|
18
18
|
super
|
19
19
|
|
20
|
-
|
20
|
+
recorder.deactivate_test_session
|
21
21
|
end
|
22
22
|
|
23
23
|
# Return the test session's name which is equal to test command used
|
@@ -32,7 +32,7 @@ module Datadog
|
|
32
32
|
return @inheritable_tags if defined?(@inheritable_tags)
|
33
33
|
|
34
34
|
# this method is not synchronized because it does not iterate over the tags collection, but rather
|
35
|
-
# uses synchronized method to get each tag value
|
35
|
+
# uses synchronized method #get_tag to get each tag value
|
36
36
|
res = {}
|
37
37
|
Ext::Test::INHERITABLE_TAGS.each do |tag|
|
38
38
|
res[tag] = get_tag(tag)
|