datadog-ci 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
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