datadog-ci 0.3.0 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +89 -1
  3. data/README.md +57 -34
  4. data/lib/datadog/ci/concurrent_span.rb +59 -0
  5. data/lib/datadog/ci/configuration/components.rb +40 -1
  6. data/lib/datadog/ci/configuration/extensions.rb +21 -0
  7. data/lib/datadog/ci/configuration/settings.rb +7 -1
  8. data/lib/datadog/ci/contrib/cucumber/configuration/settings.rb +12 -1
  9. data/lib/datadog/ci/contrib/cucumber/formatter.rb +22 -29
  10. data/lib/datadog/ci/contrib/minitest/configuration/settings.rb +10 -1
  11. data/lib/datadog/ci/contrib/minitest/hooks.rb +15 -25
  12. data/lib/datadog/ci/contrib/rspec/configuration/settings.rb +10 -1
  13. data/lib/datadog/ci/contrib/rspec/example.rb +13 -18
  14. data/lib/datadog/ci/contrib/settings.rb +2 -0
  15. data/lib/datadog/ci/ext/app_types.rb +5 -0
  16. data/lib/datadog/ci/ext/environment/extractor.rb +5 -10
  17. data/lib/datadog/ci/ext/environment/providers/github_actions.rb +13 -4
  18. data/lib/datadog/ci/ext/settings.rb +11 -0
  19. data/lib/datadog/ci/ext/test.rb +12 -1
  20. data/lib/datadog/ci/null_span.rb +63 -0
  21. data/lib/datadog/ci/span.rb +117 -0
  22. data/lib/datadog/ci/test.rb +25 -0
  23. data/lib/datadog/ci/test_module.rb +23 -0
  24. data/lib/datadog/ci/test_session.rb +36 -0
  25. data/lib/datadog/ci/test_suite.rb +25 -0
  26. data/lib/datadog/ci/test_visibility/context/global.rb +82 -0
  27. data/lib/datadog/ci/test_visibility/context/local.rb +52 -0
  28. data/lib/datadog/ci/test_visibility/recorder.rb +293 -0
  29. data/lib/datadog/ci/test_visibility/serializers/base.rb +100 -12
  30. data/lib/datadog/ci/test_visibility/serializers/factories/test_suite_level.rb +37 -0
  31. data/lib/datadog/ci/test_visibility/serializers/span.rb +2 -16
  32. data/lib/datadog/ci/test_visibility/serializers/test_module.rb +46 -0
  33. data/lib/datadog/ci/test_visibility/serializers/test_session.rb +46 -0
  34. data/lib/datadog/ci/test_visibility/serializers/test_suite.rb +46 -0
  35. data/lib/datadog/ci/test_visibility/serializers/test_v1.rb +3 -17
  36. data/lib/datadog/ci/test_visibility/serializers/test_v2.rb +38 -0
  37. data/lib/datadog/ci/test_visibility/transport.rb +4 -4
  38. data/lib/datadog/ci/utils/test_run.rb +15 -0
  39. data/lib/datadog/ci/utils/url.rb +15 -0
  40. data/lib/datadog/ci/version.rb +2 -2
  41. data/lib/datadog/ci.rb +378 -7
  42. data/sig/datadog/ci/concurrent_span.rbs +23 -0
  43. data/sig/datadog/ci/configuration/components.rbs +6 -0
  44. data/sig/datadog/ci/configuration/extensions.rbs +9 -0
  45. data/sig/datadog/ci/ext/app_types.rbs +6 -1
  46. data/sig/datadog/ci/ext/environment/extractor.rbs +0 -2
  47. data/sig/datadog/ci/ext/environment/providers/github_actions.rbs +5 -0
  48. data/sig/datadog/ci/ext/settings.rbs +3 -0
  49. data/sig/datadog/ci/ext/test.rbs +15 -0
  50. data/sig/datadog/ci/null_span.rbs +37 -0
  51. data/sig/datadog/ci/span.rbs +39 -0
  52. data/sig/datadog/ci/test.rbs +7 -0
  53. data/sig/datadog/ci/test_module.rbs +6 -0
  54. data/sig/datadog/ci/test_session.rbs +9 -0
  55. data/sig/datadog/ci/test_suite.rbs +6 -0
  56. data/sig/datadog/ci/test_visibility/context/global.rbs +39 -0
  57. data/sig/datadog/ci/test_visibility/context/local.rbs +23 -0
  58. data/sig/datadog/ci/test_visibility/recorder.rbs +85 -0
  59. data/sig/datadog/ci/test_visibility/serializers/base.rbs +26 -5
  60. data/sig/datadog/ci/test_visibility/serializers/factories/test_suite_level.rbs +13 -0
  61. data/sig/datadog/ci/test_visibility/serializers/test_module.rbs +26 -0
  62. data/sig/datadog/ci/test_visibility/serializers/test_session.rbs +26 -0
  63. data/sig/datadog/ci/test_visibility/serializers/test_suite.rbs +26 -0
  64. data/sig/datadog/ci/test_visibility/serializers/test_v1.rbs +1 -1
  65. data/sig/datadog/ci/test_visibility/serializers/test_v2.rbs +25 -0
  66. data/sig/datadog/ci/test_visibility/transport.rbs +3 -3
  67. data/sig/datadog/ci/utils/test_run.rbs +11 -0
  68. data/sig/datadog/ci/utils/url.rbs +9 -0
  69. data/sig/datadog/ci.rbs +31 -3
  70. metadata +38 -6
  71. data/lib/datadog/ci/extensions.rb +0 -19
  72. data/lib/datadog/ci/recorder.rb +0 -83
  73. data/sig/datadog/ci/extensions.rbs +0 -7
  74. data/sig/datadog/ci/recorder.rbs +0 -18
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "../../recorder"
4
3
  require_relative "../../ext/test"
