datadog-ci 0.8.3 → 1.0.0.beta2

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 (70) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +42 -0
  3. data/LICENSE-3rdparty.csv +1 -1
  4. data/README.md +40 -55
  5. data/ext/datadog_cov/datadog_cov.c +192 -0
  6. data/ext/datadog_cov/extconf.rb +18 -0
  7. data/lib/datadog/ci/configuration/components.rb +43 -9
  8. data/lib/datadog/ci/configuration/settings.rb +7 -1
  9. data/lib/datadog/ci/contrib/cucumber/configuration/settings.rb +0 -15
  10. data/lib/datadog/ci/contrib/cucumber/ext.rb +1 -5
  11. data/lib/datadog/ci/contrib/cucumber/formatter.rb +13 -18
  12. data/lib/datadog/ci/contrib/cucumber/integration.rb +1 -2
  13. data/lib/datadog/ci/contrib/cucumber/patcher.rb +3 -0
  14. data/lib/datadog/ci/contrib/cucumber/step.rb +27 -0
  15. data/lib/datadog/ci/contrib/minitest/configuration/settings.rb +0 -15
  16. data/lib/datadog/ci/contrib/minitest/ext.rb +1 -5
  17. data/lib/datadog/ci/contrib/minitest/helpers.rb +1 -2
  18. data/lib/datadog/ci/contrib/minitest/hooks.rb +4 -2
  19. data/lib/datadog/ci/contrib/minitest/integration.rb +1 -1
  20. data/lib/datadog/ci/contrib/rspec/configuration/settings.rb +0 -15
  21. data/lib/datadog/ci/contrib/rspec/example.rb +25 -23
  22. data/lib/datadog/ci/contrib/rspec/ext.rb +0 -4
  23. data/lib/datadog/ci/contrib/rspec/integration.rb +1 -2
  24. data/lib/datadog/ci/contrib/settings.rb +0 -3
  25. data/lib/datadog/ci/ext/environment/providers/base.rb +1 -1
  26. data/lib/datadog/ci/ext/environment/providers/bitbucket.rb +1 -1
  27. data/lib/datadog/ci/ext/environment/providers/local_git.rb +8 -79
  28. data/lib/datadog/ci/ext/environment.rb +11 -16
  29. data/lib/datadog/ci/ext/settings.rb +1 -0
  30. data/lib/datadog/ci/ext/test.rb +5 -0
  31. data/lib/datadog/ci/ext/transport.rb +12 -0
  32. data/lib/datadog/ci/git/local_repository.rb +238 -0
  33. data/lib/datadog/ci/git/packfiles.rb +70 -0
  34. data/lib/datadog/ci/git/search_commits.rb +77 -0
  35. data/lib/datadog/ci/git/tree_uploader.rb +90 -0
  36. data/lib/datadog/ci/git/upload_packfile.rb +66 -0
  37. data/lib/datadog/ci/git/user.rb +29 -0
  38. data/lib/datadog/ci/itr/coverage/ddcov.rb +14 -0
  39. data/lib/datadog/ci/itr/coverage/event.rb +81 -0
  40. data/lib/datadog/ci/itr/coverage/transport.rb +42 -0
  41. data/lib/datadog/ci/itr/coverage/writer.rb +108 -0
  42. data/lib/datadog/ci/itr/runner.rb +143 -6
  43. data/lib/datadog/ci/itr/skippable.rb +106 -0
  44. data/lib/datadog/ci/span.rb +9 -0
  45. data/lib/datadog/ci/test.rb +20 -14
  46. data/lib/datadog/ci/test_module.rb +2 -2
  47. data/lib/datadog/ci/test_session.rb +2 -2
  48. data/lib/datadog/ci/test_suite.rb +2 -2
  49. data/lib/datadog/ci/test_visibility/context/global.rb +1 -3
  50. data/lib/datadog/ci/test_visibility/null_recorder.rb +5 -2
  51. data/lib/datadog/ci/test_visibility/recorder.rb +63 -8
  52. data/lib/datadog/ci/test_visibility/serializers/base.rb +1 -1
  53. data/lib/datadog/ci/test_visibility/serializers/factories/test_level.rb +1 -1
  54. data/lib/datadog/ci/test_visibility/serializers/factories/test_suite_level.rb +1 -1
  55. data/lib/datadog/ci/test_visibility/transport.rb +11 -54
  56. data/lib/datadog/ci/transport/api/agentless.rb +8 -1
  57. data/lib/datadog/ci/transport/api/base.rb +23 -0
  58. data/lib/datadog/ci/transport/api/builder.rb +9 -1
  59. data/lib/datadog/ci/transport/api/evp_proxy.rb +8 -0
  60. data/lib/datadog/ci/transport/event_platform_transport.rb +88 -0
  61. data/lib/datadog/ci/transport/http.rb +43 -6
  62. data/lib/datadog/ci/transport/remote_settings_api.rb +12 -6
  63. data/lib/datadog/ci/utils/configuration.rb +2 -2
  64. data/lib/datadog/ci/utils/git.rb +6 -67
  65. data/lib/datadog/ci/utils/parsing.rb +16 -0
  66. data/lib/datadog/ci/utils/test_run.rb +13 -0
  67. data/lib/datadog/ci/version.rb +5 -5
  68. data/lib/datadog/ci/worker.rb +35 -0
  69. data/lib/datadog/ci.rb +4 -0
  70. metadata +36 -4
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "event"
4
+ require_relative "../../transport/event_platform_transport"
5
+
6
+ module Datadog
7
+ module CI
8
+ module ITR
9
+ module Coverage
10
+ class Transport < Datadog::CI::Transport::EventPlatformTransport
11
+ private
12
+
13
+ def send_payload(encoded_payload)
14
+ api.citestcov_request(
15
+ path: Ext::Transport::TEST_COVERAGE_INTAKE_PATH,
16
+ payload: encoded_payload
17
+ )
18
+ end
19
+
20
+ def encode_events(events)
21
+ events.filter_map do |event|
22
+ next unless event.valid?
23
+
24
+ encoded = encoder.encode(event)
25
+ next if event_too_large?(event, encoded)
26
+
27
+ encoded
28
+ end
29
+ end
30
+
31
+ def write_payload_header(packer)
32
+ packer.write_map_header(2)
33
+ packer.write("version")
34
+ packer.write(2)
35
+
36
+ packer.write("coverages")
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,108 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "datadog/core/workers/async"
4
+ require "datadog/core/workers/queue"
5
+ require "datadog/core/workers/polling"
6
+
7
+ require "datadog/core/buffer/cruby"
8
+ require "datadog/core/buffer/thread_safe"
9
+
10
+ require "datadog/core/environment/ext"
11
+
12
+ module Datadog
13
+ module CI
14
+ module ITR
15
+ module Coverage
16
+ class Writer
17
+ include Core::Workers::Queue
18
+ include Core::Workers::Polling
19
+
20
+ attr_reader :transport
21
+
22
+ DEFAULT_BUFFER_MAX_SIZE = 10_000
23
+ DEFAULT_SHUTDOWN_TIMEOUT = 60
24
+
25
+ def initialize(transport:, options: {})
26
+ @transport = transport
27
+
28
+ # Workers::Polling settings
29
+ self.enabled = options.fetch(:enabled, true)
30
+
31
+ # Workers::Async::Thread settings
32
+ self.fork_policy = Core::Workers::Async::Thread::FORK_POLICY_RESTART
33
+
34
+ # Workers::IntervalLoop settings
35
+ self.loop_base_interval = options[:interval] if options.key?(:interval)
36
+ self.loop_back_off_ratio = options[:back_off_ratio] if options.key?(:back_off_ratio)
37
+ self.loop_back_off_max = options[:back_off_max] if options.key?(:back_off_max)
38
+
39
+ @buffer_size = options.fetch(:buffer_size, DEFAULT_BUFFER_MAX_SIZE)
40
+
41
+ self.buffer = buffer_klass.new(@buffer_size)
42
+
43
+ @shutdown_timeout = options.fetch(:shutdown_timeout, DEFAULT_SHUTDOWN_TIMEOUT)
44
+
45
+ @stopped = false
46
+ end
47
+
48
+ def write(event)
49
+ return if @stopped
50
+
51
+ # Start worker thread. If the process has forked, it will trigger #after_fork to
52
+ # reconfigure the worker accordingly.
53
+ perform
54
+
55
+ enqueue(event)
56
+ end
57
+
58
+ def perform(*events)
59
+ responses = transport.send_events(events)
60
+
61
+ loop_back_off! if responses.find(&:server_error?)
62
+
63
+ nil
64
+ end
65
+
66
+ def stop(force_stop = false, timeout = @shutdown_timeout)
67
+ @stopped = true
68
+
69
+ buffer.close if running?
70
+
71
+ super
72
+ end
73
+
74
+ def enqueue(event)
75
+ buffer.push(event)
76
+ end
77
+
78
+ def dequeue
79
+ buffer.pop
80
+ end
81
+
82
+ def work_pending?
83
+ !buffer.empty?
84
+ end
85
+
86
+ def async?
87
+ true
88
+ end
89
+
90
+ def after_fork
91
+ # In multiprocess environments, forks will share the same buffer until its written to.
92
+ # A.K.A. copy-on-write. We don't want forks to write events generated from another process.
93
+ # Instead, we reset it after the fork. (Make sure any enqueue operations happen after this.)
94
+ self.buffer = buffer_klass.new(@buffer_size)
95
+ end
96
+
97
+ def buffer_klass
98
+ if Core::Environment::Ext::RUBY_ENGINE == "ruby"
99
+ Core::Buffer::CRuby
100
+ else
101
+ Core::Buffer::ThreadSafe
102
+ end
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end
@@ -1,8 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "pp"
4
+
5
+ require "datadog/core/utils/forking"
6
+
3
7
  require_relative "../ext/test"
