datadog-ci 0.8.3 → 1.0.0.beta2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +42 -0
- data/LICENSE-3rdparty.csv +1 -1
- data/README.md +40 -55
- data/ext/datadog_cov/datadog_cov.c +192 -0
- data/ext/datadog_cov/extconf.rb +18 -0
- data/lib/datadog/ci/configuration/components.rb +43 -9
- data/lib/datadog/ci/configuration/settings.rb +7 -1
- data/lib/datadog/ci/contrib/cucumber/configuration/settings.rb +0 -15
- data/lib/datadog/ci/contrib/cucumber/ext.rb +1 -5
- data/lib/datadog/ci/contrib/cucumber/formatter.rb +13 -18
- data/lib/datadog/ci/contrib/cucumber/integration.rb +1 -2
- data/lib/datadog/ci/contrib/cucumber/patcher.rb +3 -0
- data/lib/datadog/ci/contrib/cucumber/step.rb +27 -0
- data/lib/datadog/ci/contrib/minitest/configuration/settings.rb +0 -15
- data/lib/datadog/ci/contrib/minitest/ext.rb +1 -5
- data/lib/datadog/ci/contrib/minitest/helpers.rb +1 -2
- data/lib/datadog/ci/contrib/minitest/hooks.rb +4 -2
- data/lib/datadog/ci/contrib/minitest/integration.rb +1 -1
- data/lib/datadog/ci/contrib/rspec/configuration/settings.rb +0 -15
- data/lib/datadog/ci/contrib/rspec/example.rb +25 -23
- data/lib/datadog/ci/contrib/rspec/ext.rb +0 -4
- data/lib/datadog/ci/contrib/rspec/integration.rb +1 -2
- data/lib/datadog/ci/contrib/settings.rb +0 -3
- data/lib/datadog/ci/ext/environment/providers/base.rb +1 -1
- data/lib/datadog/ci/ext/environment/providers/bitbucket.rb +1 -1
- data/lib/datadog/ci/ext/environment/providers/local_git.rb +8 -79
- data/lib/datadog/ci/ext/environment.rb +11 -16
- data/lib/datadog/ci/ext/settings.rb +1 -0
- data/lib/datadog/ci/ext/test.rb +5 -0
- data/lib/datadog/ci/ext/transport.rb +12 -0
- data/lib/datadog/ci/git/local_repository.rb +238 -0
- data/lib/datadog/ci/git/packfiles.rb +70 -0
- data/lib/datadog/ci/git/search_commits.rb +77 -0
- data/lib/datadog/ci/git/tree_uploader.rb +90 -0
- data/lib/datadog/ci/git/upload_packfile.rb +66 -0
- data/lib/datadog/ci/git/user.rb +29 -0
- data/lib/datadog/ci/itr/coverage/ddcov.rb +14 -0
- data/lib/datadog/ci/itr/coverage/event.rb +81 -0
- data/lib/datadog/ci/itr/coverage/transport.rb +42 -0
- data/lib/datadog/ci/itr/coverage/writer.rb +108 -0
- data/lib/datadog/ci/itr/runner.rb +143 -6
- data/lib/datadog/ci/itr/skippable.rb +106 -0
- data/lib/datadog/ci/span.rb +9 -0
- data/lib/datadog/ci/test.rb +20 -14
- data/lib/datadog/ci/test_module.rb +2 -2
- data/lib/datadog/ci/test_session.rb +2 -2
- data/lib/datadog/ci/test_suite.rb +2 -2
- data/lib/datadog/ci/test_visibility/context/global.rb +1 -3
- data/lib/datadog/ci/test_visibility/null_recorder.rb +5 -2
- data/lib/datadog/ci/test_visibility/recorder.rb +63 -8
- data/lib/datadog/ci/test_visibility/serializers/base.rb +1 -1
- data/lib/datadog/ci/test_visibility/serializers/factories/test_level.rb +1 -1
- data/lib/datadog/ci/test_visibility/serializers/factories/test_suite_level.rb +1 -1
- data/lib/datadog/ci/test_visibility/transport.rb +11 -54
- data/lib/datadog/ci/transport/api/agentless.rb +8 -1
- data/lib/datadog/ci/transport/api/base.rb +23 -0
- data/lib/datadog/ci/transport/api/builder.rb +9 -1
- data/lib/datadog/ci/transport/api/evp_proxy.rb +8 -0
- data/lib/datadog/ci/transport/event_platform_transport.rb +88 -0
- data/lib/datadog/ci/transport/http.rb +43 -6
- data/lib/datadog/ci/transport/remote_settings_api.rb +12 -6
- data/lib/datadog/ci/utils/configuration.rb +2 -2
- data/lib/datadog/ci/utils/git.rb +6 -67
- data/lib/datadog/ci/utils/parsing.rb +16 -0
- data/lib/datadog/ci/utils/test_run.rb +13 -0
- data/lib/datadog/ci/version.rb +5 -5
- data/lib/datadog/ci/worker.rb +35 -0
- data/lib/datadog/ci.rb +4 -0
- metadata +36 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6b3e03ab226d98aac3dd518b1c554452a4c3812cb67e9a1d64762e2fe8767633
|
4
|
+
data.tar.gz: eac352d2b2488d16f979004f617097efe109364069f1c7b78cecfceef5365efa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c56ab91025f2a224e86bd732a5c891e961af184b29618241f8853756780ccba894c11955b00020a70139d72e47f57d22dfdf1f2ed6437f1d4e4a9d998453d7a4
|
7
|
+
data.tar.gz: e7c1aa73096d8d8b49800bbed168f288b7676d8fa328011c3e9c4f7024c86c17cf2c210a94a64dcd80f94121a80b36a824f0ca4e3aa6ccb1c35f682a1fb9e18b
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,32 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## [1.0.0.beta2] - 2024-04-23
|
4
|
+
|
5
|
+
### Added
|
6
|
+
|
7
|
+
* Code coverage events writer ([#150])
|
8
|
+
* Git tree upload - git command line integration ([#151])
|
9
|
+
* Add Git::SearchCommits api client ([#152])
|
10
|
+
* Upload packfiles API client ([#153])
|
11
|
+
* Git tree uploader ([#154])
|
12
|
+
* Git repository unshallowing logic ([#155])
|
13
|
+
* Git upload async worker ([#156])
|
14
|
+
* Reduce ITR-induced code coverage overhead for default branch ([#157])
|
15
|
+
* Skippable tests api client ([#158])
|
16
|
+
* Request skippable tests when configuring ITR ([#159])
|
17
|
+
* Test skipping implementation ([#160])
|
18
|
+
|
19
|
+
## [1.0.0.beta1] - 2024-03-25
|
20
|
+
|
21
|
+
### Added
|
22
|
+
|
23
|
+
* datadog-cov native extension for per test code coverage ([#137])
|
24
|
+
* citestcov transport to serialize and send code coverage events ([#148])
|
25
|
+
|
26
|
+
### Removed
|
27
|
+
|
28
|
+
* Ruby 2.1-2.6 support is dropped
|
29
|
+
|
3
30
|
## [0.8.3] - 2024-03-20
|
4
31
|
|
5
32
|
### Fixed
|
@@ -188,6 +215,8 @@ Currently test suite level visibility is not used by our instrumentation: it wil
|
|
188
215
|
* Ruby versions < 2.7 no longer supported ([#8][])
|
189
216
|
|
190
217
|
[Unreleased]: https://github.com/DataDog/datadog-ci-rb/compare/v0.8.3...main
|
218
|
+
[1.0.0.beta2]: https://github.com/DataDog/datadog-ci-rb/compare/v1.0.0.beta1...v1.0.0.beta2
|
219
|
+
[1.0.0.beta1]: https://github.com/DataDog/datadog-ci-rb/compare/v0.8.3...v1.0.0.beta1
|
191
220
|
[0.8.3]: https://github.com/DataDog/datadog-ci-rb/compare/v0.8.2...v0.8.3
|
192
221
|
[0.8.2]: https://github.com/DataDog/datadog-ci-rb/compare/v0.8.1...v0.8.2
|
193
222
|
[0.8.1]: https://github.com/DataDog/datadog-ci-rb/compare/v0.8.0...v0.8.1
|
@@ -258,7 +287,20 @@ Currently test suite level visibility is not used by our instrumentation: it wil
|
|
258
287
|
[#123]: https://github.com/DataDog/datadog-ci-rb/issues/123
|
259
288
|
[#131]: https://github.com/DataDog/datadog-ci-rb/issues/131
|
260
289
|
[#134]: https://github.com/DataDog/datadog-ci-rb/issues/134
|
290
|
+
[#137]: https://github.com/DataDog/datadog-ci-rb/issues/137
|
261
291
|
[#139]: https://github.com/DataDog/datadog-ci-rb/issues/139
|
262
292
|
[#141]: https://github.com/DataDog/datadog-ci-rb/issues/141
|
263
293
|
[#142]: https://github.com/DataDog/datadog-ci-rb/issues/142
|
264
294
|
[#145]: https://github.com/DataDog/datadog-ci-rb/issues/145
|
295
|
+
[#148]: https://github.com/DataDog/datadog-ci-rb/issues/148
|
296
|
+
[#150]: https://github.com/DataDog/datadog-ci-rb/issues/150
|
297
|
+
[#151]: https://github.com/DataDog/datadog-ci-rb/issues/151
|
298
|
+
[#152]: https://github.com/DataDog/datadog-ci-rb/issues/152
|
299
|
+
[#153]: https://github.com/DataDog/datadog-ci-rb/issues/153
|
300
|
+
[#154]: https://github.com/DataDog/datadog-ci-rb/issues/154
|
301
|
+
[#155]: https://github.com/DataDog/datadog-ci-rb/issues/155
|
302
|
+
[#156]: https://github.com/DataDog/datadog-ci-rb/issues/156
|
303
|
+
[#157]: https://github.com/DataDog/datadog-ci-rb/issues/157
|
304
|
+
[#158]: https://github.com/DataDog/datadog-ci-rb/issues/158
|
305
|
+
[#159]: https://github.com/DataDog/datadog-ci-rb/issues/159
|
306
|
+
[#160]: https://github.com/DataDog/datadog-ci-rb/issues/160
|
data/LICENSE-3rdparty.csv
CHANGED
@@ -1,3 +1,3 @@
|
|
1
1
|
Component,Origin,License,Copyright
|
2
|
-
|
2
|
+
datadog,https://github.com/DataDog/dd-trace-rb,Apache 2.0,"Copyright 2016-Present Datadog, Inc."
|
3
3
|
msgpack,https://rubygems.org/gems/msgpack,Apache-2.0,"Copyright (c) 2008-2015 Sadayuki Furuhashi"
|
data/README.md
CHANGED
@@ -8,19 +8,20 @@
|
|
8
8
|
Datadog's Ruby Library for instrumenting your test and continuous integration pipeline.
|
9
9
|
Learn more on our [official website](https://docs.datadoghq.com/tests/) and check out our [documentation for this library](https://docs.datadoghq.com/tests/setup/ruby/?tab=cloudciprovideragentless).
|
10
10
|
|
11
|
-
> [!IMPORTANT]
|
12
|
-
> The `datadog-ci` gem is currently a component of [`ddtrace`](https://github.com/datadog/dd-trace-rb) and should not be used without it.
|
13
|
-
>
|
14
|
-
> We expect this to change in the future.
|
15
|
-
|
16
11
|
## Installation
|
17
12
|
|
18
13
|
Add to your Gemfile.
|
19
14
|
|
20
15
|
```ruby
|
21
|
-
|
16
|
+
group :test do
|
17
|
+
gem "datadog-ci"
|
18
|
+
end
|
22
19
|
```
|
23
20
|
|
21
|
+
## Upgrade from ddtrace v1.x
|
22
|
+
|
23
|
+
If you used [test visibility for Ruby](https://docs.datadoghq.com/tests/setup/ruby/) with [ddtrace](https://github.com/datadog/dd-trace-rb) gem, check out our [upgrade guide](/docs/UpgradeGuide.md).
|
24
|
+
|
24
25
|
## Usage
|
25
26
|
|
26
27
|
### RSpec
|
@@ -34,26 +35,14 @@ require 'datadog/ci'
|
|
34
35
|
# Only activates test instrumentation on CI
|
35
36
|
if ENV["DD_ENV"] == "ci"
|
36
37
|
Datadog.configure do |c|
|
37
|
-
# Configures the tracer to ensure results delivery
|
38
|
-
c.ci.enabled = true
|
39
|
-
|
40
38
|
# The name of the service or library under test
|
41
39
|
c.service = 'my-ruby-app'
|
42
|
-
|
43
|
-
|
44
|
-
c.ci.instrument :rspec, **options
|
40
|
+
c.ci.enabled = true
|
41
|
+
c.ci.instrument :rspec
|
45
42
|
end
|
46
43
|
end
|
47
44
|
```
|
48
45
|
|
49
|
-
`options` are the following keyword arguments:
|
50
|
-
|
51
|
-
| Key | Description | Default |
|
52
|
-
| --- | ----------- | ------- |
|
53
|
-
| `enabled` | Defines whether RSpec tests should be traced. Useful for temporarily disabling tracing. `true` or `false` | `true` |
|
54
|
-
| `service_name` | Service name used for `rspec` instrumentation. | `'rspec'` |
|
55
|
-
| `operation_name` | *DEPRECATED, to be removed in 1.0* Operation name used for `rspec` instrumentation (has no effect in agentless mode or when using newer agent versions). | `'rspec.example'` |
|
56
|
-
|
57
46
|
### Minitest
|
58
47
|
|
59
48
|
The Minitest integration will trace all executions of tests when using `minitest` test framework.
|
@@ -68,13 +57,10 @@ require 'datadog/ci'
|
|
68
57
|
if ENV["DD_ENV"] == "ci"
|
69
58
|
# Configure default Minitest integration
|
70
59
|
Datadog.configure do |c|
|
71
|
-
# Configures the tracer to ensure results delivery
|
72
|
-
c.ci.enabled = true
|
73
|
-
|
74
60
|
# The name of the service or library under test
|
75
61
|
c.service = 'my-ruby-app'
|
76
|
-
|
77
|
-
c.ci.instrument :minitest
|
62
|
+
c.ci.enabled = true
|
63
|
+
c.ci.instrument :minitest
|
78
64
|
end
|
79
65
|
end
|
80
66
|
```
|
@@ -91,21 +77,13 @@ require 'minitest/autorun'
|
|
91
77
|
|
92
78
|
if ENV["DD_ENV"] == "ci"
|
93
79
|
Datadog.configure do |c|
|
94
|
-
c.ci.enabled = true
|
95
80
|
c.service = 'my-ruby-app'
|
81
|
+
c.ci.enabled = true
|
96
82
|
c.ci.instrument :minitest
|
97
83
|
end
|
98
84
|
end
|
99
85
|
```
|
100
86
|
|
101
|
-
`options` are the following keyword arguments:
|
102
|
-
|
103
|
-
| Key | Description | Default |
|
104
|
-
| --- | ----------- | ------- |
|
105
|
-
| `enabled` | Defines whether Minitest tests should be traced. Useful for temporarily disabling tracing. `true` or `false` | `true` |
|
106
|
-
| `service_name` | Service name used for `minitest` instrumentation. | `'minitest'` |
|
107
|
-
| `operation_name` | *DEPRECATED, to be removed in 1.0* Operation name used for `minitest` instrumentation (has no effect in agentless mode or when using newer agent versions). | `'minitest.test'` |
|
108
|
-
|
109
87
|
### Cucumber
|
110
88
|
|
111
89
|
Activate `Cucumber` integration with configuration
|
@@ -117,25 +95,31 @@ require 'datadog/ci'
|
|
117
95
|
# Only activates test instrumentation on CI
|
118
96
|
if ENV["DD_ENV"] == "ci"
|
119
97
|
Datadog.configure do |c|
|
120
|
-
# Configures the tracer to ensure results delivery
|
121
|
-
c.ci.enabled = true
|
122
|
-
|
123
98
|
# The name of the service or library under test
|
124
99
|
c.service = 'my-ruby-app'
|
125
|
-
|
126
|
-
|
127
|
-
c.ci.instrument :cucumber, **options
|
100
|
+
c.ci.enabled = true
|
101
|
+
c.ci.instrument :cucumber
|
128
102
|
end
|
129
103
|
end
|
130
104
|
```
|
131
105
|
|
132
|
-
|
106
|
+
### Instrumentation options
|
107
|
+
|
108
|
+
Configuration `ci.instrument` accepts the following optional parameters:
|
109
|
+
|
110
|
+
- `enabled` (default: `true`) - defines whether tests should be traced (useful for temporarily disabling tracing)
|
111
|
+
- `service_name` - name of the service or library under test (when you want it to be different for a test framework)
|
133
112
|
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
113
|
+
Example usage:
|
114
|
+
|
115
|
+
```ruby
|
116
|
+
Datadog.configure do |c|
|
117
|
+
c.service = 'my-ruby-app'
|
118
|
+
c.ci.enabled = true
|
119
|
+
c.ci.instrument :cucumber, service_name: 'my-cucumber-features', enabled: true
|
120
|
+
c.ci.instrument :minitest, service_name: 'my-unit-tests', enabled: false
|
121
|
+
end
|
122
|
+
```
|
139
123
|
|
140
124
|
## Agentless mode
|
141
125
|
|
@@ -160,7 +144,7 @@ or other external calls like here:
|
|
160
144
|
|
161
145
|
![Test trace with redis instrumented](./docs/screenshots/test-trace-with-redis.png)
|
162
146
|
|
163
|
-
|
147
|
+
To achieve this, add Datadog tracing instrumentations in your `Datadog.configure` block:
|
164
148
|
|
165
149
|
```ruby
|
166
150
|
Datadog.configure do |c|
|
@@ -173,13 +157,13 @@ end
|
|
173
157
|
...or enable auto instrumentation in your test_helper/spec_helper:
|
174
158
|
|
175
159
|
```ruby
|
176
|
-
require "
|
160
|
+
require "datadog/auto_instrument"
|
177
161
|
```
|
178
162
|
|
179
163
|
Note: in CI mode these traces are going to be submitted to CI Visibility,
|
180
164
|
they will **not** show up in Datadog APM.
|
181
165
|
|
182
|
-
For the full list of available instrumentations see [
|
166
|
+
For the full list of available instrumentations see [datadog documentation](https://github.com/DataDog/dd-trace-rb/blob/master/docs/GettingStarted.md)
|
183
167
|
|
184
168
|
### WebMock
|
185
169
|
|
@@ -193,8 +177,7 @@ Webmock accordingly.
|
|
193
177
|
|
194
178
|
```ruby
|
195
179
|
# when using agentless mode
|
196
|
-
|
197
|
-
WebMock.disable_net_connect!(:allow => /datadoghq.com/)
|
180
|
+
WebMock.disable_net_connect!(:allow => /datadoghq/)
|
198
181
|
|
199
182
|
# when using agent
|
200
183
|
WebMock.disable_net_connect!(:allow_localhost => true)
|
@@ -217,8 +200,10 @@ VCR.configure do |config|
|
|
217
200
|
config.ignore_hosts "127.0.0.1", "localhost"
|
218
201
|
|
219
202
|
# when using agentless mode
|
220
|
-
|
221
|
-
|
203
|
+
config.ignore_request do |request|
|
204
|
+
# ignore all requests to datadoghq hosts
|
205
|
+
request.uri =~ /datadoghq/
|
206
|
+
end
|
222
207
|
end
|
223
208
|
```
|
224
209
|
|
@@ -226,7 +211,7 @@ end
|
|
226
211
|
|
227
212
|
Startup logs produce a report of tracing state when the application is initially configured.
|
228
213
|
These logs are activated by default in test mode, if you don't want them you can disable this
|
229
|
-
via `
|
214
|
+
via `DD_TRACE_STARTUP_LOGS=0` or in the `Datadog.configure` block:
|
230
215
|
|
231
216
|
```ruby
|
232
217
|
Datadog.configure { |c| c.diagnostics.startup_logs.enabled = false }
|
@@ -236,7 +221,7 @@ Datadog.configure { |c| c.diagnostics.startup_logs.enabled = false }
|
|
236
221
|
|
237
222
|
Switching the library into debug mode will produce verbose, detailed logs about tracing activity, including any suppressed errors. This output can be helpful in identifying errors, confirming trace output, or catching HTTP transport issues.
|
238
223
|
|
239
|
-
You can enable this via `
|
224
|
+
You can enable this via `DD_TRACE_DEBUG=1` or in the `Datadog.configure` block:
|
240
225
|
|
241
226
|
```ruby
|
242
227
|
Datadog.configure { |c| c.diagnostics.debug = true }
|
@@ -0,0 +1,192 @@
|
|
1
|
+
#include <ruby.h>
|
2
|
+
#include <ruby/debug.h>
|
3
|
+
|
4
|
+
// constants
|
5
|
+
#define DD_COV_TARGET_FILES 1
|
6
|
+
#define DD_COV_TARGET_LINES 2
|
7
|
+
|
8
|
+
// Data structure
|
9
|
+
struct dd_cov_data
|
10
|
+
{
|
11
|
+
VALUE root;
|
12
|
+
int mode;
|
13
|
+
VALUE coverage;
|
14
|
+
};
|
15
|
+
|
16
|
+
static void dd_cov_mark(void *ptr)
|
17
|
+
{
|
18
|
+
struct dd_cov_data *dd_cov_data = ptr;
|
19
|
+
rb_gc_mark_movable(dd_cov_data->coverage);
|
20
|
+
rb_gc_mark_movable(dd_cov_data->root);
|
21
|
+
}
|
22
|
+
|
23
|
+
static void dd_cov_free(void *ptr)
|
24
|
+
{
|
25
|
+
struct dd_cov_data *dd_cov_data = ptr;
|
26
|
+
|
27
|
+
xfree(dd_cov_data);
|
28
|
+
}
|
29
|
+
|
30
|
+
static void dd_cov_compact(void *ptr)
|
31
|
+
{
|
32
|
+
struct dd_cov_data *dd_cov_data = ptr;
|
33
|
+
dd_cov_data->coverage = rb_gc_location(dd_cov_data->coverage);
|
34
|
+
dd_cov_data->root = rb_gc_location(dd_cov_data->root);
|
35
|
+
}
|
36
|
+
|
37
|
+
const rb_data_type_t dd_cov_data_type = {
|
38
|
+
.wrap_struct_name = "dd_cov",
|
39
|
+
.function = {
|
40
|
+
.dmark = dd_cov_mark,
|
41
|
+
.dfree = dd_cov_free,
|
42
|
+
.dsize = NULL,
|
43
|
+
.dcompact = dd_cov_compact},
|
44
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY};
|
45
|
+
|
46
|
+
static VALUE dd_cov_allocate(VALUE klass)
|
47
|
+
{
|
48
|
+
struct dd_cov_data *dd_cov_data;
|
49
|
+
VALUE obj = TypedData_Make_Struct(klass, struct dd_cov_data, &dd_cov_data_type, dd_cov_data);
|
50
|
+
dd_cov_data->coverage = rb_hash_new();
|
51
|
+
dd_cov_data->root = Qnil;
|
52
|
+
dd_cov_data->mode = DD_COV_TARGET_FILES;
|
53
|
+
return obj;
|
54
|
+
}
|
55
|
+
|
56
|
+
// DDCov methods
|
57
|
+
static VALUE dd_cov_initialize(int argc, VALUE *argv, VALUE self)
|
58
|
+
{
|
59
|
+
VALUE opt;
|
60
|
+
int mode;
|
61
|
+
|
62
|
+
rb_scan_args(argc, argv, "10", &opt);
|
63
|
+
VALUE rb_root = rb_hash_lookup(opt, ID2SYM(rb_intern("root")));
|
64
|
+
if (!RTEST(rb_root))
|
65
|
+
{
|
66
|
+
rb_raise(rb_eArgError, "root is required");
|
67
|
+
}
|
68
|
+
|
69
|
+
VALUE rb_mode = rb_hash_lookup(opt, ID2SYM(rb_intern("mode")));
|
70
|
+
if (!RTEST(rb_mode) || rb_mode == ID2SYM(rb_intern("files")))
|
71
|
+
{
|
72
|
+
mode = DD_COV_TARGET_FILES;
|
73
|
+
}
|
74
|
+
else if (rb_mode == ID2SYM(rb_intern("lines")))
|
75
|
+
{
|
76
|
+
mode = DD_COV_TARGET_LINES;
|
77
|
+
}
|
78
|
+
else
|
79
|
+
{
|
80
|
+
rb_raise(rb_eArgError, "mode is invalid");
|
81
|
+
}
|
82
|
+
|
83
|
+
struct dd_cov_data *dd_cov_data;
|
84
|
+
TypedData_Get_Struct(self, struct dd_cov_data, &dd_cov_data_type, dd_cov_data);
|
85
|
+
|
86
|
+
dd_cov_data->root = rb_root;
|
87
|
+
dd_cov_data->mode = mode;
|
88
|
+
|
89
|
+
return Qnil;
|
90
|
+
}
|
91
|
+
|
92
|
+
static void dd_cov_update_line_coverage(rb_event_flag_t event, VALUE data, VALUE self, ID id, VALUE klass)
|
93
|
+
{
|
94
|
+
struct dd_cov_data *dd_cov_data;
|
95
|
+
TypedData_Get_Struct(data, struct dd_cov_data, &dd_cov_data_type, dd_cov_data);
|
96
|
+
|
97
|
+
const char *filename = rb_sourcefile();
|
98
|
+
if (filename == NULL)
|
99
|
+
{
|
100
|
+
return;
|
101
|
+
}
|
102
|
+
|
103
|
+
if (dd_cov_data->root == Qnil)
|
104
|
+
{
|
105
|
+
return;
|
106
|
+
}
|
107
|
+
|
108
|
+
char *c_root = RSTRING_PTR(dd_cov_data->root);
|
109
|
+
if (c_root == NULL)
|
110
|
+
{
|
111
|
+
return;
|
112
|
+
}
|
113
|
+
long root_len = RSTRING_LEN(dd_cov_data->root);
|
114
|
+
// check that root is a prefix of the filename
|
115
|
+
// so this file is located under the given root
|
116
|
+
if (strncmp(c_root, filename, root_len) != 0)
|
117
|
+
{
|
118
|
+
return;
|
119
|
+
}
|
120
|
+
|
121
|
+
VALUE rb_str_source_file = rb_str_new2(filename);
|
122
|
+
|
123
|
+
if (dd_cov_data->mode == DD_COV_TARGET_FILES)
|
124
|
+
{
|
125
|
+
rb_hash_aset(dd_cov_data->coverage, rb_str_source_file, Qtrue);
|
126
|
+
return;
|
127
|
+
}
|
128
|
+
|
129
|
+
// this isn't optimized yet, this is a POC to show that lines coverage is possible
|
130
|
+
// ITR beta is going to use files coverage, we'll get back to this part when
|
131
|
+
// we need to implement lines coverage
|
132
|
+
if (dd_cov_data->mode == DD_COV_TARGET_LINES)
|
133
|
+
{
|
134
|
+
int line_number = rb_sourceline();
|
135
|
+
if (line_number <= 0)
|
136
|
+
{
|
137
|
+
return;
|
138
|
+
}
|
139
|
+
|
140
|
+
VALUE rb_lines = rb_hash_aref(dd_cov_data->coverage, rb_str_source_file);
|
141
|
+
if (rb_lines == Qnil)
|
142
|
+
{
|
143
|
+
rb_lines = rb_hash_new();
|
144
|
+
rb_hash_aset(dd_cov_data->coverage, rb_str_source_file, rb_lines);
|
145
|
+
}
|
146
|
+
|
147
|
+
rb_hash_aset(rb_lines, INT2FIX(line_number), Qtrue);
|
148
|
+
}
|
149
|
+
}
|
150
|
+
|
151
|
+
static VALUE dd_cov_start(VALUE self)
|
152
|
+
{
|
153
|
+
// get current thread
|
154
|
+
VALUE thval = rb_thread_current();
|
155
|
+
|
156
|
+
// add event hook
|
157
|
+
rb_thread_add_event_hook(thval, dd_cov_update_line_coverage, RUBY_EVENT_LINE, self);
|
158
|
+
|
159
|
+
return self;
|
160
|
+
}
|
161
|
+
|
162
|
+
static VALUE dd_cov_stop(VALUE self)
|
163
|
+
{
|
164
|
+
// get current thread
|
165
|
+
VALUE thval = rb_thread_current();
|
166
|
+
// remove event hook for the current thread
|
167
|
+
rb_thread_remove_event_hook(thval, dd_cov_update_line_coverage);
|
168
|
+
|
169
|
+
struct dd_cov_data *dd_cov_data;
|
170
|
+
TypedData_Get_Struct(self, struct dd_cov_data, &dd_cov_data_type, dd_cov_data);
|
171
|
+
|
172
|
+
VALUE cov = dd_cov_data->coverage;
|
173
|
+
|
174
|
+
dd_cov_data->coverage = rb_hash_new();
|
175
|
+
|
176
|
+
return cov;
|
177
|
+
}
|
178
|
+
|
179
|
+
void Init_datadog_cov(void)
|
180
|
+
{
|
181
|
+
VALUE mDatadog = rb_define_module("Datadog");
|
182
|
+
VALUE mCI = rb_define_module_under(mDatadog, "CI");
|
183
|
+
VALUE mITR = rb_define_module_under(mCI, "ITR");
|
184
|
+
VALUE mCoverage = rb_define_module_under(mITR, "Coverage");
|
185
|
+
VALUE cDatadogCov = rb_define_class_under(mCoverage, "DDCov", rb_cObject);
|
186
|
+
|
187
|
+
rb_define_alloc_func(cDatadogCov, dd_cov_allocate);
|
188
|
+
|
189
|
+
rb_define_method(cDatadogCov, "initialize", dd_cov_initialize, -1);
|
190
|
+
rb_define_method(cDatadogCov, "start", dd_cov_start, 0);
|
191
|
+
rb_define_method(cDatadogCov, "stop", dd_cov_stop, 0);
|
192
|
+
}
|
@@ -0,0 +1,18 @@
|
|
1
|
+
if RUBY_ENGINE != "ruby" || Gem.win_platform?
|
2
|
+
warn(
|
3
|
+
"WARN: Skipping build of code coverage native extension because of unsupported platform."
|
4
|
+
)
|
5
|
+
|
6
|
+
File.write("Makefile", "all install clean: # dummy makefile that does nothing")
|
7
|
+
exit
|
8
|
+
end
|
9
|
+
|
10
|
+
require "mkmf"
|
11
|
+
|
12
|
+
# Tag the native extension library with the Ruby version and Ruby platform.
|
13
|
+
# This makes it easier for development (avoids "oops I forgot to rebuild when I switched my Ruby") and ensures that
|
14
|
+
# the wrong library is never loaded.
|
15
|
+
# When requiring, we need to use the exact same string, including the version and the platform.
|
16
|
+
EXTENSION_NAME = "datadog_cov.#{RUBY_VERSION}_#{RUBY_PLATFORM}".freeze
|
17
|
+
|
18
|
+
create_makefile(EXTENSION_NAME)
|
@@ -1,7 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative "../ext/settings"
|
4
|
+
require_relative "../git/tree_uploader"
|
4
5
|
require_relative "../itr/runner"
|
6
|
+
require_relative "../itr/coverage/transport"
|
7
|
+
require_relative "../itr/coverage/writer"
|
5
8
|
require_relative "../test_visibility/flush"
|
6
9
|
require_relative "../test_visibility/recorder"
|
7
10
|
require_relative "../test_visibility/null_recorder"
|
@@ -10,25 +13,34 @@ require_relative "../test_visibility/serializers/factories/test_suite_level"
|
|
10
13
|
require_relative "../test_visibility/transport"
|
11
14
|
require_relative "../transport/api/builder"
|
12
15
|
require_relative "../transport/remote_settings_api"
|
16
|
+
require_relative "../worker"
|
13
17
|
|
14
18
|
module Datadog
|
15
19
|
module CI
|
16
20
|
module Configuration
|
17
21
|
# Adds CI behavior to Datadog trace components
|
18
22
|
module Components
|
19
|
-
attr_reader :ci_recorder
|
23
|
+
attr_reader :ci_recorder, :itr
|
20
24
|
|
21
25
|
def initialize(settings)
|
22
26
|
# Activate CI mode if enabled
|
23
27
|
if settings.ci.enabled
|
24
28
|
activate_ci!(settings)
|
25
29
|
else
|
30
|
+
@itr = nil
|
26
31
|
@ci_recorder = TestVisibility::NullRecorder.new
|
27
32
|
end
|
28
33
|
|
29
34
|
super
|
30
35
|
end
|
31
36
|
|
37
|
+
def shutdown!(replacement = nil)
|
38
|
+
super
|
39
|
+
|
40
|
+
@ci_recorder&.shutdown!
|
41
|
+
@itr&.shutdown!
|
42
|
+
end
|
43
|
+
|
32
44
|
def activate_ci!(settings)
|
33
45
|
# Configure ddtrace library for CI visibility mode
|
34
46
|
# Deactivate telemetry
|
@@ -49,10 +61,17 @@ module Datadog
|
|
49
61
|
|
50
62
|
# transport creation
|
51
63
|
writer_options = settings.ci.writer_options
|
64
|
+
coverage_writer = nil
|
52
65
|
test_visibility_api = build_test_visibility_api(settings)
|
53
66
|
|
54
67
|
if test_visibility_api
|
55
|
-
|
68
|
+
# setup writer for code coverage payloads
|
69
|
+
coverage_writer = ITR::Coverage::Writer.new(
|
70
|
+
transport: ITR::Coverage::Transport.new(api: test_visibility_api)
|
71
|
+
)
|
72
|
+
|
73
|
+
# configure tracing writer to send traces to CI visibility backend
|
74
|
+
writer_options[:transport] = TestVisibility::Transport.new(
|
56
75
|
api: test_visibility_api,
|
57
76
|
serializers_factory: serializers_factory(settings),
|
58
77
|
dd_env: settings.env
|
@@ -71,21 +90,36 @@ module Datadog
|
|
71
90
|
|
72
91
|
settings.tracing.test_mode.writer_options = writer_options
|
73
92
|
|
74
|
-
itr = Datadog::CI::ITR::Runner.new(
|
75
|
-
enabled: settings.ci.enabled && settings.ci.itr_enabled
|
76
|
-
)
|
77
|
-
|
78
93
|
remote_settings_api = Transport::RemoteSettingsApi.new(
|
79
94
|
api: test_visibility_api,
|
80
95
|
dd_env: settings.env
|
81
96
|
)
|
82
97
|
|
98
|
+
itr = ITR::Runner.new(
|
99
|
+
api: test_visibility_api,
|
100
|
+
dd_env: settings.env,
|
101
|
+
coverage_writer: coverage_writer,
|
102
|
+
enabled: settings.ci.enabled && settings.ci.itr_enabled
|
103
|
+
)
|
104
|
+
|
105
|
+
git_tree_uploader = Git::TreeUploader.new(api: test_visibility_api)
|
106
|
+
git_tree_upload_worker = if settings.ci.git_metadata_upload_enabled
|
107
|
+
Worker.new do |repository_url|
|
108
|
+
git_tree_uploader.call(repository_url)
|
109
|
+
end
|
110
|
+
else
|
111
|
+
DummyWorker.new
|
112
|
+
end
|
113
|
+
|
83
114
|
# CI visibility recorder global instance
|
84
115
|
@ci_recorder = TestVisibility::Recorder.new(
|
85
116
|
test_suite_level_visibility_enabled: !settings.ci.force_test_level_visibility,
|
86
117
|
itr: itr,
|
87
|
-
remote_settings_api: remote_settings_api
|
118
|
+
remote_settings_api: remote_settings_api,
|
119
|
+
git_tree_upload_worker: git_tree_upload_worker
|
88
120
|
)
|
121
|
+
|
122
|
+
@itr = itr
|
89
123
|
end
|
90
124
|
|
91
125
|
def build_test_visibility_api(settings)
|
@@ -122,9 +156,9 @@ module Datadog
|
|
122
156
|
|
123
157
|
def serializers_factory(settings)
|
124
158
|
if settings.ci.force_test_level_visibility
|
125
|
-
|
159
|
+
TestVisibility::Serializers::Factories::TestLevel
|
126
160
|
else
|
127
|
-
|
161
|
+
TestVisibility::Serializers::Factories::TestSuiteLevel
|
128
162
|
end
|
129
163
|
end
|
130
164
|
|
@@ -47,7 +47,7 @@ module Datadog
|
|
47
47
|
o.after_set do |value|
|
48
48
|
if value
|
49
49
|
Datadog::Core.log_deprecation do
|
50
|
-
"The experimental_test_suite_level_visibility_enabled setting has no effect and will be removed in
|
50
|
+
"The experimental_test_suite_level_visibility_enabled setting has no effect and will be removed in 2.0. " \
|
51
51
|
"Test suite level visibility is now enabled by default. " \
|
52
52
|
"If you want to disable test suite level visibility set configuration.ci.force_test_level_visibility = true."
|
53
53
|
end
|
@@ -61,6 +61,12 @@ module Datadog
|
|
61
61
|
o.default false
|
62
62
|
end
|
63
63
|
|
64
|
+
option :git_metadata_upload_enabled do |o|
|
65
|
+
o.type :bool
|
66
|
+
o.env CI::Ext::Settings::ENV_GIT_METADATA_UPLOAD_ENABLED
|
67
|
+
o.default true
|
68
|
+
end
|
69
|
+
|
64
70
|
define_method(:instrument) do |integration_name, options = {}, &block|
|
65
71
|
return unless enabled
|
66
72
|
|
@@ -26,21 +26,6 @@ module Datadog
|
|
26
26
|
Utils::Configuration.fetch_service_name(Ext::DEFAULT_SERVICE_NAME)
|
27
27
|
end
|
28
28
|
end
|
29
|
-
|
30
|
-
# @deprecated Will be removed in 1.0
|
31
|
-
option :operation_name do |o|
|
32
|
-
o.type :string
|
33
|
-
o.env Ext::ENV_OPERATION_NAME
|
34
|
-
o.default Ext::OPERATION_NAME
|
35
|
-
|
36
|
-
o.after_set do |value|
|
37
|
-
if value && value != Ext::OPERATION_NAME
|
38
|
-
Datadog::Core.log_deprecation do
|
39
|
-
"The operation_name setting has no effect and will be removed in 1.0"
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
29
|
end
|
45
30
|
end
|
46
31
|
end
|
@@ -5,7 +5,7 @@ module Datadog
|
|
5
5
|
module Contrib
|
6
6
|
module Cucumber
|
7
7
|
# Cucumber integration constants
|
8
|
-
#
|
8
|
+
# @public_api
|
9
9
|
module Ext
|
10
10
|
ENV_ENABLED = "DD_TRACE_CUCUMBER_ENABLED"
|
11
11
|
DEFAULT_SERVICE_NAME = "cucumber"
|
@@ -13,10 +13,6 @@ module Datadog
|
|
13
13
|
FRAMEWORK = "cucumber"
|
14
14
|
|
15
15
|
STEP_SPAN_TYPE = "step"
|
16
|
-
|
17
|
-
# TODO: remove in 1.0
|
18
|
-
ENV_OPERATION_NAME = "DD_TRACE_CUCUMBER_OPERATION_NAME"
|
19
|
-
OPERATION_NAME = "cucumber.test"
|
20
16
|
end
|
21
17
|
end
|
22
18
|
end
|