datadog-ci 0.5.0 → 0.5.1

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.
@@ -0,0 +1,85 @@
1
+ module Datadog
2
+ module CI
3
+ module TestVisibility
4
+ class Recorder
5
+ @test_suite_level_visibility_enabled: bool
6
+ @enabled: bool
7
+
8
+ @environment_tags: Hash[String, String]
9
+ @local_context: Datadog::CI::TestVisibility::Context::Local
10
+ @global_context: Datadog::CI::TestVisibility::Context::Global
11
+
12
+ @null_span: Datadog::CI::NullSpan
13
+
14
+ attr_reader environment_tags: Hash[String, String]
15
+ attr_reader test_suite_level_visibility_enabled: bool
16
+ attr_reader enabled: bool
17
+
18
+ def initialize: (?enabled: bool, ?test_suite_level_visibility_enabled: bool) -> void
19
+
20
+ def trace_test: (String span_name, String test_suite_name, ?service: String?, ?tags: Hash[untyped, untyped]) ?{ (Datadog::CI::Span span) -> untyped } -> untyped
21
+
22
+ def trace: (String span_type, String span_name, ?tags: Hash[untyped, untyped]) ?{ (Datadog::CI::Span span) -> untyped } -> untyped
23
+
24
+ def start_test_session: (?service: String?, ?tags: Hash[untyped, untyped]) -> Datadog::CI::Span
25
+
26
+ def start_test_module: (String test_module_name, ?service: String?, ?tags: Hash[untyped, untyped]) -> Datadog::CI::Span
27
+
28
+ def start_test_suite: (String test_suite_name, ?service: String?, ?tags: Hash[untyped, untyped]) -> Datadog::CI::Span
29
+
30
+ def active_test_session: () -> Datadog::CI::TestSession?
31
+
32
+ def active_test_module: () -> Datadog::CI::TestModule?
33
+
34
+ def active_test_suite: (String test_suite_name) -> Datadog::CI::TestSuite?
35
+
36
+ def active_test: () -> Datadog::CI::Test?
37
+
38
+ def active_span: () -> Datadog::CI::Span?
39
+
40
+ def deactivate_test: (Datadog::CI::Test test) -> void
41
+
42
+ def deactivate_test_session: () -> void
43
+
44
+ def deactivate_test_module: () -> void
45
+
46
+ def deactivate_test_suite: (String test_suite_name) -> void
47
+
48
+ def create_datadog_span: (String span_name, ?span_options: Hash[untyped, untyped], ?tags: Hash[untyped, untyped]) ?{ (Datadog::CI::Span span) -> untyped } -> untyped
49
+
50
+ def set_trace_origin: (Datadog::Tracing::TraceOperation trace) -> untyped
51
+
52
+ private
53
+
54
+ def build_test: (Datadog::Tracing::SpanOperation tracer_span, Hash[untyped, untyped] tags) -> Datadog::CI::Test
55
+
56
+ def build_test_session: (Datadog::Tracing::SpanOperation tracer_span, Hash[untyped, untyped] tags) -> Datadog::CI::TestSession
57
+
58
+ def build_test_module: (Datadog::Tracing::SpanOperation tracer_span, Hash[untyped, untyped] tags) -> Datadog::CI::TestModule
59
+
60
+ def build_test_suite: (Datadog::Tracing::SpanOperation tracer_span, Hash[untyped, untyped] tags) -> Datadog::CI::TestSuite
61
+
62
+ def build_span: (Datadog::Tracing::SpanOperation tracer_span, Hash[untyped, untyped] tags) -> Datadog::CI::Span
63
+
64
+ def build_span_options: (String? service_name, String span_type, ?Hash[Symbol, untyped] other_options) -> Hash[Symbol, untyped]
65
+
66
+ def set_initial_tags: (Datadog::CI::Span ci_span, Hash[untyped, untyped] tags) -> void
67
+
68
+ # the type (Datadog::CI::TestSession | Datadog::Tracing::SpanOperation) screams of wrong/mising abstraction
69
+ def set_session_context: (Hash[untyped, untyped] tags, ?Datadog::CI::TestSession | Datadog::Tracing::SpanOperation? test_session) -> void
70
+
71
+ def set_suite_context: (Hash[untyped, untyped] tags, ?span: Datadog::Tracing::SpanOperation, ?name: String) -> void
72
+
73
+ def set_module_context: (Hash[untyped, untyped] tags, ?Datadog::CI::TestModule | Datadog::Tracing::SpanOperation? test_module) -> void
74
+
75
+ def null_span: () -> Datadog::CI::Span
76
+
77
+ def skip_tracing: (?untyped block) -> untyped
78
+
79
+ def start_datadog_tracer_span: (String span_name, Hash[untyped, untyped] span_options) ?{ (untyped) -> untyped } -> untyped
80
+
81
+ def set_inherited_globals: (Hash[untyped, untyped] tags) -> void
82
+ end
83
+ end
84
+ end
85
+ end
data/sig/datadog/ci.rbs CHANGED
@@ -30,6 +30,6 @@ module Datadog
30
30
 
