Skip to content

Commit 0c7e4ea

Browse files
Optimize in-progress tests and suites lookup (DataDog#6728)
1 parent fa3cf4d commit 0c7e4ea

36 files changed

Lines changed: 605 additions & 575 deletions

File tree

‎dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/CiVisibilitySystem.java‎

Lines changed: 37 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import datadog.communication.ddagent.TracerVersion;
55
import datadog.trace.api.Config;
66
import datadog.trace.api.civisibility.CIVisibility;
7+
import datadog.trace.api.civisibility.DDTest;
8+
import datadog.trace.api.civisibility.DDTestSuite;
79
import datadog.trace.api.civisibility.InstrumentationBridge;
810
import datadog.trace.api.civisibility.config.ModuleExecutionSettings;
911
import datadog.trace.api.civisibility.coverage.CoverageBridge;
@@ -13,6 +15,7 @@
1315
import datadog.trace.api.civisibility.telemetry.CiVisibilityMetricCollector;
1416
import datadog.trace.api.civisibility.telemetry.NoOpMetricCollector;
1517
import datadog.trace.api.git.GitInfoProvider;
18+
import datadog.trace.bootstrap.ContextStore;
1619
import datadog.trace.civisibility.config.JvmInfo;
1720
import datadog.trace.civisibility.coverage.instrumentation.CoverageClassTransformer;
1821
import datadog.trace.civisibility.coverage.instrumentation.CoverageInstrumentationFilter;
@@ -30,6 +33,7 @@
3033
import datadog.trace.civisibility.events.TestEventsHandlerImpl;
3134
import datadog.trace.civisibility.ipc.SignalServer;
3235
import datadog.trace.civisibility.telemetry.CiVisibilityMetricCollectorImpl;
36+
import datadog.trace.civisibility.utils.ConcurrentHashMapContextStore;
3337
import datadog.trace.civisibility.utils.ProcessHierarchyUtils;
3438
import datadog.trace.util.throwable.FatalAgentMisconfigurationError;
3539
import java.lang.instrument.Instrumentation;
@@ -94,7 +98,7 @@ public static void start(Instrumentation inst, SharedCommunicationObjects sco) {
9498
}
9599

96100
InstrumentationBridge.registerTestEventsHandlerFactory(
97-
testEventsHandlerFactory(services, repoServices, executionSettings));
101+
new TestEventsHandlerFactory(services, repoServices, executionSettings));
98102
CoverageBridge.registerCoverageProbeStoreRegistry(services.coverageProbeStoreFactory);
99103
}
100104
}
@@ -138,24 +142,43 @@ public <U> BuildEventsHandler<U> create() {
138142
};
139143
}
140144

