Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
2c219fd
add `di_enabled` to settings response
daniel-mohedano Jul 4, 2025
a911ae0
add FTR related metrics
daniel-mohedano Jul 4, 2025
d20159e
add FTR to execution settings
daniel-mohedano Jul 4, 2025
c4c84d6
add basic exception replay integration in agent mode
daniel-mohedano Jul 14, 2025
ae31670
feat: headless and agentless changes
daniel-mohedano Jul 22, 2025
4f2d6a9
Merge branch 'master' into daniel.mohedano/failed-test-replay
daniel-mohedano Jul 22, 2025
c7eeac8
fix: tests
daniel-mohedano Jul 23, 2025
14cf11c
fix: testng capabilities
daniel-mohedano Aug 4, 2025
461fb1f
feat: refactor agentless intakes
daniel-mohedano Aug 6, 2025
14b1054
Merge branch 'master' into daniel.mohedano/failed-test-replay
daniel-mohedano Aug 6, 2025
a87eff0
chore: update smoke test fixtures
daniel-mohedano Aug 6, 2025
19b4edf
test: add unit test for new Intake enum
daniel-mohedano Aug 6, 2025
9e81cc7
test: remove ftr from instrumentation tests (not used)
daniel-mohedano Aug 6, 2025
4e3deb4
test: introduce FTR smoke tests for headfull and headless modes
daniel-mohedano Aug 11, 2025
f931654
style: spotless and codenarc
daniel-mohedano Aug 11, 2025
eacde60
feat: add test event finished FTR telemetry
daniel-mohedano Aug 11, 2025
0228f71
feat: add `product` field to snapshots
daniel-mohedano Aug 11, 2025
88fd665
feat: implement SuiteEnd listener for sink flushing
daniel-mohedano Aug 11, 2025
ec9c54d
feat: introduce new config variables for debugger
daniel-mohedano Aug 12, 2025
d4d2432
chore: remove todo
daniel-mohedano Aug 19, 2025
ffda9b3
Merge branch 'master' into daniel.mohedano/failed-test-replay
daniel-mohedano Aug 19, 2025
49eaebf
feat: align FTR settings with JS' implementation
daniel-mohedano Aug 21, 2025
b4cef2c
feat: PR suggestions
daniel-mohedano Aug 22, 2025
d82a7fa
feat: implement debugger config bridge
daniel-mohedano Aug 27, 2025
ab8d8e9
fix: move check from policy to history for FTR
daniel-mohedano Aug 27, 2025
bd81769
fix: tests
daniel-mohedano Aug 27, 2025
c257390
chore: update codeowners
daniel-mohedano Aug 27, 2025
73bf81d
Merge branch 'master' into daniel.mohedano/failed-test-replay
daniel-mohedano Aug 27, 2025
3a89ca3
test: better unit tests
daniel-mohedano Sep 1, 2025
54dbb03
Merge branch 'master' into daniel.mohedano/failed-test-replay
daniel-mohedano Sep 1, 2025
a1f58f3
fix: add CI Intake back
daniel-mohedano Sep 1, 2025
719a934
style: spotless
daniel-mohedano Sep 1, 2025
b223a21
fix: tests
daniel-mohedano Sep 1, 2025
58a096b
fix: correct intake usage
daniel-mohedano Sep 1, 2025
920421a
fix: change info to debug log
daniel-mohedano Sep 3, 2025
2852d25
feat: move away from deferred queue in favor of merging updates
daniel-mohedano Sep 3, 2025
d80e531
fix: pr suggestions
daniel-mohedano Sep 4, 2025
34cf624
feat: refactor FTR logic into it's own exceptiondebugger implementation
daniel-mohedano Sep 4, 2025
887350f
fix: jacoco coverage
daniel-mohedano Sep 4, 2025
f1f1264
fix: remove snapshot product and async instrumentation config
daniel-mohedano Sep 8, 2025
8e145f4
fix: remove sync config test
daniel-mohedano Sep 8, 2025
bb06f75
Merge branch 'master' into daniel.mohedano/failed-test-replay
daniel-mohedano Sep 8, 2025
098b929
fix: add history on test start
daniel-mohedano Sep 8, 2025
a56d10f
fix: use synchronized instead of atomic refs in bridge
daniel-mohedano Sep 8, 2025
f32dcef
fix: abstract repeated smoke test logic
daniel-mohedano Sep 8, 2025
ea090f9
fix: synchronization on bridge
daniel-mohedano Sep 9, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
fix: pr suggestions
  • Loading branch information