4
8
  require_relative "../ext/transport"
5
9
 
10
+ require_relative "../git/local_repository"
11
+
12
+ require_relative "../utils/parsing"
13
+
14
+ require_relative "coverage/event"
15
+ require_relative "skippable"
16
+
6
17
  module Datadog
7
18
  module CI
8
19
  module ITR
@@ -10,26 +21,44 @@ module Datadog
10
21
  # Integrates with backend to provide test impact analysis data and
11
22
  # skip tests that are not impacted by the changes
12
23
  class Runner
24
+ include Core::Utils::Forking
25
+
26
+ attr_reader :correlation_id, :skippable_tests, :skipped_tests_count
27
+
13
28
  def initialize(
29
+ dd_env:,
30
+ api: nil,
31
+ coverage_writer: nil,
14
32
  enabled: false
15
33
  )
16
34
  @enabled = enabled
35
+ @api = api
36
+ @dd_env = dd_env
37
+
17
38
  @test_skipping_enabled = false
18
39
  @code_coverage_enabled = false
19
40
 
41
+ @coverage_writer = coverage_writer
42
+
43
+ @correlation_id = nil
44
+ @skippable_tests = []
45
+
46
+ @skipped_tests_count = 0
47
+ @mutex = Mutex.new
48
+
20
49
  Datadog.logger.debug("ITR Runner initialized with enabled: #{@enabled}")
