Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8269478: Shenandoah: gc/shenandoah/mxbeans tests should be more resilient #27

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
@@ -25,6 +25,7 @@
/*
* @test TestChurnNotifications
* @summary Check that MX notifications are reported for all cycles
* @library /test/lib /
* @requires vm.gc.Shenandoah
*
* @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
@@ -41,6 +42,7 @@
/*
* @test TestChurnNotifications
* @summary Check that MX notifications are reported for all cycles
* @library /test/lib /
* @requires vm.gc.Shenandoah
*
* @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
@@ -52,6 +54,7 @@
/*
* @test TestChurnNotifications
* @summary Check that MX notifications are reported for all cycles
* @library /test/lib /
* @requires vm.gc.Shenandoah
*
* @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
@@ -63,6 +66,7 @@
/*
* @test TestChurnNotifications
* @summary Check that MX notifications are reported for all cycles
* @library /test/lib /
* @requires vm.gc.Shenandoah
*
* @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
@@ -74,6 +78,7 @@
/*
* @test TestChurnNotifications
* @summary Check that MX notifications are reported for all cycles
* @library /test/lib /
* @requires vm.gc.Shenandoah
*
* @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
@@ -85,6 +90,7 @@
/*
* @test TestChurnNotifications
* @summary Check that MX notifications are reported for all cycles
* @library /test/lib /
* @requires vm.gc.Shenandoah
*
* @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
@@ -104,6 +110,8 @@
import java.lang.management.*;
import javax.management.openmbean.*;

import jdk.test.lib.Utils;

import com.sun.management.GarbageCollectionNotificationInfo;

public class TestChurnNotifications {
@@ -121,6 +129,8 @@
static volatile Object sink;

public static void main(String[] args) throws Exception {
final long startTime = System.currentTimeMillis();

final AtomicLong churnBytes = new AtomicLong();

NotificationListener listener = new NotificationListener() {
@@ -159,17 +169,28 @@ public void handleNotification(Notification n, Object o) {

System.gc();

// Wait until notifications start arriving, and then wait some more
// to catch the ones arriving late.
while (churnBytes.get() == 0) {
Thread.sleep(1000);
}
Thread.sleep(5000);

long actual = churnBytes.get();

long minExpected = PRECISE ? (mem - HEAP_MB * 1024 * 1024) : 1;
long maxExpected = mem + HEAP_MB * 1024 * 1024;
long actual = 0;

// Look at test timeout to figure out how long we can wait without breaking into timeout.
// Default to 1/4 of the remaining time in 1s steps.
final long STEP_MS = 1000;
long spentTime = System.currentTimeMillis() - startTime;
long maxTries = (Utils.adjustTimeout(Utils.DEFAULT_TEST_TIMEOUT) - spentTime) / STEP_MS / 4;

// Wait until enough notifications are accrued to match minimum boundary.
long tries = 0;
while (tries++ < maxTries) {
actual = churnBytes.get();
if (minExpected <= actual) {
// Wait some more to test if we are breaking the maximum boundary.
Thread.sleep(5000);
actual = churnBytes.get();
break;
}
Thread.sleep(STEP_MS);
}

String msg = "Expected = [" + minExpected / M + "; " + maxExpected / M + "] (" + mem / M + "), actual = " + actual / M;
if (minExpected <= actual && actual <= maxExpected) {
@@ -25,6 +25,7 @@
/*
* @test TestPauseNotifications
* @summary Check that MX notifications are reported for all cycles
* @library /test/lib /
* @requires vm.gc.Shenandoah
*
* @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
@@ -41,6 +42,7 @@
/*
* @test TestPauseNotifications
* @summary Check that MX notifications are reported for all cycles
* @library /test/lib /
* @requires vm.gc.Shenandoah
*
* @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
@@ -51,6 +53,7 @@
/*
* @test TestPauseNotifications
* @summary Check that MX notifications are reported for all cycles
* @library /test/lib /
* @requires vm.gc.Shenandoah
*
* @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
@@ -61,6 +64,7 @@
/*
* @test TestPauseNotifications
* @summary Check that MX notifications are reported for all cycles
* @library /test/lib /
* @requires vm.gc.Shenandoah
*
* @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
@@ -71,6 +75,7 @@
/*
* @test TestPauseNotifications
* @summary Check that MX notifications are reported for all cycles
* @library /test/lib /
* @requires vm.gc.Shenandoah
*
* @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
@@ -81,6 +86,7 @@
/*
* @test TestPauseNotifications
* @summary Check that MX notifications are reported for all cycles
* @library /test/lib /
* @requires vm.gc.Shenandoah
*
* @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
@@ -98,6 +104,8 @@
import java.lang.management.*;
import javax.management.openmbean.*;

import jdk.test.lib.Utils;

import com.sun.management.GarbageCollectionNotificationInfo;

public class TestPauseNotifications {
@@ -108,26 +116,30 @@
static volatile Object sink;

public static void main(String[] args) throws Exception {
final long startTime = System.currentTimeMillis();

final AtomicLong pausesDuration = new AtomicLong();
final AtomicLong cyclesDuration = new AtomicLong();
final AtomicLong pausesCount = new AtomicLong();
final AtomicLong cyclesCount = new AtomicLong();

NotificationListener listener = new NotificationListener() {
@Override
public void handleNotification(Notification n, Object o) {
if (n.getType().equals(GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION)) {
GarbageCollectionNotificationInfo info = GarbageCollectionNotificationInfo.from((CompositeData) n.getUserData());

System.out.println(info.getGcInfo().toString());
System.out.println(info.getGcName());
System.out.println();
System.out.println("Received: " + info.getGcName());

long d = info.getGcInfo().getDuration();

String name = info.getGcName();
if (name.contains("Shenandoah")) {
if (name.equals("Shenandoah Pauses")) {
pausesCount.incrementAndGet();
pausesDuration.addAndGet(d);
} else if (name.equals("Shenandoah Cycles")) {
cyclesCount.incrementAndGet();
cyclesDuration.addAndGet(d);
} else {
throw new IllegalStateException("Unknown name: " + name);
@@ -148,40 +160,57 @@ public void handleNotification(Notification n, Object o) {
sink = new int[size];
}

// Wait until notifications start arriving, and then wait some more
// to catch the ones arriving late.
while (pausesDuration.get() == 0) {
Thread.sleep(1000);
// Look at test timeout to figure out how long we can wait without breaking into timeout.
// Default to 1/4 of the remaining time in 1s steps.
final long STEP_MS = 1000;
long spentTime = System.currentTimeMillis() - startTime;
long maxTries = (Utils.adjustTimeout(Utils.DEFAULT_TEST_TIMEOUT) - spentTime) / STEP_MS / 4;

long actualPauses = 0;
long actualCycles = 0;

// Wait until enough notifications are accrued to match minimum boundary.
long minExpected = 10;

long tries = 0;
while (tries++ < maxTries) {
actualPauses = pausesCount.get();
actualCycles = cyclesCount.get();
if (minExpected <= actualPauses && minExpected <= actualCycles) {
// Wait a little bit to catch the lingering notifications.
Thread.sleep(5000);
actualPauses = pausesCount.get();
actualCycles = cyclesCount.get();
break;
}
Thread.sleep(STEP_MS);
}
Thread.sleep(5000);

long pausesActual = pausesDuration.get();
long cyclesActual = cyclesDuration.get();

long minExpected = 1;
long maxExpected = Long.MAX_VALUE;

{
String msg = "Pauses expected = [" + minExpected + "; " + maxExpected + "], actual = " + pausesActual;
if (minExpected <= pausesActual && pausesActual <= maxExpected) {
String msg = "Pauses expected = [" + minExpected + "; +inf], actual = " + actualPauses;
if (minExpected <= actualPauses) {
System.out.println(msg);
} else {
throw new IllegalStateException(msg);
}
}

{
String msg = "Cycles expected = [" + minExpected + "; " + maxExpected + "], actual = " + cyclesActual;
if (minExpected <= cyclesActual && cyclesActual <= maxExpected) {
String msg = "Cycles expected = [" + minExpected + "; +inf], actual = " + actualCycles;
if (minExpected <= actualCycles) {
System.out.println(msg);
} else {
throw new IllegalStateException(msg);
}
}

{
String msg = "Cycle duration (" + cyclesActual + "), pause duration (" + pausesActual + ")";
if (pausesActual <= cyclesActual) {
long actualPauseDuration = pausesDuration.get();
long actualCycleDuration = cyclesDuration.get();

String msg = "Pauses duration (" + actualPauseDuration + ") is expected to be not larger than cycles duration (" + actualCycleDuration + ")";

if (actualPauseDuration <= actualCycleDuration) {
System.out.println(msg);
} else {
throw new IllegalStateException(msg);