31
31
  def self.components: () -> Datadog::CI::Configuration::Components
32
32
 
33
- def self.recorder: () -> Datadog::CI::Recorder
33
+ def self.recorder: () -> Datadog::CI::TestVisibility::Recorder
34
34
  end
35
35
  end
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: 0.5.0
4
+ version: 0.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Datadog, Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-12-06 00:00:00.000000000 Z
11
+ date: 2023-12-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: msgpack
@@ -44,9 +44,8 @@ files:
44
44
  - lib/datadog/ci.rb
45
45
  - lib/datadog/ci/concurrent_span.rb
46
46
  - lib/datadog/ci/configuration/components.rb
47
+ - lib/datadog/ci/configuration/extensions.rb
47
48
  - lib/datadog/ci/configuration/settings.rb
48
- - lib/datadog/ci/context/global.rb
49
- - lib/datadog/ci/context/local.rb
50
49
  - lib/datadog/ci/contrib/cucumber/configuration/settings.rb
51
50
  - lib/datadog/ci/contrib/cucumber/ext.rb
52
51
  - lib/datadog/ci/contrib/cucumber/formatter.rb
@@ -90,15 +89,16 @@ files:
90
89
  - lib/datadog/ci/ext/settings.rb
91
90
  - lib/datadog/ci/ext/test.rb
92
91
  - lib/datadog/ci/ext/transport.rb
93
- - lib/datadog/ci/extensions.rb
94
92
  - lib/datadog/ci/null_span.rb
95
- - lib/datadog/ci/recorder.rb
96
93
  - lib/datadog/ci/span.rb
97
94
  - lib/datadog/ci/test.rb
98
95
  - lib/datadog/ci/test_module.rb
99
96
  - lib/datadog/ci/test_session.rb
100
97
  - lib/datadog/ci/test_suite.rb
98
+ - lib/datadog/ci/test_visibility/context/global.rb
99
+ - lib/datadog/ci/test_visibility/context/local.rb
101
100
  - lib/datadog/ci/test_visibility/flush.rb
101
+ - lib/datadog/ci/test_visibility/recorder.rb
102
102
  - lib/datadog/ci/test_visibility/serializers/base.rb
103
103
  - lib/datadog/ci/test_visibility/serializers/factories/test_level.rb
104
104
  - lib/datadog/ci/test_visibility/serializers/factories/test_suite_level.rb
@@ -122,9 +122,8 @@ files:
122
122
  - sig/datadog/ci.rbs
123
123
  - sig/datadog/ci/concurrent_span.rbs
124
124
  - sig/datadog/ci/configuration/components.rbs
125
+ - sig/datadog/ci/configuration/extensions.rbs
125
126
  - sig/datadog/ci/configuration/settings.rbs
126
- - sig/datadog/ci/context/global.rbs
127
- - sig/datadog/ci/context/local.rbs
128
127
  - sig/datadog/ci/contrib/cucumber/configuration/settings.rbs
129
128
  - sig/datadog/ci/contrib/cucumber/ext.rbs
130
129
  - sig/datadog/ci/contrib/cucumber/formatter.rbs
@@ -168,15 +167,16 @@ files:
168
167
  - sig/datadog/ci/ext/settings.rbs
