8
8
import datadog .communication .BackendApi ;
9
9
import datadog .communication .http .OkHttpUtils ;
10
10
import datadog .trace .api .civisibility .config .Configurations ;
11
+ import datadog .trace .api .civisibility .config .TestFQN ;
11
12
import datadog .trace .api .civisibility .config .TestIdentifier ;
12
13
import datadog .trace .api .civisibility .config .TestMetadata ;
13
14
import datadog .trace .api .civisibility .telemetry .CiVisibilityCountMetric ;
@@ -54,6 +55,7 @@ public class ConfigurationApiImpl implements ConfigurationApi {
54
55
private static final String CHANGED_FILES_URI = "ci/tests/diffs" ;
55
56
private static final String FLAKY_TESTS_URI = "ci/libraries/tests/flaky" ;
56
57
private static final String KNOWN_TESTS_URI = "ci/libraries/tests" ;
58
+ private static final String TEST_MANAGEMENT_TESTS_URI = "test/libraries/test-management/tests" ;
57
59
58
60
private final BackendApi backendApi ;
59
61
private final CiVisibilityMetricCollector metricCollector ;
@@ -63,6 +65,7 @@ public class ConfigurationApiImpl implements ConfigurationApi {
63
65
private final JsonAdapter <EnvelopeDto <CiVisibilitySettings >> settingsResponseAdapter ;
64
66
private final JsonAdapter <MultiEnvelopeDto <TestIdentifierJson >> testIdentifiersResponseAdapter ;
65
67
private final JsonAdapter <EnvelopeDto <KnownTestsDto >> testFullNamesResponseAdapter ;
68
+ private final JsonAdapter <EnvelopeDto <TestManagementTestsDto >> testManagementTestsResponseAdapter ;
66
69
private final JsonAdapter <EnvelopeDto <ChangedFiles >> changedFilesResponseAdapter ;
67
70
68
71
public ConfigurationApiImpl (BackendApi backendApi , CiVisibilityMetricCollector metricCollector ) {
@@ -105,6 +108,11 @@ public ConfigurationApiImpl(BackendApi backendApi, CiVisibilityMetricCollector m
105
108
ConfigurationApiImpl .class , EnvelopeDto .class , KnownTestsDto .class );
106
109
testFullNamesResponseAdapter = moshi .adapter (testFullNamesResponseType );
107
110
111
+ ParameterizedType testManagementTestsResponseType =
112
+ Types .newParameterizedTypeWithOwner (
113
+ ConfigurationApiImpl .class , EnvelopeDto .class , TestManagementTestsDto .class );
114
+ testManagementTestsResponseAdapter = moshi .adapter (testManagementTestsResponseType );
115
+
108
116
ParameterizedType changedFilesResponseAdapterType =
109
117
Types .newParameterizedTypeWithOwner (
110
118
ConfigurationApiImpl .class , EnvelopeDto .class , ChangedFiles .class );
@@ -202,8 +210,8 @@ public SkippableTests getSkippableTests(TracerEnvironment tracerEnvironment) thr
202
210
}
203
211
204
212
@ Override
205
- public Map <String , Collection <TestIdentifier >> getFlakyTestsByModule (
206
- TracerEnvironment tracerEnvironment ) throws IOException {
213
+ public Map <String , Collection <TestFQN >> getFlakyTestsByModule (TracerEnvironment tracerEnvironment )
214
+ throws IOException {
207
215
OkHttpUtils .CustomListener telemetryListener =
208
216
new TelemetryListener .Builder (metricCollector )
209
217
.requestCount (CiVisibilityCountMetric .FLAKY_TESTS_REQUEST )
@@ -231,15 +239,15 @@ public Map<String, Collection<TestIdentifier>> getFlakyTestsByModule(
231
239
Configurations requestConf = tracerEnvironment .getConfigurations ();
232
240
233
241
int flakyTestsCount = 0 ;
234
- Map <String , Collection <TestIdentifier >> testIdentifiers = new HashMap <>();
242
+ Map <String , Collection <TestFQN >> testIdentifiers = new HashMap <>();
235
243
for (DataDto <TestIdentifierJson > dataDto : response ) {
236
244
TestIdentifierJson testIdentifierJson = dataDto .getAttributes ();
237
245
Configurations conf = testIdentifierJson .getConfigurations ();
238
246
String moduleName =
239
247
(conf != null && conf .getTestBundle () != null ? conf : requestConf ).getTestBundle ();
240
248
testIdentifiers
241
249
.computeIfAbsent (moduleName , k -> new HashSet <>())
242
- .add (testIdentifierJson .toTestIdentifier ());
250
+ .add (testIdentifierJson .toTestIdentifier (). toFQN () );
243
251
flakyTestsCount ++;
244
252
}
245
253
@@ -249,8 +257,8 @@ public Map<String, Collection<TestIdentifier>> getFlakyTestsByModule(
249
257
250
258
@ Nullable
251
259
@ Override
252
- public Map <String , Collection <TestIdentifier >> getKnownTestsByModule (
253
- TracerEnvironment tracerEnvironment ) throws IOException {
260
+ public Map <String , Collection <TestFQN >> getKnownTestsByModule (TracerEnvironment tracerEnvironment )
261
+ throws IOException {
254
262
OkHttpUtils .CustomListener telemetryListener =
255
263
new TelemetryListener .Builder (metricCollector )
256
264
.requestCount (CiVisibilityCountMetric .KNOWN_TESTS_REQUEST )
@@ -276,10 +284,10 @@ public Map<String, Collection<TestIdentifier>> getKnownTestsByModule(
276
284
return parseTestIdentifiers (knownTests );
277
285
}
278
286
279
- private Map <String , Collection <TestIdentifier >> parseTestIdentifiers (KnownTestsDto knownTests ) {
287
+ private Map <String , Collection <TestFQN >> parseTestIdentifiers (KnownTestsDto knownTests ) {
280
288
int knownTestsCount = 0 ;
281
289
282
- Map <String , Collection <TestIdentifier >> testIdentifiers = new HashMap <>();
290
+ Map <String , Collection <TestFQN >> testIdentifiers = new HashMap <>();
283
291
for (Map .Entry <String , Map <String , List <String >>> e : knownTests .tests .entrySet ()) {
284
292
String moduleName = e .getKey ();
285
293
Map <String , List <String >> testsBySuiteName = e .getValue ();
@@ -292,7 +300,7 @@ private Map<String, Collection<TestIdentifier>> parseTestIdentifiers(KnownTestsD
292
300
for (String testName : testNames ) {
293
301
testIdentifiers
294
302
.computeIfAbsent (moduleName , k -> new HashSet <>())
295
- .add (new TestIdentifier (suiteName , testName , null ));
303
+ .add (new TestFQN (suiteName , testName ));
296
304
}
297
305
}
298
306
}
@@ -309,6 +317,90 @@ private Map<String, Collection<TestIdentifier>> parseTestIdentifiers(KnownTestsD
309
317
: null ;
310
318
}
311
319
320
+ @ Override
321
+ public Map <TestSetting , Map <String , Collection <TestFQN >>> getTestManagementTestsByModule (
322
+ TracerEnvironment tracerEnvironment ) throws IOException {
323
+ OkHttpUtils .CustomListener telemetryListener =
324
+ new TelemetryListener .Builder (metricCollector )
325
+ .requestCount (CiVisibilityCountMetric .TEST_MANAGEMENT_TESTS_REQUEST )
326
+ .requestErrors (CiVisibilityCountMetric .TEST_MANAGEMENT_TESTS_REQUEST_ERRORS )
327
+ .requestDuration (CiVisibilityDistributionMetric .TEST_MANAGEMENT_TESTS_REQUEST_MS )
328
+ .responseBytes (CiVisibilityDistributionMetric .TEST_MANAGEMENT_TESTS_RESPONSE_BYTES )
329
+ .build ();
330
+
331
+ String uuid = uuidGenerator .get ();
332
+ EnvelopeDto <TracerEnvironment > request =
333
+ new EnvelopeDto <>(new DataDto <>(uuid , "ci_app_libraries_tests_request" , tracerEnvironment ));
334
+ String json = requestAdapter .toJson (request );
335
+ RequestBody requestBody = RequestBody .create (JSON , json );
336
+ TestManagementTestsDto testManagementTestsDto =
337
+ backendApi .post (
338
+ TEST_MANAGEMENT_TESTS_URI ,
339
+ requestBody ,
340
+ is ->
341
+ testManagementTestsResponseAdapter .fromJson (Okio .buffer (Okio .source (is )))
342
+ .data
343
+ .attributes ,
344
+ telemetryListener ,
345
+ false );
346
+
347
+ return parseTestManagementTests (testManagementTestsDto );
348
+ }
349
+
350
+ private Map <TestSetting , Map <String , Collection <TestFQN >>> parseTestManagementTests (
351
+ TestManagementTestsDto testsManagementTestsDto ) {
352
+ int testManagementTestsCount = 0 ;
353
+
354
+ Map <String , Collection <TestFQN >> quarantinedTestsByModule = new HashMap <>();
355
+ Map <String , Collection <TestFQN >> disabledTestsByModule = new HashMap <>();
356
+ Map <String , Collection <TestFQN >> attemptToFixTestsByModule = new HashMap <>();
357
+
358
+ for (Map .Entry <String , TestManagementTestsDto .Suites > e :
359
+ testsManagementTestsDto .getModules ().entrySet ()) {
360
+ String moduleName = e .getKey ();
361
+ Map <String , TestManagementTestsDto .Tests > testsBySuiteName = e .getValue ().getSuites ();
362
+
363
+ for (Map .Entry <String , TestManagementTestsDto .Tests > se : testsBySuiteName .entrySet ()) {
364
+ String suiteName = se .getKey ();
365
+ Map <String , TestManagementTestsDto .Properties > tests = se .getValue ().getTests ();
366
+
367
+ testManagementTestsCount += tests .size ();
368
+
369
+ for (Map .Entry <String , TestManagementTestsDto .Properties > te : tests .entrySet ()) {
370
+ String testName = te .getKey ();
371
+ TestManagementTestsDto .Properties properties = te .getValue ();
372
+ if (properties .isQuarantined ()) {
373
+ quarantinedTestsByModule
374
+ .computeIfAbsent (moduleName , k -> new HashSet <>())
375
+ .add (new TestFQN (suiteName , testName ));
376
+ }
377
+ if (properties .isDisabled ()) {
378
+ disabledTestsByModule
379
+ .computeIfAbsent (moduleName , k -> new HashSet <>())
380
+ .add (new TestFQN (suiteName , testName ));
381
+ }
382
+ if (properties .isAttemptToFix ()) {
383
+ attemptToFixTestsByModule
384
+ .computeIfAbsent (moduleName , k -> new HashSet <>())
385
+ .add (new TestFQN (suiteName , testName ));
386
+ }
387
+ }
388
+ }
389
+ }
390
+
391
+ Map <TestSetting , Map <String , Collection <TestFQN >>> testsByTypeByModule = new HashMap <>();
392
+ testsByTypeByModule .put (TestSetting .QUARANTINED , quarantinedTestsByModule );
393
+ testsByTypeByModule .put (TestSetting .DISABLED , disabledTestsByModule );
394
+ testsByTypeByModule .put (TestSetting .ATTEMPT_TO_FIX , attemptToFixTestsByModule );
395
+
396
+ LOGGER .debug ("Received {} test management tests in total" , testManagementTestsCount );
397
+ metricCollector .add (
398
+ CiVisibilityDistributionMetric .TEST_MANAGEMENT_TESTS_RESPONSE_TESTS ,
399
+ testManagementTestsCount );
400
+
401
+ return testsByTypeByModule ;
402
+ }
403
+
312
404
@ Override
313
405
public ChangedFiles getChangedFiles (TracerEnvironment tracerEnvironment ) throws IOException {
314
406
OkHttpUtils .CustomListener telemetryListener =
@@ -427,4 +519,66 @@ private KnownTestsDto(Map<String, Map<String, List<String>>> tests) {
427
519
this .tests = tests ;
428
520
}
429
521
}
522
+
523
+ private static final class TestManagementTestsDto {
524
+ private static final class Properties {
525
+ private final Map <String , Boolean > properties ;
526
+
527
+ private Properties (Map <String , Boolean > properties ) {
528
+ this .properties = properties ;
529
+ }
530
+
531
+ public Boolean isQuarantined () {
532
+ return properties != null
533
+ ? properties .getOrDefault (TestSetting .QUARANTINED .asString (), false )
534
+ : false ;
535
+ }
536
+
537
+ public Boolean isDisabled () {
538
+ return properties != null
539
+ ? properties .getOrDefault (TestSetting .DISABLED .asString (), false )
540
+ : false ;
541
+ }
542
+
543
+ public Boolean isAttemptToFix () {
544
+ return properties != null
545
+ ? properties .getOrDefault (TestSetting .ATTEMPT_TO_FIX .asString (), false )
546
+ : false ;
547
+ }
548
+ }
549
+
550
+ private static final class Tests {
551
+ private final Map <String , Properties > tests ;
552
+
553
+ private Tests (Map <String , Properties > tests ) {
554
+ this .tests = tests ;
555
+ }
556
+
557
+ public Map <String , Properties > getTests () {
558
+ return tests != null ? tests : Collections .emptyMap ();
559
+ }
560
+ }
561
+
562
+ private static final class Suites {
563
+ private final Map <String , Tests > suites ;
564
+
565
+ private Suites (Map <String , Tests > suites ) {
566
+ this .suites = suites ;
567
+ }
568
+
569
+ public Map <String , Tests > getSuites () {
570
+ return suites != null ? suites : Collections .emptyMap ();
571
+ }
572
+ }
573
+
574
+ private final Map <String , Suites > modules ;
575
+
576
+ private TestManagementTestsDto (Map <String , Suites > modules ) {
577
+ this .modules = modules ;
578
+ }
579
+
580
+ public Map <String , Suites > getModules () {
581
+ return modules != null ? modules : Collections .emptyMap ();
582
+ }
583
+ }
430
584
}
0 commit comments