datadog-ci 1.0.0.beta6 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +21 -2
- data/README.md +15 -205
- data/ext/datadog_cov/datadog_cov.c +115 -85
- data/lib/datadog/ci/codeowners/matcher.rb +1 -1
- data/lib/datadog/ci/codeowners/parser.rb +5 -5
- data/lib/datadog/ci/configuration/components.rb +17 -1
- data/lib/datadog/ci/configuration/settings.rb +6 -0
- data/lib/datadog/ci/contrib/cucumber/formatter.rb +1 -1
- data/lib/datadog/ci/contrib/rspec/example.rb +7 -4
- data/lib/datadog/ci/ext/environment/providers/gitlab.rb +2 -2
- data/lib/datadog/ci/ext/environment.rb +1 -4
- data/lib/datadog/ci/ext/settings.rb +8 -7
- data/lib/datadog/ci/itr/coverage/event.rb +1 -1
- data/lib/datadog/ci/itr/coverage/writer.rb +3 -1
- data/lib/datadog/ci/itr/runner.rb +11 -2
- data/lib/datadog/ci/test_visibility/serializers/base.rb +1 -7
- data/lib/datadog/ci/test_visibility/serializers/span.rb +2 -2
- data/lib/datadog/ci/test_visibility/serializers/test_module.rb +2 -2
- data/lib/datadog/ci/test_visibility/serializers/test_session.rb +2 -2
- data/lib/datadog/ci/test_visibility/serializers/test_suite.rb +2 -2
- data/lib/datadog/ci/test_visibility/serializers/test_v1.rb +2 -2
- data/lib/datadog/ci/test_visibility/serializers/test_v2.rb +3 -3
- data/lib/datadog/ci/transport/http.rb +1 -0
- data/lib/datadog/ci/version.rb +4 -4
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 73bd9b05aba53e1197420cc0e4a529339b6526e13775467fa326b4949e44043a
|
4
|
+
data.tar.gz: 7613c476a2a3f2cf28d7dd99dd53da2fa6c921c9a03de18a6997f25e3fe0f27a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fc66a07d4ccceb71f18b26d290e387b6b403d7efbb46169ced3db9ad0e67e2f29ec163bdaa43a7f7508c6511ca0c68d99257d32d3a25e62b42e00219d7ef44a1
|
7
|
+
data.tar.gz: 6fb71c67ecea77fc61238fa7f739192a7670f51d8f4c052d436d2f4d69743f1202f27e27cf84fa76ce74860145d13badb00862c1c03b37d93dc9a33e597afb3d
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,18 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## [1.0.1] - 2024-06-11
|
4
|
+
|
5
|
+
### Fixed
|
6
|
+
* multi threaded code coverage support for datadog_cov ([#189][])
|
7
|
+
* code coverage extension fixes and improvements ([#171][])
|
8
|
+
|
9
|
+
## [1.0.0] - 2024-06-06
|
10
|
+
|
11
|
+
|
12
|
+
### Changed
|
13
|
+
* automatically trace with correct time even when time is stubbed by timecop ([#185][])
|
14
|
+
* depend on gem datadog ~> 2.0 ([#190][])
|
15
|
+
|
3
16
|
## [1.0.0.beta6] - 2024-05-29
|
4
17
|
|
5
18
|
### Added
|
@@ -254,7 +267,9 @@ Currently test suite level visibility is not used by our instrumentation: it wil
|
|
254
267
|
|
255
268
|
- Ruby versions < 2.7 no longer supported ([#8][])
|
256
269
|
|
257
|
-
[Unreleased]: https://github.com/DataDog/datadog-ci-rb/compare/v1.0.
|
270
|
+
[Unreleased]: https://github.com/DataDog/datadog-ci-rb/compare/v1.0.1...main
|
271
|
+
[1.0.1]: https://github.com/DataDog/datadog-ci-rb/compare/v1.0.0...v1.0.1
|
272
|
+
[1.0.0]: https://github.com/DataDog/datadog-ci-rb/compare/v1.0.0.beta6...v1.0.0
|
258
273
|
[1.0.0.beta6]: https://github.com/DataDog/datadog-ci-rb/compare/v1.0.0.beta5...v1.0.0.beta6
|
259
274
|
[1.0.0.beta5]: https://github.com/DataDog/datadog-ci-rb/compare/v1.0.0.beta4...v1.0.0.beta5
|
260
275
|
[1.0.0.beta4]: https://github.com/DataDog/datadog-ci-rb/compare/v1.0.0.beta3...v1.0.0.beta4
|
@@ -353,9 +368,13 @@ Currently test suite level visibility is not used by our instrumentation: it wil
|
|
353
368
|
[#167]: https://github.com/DataDog/datadog-ci-rb/issues/167
|
354
369
|
[#168]: https://github.com/DataDog/datadog-ci-rb/issues/168
|
355
370
|
[#170]: https://github.com/DataDog/datadog-ci-rb/issues/170
|
371
|
+
[#171]: https://github.com/DataDog/datadog-ci-rb/issues/171
|
356
372
|
[#172]: https://github.com/DataDog/datadog-ci-rb/issues/172
|
357
373
|
[#173]: https://github.com/DataDog/datadog-ci-rb/issues/173
|
358
374
|
[#174]: https://github.com/DataDog/datadog-ci-rb/issues/174
|
359
375
|
[#175]: https://github.com/DataDog/datadog-ci-rb/issues/175
|
360
376
|
[#180]: https://github.com/DataDog/datadog-ci-rb/issues/180
|
361
|
-
[#183]: https://github.com/DataDog/datadog-ci-rb/issues/183
|
377
|
+
[#183]: https://github.com/DataDog/datadog-ci-rb/issues/183
|
378
|
+
[#185]: https://github.com/DataDog/datadog-ci-rb/issues/185
|
379
|
+
[#189]: https://github.com/DataDog/datadog-ci-rb/issues/189
|
380
|
+
[#190]: https://github.com/DataDog/datadog-ci-rb/issues/190
|
data/README.md
CHANGED
@@ -1,13 +1,23 @@
|
|
1
|
-
# Datadog
|
1
|
+
# Datadog Test Visibility for Ruby
|
2
2
|
|
3
3
|
[![Gem Version](https://badge.fury.io/rb/datadog-ci.svg)](https://badge.fury.io/rb/datadog-ci)
|
4
4
|
[![YARD documentation](https://img.shields.io/badge/YARD-documentation-blue)](https://datadoghq.dev/datadog-ci-rb/)
|
5
5
|
[![codecov](https://codecov.io/gh/DataDog/datadog-ci-rb/branch/main/graph/badge.svg)](https://app.codecov.io/gh/DataDog/datadog-ci-rb/branch/main)
|
6
6
|
[![CircleCI](https://dl.circleci.com/status-badge/img/gh/DataDog/datadog-ci-rb/tree/main.svg?style=svg)](https://dl.circleci.com/status-badge/redirect/gh/DataDog/datadog-ci-rb/tree/main)
|
7
7
|
|
8
|
-
Datadog's Ruby Library for instrumenting your
|
8
|
+
Datadog's Ruby Library for instrumenting your tests.
|
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
|
+
## Features
|
12
|
+
|
13
|
+
- [Test Visibility](https://docs.datadoghq.com/tests/) - collect metrics and results for your tests
|
14
|
+
- [Intelligent test runner](https://docs.datadoghq.com/intelligent_test_runner/) - save time by selectively running only tests affected by code changes
|
15
|
+
- [Search and manage CI tests](https://docs.datadoghq.com/tests/search/)
|
16
|
+
- [Enhance developer workflows](https://docs.datadoghq.com/tests/developer_workflows)
|
17
|
+
- [Flaky test management](https://docs.datadoghq.com/tests/guides/flaky_test_management/)
|
18
|
+
- [Add custom measures to your tests](https://docs.datadoghq.com/tests/guides/add_custom_measures/?tab=ruby)
|
19
|
+
- [Browser tests integration with Datadog RUM](https://docs.datadoghq.com/tests/browser_tests)
|
20
|
+
|
11
21
|
## Installation
|
12
22
|
|
13
23
|
Add to your Gemfile.
|
@@ -22,210 +32,10 @@ end
|
|
22
32
|
|
23
33
|
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
34
|
|
25
|
-
##
|
26
|
-
|
27
|
-
### RSpec
|
28
|
-
|
29
|
-
To activate `RSpec` integration, add this to the `spec_helper.rb` file:
|
30
|
-
|
31
|
-
```ruby
|
32
|
-
require 'rspec'
|
33
|
-
require 'datadog/ci'
|
34
|
-
|
35
|
-
# Only activates test instrumentation on CI
|
36
|
-
if ENV["DD_ENV"] == "ci"
|
37
|
-
Datadog.configure do |c|
|
38
|
-
# The name of the service or library under test
|
39
|
-
c.service = 'my-ruby-app'
|
40
|
-
c.ci.enabled = true
|
41
|
-
c.ci.instrument :rspec
|
42
|
-
end
|
43
|
-
end
|
44
|
-
```
|
45
|
-
|
46
|
-
### Minitest
|
47
|
-
|
48
|
-
The Minitest integration will trace all executions of tests when using `minitest` test framework.
|
49
|
-
|
50
|
-
To activate your integration, use the `Datadog.configure` method:
|
51
|
-
|
52
|
-
```ruby
|
53
|
-
require 'minitest'
|
54
|
-
require 'datadog/ci'
|
55
|
-
|
56
|
-
# Only activates test instrumentation on CI
|
57
|
-
if ENV["DD_ENV"] == "ci"
|
58
|
-
# Configure default Minitest integration
|
59
|
-
Datadog.configure do |c|
|
60
|
-
# The name of the service or library under test
|
61
|
-
c.service = 'my-ruby-app'
|
62
|
-
c.ci.enabled = true
|
63
|
-
c.ci.instrument :minitest
|
64
|
-
end
|
65
|
-
end
|
66
|
-
```
|
67
|
-
|
68
|
-
> [!IMPORTANT]
|
69
|
-
> When using `minitest/autorun` the order of requires matters: `datadog/ci` must be
|
70
|
-
> always required before `minitest/autorun`.
|
71
|
-
|
72
|
-
Example using `minitest/autorun`
|
73
|
-
|
74
|
-
```ruby
|
75
|
-
require 'datadog/ci'
|
76
|
-
require 'minitest/autorun'
|
77
|
-
|
78
|
-
if ENV["DD_ENV"] == "ci"
|
79
|
-
Datadog.configure do |c|
|
80
|
-
c.service = 'my-ruby-app'
|
81
|
-
c.ci.enabled = true
|
82
|
-
c.ci.instrument :minitest
|
83
|
-
end
|
84
|
-
end
|
85
|
-
```
|
86
|
-
|
87
|
-
### Cucumber
|
88
|
-
|
89
|
-
Activate `Cucumber` integration with configuration
|
90
|
-
|
91
|
-
```ruby
|
92
|
-
require 'cucumber'
|
93
|
-
require 'datadog/ci'
|
94
|
-
|
95
|
-
# Only activates test instrumentation on CI
|
96
|
-
if ENV["DD_ENV"] == "ci"
|
97
|
-
Datadog.configure do |c|
|
98
|
-
# The name of the service or library under test
|
99
|
-
c.service = 'my-ruby-app'
|
100
|
-
c.ci.enabled = true
|
101
|
-
c.ci.instrument :cucumber
|
102
|
-
end
|
103
|
-
end
|
104
|
-
```
|
105
|
-
|
106
|
-
### Instrumentation options
|
107
|
-
|
108
|
-
Configuration `ci.instrument` accepts the following optional parameters:
|
35
|
+
## Setup
|
109
36
|
|
110
|
-
-
|
111
|
-
-
|
112
|
-
|
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
|
-
```
|
123
|
-
|
124
|
-
## Agentless mode
|
125
|
-
|
126
|
-
If you are using a cloud CI provider without access to the underlying worker nodes, such as GitHub Actions or CircleCI, configure the library to use the Agentless mode. For this, set the following environment variables:
|
127
|
-
`DD_CIVISIBILITY_AGENTLESS_ENABLED=true (Required)` and `DD_API_KEY=your_secret_api_key (Required)`.
|
128
|
-
|
129
|
-
Additionally, configure which [Datadog site](https://docs.datadoghq.com/getting_started/site/) you want to send data to:
|
130
|
-
`DD_SITE=your.datadoghq.com` (datadoghq.com by default).
|
131
|
-
|
132
|
-
Agentless mode can also be enabled via `Datadog.configure` (but don't forget to set DD_API_KEY environment variable):
|
133
|
-
|
134
|
-
```ruby
|
135
|
-
Datadog.configure { |c| c.ci.agentless_mode_enabled = true }
|
136
|
-
```
|
137
|
-
|
138
|
-
## Additional configuration
|
139
|
-
|
140
|
-
### Add tracing instrumentations
|
141
|
-
|
142
|
-
It can be useful to have rich tracing information about your tests that includes time spent performing database operations
|
143
|
-
or other external calls like here:
|
144
|
-
|
145
|
-
![Test trace with redis instrumented](./docs/screenshots/test-trace-with-redis.png)
|
146
|
-
|
147
|
-
To achieve this, add Datadog tracing instrumentations in your `Datadog.configure` block:
|
148
|
-
|
149
|
-
```ruby
|
150
|
-
Datadog.configure do |c|
|
151
|
-
# ... ci configs and instrumentation here ...
|
152
|
-
c.tracing.instrument :redis
|
153
|
-
c.tracing.instrument :pg
|
154
|
-
end
|
155
|
-
```
|
156
|
-
|
157
|
-
...or enable auto instrumentation in your test_helper/spec_helper:
|
158
|
-
|
159
|
-
```ruby
|
160
|
-
require "datadog/auto_instrument"
|
161
|
-
```
|
162
|
-
|
163
|
-
Note: in CI mode these traces are going to be submitted to CI Visibility,
|
164
|
-
they will **not** show up in Datadog APM.
|
165
|
-
|
166
|
-
For the full list of available instrumentations see [datadog documentation](https://github.com/DataDog/dd-trace-rb/blob/master/docs/GettingStarted.md)
|
167
|
-
|
168
|
-
### WebMock
|
169
|
-
|
170
|
-
[WebMock](https://github.com/bblimke/webmock)
|
171
|
-
is a popular Ruby library that stubs HTTP requests when running tests.
|
172
|
-
By default it fails when used together with datadog-ci as traces are being sent
|
173
|
-
to Datadog via HTTP calls.
|
174
|
-
|
175
|
-
In order to allow HTTP connections for Datadog backend you would need to configure
|
176
|
-
Webmock accordingly.
|
177
|
-
|
178
|
-
```ruby
|
179
|
-
# when using agentless mode
|
180
|
-
WebMock.disable_net_connect!(:allow => /datadoghq/)
|
181
|
-
|
182
|
-
# when using agent
|
183
|
-
WebMock.disable_net_connect!(:allow_localhost => true)
|
184
|
-
|
185
|
-
# or for more granular setting set your agent URL
|
186
|
-
WebMock.disable_net_connect!(:allow => "localhost:8126")
|
187
|
-
```
|
188
|
-
|
189
|
-
### VCR
|
190
|
-
|
191
|
-
[VCR](https://github.com/vcr/vcr) is another popular testing library for HTTP interactions.
|
192
|
-
|
193
|
-
It requires additional configuration to correctly work with datadog-ci:
|
194
|
-
|
195
|
-
```ruby
|
196
|
-
VCR.configure do |config|
|
197
|
-
# ... your usual configuration here ...
|
198
|
-
|
199
|
-
# when using agent
|
200
|
-
config.ignore_hosts "127.0.0.1", "localhost"
|
201
|
-
|
202
|
-
# when using agentless mode
|
203
|
-
config.ignore_request do |request|
|
204
|
-
# ignore all requests to datadoghq hosts
|
205
|
-
request.uri =~ /datadoghq/
|
206
|
-
end
|
207
|
-
end
|
208
|
-
```
|
209
|
-
|
210
|
-
### Disabling startup logs
|
211
|
-
|
212
|
-
Startup logs produce a report of tracing state when the application is initially configured.
|
213
|
-
These logs are activated by default in test mode, if you don't want them you can disable this
|
214
|
-
via `DD_TRACE_STARTUP_LOGS=0` or in the `Datadog.configure` block:
|
215
|
-
|
216
|
-
```ruby
|
217
|
-
Datadog.configure { |c| c.diagnostics.startup_logs.enabled = false }
|
218
|
-
```
|
219
|
-
|
220
|
-
### Enabling debug mode
|
221
|
-
|
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.
|
223
|
-
|
224
|
-
You can enable this via `DD_TRACE_DEBUG=1` or in the `Datadog.configure` block:
|
225
|
-
|
226
|
-
```ruby
|
227
|
-
Datadog.configure { |c| c.diagnostics.debug = true }
|
228
|
-
```
|
37
|
+
- [Test visibility setup](https://docs.datadoghq.com/tests/setup/ruby/?tab=cloudciprovideragentless)
|
38
|
+
- [Intelligent test runner setup](https://docs.datadoghq.com/intelligent_test_runner/setup/ruby) (test visibility setup is required before setting up intelligent test runner)
|
229
39
|
|
230
40
|
## Contributing
|
231
41
|
|
@@ -1,55 +1,54 @@
|
|
1
1
|
#include <ruby.h>
|
2
2
|
#include <ruby/debug.h>
|
3
3
|
|
4
|
-
|
5
|
-
#define DD_COV_TARGET_FILES 1
|
6
|
-
#define DD_COV_TARGET_LINES 2
|
4
|
+
#define PROFILE_FRAMES_BUFFER_SIZE 1
|
7
5
|
|
8
|
-
|
6
|
+
// threading modes
|
7
|
+
#define SINGLE_THREADED_COVERAGE_MODE 0
|
8
|
+
#define MULTI_THREADED_COVERAGE_MODE 1
|
9
|
+
|
10
|
+
char *ruby_strndup(const char *str, size_t size)
|
9
11
|
{
|
10
|
-
|
11
|
-
{
|
12
|
-
return 0;
|
13
|
-
}
|
12
|
+
char *dup;
|
14
13
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
return 0;
|
19
|
-
}
|
14
|
+
dup = xmalloc(size + 1);
|
15
|
+
memcpy(dup, str, size);
|
16
|
+
dup[size] = '\0';
|
20
17
|
|
21
|
-
|
22
|
-
if (strncmp(c_prefix, str, prefix_len) == 0)
|
23
|
-
{
|
24
|
-
return 1;
|
25
|
-
}
|
26
|
-
else
|
27
|
-
{
|
28
|
-
return 0;
|
29
|
-
}
|
18
|
+
return dup;
|
30
19
|
}
|
31
20
|
|
32
21
|
// Data structure
|
33
22
|
struct dd_cov_data
|
34
23
|
{
|
35
|
-
|
36
|
-
|
37
|
-
|
24
|
+
char *root;
|
25
|
+
long root_len;
|
26
|
+
|
27
|
+
char *ignored_path;
|
28
|
+
long ignored_path_len;
|
29
|
+
|
38
30
|
VALUE coverage;
|
31
|
+
|
32
|
+
uintptr_t last_filename_ptr;
|
33
|
+
|
34
|
+
// for single threaded mode: thread that is being covered
|
35
|
+
VALUE th_covered;
|
36
|
+
|
37
|
+
int threading_mode;
|
39
38
|
};
|
40
39
|
|
41
40
|
static void dd_cov_mark(void *ptr)
|
42
41
|
{
|
43
42
|
struct dd_cov_data *dd_cov_data = ptr;
|
44
43
|
rb_gc_mark_movable(dd_cov_data->coverage);
|
45
|
-
rb_gc_mark_movable(dd_cov_data->
|
46
|
-
rb_gc_mark_movable(dd_cov_data->ignored_path);
|
44
|
+
rb_gc_mark_movable(dd_cov_data->th_covered);
|
47
45
|
}
|
48
46
|
|
49
47
|
static void dd_cov_free(void *ptr)
|
50
48
|
{
|
51
49
|
struct dd_cov_data *dd_cov_data = ptr;
|
52
|
-
|
50
|
+
xfree(dd_cov_data->root);
|
51
|
+
xfree(dd_cov_data->ignored_path);
|
53
52
|
xfree(dd_cov_data);
|
54
53
|
}
|
55
54
|
|
@@ -57,8 +56,7 @@ static void dd_cov_compact(void *ptr)
|
|
57
56
|
{
|
58
57
|
struct dd_cov_data *dd_cov_data = ptr;
|
59
58
|
dd_cov_data->coverage = rb_gc_location(dd_cov_data->coverage);
|
60
|
-
dd_cov_data->
|
61
|
-
dd_cov_data->ignored_path = rb_gc_location(dd_cov_data->ignored_path);
|
59
|
+
dd_cov_data->th_covered = rb_gc_location(dd_cov_data->th_covered);
|
62
60
|
}
|
63
61
|
|
64
62
|
const rb_data_type_t dd_cov_data_type = {
|
@@ -74,10 +72,15 @@ static VALUE dd_cov_allocate(VALUE klass)
|
|
74
72
|
{
|
75
73
|
struct dd_cov_data *dd_cov_data;
|
76
74
|
VALUE obj = TypedData_Make_Struct(klass, struct dd_cov_data, &dd_cov_data_type, dd_cov_data);
|
75
|
+
|
77
76
|
dd_cov_data->coverage = rb_hash_new();
|
78
|
-
dd_cov_data->root =
|
79
|
-
dd_cov_data->
|
80
|
-
dd_cov_data->
|
77
|
+
dd_cov_data->root = NULL;
|
78
|
+
dd_cov_data->root_len = 0;
|
79
|
+
dd_cov_data->ignored_path = NULL;
|
80
|
+
dd_cov_data->ignored_path_len = 0;
|
81
|
+
dd_cov_data->last_filename_ptr = 0;
|
82
|
+
dd_cov_data->threading_mode = MULTI_THREADED_COVERAGE_MODE;
|
83
|
+
|
81
84
|
return obj;
|
82
85
|
}
|
83
86
|
|
@@ -85,7 +88,6 @@ static VALUE dd_cov_allocate(VALUE klass)
|
|
85
88
|
static VALUE dd_cov_initialize(int argc, VALUE *argv, VALUE self)
|
86
89
|
{
|
87
90
|
VALUE opt;
|
88
|
-
int mode;
|
89
91
|
|
90
92
|
rb_scan_args(argc, argv, "10", &opt);
|
91
93
|
VALUE rb_root = rb_hash_lookup(opt, ID2SYM(rb_intern("root")));
|
@@ -93,113 +95,141 @@ static VALUE dd_cov_initialize(int argc, VALUE *argv, VALUE self)
|
|
93
95
|
{
|
94
96
|
rb_raise(rb_eArgError, "root is required");
|
95
97
|
}
|
96
|
-
|
97
98
|
VALUE rb_ignored_path = rb_hash_lookup(opt, ID2SYM(rb_intern("ignored_path")));
|
98
99
|
|
99
|
-
VALUE
|
100
|
-
|
100
|
+
VALUE rb_threading_mode = rb_hash_lookup(opt, ID2SYM(rb_intern("threading_mode")));
|
101
|
+
int threading_mode;
|
102
|
+
if (rb_threading_mode == ID2SYM(rb_intern("multi")))
|
101
103
|
{
|
102
|
-
|
104
|
+
threading_mode = MULTI_THREADED_COVERAGE_MODE;
|
103
105
|
}
|
104
|
-
else if (
|
106
|
+
else if (rb_threading_mode == ID2SYM(rb_intern("single")))
|
105
107
|
{
|
106
|
-
|
108
|
+
threading_mode = SINGLE_THREADED_COVERAGE_MODE;
|
107
109
|
}
|
108
110
|
else
|
109
111
|
{
|
110
|
-
rb_raise(rb_eArgError, "mode is invalid");
|
112
|
+
rb_raise(rb_eArgError, "threading mode is invalid");
|
111
113
|
}
|
112
114
|
|
113
115
|
struct dd_cov_data *dd_cov_data;
|
114
116
|
TypedData_Get_Struct(self, struct dd_cov_data, &dd_cov_data_type, dd_cov_data);
|
115
117
|
|
116
|
-
dd_cov_data->
|
117
|
-
dd_cov_data->
|
118
|
-
dd_cov_data->
|
118
|
+
dd_cov_data->threading_mode = threading_mode;
|
119
|
+
dd_cov_data->root_len = RSTRING_LEN(rb_root);
|
120
|
+
dd_cov_data->root = ruby_strndup(RSTRING_PTR(rb_root), dd_cov_data->root_len);
|
121
|
+
|
122
|
+
if (RTEST(rb_ignored_path))
|
123
|
+
{
|
124
|
+
dd_cov_data->ignored_path_len = RSTRING_LEN(rb_ignored_path);
|
125
|
+
dd_cov_data->ignored_path = ruby_strndup(RSTRING_PTR(rb_ignored_path), dd_cov_data->ignored_path_len);
|
126
|
+
}
|
119
127
|
|
120
128
|
return Qnil;
|
121
129
|
}
|
122
130
|
|
123
|
-
static void
|
131
|
+
static void dd_cov_update_coverage(rb_event_flag_t event, VALUE data, VALUE self, ID id, VALUE klass)
|
124
132
|
{
|
125
133
|
struct dd_cov_data *dd_cov_data;
|
126
134
|
TypedData_Get_Struct(data, struct dd_cov_data, &dd_cov_data_type, dd_cov_data);
|
127
135
|
|
128
|
-
const char *
|
129
|
-
|
136
|
+
const char *c_filename = rb_sourcefile();
|
137
|
+
|
138
|
+
// skip if we cover the same file again
|
139
|
+
uintptr_t current_filename_ptr = (uintptr_t)c_filename;
|
140
|
+
if (dd_cov_data->last_filename_ptr == current_filename_ptr)
|
130
141
|
{
|
131
142
|
return;
|
132
143
|
}
|
144
|
+
dd_cov_data->last_filename_ptr = current_filename_ptr;
|
133
145
|
|
134
|
-
|
135
|
-
|
146
|
+
VALUE top_frame;
|
147
|
+
int captured_frames = rb_profile_frames(
|
148
|
+
0 /* stack starting depth */,
|
149
|
+
PROFILE_FRAMES_BUFFER_SIZE,
|
150
|
+
&top_frame,
|
151
|
+
NULL);
|
152
|
+
|
153
|
+
if (captured_frames != PROFILE_FRAMES_BUFFER_SIZE)
|
136
154
|
{
|
137
155
|
return;
|
138
156
|
}
|
139
157
|
|
140
|
-
|
141
|
-
|
142
|
-
if (RTEST(dd_cov_data->ignored_path) && is_prefix(dd_cov_data->ignored_path, filename) == 1)
|
158
|
+
VALUE filename = rb_profile_frame_path(top_frame);
|
159
|
+
if (filename == Qnil)
|
143
160
|
{
|
144
161
|
return;
|
145
162
|
}
|
146
163
|
|
147
|
-
|
148
|
-
|
149
|
-
if (dd_cov_data->
|
164
|
+
char *filename_ptr = RSTRING_PTR(filename);
|
165
|
+
// if the current filename is not located under the root, we skip it
|
166
|
+
if (strncmp(dd_cov_data->root, filename_ptr, dd_cov_data->root_len) != 0)
|
150
167
|
{
|
151
|
-
rb_hash_aset(dd_cov_data->coverage, rb_str_source_file, Qtrue);
|
152
168
|
return;
|
153
169
|
}
|
154
170
|
|
155
|
-
//
|
156
|
-
//
|
157
|
-
|
158
|
-
if (dd_cov_data->mode == DD_COV_TARGET_LINES)
|
171
|
+
// if ignored_path is provided and the current filename is located under the ignored_path, we skip it too
|
172
|
+
// this is useful for ignoring bundled gems location
|
173
|
+
if (dd_cov_data->ignored_path_len != 0 && strncmp(dd_cov_data->ignored_path, filename_ptr, dd_cov_data->ignored_path_len) == 0)
|
159
174
|
{
|
160
|
-
|
161
|
-
if (line_number <= 0)
|
162
|
-
{
|
163
|
-
return;
|
164
|
-
}
|
165
|
-
|
166
|
-
VALUE rb_lines = rb_hash_aref(dd_cov_data->coverage, rb_str_source_file);
|
167
|
-
if (rb_lines == Qnil)
|
168
|
-
{
|
169
|
-
rb_lines = rb_hash_new();
|
170
|
-
rb_hash_aset(dd_cov_data->coverage, rb_str_source_file, rb_lines);
|
171
|
-
}
|
172
|
-
|
173
|
-
rb_hash_aset(rb_lines, INT2FIX(line_number), Qtrue);
|
175
|
+
return;
|
174
176
|
}
|
177
|
+
|
178
|
+
rb_hash_aset(dd_cov_data->coverage, filename, Qtrue);
|
175
179
|
}
|
176
180
|
|
177
181
|
static VALUE dd_cov_start(VALUE self)
|
178
182
|
{
|
179
|
-
// get current thread
|
180
|
-
VALUE thval = rb_thread_current();
|
181
183
|
|
182
|
-
|
183
|
-
|
184
|
+
struct dd_cov_data *dd_cov_data;
|
185
|
+
TypedData_Get_Struct(self, struct dd_cov_data, &dd_cov_data_type, dd_cov_data);
|
186
|
+
|
187
|
+
if (dd_cov_data->root_len == 0)
|
188
|
+
{
|
189
|
+
rb_raise(rb_eRuntimeError, "root is required");
|
190
|
+
}
|
191
|
+
|
192
|
+
if (dd_cov_data->threading_mode == SINGLE_THREADED_COVERAGE_MODE)
|
193
|
+
{
|
194
|
+
VALUE thval = rb_thread_current();
|
195
|
+
rb_thread_add_event_hook(thval, dd_cov_update_coverage, RUBY_EVENT_LINE, self);
|
196
|
+
dd_cov_data->th_covered = thval;
|
197
|
+
}
|
198
|
+
else
|
199
|
+
{
|
200
|
+
rb_add_event_hook(dd_cov_update_coverage, RUBY_EVENT_LINE, self);
|
201
|
+
}
|
184
202
|
|
185
203
|
return self;
|
186
204
|
}
|
187
205
|
|
188
206
|
static VALUE dd_cov_stop(VALUE self)
|
189
207
|
{
|
190
|
-
// get current thread
|
191
|
-
VALUE thval = rb_thread_current();
|
192
|
-
// remove event hook for the current thread
|
193
|
-
rb_thread_remove_event_hook(thval, dd_cov_update_line_coverage);
|
194
|
-
|
195
208
|
struct dd_cov_data *dd_cov_data;
|
196
209
|
TypedData_Get_Struct(self, struct dd_cov_data, &dd_cov_data_type, dd_cov_data);
|
197
210
|
|
198
|
-
|
211
|
+
if (dd_cov_data->threading_mode == SINGLE_THREADED_COVERAGE_MODE)
|
212
|
+
{
|
213
|
+
VALUE thval = rb_thread_current();
|
214
|
+
if (!rb_equal(thval, dd_cov_data->th_covered))
|
215
|
+
{
|
216
|
+
rb_raise(rb_eRuntimeError, "Coverage was not started by this thread");
|
217
|
+
}
|
218
|
+
|
219
|
+
rb_thread_remove_event_hook(dd_cov_data->th_covered, dd_cov_update_coverage);
|
220
|
+
dd_cov_data->th_covered = Qnil;
|
221
|
+
}
|
222
|
+
else
|
223
|
+
{
|
224
|
+
rb_remove_event_hook(dd_cov_update_coverage);
|
225
|
+
}
|
226
|
+
|
227
|
+
VALUE res = dd_cov_data->coverage;
|
199
228
|
|
200
229
|
dd_cov_data->coverage = rb_hash_new();
|
230
|
+
dd_cov_data->last_filename_ptr = 0;
|
201
231
|
|
202
|
-
return
|
232
|
+
return res;
|
203
233
|
}
|
204
234
|
|
205
235
|
void Init_datadog_cov(void)
|
@@ -87,7 +87,7 @@ module Datadog
|
|
87
87
|
return pattern if pattern == "*"
|
88
88
|
|
89
89
|
# if pattern ends with a slash then it matches everything deeply nested in this directory
|
90
|
-
pattern
|
90
|
+
pattern << "**" if pattern.end_with?(::File::SEPARATOR)
|
91
91
|
|
92
92
|
# if pattern doesn't start with a slash then it matches anywhere in the repository
|
93
93
|
if !pattern.start_with?(::File::SEPARATOR, "**#{::File::SEPARATOR}", "*#{::File::SEPARATOR}")
|
@@ -8,11 +8,11 @@ module Datadog
|
|
8
8
|
# Responsible for parsing a CODEOWNERS file
|
9
9
|
class Parser
|
10
10
|
DEFAULT_LOCATION = "CODEOWNERS"
|
11
|
-
POSSIBLE_CODEOWNERS_LOCATIONS = [
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
11
|
+
POSSIBLE_CODEOWNERS_LOCATIONS = %w[
|
12
|
+
CODEOWNERS
|
13
|
+
.github/CODEOWNERS
|
14
|
+
.gitlab/CODEOWNERS
|
15
|
+
docs/CODEOWNERS
|
16
16
|
].freeze
|
17
17
|
|
18
18
|
def initialize(root_file_path)
|
@@ -70,6 +70,17 @@ module Datadog
|
|
70
70
|
# Choose user defined TraceFlush or default to CI TraceFlush
|
71
71
|
settings.tracing.test_mode.trace_flush = settings.ci.trace_flush || CI::TestVisibility::Flush::Partial.new
|
72
72
|
|
73
|
+
# When timecop is present, Time.now is mocked and .now_without_mock_time is added on Time to
|
74
|
+
# get the current time without the mock.
|
75
|
+
if timecop?
|
76
|
+
settings.time_now_provider = -> do
|
77
|
+
Time.now_without_mock_time
|
78
|
+
rescue NoMethodError
|
79
|
+
# fallback to normal Time.now if Time.now_without_mock_time is not defined for any reason
|
80
|
+
Time.now
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
73
84
|
# startup logs are useless for CI visibility and create noise
|
74
85
|
settings.diagnostics.startup_logs.enabled = false
|
75
86
|
|
@@ -118,7 +129,8 @@ module Datadog
|
|
118
129
|
config_tags: custom_configuration_tags,
|
119
130
|
coverage_writer: coverage_writer,
|
120
131
|
enabled: settings.ci.enabled && settings.ci.itr_enabled,
|
121
|
-
bundle_location: settings.ci.itr_code_coverage_excluded_bundle_path
|
132
|
+
bundle_location: settings.ci.itr_code_coverage_excluded_bundle_path,
|
133
|
+
use_single_threaded_coverage: settings.ci.itr_code_coverage_use_single_threaded_mode
|
122
134
|
)
|
123
135
|
|
124
136
|
git_tree_uploader = Git::TreeUploader.new(api: test_visibility_api)
|
@@ -191,6 +203,10 @@ module Datadog
|
|
191
203
|
"Please make sure to set valid site in DD_SITE environment variable"
|
192
204
|
end
|
193
205
|
end
|
206
|
+
|
207
|
+
def timecop?
|
208
|
+
Gem.loaded_specs.key?("timecop") || defined?(Timecop)
|
209
|
+
end
|
194
210
|
end
|
195
211
|
end
|
196
212
|
end
|
@@ -76,6 +76,12 @@ module Datadog
|
|
76
76
|
end
|
77
77
|
end
|
78
78
|
|
79
|
+
option :itr_code_coverage_use_single_threaded_mode do |o|
|
80
|
+
o.type :bool
|
81
|
+
o.env CI::Ext::Settings::ENV_ITR_CODE_COVERAGE_USE_SINGLE_THREADED_MODE
|
82
|
+
o.default false
|
83
|
+
end
|
84
|
+
|
79
85
|
define_method(:instrument) do |integration_name, options = {}, &block|
|
80
86
|
return unless enabled
|
81
87
|
|
@@ -187,7 +187,7 @@ module Datadog
|
|
187
187
|
def ok?(result, strict)
|
188
188
|
# in minor update in Cucumber 9.2.0, the arity of the `ok?` method changed
|
189
189
|
parameters = result.method(:ok?).parameters
|
190
|
-
if parameters == [[
|
190
|
+
if parameters == [%i[opt be_strict]]
|
191
191
|
result.ok?(strict)
|
192
192
|
else
|
193
193
|
result.ok?(strict: strict)
|
@@ -23,7 +23,7 @@ module Datadog
|
|
23
23
|
test_name = full_description.strip
|
24
24
|
if metadata[:description].empty?
|
25
25
|
# for unnamed it blocks this appends something like "example at ./spec/some_spec.rb:10"
|
26
|
-
test_name
|
26
|
+
test_name << " #{description}"
|
27
27
|
end
|
28
28
|
|
29
29
|
test_suite_description = fetch_top_level_example_group[:description]
|
@@ -33,7 +33,7 @@ module Datadog
|
|
33
33
|
test_name = test_name.sub(test_suite_description, "").strip
|
34
34
|
|
35
35
|
if ci_queue?
|
36
|
-
suite_name
|
36
|
+
suite_name = "#{suite_name} (ci-queue running example [#{test_name}])"
|
37
37
|
test_suite_span = CI.start_test_suite(suite_name)
|
38
38
|
end
|
39
39
|
|
@@ -83,9 +83,12 @@ module Datadog
|
|
83
83
|
private
|
84
84
|
|
85
85
|
def fetch_top_level_example_group
|
86
|
-
|
86
|
+
example_group = metadata[:example_group]
|
87
|
+
parent_example_group = example_group[:parent_example_group]
|
87
88
|
|
88
|
-
|
89
|
+
return example_group unless parent_example_group
|
90
|
+
|
91
|
+
res = parent_example_group
|
89
92
|
while (parent = res[:parent_example_group])
|
90
93
|
res = parent
|
91
94
|
end
|
@@ -75,12 +75,12 @@ module Datadog
|
|
75
75
|
end
|
76
76
|
|
77
77
|
def git_commit_author_name
|
78
|
-
name,
|
78
|
+
name, _email = extract_name_email
|
79
79
|
name
|
80
80
|
end
|
81
81
|
|
82
82
|
def git_commit_author_email
|
83
|
-
|
83
|
+
_name, email = extract_name_email
|
84
84
|
email
|
85
85
|
end
|
86
86
|
|
@@ -23,10 +23,7 @@ module Datadog
|
|
23
23
|
TAG_NODE_NAME = "ci.node.name"
|
24
24
|
TAG_CI_ENV_VARS = "_dd.ci.env_vars"
|
25
25
|
|
26
|
-
POSSIBLE_BUNDLE_LOCATIONS = [
|
27
|
-
"vendor/bundle",
|
28
|
-
".bundle"
|
29
|
-
].freeze
|
26
|
+
POSSIBLE_BUNDLE_LOCATIONS = %w[vendor/bundle .bundle].freeze
|
30
27
|
|
31
28
|
module_function
|
32
29
|
|
@@ -13,15 +13,16 @@ module Datadog
|
|
13
13
|
ENV_ITR_ENABLED = "DD_CIVISIBILITY_ITR_ENABLED"
|
14
14
|
ENV_GIT_METADATA_UPLOAD_ENABLED = "DD_CIVISIBILITY_GIT_METADATA_UPLOAD_ENABLED"
|
15
15
|
ENV_ITR_CODE_COVERAGE_EXCLUDED_BUNDLE_PATH = "DD_CIVISIBILITY_ITR_CODE_COVERAGE_EXCLUDED_BUNDLE_PATH"
|
16
|
+
ENV_ITR_CODE_COVERAGE_USE_SINGLE_THREADED_MODE = "DD_CIVISIBILITY_ITR_CODE_COVERAGE_USE_SINGLE_THREADED_MODE"
|
16
17
|
|
17
18
|
# Source: https://docs.datadoghq.com/getting_started/site/
|
18
|
-
DD_SITE_ALLOWLIST = [
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
19
|
+
DD_SITE_ALLOWLIST = %w[
|
20
|
+
datadoghq.com
|
21
|
+
us3.datadoghq.com
|
22
|
+
us5.datadoghq.com
|
23
|
+
datadoghq.eu
|
24
|
+
ddog-gov.com
|
25
|
+
ap1.datadoghq.com
|
25
26
|
].freeze
|
26
27
|
end
|
27
28
|
end
|
@@ -21,7 +21,7 @@ module Datadog
|
|
21
21
|
def valid?
|
22
22
|
valid = true
|
23
23
|
|
24
|
-
[
|
24
|
+
%i[test_id test_suite_id test_session_id coverage].each do |key|
|
25
25
|
next unless send(key).nil?
|
26
26
|
|
27
27
|
Datadog.logger.warn("citestcov event is invalid: [#{key}] is nil. Event: #{self}")
|
@@ -22,6 +22,8 @@ module Datadog
|
|
22
22
|
DEFAULT_BUFFER_MAX_SIZE = 10_000
|
23
23
|
DEFAULT_SHUTDOWN_TIMEOUT = 60
|
24
24
|
|
25
|
+
DEFAULT_INTERVAL = 3
|
26
|
+
|
25
27
|
def initialize(transport:, options: {})
|
26
28
|
@transport = transport
|
27
29
|
|
@@ -32,7 +34,7 @@ module Datadog
|
|
32
34
|
self.fork_policy = Core::Workers::Async::Thread::FORK_POLICY_RESTART
|
33
35
|
|
34
36
|
# Workers::IntervalLoop settings
|
35
|
-
self.loop_base_interval = options[:interval]
|
37
|
+
self.loop_base_interval = options[:interval] || DEFAULT_INTERVAL
|
36
38
|
self.loop_back_off_ratio = options[:back_off_ratio] if options.key?(:back_off_ratio)
|
37
39
|
self.loop_back_off_max = options[:back_off_max] if options.key?(:back_off_max)
|
38
40
|
|
@@ -31,7 +31,8 @@ module Datadog
|
|
31
31
|
api: nil,
|
32
32
|
coverage_writer: nil,
|
33
33
|
enabled: false,
|
34
|
-
bundle_location: nil
|
34
|
+
bundle_location: nil,
|
35
|
+
use_single_threaded_coverage: false
|
35
36
|
)
|
36
37
|
@enabled = enabled
|
37
38
|
@api = api
|
@@ -43,6 +44,7 @@ module Datadog
|
|
43
44
|
else
|
44
45
|
bundle_location
|
45
46
|
end
|
47
|
+
@use_single_threaded_coverage = use_single_threaded_coverage
|
46
48
|
|
47
49
|
@test_skipping_enabled = false
|
48
50
|
@code_coverage_enabled = false
|
@@ -186,12 +188,15 @@ module Datadog
|
|
186
188
|
def coverage_collector
|
187
189
|
Thread.current[:dd_coverage_collector] ||= Coverage::DDCov.new(
|
188
190
|
root: Git::LocalRepository.root,
|
189
|
-
ignored_path: @bundle_location
|
191
|
+
ignored_path: @bundle_location,
|
192
|
+
threading_mode: code_coverage_mode
|
190
193
|
)
|
191
194
|
end
|
192
195
|
|
193
196
|
def load_datadog_cov!
|
194
197
|
require "datadog_cov.#{RUBY_VERSION}_#{RUBY_PLATFORM}"
|
198
|
+
|
199
|
+
Datadog.logger.debug("Loaded Datadog code coverage collector, using coverage mode: #{code_coverage_mode}")
|
195
200
|
rescue LoadError => e
|
196
201
|
Datadog.logger.error("Failed to load coverage collector: #{e}. Code coverage will not be collected.")
|
197
202
|
|
@@ -222,6 +227,10 @@ module Datadog
|
|
222
227
|
Datadog.logger.debug { "Found #{@skippable_tests.count} skippable tests." }
|
223
228
|
Datadog.logger.debug { "ITR correlation ID: #{@correlation_id}" }
|
224
229
|
end
|
230
|
+
|
231
|
+
def code_coverage_mode
|
232
|
+
@use_single_threaded_coverage ? :single : :multi
|
233
|
+
end
|
225
234
|
end
|
226
235
|
end
|
227
236
|
end
|
@@ -20,13 +20,7 @@ module Datadog
|
|
20
20
|
"type" => "span_type"
|
21
21
|
].freeze
|
22
22
|
|
23
|
-
REQUIRED_FIELDS = [
|
24
|
-
"error",
|
25
|
-
"name",
|
26
|
-
"resource",
|
27
|
-
"start",
|
28
|
-
"duration"
|
29
|
-
].freeze
|
23
|
+
REQUIRED_FIELDS = %w[error name resource start duration].freeze
|
30
24
|
|
31
25
|
attr_reader :trace, :span, :meta, :options
|
32
26
|
|
@@ -7,11 +7,11 @@ module Datadog
|
|
7
7
|
module TestVisibility
|
8
8
|
module Serializers
|
9
9
|
class Span < Base
|
10
|
-
CONTENT_FIELDS = ([
|
10
|
+
CONTENT_FIELDS = (%w[trace_id span_id parent_id] + Base::CONTENT_FIELDS).freeze
|
11
11
|
|
12
12
|
CONTENT_MAP_SIZE = calculate_content_map_size(CONTENT_FIELDS)
|
13
13
|
|
14
|
-
REQUIRED_FIELDS = ([
|
14
|
+
REQUIRED_FIELDS = (%w[trace_id span_id] + Base::REQUIRED_FIELDS).freeze
|
15
15
|
|
16
16
|
def content_fields
|
17
17
|
CONTENT_FIELDS
|
@@ -8,11 +8,11 @@ module Datadog
|
|
8
8
|
module TestVisibility
|
9
9
|
module Serializers
|
10
10
|
class TestModule < Base
|
11
|
-
CONTENT_FIELDS = ([
|
11
|
+
CONTENT_FIELDS = (%w[test_session_id test_module_id] + Base::CONTENT_FIELDS).freeze
|
12
12
|
|
13
13
|
CONTENT_MAP_SIZE = calculate_content_map_size(CONTENT_FIELDS)
|
14
14
|
|
15
|
-
REQUIRED_FIELDS = ([
|
15
|
+
REQUIRED_FIELDS = (%w[test_session_id test_module_id] + Base::REQUIRED_FIELDS).freeze
|
16
16
|
|
17
17
|
def content_fields
|
18
18
|
CONTENT_FIELDS
|
@@ -8,11 +8,11 @@ module Datadog
|
|
8
8
|
module TestVisibility
|
9
9
|
module Serializers
|
10
10
|
class TestSession < Base
|
11
|
-
CONTENT_FIELDS = ([
|
11
|
+
CONTENT_FIELDS = (%w[test_session_id] + Base::CONTENT_FIELDS).freeze
|
12
12
|
|
13
13
|
CONTENT_MAP_SIZE = calculate_content_map_size(CONTENT_FIELDS)
|
14
14
|
|
15
|
-
REQUIRED_FIELDS = ([
|
15
|
+
REQUIRED_FIELDS = (%w[test_session_id] + Base::REQUIRED_FIELDS).freeze
|
16
16
|
|
17
17
|
def content_fields
|
18
18
|
CONTENT_FIELDS
|
@@ -8,11 +8,11 @@ module Datadog
|
|
8
8
|
module TestVisibility
|
9
9
|
module Serializers
|
10
10
|
class TestSuite < Base
|
11
|
-
CONTENT_FIELDS = ([
|
11
|
+
CONTENT_FIELDS = (%w[test_session_id test_module_id test_suite_id] + Base::CONTENT_FIELDS).freeze
|
12
12
|
|
13
13
|
CONTENT_MAP_SIZE = calculate_content_map_size(CONTENT_FIELDS)
|
14
14
|
|
15
|
-
REQUIRED_FIELDS = ([
|
15
|
+
REQUIRED_FIELDS = (%w[test_session_id test_module_id test_suite_id] + Base::REQUIRED_FIELDS).freeze
|
16
16
|
|
17
17
|
def content_fields
|
18
18
|
CONTENT_FIELDS
|
@@ -8,11 +8,11 @@ module Datadog
|
|
8
8
|
module TestVisibility
|
9
9
|
module Serializers
|
10
10
|
class TestV1 < Base
|
11
|
-
CONTENT_FIELDS = ([
|
11
|
+
CONTENT_FIELDS = (%w[trace_id span_id] + Base::CONTENT_FIELDS).freeze
|
12
12
|
|
13
13
|
CONTENT_MAP_SIZE = calculate_content_map_size(CONTENT_FIELDS)
|
14
14
|
|
15
|
-
REQUIRED_FIELDS = ([
|
15
|
+
REQUIRED_FIELDS = (%w[trace_id span_id] + Base::REQUIRED_FIELDS).freeze
|
16
16
|
|
17
17
|
def content_fields
|
18
18
|
CONTENT_FIELDS
|
@@ -8,15 +8,15 @@ module Datadog
|
|
8
8
|
module TestVisibility
|
9
9
|
module Serializers
|
10
10
|
class TestV2 < TestV1
|
11
|
-
CONTENT_FIELDS = ([
|
11
|
+
CONTENT_FIELDS = (%w[test_session_id test_module_id test_suite_id] + TestV1::CONTENT_FIELDS).freeze
|
12
12
|
|
13
|
-
CONTENT_FIELDS_WITH_ITR_CORRELATION_ID = (CONTENT_FIELDS + [
|
13
|
+
CONTENT_FIELDS_WITH_ITR_CORRELATION_ID = (CONTENT_FIELDS + %w[itr_correlation_id]).freeze
|
14
14
|
|
15
15
|
CONTENT_MAP_SIZE = calculate_content_map_size(CONTENT_FIELDS)
|
16
16
|
|
17
17
|
CONTENT_MAP_SIZE_WITH_ITR_CORRELATION_ID = calculate_content_map_size(CONTENT_FIELDS_WITH_ITR_CORRELATION_ID)
|
18
18
|
|
19
|
-
REQUIRED_FIELDS = ([
|
19
|
+
REQUIRED_FIELDS = (%w[test_session_id test_module_id test_suite_id] + TestV1::REQUIRED_FIELDS).freeze
|
20
20
|
|
21
21
|
def content_fields
|
22
22
|
return CONTENT_FIELDS if itr_correlation_id.nil?
|
data/lib/datadog/ci/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: datadog-ci
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Datadog, Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-06-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: datadog
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 2.0
|
19
|
+
version: '2.0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 2.0
|
26
|
+
version: '2.0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: msgpack
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -201,7 +201,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
201
201
|
- !ruby/object:Gem::Version
|
202
202
|
version: 2.0.0
|
203
203
|
requirements: []
|
204
|
-
rubygems_version: 3.
|
204
|
+
rubygems_version: 3.5.9
|
205
205
|
signing_key:
|
206
206
|
specification_version: 4
|
207
207
|
summary: Datadog CI visibility for your ruby application
|