datadog-ci 1.13.0 → 1.15.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 (46) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +35 -2
  3. data/lib/datadog/ci/configuration/components.rb +2 -1
  4. data/lib/datadog/ci/configuration/settings.rb +6 -0
  5. data/lib/datadog/ci/contrib/minitest/helpers.rb +26 -0
  6. data/lib/datadog/ci/contrib/minitest/runnable.rb +1 -19
  7. data/lib/datadog/ci/contrib/minitest/runner.rb +12 -5
  8. data/lib/datadog/ci/contrib/minitest/test.rb +2 -9
  9. data/lib/datadog/ci/contrib/parallel_tests/cli.rb +84 -0
  10. data/lib/datadog/ci/contrib/parallel_tests/configuration/settings.rb +32 -0
  11. data/lib/datadog/ci/contrib/parallel_tests/ext.rb +16 -0
  12. data/lib/datadog/ci/contrib/parallel_tests/integration.rb +42 -0
  13. data/lib/datadog/ci/contrib/parallel_tests/patcher.rb +24 -0
  14. data/lib/datadog/ci/contrib/rspec/example.rb +7 -0
  15. data/lib/datadog/ci/contrib/rspec/example_group.rb +18 -8
  16. data/lib/datadog/ci/contrib/rspec/helpers.rb +18 -0
  17. data/lib/datadog/ci/contrib/rspec/runner.rb +3 -1
  18. data/lib/datadog/ci/ext/settings.rb +1 -0
  19. data/lib/datadog/ci/ext/test.rb +20 -0
  20. data/lib/datadog/ci/git/local_repository.rb +1 -1
  21. data/lib/datadog/ci/git/tree_uploader.rb +9 -0
  22. data/lib/datadog/ci/readonly_test_module.rb +28 -0
  23. data/lib/datadog/ci/readonly_test_session.rb +31 -0
  24. data/lib/datadog/ci/remote/component.rb +43 -16
  25. data/lib/datadog/ci/span.rb +4 -0
  26. data/lib/datadog/ci/test_management/component.rb +34 -1
  27. data/lib/datadog/ci/test_management/tests_properties.rb +2 -1
  28. data/lib/datadog/ci/test_optimisation/component.rb +38 -33
  29. data/lib/datadog/ci/test_optimisation/skippable_percentage/base.rb +4 -0
  30. data/lib/datadog/ci/test_optimisation/skippable_percentage/calculator.rb +3 -3
  31. data/lib/datadog/ci/test_retries/strategy/retry_new.rb +1 -1
  32. data/lib/datadog/ci/test_session.rb +7 -1
  33. data/lib/datadog/ci/test_suite.rb +18 -0
  34. data/lib/datadog/ci/test_visibility/component.rb +130 -30
  35. data/lib/datadog/ci/test_visibility/context.rb +102 -41
  36. data/lib/datadog/ci/test_visibility/null_component.rb +5 -1
  37. data/lib/datadog/ci/test_visibility/store/{local.rb → fiber_local.rb} +1 -1
  38. data/lib/datadog/ci/test_visibility/store/{global.rb → process.rb} +26 -14
  39. data/lib/datadog/ci/test_visibility/transport.rb +1 -2
  40. data/lib/datadog/ci/transport/http.rb +1 -1
  41. data/lib/datadog/ci/utils/file_storage.rb +57 -0
  42. data/lib/datadog/ci/utils/stateful.rb +52 -0
  43. data/lib/datadog/ci/version.rb +1 -1
  44. data/lib/datadog/ci.rb +5 -4
  45. metadata +28 -5
  46. data/lib/datadog/ci/test_visibility/capabilities.rb +0 -36
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bc134bf501f298c7803572320d3c82d93b64b0dbfc59b2d8219d42fd5fed24e6
4
- data.tar.gz: 4714f599fef9eae12cb3dc99dfb17dc0431a9dfee7d9337da9fada542429c6c5
3
+ metadata.gz: c4507da31359cd997cb38e73190a4e6514ad8c69d86f9ce1b0c47fd7764e5dbd
4
+ data.tar.gz: 515872f426f95492fed9d1577f14bb7b1e447b0c011edf2bbfbb7ea23992d9cc
5
5
  SHA512:
