Skip to content

Commit 06d8afe

Browse files
committed
test: verify JVM producers in all-thread scope
1 parent 90a9753 commit 06d8afe

5 files changed

Lines changed: 63 additions & 6 deletions

File tree

ddprof-test/src/test/java/com/datadoghq/profiler/wallclock/JvmtiBasedMonitorTaskBlockTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,6 @@ protected void withTestAssumptions() {
2525

2626
@Override
2727
protected String getProfilerCommand() {
28-
return "wall=1ms,wallprecheck=true,jvmtistacks=true";
28+
return "wall=1ms,filter=,wallprecheck=true,jvmtistacks=true";
2929
}
3030
}

ddprof-test/src/test/java/com/datadoghq/profiler/wallclock/JvmtiBasedParkTaskBlockTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,6 @@ protected void withTestAssumptions() {
2525

2626
@Override
2727
protected String getProfilerCommand() {
28-
return "wall=1ms,wallprecheck=true,jvmtistacks=true";
28+
return "wall=1ms,filter=,wallprecheck=true,jvmtistacks=true";
2929
}
3030
}

ddprof-test/src/test/java/com/datadoghq/profiler/wallclock/MonitorTaskBlockTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ public void staleWaitStateIsRecoveredAfterProfilerRestart() throws Exception {
142142
Path recording = Files.createTempFile("MonitorTaskBlockTest-restart-", ".jfr");
143143
boolean restarted = false;
144144
try {
145-
profiler.execute("start,wall=1ms,wallscope=all,wallprecheck=true,jfr,file="
145+
profiler.execute("start,wall=1ms,filter=,wallprecheck=true,jfr,file="
146146
+ recording.toAbsolutePath());
147147
restarted = true;
148148
synchronized (contentionMonitor) {
@@ -218,7 +218,7 @@ public void virtualMonitorCallbacksDoNotEmitCarrierTaskBlocks() throws Exception
218218

219219
@Override
220220
protected String getProfilerCommand() {
221-
return "wall=1ms,wallprecheck=true";
221+
return "wall=1ms,filter=,wallprecheck=true";
222222
}
223223

224224
protected void assertTaskBlockStackReference(IItemCollection events) {

ddprof-test/src/test/java/com/datadoghq/profiler/wallclock/ParkTaskBlockTest.java

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,17 @@
88
import com.datadoghq.profiler.AbstractProfilerTest;
99
import com.datadoghq.profiler.ProfilerOwnedBlockHooks;
1010
import java.lang.reflect.Method;
11+
import java.util.concurrent.CountDownLatch;
1112
import java.util.concurrent.TimeUnit;
13+
import java.util.concurrent.atomic.AtomicBoolean;
14+
import java.util.concurrent.atomic.AtomicReference;
1215
import java.util.concurrent.locks.LockSupport;
1316
import org.junit.jupiter.api.Test;
1417
import org.junit.jupiter.api.Assumptions;
1518
import org.openjdk.jmc.common.item.IItemCollection;
1619

1720
import static org.junit.jupiter.api.Assertions.assertFalse;
21+
import static org.junit.jupiter.api.Assertions.assertTrue;
1822

1923
/** Verifies TaskBlock production from Java-owned platform-thread park hooks. */
2024
public class ParkTaskBlockTest extends AbstractProfilerTest {
@@ -94,9 +98,17 @@ public void virtualParkDoesNotMutateCarrierProducerState() throws Exception {
9498
TaskBlockAssertions.assertContains(events, 0, 0, BLOCKER, UNBLOCKING_SPAN_ID);
9599
}
96100

101+
@Test
102+
public void platformParkSuppressesSignalsAndClearsOwnership() throws Exception {
103+
long baseline = profiler.getDebugCounters()
104+
.getOrDefault("wc_signals_suppressed_owned_block", 0L);
105+
long afterFirstPark = runSuppressedPark(baseline);
106+
runSuppressedPark(afterFirstPark);
107+
}
108+
97109
@Override
98110
protected String getProfilerCommand() {
99-
return "wall=1ms,wallprecheck=true";
111+
return "wall=1ms,filter=,wallprecheck=true";
100112
}
101113

102114
protected void assertTaskBlockStackReference(IItemCollection events) {
@@ -112,4 +124,46 @@ private static void parkForMillis(long millis) {
112124
LockSupport.parkNanos(remaining);
113125
}
114126
}
127+
128+
private long runSuppressedPark(long baseline) throws Exception {
129+
CountDownLatch armed = new CountDownLatch(1);
130+
AtomicBoolean release = new AtomicBoolean();
131+
AtomicReference<Throwable> error = new AtomicReference<>();
132+
Thread worker = new Thread(() -> {
133+
try {
134+
ProfilerOwnedBlockHooks.parkEnter(profiler);
135+
armed.countDown();
136+
while (!release.get()) {
137+
Thread.yield();
138+
}
139+
} catch (Throwable t) {
140+
error.set(t);
141+
} finally {
142+
ProfilerOwnedBlockHooks.parkExit(profiler, BLOCKER, UNBLOCKING_SPAN_ID);
143+
}
144+
}, "taskblock-park-suppression");
145+
146+
worker.start();
147+
assertTrue(armed.await(5, TimeUnit.SECONDS));
148+
try {
149+
waitForCounterAbove("wc_signals_suppressed_owned_block", baseline, 5_000L);
150+
} finally {
151+
release.set(true);
152+
}
153+
worker.join(5_000L);
154+
assertFalse(worker.isAlive());
155+
if (error.get() != null) throw new AssertionError(error.get());
156+
return profiler.getDebugCounters()
157+
.getOrDefault("wc_signals_suppressed_owned_block", 0L);
158+
}
159+
160+
private void waitForCounterAbove(String name, long baseline, long timeoutMillis)
161+
throws Exception {
162+
long deadline = System.nanoTime() + TimeUnit.MILLISECONDS.toNanos(timeoutMillis);
163+
while (System.nanoTime() < deadline) {
164+
if (profiler.getDebugCounters().getOrDefault(name, 0L) > baseline) return;
165+
Thread.sleep(10L);
166+
}
167+
throw new AssertionError("Counter did not increase: " + name);
168+
}
115169
}

ddprof-test/src/test/java/com/datadoghq/profiler/wallclock/WallclockMitigationsCombinedTest.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ public void contextScopedThreadsRemainSampled() throws Exception {
4343
Thread sleeping =
4444
new Thread(
4545
() -> {
46+
registerCurrentThreadForWallClockProfiling();
4647
ready.countDown();
4748
long token = ProfilerOwnedBlockHooks.blockEnter(
4849
profiler, OSTHREAD_STATE_SLEEPING);
@@ -58,6 +59,7 @@ public void contextScopedThreadsRemainSampled() throws Exception {
5859
Thread parkedBusy =
5960
new Thread(
6061
() -> {
62+
registerCurrentThreadForWallClockProfiling();
6163
long spanId = 0x1111L;
6264
long rootSpanId = 0x2222L;
6365
profiler.setContext(rootSpanId, spanId, 0, 0);
@@ -76,6 +78,7 @@ public void contextScopedThreadsRemainSampled() throws Exception {
7678
Thread runnable =
7779
new Thread(
7880
() -> {
81+
registerCurrentThreadForWallClockProfiling();
7982
ready.countDown();
8083
while (!stop.get()) {
8184
// keep runnable
@@ -121,7 +124,7 @@ public void contextScopedThreadsRemainSampled() throws Exception {
121124

122125
@Override
123126
protected String getProfilerCommand() {
124-
return "wall=1ms,wallprecheck=true";
127+
return "wall=1ms,filter=0,wallprecheck=true";
125128
}
126129

127130
private Map<String, Long> samplesByThreadName() {

0 commit comments

Comments
 (0)