datadog-ci 1.5.0 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +23 -2
- data/README.md +1 -0
- data/lib/datadog/ci/configuration/components.rb +2 -1
- data/lib/datadog/ci/configuration/settings.rb +5 -0
- data/lib/datadog/ci/contrib/cucumber/formatter.rb +25 -3
- data/lib/datadog/ci/contrib/minitest/helpers.rb +4 -4
- data/lib/datadog/ci/contrib/minitest/runnable.rb +15 -2
- data/lib/datadog/ci/contrib/rspec/example_group.rb +7 -1
- data/lib/datadog/ci/contrib/simplecov/configuration/settings.rb +26 -0
- data/lib/datadog/ci/contrib/simplecov/ext.rb +15 -0
- data/lib/datadog/ci/contrib/simplecov/integration.rb +47 -0
- data/lib/datadog/ci/contrib/simplecov/patcher.rb +28 -0
- data/lib/datadog/ci/contrib/simplecov/result_extractor.rb +36 -0
- data/lib/datadog/ci/ext/environment/extractor.rb +5 -0
- data/lib/datadog/ci/ext/environment/providers/base.rb +4 -0
- data/lib/datadog/ci/ext/environment/providers/github_actions.rb +24 -0
- data/lib/datadog/ci/ext/git.rb +5 -0
- data/lib/datadog/ci/ext/settings.rb +1 -0
- data/lib/datadog/ci/ext/test.rb +9 -0
- data/lib/datadog/ci/span.rb +14 -0
- data/lib/datadog/ci/test.rb +0 -7
- data/lib/datadog/ci/test_session.rb +18 -0
- data/lib/datadog/ci/test_visibility/component.rb +23 -5
- data/lib/datadog/ci/test_visibility/context.rb +4 -0
- data/lib/datadog/ci/test_visibility/null_component.rb +7 -0
- data/lib/datadog/ci/test_visibility/telemetry.rb +1 -3
- data/lib/datadog/ci/test_visibility/total_coverage.rb +36 -0
- data/lib/datadog/ci/test_visibility/transport.rb +21 -3
- data/lib/datadog/ci/utils/test_run.rb +8 -0
- data/lib/datadog/ci/version.rb +1 -1
- data/lib/datadog/ci.rb +1 -0
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f4cb94bf0ef94f54289e38a26649d24eeaaca99ba91229f5ebb096c046bdc582
|
4
|
+
data.tar.gz: 9a88847a58121a1516b95fc1abac1fa89d4a1bab5c4593f932fc804410ee8a57
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7830a7b52821efbea8e0f86e878588ef96718e845fd7a33575a4a5e92d350e26e36bb4b78f7ce78b58ff59654c62973c4eca58f21c63b958d44f4d8feff122cc
|
7
|
+
data.tar.gz: da8d30e84f9dea71eb498cccb6e03cb092e27e773008dc7533188020ee5cb59de774e4d2be32821e3fd82e28f4ccb426572695fd532dc7f7fff6479a392bca85
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,19 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## [1.7.0] - 2024-09-25
|
4
|
+
|
5
|
+
### Added
|
6
|
+
* Report total lines coverage percentage to Datadog ([#240][])
|
7
|
+
* add source location info to test suites ([#239][])
|
8
|
+
* Add pull_request extra tags for GitHub Actions ([#238][])
|
9
|
+
|
10
|
+
## [1.6.0] - 2024-09-20
|
11
|
+
|
12
|
+
|
13
|
+
### Added
|
14
|
+
* support logical names for test sessions ([#235][])
|
15
|
+
* Send internal vCPU count metric ([#236][])
|
16
|
+
|
3
17
|
## [1.5.0] - 2024-09-18
|
4
18
|
|
5
19
|
### Added
|
@@ -325,7 +339,9 @@ Currently test suite level visibility is not used by our instrumentation: it wil
|
|
325
339
|
|
326
340
|
- Ruby versions < 2.7 no longer supported ([#8][])
|
327
341
|
|
328
|
-
[Unreleased]: https://github.com/DataDog/datadog-ci-rb/compare/v1.
|
342
|
+
[Unreleased]: https://github.com/DataDog/datadog-ci-rb/compare/v1.7.0...main
|
343
|
+
[1.7.0]: https://github.com/DataDog/datadog-ci-rb/compare/v1.6.0...v1.7.0
|
344
|
+
[1.6.0]: https://github.com/DataDog/datadog-ci-rb/compare/v1.5.0...v1.6.0
|
329
345
|
[1.5.0]: https://github.com/DataDog/datadog-ci-rb/compare/v1.4.1...v1.5.0
|
330
346
|
[1.4.1]: https://github.com/DataDog/datadog-ci-rb/compare/v1.4.0...v1.4.1
|
331
347
|
[1.4.0]: https://github.com/DataDog/datadog-ci-rb/compare/v1.3.0...v1.4.0
|
@@ -467,4 +483,9 @@ Currently test suite level visibility is not used by our instrumentation: it wil
|
|
467
483
|
[#226]: https://github.com/DataDog/datadog-ci-rb/issues/226
|
468
484
|
[#227]: https://github.com/DataDog/datadog-ci-rb/issues/227
|
469
485
|
[#229]: https://github.com/DataDog/datadog-ci-rb/issues/229
|
470
|
-
[#231]: https://github.com/DataDog/datadog-ci-rb/issues/231
|
486
|
+
[#231]: https://github.com/DataDog/datadog-ci-rb/issues/231
|
487
|
+
[#235]: https://github.com/DataDog/datadog-ci-rb/issues/235
|
488
|
+
[#236]: https://github.com/DataDog/datadog-ci-rb/issues/236
|
489
|
+
[#238]: https://github.com/DataDog/datadog-ci-rb/issues/238
|
490
|
+
[#239]: https://github.com/DataDog/datadog-ci-rb/issues/239
|
491
|
+
[#240]: https://github.com/DataDog/datadog-ci-rb/issues/240
|
data/README.md
CHANGED
@@ -13,6 +13,7 @@ Learn more on our [official website](https://docs.datadoghq.com/tests/) and chec
|
|
13
13
|
- [Test Visibility](https://docs.datadoghq.com/tests/) - collect metrics and results for your tests
|
14
14
|
- [Intelligent test runner](https://docs.datadoghq.com/intelligent_test_runner/) - save time by selectively running only tests affected by code changes
|
15
15
|
- [Auto test retries](https://docs.datadoghq.com/tests/auto_test_retries/?tab=ruby) - retrying failing tests up to N times to avoid failing your build due to flaky tests
|
16
|
+
- [Early flake detection](https://docs.datadoghq.com/tests/early_flake_detection?tab=ruby) - Datadog’s test flakiness solution that identifies flakes early by running newly added tests multiple times
|
16
17
|
- [Search and manage CI tests](https://docs.datadoghq.com/tests/search/)
|
17
18
|
- [Enhance developer workflows](https://docs.datadoghq.com/tests/developer_workflows)
|
18
19
|
- [Flaky test management](https://docs.datadoghq.com/tests/guides/flaky_test_management/)
|
@@ -123,7 +123,8 @@ module Datadog
|
|
123
123
|
# @type ivar @test_optimisation: Datadog::CI::TestOptimisation::Component
|
124
124
|
@test_optimisation = build_test_optimisation(settings, test_visibility_api)
|
125
125
|
@test_visibility = TestVisibility::Component.new(
|
126
|
-
test_suite_level_visibility_enabled: !settings.ci.force_test_level_visibility
|
126
|
+
test_suite_level_visibility_enabled: !settings.ci.force_test_level_visibility,
|
127
|
+
logical_test_session_name: settings.ci.test_session_name
|
127
128
|
)
|
128
129
|
end
|
129
130
|
|
@@ -24,6 +24,11 @@ module Datadog
|
|
24
24
|
o.default false
|
25
25
|
end
|
26
26
|
|
27
|
+
option :test_session_name do |o|
|
28
|
+
o.type :string, nilable: true
|
29
|
+
o.env CI::Ext::Settings::ENV_TEST_SESSION_NAME
|
30
|
+
end
|
31
|
+
|
27
32
|
option :agentless_mode_enabled do |o|
|
28
33
|
o.type :bool
|
29
34
|
o.env CI::Ext::Settings::ENV_AGENTLESS_MODE_ENABLED
|
@@ -70,7 +70,12 @@ module Datadog
|
|
70
70
|
tags[CI::Ext::Test::TAG_PARAMETERS] = Utils::TestRun.test_parameters(arguments: parameters)
|
71
71
|
end
|
72
72
|
|
73
|
-
|
73
|
+
unless same_test_suite_as_current?(test_suite_name)
|
74
|
+
start_test_suite(
|
75
|
+
test_suite_name,
|
76
|
+
tags: test_suite_source_file_tags(event.test_case)
|
77
|
+
)
|
78
|
+
end
|
74
79
|
|
75
80
|
test_span = test_visibility_component.trace_test(
|
76
81
|
event.test_case.name,
|
@@ -146,10 +151,10 @@ module Datadog
|
|
146
151
|
test_session.finish
|
147
152
|
end
|
148
153
|
|
149
|
-
def start_test_suite(test_suite_name)
|
154
|
+
def start_test_suite(test_suite_name, tags: {})
|
150
155
|
finish_current_test_suite
|
151
156
|
|
152
|
-
@current_test_suite = test_visibility_component.start_test_suite(test_suite_name)
|
157
|
+
@current_test_suite = test_visibility_component.start_test_suite(test_suite_name, tags: tags)
|
153
158
|
end
|
154
159
|
|
155
160
|
def finish_current_test_suite
|
@@ -201,6 +206,23 @@ module Datadog
|
|
201
206
|
def test_visibility_component
|
202
207
|
Datadog.send(:components).test_visibility
|
203
208
|
end
|
209
|
+
|
210
|
+
def test_suite_source_file_tags(test_case)
|
211
|
+
if test_case.respond_to?(:parent_locations)
|
212
|
+
# supported in cucumber >= 9.0
|
213
|
+
source_file = test_case.parent_locations.file
|
214
|
+
line_number = test_case.parent_locations.line.to_s
|
215
|
+
else
|
216
|
+
# fallback for cucumber < 9.0
|
217
|
+
source_file = test_case.location.file
|
218
|
+
line_number = "1"
|
219
|
+
end
|
220
|
+
|
221
|
+
{
|
222
|
+
CI::Ext::Test::TAG_SOURCE_FILE => Git::LocalRepository.relative_to_root(source_file),
|
223
|
+
CI::Ext::Test::TAG_SOURCE_START => line_number.to_s
|
224
|
+
}
|
225
|
+
end
|
204
226
|
end
|
205
227
|
end
|
206
228
|
end
|
@@ -6,7 +6,7 @@ module Datadog
|
|
6
6
|
module Minitest
|
7
7
|
module Helpers
|
8
8
|
def self.test_suite_name(klass, method_name)
|
9
|
-
source_location = extract_source_location_from_class(klass)
|
9
|
+
source_location = extract_source_location_from_class(klass)&.first
|
10
10
|
# if we are in anonymous class, fallback to the method source location
|
11
11
|
if source_location.nil?
|
12
12
|
source_location, = klass.instance_method(method_name).source_location
|
@@ -23,11 +23,11 @@ module Datadog
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def self.extract_source_location_from_class(klass)
|
26
|
-
return
|
26
|
+
return [] if klass.nil? || klass.name.nil?
|
27
27
|
|
28
|
-
klass.const_source_location(klass.name)
|
28
|
+
klass.const_source_location(klass.name)
|
29
29
|
rescue
|
30
|
-
|
30
|
+
[]
|
31
31
|
end
|
32
32
|
end
|
33
33
|
end
|
@@ -18,8 +18,21 @@ module Datadog
|
|
18
18
|
return super if method.nil?
|
19
19
|
|
20
20
|
test_suite_name = Helpers.test_suite_name(self, method)
|
21
|
-
|
22
|
-
|
21
|
+
source_file, line_number = Helpers.extract_source_location_from_class(self)
|
22
|
+
|
23
|
+
test_suite_tags = if source_file
|
24
|
+
{
|
25
|
+
CI::Ext::Test::TAG_SOURCE_FILE => (Git::LocalRepository.relative_to_root(source_file) if source_file),
|
26
|
+
CI::Ext::Test::TAG_SOURCE_START => line_number&.to_s
|
27
|
+
}
|
28
|
+
else
|
29
|
+
{}
|
30
|
+
end
|
31
|
+
|
32
|
+
test_suite = test_visibility_component.start_test_suite(
|
33
|
+
test_suite_name,
|
34
|
+
tags: test_suite_tags
|
35
|
+
)
|
23
36
|
|
24
37
|
results = super
|
25
38
|
return results unless test_suite
|
@@ -21,7 +21,13 @@ module Datadog
|
|
21
21
|
return super unless top_level?
|
22
22
|
|
23
23
|
suite_name = "#{description} at #{file_path}"
|
24
|
-
test_suite = test_visibility_component.start_test_suite(
|
24
|
+
test_suite = test_visibility_component.start_test_suite(
|
25
|
+
suite_name,
|
26
|
+
tags: {
|
27
|
+
CI::Ext::Test::TAG_SOURCE_FILE => Git::LocalRepository.relative_to_root(metadata[:file_path]),
|
28
|
+
CI::Ext::Test::TAG_SOURCE_START => metadata[:line_number].to_s
|
29
|
+
}
|
30
|
+
)
|
25
31
|
|
26
32
|
success = super
|
27
33
|
return success unless test_suite
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "datadog/core"
|
4
|
+
|
5
|
+
require_relative "../ext"
|
6
|
+
require_relative "../../settings"
|
7
|
+
|
8
|
+
module Datadog
|
9
|
+
module CI
|
10
|
+
module Contrib
|
11
|
+
module Simplecov
|
12
|
+
module Configuration
|
13
|
+
# Custom settings for the Simplecov integration
|
14
|
+
# @public_api
|
15
|
+
class Settings < Datadog::CI::Contrib::Settings
|
16
|
+
option :enabled do |o|
|
17
|
+
o.type :bool
|
18
|
+
o.env Ext::ENV_ENABLED
|
19
|
+
o.default true
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Datadog
|
4
|
+
module CI
|
5
|
+
module Contrib
|
6
|
+
module Simplecov
|
7
|
+
# Simplecov integration constants
|
8
|
+
# @public_api
|
9
|
+
module Ext
|
10
|
+
ENV_ENABLED = "DD_CIVISIBILITY_SIMPLECOV_INSTRUMENTATION_ENABLED"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../integration"
|
4
|
+
require_relative "configuration/settings"
|
5
|
+
require_relative "patcher"
|
6
|
+
|
7
|
+
module Datadog
|
8
|
+
module CI
|
9
|
+
module Contrib
|
10
|
+
module Simplecov
|
11
|
+
# Description of Simplecov integration
|
12
|
+
class Integration
|
13
|
+
include Datadog::CI::Contrib::Integration
|
14
|
+
|
15
|
+
MINIMUM_VERSION = Gem::Version.new("0.18.0")
|
16
|
+
|
17
|
+
register_as :simplecov
|
18
|
+
|
19
|
+
def self.version
|
20
|
+
Gem.loaded_specs["simplecov"]&.version
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.loaded?
|
24
|
+
!defined?(::SimpleCov).nil?
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.compatible?
|
28
|
+
super && version >= MINIMUM_VERSION
|
29
|
+
end
|
30
|
+
|
31
|
+
# additional instrumentations for test helpers are auto instrumented on test session start
|
32
|
+
def auto_instrument?
|
33
|
+
true
|
34
|
+
end
|
35
|
+
|
36
|
+
def new_configuration
|
37
|
+
Configuration::Settings.new
|
38
|
+
end
|
39
|
+
|
40
|
+
def patcher
|
41
|
+
Patcher
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "datadog/tracing/contrib/patcher"
|
4
|
+
|
5
|
+
require_relative "result_extractor"
|
6
|
+
|
7
|
+
module Datadog
|
8
|
+
module CI
|
9
|
+
module Contrib
|
10
|
+
module Simplecov
|
11
|
+
# Patcher enables patching of 'SimpleCov' module.
|
12
|
+
module Patcher
|
13
|
+
include Datadog::Tracing::Contrib::Patcher
|
14
|
+
|
15
|
+
module_function
|
16
|
+
|
17
|
+
def target_version
|
18
|
+
Integration.version
|
19
|
+
end
|
20
|
+
|
21
|
+
def patch
|
22
|
+
::SimpleCov.include(ResultExtractor)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "coverage"
|
4
|
+
|
5
|
+
module Datadog
|
6
|
+
module CI
|
7
|
+
module Contrib
|
8
|
+
module Simplecov
|
9
|
+
module ResultExtractor
|
10
|
+
def self.included(base)
|
11
|
+
base.singleton_class.prepend(ClassMethods)
|
12
|
+
end
|
13
|
+
|
14
|
+
module ClassMethods
|
15
|
+
def __dd_peek_result
|
16
|
+
unless datadog_configuration[:enabled]
|
17
|
+
Datadog.logger.debug("SimpleCov instrumentation is disabled")
|
18
|
+
return nil
|
19
|
+
end
|
20
|
+
|
21
|
+
result = ::SimpleCov::UselessResultsRemover.call(
|
22
|
+
::SimpleCov::ResultAdapter.call(::Coverage.peek_result)
|
23
|
+
)
|
24
|
+
|
25
|
+
::SimpleCov::Result.new(add_not_loaded_files(result))
|
26
|
+
end
|
27
|
+
|
28
|
+
def datadog_configuration
|
29
|
+
Datadog.configuration.ci[:simplecov]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -49,6 +49,11 @@ module Datadog
|
|
49
49
|
Git::TAG_COMMIT_SHA => @provider.git_commit_sha
|
50
50
|
}
|
51
51
|
|
52
|
+
# set additional tags if provider needs them
|
53
|
+
@provider.additional_tags.each do |key, value|
|
54
|
+
@tags[key] = value
|
55
|
+
end
|
56
|
+
|
52
57
|
# Normalize Git references and filter sensitive data
|
53
58
|
normalize_git!
|
54
59
|
# Expand ~
|
@@ -75,6 +75,30 @@ module Datadog
|
|
75
75
|
}.reject { |_, v| v.nil? }.to_json
|
76
76
|
end
|
77
77
|
|
78
|
+
def additional_tags
|
79
|
+
base_ref = env["GITHUB_BASE_REF"]
|
80
|
+
return {} if base_ref.nil? || base_ref.empty?
|
81
|
+
|
82
|
+
# @type var result: Hash[String, String]
|
83
|
+
result = {
|
84
|
+
Git::TAG_PULL_REQUEST_BASE_BRANCH => base_ref
|
85
|
+
}
|
86
|
+
|
87
|
+
event_path = env["GITHUB_EVENT_PATH"]
|
88
|
+
event_json = JSON.parse(File.read(event_path))
|
89
|
+
|
90
|
+
head_sha = event_json.dig("pull_request", "head", "sha")
|
91
|
+
result[Git::TAG_COMMIT_HEAD_SHA] = head_sha if head_sha
|
92
|
+
|
93
|
+
base_sha = event_json.dig("pull_request", "base", "sha")
|
94
|
+
result[Git::TAG_PULL_REQUEST_BASE_BRANCH_SHA] = base_sha if base_sha
|
95
|
+
|
96
|
+
result
|
97
|
+
rescue => e
|
98
|
+
Datadog.logger.error("Failed to extract additional tags from GitHub Actions: #{e}")
|
99
|
+
{}
|
100
|
+
end
|
101
|
+
|
78
102
|
private
|
79
103
|
|
80
104
|
def github_server_url
|
data/lib/datadog/ci/ext/git.rb
CHANGED
@@ -20,6 +20,11 @@ module Datadog
|
|
20
20
|
TAG_COMMIT_MESSAGE = "git.commit.message"
|
21
21
|
TAG_COMMIT_SHA = "git.commit.sha"
|
22
22
|
|
23
|
+
# additional tags that we use for github actions jobs with "pull_request" target
|
24
|
+
TAG_COMMIT_HEAD_SHA = "git.commit.head_sha"
|
25
|
+
TAG_PULL_REQUEST_BASE_BRANCH = "git.pull_request.base_branch"
|
26
|
+
TAG_PULL_REQUEST_BASE_BRANCH_SHA = "git.pull_request.base_branch_sha"
|
27
|
+
|
23
28
|
ENV_REPOSITORY_URL = "DD_GIT_REPOSITORY_URL"
|
24
29
|
ENV_COMMIT_SHA = "DD_GIT_COMMIT_SHA"
|
25
30
|
ENV_BRANCH = "DD_GIT_BRANCH"
|
@@ -19,6 +19,7 @@ module Datadog
|
|
19
19
|
ENV_RETRY_FAILED_TESTS_MAX_ATTEMPTS = "DD_CIVISIBILITY_FLAKY_RETRY_COUNT"
|
20
20
|
ENV_RETRY_FAILED_TESTS_TOTAL_LIMIT = "DD_CIVISIBILITY_TOTAL_FLAKY_RETRY_COUNT"
|
21
21
|
ENV_RETRY_NEW_TESTS_ENABLED = "DD_CIVISIBILITY_EARLY_FLAKE_DETECTION_ENABLED"
|
22
|
+
ENV_TEST_SESSION_NAME = "DD_TEST_SESSION_NAME"
|
22
23
|
|
23
24
|
# Source: https://docs.datadoghq.com/getting_started/site/
|
24
25
|
DD_SITE_ALLOWLIST = %w[
|
data/lib/datadog/ci/ext/test.rb
CHANGED
@@ -64,10 +64,19 @@ module Datadog
|
|
64
64
|
TAG_EARLY_FLAKE_ENABLED = "test.early_flake.enabled" # true if early flake detection is enabled
|
65
65
|
TAG_EARLY_FLAKE_ABORT_REASON = "test.early_flake.abort_reason" # reason why early flake detection was aborted
|
66
66
|
|
67
|
+
# Tags for total code coverage
|
68
|
+
TAG_CODE_COVERAGE_LINES_PCT = "test.code_coverage.lines_pct"
|
69
|
+
|
67
70
|
# internal APM tag to mark a span as a test span
|
68
71
|
TAG_SPAN_KIND = "span.kind"
|
69
72
|
SPAN_KIND_TEST = "test"
|
70
73
|
|
74
|
+
# common tags that are serialized directly in msgpack header in metadata field
|
75
|
+
METADATA_TAG_TEST_SESSION_NAME = "test_session.name"
|
76
|
+
|
77
|
+
# internal metric with the number of virtual CPUs
|
78
|
+
METRIC_CPU_COUNT = "_dd.host.vcpu_count"
|
79
|
+
|
71
80
|
# tags that are common for the whole session and can be inherited from the test session
|
72
81
|
INHERITABLE_TAGS = [TAG_FRAMEWORK, TAG_FRAMEWORK_VERSION].freeze
|
73
82
|
|
data/lib/datadog/ci/span.rb
CHANGED
@@ -114,6 +114,13 @@ module Datadog
|
|
114
114
|
tracer_span.clear_tag(key)
|
115
115
|
end
|
116
116
|
|
117
|
+
# Gets metric value by key.
|
118
|
+
# @param [String] key the key of the metric.
|
119
|
+
# @return [Numeric] value the value of the metric.
|
120
|
+
def get_metric(key)
|
121
|
+
tracer_span.get_metric(key)
|
122
|
+
end
|
123
|
+
|
117
124
|
# Sets metric value by key.
|
118
125
|
# @param [String] key the key of the metric.
|
119
126
|
# @param [Numeric] value the value of the metric.
|
@@ -183,6 +190,13 @@ module Datadog
|
|
183
190
|
tracer_span.get_tag(Ext::Test::TAG_RUNTIME_VERSION)
|
184
191
|
end
|
185
192
|
|
193
|
+
# Source file path where the test or test suite defined (relative to git repository root).
|
194
|
+
# @return [String] the source file path of the test
|
195
|
+
# @return [nil] if the source file path is not found
|
196
|
+
def source_file
|
197
|
+
get_tag(Ext::Test::TAG_SOURCE_FILE)
|
198
|
+
end
|
199
|
+
|
186
200
|
def set_environment_runtime_tags
|
187
201
|
tracer_span.set_tag(Ext::Test::TAG_OS_ARCHITECTURE, ::RbConfig::CONFIG["host_cpu"])
|
188
202
|
tracer_span.set_tag(Ext::Test::TAG_OS_PLATFORM, ::RbConfig::CONFIG["host_os"])
|
data/lib/datadog/ci/test.rb
CHANGED
@@ -57,13 +57,6 @@ module Datadog
|
|
57
57
|
get_tag(Ext::Test::TAG_TEST_SESSION_ID)
|
58
58
|
end
|
59
59
|
|
60
|
-
# Source file path of the test relative to git repository root.
|
61
|
-
# @return [String] the source file path of the test
|
62
|
-
# @return [nil] if the source file path is not found
|
63
|
-
def source_file
|
64
|
-
get_tag(Ext::Test::TAG_SOURCE_FILE)
|
65
|
-
end
|
66
|
-
|
67
60
|
# Returns "true" if the test is skipped by the intelligent test runner.
|
68
61
|
# @return [Boolean] true if the test is skipped by the intelligent test runner, false otherwise.
|
69
62
|
def skipped_by_itr?
|
@@ -28,6 +28,24 @@ module Datadog
|
|
28
28
|
get_tag(Ext::Test::TAG_COMMAND)
|
29
29
|
end
|
30
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
|
+
|
31
49
|
def skipping_tests?
|
32
50
|
get_tag(Ext::Test::TAG_ITR_TEST_SKIPPING_ENABLED) == "true"
|
33
51
|
end
|
@@ -4,6 +4,7 @@ require "rbconfig"
|
|
4
4
|
|
5
5
|
require_relative "context"
|
6
6
|
require_relative "telemetry"
|
7
|
+
require_relative "total_coverage"
|
7
8
|
|
8
9
|
require_relative "../codeowners/parser"
|
9
10
|
require_relative "../contrib/contrib"
|
@@ -17,15 +18,17 @@ module Datadog
|
|
17
18
|
module TestVisibility
|
18
19
|
# Common behavior for CI tests
|
19
20
|
class Component
|
20
|
-
attr_reader :test_suite_level_visibility_enabled
|
21
|
+
attr_reader :test_suite_level_visibility_enabled, :logical_test_session_name
|
21
22
|
|
22
23
|
def initialize(
|
23
24
|
test_suite_level_visibility_enabled: false,
|
24
|
-
codeowners: Codeowners::Parser.new(Git::LocalRepository.root).parse
|
25
|
+
codeowners: Codeowners::Parser.new(Git::LocalRepository.root).parse,
|
26
|
+
logical_test_session_name: nil
|
25
27
|
)
|
26
28
|
@test_suite_level_visibility_enabled = test_suite_level_visibility_enabled
|
27
29
|
@context = Context.new
|
28
30
|
@codeowners = codeowners
|
31
|
+
@logical_test_session_name = logical_test_session_name
|
29
32
|
end
|
30
33
|
|
31
34
|
def start_test_session(service: nil, tags: {}, total_tests_count: 0)
|
@@ -152,6 +155,9 @@ module Datadog
|
|
152
155
|
Telemetry.test_session_started(test_session)
|
153
156
|
Telemetry.event_created(test_session)
|
154
157
|
|
158
|
+
# sets logical test session name if none provided by the user
|
159
|
+
override_logical_test_session_name!(test_session) if logical_test_session_name.nil?
|
160
|
+
|
155
161
|
# signal Remote::Component to configure the library
|
156
162
|
remote.configure(test_session)
|
157
163
|
end
|
@@ -161,6 +167,8 @@ module Datadog
|
|
161
167
|
end
|
162
168
|
|
163
169
|
def on_test_suite_started(test_suite)
|
170
|
+
set_codeowners(test_suite)
|
171
|
+
|
164
172
|
Telemetry.event_created(test_suite)
|
165
173
|
end
|
166
174
|
|
@@ -181,6 +189,8 @@ module Datadog
|
|
181
189
|
def on_test_session_finished(test_session)
|
182
190
|
test_optimisation.write_test_session_tags(test_session)
|
183
191
|
|
192
|
+
TotalCoverage.extract_lines_pct(test_session)
|
193
|
+
|
184
194
|
Telemetry.event_finished(test_session)
|
185
195
|
end
|
186
196
|
|
@@ -218,10 +228,10 @@ module Datadog
|
|
218
228
|
end
|
219
229
|
end
|
220
230
|
|
221
|
-
def set_codeowners(
|
222
|
-
source =
|
231
|
+
def set_codeowners(span)
|
232
|
+
source = span.source_file
|
223
233
|
owners = @codeowners.list_owners(source) if source
|
224
|
-
|
234
|
+
span.set_tag(Ext::Test::TAG_CODEOWNERS, owners) unless owners.nil?
|
225
235
|
end
|
226
236
|
|
227
237
|
def fix_test_suite!(test)
|
@@ -269,6 +279,14 @@ module Datadog
|
|
269
279
|
end
|
270
280
|
end
|
271
281
|
|
282
|
+
def override_logical_test_session_name!(test_session)
|
283
|
+
@logical_test_session_name = test_session.test_command
|
284
|
+
ci_job_name = test_session.ci_job_name
|
285
|
+
if ci_job_name
|
286
|
+
@logical_test_session_name = "#{ci_job_name}-#{@logical_test_session_name}"
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
272
290
|
def test_optimisation
|
273
291
|
Datadog.send(:components).test_optimisation
|
274
292
|
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
|
@@ -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
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../ext/test"
|
4
|
+
|
5
|
+
module Datadog
|
6
|
+
module CI
|
7
|
+
module TestVisibility
|
8
|
+
module TotalCoverage
|
9
|
+
def self.extract_lines_pct(test_session)
|
10
|
+
unless defined?(::SimpleCov)
|
11
|
+
Datadog.logger.debug("SimpleCov is not loaded, skipping code coverage extraction")
|
12
|
+
return
|
13
|
+
end
|
14
|
+
|
15
|
+
unless ::SimpleCov.running
|
16
|
+
Datadog.logger.debug("SimpleCov is not running, skipping code coverage extraction")
|
17
|
+
return
|
18
|
+
end
|
19
|
+
|
20
|
+
unless ::SimpleCov.respond_to?(:__dd_peek_result)
|
21
|
+
Datadog.logger.debug("SimpleCov is not patched, skipping code coverage extraction")
|
22
|
+
return
|
23
|
+
end
|
24
|
+
|
25
|
+
result = ::SimpleCov.__dd_peek_result
|
26
|
+
unless result
|
27
|
+
Datadog.logger.debug("SimpleCov result is nil, skipping code coverage extraction")
|
28
|
+
return
|
29
|
+
end
|
30
|
+
|
31
|
+
test_session.set_tag(Ext::Test::TAG_CODE_COVERAGE_LINES_PCT, result.covered_percent)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -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
|
@@ -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
@@ -410,6 +410,7 @@ require_relative "ci/contrib/cucumber/integration"
|
|
410
410
|
require_relative "ci/contrib/rspec/integration"
|
411
411
|
require_relative "ci/contrib/minitest/integration"
|
412
412
|
require_relative "ci/contrib/selenium/integration"
|
413
|
+
require_relative "ci/contrib/simplecov/integration"
|
413
414
|
|
414
415
|
# Configuration extensions
|
415
416
|
require_relative "ci/configuration/extensions"
|
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.7.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-09-
|
11
|
+
date: 2024-09-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: datadog
|
@@ -103,6 +103,11 @@ files:
|
|
103
103
|
- lib/datadog/ci/contrib/selenium/patcher.rb
|
104
104
|
- lib/datadog/ci/contrib/selenium/rum.rb
|
105
105
|
- lib/datadog/ci/contrib/settings.rb
|
106
|
+
- lib/datadog/ci/contrib/simplecov/configuration/settings.rb
|
107
|
+
- lib/datadog/ci/contrib/simplecov/ext.rb
|
108
|
+
- lib/datadog/ci/contrib/simplecov/integration.rb
|
109
|
+
- lib/datadog/ci/contrib/simplecov/patcher.rb
|
110
|
+
- lib/datadog/ci/contrib/simplecov/result_extractor.rb
|
106
111
|
- lib/datadog/ci/ext/app_types.rb
|
107
112
|
- lib/datadog/ci/ext/environment.rb
|
108
113
|
- lib/datadog/ci/ext/environment/extractor.rb
|
@@ -179,6 +184,7 @@ files:
|
|
179
184
|
- lib/datadog/ci/test_visibility/store/global.rb
|
180
185
|
- lib/datadog/ci/test_visibility/store/local.rb
|
181
186
|
- lib/datadog/ci/test_visibility/telemetry.rb
|
187
|
+
- lib/datadog/ci/test_visibility/total_coverage.rb
|
182
188
|
- lib/datadog/ci/test_visibility/transport.rb
|
183
189
|
- lib/datadog/ci/transport/adapters/net.rb
|
184
190
|
- lib/datadog/ci/transport/adapters/net_http_client.rb
|