21
50
  end
22
51
 
23
- def configure(remote_configuration, test_session)
52
+ def configure(remote_configuration, test_session:, git_tree_upload_worker:)
24
53
  Datadog.logger.debug("Configuring ITR Runner with remote configuration: #{remote_configuration}")
25
54
 
26
- @enabled = convert_to_bool(
55
+ @enabled = Utils::Parsing.convert_to_bool(
27
56
  remote_configuration.fetch(Ext::Transport::DD_API_SETTINGS_RESPONSE_ITR_ENABLED_KEY, false)
28
57
  )
29
- @test_skipping_enabled = @enabled && convert_to_bool(
58
+ @test_skipping_enabled = @enabled && Utils::Parsing.convert_to_bool(
30
59
  remote_configuration.fetch(Ext::Transport::DD_API_SETTINGS_RESPONSE_TESTS_SKIPPING_KEY, false)
31
60
  )
32
- @code_coverage_enabled = @enabled && convert_to_bool(
61
+ @code_coverage_enabled = @enabled && Utils::Parsing.convert_to_bool(
33
62
  remote_configuration.fetch(Ext::Transport::DD_API_SETTINGS_RESPONSE_CODE_COVERAGE_KEY, false)
34
63
  )
35
64
 
@@ -41,7 +70,11 @@ module Datadog
41
70
  # we skip tests, not suites
42
71
  test_session.set_tag(Ext::Test::TAG_ITR_TEST_SKIPPING_TYPE, Ext::Test::ITR_TEST_SKIPPING_MODE)
43
72
 
73
+ load_datadog_cov! if @code_coverage_enabled
74
+
44
75
  Datadog.logger.debug("Configured ITR Runner with enabled: #{@enabled}, skipping_tests: #{@test_skipping_enabled}, code_coverage: #{@code_coverage_enabled}")
76
+
77
+ fetch_skippable_tests(test_session: test_session, git_tree_upload_worker: git_tree_upload_worker)
45
78
  end
46
79
 
47
80
  def enabled?
@@ -56,10 +89,114 @@ module Datadog
56
89
  @code_coverage_enabled
57
90
  end
58
91
 
92
+ def start_coverage(test)
93
+ return if !enabled? || !code_coverage?
94
+
95
+ coverage_collector&.start
96
+ end
97
+
98
+ def stop_coverage(test)
99
+ return if !enabled? || !code_coverage?
100
+
101
+ coverage = coverage_collector&.stop
102
+ return if coverage.nil? || coverage.empty?
103
+
104
+ return if test.skipped?
105
+
106
+ test_source_file = test.source_file
107
+
108
+ # cucumber's gherkin files are not covered by the code coverage collector
109
+ ensure_test_source_covered(test_source_file, coverage) unless test_source_file.nil?
110
+
111
+ event = Coverage::Event.new(
112
+ test_id: test.id.to_s,
113
+ test_suite_id: test.test_suite_id.to_s,
114
+ test_session_id: test.test_session_id.to_s,
115
+ coverage: coverage
116
+ )
117
+
118
+ Datadog.logger.debug { "Writing coverage event \n #{event.pretty_inspect}" }
119
+
120
+ write(event)
121
+
122
+ event
123
+ end
124
+
125
+ def mark_if_skippable(test)
126
+ return if !enabled? || !skipping_tests?
127
+
128
+ skippable_test_id = Utils::TestRun.skippable_test_id(test.name, test.test_suite_name, test.parameters)
129
+ if @skippable_tests.include?(skippable_test_id)
130
+ test.set_tag(Ext::Test::TAG_ITR_SKIPPED_BY_ITR, "true")
131
+
132
+ Datadog.logger.debug { "Marked test as skippable: #{skippable_test_id}" }
133
+ else
134
+ Datadog.logger.debug { "Test is not skippable: #{skippable_test_id}" }
135
+ end
136
+ end
137
+
138
+ def count_skipped_test(test)
139
+ if forked?
140
+ Datadog.logger.warn { "ITR is not supported for forking test runners yet" }
141
+ return
142
+ end
143
+
144
+ return if !test.skipped? || !test.skipped_by_itr?
145
+
146
+ @mutex.synchronize do
147
+ @skipped_tests_count += 1
148
+ end
149
+ end
150
+
151
+ def write_test_session_tags(test_session)
152
+ return if !enabled?
153
+
154
+ test_session.set_tag(Ext::Test::TAG_ITR_TESTS_SKIPPED, @skipped_tests_count.positive?.to_s)
155
+ test_session.set_tag(Ext::Test::TAG_ITR_TEST_SKIPPING_COUNT, @skipped_tests_count)
156
+ end
157
+
158
+ def shutdown!
159
+ @coverage_writer&.stop
160
+ end
161
+
59
162
  private
60
163
 
61
- def convert_to_bool(value)
62
- value.to_s == "true"
164
+ def write(event)
165
+ # skip sending events if writer is not configured
166
+ @coverage_writer&.write(event)
167
+ end
168
+
169
+ def coverage_collector
170
+ Thread.current[:dd_coverage_collector] ||= Coverage::DDCov.new(root: Git::LocalRepository.root)
171
+ end
172
+
173
+ def load_datadog_cov!
174
+ require "datadog_cov.#{RUBY_VERSION}_#{RUBY_PLATFORM}"
175
+ rescue LoadError => e
176
+ Datadog.logger.error("Failed to load coverage collector: #{e}. Code coverage will not be collected.")
177
+
178
+ @code_coverage_enabled = false
179
+ end
180
+
181
+ def ensure_test_source_covered(test_source_file, coverage)
182
+ absolute_test_source_file_path = File.join(Git::LocalRepository.root, test_source_file)
183
+ return if coverage.key?(absolute_test_source_file_path)
184
+
185
+ coverage[absolute_test_source_file_path] = true
186
+ end
187
+
188
+ def fetch_skippable_tests(test_session:, git_tree_upload_worker:)
189
+ return unless skipping_tests?
190
+
191
+ # we can only request skippable tests if git metadata is already uploaded
192
+ git_tree_upload_worker.wait_until_done
193
+
194
+ skippable_response = Skippable.new(api: @api, dd_env: @dd_env).fetch_skippable_tests(test_session)
195
+ @correlation_id = skippable_response.correlation_id
196
+ @skippable_tests = skippable_response.tests
197
+
198
+ Datadog.logger.debug { "Fetched skippable tests: \n #{@skippable_tests}" }
199
+ Datadog.logger.debug { "ITR correlation ID: #{@correlation_id}" }
63
200
  end
64
201
  end
65
202
  end
@@ -0,0 +1,106 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+
5
+ require_relative "../ext/transport"
6
+ require_relative "../ext/test"
7
+ require_relative "../utils/test_run"
8
+
9
+ module Datadog
10
+ module CI
11
+ module ITR
12
+ class Skippable
13
+ class Response
14
+ def initialize(http_response)
15
+ @http_response = http_response
16
+ @json = nil
17
+ end
18
+
19
+ def ok?
20
+ resp = @http_response
21
+ !resp.nil? && resp.ok?
22
+ end
23
+
24
+ def correlation_id
25
+ payload.dig("meta", "correlation_id")
26
+ end
27
+
28
+ def tests
29
+ res = Set.new
30
+
31
+ payload.fetch("data", [])
32
+ .each do |test_data|
33
+ next unless test_data["type"] == Ext::Test::ITR_TEST_SKIPPING_MODE
34
+
35
+ attrs = test_data["attributes"] || {}
36
+ res << Utils::TestRun.skippable_test_id(attrs["name"], attrs["suite"], attrs["parameters"])
37
+ end
38
+
39
+ res
40
+ end
41
+
42
+ private
43
+
44
+ def payload
45
+ cached = @json
46
+ return cached unless cached.nil?
47
+
48
+ resp = @http_response
49
+ return @json = {} if resp.nil? || !ok?
50
+
51
+ begin
52
+ @json = JSON.parse(resp.payload)
53
+ rescue JSON::ParserError => e
54
+ Datadog.logger.error("Failed to parse skippable tests response payload: #{e}. Payload was: #{resp.payload}")
55
+ @json = {}
56
+ end
57
+ end
58
+ end
59
+
60
+ def initialize(dd_env:, api: nil)
61
+ @api = api
62
+ @dd_env = dd_env
63
+ end
64
+
65
+ def fetch_skippable_tests(test_session)
66
+ api = @api
67
+ return Response.new(nil) unless api
68
+
69
+ request_payload = payload(test_session)
70
+ Datadog.logger.debug("Fetching skippable tests with request: #{request_payload}")
71
+
72
+ http_response = api.api_request(
73
+ path: Ext::Transport::DD_API_SKIPPABLE_TESTS_PATH,
74
+ payload: request_payload
75
+ )
76
+
77
+ Response.new(http_response)
78
+ end
79
+
80
+ private
81
+
82
+ def payload(test_session)
83
+ {
84
+ "data" => {
85
+ "type" => Ext::Transport::DD_API_SKIPPABLE_TESTS_TYPE,
86
+ "attributes" => {
87
+ "test_level" => Ext::Test::ITR_TEST_SKIPPING_MODE,
88
+ "service" => test_session.service,
89
+ "env" => @dd_env,
90
+ "repository_url" => test_session.git_repository_url,
91
+ "sha" => test_session.git_commit_sha,
92
+ "configurations" => {
93
+ Ext::Test::TAG_OS_PLATFORM => test_session.os_platform,
94
+ Ext::Test::TAG_OS_ARCHITECTURE => test_session.os_architecture,
95
+ Ext::Test::TAG_OS_VERSION => test_session.os_version,
96
+ Ext::Test::TAG_RUNTIME_NAME => test_session.runtime_name,
97
+ Ext::Test::TAG_RUNTIME_VERSION => test_session.runtime_version
98
+ }
99
+ }
100
+ }
101
+ }.to_json
102
+ end
103
+ end
104
+ end
105
+ end
106
+ end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "datadog/core/environment/platform"
4
+
3
5
  require_relative "ext/test"
4
6
  require_relative "utils/test_run"
5
7
 
@@ -151,6 +153,12 @@ module Datadog
151
153
  tracer_span.get_tag(Ext::Test::TAG_OS_PLATFORM)
152
154
  end
153
155
 
156
+ # Returns the OS version extracted from the environment.
157
+ # @return [String] OS version.
158
+ def os_version
159
+ tracer_span.get_tag(Ext::Test::TAG_OS_VERSION)
160
+ end
161
+
154
162
  # Returns the runtime name extracted from the environment.
155
163
  # @return [String] runtime name.
156
164
  def runtime_name
@@ -166,6 +174,7 @@ module Datadog
166
174
  def set_environment_runtime_tags
167
175
  tracer_span.set_tag(Ext::Test::TAG_OS_ARCHITECTURE, ::RbConfig::CONFIG["host_cpu"])
168
176
  tracer_span.set_tag(Ext::Test::TAG_OS_PLATFORM, ::RbConfig::CONFIG["host_os"])
177
+ tracer_span.set_tag(Ext::Test::TAG_OS_VERSION, Core::Environment::Platform.kernel_release)
169
178
  tracer_span.set_tag(Ext::Test::TAG_RUNTIME_NAME, Core::Environment::Ext::LANG_ENGINE)
170
179
  tracer_span.set_tag(Ext::Test::TAG_RUNTIME_VERSION, Core::Environment::Ext::ENGINE_VERSION)
171
180
  tracer_span.set_tag(Ext::Test::TAG_COMMAND, Utils::TestRun.command)
@@ -3,6 +3,7 @@
3
3
  require "json"
4
4
 
5
5
  require_relative "span"
6
+ require_relative "utils/test_run"
6
7
 
7
8
  module Datadog
8
9
  module CI
@@ -18,9 +19,9 @@ module Datadog
18
19
  # Finishes the current test.
19
20
  # @return [void]
20
21
  def finish
21
- super
22
-
23
22
  recorder.deactivate_test
23
+
24
+ super
24
25
  end
25
26
 
26
27
  # Running test suite that this test is part of (if any).
@@ -62,6 +63,12 @@ module Datadog
62
63
  get_tag(Ext::Test::TAG_SOURCE_FILE)
63
64
  end
64
65
 
66
+ # Returns "true" if the test is skipped by the intelligent test runner.
67
+ # @return [Boolean] true if the test is skipped by the intelligent test runner, false otherwise.
68
+ def skipped_by_itr?
69
+ get_tag(Ext::Test::TAG_ITR_SKIPPED_BY_ITR) == "true"
70
+ end
71
+
65
72
  # Sets the status of the span to "pass".
66
73
  # @return [void]
67
74
  def passed!
@@ -89,7 +96,7 @@ module Datadog
89
96
  record_test_result(Ext::Test::Status::SKIP)
90
97
  end
91
98
 
92
- # Sets the parameters for this test (e.g. Cucumber example or RSpec shared specs).
99
+ # Sets the parameters for this test (e.g. Cucumber example or RSpec specs).
93
100
  # Parameters are needed to compute test fingerprint to distinguish between different tests having same names.
94
101
  #
95
102
  # @param [Hash] arguments the arguments that test accepts as key-value hash
@@ -98,22 +105,21 @@ module Datadog
98
105
  def set_parameters(arguments, metadata = {})
99
106
  return if arguments.nil?
100
107
 
101
- set_tag(
102
- Ext::Test::TAG_PARAMETERS,
103
- JSON.generate(
104
- {
105
- arguments: arguments,
106
- metadata: metadata
107
- }
108
- )
109
- )
108
+ set_tag(Ext::Test::TAG_PARAMETERS, Utils::TestRun.test_parameters(arguments: arguments, metadata: metadata))
109
+ end
110
+
111
+ # Gets the parameters for this test (e.g. Cucumber example or RSpec specs) as a serialized JSON.
112
+ #
113
+ # @return [String] the serialized JSON of the parameters
114
+ # @return [nil] if this test does not have parameters
115
+ def parameters
116
+ get_tag(Ext::Test::TAG_PARAMETERS)
110
117
  end
111
118
 
112
119
  private
113
120
 
114
121
  def record_test_result(datadog_status)
115
- suite = test_suite
116
- suite.record_test_result(datadog_status) if suite
122
+ test_suite&.record_test_result(datadog_status)
117
123
  end
118
124
  end
119
125
  end
@@ -14,9 +14,9 @@ module Datadog
14
14
  # Finishes this test module.
15
15
  # @return [void]
16
16
  def finish
17
- super
18
-
19
17
  recorder.deactivate_test_module
18
+
19
+ super
20
20
  end
21
21
  end
22
22
  end
@@ -15,9 +15,9 @@ module Datadog
15
15
  # Finishes the current test session.
16
16
  # @return [void]
17
17
  def finish
18
- super
19
-
20
18
  recorder.deactivate_test_session
19
+
20
+ super
21
21
  end
22
22
 
23
23
  # Return the test session's name which is equal to test command used
@@ -26,9 +26,9 @@ module Datadog
26
26
  # we try to derive test suite status from execution stats if no status was set explicitly
27
27
  set_status_from_stats! if undefined?
28
28
 
29
- super
30
-
31
29
  recorder.deactivate_test_suite(name)
30
+
31
+ super
32
32
  end
33
33
  end
34
34
 
@@ -55,9 +55,7 @@ module Datadog
55
55
 
56
56
  def service
57
57
  @mutex.synchronize do
58
- # thank you RBS for this weirdness
59
- test_session = @test_session
60
- test_session.service if test_session
58
+ @test_session&.service
61
59
  end
62
60
  end
63
61
 
@@ -23,7 +23,7 @@ module Datadog
23
23
  skip_tracing(block)
24
24
  end
25
25
 
26
- def trace(type, span_name, tags: {}, &block)
26
+ def trace(span_name, type: "span", tags: {}, &block)
27
27
  skip_tracing(block)
28
28
  end
29
29
 
@@ -42,10 +42,13 @@ module Datadog
42
42
  def active_test_suite(test_suite_name)
43
43
  end
44
44
 
45
+ def shutdown!
46
+ end
47
+
45
48
  private
46
49
 
47
50
  def skip_tracing(block = nil)
48
- block.call(nil) if block
51
+ block&.call(nil)
49
52
  end
50
53
  end
51
54
  end