169
168
  - sig/datadog/ci/ext/test.rbs
170
169
  - sig/datadog/ci/ext/transport.rbs
171
- - sig/datadog/ci/extensions.rbs
172
170
  - sig/datadog/ci/null_span.rbs
173
- - sig/datadog/ci/recorder.rbs
174
171
  - sig/datadog/ci/span.rbs
175
172
  - sig/datadog/ci/test.rbs
176
173
  - sig/datadog/ci/test_module.rbs
177
174
  - sig/datadog/ci/test_session.rbs
178
175
  - sig/datadog/ci/test_suite.rbs
176
+ - sig/datadog/ci/test_visibility/context/global.rbs
177
+ - sig/datadog/ci/test_visibility/context/local.rbs
179
178
  - sig/datadog/ci/test_visibility/flush.rbs
179
+ - sig/datadog/ci/test_visibility/recorder.rbs
180
180
  - sig/datadog/ci/test_visibility/serializers/base.rbs
181
181
  - sig/datadog/ci/test_visibility/serializers/factories/test_level.rbs
182
182
  - sig/datadog/ci/test_visibility/serializers/factories/test_suite_level.rbs
@@ -1,80 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Datadog
4
- module CI
5
- module Context
6
- # This context is shared between threads and represents the current test session and test module.
7
- class Global
8
- def initialize
9
- # we are using Monitor instead of Mutex because it is reentrant
10
- @mutex = Monitor.new
11
-
12
- @test_session = nil
13
- @test_module = nil
14
- @test_suites = {}
15
- end
16
-
17
- def fetch_or_activate_test_suite(test_suite_name, &block)
18
- @mutex.synchronize do
19
- @test_suites[test_suite_name] ||= block.call
20
- end
21
- end
22
-
23
- def fetch_or_activate_test_module(&block)
24
- @mutex.synchronize do
25
- @test_module ||= block.call
26
- end
27
- end
28
-
29
- def fetch_or_activate_test_session(&block)
30
- @mutex.synchronize do
31
- @test_session ||= block.call
32
- end
33
- end
34
-
35
- def active_test_module
36
- @test_module
37
- end
38
-
39
- def active_test_session
40
- @test_session
41
- end
42
-
43
- def active_test_suite(test_suite_name)
44
- @mutex.synchronize { @test_suites[test_suite_name] }
45
- end
46
-
47
- def service
48
- @mutex.synchronize do
49
- # thank you RBS for this weirdness
50
- test_session = @test_session
51
- test_session.service if test_session
52
- end
53
- end
54
-
55
- def inheritable_session_tags
56
- @mutex.synchronize do
57
- test_session = @test_session
58
- if test_session
59
- test_session.inheritable_tags
60
- else
61
- {}
62
- end
63
- end
64
- end
65
-
66
- def deactivate_test_session!
67
- @mutex.synchronize { @test_session = nil }
68
- end
69
-
70
- def deactivate_test_module!
71
- @mutex.synchronize { @test_module = nil }
72
- end
73
-
74
- def deactivate_test_suite!(test_suite_name)
75
- @mutex.synchronize { @test_suites.delete(test_suite_name) }
76
- end
77
- end
78
- end
79
- end
80
- end
@@ -1,50 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Datadog
4
- module CI
5
- module Context
6
- class Local
7
- def initialize
8
- @key = :datadog_ci_active_test
9
-
10
- self.active_test = nil
11
- end
12
-
13
- def activate_test!(test)
14
- raise "Nested tests are not supported. Currently active test: #{active_test}" unless active_test.nil?
15
-
16
- if block_given?
17
- begin
18
- self.active_test = test
19
- yield
20
- ensure
21
- self.active_test = nil
22
- end
23
- else
24
- self.active_test = test
25
- end
26
- end
27
-
28
- def deactivate_test!(test)
29
- return if active_test.nil?
30
-
31
- if active_test == test
32
- self.active_test = nil
33
- else
34
- raise "Trying to deactivate test #{test}, but currently active test is #{active_test}"
35
- end
36
- end
37
-
38
- def active_test
39
- Thread.current[@key]
40
- end
41
-
42
- private
43
-
44
- def active_test=(test)
45
- Thread.current[@key] = test
46
- end
47
- end
48
- end
49
- end
50
- end
@@ -1,19 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "datadog/core/configuration/settings"
4
- require "datadog/core/configuration/components"
5
-
6
- require_relative "configuration/settings"
7
- require_relative "configuration/components"
8
-
9
- module Datadog
10
- module CI
11
- # Extends Datadog tracing with CI features
12
- module Extensions
13
- def self.activate!
14
- Core::Configuration::Settings.extend(CI::Configuration::Settings)
15
- Core::Configuration::Components.prepend(CI::Configuration::Components)
16
- end
17
- end
18
- end
19
- end
@@ -1,291 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "datadog/tracing"
4
- require "datadog/tracing/trace_digest"
5
-
6
- require "rbconfig"
7
-
8
- require_relative "ext/app_types"
9
- require_relative "ext/test"
10
- require_relative "ext/environment"
11
-
12
- require_relative "context/global"
13
- require_relative "context/local"
14
-
15
- require_relative "span"
16
- require_relative "null_span"
17
- require_relative "test"
18
- require_relative "test_session"
19
- require_relative "test_module"
20
- require_relative "test_suite"
21
-
22
- module Datadog
23
- module CI
24
- # Common behavior for CI tests
25
- # Note: this class has too many responsibilities and should be split into multiple classes
26
- class Recorder
27
- attr_reader :environment_tags, :test_suite_level_visibility_enabled, :enabled
28
-
29
- def initialize(enabled: true, test_suite_level_visibility_enabled: false)
30
- @enabled = enabled
31
- @test_suite_level_visibility_enabled = enabled && test_suite_level_visibility_enabled
32
-
33
- @environment_tags = Ext::Environment.tags(ENV).freeze
34
- @local_context = Context::Local.new
35
- @global_context = Context::Global.new
36
- end
37
-
38
- def start_test_session(service: nil, tags: {})
39
- return skip_tracing unless test_suite_level_visibility_enabled
40
-
41
- @global_context.fetch_or_activate_test_session do
42
- tracer_span = start_datadog_tracer_span(
43
- "test.session", build_span_options(service, Ext::AppTypes::TYPE_TEST_SESSION)
44
- )
45
- set_session_context(tags, tracer_span)
46
-
47
- build_test_session(tracer_span, tags)
48
- end
49
- end
50
-
51
- def start_test_module(test_module_name, service: nil, tags: {})
52
- return skip_tracing unless test_suite_level_visibility_enabled
53
-
54
- @global_context.fetch_or_activate_test_module do
55
- set_inherited_globals(tags)
56
- set_session_context(tags)
57
-
58
- tracer_span = start_datadog_tracer_span(
59
- test_module_name, build_span_options(service, Ext::AppTypes::TYPE_TEST_MODULE)
60
- )
61
- set_module_context(tags, tracer_span)
62
-
63
- build_test_module(tracer_span, tags)
64
- end
65
- end
66
-
67
- def start_test_suite(test_suite_name, service: nil, tags: {})
68
- return skip_tracing unless test_suite_level_visibility_enabled
69
-
70
- @global_context.fetch_or_activate_test_suite(test_suite_name) do
71
- set_inherited_globals(tags)
72
- set_session_context(tags)
73
- set_module_context(tags)
74
-
75
- tracer_span = start_datadog_tracer_span(
76
- test_suite_name, build_span_options(service, Ext::AppTypes::TYPE_TEST_SUITE)
77
- )
78
- set_suite_context(tags, span: tracer_span)
79
-
80
- build_test_suite(tracer_span, tags)
81
- end
82
- end
83
-
84
- def trace_test(test_name, test_suite_name, service: nil, tags: {}, &block)
85
- return skip_tracing(block) unless enabled
86
-
87
- set_inherited_globals(tags)
88
- set_session_context(tags)
89
- set_module_context(tags)
90
- set_suite_context(tags, name: test_suite_name)
91
-
92
- tags[Ext::Test::TAG_NAME] = test_name
93
-
94
- span_options = build_span_options(
95
- service,
96
- Ext::AppTypes::TYPE_TEST,
97
- # :resource is needed for the agent APM protocol to work correctly (for older agent versions)
98
- # :continue_from is required to start a new trace for each test
99
- {resource: test_name, continue_from: Datadog::Tracing::TraceDigest.new}
100
- )
101
-
102
- if block
103
- start_datadog_tracer_span(test_name, span_options) do |tracer_span|
104
- test = build_test(tracer_span, tags)
105
-
106
- @local_context.activate_test!(test) do
107
- block.call(test)
108
- end
109
- end
110
- else
111
- tracer_span = start_datadog_tracer_span(test_name, span_options)
112
-
113
- test = build_test(tracer_span, tags)
114
- @local_context.activate_test!(test)
115
- test
116
- end
117
- end
118
-
119
- def trace(span_type, span_name, tags: {}, &block)
120
- return skip_tracing(block) unless enabled
121
-
122
- span_options = build_span_options(
123
- nil, # service name is completely optional for custom spans
124
- span_type,
125
- {resource: span_name}
126
- )
127
-
128
- if block
129
- start_datadog_tracer_span(span_name, span_options) do |tracer_span|
130
- block.call(build_span(tracer_span, tags))
131
- end
132
- else
133
- tracer_span = start_datadog_tracer_span(span_name, span_options)
134
-
135
- build_span(tracer_span, tags)
136
- end
137
- end
138
-
139
- def active_span
140
- tracer_span = Datadog::Tracing.active_span
141
- Span.new(tracer_span) if tracer_span
142
- end
143
-
144
- def active_test
145
- @local_context.active_test
146
- end
147
-
148
- def active_test_session
149
- @global_context.active_test_session
150
- end
151
-
152
- def active_test_module
153
- @global_context.active_test_module
154
- end
155
-
156
- def active_test_suite(test_suite_name)
157
- @global_context.active_test_suite(test_suite_name)
158
- end
159
-
160
- def deactivate_test(test)
161
- @local_context.deactivate_test!(test)
162
- end
163
-
164
- def deactivate_test_session
165
- @global_context.deactivate_test_session!
166
- end
167
-
168
- def deactivate_test_module
169
- @global_context.deactivate_test_module!
170
- end
171
-
172
- def deactivate_test_suite(test_suite_name)
173
- @global_context.deactivate_test_suite!(test_suite_name)
174
- end
175
-
176
- private
177
-
178
- def skip_tracing(block = nil)
179
- if block
180
- block.call(null_span)
181
- else
182
- null_span
183
- end
184
- end
185
-
186
- # Sets trace's origin to ciapp-test
187
- def set_trace_origin(trace)
188
- trace.origin = Ext::Test::CONTEXT_ORIGIN if trace
189
- end
190
-
191
- def build_test_session(tracer_span, tags)
192
- test_session = TestSession.new(tracer_span)
193
- set_initial_tags(test_session, tags)
194
- test_session
195
- end
196
-
197
- def build_test_module(tracer_span, tags)
198
- test_module = TestModule.new(tracer_span)
199
- set_initial_tags(test_module, tags)
200
- test_module
201
- end
202
-
203
- def build_test_suite(tracer_span, tags)
204
- test_suite = TestSuite.new(tracer_span)
205
- set_initial_tags(test_suite, tags)
206
- test_suite
207
- end
208
-
209
- def build_test(tracer_span, tags)
210
- test = Test.new(tracer_span)
211
- set_initial_tags(test, tags)
212
- test
213
- end
214
-
215
- def build_span(tracer_span, tags)
216
- span = Span.new(tracer_span)
217
- set_initial_tags(span, tags)
218
- span
219
- end
220
-
221
- def build_span_options(service, span_type, other_options = {})
222
- other_options[:service] = service || @global_context.service
223
- other_options[:span_type] = span_type
224
-
225
- other_options
226
- end
227
-
228
- def set_inherited_globals(tags)
229
- # this code achieves the same as @global_context.inheritable_session_tags.merge(tags)
230
- # but without allocating a new hash
231
- @global_context.inheritable_session_tags.each do |key, value|
232
- tags[key] = value unless tags.key?(key)
233
- end
234
- end
235
-
236
- def set_initial_tags(ci_span, tags)
237
- ci_span.set_default_tags
238
- ci_span.set_environment_runtime_tags
239
-
240
- ci_span.set_tags(tags)
241
- ci_span.set_tags(environment_tags)
242
- end
243
-
244
- def set_session_context(tags, test_session = nil)
245
- test_session ||= active_test_session
246
- tags[Ext::Test::TAG_TEST_SESSION_ID] = test_session.id.to_s if test_session
247
- end
248
-
249
- def set_module_context(tags, test_module = nil)
250
- test_module ||= active_test_module
251
- if test_module
252
- tags[Ext::Test::TAG_TEST_MODULE_ID] = test_module.id.to_s
253
- tags[Ext::Test::TAG_MODULE] = test_module.name
254
- end
255
- end
256
-
257
- def set_suite_context(tags, span: nil, name: nil)
258
- return if span.nil? && name.nil?
259
-
260
- test_suite = span || active_test_suite(name)
261
-
262
- if test_suite
263
- tags[Ext::Test::TAG_TEST_SUITE_ID] = test_suite.id.to_s
264
- tags[Ext::Test::TAG_SUITE] = test_suite.name
265
- else
266
- tags[Ext::Test::TAG_SUITE] = name
267
- end
268
- end
269
-
270
- def start_datadog_tracer_span(span_name, span_options, &block)
271
- if block
272
- Datadog::Tracing.trace(span_name, **span_options) do |tracer_span, trace|
273
- set_trace_origin(trace)
274
-
275
- yield tracer_span
276
- end
277
- else
278
- tracer_span = Datadog::Tracing.trace(span_name, **span_options)
279
- trace = Datadog::Tracing.active_trace
280
- set_trace_origin(trace)
281
-
282
- tracer_span
283
- end
284
- end
285
-
286
- def null_span
287
- @null_span ||= NullSpan.new
288
- end
289
- end
290
- end
291
- end
@@ -1,37 +0,0 @@
1
- module Datadog
2
- module CI
3
- module Context
4
- class Global
5
- @mutex: Thread::Mutex
6
-
7
- @test_session: Datadog::CI::TestSession?
8
- @test_module: Datadog::CI::TestModule?
9
- @test_suites: Hash[String, Datadog::CI::TestSuite]
10
-
11
- def initialize: () -> void
12
-
13
- def fetch_or_activate_test_suite: (String test_suite_name) {() -> Datadog::CI::TestSuite} -> Datadog::CI::TestSuite
14
-
15
- def fetch_or_activate_test_module: () {() -> Datadog::CI::TestModule} -> Datadog::CI::TestModule
16
-
17
- def fetch_or_activate_test_session: () {() -> Datadog::CI::TestSession} -> Datadog::CI::TestSession
18
-
19
- def active_test_session: () -> Datadog::CI::TestSession?
20
-
21
- def active_test_suite: (String test_suite_name) -> Datadog::CI::TestSuite?
22
-
23
- def service: () -> String?
24
-
25
- def inheritable_session_tags: () -> Hash[untyped, untyped]
26
-
27
- def active_test_module: () -> Datadog::CI::TestModule?
28
-
29
- def deactivate_test_session!: () -> void
30
-
31
- def deactivate_test_module!: () -> void
32
-
33
- def deactivate_test_suite!: (String test_suite_name) -> void
34
- end
35
- end
36
- end
37
- end
@@ -1,21 +0,0 @@
1
- module Datadog
2
- module CI
3
- module Context
4
- class Local
5
- @key: Symbol
6
-
7
- def initialize: () -> void
8
-
9
- def activate_test!: (Datadog::CI::Test test) ?{ () -> untyped } -> void
10
-
11
- def deactivate_test!: (Datadog::CI::Test test) -> void
12
-
13
- def active_test: () -> Datadog::CI::Test?
14
-
15
- private
16
-
17
- def active_test=: (Datadog::CI::Test? test) -> untyped
18
- end
19
- end
20
- end
21
- end
@@ -1,7 +0,0 @@
1
- module Datadog
2
- module CI
3
- module Extensions
4
- def self.activate!: () -> untyped
5
- end
6
- end
7
- end