datadog-ci 1.8.0 → 1.9.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +18 -2
- data/README.md +6 -8
- data/exe/ddcirb +3 -1
- data/lib/datadog/ci/auto_instrument.rb +8 -0
- data/lib/datadog/ci/cli/cli.rb +5 -1
- data/lib/datadog/ci/cli/command/base.rb +1 -0
- data/lib/datadog/ci/cli/command/exec.rb +29 -0
- data/lib/datadog/ci/cli/command/skippable_tests_percentage.rb +0 -1
- data/lib/datadog/ci/configuration/settings.rb +3 -21
- data/lib/datadog/ci/contrib/ciqueue/integration.rb +34 -0
- data/lib/datadog/ci/contrib/ciqueue/patcher.rb +23 -0
- data/lib/datadog/ci/contrib/cucumber/formatter.rb +10 -5
- data/lib/datadog/ci/contrib/cucumber/integration.rb +5 -14
- data/lib/datadog/ci/contrib/cucumber/patcher.rb +2 -6
- data/lib/datadog/ci/contrib/instrumentation.rb +173 -0
- data/lib/datadog/ci/contrib/integration.rb +101 -117
- data/lib/datadog/ci/contrib/knapsack/extension.rb +27 -0
- data/lib/datadog/ci/contrib/knapsack/integration.rb +36 -0
- data/lib/datadog/ci/contrib/knapsack/patcher.rb +29 -0
- data/lib/datadog/ci/contrib/knapsack/runner.rb +66 -0
- data/lib/datadog/ci/contrib/minitest/integration.rb +6 -14
- data/lib/datadog/ci/contrib/minitest/patcher.rb +1 -5
- data/lib/datadog/ci/contrib/minitest/runner.rb +6 -1
- data/lib/datadog/ci/contrib/minitest/test.rb +6 -1
- data/lib/datadog/ci/contrib/patcher.rb +62 -0
- data/lib/datadog/ci/contrib/rspec/example.rb +6 -1
- data/lib/datadog/ci/contrib/rspec/integration.rb +10 -13
- data/lib/datadog/ci/contrib/rspec/patcher.rb +2 -33
- data/lib/datadog/ci/contrib/rspec/runner.rb +6 -1
- data/lib/datadog/ci/contrib/selenium/capybara_driver.rb +1 -1
- data/lib/datadog/ci/contrib/selenium/driver.rb +1 -1
- data/lib/datadog/ci/contrib/selenium/integration.rb +6 -10
- data/lib/datadog/ci/contrib/selenium/navigation.rb +6 -2
- data/lib/datadog/ci/contrib/selenium/patcher.rb +2 -6
- data/lib/datadog/ci/contrib/selenium/rum.rb +0 -2
- data/lib/datadog/ci/contrib/simplecov/integration.rb +6 -10
- data/lib/datadog/ci/contrib/simplecov/patcher.rb +2 -6
- data/lib/datadog/ci/test_retries/strategy/retry_new.rb +1 -1
- data/lib/datadog/ci/test_visibility/component.rb +2 -2
- data/lib/datadog/ci/test_visibility/telemetry.rb +2 -1
- data/lib/datadog/ci/version.rb +1 -1
- data/lib/datadog/ci.rb +9 -1
- metadata +13 -7
- data/lib/datadog/ci/contrib/contrib.rb +0 -31
- data/lib/datadog/ci/contrib/rspec/knapsack_pro/extension.rb +0 -29
- data/lib/datadog/ci/contrib/rspec/knapsack_pro/patcher.rb +0 -26
- data/lib/datadog/ci/contrib/rspec/knapsack_pro/runner.rb +0 -62
@@ -1,147 +1,131 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative "settings"
|
4
|
+
require_relative "instrumentation"
|
4
5
|
|
5
6
|
module Datadog
|
6
7
|
module CI
|
7
8
|
module Contrib
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
def self.included(base)
|
12
|
-
base.extend(ClassMethods)
|
13
|
-
base.include(InstanceMethods)
|
9
|
+
class Integration
|
10
|
+
def self.inherited(subclass)
|
11
|
+
Instrumentation.register_integration(subclass)
|
14
12
|
end
|
15
13
|
|
16
|
-
|
17
|
-
|
14
|
+
# List of integrations names that depend on this integration.
|
15
|
+
# Specify when you might need to automatically instrument other integrations (like test runner for the
|
16
|
+
# test framework).
|
17
|
+
def dependants
|
18
|
+
[]
|
18
19
|
end
|
19
20
|
|
20
|
-
|
21
|
-
|
21
|
+
# Version of the integration target code in the environment.
|
22
|
+
#
|
23
|
+
# This is the gem version, when the instrumentation target is a Ruby gem.
|
24
|
+
#
|
25
|
+
# If the target for instrumentation has concept of versioning, override {.version},
|
26
|
+
# otherwise override {.available?} and implement a custom target presence check.
|
27
|
+
# @return [Object] the target version
|
28
|
+
def version
|
29
|
+
nil
|
22
30
|
end
|
23
31
|
|
24
|
-
#
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
def version
|
38
|
-
nil
|
39
|
-
end
|
32
|
+
# Is the target available to be instrumented? (e.g. gem installed?)
|
33
|
+
#
|
34
|
+
# The target doesn't have to be loaded (e.g. `require`) yet, but needs to be able
|
35
|
+
# to be loaded before instrumentation can commence.
|
36
|
+
#
|
37
|
+
# By default, {.available?} checks if {.version} returned a non-nil object.
|
38
|
+
#
|
39
|
+
# If the target for instrumentation has concept of versioning, override {.version},
|
40
|
+
# otherwise override {.available?} and implement a custom target presence check.
|
41
|
+
# @return [Boolean] is the target available for instrumentation in this Ruby environment?
|
42
|
+
def available?
|
43
|
+
!version.nil?
|
44
|
+
end
|
40
45
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
# @return [Boolean] is the target available for instrumentation in this Ruby environment?
|
51
|
-
def available?
|
52
|
-
!version.nil?
|
53
|
-
end
|
46
|
+
# Is the target loaded into the application? (e.g. gem required? Constant defined?)
|
47
|
+
#
|
48
|
+
# The target's objects should be ready to be referenced by the instrumented when {.loaded}
|
49
|
+
# returns `true`.
|
50
|
+
#
|
51
|
+
# @return [Boolean] is the target ready to be referenced during instrumentation?
|
52
|
+
def loaded?
|
53
|
+
true
|
54
|
+
end
|
54
55
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
# @return [Boolean] is the target ready to be referenced during instrumentation?
|
61
|
-
def loaded?
|
62
|
-
true
|
63
|
-
end
|
56
|
+
# Is this instrumentation compatible with the available target? (e.g. minimum version met?)
|
57
|
+
# @return [Boolean] is the available target compatible with this instrumentation?
|
58
|
+
def compatible?
|
59
|
+
available?
|
60
|
+
end
|
64
61
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
62
|
+
# Can the patch for this integration be applied?
|
63
|
+
#
|
64
|
+
# By default, this is equivalent to {#available?}, {#loaded?}, and {#compatible?}
|
65
|
+
# all being truthy.
|
66
|
+
def patchable?
|
67
|
+
available? && loaded? && compatible?
|
68
|
+
end
|
70
69
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
# all being truthy.
|
75
|
-
def patchable?
|
76
|
-
available? && loaded? && compatible?
|
77
|
-
end
|
70
|
+
# returns the configuration instance.
|
71
|
+
def configuration
|
72
|
+
@configuration ||= new_configuration
|
78
73
|
end
|
79
74
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
end
|
75
|
+
def configure(options = {}, &block)
|
76
|
+
configuration.configure(options, &block)
|
77
|
+
configuration
|
78
|
+
end
|
85
79
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
end
|
80
|
+
def enabled
|
81
|
+
configuration.enabled
|
82
|
+
end
|
90
83
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
84
|
+
# The patcher module to inject instrumented objects into the instrumentation target.
|
85
|
+
#
|
86
|
+
# {Contrib::Patcher} includes the basic functionality of a patcher. `include`ing
|
87
|
+
# {Contrib::Patcher} into a new module is the recommend way to create a custom patcher.
|
88
|
+
#
|
89
|
+
# @return [Contrib::Patcher] a module that `include`s {Contrib::Patcher}
|
90
|
+
def patcher
|
91
|
+
nil
|
92
|
+
end
|
95
93
|
|
96
|
-
|
97
|
-
|
94
|
+
# @!visibility private
|
95
|
+
def patch
|
96
|
+
if !patchable? || patcher.nil?
|
97
|
+
return {
|
98
|
+
ok: false,
|
99
|
+
available: available?,
|
100
|
+
loaded: loaded?,
|
101
|
+
compatible: compatible?,
|
102
|
+
patchable: patchable?
|
103
|
+
}
|
98
104
|
end
|
99
105
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
# {Contrib::Patcher} into a new module is the recommend way to create a custom patcher.
|
104
|
-
#
|
105
|
-
# @return [Contrib::Patcher] a module that `include`s {Contrib::Patcher}
|
106
|
-
def patcher
|
107
|
-
nil
|
108
|
-
end
|
106
|
+
patcher.patch
|
107
|
+
{ok: true}
|
108
|
+
end
|
109
109
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
patcher_klass = patcher
|
114
|
-
if !self.class.patchable? || patcher_klass.nil?
|
115
|
-
return {
|
116
|
-
available: self.class.available?,
|
117
|
-
loaded: self.class.loaded?,
|
118
|
-
compatible: self.class.compatible?,
|
119
|
-
patchable: self.class.patchable?
|
120
|
-
}
|
121
|
-
end
|
122
|
-
|
123
|
-
patcher_klass.patch
|
124
|
-
true
|
125
|
-
end
|
110
|
+
def patched?
|
111
|
+
patcher&.patched?
|
112
|
+
end
|
126
113
|
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
114
|
+
# Can the patch for this integration be applied automatically?
|
115
|
+
# @return [Boolean] can the tracer activate this instrumentation without explicit user input?
|
116
|
+
def late_instrument?
|
117
|
+
false
|
118
|
+
end
|
132
119
|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
def new_configuration
|
143
|
-
Datadog::CI::Contrib::Settings.new
|
144
|
-
end
|
120
|
+
# Returns a new configuration object for this integration.
|
121
|
+
#
|
122
|
+
# This method normally needs to be overridden for each integration
|
123
|
+
# as their settings, defaults and environment variables are
|
124
|
+
# specific for each integration.
|
125
|
+
#
|
126
|
+
# @return [Datadog::CI::Contrib::Settings] a new, integration-specific settings object
|
127
|
+
def new_configuration
|
128
|
+
Datadog::CI::Contrib::Settings.new
|
145
129
|
end
|
146
130
|
end
|
147
131
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "knapsack_pro/extensions/rspec_extension"
|
4
|
+
|
5
|
+
require_relative "runner"
|
6
|
+
|
7
|
+
module Datadog
|
8
|
+
module CI
|
9
|
+
module Contrib
|
10
|
+
module Knapsack
|
11
|
+
module Extension
|
12
|
+
def self.included(base)
|
13
|
+
base.singleton_class.prepend(ClassMethods)
|
14
|
+
end
|
15
|
+
|
16
|
+
module ClassMethods
|
17
|
+
def setup!
|
18
|
+
super
|
19
|
+
|
20
|
+
::RSpec::Core::Runner.include(Datadog::CI::Contrib::Knapsack::Runner)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../integration"
|
4
|
+
require_relative "patcher"
|
5
|
+
|
6
|
+
module Datadog
|
7
|
+
module CI
|
8
|
+
module Contrib
|
9
|
+
module Knapsack
|
10
|
+
# Knapsack Pro test runner instrumentation
|
11
|
+
# https://github.com/KnapsackPro/knapsack_pro-ruby
|
12
|
+
class Integration < Contrib::Integration
|
13
|
+
MINIMUM_VERSION = Gem::Version.new("7.0.0")
|
14
|
+
|
15
|
+
def version
|
16
|
+
Gem.loaded_specs["knapsack_pro"]&.version
|
17
|
+
end
|
18
|
+
|
19
|
+
def loaded?
|
20
|
+
!defined?(::KnapsackPro).nil? &&
|
21
|
+
!defined?(::KnapsackPro::Extensions::RSpecExtension).nil? &&
|
22
|
+
!defined?(::KnapsackPro::Extensions::RSpecExtension::Runner).nil?
|
23
|
+
end
|
24
|
+
|
25
|
+
def compatible?
|
26
|
+
super && version >= MINIMUM_VERSION
|
27
|
+
end
|
28
|
+
|
29
|
+
def patcher
|
30
|
+
Patcher
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../patcher"
|
4
|
+
|
5
|
+
module Datadog
|
6
|
+
module CI
|
7
|
+
module Contrib
|
8
|
+
module Knapsack
|
9
|
+
module Patcher
|
10
|
+
include Datadog::CI::Contrib::Patcher
|
11
|
+
|
12
|
+
module_function
|
13
|
+
|
14
|
+
def patch
|
15
|
+
if ::RSpec::Core::Runner.ancestors.include?(::KnapsackPro::Extensions::RSpecExtension::Runner)
|
16
|
+
# knapsack already patched rspec runner
|
17
|
+
require_relative "runner"
|
18
|
+
::RSpec::Core::Runner.include(Datadog::CI::Contrib::Knapsack::Runner)
|
19
|
+
else
|
20
|
+
# knapsack didn't patch rspec runner yet
|
21
|
+
require_relative "extension"
|
22
|
+
::KnapsackPro::Extensions::RSpecExtension.include(Datadog::CI::Contrib::Knapsack::Extension)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../../ext/test"
|
4
|
+
require_relative "../rspec/ext"
|
5
|
+
require_relative "../instrumentation"
|
6
|
+
|
7
|
+
module Datadog
|
8
|
+
module CI
|
9
|
+
module Contrib
|
10
|
+
module Knapsack
|
11
|
+
module Runner
|
12
|
+
def self.included(base)
|
13
|
+
base.prepend(InstanceMethods)
|
14
|
+
end
|
15
|
+
|
16
|
+
module InstanceMethods
|
17
|
+
# TODO: this is coupled to RSpec integration being present, not sure if it's bad or not at this point
|
18
|
+
def knapsack__run_specs(*args)
|
19
|
+
return super if ::RSpec.configuration.dry_run? && !datadog_configuration[:dry_run_enabled]
|
20
|
+
return super unless datadog_configuration[:enabled]
|
21
|
+
|
22
|
+
test_session = test_visibility_component.start_test_session(
|
23
|
+
tags: {
|
24
|
+
CI::Ext::Test::TAG_FRAMEWORK => CI::Contrib::RSpec::Ext::FRAMEWORK,
|
25
|
+
CI::Ext::Test::TAG_FRAMEWORK_VERSION => datadog_integration.version.to_s
|
26
|
+
},
|
27
|
+
service: datadog_configuration[:service_name]
|
28
|
+
)
|
29
|
+
|
30
|
+
test_module = test_visibility_component.start_test_module(CI::Contrib::RSpec::Ext::FRAMEWORK)
|
31
|
+
|
32
|
+
result = super
|
33
|
+
return result unless test_module && test_session
|
34
|
+
|
35
|
+
if result != 0
|
36
|
+
test_module.failed!
|
37
|
+
test_session.failed!
|
38
|
+
else
|
39
|
+
test_module.passed!
|
40
|
+
test_session.passed!
|
41
|
+
end
|
42
|
+
test_module.finish
|
43
|
+
test_session.finish
|
44
|
+
|
45
|
+
result
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def datadog_integration
|
51
|
+
CI::Contrib::Instrumentation.fetch_integration(:rspec)
|
52
|
+
end
|
53
|
+
|
54
|
+
def datadog_configuration
|
55
|
+
Datadog.configuration.ci[:rspec]
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_visibility_component
|
59
|
+
Datadog.send(:components).test_visibility
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -9,30 +9,22 @@ module Datadog
|
|
9
9
|
module Contrib
|
10
10
|
module Minitest
|
11
11
|
# Description of Minitest integration
|
12
|
-
class Integration
|
13
|
-
include Datadog::CI::Contrib::Integration
|
14
|
-
|
12
|
+
class Integration < Contrib::Integration
|
15
13
|
MINIMUM_VERSION = Gem::Version.new("5.0.0")
|
16
14
|
|
17
|
-
|
18
|
-
|
19
|
-
def self.version
|
15
|
+
def version
|
20
16
|
Gem.loaded_specs["minitest"]&.version
|
21
17
|
end
|
22
18
|
|
23
|
-
def
|
24
|
-
!defined?(::Minitest).nil?
|
19
|
+
def loaded?
|
20
|
+
!defined?(::Minitest).nil? && !defined?(::Minitest::Runnable).nil? && !defined?(::Minitest::Test).nil? &&
|
21
|
+
!defined?(::Minitest::CompositeReporter).nil?
|
25
22
|
end
|
26
23
|
|
27
|
-
def
|
24
|
+
def compatible?
|
28
25
|
super && version >= MINIMUM_VERSION
|
29
26
|
end
|
30
27
|
|
31
|
-
# test environments should not auto instrument test libraries
|
32
|
-
def auto_instrument?
|
33
|
-
false
|
34
|
-
end
|
35
|
-
|
36
28
|
def new_configuration
|
37
29
|
Configuration::Settings.new
|
38
30
|
end
|
@@ -11,14 +11,10 @@ module Datadog
|
|
11
11
|
module Minitest
|
12
12
|
# Patcher enables patching of 'minitest' module.
|
13
13
|
module Patcher
|
14
|
-
include Datadog::
|
14
|
+
include Datadog::CI::Contrib::Patcher
|
15
15
|
|
16
16
|
module_function
|
17
17
|
|
18
|
-
def target_version
|
19
|
-
Integration.version
|
20
|
-
end
|
21
|
-
|
22
18
|
def patch
|
23
19
|
# test session start
|
24
20
|
::Minitest.include(Runner)
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative "../../ext/test"
|
4
|
+
require_relative "../instrumentation"
|
4
5
|
require_relative "ext"
|
5
6
|
|
6
7
|
module Datadog
|
@@ -25,7 +26,7 @@ module Datadog
|
|
25
26
|
test_visibility_component.start_test_session(
|
26
27
|
tags: {
|
27
28
|
CI::Ext::Test::TAG_FRAMEWORK => Ext::FRAMEWORK,
|
28
|
-
CI::Ext::Test::TAG_FRAMEWORK_VERSION =>
|
29
|
+
CI::Ext::Test::TAG_FRAMEWORK_VERSION => datadog_integration.version.to_s
|
29
30
|
},
|
30
31
|
service: datadog_configuration[:service_name],
|
31
32
|
total_tests_count: (DD_ESTIMATED_TESTS_PER_SUITE * ::Minitest::Runnable.runnables.size).to_i
|
@@ -47,6 +48,10 @@ module Datadog
|
|
47
48
|
|
48
49
|
private
|
49
50
|
|
51
|
+
def datadog_integration
|
52
|
+
CI::Contrib::Instrumentation.fetch_integration(:minitest)
|
53
|
+
end
|
54
|
+
|
50
55
|
def datadog_configuration
|
51
56
|
Datadog.configuration.ci[:minitest]
|
52
57
|
end
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require_relative "../../ext/test"
|
4
4
|
require_relative "../../git/local_repository"
|
5
|
+
require_relative "../instrumentation"
|
5
6
|
require_relative "ext"
|
6
7
|
require_relative "helpers"
|
7
8
|
|
@@ -36,7 +37,7 @@ module Datadog
|
|
36
37
|
test_suite_name,
|
37
38
|
tags: {
|
38
39
|
CI::Ext::Test::TAG_FRAMEWORK => Ext::FRAMEWORK,
|
39
|
-
CI::Ext::Test::TAG_FRAMEWORK_VERSION =>
|
40
|
+
CI::Ext::Test::TAG_FRAMEWORK_VERSION => datadog_integration.version.to_s,
|
40
41
|
CI::Ext::Test::TAG_SOURCE_FILE => Git::LocalRepository.relative_to_root(source_file),
|
41
42
|
CI::Ext::Test::TAG_SOURCE_START => line_number.to_s
|
42
43
|
},
|
@@ -79,6 +80,10 @@ module Datadog
|
|
79
80
|
span.finish
|
80
81
|
end
|
81
82
|
|
83
|
+
def datadog_integration
|
84
|
+
CI::Contrib::Instrumentation.fetch_integration(:minitest)
|
85
|
+
end
|
86
|
+
|
82
87
|
def datadog_configuration
|
83
88
|
Datadog.configuration.ci[:minitest]
|
84
89
|
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "datadog/core/utils/only_once"
|
4
|
+
|
5
|
+
module Datadog
|
6
|
+
module CI
|
7
|
+
module Contrib
|
8
|
+
# Common behavior for patcher modules.
|
9
|
+
module Patcher
|
10
|
+
def self.included(base)
|
11
|
+
base.singleton_class.prepend(CommonMethods)
|
12
|
+
end
|
13
|
+
|
14
|
+
# Prepended instance methods for all patchers
|
15
|
+
module CommonMethods
|
16
|
+
attr_accessor \
|
17
|
+
:patch_error_result,
|
18
|
+
:patch_successful
|
19
|
+
|
20
|
+
def patch_name
|
21
|
+
(self.class != Class && self.class != Module) ? self.class.name : name
|
22
|
+
end
|
23
|
+
|
24
|
+
def patched?
|
25
|
+
patch_only_once.ran?
|
26
|
+
end
|
27
|
+
|
28
|
+
def patch
|
29
|
+
return unless defined?(super)
|
30
|
+
|
31
|
+
patch_only_once.run do
|
32
|
+
super.tap do
|
33
|
+
@patch_successful = true
|
34
|
+
end
|
35
|
+
rescue => e
|
36
|
+
on_patch_error(e)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# Processes patching errors. This default implementation logs the error and reports relevant metrics.
|
41
|
+
# @param e [Exception]
|
42
|
+
def on_patch_error(e)
|
43
|
+
Datadog.logger.error("Failed to apply #{patch_name} patch. Cause: #{e} Location: #{Array(e.backtrace).first}")
|
44
|
+
|
45
|
+
@patch_error_result = {
|
46
|
+
type: e.class.name,
|
47
|
+
message: e.message,
|
48
|
+
line: Array(e.backtrace).first
|
49
|
+
}
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def patch_only_once
|
55
|
+
# NOTE: This is not thread-safe
|
56
|
+
@patch_only_once ||= Datadog::Core::Utils::OnlyOnce.new
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -3,6 +3,7 @@
|
|
3
3
|
require_relative "../../ext/test"
|
4
4
|
require_relative "../../git/local_repository"
|
5
5
|
require_relative "../../utils/test_run"
|
6
|
+
require_relative "../instrumentation"
|
6
7
|
require_relative "ext"
|
7
8
|
|
8
9
|
module Datadog
|
@@ -46,7 +47,7 @@ module Datadog
|
|
46
47
|
suite_name,
|
47
48
|
tags: {
|
48
49
|
CI::Ext::Test::TAG_FRAMEWORK => Ext::FRAMEWORK,
|
49
|
-
CI::Ext::Test::TAG_FRAMEWORK_VERSION =>
|
50
|
+
CI::Ext::Test::TAG_FRAMEWORK_VERSION => datadog_integration.version.to_s,
|
50
51
|
CI::Ext::Test::TAG_SOURCE_FILE => Git::LocalRepository.relative_to_root(metadata[:file_path]),
|
51
52
|
CI::Ext::Test::TAG_SOURCE_START => metadata[:line_number].to_s,
|
52
53
|
CI::Ext::Test::TAG_PARAMETERS => Utils::TestRun.test_parameters(
|
@@ -120,6 +121,10 @@ module Datadog
|
|
120
121
|
res
|
121
122
|
end
|
122
123
|
|
124
|
+
def datadog_integration
|
125
|
+
CI::Contrib::Instrumentation.fetch_integration(:rspec)
|
126
|
+
end
|
127
|
+
|
123
128
|
def datadog_configuration
|
124
129
|
Datadog.configuration.ci[:rspec]
|
125
130
|
end
|
@@ -9,31 +9,28 @@ module Datadog
|
|
9
9
|
module Contrib
|
10
10
|
module RSpec
|
11
11
|
# Description of RSpec integration
|
12
|
-
class Integration
|
13
|
-
include Datadog::CI::Contrib::Integration
|
14
|
-
|
12
|
+
class Integration < Contrib::Integration
|
15
13
|
MINIMUM_VERSION = Gem::Version.new("3.0.0")
|
16
14
|
|
17
|
-
|
15
|
+
def dependants
|
16
|
+
%i[knapsack ciqueue]
|
17
|
+
end
|
18
18
|
|
19
|
-
def
|
19
|
+
def version
|
20
20
|
Gem.loaded_specs["rspec-core"]&.version
|
21
21
|
end
|
22
22
|
|
23
|
-
def
|
23
|
+
def loaded?
|
24
24
|
!defined?(::RSpec).nil? && !defined?(::RSpec::Core).nil? &&
|
25
|
-
!defined?(::RSpec::Core::Example).nil?
|
25
|
+
!defined?(::RSpec::Core::Example).nil? &&
|
26
|
+
!defined?(::RSpec::Core::Runner).nil? &&
|
27
|
+
!defined?(::RSpec::Core::ExampleGroup).nil?
|
26
28
|
end
|
27
29
|
|
28
|
-
def
|
30
|
+
def compatible?
|
29
31
|
super && version >= MINIMUM_VERSION
|
30
32
|
end
|
31
33
|
|
32
|
-
# test environments should not auto instrument test libraries
|
33
|
-
def auto_instrument?
|
34
|
-
false
|
35
|
-
end
|
36
|
-
|
37
34
|
def new_configuration
|
38
35
|
Configuration::Settings.new
|
39
36
|
end
|