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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 262f238c451500ef744ff6f24ba5176a5e2064ef49d46055965bb5ed13bc70ea
4
- data.tar.gz: 3023b3bca603feb1a591ebf8e68c9339cc887aaea2466fda2596c3cb6a209295
3
+ metadata.gz: 63e9fdf2c856764bb9567cf89d76f27a4f327244152c510abcd4d64e180a0cc6
4
+ data.tar.gz: 963f5b534027215799efe65a108a4aa8267c2c31aa4fc1402d19d02f996fc2e9
5
5
  SHA512:
6
- metadata.gz: a15556f403d45a9b4384643028ca42971f40847f7cb0a090ae4776a2e4f1615931fe8612f5306f21578ed30d72e15d725d1fbe74f488752cbec01f30f74a67ed
7
- data.tar.gz: 02c7f199399babed0311149c2abca1a3cad27b705d92b139e0485351589707e24ee136ccebae5cef1361afdaabdfe5e2209fa97bd65edfeb947777156bd91c68
6
+ metadata.gz: e94bbd5cc929f95a386cadd633b93f2a53962eefe686354712a9801a8b9865a52fc74c6401f96635a47b9001d71287cadc568ba3bb81ed764d68bdf232b85e5b
7
+ data.tar.gz: 7a33d2dc09b32798f2fcae80a96bec0e919b4c60f65283f4cf158a020ecd573e450bb925c790c822c63a86b4cf214fae4427e7d4bdb6cde28ca1105dcc95a20a
data/CHANGELOG.md CHANGED
@@ -1,5 +1,28 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.6.0] - 2024-01-03
4
+
5
+ ### Added
6
+
7
+ * Test suite level visibility instrumentation for RSpec ([#86][])
8
+ * Test suite level visibility instrumentation for Cucumber ([#90][])
9
+ * Test suite level visibility instrumentation for Minitest framework ([#92][])
10
+
11
+ ### Fixed
12
+
13
+ * Do not instantiate TestVisibility::Recorder unless CI visibility is enabled ([#89][])
14
+
15
+ ## [0.5.1] - 2023-12-11
16
+
17
+ ### Fixed
18
+
19
+ * do not collect environment tags when CI is not enabled ([#87][])
20
+
21
+ ### Changed
22
+
23
+ * Move private classes and modules deeper in module hierarchy ([#85][])
24
+ * update appraisal dependencies ([#84][])
25
+
3
26
  ## [0.5.0] - 2023-12-06
4
27
 
5
28
  ### Test suite level visibility
@@ -101,7 +124,8 @@ Currently test suite level visibility is not used by our instrumentation: it wil
101
124
 
102
125
  * Ruby versions < 2.7 no longer supported ([#8][])
103
126
 
104
- [Unreleased]: https://github.com/DataDog/datadog-ci-rb/compare/v0.5.0...main
127
+ [Unreleased]: https://github.com/DataDog/datadog-ci-rb/compare/v0.5.1...main
128
+ [0.5.1]: https://github.com/DataDog/datadog-ci-rb/compare/v0.5.0...v0.5.1
105
129
  [0.5.0]: https://github.com/DataDog/datadog-ci-rb/compare/v0.4.1...v0.5.0
106
130
  [0.4.1]: https://github.com/DataDog/datadog-ci-rb/compare/v0.4.0...v0.4.1
107
131
  [0.4.0]: https://github.com/DataDog/datadog-ci-rb/compare/v0.3.0...v0.4.0
@@ -138,4 +162,11 @@ Currently test suite level visibility is not used by our instrumentation: it wil
138
162
  [#79]: https://github.com/DataDog/datadog-ci-rb/issues/79
139
163
  [#80]: https://github.com/DataDog/datadog-ci-rb/issues/80
140
164
  [#81]: https://github.com/DataDog/datadog-ci-rb/issues/81
141
- [#82]: https://github.com/DataDog/datadog-ci-rb/issues/82
165
+ [#82]: https://github.com/DataDog/datadog-ci-rb/issues/82
166
+ [#84]: https://github.com/DataDog/datadog-ci-rb/issues/84
167
+ [#85]: https://github.com/DataDog/datadog-ci-rb/issues/85
168
+ [#86]: https://github.com/DataDog/datadog-ci-rb/issues/86
169
+ [#87]: https://github.com/DataDog/datadog-ci-rb/issues/87
170
+ [#89]: https://github.com/DataDog/datadog-ci-rb/issues/89
171
+ [#90]: https://github.com/DataDog/datadog-ci-rb/issues/90
172
+ [#92]: https://github.com/DataDog/datadog-ci-rb/issues/92
@@ -6,11 +6,12 @@ require "datadog/core/remote/negotiation"
6
6
  require_relative "../ext/transport"
7
7
  require_relative "../ext/settings"
8
8
  require_relative "../test_visibility/flush"
9
- require_relative "../test_visibility/transport"
9
+ require_relative "../test_visibility/recorder"
10
+ require_relative "../test_visibility/null_recorder"
10
11
  require_relative "../test_visibility/serializers/factories/test_level"
11
12
  require_relative "../test_visibility/serializers/factories/test_suite_level"
13
+ require_relative "../test_visibility/transport"
12
14
  require_relative "../transport/api/builder"
13
- require_relative "../recorder"
14
15
 
15
16
  module Datadog
16
17
  module CI
@@ -21,14 +22,12 @@ module Datadog
21
22
 
22
23
  def initialize(settings)
23
24
  # Activate CI mode if enabled
24
- activate_ci!(settings) if settings.ci.enabled
25
-
26
- @ci_recorder = Recorder.new(
27
- enabled: settings.ci.enabled,
28
- test_suite_level_visibility_enabled: settings.ci.experimental_test_suite_level_visibility_enabled
29
- )
25
+ if settings.ci.enabled
26
+ activate_ci!(settings)
27
+ else
28
+ @ci_recorder = TestVisibility::NullRecorder.new
29
+ end
30
30
 
31
- # Initialize normally
32
31
  super
33
32
  end
34
33
 
@@ -65,11 +64,16 @@ module Datadog
65
64
  if test_visibility_transport
66
65
  writer_options[:transport] = test_visibility_transport
67
66
  writer_options[:shutdown_timeout] = 60
67
+ writer_options[:buffer_size] = 10_000
68
68
 
69
69
  settings.tracing.test_mode.async = true
70
70
  end
71
71
 
72
72
  settings.tracing.test_mode.writer_options = writer_options
73
+
74
+ @ci_recorder = TestVisibility::Recorder.new(
75
+ test_suite_level_visibility_enabled: settings.ci.experimental_test_suite_level_visibility_enabled
76
+ )
73
77
  end
74
78
 
75
79
  def can_use_evp_proxy?(settings, agent_settings)
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "datadog/core/configuration/settings"
4
+ require "datadog/core/configuration/components"
5
+
6
+ require_relative "settings"
7
+ require_relative "components"
8
+
9
+ module Datadog
10
+ module CI
11
+ module Configuration
12
+ # Extends Datadog tracing with CI features
13
+ module Extensions
14
+ def self.activate!
15
+ Core::Configuration::Settings.extend(CI::Configuration::Settings)
16
+ Core::Configuration::Components.prepend(CI::Configuration::Components)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -21,7 +21,7 @@ module Datadog
21
21
 
22
22
  option :service_name do |o|
23
23
  o.type :string
24
- o.default { Datadog.configuration.service_without_fallback || Ext::SERVICE_NAME }
24
+ o.default { Datadog.configuration.service_without_fallback || Ext::DEFAULT_SERVICE_NAME }
25
25
  end
26
26
 
27
27
  # @deprecated Will be removed in 1.0
@@ -7,14 +7,16 @@ module Datadog
7
7
  # Cucumber integration constants
8
8
  # TODO: mark as `@public_api` when GA, to protect from resource and tag name changes.
9
9
  module Ext
10
- APP = "cucumber"
11
10
  ENV_ENABLED = "DD_TRACE_CUCUMBER_ENABLED"
12
- ENV_OPERATION_NAME = "DD_TRACE_CUCUMBER_OPERATION_NAME"
11
+ DEFAULT_SERVICE_NAME = "cucumber"
12
+
13
13
  FRAMEWORK = "cucumber"
14
- OPERATION_NAME = "cucumber.test"
15
- SERVICE_NAME = "cucumber"
14
+
16
15
  STEP_SPAN_TYPE = "step"
17
- TEST_TYPE = "test"
16
+
17
+ # TODO: remove in 1.0
18
+ ENV_OPERATION_NAME = "DD_TRACE_CUCUMBER_OPERATION_NAME"
19
+ OPERATION_NAME = "cucumber.test"
18
20
  end
19
21
  end
20
22
  end
@@ -9,31 +9,60 @@ module Datadog
9
9
  module Cucumber
10
10
  # Defines collection of instrumented Cucumber events
11
11
  class Formatter
12
- attr_reader :config, :current_feature_span, :current_step_span
12
+ attr_reader :config
13
13
  private :config
14
- private :current_feature_span, :current_step_span
15
14
 
16
15
  def initialize(config)
17
16
  @config = config
17
+ @failed_tests_count = 0
18
+
19
+ @current_test_suite = nil
20
+ @failed_tests_in_current_test_suite = 0
18
21
 
19
22
  bind_events(config)
20
23
  end
21
24
 
22
25
  def bind_events(config)
26
+ config.on_event :test_run_started, &method(:on_test_run_started)
27
+ config.on_event :test_run_finished, &method(:on_test_run_finished)
23
28
  config.on_event :test_case_started, &method(:on_test_case_started)
24
29
  config.on_event :test_case_finished, &method(:on_test_case_finished)
25
30
  config.on_event :test_step_started, &method(:on_test_step_started)
26
31
  config.on_event :test_step_finished, &method(:on_test_step_finished)
27
32
  end
28
33
 
34
+ def on_test_run_started(event)
35
+ test_session = CI.start_test_session(
36
+ tags: {
37
+ CI::Ext::Test::TAG_FRAMEWORK => Ext::FRAMEWORK,
38
+ CI::Ext::Test::TAG_FRAMEWORK_VERSION => CI::Contrib::Cucumber::Integration.version.to_s,
39
+ CI::Ext::Test::TAG_TYPE => CI::Ext::Test::TEST_TYPE
40
+ },
41
+ service: configuration[:service_name]
42
+ )
43
+ CI.start_test_module(test_session.name)
44
+ end
45
+
46
+ def on_test_run_finished(event)
47
+ if event.respond_to?(:success)
48
+ finish_session(event.success)
49
+ else
50
+ finish_session(@failed_tests_count.zero?)
51
+ end
52
+ end
53
+
29
54
  def on_test_case_started(event)
55
+ test_suite_name = event.test_case.location.file
56
+
57
+ start_test_suite(test_suite_name) unless same_test_suite_as_current?(test_suite_name)
58
+
30
59
  CI.start_test(
31
60
  event.test_case.name,
32
- event.test_case.location.file,
61
+ test_suite_name,
33
62
  tags: {
34
63
  CI::Ext::Test::TAG_FRAMEWORK => Ext::FRAMEWORK,
35
64
  CI::Ext::Test::TAG_FRAMEWORK_VERSION => CI::Contrib::Cucumber::Integration.version.to_s,
36
- CI::Ext::Test::TAG_TYPE => Ext::TEST_TYPE
65
+ CI::Ext::Test::TAG_TYPE => CI::Ext::Test::TEST_TYPE
37
66
  },
38
67
  service: configuration[:service_name]
39
68
  )
@@ -43,15 +72,17 @@ module Datadog
43
72
  test_span = CI.active_test
44
73
  return if test_span.nil?
45
74
 
46
- if event.result.skipped?
47
- test_span.skipped!
48
- elsif event.result.ok?
49
- test_span.passed!
50
- elsif event.result.failed?
51
- test_span.failed!
75
+ # We need to track overall test failures manually if we are using cucumber < 8.0 because
76
+ # TestRunFinished event does not have a success attribute before 8.0.
77
+ #
78
+ # To track whether test suite failed or passed we need to
79
+ # track the number of failed tests in the current test suite.
80
+ if event.result.failed?
81
+ @failed_tests_count += 1
82
+ @failed_tests_in_current_test_suite += 1
52
83
  end
53
84
 
54
- test_span.finish
85
+ finish_test(test_span, event.result)
55
86
  end
56
87
 
57
88
  def on_test_step_started(event)
@@ -62,18 +93,67 @@ module Datadog
62
93
  current_step_span = CI.active_span(Ext::STEP_SPAN_TYPE)
63
94
  return if current_step_span.nil?
64
95
 
65
- if event.result.skipped?
66
- current_step_span.skipped!
67
- elsif event.result.ok?
68
- current_step_span.passed!
69
- elsif event.result.failed?
70
- current_step_span.failed!(exception: event.result.exception)
96
+ finish_test(current_step_span, event.result)
97
+ end
98
+
99
+ private
100
+
101
+ def finish_test(span, result)
102
+ if result.skipped?
103
+ span.skipped!
104
+ elsif result.ok?
105
+ span.passed!
106
+ elsif result.failed?
107
+ span.failed!(exception: result.exception)
71
108
  end
109
+ span.finish
110
+ end
111
+
112
+ def finish_session(result)
113
+ finish_current_test_suite
114
+
115
+ test_session = CI.active_test_session
116
+ test_module = CI.active_test_module
117
+
118
+ return unless test_session && test_module
72
119
 
73
- current_step_span.finish
120
+ if result
121
+ test_module.passed!
122
+ test_session.passed!
123
+ else
124
+ test_module.failed!
125
+ test_session.failed!
126
+ end
127
+
128
+ test_module.finish
129
+ test_session.finish
74
130
  end
75
131
 
76
- private
132
+ def start_test_suite(test_suite_name)
133
+ finish_current_test_suite
134
+
135
+ @current_test_suite = CI.start_test_suite(test_suite_name)
136
+ end
137
+
138
+ def finish_current_test_suite
139
+ test_suite = @current_test_suite
140
+ return unless test_suite
141
+
142
+ if @failed_tests_in_current_test_suite.zero?
143
+ test_suite.passed!
144
+ else
145
+ test_suite.failed!
146
+ end
147
+ @failed_tests_in_current_test_suite = 0
148
+ test_suite.finish
149
+ end
150
+
151
+ def same_test_suite_as_current?(test_suite_name)
152
+ test_suite = @current_test_suite
153
+ return false unless test_suite
154
+
155
+ test_suite.name == test_suite_name
156
+ end
77
157
 
78
158
  def configuration
79
159
  Datadog.configuration.ci[:cucumber]
@@ -19,7 +19,7 @@ module Datadog
19
19
 
20
20
  option :service_name do |o|
21
21
  o.type :string
22
- o.default { Datadog.configuration.service_without_fallback || Ext::SERVICE_NAME }
22
+ o.default { Datadog.configuration.service_without_fallback || Ext::DEFAULT_SERVICE_NAME }
23
23
  end
24
24
 
25
25
  # @deprecated Will be removed in 1.0
@@ -7,13 +7,15 @@ module Datadog
7
7
  # Minitest integration constants
8
8
  # TODO: mark as `@public_api` when GA, to protect from resource and tag name changes.
9
9
  module Ext
10
- APP = "minitest"
11
10
  ENV_ENABLED = "DD_TRACE_MINITEST_ENABLED"
12
- ENV_OPERATION_NAME = "DD_TRACE_MINITEST_OPERATION_NAME"
11
+
13
12
  FRAMEWORK = "minitest"
13
+
14
+ DEFAULT_SERVICE_NAME = "minitest"
15
+
16
+ # TODO: remove in 1.0
17
+ ENV_OPERATION_NAME = "DD_TRACE_MINITEST_OPERATION_NAME"
14
18
  OPERATION_NAME = "minitest.test"
15
- SERVICE_NAME = "minitest"
16
- TEST_TYPE = "test"
17
19
  end
18
20
  end
19
21
  end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Datadog
4
+ module CI
5
+ module Contrib
6
+ module Minitest
7
+ module Helpers
8
+ def self.test_suite_name(klass, method_name)
9
+ source_location, = klass.instance_method(method_name).source_location
10
+ source_file_path = Pathname.new(source_location.to_s).relative_path_from(Pathname.pwd).to_s
11
+
12
+ "#{klass.name} at #{source_file_path}"
13
+ end
14
+
15
+ def self.parallel?(klass)
16
+ klass.ancestors.include?(::Minitest::Parallel::Test)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ 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
@@ -11,22 +12,27 @@ module Datadog
11
12
  module Hooks
12
13
  def before_setup
13
14
  super
14
- return unless configuration[:enabled]
15
+ return unless datadog_configuration[:enabled]
15
16
 
16
17
  test_name = "#{class_name}##{name}"
17
18
 
18
- path, = method(name).source_location
19
- test_suite = Pathname.new(path.to_s).relative_path_from(Pathname.pwd).to_s
19
+ test_suite_name = Helpers.test_suite_name(self.class, name)
20
+ if Helpers.parallel?(self.class)
21
+ test_suite_name = "#{test_suite_name} (#{name} concurrently)"
22
+
23
+ # for parallel execution we need to start a new test suite for each test
24
+ CI.start_test_suite(test_suite_name)
25
+ end
20
26
 
21
27
  CI.start_test(
22
28
  test_name,
23
- test_suite,
29
+ test_suite_name,
24
30
  tags: {
25
31
  CI::Ext::Test::TAG_FRAMEWORK => Ext::FRAMEWORK,
26
32
  CI::Ext::Test::TAG_FRAMEWORK_VERSION => CI::Contrib::Minitest::Integration.version.to_s,
27
- CI::Ext::Test::TAG_TYPE => Ext::TEST_TYPE
33
+ CI::Ext::Test::TAG_TYPE => CI::Ext::Test::TEST_TYPE
28
34
  },
29
- service: configuration[:service_name]
35
+ service: datadog_configuration[:service_name]
30
36
  )
31
37
  end
32
38
 
@@ -34,24 +40,46 @@ module Datadog
34
40
  test_span = CI.active_test
35
41
  return super unless test_span
36
42
 
37
- case result_code
38
- when "."
39
- test_span.passed!
40
- when "E", "F"
41
- test_span.failed!(exception: failure)
42
- when "S"
43
- test_span.skipped!(reason: failure.message)
43
+ finish_test(test_span, result_code)
44
+ if Helpers.parallel?(self.class)
45
+ finish_test_suite(test_span.test_suite, result_code)
44
46
  end
45
47
 
46
- test_span.finish
47
-
48
48
  super
49
49
  end
50
50
 
51
51
  private
52
52
 
53
- def configuration
54
- ::Datadog.configuration.ci[:minitest]
53
+ def finish_test(test_span, result_code)
54
+ finish_with_result(test_span, result_code)
55
+
56
+ # mark test suite as failed if any test failed
57
+ if test_span.failed?
58
+ test_suite = test_span.test_suite
59
+ test_suite.failed! if test_suite
60
+ end
61
+ end
62
+
63
+ def finish_test_suite(test_suite, result_code)
64
+ return unless test_suite
65
+
66
+ finish_with_result(test_suite, result_code)
67
+ end
68
+
69
+ def finish_with_result(span, result_code)
70
+ case result_code
71
+ when "."
72
+ span.passed!
73
+ when "E", "F"
74
+ span.failed!(exception: failure)
75
+ when "S"
76
+ span.skipped!(reason: failure.message)
77
+ end
78
+ span.finish
79
+ end
80
+
81
+ def datadog_configuration
82
+ Datadog.configuration.ci[:minitest]
55
83
  end
56
84
  end
57
85
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "hooks"
4
+ require_relative "runnable"
4
5
 
5
6
  module Datadog
6
7
  module CI
@@ -17,7 +18,13 @@ module Datadog
17
18
  end
18
19
 
19
20
  def patch
21
+ require_relative "plugin"
22
+
20
23
  ::Minitest::Test.include(Hooks)
24
+ ::Minitest.include(Plugin)
25
+ ::Minitest::Runnable.include(Runnable)
26
+
27
+ ::Minitest.extensions << "datadog_ci"
21
28
  end
22
29
  end
23
30
  end
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "weakref"
4
+
5
+ require_relative "../../ext/test"
6
+ require_relative "ext"
7
+
8
+ module Datadog
9
+ module CI
10
+ module Contrib
11
+ module Minitest
12
+ module Plugin
13
+ def self.included(base)
14
+ base.extend(ClassMethods)
15
+ end
16
+
17
+ class DatadogReporter < ::Minitest::AbstractReporter
18
+ def initialize(minitest_reporter)
19
+ # This creates circular reference as minitest_reporter also holds reference to DatadogReporter.
20
+ # To make sure that minitest_reporter can be garbage collected, we use WeakRef.
21
+ @reporter = WeakRef.new(minitest_reporter)
22
+ end
23
+
24
+ def report
25
+ active_test_session = CI.active_test_session
26
+ active_test_module = CI.active_test_module
27
+
28
+ return unless @reporter.weakref_alive?
29
+ return if active_test_session.nil? || active_test_module.nil?
30
+
31
+ if @reporter.passed?
32
+ active_test_module.passed!
33
+ active_test_session.passed!
34
+ else
35
+ active_test_module.failed!
36
+ active_test_session.failed!
37
+ end
38
+
39
+ active_test_module.finish
40
+ active_test_session.finish
41
+
42
+ nil
43
+ end
44
+ end
45
+
46
+ module ClassMethods
47
+ def plugin_datadog_ci_init(*)
48
+ return unless datadog_configuration[:enabled]
49
+
50
+ test_session = CI.start_test_session(
51
+ tags: {
52
+ CI::Ext::Test::TAG_FRAMEWORK => Ext::FRAMEWORK,
53
+ CI::Ext::Test::TAG_FRAMEWORK_VERSION => CI::Contrib::Minitest::Integration.version.to_s,
54
+ CI::Ext::Test::TAG_TYPE => CI::Ext::Test::TEST_TYPE
55
+ },
56
+ service: datadog_configuration[:service_name]
57
+ )
58
+ CI.start_test_module(test_session.name)
59
+
60
+ reporter.reporters << DatadogReporter.new(reporter)
61
+ end
62
+
63
+ private
64
+
65
+ def datadog_configuration
66
+ Datadog.configuration.ci[:minitest]
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,42 @@
1
+ require_relative "helpers"
2
+
3
+ module Datadog
4
+ module CI
5
+ module Contrib
6
+ module Minitest
7
+ module Runnable
8
+ def self.included(base)
9
+ base.singleton_class.prepend(ClassMethods)
10
+ end
11
+
12
+ module ClassMethods
13
+ def run(*)
14
+ return super unless datadog_configuration[:enabled]
15
+ return super if Helpers.parallel?(self)
16
+
17
+ method = runnable_methods.first
18
+ return super if method.nil?
19
+
20
+ test_suite_name = Helpers.test_suite_name(self, method)
21
+
22
+ test_suite = Datadog::CI.start_test_suite(test_suite_name)
23
+ test_suite.passed! # will be overridden if any test fails
24
+
25
+ results = super
26
+
27
+ test_suite.finish
28
+
29
+ results
30
+ end
31
+
32
+ private
33
+
34
+ def datadog_configuration
35
+ Datadog.configuration.ci[:minitest]
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -19,7 +19,7 @@ module Datadog
19
19
 
20
20
  option :service_name do |o|
21
21
  o.type :string
22
- o.default { Datadog.configuration.service_without_fallback || Ext::SERVICE_NAME }
22
+ o.default { Datadog.configuration.service_without_fallback || Ext::DEFAULT_SERVICE_NAME }
23
23
  end
24
24
 
25
25
  # @deprecated Will be removed in 1.0
@@ -26,11 +26,11 @@ module Datadog
26
26
 
27
27
  CI.trace_test(
28
28
  test_name,
29
- metadata[:example_group][:file_path],
29
+ metadata[:example_group][:rerun_file_path],
30
30
  tags: {
31
31
  CI::Ext::Test::TAG_FRAMEWORK => Ext::FRAMEWORK,
32
32
  CI::Ext::Test::TAG_FRAMEWORK_VERSION => CI::Contrib::RSpec::Integration.version.to_s,
33
- CI::Ext::Test::TAG_TYPE => Ext::TEST_TYPE
33
+ CI::Ext::Test::TAG_TYPE => CI::Ext::Test::TEST_TYPE
34
34
  },
35
35
  service: configuration[:service_name]
36
36
  ) do |test_span|