datadog-ci 0.5.0 → 0.6.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.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +33 -2
  3. data/lib/datadog/ci/configuration/components.rb +13 -9
  4. data/lib/datadog/ci/configuration/extensions.rb +21 -0
  5. data/lib/datadog/ci/contrib/cucumber/configuration/settings.rb +1 -1
  6. data/lib/datadog/ci/contrib/cucumber/ext.rb +7 -5
  7. data/lib/datadog/ci/contrib/cucumber/formatter.rb +99 -19
  8. data/lib/datadog/ci/contrib/minitest/configuration/settings.rb +1 -1
  9. data/lib/datadog/ci/contrib/minitest/ext.rb +6 -4
  10. data/lib/datadog/ci/contrib/minitest/helpers.rb +22 -0
  11. data/lib/datadog/ci/contrib/minitest/hooks.rb +45 -17
  12. data/lib/datadog/ci/contrib/minitest/patcher.rb +7 -0
  13. data/lib/datadog/ci/contrib/minitest/plugin.rb +73 -0
  14. data/lib/datadog/ci/contrib/minitest/runnable.rb +42 -0
  15. data/lib/datadog/ci/contrib/rspec/configuration/settings.rb +1 -1
  16. data/lib/datadog/ci/contrib/rspec/example.rb +2 -2
  17. data/lib/datadog/ci/contrib/rspec/example_group.rb +46 -0
  18. data/lib/datadog/ci/contrib/rspec/ext.rb +5 -4
  19. data/lib/datadog/ci/contrib/rspec/integration.rb +1 -1
  20. data/lib/datadog/ci/contrib/rspec/patcher.rb +5 -0
  21. data/lib/datadog/ci/contrib/rspec/runner.rb +57 -0
  22. data/lib/datadog/ci/contrib/settings.rb +1 -1
  23. data/lib/datadog/ci/ext/test.rb +2 -0
  24. data/lib/datadog/ci/span.rb +24 -0
  25. data/lib/datadog/ci/test.rb +30 -0
  26. data/lib/datadog/ci/test_session.rb +8 -0
  27. data/lib/datadog/ci/test_visibility/context/global.rb +82 -0
  28. data/lib/datadog/ci/test_visibility/context/local.rb +52 -0
  29. data/lib/datadog/ci/test_visibility/null_recorder.rb +73 -0
  30. data/lib/datadog/ci/test_visibility/recorder.rb +314 -0
  31. data/lib/datadog/ci/version.rb +1 -1
  32. data/lib/datadog/ci.rb +3 -3
  33. data/sig/datadog/ci/configuration/components.rbs +2 -2
  34. data/sig/datadog/ci/configuration/extensions.rbs +9 -0
  35. data/sig/datadog/ci/contrib/cucumber/ext.rbs +1 -5
  36. data/sig/datadog/ci/contrib/cucumber/formatter.rbs +17 -4
  37. data/sig/datadog/ci/contrib/minitest/ext.rbs +1 -5
  38. data/sig/datadog/ci/contrib/minitest/helpers.rbs +13 -0
  39. data/sig/datadog/ci/contrib/minitest/hooks.rbs +9 -1
  40. data/sig/datadog/ci/contrib/minitest/plugin.rbs +31 -0
  41. data/sig/datadog/ci/contrib/minitest/runnable.rbs +24 -0
  42. data/sig/datadog/ci/contrib/rspec/example_group.rbs +21 -0
  43. data/sig/datadog/ci/contrib/rspec/ext.rbs +2 -8
  44. data/sig/datadog/ci/contrib/rspec/runner.rbs +21 -0
  45. data/sig/datadog/ci/ext/test.rbs +2 -0
  46. data/sig/datadog/ci/span.rbs +8 -0
  47. data/sig/datadog/ci/test.rbs +5 -0
  48. data/sig/datadog/ci/test_visibility/context/global.rbs +39 -0
  49. data/sig/datadog/ci/test_visibility/context/local.rbs +23 -0
  50. data/sig/datadog/ci/test_visibility/null_recorder.rbs +45 -0
  51. data/sig/datadog/ci/test_visibility/recorder.rbs +85 -0
  52. data/sig/datadog/ci.rbs +3 -1
  53. metadata +23 -11
  54. data/lib/datadog/ci/context/global.rb +0 -80
  55. data/lib/datadog/ci/context/local.rb +0 -50
  56. data/lib/datadog/ci/extensions.rb +0 -19
  57. data/lib/datadog/ci/recorder.rb +0 -291
  58. data/sig/datadog/ci/context/global.rbs +0 -37
  59. data/sig/datadog/ci/context/local.rbs +0 -21
  60. data/sig/datadog/ci/extensions.rbs +0 -7
  61. data/sig/datadog/ci/recorder.rbs +0 -83
