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

CRIU tests get accurate pre-checkpoint time #18425

Merged
merged 1 commit into from
Nov 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion runtime/criusupport/criusupport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -656,13 +656,13 @@ Java_org_eclipse_openj9_criu_CRIUSupport_checkpointJVMImpl(JNIEnv *env,
bool setupCRIU = true;
PORT_ACCESS_FROM_VMC(currentThread);

Trc_CRIU_checkpointJVMImpl_Entry(currentThread);
if (NULL == vm->checkpointState.criuJVMCheckpointExceptionClass) {
setupCRIU = setupJNIFieldIDsAndCRIUAPI(env, &currentExceptionClass, &systemReturnCode, &nlsMsgFormat);
}

vm->checkpointState.checkpointThread = currentThread;

Trc_CRIU_checkpointJVMImpl_Entry(currentThread);
if (vmFuncs->isCheckpointAllowed(currentThread) && setupCRIU) {
#if defined(LINUX)
j9object_t cpDir = NULL;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,35 +82,33 @@ public static void checkPointJVM(CRIUSupport criu, Path path, boolean deleteDir)
deleteCheckpointDirectory(path);
}
} else {
System.err.println("CRIU is not enabled");
throw new RuntimeException("CRIU is not enabled");
}
}

public static CRIUSupport prepareCheckPointJVM(Path path) {
CRIUSupport criu = null;
if (CRIUSupport.isCRIUSupportEnabled()) {
deleteCheckpointDirectory(path);
createCheckpointDirectory(path);
criu = new CRIUSupport(path);
return (new CRIUSupport(path)).setLeaveRunning(false).setShellJob(true).setFileLocks(true);
} else {
System.err.println("CRIU is not enabled");
throw new RuntimeException("CRIU is not enabled");
}
return criu;
}

