datadog-ci 1.3.0 → 1.4.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.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +41 -2
  3. data/README.md +1 -0
  4. data/ext/datadog_cov/datadog_cov.c +1 -1
  5. data/lib/datadog/ci/configuration/components.rb +25 -11
  6. data/lib/datadog/ci/configuration/settings.rb +19 -1
  7. data/lib/datadog/ci/contrib/cucumber/configuration_override.rb +37 -0
  8. data/lib/datadog/ci/contrib/cucumber/formatter.rb +5 -5
  9. data/lib/datadog/ci/contrib/cucumber/instrumentation.rb +9 -1
  10. data/lib/datadog/ci/contrib/cucumber/patcher.rb +3 -3
  11. data/lib/datadog/ci/contrib/minitest/runner.rb +16 -0
  12. data/lib/datadog/ci/contrib/minitest/test.rb +1 -0
  13. data/lib/datadog/ci/contrib/rspec/example.rb +67 -39
  14. data/lib/datadog/ci/contrib/rspec/example_group.rb +1 -1
  15. data/lib/datadog/ci/ext/settings.rb +3 -0
  16. data/lib/datadog/ci/ext/telemetry.rb +1 -0
  17. data/lib/datadog/ci/ext/test.rb +11 -11
  18. data/lib/datadog/ci/ext/transport.rb +1 -0
  19. data/lib/datadog/ci/git/local_repository.rb +32 -13
  20. data/lib/datadog/ci/remote/component.rb +50 -0
  21. data/lib/datadog/ci/remote/library_settings.rb +91 -0
  22. data/lib/datadog/ci/{transport/remote_settings_api.rb → remote/library_settings_client.rb} +11 -56
  23. data/lib/datadog/ci/test.rb +8 -1
  24. data/lib/datadog/ci/test_optimisation/component.rb +12 -16
  25. data/lib/datadog/ci/test_retries/component.rb +84 -0
  26. data/lib/datadog/ci/test_retries/null_component.rb +28 -0
  27. data/lib/datadog/ci/test_retries/strategy/base.rb +19 -0
  28. data/lib/datadog/ci/test_retries/strategy/no_retry.rb +16 -0
  29. data/lib/datadog/ci/test_retries/strategy/retry_failed.rb +37 -0
  30. data/lib/datadog/ci/test_suite.rb +39 -18
  31. data/lib/datadog/ci/test_visibility/component.rb +45 -47
  32. data/lib/datadog/ci/test_visibility/null_component.rb +6 -0
  33. data/lib/datadog/ci/test_visibility/telemetry.rb +3 -0
  34. data/lib/datadog/ci/version.rb +2 -2
  35. metadata +13 -6
  36. data/lib/datadog/ci/contrib/cucumber/step.rb +0 -27
@@ -19,23 +19,15 @@ module Datadog
19
19
  class Component
20
20
  attr_reader :test_suite_level_visibility_enabled
21
21
 
22
+ FIBER_LOCAL_TEST_FINISHED_CALLBACK_KEY = :__dd_test_finished_callback
23
+
22
24
  def initialize(
23
- test_optimisation:,
24
- remote_settings_api:,
25
- git_tree_upload_worker: DummyWorker.new,
26
25
  test_suite_level_visibility_enabled: false,
27
26
  codeowners: Codeowners::Parser.new(Git::LocalRepository.root).parse
28
27
  )
29
28
  @test_suite_level_visibility_enabled = test_suite_level_visibility_enabled
30
29
  @context = Context.new
31
30
  @codeowners = codeowners
32
- @test_optimisation = test_optimisation
33
- @remote_settings_api = remote_settings_api
34
- @git_tree_upload_worker = git_tree_upload_worker
35
- end
36
-
37
- def shutdown!
38
- @git_tree_upload_worker.stop
39
31
  end
40
32
 
41
33
  def start_test_session(service: nil, tags: {})
@@ -135,22 +127,39 @@ module Datadog
135
127
  @context.deactivate_test_suite(test_suite_name)
136
128
  end
137
129
 
130
+ # sets fiber-local callback to be called when test is finished
131
+ def set_test_finished_callback(callback)
132
+ Thread.current[FIBER_LOCAL_TEST_FINISHED_CALLBACK_KEY] = callback
133
+ end
134
+
135
+ def remove_test_finished_callback
136
+ Thread.current[FIBER_LOCAL_TEST_FINISHED_CALLBACK_KEY] = nil
137
+ end
138
+
138
139
  def itr_enabled?
139
- @test_optimisation.enabled?
140
+ test_optimisation.enabled?
141
+ end
142
+
143
+ def shutdown!
144
+ # noop, there is no thread owned by test visibility component
140
145
  end
141
146
 
142
147
  private
143
148
 
144
149
  # DOMAIN EVENTS