5
4
  require_relative "ext"
6
5
 
@@ -19,41 +18,32 @@ module Datadog
19
18
  path, = method(name).source_location
20
19
  test_suite = Pathname.new(path.to_s).relative_path_from(Pathname.pwd).to_s
21
20
 
22
- span = CI::Recorder.trace(
23
- configuration[:operation_name],
24
- {
25
- span_options: {
26
- resource: test_name,
27
- service: configuration[:service_name]
28
- },
29
- framework: Ext::FRAMEWORK,
30
- framework_version: CI::Contrib::Minitest::Integration.version.to_s,
31
- test_name: test_name,
32
- test_suite: test_suite,
33
- test_type: Ext::TEST_TYPE
34
- }
21
+ CI.start_test(
22
+ test_name,
23
+ test_suite,
24
+ tags: {
25
+ CI::Ext::Test::TAG_FRAMEWORK => Ext::FRAMEWORK,
26
+ CI::Ext::Test::TAG_FRAMEWORK_VERSION => CI::Contrib::Minitest::Integration.version.to_s,
27
+ CI::Ext::Test::TAG_TYPE => Ext::TEST_TYPE
28
+ },
29
+ service: configuration[:service_name]
35
30
  )
36
-
37
- Thread.current[:_datadog_test_span] = span
38
31
  end
39
32
 
40
33
  def after_teardown
41
- span = Thread.current[:_datadog_test_span]
42
- return super unless span
43
-
44
- Thread.current[:_datadog_test_span] = nil
34
+ test_span = CI.active_test
35
+ return super unless test_span
45
36
 
46
37
  case result_code
47
38
  when "."
48
- CI::Recorder.passed!(span)
39
+ test_span.passed!
49
40
  when "E", "F"
50
- CI::Recorder.failed!(span, failure)
41
+ test_span.failed!(exception: failure)
51
42
  when "S"
52
- CI::Recorder.skipped!(span)
53
- span.set_tag(CI::Ext::Test::TAG_SKIP_REASON, failure.message)
43
+ test_span.skipped!(reason: failure.message)
54
44
  end
55
45
 
56
- span.finish
46
+ test_span.finish
57
47
 
58
48
  super
59
49
  end
@@ -9,7 +9,7 @@ module Datadog
9
9
  module RSpec
10
10
  module Configuration
11
11
  # Custom settings for the RSpec integration
12
- # TODO: mark as `@public_api` when GA
12
+ # @public_api
13
13
  class Settings < Datadog::CI::Contrib::Settings
14
14
  option :enabled do |o|
15
15
  o.type :bool
@@ -22,10 +22,19 @@ module Datadog
22
22
  o.default { Datadog.configuration.service_without_fallback || Ext::SERVICE_NAME }
23
23
  end
24
24
 
25
+ # @deprecated Will be removed in 1.0
25
26
  option :operation_name do |o|
26
27
  o.type :string
27
28
  o.env Ext::ENV_OPERATION_NAME
28
29
  o.default Ext::OPERATION_NAME
30
+
31
+ o.after_set do |value|
32
+ if value && value != Ext::OPERATION_NAME
33
+ Datadog::Core.log_deprecation do
34
+ "The operation_name setting has no effect and will be removed in 1.0"
35
+ end
36
+ end
37
+ end
29
38
  end
30
39
  end
31
40
  end
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "../../recorder"
4
3
  require_relative "../../ext/test"
5
4
  require_relative "ext"
6
5
 
@@ -25,29 +24,25 @@ module Datadog
25
24
  test_name += " #{description}"
26
25
  end
27
26
 
28
- CI::Recorder.trace(
29
- configuration[:operation_name],
30
- {
31
- span_options: {
32
- resource: test_name,
33
- service: configuration[:service_name]
34
- },
35
- framework: Ext::FRAMEWORK,
36
- framework_version: CI::Contrib::RSpec::Integration.version.to_s,
37
- test_name: test_name,
38
- test_suite: metadata[:example_group][:file_path],
39
- test_type: Ext::TEST_TYPE
40
- }
41
- ) do |span|
27
+ CI.trace_test(
28
+ test_name,
29
+ metadata[:example_group][:file_path],
30
+ tags: {
31
+ CI::Ext::Test::TAG_FRAMEWORK => Ext::FRAMEWORK,
32
+ CI::Ext::Test::TAG_FRAMEWORK_VERSION => CI::Contrib::RSpec::Integration.version.to_s,
33
+ CI::Ext::Test::TAG_TYPE => Ext::TEST_TYPE
34
+ },
35
+ service: configuration[:service_name]
36
+ ) do |test_span|
42
37
  result = super
43
38
 
44
39
  case execution_result.status
45
40
  when :passed
46
- CI::Recorder.passed!(span)
41
+ test_span.passed!
47
42
  when :failed
48
- CI::Recorder.failed!(span, execution_result.exception)
43
+ test_span.failed!(exception: execution_result.exception)
49
44
  else
50
- CI::Recorder.skipped!(span, execution_result.exception) if execution_result.example_skipped?
45
+ test_span.skipped!(exception: execution_result.exception) if execution_result.example_skipped?
51
46
  end
52
47
 
53
48
  result
@@ -10,6 +10,8 @@ module Datadog
10
10
 
11
11
  option :enabled, default: true
12
12
  option :service_name
13
+
14
+ # @deprecated Will be removed in 1.0
13
15
  option :operation_name
14
16
 
15
17
  def configure(options = {})
@@ -5,6 +5,11 @@ module Datadog
5
5
  module Ext
6
6
  module AppTypes
7
7
  TYPE_TEST = "test"
8
+ TYPE_TEST_SESSION = "test_session_end"
9
+ TYPE_TEST_MODULE = "test_module_end"
10
+ TYPE_TEST_SUITE = "test_suite_end"
11
+
12
+ CI_SPAN_TYPES = [TYPE_TEST, TYPE_TEST_SESSION, TYPE_TEST_MODULE, TYPE_TEST_SUITE].freeze
8
13
  end
9
14
  end
10
15
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require_relative "../git"
4
4
  require_relative "../../utils/git"
5
+ require_relative "../../utils/url"
5
6
  require_relative "providers"
6
7
 
7
8
  module Datadog
@@ -68,14 +69,14 @@ module Datadog
68
69
 
69
70
  def normalize_git!
70
71
  branch_ref = @tags[Git::TAG_BRANCH]
71
- if Datadog::CI::Utils::Git.is_git_tag?(branch_ref)
72
+ if Utils::Git.is_git_tag?(branch_ref)
72
73
  @tags[Git::TAG_TAG] = branch_ref
73
74
  @tags.delete(Git::TAG_BRANCH)
74
75
  end
75
76
 
76
- @tags[Git::TAG_TAG] = Datadog::CI::Utils::Git.normalize_ref(@tags[Git::TAG_TAG])
77
- @tags[Git::TAG_BRANCH] = Datadog::CI::Utils::Git.normalize_ref(@tags[Git::TAG_BRANCH])
78
- @tags[Git::TAG_REPOSITORY_URL] = filter_sensitive_info(
77
+ @tags[Git::TAG_TAG] = Utils::Git.normalize_ref(@tags[Git::TAG_TAG])
78
+ @tags[Git::TAG_BRANCH] = Utils::Git.normalize_ref(@tags[Git::TAG_BRANCH])
79
+ @tags[Git::TAG_REPOSITORY_URL] = Utils::Url.filter_sensitive_info(
79
80
  @tags[Git::TAG_REPOSITORY_URL]
80
81
  )
81
82
  end
@@ -87,12 +88,6 @@ module Datadog
87
88
  @tags[TAG_WORKSPACE_PATH] = File.expand_path(workspace_path)
88
89
  end
89
90
  end
90
-
91
- def filter_sensitive_info(url)
92
- return nil if url.nil?
93
-
94
- url.gsub(%r{(https?://)[^/]*@}, '\1')
95
- end
96
91
  end
97
92
  end
98
93
  end
@@ -3,6 +3,7 @@
3
3
  require "json"
4
4
 
5
5
  require_relative "base"
6
+ require_relative "../../../utils/url"
6
7
 
7
8
  module Datadog
8
9
  module CI
@@ -25,7 +26,7 @@ module Datadog
25
26
  end
26
27
 
27
28
  def job_url
28
- "#{env["GITHUB_SERVER_URL"]}/#{env["GITHUB_REPOSITORY"]}/commit/#{env["GITHUB_SHA"]}/checks"
29
+ "#{github_server_url}/#{env["GITHUB_REPOSITORY"]}/commit/#{env["GITHUB_SHA"]}/checks"
29
30
  end
30
31
 
31
32
  def pipeline_id
@@ -41,7 +42,7 @@ module Datadog
41
42
  end
42
43
 
43
44
  def pipeline_url
44
- res = "#{env["GITHUB_SERVER_URL"]}/#{env["GITHUB_REPOSITORY"]}/actions/runs/#{env["GITHUB_RUN_ID"]}"
45
+ res = "#{github_server_url}/#{env["GITHUB_REPOSITORY"]}/actions/runs/#{env["GITHUB_RUN_ID"]}"
45
46
  res = "#{res}/attempts/#{env["GITHUB_RUN_ATTEMPT"]}" if env["GITHUB_RUN_ATTEMPT"]
46
47
  res
47
48
  end
@@ -51,7 +52,7 @@ module Datadog
51
52
  end
52
53
 
53
54
  def git_repository_url
54
- "#{env["GITHUB_SERVER_URL"]}/#{env["GITHUB_REPOSITORY"]}.git"
55
+ "#{github_server_url}/#{env["GITHUB_REPOSITORY"]}.git"
55
56
  end
56
57
 
57
58
  def git_commit_sha
@@ -66,12 +67,20 @@ module Datadog
66
67
 
67
68
  def ci_env_vars
68
69
  {
69
- "GITHUB_SERVER_URL" => env["GITHUB_SERVER_URL"],
70
+ "GITHUB_SERVER_URL" => github_server_url,
70
71
  "GITHUB_REPOSITORY" => env["GITHUB_REPOSITORY"],
71
72
  "GITHUB_RUN_ID" => env["GITHUB_RUN_ID"],
72
73
  "GITHUB_RUN_ATTEMPT" => env["GITHUB_RUN_ATTEMPT"]
73
74
  }.reject { |_, v| v.nil? }.to_json
74
75
  end
76
+
77
+ private
78
+
79
+ def github_server_url
80
+ return @github_server_url if defined?(@github_server_url)
81
+
82
+ @github_server_url ||= Utils::Url.filter_sensitive_info(env["GITHUB_SERVER_URL"])
83
+ end
75
84
  end
76
85
  end
77
86
  end
@@ -8,6 +8,17 @@ module Datadog
8
8
  ENV_MODE_ENABLED = "DD_TRACE_CI_ENABLED"
9
9
  ENV_AGENTLESS_MODE_ENABLED = "DD_CIVISIBILITY_AGENTLESS_ENABLED"
10
10
  ENV_AGENTLESS_URL = "DD_CIVISIBILITY_AGENTLESS_URL"
11
+ ENV_EXPERIMENTAL_TEST_SUITE_LEVEL_VISIBILITY_ENABLED = "DD_CIVISIBILITY_EXPERIMENTAL_TEST_SUITE_LEVEL_VISIBILITY_ENABLED"
12
+
13
+ # Source: https://docs.datadoghq.com/getting_started/site/
14
+ DD_SITE_ALLOWLIST = [
15
+ "datadoghq.com",
16
+ "us3.datadoghq.com",
17
+ "us5.datadoghq.com",
18
+ "datadoghq.eu",
19
+ "ddog-gov.com",
20
+ "ap1.datadoghq.com"
21
+ ].freeze
11
22
  end
12
23
  end
13
24
  end
@@ -4,6 +4,7 @@ module Datadog
4
4
  module CI
5
5
  module Ext
6
6
  # Defines constants for test tags
7
+ # @public_api
7
8
  module Test
8
9
  CONTEXT_ORIGIN = "ciapp-test"
9
10
 
@@ -14,8 +15,19 @@ module Datadog
14
15
  TAG_SKIP_REASON = "test.skip_reason" # DEV: Not populated yet
15
16
  TAG_STATUS = "test.status"
16
17
  TAG_SUITE = "test.suite"
18
+ TAG_MODULE = "test.module"
17
19
  TAG_TRAITS = "test.traits"
18
20
  TAG_TYPE = "test.type"
21
+ TAG_COMMAND = "test.command"
22
+
23
+ # those tags are special and they are used to correlate tests with the test sessions, suites, and modules
24
+ TAG_TEST_SESSION_ID = "_test.session_id"
25
+ TAG_TEST_MODULE_ID = "_test.module_id"
26
+ TAG_TEST_SUITE_ID = "_test.suite_id"
27
+ SPECIAL_TAGS = [TAG_TEST_SESSION_ID, TAG_TEST_MODULE_ID, TAG_TEST_SUITE_ID].freeze
28
+
29
+ # tags that can be inherited from the test session
30
+ INHERITABLE_TAGS = [TAG_FRAMEWORK, TAG_FRAMEWORK_VERSION, TAG_TYPE].freeze
19
31
 
20
32
  # Environment runtime tags
21
33
  TAG_OS_ARCHITECTURE = "os.architecture"
@@ -23,7 +35,6 @@ module Datadog
23
35
  TAG_RUNTIME_NAME = "runtime.name"
24
36
  TAG_RUNTIME_VERSION = "runtime.version"
25
37
 
26
- # TODO: is there a better place for SPAN_KIND?
27
38
  TAG_SPAN_KIND = "span.kind"
28
39
 
29
40
  module Status
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "datadog/tracing/span_operation"
4
+
5
+ module Datadog
6
+ module CI
7
+ # Represents an ignored span when CI visibility is disabled.
8
+ # Replaces all methods with no-op.
9
+ #
10
+ # @public_api
11
+ class NullSpan < Span
12
+ def initialize
13
+ super(Datadog::Tracing::SpanOperation.new("null.span"))
14
+ end
15
+
16
+ def id
17
+ end
18
+
19
+ def name
20
+ end
21
+
22
+ def service
23
+ end
24
+
25
+ def span_type
26
+ end
27
+
28
+ def passed!
29
+ end
30
+
31
+ def failed!(exception: nil)
32
+ end
33
+
34
+ def skipped!(exception: nil, reason: nil)
35
+ end
36
+
37
+ def get_tag(key)
38
+ end
39
+
40
+ def set_tag(key, value)
41
+ end
42
+
43
+ def set_metric(key, value)
44
+ end
45
+
46
+ def finish
47
+ end
48
+
49
+ def set_tags(tags)
50
+ end
51
+
52
+ def set_environment_runtime_tags
53
+ end
54
+
55
+ def set_default_tags
56
+ end
57
+
58
+ def to_s
59
+ self.class.to_s
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,117 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "ext/test"
4
+ require_relative "utils/test_run"
5
+
6
+ module Datadog
7
+ module CI
8
+ # Represents a single part of a test run.
9
+ # Could be a session, suite, test, or any custom span.
10
+ #
11
+ # @public_api
12
+ class Span
13
+ attr_reader :tracer_span
14
+
15
+ def initialize(tracer_span)
16
+ @tracer_span = tracer_span
17
+ end
18
+
19
+ # @return [Integer] the ID of the span.
20
+ def id
21
+ tracer_span.id
22
+ end
23
+
24
+ # @return [String] the name of the span.
25
+ def name
26
+ tracer_span.name
27
+ end
28
+
29
+ # @return [String] the service name of the span.
30
+ def service
31
+ tracer_span.service
32
+ end
33
+
34
+ # @return [String] the type of the span (for example "test" or type that was provided to [Datadog::CI.trace]).
35
+ def span_type
36
+ tracer_span.type
37
+ end
38
+
39
+ # Sets the status of the span to "pass".
40
+ # @return [void]
41
+ def passed!
42
+ tracer_span.set_tag(Ext::Test::TAG_STATUS, Ext::Test::Status::PASS)
43
+ end
44
+
45
+ # Sets the status of the span to "fail".
46
+ # @param [Exception] exception the exception that caused the test to fail.
47
+ # @return [void]
48
+ def failed!(exception: nil)
49
+ tracer_span.status = 1
50
+ tracer_span.set_tag(Ext::Test::TAG_STATUS, Ext::Test::Status::FAIL)
51
+ tracer_span.set_error(exception) unless exception.nil?
52
+ end
53
+
54
+ # Sets the status of the span to "skip".
55
+ # @param [Exception] exception the exception that caused the test to fail.
56
+ # @param [String] reason the reason why the test was skipped.
57
+ # @return [void]
58
+ def skipped!(exception: nil, reason: nil)
59
+ tracer_span.set_tag(Ext::Test::TAG_STATUS, Ext::Test::Status::SKIP)
60
+ tracer_span.set_error(exception) unless exception.nil?
61
+ tracer_span.set_tag(Ext::Test::TAG_SKIP_REASON, reason) unless reason.nil?
62
+ end
63
+
64
+ # Gets tag value by key.
65
+ # @param [String] key the key of the tag.
66
+ # @return [String] the value of the tag.
67
+ def get_tag(key)
68
+ tracer_span.get_tag(key)
69
+ end
70
+
71
+ # Sets tag value by key.
72
+ # @param [String] key the key of the tag.
73
+ # @param [String] value the value of the tag.
74
+ # @return [void]
75
+ def set_tag(key, value)
76
+ tracer_span.set_tag(key, value)
77
+ end
78
+
79
+ # Sets metric value by key.
80
+ # @param [String] key the key of the metric.
81
+ # @param [Numeric] value the value of the metric.
82
+ # @return [void]
83
+ def set_metric(key, value)
84
+ tracer_span.set_metric(key, value)
85
+ end
86
+
87
+ # Finishes the span.
88
+ # @return [void]
89
+ def finish
90
+ tracer_span.finish
91
+ end
92
+
93
+ # Sets multiple tags at once.
94
+ # @param [Hash[String, String]] tags the tags to set.
95
+ # @return [void]
96
+ def set_tags(tags)
97
+ tracer_span.set_tags(tags)
98
+ end
99
+
100
+ def set_environment_runtime_tags
101
+ tracer_span.set_tag(Ext::Test::TAG_OS_ARCHITECTURE, ::RbConfig::CONFIG["host_cpu"])
102
+ tracer_span.set_tag(Ext::Test::TAG_OS_PLATFORM, ::RbConfig::CONFIG["host_os"])
103
+ tracer_span.set_tag(Ext::Test::TAG_RUNTIME_NAME, Core::Environment::Ext::LANG_ENGINE)
104
+ tracer_span.set_tag(Ext::Test::TAG_RUNTIME_VERSION, Core::Environment::Ext::ENGINE_VERSION)
105
+ tracer_span.set_tag(Ext::Test::TAG_COMMAND, Utils::TestRun.command)
106
+ end
107
+
108
+ def set_default_tags
109
+ tracer_span.set_tag(Ext::Test::TAG_SPAN_KIND, Ext::AppTypes::TYPE_TEST)
110
+ end
111
+
112
+ def to_s
113
+ "#{self.class}(name:#{name},tracer_span:#{@tracer_span})"
114
+ end
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "span"
4
+
5
+ module Datadog
6
+ module CI
7
+ # Represents a single part of a test run.
8
+ #
9
+ # @public_api
10
+ class Test < Span
11
+ # @return [String] the name of the test.
12
+ def name
13
+ get_tag(Ext::Test::TAG_NAME)
14
+ end
15
+
16
+ # Finishes the current test.
17
+ # @return [void]
18
+ def finish
19
+ super
20
+
21
+ CI.deactivate_test(self)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "concurrent_span"
4
+
5
+ module Datadog
6
+ module CI
7
+ # Represents a single test module.
8
+ # Read here on what test module could mean:
9
+ # https://docs.datadoghq.com/continuous_integration/explorer/?tab=testruns#module
10
+ # This object can be shared between multiple threads.
11
+ #
12
+ # @public_api
13
+ class TestModule < ConcurrentSpan
14
+ # Finishes this test module.
15
+ # @return [void]
16
+ def finish
17
+ super
18
+
19
+ CI.deactivate_test_module
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "concurrent_span"
4
+ require_relative "ext/test"
5
+
6
+ module Datadog
7
+ module CI
8
+ # Represents the whole test session process.
9
+ # Documentation on test sessions is here:
10
+ # https://docs.datadoghq.com/continuous_integration/explorer/?tab=testruns#sessions
11
+ # This object can be shared between multiple threads.
12
+ #
13
+ # @public_api
14
+ class TestSession < ConcurrentSpan
15
+ # Finishes the current test session.
16
+ # @return [void]
17
+ def finish
18
+ super
19
+
20
+ CI.deactivate_test_session
21
+ end
22
+
23
+ def inheritable_tags
24
+ return @inheritable_tags if defined?(@inheritable_tags)
25
+
26
+ # this method is not synchronized because it does not iterate over the tags collection, but rather
27
+ # uses synchronized method to get each tag value
28
+ res = {}
29
+ Ext::Test::INHERITABLE_TAGS.each do |tag|
30
+ res[tag] = get_tag(tag)
31
+ end
32
+ @inheritable_tags = res.freeze
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "concurrent_span"
4
+
5
+ module Datadog
6
+ module CI
7
+ # Represents a single test suite.
8
+ #
9
+ # Read here on what test suite means:
10
+ # https://docs.datadoghq.com/continuous_integration/explorer/?tab=testruns#suite
11
+ #
12
+ # This object can be shared between multiple threads.
13
+ #
14
+ # @public_api
15
+ class TestSuite < ConcurrentSpan
16
+ # Finishes this test suite.
17
+ # @return [void]
18
+ def finish
19
+ super
20
+
21
+ CI.deactivate_test_suite(name)
22
+ end
23
+ end
24
+ end
25
+ end