daniel-mohedano committed Sep 4, 2025
commit d80e531c7671f0966b13c277e6bf5c7054380e59
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,7 @@ public static void start(Instrumentation inst, SharedCommunicationObjects sco) {
}

if (executionSettings.isFailedTestReplayEnabled()) {
DebuggerConfigBridge.updateConfig(
new DebuggerConfigUpdate.Builder().setExceptionReplayEnabled(true).build());
DebuggerConfigBridge.updateConfig(new DebuggerConfigUpdate(null, true, null, null));
}

CiVisibilityCoverageServices.Child coverageServices =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ public void start() {

public void stop() {
lowRateFlush(this);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in that case, add
snapshotSink.highRateFlush(null);
also

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

addressed in d80e531

snapshotSink.highRateFlush(null);
cancelSchedule(this.flushIntervalScheduled);
cancelSchedule(this.lowRateScheduled);
probeStatusSink.stop();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,18 @@ public void enableDisable() {
when(sco.featuresDiscovery(any())).thenReturn(mock(DDAgentFeaturesDiscovery.class));
DebuggerAgent.run(mock(Instrumentation.class), sco);
DefaultDebuggerConfigUpdater productConfigUpdater = new DefaultDebuggerConfigUpdater();
productConfigUpdater.updateConfig(DebuggerConfigUpdate.empty());
productConfigUpdater.updateConfig(DebuggerConfigUpdate.allEnabled());
productConfigUpdater.updateConfig(new DebuggerConfigUpdate());
productConfigUpdater.updateConfig(new DebuggerConfigUpdate(true, true, true, true));
assertTrue(productConfigUpdater.isDynamicInstrumentationEnabled());
assertTrue(productConfigUpdater.isExceptionReplayEnabled());
assertTrue(productConfigUpdater.isCodeOriginEnabled());
assertTrue(productConfigUpdater.isDistributedDebuggerEnabled());
productConfigUpdater.updateConfig(DebuggerConfigUpdate.empty());
productConfigUpdater.updateConfig(new DebuggerConfigUpdate());
assertTrue(productConfigUpdater.isDynamicInstrumentationEnabled());
assertTrue(productConfigUpdater.isExceptionReplayEnabled());
assertTrue(productConfigUpdater.isCodeOriginEnabled());
assertTrue(productConfigUpdater.isDistributedDebuggerEnabled());
productConfigUpdater.updateConfig(DebuggerConfigUpdate.allDisabled());
productConfigUpdater.updateConfig(new DebuggerConfigUpdate(false, false, false, false));
assertFalse(productConfigUpdater.isDynamicInstrumentationEnabled());
assertFalse(productConfigUpdater.isExceptionReplayEnabled());
assertFalse(productConfigUpdater.isCodeOriginEnabled());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -222,12 +222,11 @@ void applyConfigOverrides(LibConfig libConfig) {

maybeOverride(builder::setTracingTags, parseTagListToMap(libConfig.tracingTags));
DebuggerConfigBridge.updateConfig(
new DebuggerConfigUpdate.Builder()
.setDynamicInstrumentationEnabled(libConfig.dynamicInstrumentationEnabled)
.setExceptionReplayEnabled(libConfig.exceptionReplayEnabled)
.setCodeOriginEnabled(libConfig.codeOriginEnabled)
.setDistributedDebuggerEnabled(libConfig.liveDebuggingEnabled)
.build());
new DebuggerConfigUpdate(
libConfig.dynamicInstrumentationEnabled,
libConfig.exceptionReplayEnabled,
libConfig.codeOriginEnabled,
libConfig.liveDebuggingEnabled));
builder.apply();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@ public static void updateConfig(DebuggerConfigUpdate update) {
LOGGER.debug("No config update detected, skipping");
return;
}
if (UPDATER.get() != null) {
LOGGER.debug("DebuggerConfigUpdater available, performing update");
UPDATER.get().updateConfig(update);
DebuggerConfigUpdater updater = UPDATER.get();
if (updater != null) {
LOGGER.debug("DebuggerConfigUpdater available, performing update: {}", update);
updater.updateConfig(update);
} else {
LOGGER.debug("DebuggerConfigUpdater not available, deferring update");
DEFERRED_UPDATE.updateAndGet(existing -> DebuggerConfigUpdate.coalesce(existing, update));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
package datadog.trace.api.debugger;

import java.util.Objects;

public class DebuggerConfigUpdate {
private final Boolean dynamicInstrumentationEnabled;
private final Boolean exceptionReplayEnabled;
private final Boolean codeOriginEnabled;
private final Boolean distributedDebuggerEnabled;

private DebuggerConfigUpdate(Builder builder) {
this.dynamicInstrumentationEnabled = builder.dynamicInstrumentationEnabled;
this.exceptionReplayEnabled = builder.exceptionReplayEnabled;
this.codeOriginEnabled = builder.codeOriginEnabled;
this.distributedDebuggerEnabled = builder.distributedDebuggerEnabled;
public DebuggerConfigUpdate() {
this(null, null, null, null);
}

public DebuggerConfigUpdate(
Boolean dynamicInstrumentationEnabled,
Boolean exceptionReplayEnabled,
Boolean codeOriginEnabled,
Boolean distributedDebuggerEnabled) {
this.dynamicInstrumentationEnabled = dynamicInstrumentationEnabled;
this.exceptionReplayEnabled = exceptionReplayEnabled;
this.codeOriginEnabled = codeOriginEnabled;
this.distributedDebuggerEnabled = distributedDebuggerEnabled;
}

public Boolean getDynamicInstrumentationEnabled() {
Expand All @@ -31,16 +37,6 @@ public Boolean getDistributedDebuggerEnabled() {
return distributedDebuggerEnabled;
}

@Override
public boolean equals(Object o) {
if (!(o instanceof DebuggerConfigUpdate)) return false;
DebuggerConfigUpdate that = (DebuggerConfigUpdate) o;
return Objects.equals(dynamicInstrumentationEnabled, that.dynamicInstrumentationEnabled)
&& Objects.equals(exceptionReplayEnabled, that.exceptionReplayEnabled)
&& Objects.equals(codeOriginEnabled, that.codeOriginEnabled)
&& Objects.equals(distributedDebuggerEnabled, that.distributedDebuggerEnabled);
}

@Override
public String toString() {
return "DebuggerConfigUpdate{"
Expand All @@ -55,15 +51,6 @@ public String toString() {
+ '}';
}

@Override
public int hashCode() {
return Objects.hash(
dynamicInstrumentationEnabled,
exceptionReplayEnabled,
codeOriginEnabled,
distributedDebuggerEnabled);
}

public boolean hasUpdates() {
return dynamicInstrumentationEnabled != null
|| exceptionReplayEnabled != null
Expand All @@ -77,76 +64,15 @@ public static DebuggerConfigUpdate coalesce(
return update;
}

return new Builder()
.setDynamicInstrumentationEnabled(
coalesceSetting(
existing.dynamicInstrumentationEnabled, update.dynamicInstrumentationEnabled))
.setExceptionReplayEnabled(
coalesceSetting(existing.exceptionReplayEnabled, update.exceptionReplayEnabled))
.setCodeOriginEnabled(coalesceSetting(existing.codeOriginEnabled, update.codeOriginEnabled))
.setDistributedDebuggerEnabled(
coalesceSetting(existing.distributedDebuggerEnabled, update.distributedDebuggerEnabled))
.build();
return new DebuggerConfigUpdate(
coalesceSetting(
existing.dynamicInstrumentationEnabled, update.dynamicInstrumentationEnabled),
coalesceSetting(existing.exceptionReplayEnabled, update.exceptionReplayEnabled),
coalesceSetting(existing.codeOriginEnabled, update.codeOriginEnabled),
coalesceSetting(existing.distributedDebuggerEnabled, update.distributedDebuggerEnabled));
}

private static Boolean coalesceSetting(Boolean existing, Boolean update) {
return update != null ? update : existing;
}

public static final class Builder {
private Boolean dynamicInstrumentationEnabled;
private Boolean exceptionReplayEnabled;
private Boolean codeOriginEnabled;
private Boolean distributedDebuggerEnabled;

public Builder setDynamicInstrumentationEnabled(Boolean dynamicInstrumentationEnabled) {
this.dynamicInstrumentationEnabled = dynamicInstrumentationEnabled;
return this;
}

public Builder setExceptionReplayEnabled(Boolean exceptionReplayEnabled) {
this.exceptionReplayEnabled = exceptionReplayEnabled;
return this;
}

public Builder setCodeOriginEnabled(Boolean codeOriginEnabled) {
this.codeOriginEnabled = codeOriginEnabled;
return this;
}

public Builder setDistributedDebuggerEnabled(Boolean distributedDebuggerEnabled) {
this.distributedDebuggerEnabled = distributedDebuggerEnabled;
return this;
}

public Builder enableAll() {
return setDynamicInstrumentationEnabled(true)
.setExceptionReplayEnabled(true)
.setCodeOriginEnabled(true)
.setDistributedDebuggerEnabled(true);
}

public Builder disableAll() {
return setDynamicInstrumentationEnabled(false)
.setExceptionReplayEnabled(false)
.setCodeOriginEnabled(false)
.setDistributedDebuggerEnabled(false);
}

public DebuggerConfigUpdate build() {
return new DebuggerConfigUpdate(this);
}
}

public static DebuggerConfigUpdate empty() {
return new Builder().build();
}

public static DebuggerConfigUpdate allEnabled() {
return new Builder().enableAll().build();
}

public static DebuggerConfigUpdate allDisabled() {
return new Builder().disableAll().build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,22 @@ class DebuggerConfigBridgeTest extends Specification {

when:
DebuggerConfigBridge.setUpdater(updater)
DebuggerConfigBridge.updateConfig(new DebuggerConfigUpdate.Builder().setExceptionReplayEnabled(true).build())
DebuggerConfigBridge.updateConfig(new DebuggerConfigUpdate(null, true, null, null))

then:
updater.calls == 1
DebuggerConfigBridge.isExceptionReplayEnabled()

when:
DebuggerConfigBridge.updateConfig(new DebuggerConfigUpdate.Builder().setDynamicInstrumentationEnabled(true).build())
DebuggerConfigBridge.updateConfig(new DebuggerConfigUpdate(true, null, null, null))

then:
updater.calls == 2
DebuggerConfigBridge.isExceptionReplayEnabled()
DebuggerConfigBridge.isDynamicInstrumentationEnabled()

when:
DebuggerConfigBridge.updateConfig(DebuggerConfigUpdate.allDisabled())
DebuggerConfigBridge.updateConfig(new DebuggerConfigUpdate(false, false, false, false))

then:
updater.calls == 3
Expand All @@ -50,7 +50,7 @@ class DebuggerConfigBridgeTest extends Specification {
DebuggerConfigBridge.setUpdater(updater)

when:
DebuggerConfigBridge.updateConfig(new DebuggerConfigUpdate.Builder().build())
DebuggerConfigBridge.updateConfig(new DebuggerConfigUpdate())

then:
updater.calls == 0
Expand All @@ -60,9 +60,9 @@ class DebuggerConfigBridgeTest extends Specification {
def updater = new MockDebuggerConfigUpdater()

when:
DebuggerConfigBridge.updateConfig(new DebuggerConfigUpdate.Builder().setExceptionReplayEnabled(false).build())
DebuggerConfigBridge.updateConfig(DebuggerConfigUpdate.allEnabled())
DebuggerConfigBridge.updateConfig(new DebuggerConfigUpdate.Builder().setExceptionReplayEnabled(false).build())
DebuggerConfigBridge.updateConfig(new DebuggerConfigUpdate(null, false, null, null))
DebuggerConfigBridge.updateConfig(new DebuggerConfigUpdate(true, true, true, true))
DebuggerConfigBridge.updateConfig(new DebuggerConfigUpdate(null, false, null, null))

then:
updater.calls == 0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import spock.lang.Specification
class DebuggerConfigUpdateTest extends Specification {

def "test update coalesce"() {
def existing = new DebuggerConfigUpdate.Builder().setExceptionReplayEnabled(true).setDynamicInstrumentationEnabled(false).build()
def update = new DebuggerConfigUpdate.Builder().setExceptionReplayEnabled(false).setCodeOriginEnabled(true).build()
def existing = new DebuggerConfigUpdate(false, true, null, null)
def update = new DebuggerConfigUpdate(null, false, true, null)

when:
def result = DebuggerConfigUpdate.coalesce(existing, update)
Expand Down