145
150
  def on_test_session_started(test_session)
146
- Telemetry.event_created(test_session)
147
- Telemetry.test_session_started(test_session)
151
+ # signal git tree upload worker to start uploading git metadata
152
+ git_tree_upload_worker.perform(test_session.git_repository_url)
148
153
 
149
154
  # finds and instruments additional test libraries that we support (ex: selenium-webdriver)
150
155
  Contrib.auto_instrument_on_session_start!
151
156
 
152
- @git_tree_upload_worker.perform(test_session.git_repository_url)
153
- configure_library(test_session)
157
+ # sends internal telemetry events
158
+ Telemetry.test_session_started(test_session)
159
+ Telemetry.event_created(test_session)
160
+
161
+ # signal Remote::Component to configure the library
162
+ remote.configure(test_session)
154
163
  end
155
164
 
156
165
  def on_test_module_started(test_module)
@@ -165,18 +174,18 @@ module Datadog
165
174
  # sometimes test suite is not being assigned correctly
166
175
  # fix it by fetching the one single running test suite from the global context
167
176
  fix_test_suite!(test) if test.test_suite_id.nil?
168
-
169
177
  validate_test_suite_level_visibility_correctness(test)
178
+
170
179
  set_codeowners(test)
171
180
 
172
181
  Telemetry.event_created(test)
173
182
 
174
- @test_optimisation.mark_if_skippable(test)
175
- @test_optimisation.start_coverage(test)
183
+ test_optimisation.mark_if_skippable(test)
184
+ test_optimisation.start_coverage(test)
176
185
  end
177
186
 
178
187
  def on_test_session_finished(test_session)
179
- @test_optimisation.write_test_session_tags(test_session)
188
+ test_optimisation.write_test_session_tags(test_session)
180
189
 
181
190
  Telemetry.event_finished(test_session)
182
191
  end
@@ -190,37 +199,12 @@ module Datadog
190
199
  end
191
200
 
192
201
  def on_test_finished(test)
193
- @test_optimisation.stop_coverage(test)
194
- @test_optimisation.count_skipped_test(test)
202
+ test_optimisation.stop_coverage(test)
203
+ test_optimisation.count_skipped_test(test)
195
204
 
196
205
  Telemetry.event_finished(test)
197
- end
198
-
199
- # TODO: move this to CI::Configuration::Remote
200
- def configure_library(test_session)
201
- # this will change when EFD is implemented
202
- return unless itr_enabled?
203
-
204
- remote_configuration = @remote_settings_api.fetch_library_settings(test_session)
205
- # sometimes we can skip code coverage for default branch if there are no changes in the repository
206
- # backend needs git metadata uploaded for this test session to check if we can skip code coverage
207
- if remote_configuration.require_git?
208
- Datadog.logger.debug { "Library configuration endpoint requires git upload to be finished, waiting..." }
209
- @git_tree_upload_worker.wait_until_done
210
-
211
- Datadog.logger.debug { "Requesting library configuration again..." }
212
- remote_configuration = @remote_settings_api.fetch_library_settings(test_session)
213
-
214
- if remote_configuration.require_git?
215
- Datadog.logger.debug { "git metadata upload did not complete in time when configuring library" }
216
- end
217
- end
218
206
 
219
- @test_optimisation.configure(
220
- remote_configuration.payload,
221
- test_session: test_session,
222
- git_tree_upload_worker: @git_tree_upload_worker
223
- )
207
+ Thread.current[FIBER_LOCAL_TEST_FINISHED_CALLBACK_KEY]&.call(test)
224
208
  end
225
209
 
226
210
  # HELPERS
@@ -235,6 +219,8 @@ module Datadog
235
219
  end
236
220
 
237
221
  def fix_test_suite!(test)
222
+ return unless test_suite_level_visibility_enabled
223
+
238
224
  test_suite = @context.single_active_test_suite
239
225
  unless test_suite
240
226
  Datadog.logger.debug do
@@ -276,6 +262,18 @@ module Datadog
276
262
  end
277
263
  end
278
264
  end
265
+
266
+ def test_optimisation
267
+ Datadog.send(:components).test_optimisation
268
+ end
269
+
270
+ def git_tree_upload_worker
271
+ Datadog.send(:components).git_tree_upload_worker
272
+ end
273
+
274
+ def remote
275
+ Datadog.send(:components).ci_remote
276
+ end
279
277
  end
280
278
  end
281
279
  end
@@ -47,6 +47,12 @@ module Datadog
47
47
  false
48
48
  end
49
49
 
50
+ def set_test_finished_callback(_)
51
+ end
52
+
53
+ def remove_test_finished_callback
54
+ end
55
+
50
56
  private
51
57
 
52
58
  def skip_tracing(block = nil)