6
- metadata.gz: e54fa5b48885accd1c304fca925292470930f6c916e318c5a02eed24989d089e431b99aa56c3eab75f1ed4445c3ab8bd14b1783baa01c32e52bf3d0df5f3813b
7
- data.tar.gz: 0f42913850d53736f3b058db3c7bea7e2f4cc0c5ccf511545d052afb142967084185075888511887185dbf5b82ee4b6931b7da76f91b91fe0c99760efb1b9574
6
+ metadata.gz: 3d0db7cb6a13a4c2f0b38b22c8dc2470a9ec760c38312c929a7b6224b118e18b279addf76901f7f094f60123a9e65d9afef06c15970bf01b247bc031bf80725d
7
+ data.tar.gz: f731bc7979a69ae63362d06d0313754bd825a22baf934cb682c1dc2a16a8584d0c3ece806f2bfb75d42924c09fff6296bf8c5c1be142afbe3ab7716bcb753815
data/CHANGELOG.md CHANGED
@@ -1,5 +1,29 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [1.15.0] - 2025-03-25
4
+
5
+
6
+ ### Added
7
+
8
+ * parallel tests gem support ([#299][])
9
+ * implemented attempt to fix flow V2 ([#298][])
10
+
11
+ ### Fixed
12
+
13
+ * Fix: prevent test impact analysis from skipping flaky tests that are attempted to be fixed ([#301][])
14
+ * Fix git commit message extraction to extract multiline commit messages correctly ([#300][])
15
+
16
+ ## [1.14.0] - 2025-03-11
17
+
18
+ ### Added
19
+
20
+ * Test impact analysis: add rails parallel testing support ([#294][])
21
+ * Add parallel testing support to minitest framework ([#295][])
22
+
23
+ ### Changed
24
+
25
+ * Test knapsack_pro v8 ([#292][])
26
+
3
27
  ## [1.13.0] - 2025-02-25
4
28
 
5
29
  ### Added
@@ -393,7 +417,9 @@ Currently test suite level visibility is not used by our instrumentation: it wil
393
417
 
394
418
  - Ruby versions < 2.7 no longer supported ([#8][])
395
419
 
396
- [Unreleased]: https://github.com/DataDog/datadog-ci-rb/compare/v1.13.0...main
420
+ [Unreleased]: https://github.com/DataDog/datadog-ci-rb/compare/v1.15.0...main
421
+ [1.15.0]: https://github.com/DataDog/datadog-ci-rb/compare/v1.14.0...v1.15.0
422
+ [1.14.0]: https://github.com/DataDog/datadog-ci-rb/compare/v1.13.0...v1.14.0
397
423
  [1.13.0]: https://github.com/DataDog/datadog-ci-rb/compare/v1.12.0...v1.13.0
398
424
  [1.12.0]: https://github.com/DataDog/datadog-ci-rb/compare/v1.11.0...v1.12.0
399
425
  [1.11.0]: https://github.com/DataDog/datadog-ci-rb/compare/v1.10.0...v1.11.0
@@ -564,4 +590,11 @@ Currently test suite level visibility is not used by our instrumentation: it wil
564
590
  [#275]: https://github.com/DataDog/datadog-ci-rb/issues/275
565
591
  [#283]: https://github.com/DataDog/datadog-ci-rb/issues/283
566
592
  [#286]: https://github.com/DataDog/datadog-ci-rb/issues/286
567
- [#289]: https://github.com/DataDog/datadog-ci-rb/issues/289
593
+ [#289]: https://github.com/DataDog/datadog-ci-rb/issues/289
594
+ [#292]: https://github.com/DataDog/datadog-ci-rb/issues/292
595
+ [#294]: https://github.com/DataDog/datadog-ci-rb/issues/294
596
+ [#295]: https://github.com/DataDog/datadog-ci-rb/issues/295
597
+ [#298]: https://github.com/DataDog/datadog-ci-rb/issues/298
598
+ [#299]: https://github.com/DataDog/datadog-ci-rb/issues/299
599
+ [#300]: https://github.com/DataDog/datadog-ci-rb/issues/300
600
+ [#301]: https://github.com/DataDog/datadog-ci-rb/issues/301
@@ -129,7 +129,8 @@ module Datadog
129
129
  @test_visibility = TestVisibility::Component.new(
130
130
  test_suite_level_visibility_enabled: !settings.ci.force_test_level_visibility,
131
131
  logical_test_session_name: settings.ci.test_session_name,
132
- known_tests_client: build_known_tests_client(settings, test_visibility_api)
132
+ known_tests_client: build_known_tests_client(settings, test_visibility_api),
133
+ context_service_uri: settings.ci.test_visibility_drb_server_uri
133
134
  )
134
135
  end
135
136
 
@@ -134,6 +134,12 @@ module Datadog
134
134
  o.default false
135
135
  end
136
136
 
137
+ # internal only
138
+ option :test_visibility_drb_server_uri do |o|
139
+ o.type :string, nilable: true
140
+ o.env CI::Ext::Settings::ENV_TEST_VISIBILITY_DRB_SERVER_URI
141
+ end
142
+
137
143
  define_method(:instrument) do |integration_name, options = {}, &block|
138
144
  return unless enabled
139
145
 
@@ -5,6 +5,32 @@ module Datadog
5
5
  module Contrib
6
6
  module Minitest
7
7
  module Helpers
8
+ def self.start_test_suite(klass)
9
+ method = klass.runnable_methods.first
10
+ return nil if method.nil?
11
+
12
+ test_suite_name = test_suite_name(klass, method)
13
+ source_file, line_number = extract_source_location_from_class(klass)
14
+
15
+ test_suite_tags = if source_file
16
+ {
17
+ CI::Ext::Test::TAG_SOURCE_FILE => (Git::LocalRepository.relative_to_root(source_file) if source_file),
18
+ CI::Ext::Test::TAG_SOURCE_START => line_number&.to_s
19
+ }
20
+ else
21
+ {}
22
+ end
23
+
24
+ test_visibility_component = Datadog.send(:components).test_visibility
25
+ test_suite = test_visibility_component.start_test_suite(
26
+ test_suite_name,
27
+ tags: test_suite_tags
28
+ )
29
+ test_suite&.set_expected_tests!(klass.runnable_methods)
30
+
31
+ test_suite
32
+ end
33
+
8
34
  def self.test_suite_name(klass, method_name)
9
35
  source_location = extract_source_location_from_class(klass)&.first
10
36
  # if we are in anonymous class, fallback to the method source location
@@ -14,25 +14,7 @@ module Datadog
14
14
  return super unless datadog_configuration[:enabled]
15
15
  return super if Helpers.parallel?(self)
16
16
 
17
- method = runnable_methods.first
18
- return super if method.nil?
19
-
20
- test_suite_name = Helpers.test_suite_name(self, method)
21
- source_file, line_number = Helpers.extract_source_location_from_class(self)
22
-
23
- test_suite_tags = if source_file
24
- {
25
- CI::Ext::Test::TAG_SOURCE_FILE => (Git::LocalRepository.relative_to_root(source_file) if source_file),
26
- CI::Ext::Test::TAG_SOURCE_START => line_number&.to_s
27
- }
28
- else
29
- {}
30
- end
31
-
32
- test_suite = test_visibility_component.start_test_suite(
33
- test_suite_name,
34
- tags: test_suite_tags
35
- )
17
+ test_suite = Helpers.start_test_suite(self)
36
18
 
37
19
  results = super
38
20
  return results unless test_suite
@@ -9,8 +9,6 @@ module Datadog
9
9
  module Contrib
10
10
  module Minitest
11
11
  module Runner
12
- DD_ESTIMATED_TESTS_PER_SUITE = 5
13
-
14
12
  def self.included(base)
15
13
  base.singleton_class.prepend(ClassMethods)
16
14
  end
@@ -21,15 +19,18 @@ module Datadog
21
19
 
22
20
  return unless datadog_configuration[:enabled]
23
21
 
24
- # minitest does not store the total number of tests, so we can't pass it to the test session
25
- # instead, we use the number of test suites * DD_ESTIMATED_TESTS_PER_SUITE as a rough estimate
22
+ tests_count = ::Minitest::Runnable.runnables.sum { |runnable| runnable.runnable_methods.size }
23
+
26
24
  test_visibility_component.start_test_session(
27
25
  tags: {
28
26
  CI::Ext::Test::TAG_FRAMEWORK => Ext::FRAMEWORK,
29
27
  CI::Ext::Test::TAG_FRAMEWORK_VERSION => datadog_integration.version.to_s
30
28
  },
31
29
  service: datadog_configuration[:service_name],
32
- total_tests_count: (DD_ESTIMATED_TESTS_PER_SUITE * ::Minitest::Runnable.runnables.size).to_i
30
+ estimated_total_tests_count: tests_count,
31
+ # if minitest is being used with a parallel runner, then tests split will happen by example, not by test suite
32
+ # we need to always start/stop test suites in the parent process in this case
33
+ local_test_suites_mode: false
33
34
  )
34
35
  test_visibility_component.start_test_module(Ext::FRAMEWORK)
35
36
  end
@@ -43,6 +44,12 @@ module Datadog
43
44
  result = super
44
45
  end
45
46
 
47
+ # get the current test suite and mark this method as done, so we can check if all tests were executed
48
+ # for this test suite
49
+ test_suite_name = Helpers.test_suite_name(klass, method_name)
50
+ test_suite = test_visibility_component.active_test_suite(test_suite_name)
51
+ test_suite&.expected_test_done!(method_name)
52
+
46
53
  result
47
54
  end
48
55
 
@@ -22,14 +22,11 @@ module Datadog
22
22
  super
23
23
  return unless datadog_configuration[:enabled]
24
24
 
25
- test_suite_name = Helpers.test_suite_name(self.class, name)
26
25
  if Helpers.parallel?(self.class)
27
- test_suite_name = "#{test_suite_name} (#{name} concurrently)"
28
-
29
- # for parallel execution we need to start a new test suite for each test
30
- test_visibility_component.start_test_suite(test_suite_name)
26
+ Helpers.start_test_suite(self.class)
31
27
  end
32
28
 
29
+ test_suite_name = Helpers.test_suite_name(self.class, name)
33
30
  source_file, line_number = method(name).source_location
34
31
 
35
32
  test_span = test_visibility_component.trace_test(
@@ -56,10 +53,6 @@ module Datadog
56
53
  # remove failures if test passed at least once on retries or quarantined
57
54
  self.failures = [] if test_span.should_ignore_failures?
58
55
 
59
- if Helpers.parallel?(self.class)
60
- finish_with_result(test_span.test_suite, result_code)
61
- end
62
-
63
56
  super
64
57
  end
65
58
 
@@ -0,0 +1,84 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../../ext/test"
4
+ require_relative "../rspec/ext"
5
+
6
+ module Datadog
7
+ module CI
8
+ module Contrib
9
+ module ParallelTests
10
+ module CLI
11
+ def self.included(base)
12
+ base.prepend(InstanceMethods)
13
+ end
14
+
15
+ module InstanceMethods
16
+ def run_tests_in_parallel(num_processes, options)
17
+ # only rspec runner is supported for now
18
+ return super if @runner != ::ParallelTests::RSpec::Runner
19
+
20
+ begin
21
+ test_session = test_visibility_component.start_test_session(
22
+ tags: {
23
+ CI::Ext::Test::TAG_FRAMEWORK => CI::Contrib::RSpec::Ext::FRAMEWORK,
24
+ CI::Ext::Test::TAG_FRAMEWORK_VERSION => datadog_extract_rspec_version
25
+ },
26
+ service: datadog_configuration[:service_name],
27
+ estimated_total_tests_count: 10_000, # temporary value, updated by child processes
28
+ distributed: true
29
+ )
30
+ test_module = test_visibility_component.start_test_module("rspec")
31
+
32
+ options[:env] ||= {}
33
+ options[:env][CI::Ext::Settings::ENV_TEST_VISIBILITY_DRB_SERVER_URI] = test_visibility_component.context_service_uri
34
+
35
+ super
36
+ ensure
37
+ test_module&.finish
38
+ test_session&.finish
39
+ end
40
+ end
41
+
42
+ def any_test_failed?(test_results)
43
+ res = super
44
+
45
+ test_session = test_visibility_component.active_test_session
46
+ test_module = test_visibility_component.active_test_module
47
+ if res
48
+ test_module&.failed!
49
+ test_session&.failed!
50
+ else
51
+ test_module&.passed!
52
+ test_session&.passed!
53
+ end
54
+
55
+ res
56
+ end
57
+
58
+ def datadog_extract_rspec_version
59
+ # Try to find either 'rspec' or 'rspec-core' gem
60
+ if Gem.loaded_specs["rspec"]
61
+ Gem.loaded_specs["rspec"].version.to_s
62
+ elsif Gem.loaded_specs["rspec-core"]
63
+ Gem.loaded_specs["rspec-core"].version.to_s
64
+ else
65
+ "0.0.0"
66
+ end
67
+ rescue => e
68
+ Datadog.logger.debug("Error extracting RSpec version: #{e.class.name} - #{e.message}")
69
+ "0.0.0"
70
+ end
71
+
72
+ def datadog_configuration
73
+ Datadog.configuration.ci[:paralleltests]
74
+ end
75
+
76
+ def test_visibility_component
77
+ Datadog.send(:components).test_visibility
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../ext"
4
+ require_relative "../../settings"
5
+ require_relative "../../../utils/configuration"
6
+
7
+ module Datadog
8
+ module CI
9
+ module Contrib
10
+ module ParallelTests
11
+ module Configuration
12
+ # Custom settings for the ParallelTests integration
13
+ # @public_api
14
+ class Settings < Datadog::CI::Contrib::Settings
15
+ option :enabled do |o|
16
+ o.type :bool
17
+ o.env Ext::ENV_ENABLED
18
+ o.default true
19
+ end
20
+
21
+ option :service_name do |o|
22
+ o.type :string
23
+ o.default do
24
+ Utils::Configuration.fetch_service_name(Ext::DEFAULT_SERVICE_NAME)
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Datadog
4
+ module CI
5
+ module Contrib
6
+ module ParallelTests
7
+ # Datadog ParallelTests integration constants
8
+ module Ext
9
+ ENV_ENABLED = "DD_TRACE_PARALLEL_TESTS_ENABLED"
10
+
11
+ DEFAULT_SERVICE_NAME = "parallel_tests"
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../integration"
4
+ require_relative "configuration/settings"
5
+ require_relative "patcher"
6
+
7
+ module Datadog
8
+ module CI
9
+ module Contrib
10
+ module ParallelTests
11
+ # Description of ParallelTests integration
12
+ class Integration < Datadog::CI::Contrib::Integration
13
+ MINIMUM_VERSION = Gem::Version.new("4.0")
14
+
15
+ def version
16
+ Gem.loaded_specs["parallel_tests"]&.version
17
+ end
18
+
19
+ def loaded?
20
+ !defined?(::ParallelTests).nil? && !defined?(::ParallelTests::CLI).nil?
21
+ end
22
+
23
+ def compatible?
24
+ super && version >= MINIMUM_VERSION
25
+ end
26
+
27
+ def late_instrument?
28
+ false
29
+ end
30
+
31
+ def new_configuration
32
+ Configuration::Settings.new
33
+ end
34
+
35
+ def patcher
36
+ Patcher
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "cli"
4
+ require_relative "integration"
5
+ require_relative "../patcher"
6
+
7
+ module Datadog
8
+ module CI
9
+ module Contrib
10
+ module ParallelTests
11
+ # Patcher enables patching of parallel_tests module
12
+ module Patcher
13
+ include Datadog::CI::Contrib::Patcher
14
+
15
+ module_function
16
+
17
+ def patch
18
+ ::ParallelTests::CLI.include(CLI)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -97,6 +97,13 @@ module Datadog
97
97
  )
98
98
  end
99
99
 
100
+ def datadog_fqn_test_id
101
+ @datadog_fqn_test_id ||= Utils::TestRun.datadog_test_id(
102
+ datadog_test_name,
103
+ datadog_test_suite_name
104
+ )
105
+ end
106
+
100
107
  def datadog_unskippable?
101
108
  !!metadata[CI::Ext::Test::ITR_UNSKIPPABLE_OPTION]
102
109
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require_relative "../../ext/test"
4
4
  require_relative "ext"
5
+ require_relative "helpers"
5
6
 
6
7
  module Datadog
7
8
  module CI
@@ -28,13 +29,17 @@ module Datadog
28
29
  return super unless top_level?
29
30
 
30
31
  suite_name = "#{description} at #{file_path}"
31
- test_suite = test_visibility_component&.start_test_suite(
32
- suite_name,
33
- tags: {
34
- CI::Ext::Test::TAG_SOURCE_FILE => Git::LocalRepository.relative_to_root(metadata[:file_path]),
35
- CI::Ext::Test::TAG_SOURCE_START => metadata[:line_number].to_s
36
- }
37
- )
32
+ suite_tags = {
33
+ CI::Ext::Test::TAG_SOURCE_FILE => Git::LocalRepository.relative_to_root(metadata[:file_path]),
34
+ CI::Ext::Test::TAG_SOURCE_START => metadata[:line_number].to_s
35
+ }
36
+
37
+ test_suite =
38
+ test_visibility_component&.start_test_suite(
39
+ suite_name,
40
+ tags: suite_tags,
41
+ service: datadog_configuration[:service_name]
42
+ )
38
43
 
39
44
  success = super
40
45
  return success unless test_suite
@@ -56,7 +61,8 @@ module Datadog
56
61
 
57
62
  def all_examples_skipped_by_datadog?
58
63
  descendant_filtered_examples.all? do |example|
59
- !example.datadog_unskippable? && test_optimisation_component&.skippable?(example)
64
+ !example.datadog_unskippable? && test_optimisation_component&.skippable?(example.datadog_test_id) &&
65
+ !test_management_component&.attempt_to_fix?(example.datadog_fqn_test_id)
60
66
  end
61
67
  end
62
68
 
@@ -71,6 +77,10 @@ module Datadog
71
77
  def test_optimisation_component
72
78
  Datadog.send(:components).test_optimisation
73
79
  end
80
+
81
+ def test_management_component
82
+ Datadog.send(:components).test_management
83
+ end
74
84
  end
75
85
  end
76
86
  end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Datadog
4
+ module CI
5
+ module Contrib
6
+ module RSpec
7
+ # Helper methods for RSpec instrumentation
8
+ module Helpers
9
+ module_function
10
+
11
+ def parallel_tests?
12
+ !!ENV.fetch("TEST_ENV_NUMBER", nil) && !!ENV.fetch("PARALLEL_TEST_GROUPS", nil)
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -3,6 +3,7 @@
3
3
  require_relative "../../ext/test"
4
4
  require_relative "../instrumentation"
5
5
  require_relative "ext"
6
+ require_relative "helpers"
6
7
 
7
8
  module Datadog
8
9
  module CI
@@ -25,13 +26,14 @@ module Datadog
25
26
  CI::Ext::Test::TAG_FRAMEWORK_VERSION => datadog_integration.version.to_s
26
27
  },
27
28
  service: datadog_configuration[:service_name],
28
- total_tests_count: ::RSpec.world.example_count
29
+ estimated_total_tests_count: ::RSpec.world.example_count
29
30
  )
30
31
 
31
32
  test_module = test_visibility_component.start_test_module(Ext::FRAMEWORK)
32
33
 
33
34
  result = super
34
35
  return result unless test_module && test_session
36
+ return result if Helpers.parallel_tests?
35
37
 
36
38
  if result != 0
37
39
  test_module.failed!
@@ -22,6 +22,7 @@ module Datadog
22
22
  ENV_TEST_SESSION_NAME = "DD_TEST_SESSION_NAME"
23
23
  ENV_TEST_MANAGEMENT_ENABLED = "DD_TEST_MANAGEMENT_ENABLED"
24
24
  ENV_TEST_MANAGEMENT_ATTEMPT_TO_FIX_RETRIES = "DD_TEST_MANAGEMENT_ATTEMPT_TO_FIX_RETRIES"
25
+ ENV_TEST_VISIBILITY_DRB_SERVER_URI = "DD_TEST_VISIBILITY_DRB_SERVER_URI"
25
26
 
26
27
  # Source: https://docs.datadoghq.com/getting_started/site/
27
28
  DD_SITE_ALLOWLIST = %w[
@@ -86,6 +86,26 @@ module Datadog
86
86
  TAG_TEST_MANAGEMENT_QUARANTINE = "_dd.library_capabilities.test_management.quarantine"
87
87
  TAG_TEST_MANAGEMENT_DISABLE = "_dd.library_capabilities.test_management.disable"
88
88
  TAG_TEST_MANAGEMENT_ATTEMPT_TO_FIX = "_dd.library_capabilities.test_management.attempt_to_fix"
89
+
90
+ # Version numbers for library capabilities
91
+ module Versions
92
+ TEST_IMPACT_ANALYSIS_VERSION = "1"
93
+ EARLY_FLAKE_DETECTION_VERSION = "1"
94
+ AUTO_TEST_RETRIES_VERSION = "1"
95
+ TEST_MANAGEMENT_QUARANTINE_VERSION = "1"
96
+ TEST_MANAGEMENT_DISABLE_VERSION = "1"
97
+ TEST_MANAGEMENT_ATTEMPT_TO_FIX_VERSION = "2"
98
+ end
99
+
100
+ # Map of capabilities to their versions
101
+ CAPABILITY_VERSIONS = {
102
+ TAG_TEST_IMPACT_ANALYSIS => Versions::TEST_IMPACT_ANALYSIS_VERSION,
103
+ TAG_EARLY_FLAKE_DETECTION => Versions::EARLY_FLAKE_DETECTION_VERSION,
104
+ TAG_AUTO_TEST_RETRIES => Versions::AUTO_TEST_RETRIES_VERSION,
105
+ TAG_TEST_MANAGEMENT_QUARANTINE => Versions::TEST_MANAGEMENT_QUARANTINE_VERSION,
106
+ TAG_TEST_MANAGEMENT_DISABLE => Versions::TEST_MANAGEMENT_DISABLE_VERSION,
107
+ TAG_TEST_MANAGEMENT_ATTEMPT_TO_FIX => Versions::TEST_MANAGEMENT_ATTEMPT_TO_FIX_VERSION
108
+ }.freeze
89
109
  end
90
110
 
91
111
  # internal APM tag to mark a span as a test span
@@ -142,7 +142,7 @@ module Datadog
142
142
  end
143
143
 
144
144
  def self.git_commit_message
145
- exec_git_command("git show -s --format=%s")
145
+ exec_git_command("git log -n 1 --format=%B")
146
146
  rescue => e
147
147
  log_failure(e, "git commit message")
148
148
  nil
@@ -27,6 +27,11 @@ module Datadog
27
27
  return
28
28
  end
29
29
 
30
+ if test_visibility_component.client_process?
31
+ Datadog.logger.debug("Test visibility component is running in client process, aborting git upload")
32
+ return
33
+ end
34
+
30
35
  Datadog.logger.debug { "Uploading git tree for repository #{repository_url}" }
31
36
 
32
37
  latest_commits = LocalRepository.git_commits
@@ -91,6 +96,10 @@ module Datadog
91
96
  backend_commits.include?(commit)
92
97
  end
93
98
  end
99
+
100
+ def test_visibility_component
101
+ Datadog.send(:components).test_visibility
102
+ end
94
103
  end
95
104
  end
96
105
  end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "test_module"
4
+
5
+ module Datadog
6
+ module CI
7
+ # @internal_api
8
+ class ReadonlyTestModule < TestModule
9
+ def initialize(test_module)
10
+ @id = test_module.id
11
+ @name = test_module.name
12
+ end
13
+ attr_reader :id, :name
14
+
15
+ def finish
16
+ raise "ReadonlyTestModule cannot be finished"
17
+ end
18
+
19
+ def set_tag(key, value)
20
+ raise "ReadonlyTestModule cannot be modified"
21
+ end
22
+
23
+ def set_metric(key, value)
24
+ raise "ReadonlyTestModule cannot be modified"
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "test_session"
4
+
5
+ module Datadog
6
+ module CI
7
+ # @internal_api
8
+ class ReadonlyTestSession < TestSession
9
+ def initialize(test_session)
10
+ @id = test_session.id
11
+ @name = test_session.name
12
+ @inheritable_tags = test_session.inheritable_tags
13
+ @service = test_session.service
14
+ end
15
+
16
+ attr_reader :id, :name, :inheritable_tags, :service
17
+
18
+ def finish
19
+ raise "ReadonlyTestSession cannot be finished"
20
+ end
21
+
22
+ def set_tag(key, value)
23
+ raise "ReadonlyTestSession cannot be modified"
24
+ end
25
+
26
+ def set_metric(key, value)
27
+ raise "ReadonlyTestSession cannot be modified"
28
+ end
29
+ end
30
+ end
31
+ end