141-
private static TestEventsHandler.Factory testEventsHandlerFactory(
142-
CiVisibilityServices services,
143-
CiVisibilityRepoServices repoServices,
144-
ModuleExecutionSettings executionSettings) {
145-
TestFrameworkSession.Factory sessionFactory;
146-
if (ProcessHierarchyUtils.isChild()) {
147-
sessionFactory = childTestFrameworkSessionFactory(services, repoServices, executionSettings);
148-
} else {
149-
sessionFactory =
150-
headlessTestFrameworkEssionFactory(services, repoServices, executionSettings);
145+
private static final class TestEventsHandlerFactory implements TestEventsHandler.Factory {
146+
private final CiVisibilityServices services;
147+
private final CiVisibilityRepoServices repoServices;
148+
private final TestFrameworkSession.Factory sessionFactory;
149+
150+
private TestEventsHandlerFactory(
151+
CiVisibilityServices services,
152+
CiVisibilityRepoServices repoServices,
153+
ModuleExecutionSettings executionSettings) {
154+
this.services = services;
155+
this.repoServices = repoServices;
156+
if (ProcessHierarchyUtils.isChild()) {
157+
sessionFactory =
158+
childTestFrameworkSessionFactory(services, repoServices, executionSettings);
159+
} else {
160+
sessionFactory =
161+
headlessTestFrameworkEssionFactory(services, repoServices, executionSettings);
162+
}
151163
}
152164

153-
return (String component) -> {
165+
@Override
166+
public <SuiteKey, TestKey> TestEventsHandler<SuiteKey, TestKey> create(String component) {
167+
return create(
168+
component, new ConcurrentHashMapContextStore<>(), new ConcurrentHashMapContextStore<>());
169+
}
170+
171+
@Override
172+
public <SuiteKey, TestKey> TestEventsHandler<SuiteKey, TestKey> create(
173+
String component,
174+
ContextStore<SuiteKey, DDTestSuite> suiteStore,
175+
ContextStore<TestKey, DDTest> testStore) {
154176
TestFrameworkSession testSession =
155177
sessionFactory.startSession(repoServices.moduleName, component, null);
156178
TestFrameworkModule testModule = testSession.testModuleStart(repoServices.moduleName, null);
157-
return new TestEventsHandlerImpl(services.metricCollector, testSession, testModule);
158-
};
179+
return new TestEventsHandlerImpl<>(
180+
services.metricCollector, testSession, testModule, suiteStore, testStore);
181+
}
159182
}
160183

161184
private static BuildSystemSession.Factory buildSystemSessionFactory(

‎dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/events/TestEventsHandlerImpl.java‎

Lines changed: 32 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@
33
import static datadog.trace.util.Strings.toJson;
44

55
import datadog.trace.api.DisableTestTrace;
6+
import datadog.trace.api.civisibility.DDTest;
7+
import datadog.trace.api.civisibility.DDTestSuite;
68
import datadog.trace.api.civisibility.InstrumentationBridge;
79
import datadog.trace.api.civisibility.config.TestIdentifier;
8-
import datadog.trace.api.civisibility.events.TestDescriptor;
910
import datadog.trace.api.civisibility.events.TestEventsHandler;
10-
import datadog.trace.api.civisibility.events.TestSuiteDescriptor;
1111
import datadog.trace.api.civisibility.retry.TestRetryPolicy;
1212
import datadog.trace.api.civisibility.telemetry.CiVisibilityCountMetric;
1313
import datadog.trace.api.civisibility.telemetry.CiVisibilityMetricCollector;
@@ -19,7 +19,6 @@
1919
import datadog.trace.civisibility.domain.TestFrameworkSession;
2020
import datadog.trace.civisibility.domain.TestImpl;
2121
import datadog.trace.civisibility.domain.TestSuiteImpl;
22-
import datadog.trace.civisibility.utils.ConcurrentHashMapContextStore;
2322
import java.lang.reflect.Method;
2423
import java.util.Collection;
2524
import java.util.Collections;
@@ -29,31 +28,33 @@
2928
import org.slf4j.Logger;
3029
import org.slf4j.LoggerFactory;
3130

32-
public class TestEventsHandlerImpl implements TestEventsHandler {
31+
public class TestEventsHandlerImpl<SuiteKey, TestKey>
32+
implements TestEventsHandler<SuiteKey, TestKey> {
3333

3434
private static final Logger log = LoggerFactory.getLogger(TestEventsHandlerImpl.class);
3535

3636
private final CiVisibilityMetricCollector metricCollector;
3737
private final TestFrameworkSession testSession;
3838
private final TestFrameworkModule testModule;
39-
40-
private final ContextStore<TestSuiteDescriptor, TestSuiteImpl> inProgressTestSuites =
41-
new ConcurrentHashMapContextStore<>();
42-
43-
private final ContextStore<TestDescriptor, TestImpl> inProgressTests =
44-
new ConcurrentHashMapContextStore<>();
39+
private final ContextStore<SuiteKey, TestSuiteImpl> inProgressTestSuites;
40+
private final ContextStore<TestKey, TestImpl> inProgressTests;
4541

4642
public TestEventsHandlerImpl(
4743
CiVisibilityMetricCollector metricCollector,
4844
TestFrameworkSession testSession,
49-
TestFrameworkModule testModule) {
45+
TestFrameworkModule testModule,
46+
ContextStore<SuiteKey, DDTestSuite> suiteStore,
47+
ContextStore<TestKey, DDTest> testStore) {
5048
this.metricCollector = metricCollector;
5149
this.testSession = testSession;
5250
this.testModule = testModule;
51+
this.inProgressTestSuites = (ContextStore) suiteStore;
52+
this.inProgressTests = (ContextStore) testStore;
5353
}
5454

5555
@Override
5656
public void onTestSuiteStart(
57+
final SuiteKey descriptor,
5758
final String testSuiteName,
5859
final @Nullable String testFramework,
5960
final @Nullable String testFrameworkVersion,
@@ -79,55 +80,45 @@ public void onTestSuiteStart(
7980
Tags.TEST_TRAITS, toJson(Collections.singletonMap("category", toJson(categories)), true));
8081
}
8182

82-
TestSuiteDescriptor descriptor = new TestSuiteDescriptor(testSuiteName, testClass);
8383
inProgressTestSuites.put(descriptor, testSuite);
8484
}
8585

8686
@Override
87-
public void onTestSuiteFinish(final String testSuiteName, final @Nullable Class<?> testClass) {
88-
if (skipTrace(testClass)) {
87+
public void onTestSuiteFinish(SuiteKey descriptor) {
88+
if (skipTrace(descriptor.getClass())) {
8989
return;
9090
}
9191

92-
TestSuiteDescriptor descriptor = new TestSuiteDescriptor(testSuiteName, testClass);
9392
TestSuiteImpl testSuite = inProgressTestSuites.remove(descriptor);
9493
testSuite.end(null);
9594
}
9695

9796
@Override
98-
public void onTestSuiteSkip(String testSuiteName, Class<?> testClass, @Nullable String reason) {
99-
TestSuiteDescriptor descriptor = new TestSuiteDescriptor(testSuiteName, testClass);
97+
public void onTestSuiteSkip(SuiteKey descriptor, @Nullable String reason) {
10098
TestSuiteImpl testSuite = inProgressTestSuites.get(descriptor);
10199
if (testSuite == null) {
102-
log.debug(
103-
"Ignoring skip event, could not find test suite with name {} and class {}",
104-
testSuiteName,
105-
testClass);
100+
log.debug("Ignoring skip event, could not find test suite {}", descriptor);
106101
return;
107102
}
108103
testSuite.setSkipReason(reason);
109104
}
110105

111106
@Override
112-
public void onTestSuiteFailure(
113-
String testSuiteName, Class<?> testClass, @Nullable Throwable throwable) {
114-
TestSuiteDescriptor descriptor = new TestSuiteDescriptor(testSuiteName, testClass);
107+
public void onTestSuiteFailure(SuiteKey descriptor, @Nullable Throwable throwable) {
115108
TestSuiteImpl testSuite = inProgressTestSuites.get(descriptor);
116109
if (testSuite == null) {
117-
log.debug(
118-
"Ignoring fail event, could not find test suite with name {} and class {}",
119-
testSuiteName,
120-
testClass);
110+
log.debug("Ignoring fail event, could not find test suite {}", descriptor);
121111
return;
122112
}
123113
testSuite.setErrorInfo(throwable);
124114
}
125115

126116
@Override
127117
public void onTestStart(
118+
final SuiteKey suiteDescriptor,
119+
final TestKey descriptor,
128120
final String testSuiteName,
129121
final String testName,
130-
final @Nullable Object testQualifier,
131122
final @Nullable String testFramework,
132123
final @Nullable String testFrameworkVersion,
133124
final @Nullable String testParameters,
@@ -140,7 +131,6 @@ public void onTestStart(
140131
return;
141132
}
142133

143-
TestSuiteDescriptor suiteDescriptor = new TestSuiteDescriptor(testSuiteName, testClass);
144134
TestSuiteImpl testSuite = inProgressTestSuites.get(suiteDescriptor);
145135
TestImpl test = testSuite.testStart(testName, testMethod, null);
146136

@@ -183,81 +173,45 @@ public void onTestStart(
183173
test.setTag(Tags.TEST_IS_RETRY, true);
184174
}
185175

186-
TestDescriptor descriptor =
187-
new TestDescriptor(testSuiteName, testClass, testName, testParameters, testQualifier);
188176
inProgressTests.put(descriptor, test);
189177
}
190178

191179
@Override
192-
public void onTestSkip(
193-
String testSuiteName,
194-
Class<?> testClass,
195-
String testName,
196-
@Nullable Object testQualifier,
197-
@Nullable String testParameters,
198-
@Nullable String reason) {
199-
TestDescriptor descriptor =
200-
new TestDescriptor(testSuiteName, testClass, testName, testParameters, testQualifier);
180+
public void onTestSkip(TestKey descriptor, @Nullable String reason) {
201181
TestImpl test = inProgressTests.get(descriptor);
202182
if (test == null) {
203-
log.debug(
204-
"Ignoring skip event, could not find test with name {}, suite name{} and class {}",
205-
testName,
206-
testSuiteName,
207-
testClass);
183+
log.debug("Ignoring skip event, could not find test {}}", descriptor);
208184
return;
209185
}
210186
test.setSkipReason(reason);
211187
}
212188

213189
@Override
214-
public void onTestFailure(
215-
String testSuiteName,
216-
Class<?> testClass,
217-
String testName,
218-
@Nullable Object testQualifier,
219-
@Nullable String testParameters,
220-
@Nullable Throwable throwable) {
221-
TestDescriptor descriptor =
222-
new TestDescriptor(testSuiteName, testClass, testName, testParameters, testQualifier);
190+
public void onTestFailure(TestKey descriptor, @Nullable Throwable throwable) {
223191
TestImpl test = inProgressTests.get(descriptor);
224192
if (test == null) {
225-
log.debug(
226-
"Ignoring fail event, could not find test with name {}, suite name{} and class {}",
227-
testName,
228-
testSuiteName,
229-
testClass);
193+
log.debug("Ignoring fail event, could not find test {}", descriptor);
230194
return;
231195
}
232196
test.setErrorInfo(throwable);
233197
}
234198

235199
@Override
236-
public void onTestFinish(
237-
final String testSuiteName,
238-
final Class<?> testClass,
239-
final String testName,
240-
final @Nullable Object testQualifier,
241-
final @Nullable String testParameters) {
242-
TestDescriptor descriptor =
243-
new TestDescriptor(testSuiteName, testClass, testName, testParameters, testQualifier);
200+
public void onTestFinish(TestKey descriptor) {
244201
TestImpl test = inProgressTests.remove(descriptor);
245202
if (test == null) {
246-
log.debug(
247-
"Ignoring finish event, could not find test with name {}, suite name{} and class {}",
248-
testName,
249-
testSuiteName,
250-
testClass);
203+
log.debug("Ignoring finish event, could not find test {}", descriptor);
251204
return;
252205
}
253206
test.end(null);
254207
}
255208

256209
@Override
257210
public void onTestIgnore(
211+
final SuiteKey suiteDescriptor,
212+
final TestKey testDescriptor,
258213
final String testSuiteName,
259214
final String testName,
260-
final @Nullable Object testQualifier,
261215
final @Nullable String testFramework,
262216
final @Nullable String testFrameworkVersion,
263217
final @Nullable String testParameters,
@@ -267,9 +221,10 @@ public void onTestIgnore(
267221
final @Nullable Method testMethod,
268222
final @Nullable String reason) {
269223
onTestStart(
224+
suiteDescriptor,
225+
testDescriptor,
270226
testSuiteName,
271227
testName,
272-
testQualifier,
273228
testFramework,
274229
testFrameworkVersion,
275230
testParameters,
@@ -278,8 +233,8 @@ public void onTestIgnore(
278233
testMethodName,
279234
testMethod,
280235
false);
281-
onTestSkip(testSuiteName, testClass, testName, testQualifier, testParameters, reason);
282-
onTestFinish(testSuiteName, testClass, testName, testQualifier, testParameters);
236+
onTestSkip(testDescriptor, reason);
237+
onTestFinish(testDescriptor);
283238
}
284239

285240
private static boolean skipTrace(final Class<?> testClass) {

0 commit comments

Comments
 (0)