@@ -55,6 +55,9 @@ module Datadog
55
55
  # codeowner tag
56
56
  tags[Ext::Telemetry::TAG_HAS_CODEOWNER] = "true" if span.get_tag(Ext::Test::TAG_CODEOWNERS)
57
57
 
58
+ # set is_retry tag if span represents a retried test
59
+ tags[Ext::Telemetry::TAG_IS_RETRY] = "true" if span.get_tag(Ext::Test::TAG_IS_RETRY)
60
+
58
61
  tags
59
62
  end
60
63
 
@@ -4,8 +4,8 @@ module Datadog
4
4
  module CI
5
5
  module VERSION
6
6
  MAJOR = 1
7
- MINOR = 3
8
- PATCH = 0
7
+ MINOR = 4
8
+ PATCH = 1
9
9
  PRE = nil
10
10
  BUILD = nil
11
11
  # PRE and BUILD above are modified for dev gems during gem build GHA workflow
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.3.0
4
+ version: 1.4.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: 2024-07-30 00:00:00.000000000 Z
11
+ date: 2024-08-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: datadog
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '2.2'
19
+ version: '2.3'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '2.2'
26
+ version: '2.3'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: msgpack
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -68,12 +68,12 @@ files:
68
68
  - lib/datadog/ci/configuration/settings.rb
69
69
  - lib/datadog/ci/contrib/contrib.rb
70
70
  - lib/datadog/ci/contrib/cucumber/configuration/settings.rb
71
+ - lib/datadog/ci/contrib/cucumber/configuration_override.rb
71
72
  - lib/datadog/ci/contrib/cucumber/ext.rb
72
73
  - lib/datadog/ci/contrib/cucumber/formatter.rb
73
74
  - lib/datadog/ci/contrib/cucumber/instrumentation.rb
74
75
  - lib/datadog/ci/contrib/cucumber/integration.rb
75
76
  - lib/datadog/ci/contrib/cucumber/patcher.rb
76
- - lib/datadog/ci/contrib/cucumber/step.rb
77
77
  - lib/datadog/ci/contrib/integration.rb
78
78
  - lib/datadog/ci/contrib/minitest/configuration/settings.rb
79
79
  - lib/datadog/ci/contrib/minitest/ext.rb
@@ -136,6 +136,9 @@ files:
136
136
  - lib/datadog/ci/git/tree_uploader.rb
137
137
  - lib/datadog/ci/git/upload_packfile.rb
138
138
  - lib/datadog/ci/git/user.rb
139
+ - lib/datadog/ci/remote/component.rb
140
+ - lib/datadog/ci/remote/library_settings.rb
141
+ - lib/datadog/ci/remote/library_settings_client.rb
139
142
  - lib/datadog/ci/span.rb
140
143
  - lib/datadog/ci/test.rb
141
144
  - lib/datadog/ci/test_module.rb
@@ -146,6 +149,11 @@ files:
146
149
  - lib/datadog/ci/test_optimisation/coverage/writer.rb
147
150
  - lib/datadog/ci/test_optimisation/skippable.rb
148
151
  - lib/datadog/ci/test_optimisation/telemetry.rb
152
+ - lib/datadog/ci/test_retries/component.rb
153
+ - lib/datadog/ci/test_retries/null_component.rb
154
+ - lib/datadog/ci/test_retries/strategy/base.rb
155
+ - lib/datadog/ci/test_retries/strategy/no_retry.rb
156
+ - lib/datadog/ci/test_retries/strategy/retry_failed.rb
149
157
  - lib/datadog/ci/test_session.rb
150
158
  - lib/datadog/ci/test_suite.rb
151
159
  - lib/datadog/ci/test_visibility/component.rb
@@ -175,7 +183,6 @@ files:
175
183
  - lib/datadog/ci/transport/event_platform_transport.rb
176
184
  - lib/datadog/ci/transport/gzip.rb
177
185
  - lib/datadog/ci/transport/http.rb
178
- - lib/datadog/ci/transport/remote_settings_api.rb
179
186
  - lib/datadog/ci/transport/telemetry.rb
180
187
  - lib/datadog/ci/utils/bundle.rb
181
188
  - lib/datadog/ci/utils/configuration.rb
@@ -1,27 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Datadog
4
- module CI
5
- module Contrib
6
- module Cucumber
7
- # instruments Cucumber::Core::Test::Step from cucumber-ruby-core to change
8
- module Step
9
- def self.included(base)
10
- base.prepend(InstanceMethods)
11
- end
12
-
13
- module InstanceMethods
14
- def execute(*args)
15
- test_span = CI.active_test
16
- if test_span&.skipped_by_itr?
17
- @action.skip(*args)
18
- else
19
- super
20
- end
21
- end
22
- end
23
- end
24
- end
25
- end
26
- end
27
- end