public static void checkPointJVMNoSetup(CRIUSupport criu, Path path, boolean deleteDir) {
if (criu != null) {
try {
showThreadCurrentTime("Performing CRIUSupport.checkpointJVM()");
criu.setLeaveRunning(false).setShellJob(true).setFileLocks(true).checkpointJVM();
criu.checkpointJVM();
} catch (SystemRestoreException e) {
e.printStackTrace();
}
if (deleteDir) {
deleteCheckpointDirectory(path);
}
} else {
System.err.println("CRIU is not enabled");
throw new RuntimeException("CRIU is not enabled");
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,6 @@ public static void main(String[] args) throws InterruptedException {

private void test(String testName) throws InterruptedException {
CRIUSupport criu = CRIUTestUtils.prepareCheckPointJVM(CRIUTestUtils.imagePath);
if (criu == null) {
return;
}
System.out.println("Start test name: " + testName);
CRIUTestUtils.showThreadCurrentTime("Before starting " + testName);
switch (testName) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,6 @@ public static void main(String[] args) {
static void TestConcurrentModePreCheckpointHookThrowException() {
CRIUTestUtils.showThreadCurrentTime("TestConcurrentModePreCheckpointHookThrowException() starts ..");
CRIUSupport criu = CRIUTestUtils.prepareCheckPointJVM(CRIUTestUtils.imagePath);
if (criu == null) {
// "CRIU is not enabled" is to appear and cause the test failure.
return;
}
criu.registerPreCheckpointHook(() -> {
throw new RuntimeException("TestConcurrentModePreCheckpointHookThrowException() within preCheckpointHook");
}, CRIUSupport.HookMode.CONCURRENT_MODE, USER_HOOK_MODE_PRIORITY_LOW);
Expand All @@ -92,10 +88,6 @@ static void TestConcurrentModePreCheckpointHookThrowException() {
static void TestConcurrentModePreCheckpointHookThrowExceptionPriority() {
CRIUTestUtils.showThreadCurrentTime("TestConcurrentModePreCheckpointHookThrowExceptionPriority() starts ..");
CRIUSupport criu = CRIUTestUtils.prepareCheckPointJVM(CRIUTestUtils.imagePath);
if (criu == null) {
// "CRIU is not enabled" is to appear and cause the test failure.
return;
}
criu.registerPreCheckpointHook(
() -> CRIUTestUtils.showThreadCurrentTime("TestConcurrentModePreCheckpointHookThrowExceptionPriority() within preCheckpointHook"),
CRIUSupport.HookMode.CONCURRENT_MODE, 100);
Expand All @@ -109,10 +101,6 @@ static void TestConcurrentModePreCheckpointHookThrowExceptionPriority() {
static void TestConcurrentModePreCheckpointHookRunOnce() {
CRIUTestUtils.showThreadCurrentTime("TestConcurrentModePreCheckpointHookRunOnce() starts ..");
CRIUSupport criu = CRIUTestUtils.prepareCheckPointJVM(CRIUTestUtils.imagePath);
if (criu == null) {
// "CRIU is not enabled" is to appear and cause the test failure.
return;
}
criu.registerPreCheckpointHook(
() -> CRIUTestUtils.showThreadCurrentTime("TestConcurrentModePreCheckpointHookRunOnce() within preCheckpointHook"),
CRIUSupport.HookMode.CONCURRENT_MODE, USER_HOOK_MODE_PRIORITY_LOW);
Expand All @@ -126,10 +114,6 @@ static void TestConcurrentModePreCheckpointHookRunOnce() {
static void TestConcurrentModePreCheckpointHookPriorities() {
CRIUTestUtils.showThreadCurrentTime("TestConcurrentModePreCheckpointHookPriorities() starts ..");
CRIUSupport criu = CRIUTestUtils.prepareCheckPointJVM(CRIUTestUtils.imagePath);
if (criu == null) {
// "CRIU is not enabled" is to appear and cause the test failure.
return;
}
final TestResult testResult = new TestResult(true, 0);
criu.registerPreCheckpointHook(() -> {
CRIUTestUtils.showThreadCurrentTime("The preCheckpointHook with lower priority in CONCURRENT_MODE");
Expand Down Expand Up @@ -190,10 +174,6 @@ static void TestConcurrentModePreCheckpointHookPriorities() {
static void TestConcurrentModePostRestoreHookThrowException() {
CRIUTestUtils.showThreadCurrentTime("TestConcurrentModePostRestoreHookThrowException() starts ..");
CRIUSupport criu = CRIUTestUtils.prepareCheckPointJVM(CRIUTestUtils.imagePath);
if (criu == null) {
// "CRIU is not enabled" is to appear and cause the test failure.
return;
}
criu.registerPostRestoreHook(() -> {
throw new RuntimeException("TestConcurrentModePostRestoreHookThrowException() within postRestoreHook");
}, CRIUSupport.HookMode.CONCURRENT_MODE, 1);
Expand All @@ -207,10 +187,6 @@ static void TestConcurrentModePostRestoreHookThrowException() {
static void TestConcurrentModePostRestoreHookThrowExceptionPriority() {
CRIUTestUtils.showThreadCurrentTime("TestConcurrentModePostRestoreHookThrowExceptionPriority() starts ..");
CRIUSupport criu = CRIUTestUtils.prepareCheckPointJVM(CRIUTestUtils.imagePath);
if (criu == null) {
// "CRIU is not enabled" is to appear and cause the test failure.
return;
}
criu.registerPostRestoreHook(
() -> CRIUTestUtils.showThreadCurrentTime("TestConcurrentModePostRestoreHookRunOnce() within postRestoreHook"),
CRIUSupport.HookMode.CONCURRENT_MODE, -1);
Expand All @@ -224,10 +200,6 @@ static void TestConcurrentModePostRestoreHookThrowExceptionPriority() {
static void TestConcurrentModePostRestoreHookRunOnce() {
CRIUTestUtils.showThreadCurrentTime("TestConcurrentModePostRestoreHookRunOnce() starts ..");
CRIUSupport criu = CRIUTestUtils.prepareCheckPointJVM(CRIUTestUtils.imagePath);
if (criu == null) {
// "CRIU is not enabled" is to appear and cause the test failure.
return;
}
criu.registerPostRestoreHook(
() -> CRIUTestUtils.showThreadCurrentTime("TestConcurrentModePostRestoreHookRunOnce() within postRestoreHook"),
CRIUSupport.HookMode.CONCURRENT_MODE, 1);
Expand All @@ -241,10 +213,6 @@ static void TestConcurrentModePostRestoreHookRunOnce() {
static void TestConcurrentModePostRestoreHookPriorities() {
CRIUTestUtils.showThreadCurrentTime("TestConcurrentModePostRestoreHookPriorities() starts ..");
CRIUSupport criu = CRIUTestUtils.prepareCheckPointJVM(CRIUTestUtils.imagePath);
if (criu == null) {
// "CRIU is not enabled" is to appear and cause the test failure.
return;
}
final TestResult testResult = new TestResult(true, 0);
criu.registerPostRestoreHook(() -> {
CRIUTestUtils.showThreadCurrentTime("The postRestoreHook with lower priority in CONCURRENT_MODE");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,6 @@ private void testVirtualThreadForkJoinPoolParallelism(boolean isCheckpoint, bool

private void test(String testName) throws InterruptedException {
CRIUSupport criu = CRIUTestUtils.prepareCheckPointJVM(CRIUTestUtils.imagePath);
if (criu == null) {
// prepareCheckPointJVM() has an error message "CRIU is not enabled".
return;
}
CRIUTestUtils.showThreadCurrentTime("Before starting " + testName);
switch (testName) {
case "testVirtualThreadForkJoinPoolParallelism":
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,6 @@ void testSingleThreadModeCheckpointExceptionJUCLock() {
CRIUTestUtils.showThreadCurrentTime("testSingleThreadModeCheckpointExceptionJUCLock() before ReentrantLock.lock()");
jucLock.lock();
CRIUSupport criu = CRIUTestUtils.prepareCheckPointJVM(CRIUTestUtils.imagePath);
if (criu == null) {
// "CRIU is not enabled" is to appear and cause the test failure.
return;
}

try {
// ensure the lock already taken before performing a checkpoint
Expand Down Expand Up @@ -131,10 +127,6 @@ void testSingleThreadModeCheckpointExceptionSynLock() {
"testSingleThreadModeCheckpointExceptionSynLock() before synchronized on " + synLock);
synchronized (synLock) {
CRIUSupport criu = CRIUTestUtils.prepareCheckPointJVM(CRIUTestUtils.imagePath);
if (criu == null) {
// "CRIU is not enabled" is to appear and cause the test failure.
return;
}

try {
// ensure the lock already taken before performing a checkpoint
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,6 @@ void testSingleThreadModeRestoreExceptionJUCLock() {
CRIUTestUtils.showThreadCurrentTime("testSingleThreadModeRestoreExceptionJUCLock() before ReentrantLock.lock()");
jucLock.lock();
CRIUSupport criu = CRIUTestUtils.prepareCheckPointJVM(CRIUTestUtils.imagePath);
if (criu == null) {
// "CRIU is not enabled" is to appear and cause the test failure.
return;
}

try {
// ensure the lock already taken before performing a checkpoint
Expand Down Expand Up @@ -139,10 +135,6 @@ void testSingleThreadModeRestoreExceptionSynLock() {
"testSingleThreadModeRestoreExceptionSynLock() before synchronized on " + synLock);
synchronized (synLock) {
CRIUSupport criu = CRIUTestUtils.prepareCheckPointJVM(CRIUTestUtils.imagePath);
if (criu == null) {
// "CRIU is not enabled" is to appear and cause the test failure.
return;
}

try {
// ensure the lock already taken before performing a checkpoint
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ public class TimeChangeTest {
private final static long MILLIS_DELAY_AFTERCHECKPOINTDONE = 5000;
private final long startNanoTime = System.nanoTime();
private final long currentTimeMillis = System.currentTimeMillis();
private final static Path imagePath = Paths.get("cpData");

public static void main(String args[]) throws InterruptedException {
if (args.length == 0) {
Expand Down Expand Up @@ -82,6 +81,7 @@ public static void main(String args[]) throws InterruptedException {
}

private void test(String testName) throws InterruptedException {
CRIUSupport criu = CRIUTestUtils.prepareCheckPointJVM(CRIUTestUtils.imagePath);
System.out.println("Start test name: " + testName);
showThreadCurrentTime("Before starting " + testName);
Timer timer = new Timer();
Expand All @@ -101,7 +101,7 @@ private void test(String testName) throws InterruptedException {
default:
throw new RuntimeException("Unrecognized test name: " + testName);
}
CRIUTestUtils.checkPointJVM(imagePath, false);
CRIUTestUtils.checkPointJVMNoSetup(criu, CRIUTestUtils.imagePath, false);
// maximum test running time is 12s
Thread.sleep(12000);
showThreadCurrentTime("End " + testName);
Expand Down Expand Up @@ -209,9 +209,10 @@ public void run() {
}

public void testSystemNanoTime() {
CRIUSupport criu = CRIUTestUtils.prepareCheckPointJVM(CRIUTestUtils.imagePath);
final long beforeCheckpoint = System.nanoTime();
System.out.println("System.nanoTime() before CRIU checkpoint: " + beforeCheckpoint);
CRIUTestUtils.checkPointJVM(imagePath, false);
CRIUTestUtils.checkPointJVMNoSetup(criu, CRIUTestUtils.imagePath, false);
final long afterRestore = System.nanoTime();
final long elapsedTime = afterRestore - beforeCheckpoint;
if (elapsedTime < MAX_TARDINESS_NS) {
Expand All @@ -229,8 +230,9 @@ private void testGetLastRestoreTime() {
System.out.println("FAILED: InternalCRIUSupport.getLastRestoreTime() - " + lastRestoreTime
+ " should be -1 before restore");
}
CRIUSupport criu = CRIUTestUtils.prepareCheckPointJVM(CRIUTestUtils.imagePath);
long beforeCheckpoint = System.currentTimeMillis();
CRIUTestUtils.checkPointJVM(imagePath, false);
CRIUTestUtils.checkPointJVMNoSetup(criu, CRIUTestUtils.imagePath, false);
lastRestoreTime = InternalCRIUSupport.getLastRestoreTime();
long afterRestore = System.currentTimeMillis();
if (beforeCheckpoint >= lastRestoreTime) {
Expand All @@ -247,36 +249,33 @@ private void testGetLastRestoreTime() {
}

private void testMXBeanUpTime() {
CRIUSupport criu = CRIUTestUtils.prepareCheckPointJVM(CRIUTestUtils.imagePath);
RuntimeMXBean mxb = ManagementFactory.getRuntimeMXBean();
long uptimeBeforeCheckpoint = mxb.getUptime();
CRIUTestUtils.checkPointJVM(imagePath, false);
CRIUTestUtils.checkPointJVMNoSetup(criu, CRIUTestUtils.imagePath, false);
long uptimeAfterCheckpoint = mxb.getUptime();
// UpTime adjustment less than the JVM down time 2s.
long adjustMillis = 1500;

if (uptimeAfterCheckpoint <= uptimeBeforeCheckpoint) {
System.out.println("FAILED: testMXBeanUpTime() - uptimeAfterCheckpoint " + uptimeAfterCheckpoint
+ " can't be less than uptimeBeforeCheckpoint " + uptimeBeforeCheckpoint);
} else if (uptimeAfterCheckpoint >= (uptimeBeforeCheckpoint + adjustMillis)) {
System.out.println("FAILED: testMXBeanUpTime() - uptimeAfterCheckpoint " + uptimeAfterCheckpoint
+ " can't be greater than uptimeBeforeCheckpoint " + uptimeBeforeCheckpoint + " + " + adjustMillis);
} else {
System.out.println("PASSED: testMXBeanUpTime() - uptimeAfterCheckpoint " + uptimeAfterCheckpoint
+ " is less than uptimeBeforeCheckpoint " + uptimeBeforeCheckpoint + " + "
+ adjustMillis);
+ " is greater than uptimeBeforeCheckpoint " + uptimeBeforeCheckpoint);
}
}

public void testSystemNanoTimeJitPreCheckpointCompile() {
CRIUSupport criu = CRIUTestUtils.prepareCheckPointJVM(CRIUTestUtils.imagePath);
testSystemNanoTimeJitTestPreCheckpointPhase();
testSystemNanoTimeJitWarmupPhase();
CRIUTestUtils.checkPointJVM(imagePath, false);
CRIUTestUtils.checkPointJVMNoSetup(criu, CRIUTestUtils.imagePath, false);
testSystemNanoTimeJitTestPostCheckpointPhase();
}

public void testSystemNanoTimeJitPostCheckpointCompile() {
CRIUSupport criu = CRIUTestUtils.prepareCheckPointJVM(CRIUTestUtils.imagePath);
testSystemNanoTimeJitTestPreCheckpointPhase();
CRIUTestUtils.checkPointJVM(imagePath, false);
CRIUTestUtils.checkPointJVMNoSetup(criu, CRIUTestUtils.imagePath, false);
testSystemNanoTimeJitWarmupPhase();
testSystemNanoTimeJitTestPostCheckpointPhase();
}
Expand Down