@@ -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
@@ -1,83 +0,0 @@
1
- module Datadog
2
- module CI
3
- class Recorder
4
- @test_suite_level_visibility_enabled: bool
5
- @enabled: bool
6
-
7
- @environment_tags: Hash[String, String]
8
- @local_context: Datadog::CI::Context::Local
9
- @global_context: Datadog::CI::Context::Global
10
-
11
- @null_span: Datadog::CI::NullSpan
12
-
13
- attr_reader environment_tags: Hash[String, String]
14
- attr_reader test_suite_level_visibility_enabled: bool
15
- attr_reader enabled: bool
16
-
17
- def initialize: (?enabled: bool, ?test_suite_level_visibility_enabled: bool) -> void
18
-
19
- def trace_test: (String span_name, String test_suite_name, ?service: String?, ?tags: Hash[untyped, untyped]) ?{ (Datadog::CI::Span span) -> untyped } -> untyped
20
-
21
- def trace: (String span_type, String span_name, ?tags: Hash[untyped, untyped]) ?{ (Datadog::CI::Span span) -> untyped } -> untyped
22
-
23
- def start_test_session: (?service: String?, ?tags: Hash[untyped, untyped]) -> Datadog::CI::Span
24
-
25
- def start_test_module: (String test_module_name, ?service: String?, ?tags: Hash[untyped, untyped]) -> Datadog::CI::Span
26
-
27
- def start_test_suite: (String test_suite_name, ?service: String?, ?tags: Hash[untyped, untyped]) -> Datadog::CI::Span
28
-
29
- def active_test_session: () -> Datadog::CI::TestSession?
30
-
31
- def active_test_module: () -> Datadog::CI::TestModule?
32
-
33
- def active_test_suite: (String test_suite_name) -> Datadog::CI::TestSuite?
34
-
35
- def active_test: () -> Datadog::CI::Test?
36
-
37
- def active_span: () -> Datadog::CI::Span?
38
-
39
- def deactivate_test: (Datadog::CI::Test test) -> void
40
-
41
- def deactivate_test_session: () -> void
42
-
43
- def deactivate_test_module: () -> void
44
-
45
- def deactivate_test_suite: (String test_suite_name) -> void
46
-
47
- def create_datadog_span: (String span_name, ?span_options: Hash[untyped, untyped], ?tags: Hash[untyped, untyped]) ?{ (Datadog::CI::Span span) -> untyped } -> untyped
48
-
49
- def set_trace_origin: (Datadog::Tracing::TraceOperation trace) -> untyped
50
-
51
- private
52
-
53
- def build_test: (Datadog::Tracing::SpanOperation tracer_span, Hash[untyped, untyped] tags) -> Datadog::CI::Test
54
-
55
- def build_test_session: (Datadog::Tracing::SpanOperation tracer_span, Hash[untyped, untyped] tags) -> Datadog::CI::TestSession
56
-
57
- def build_test_module: (Datadog::Tracing::SpanOperation tracer_span, Hash[untyped, untyped] tags) -> Datadog::CI::TestModule
58
-
59
- def build_test_suite: (Datadog::Tracing::SpanOperation tracer_span, Hash[untyped, untyped] tags) -> Datadog::CI::TestSuite
60
-
61
- def build_span: (Datadog::Tracing::SpanOperation tracer_span, Hash[untyped, untyped] tags) -> Datadog::CI::Span
62
-
63
- def build_span_options: (String? service_name, String span_type, ?Hash[Symbol, untyped] other_options) -> Hash[Symbol, untyped]
64
-
65
- def set_initial_tags: (Datadog::CI::Span ci_span, Hash[untyped, untyped] tags) -> void
66
-
67
- # the type (Datadog::CI::TestSession | Datadog::Tracing::SpanOperation) screams of wrong/mising abstraction
68
- def set_session_context: (Hash[untyped, untyped] tags, ?Datadog::CI::TestSession | Datadog::Tracing::SpanOperation? test_session) -> void
69
-
70
- def set_suite_context: (Hash[untyped, untyped] tags, ?span: Datadog::Tracing::SpanOperation, ?name: String) -> void
71
-
72
- def set_module_context: (Hash[untyped, untyped] tags, ?Datadog::CI::TestModule | Datadog::Tracing::SpanOperation? test_module) -> void
73
-
74
- def null_span: () -> Datadog::CI::Span
75
-
76
- def skip_tracing: (?untyped block) -> untyped
77
-
78
- def start_datadog_tracer_span: (String span_name, Hash[untyped, untyped] span_options) ?{ (untyped) -> untyped } -> untyped
79
-
80
- def set_inherited_globals: (Hash[untyped, untyped] tags) -> void
81
- end
82
- end
83
- end