mirror of
https://github.com/openjdk/jdk.git
synced 2026-05-17 17:07:53 +00:00
8170896: TEST_BUG: java/rmi/server/Unreferenced/leaseCheckInterval/LeaseCheckInterval.java failed with unreferenced() not invoked after 20.0 seconds
Reviewed-by: smarks, msheppar, dfuchs
This commit is contained in:
parent
f43fbf0823
commit
efa16e9e5f
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -31,10 +31,9 @@
|
||||
* may be delayed longer than expected. While this is not a spec violation
|
||||
* (because there are no timeliness guarantees for any of these garbage
|
||||
* collection-related events), the user might expect that an unreferenced()
|
||||
* invocation for an object whose last client has terminated abnorally
|
||||
* invocation for an object whose last client has terminated abnormally
|
||||
* should occur on relatively the same time order as the lease value
|
||||
* granted.
|
||||
* @author Peter Jones
|
||||
*
|
||||
* @library ../../../testlibrary
|
||||
* @modules java.rmi/sun.rmi.registry
|
||||
@ -47,40 +46,39 @@
|
||||
|
||||
import java.rmi.Remote;
|
||||
import java.rmi.RemoteException;
|
||||
import java.rmi.registry.LocateRegistry;
|
||||
import java.rmi.registry.Registry;
|
||||
import java.rmi.server.UnicastRemoteObject;
|
||||
import java.rmi.server.Unreferenced;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
public class LeaseCheckInterval implements Remote, Unreferenced {
|
||||
|
||||
public static final String BINDING = "LeaseCheckInterval";
|
||||
// lease expiry time (milliseconds)
|
||||
private static final long LEASE_VALUE = 10000;
|
||||
private static final long TIMEOUT = 20000;
|
||||
// the maximum allowed duration between the lease expiration and
|
||||
// the Unreferenced.unreferenced() callback method to be invoked
|
||||
private static final Duration EXPECTED_MAX_DURATION = Duration.ofMinutes(1);
|
||||
|
||||
private Object lock = new Object();
|
||||
private boolean unreferencedInvoked = false;
|
||||
// will be counted down when Unreferenced.unreferenced() is invoked
|
||||
private static final CountDownLatch callbackInvocationLatch = new CountDownLatch(1);
|
||||
|
||||
@Override
|
||||
public void unreferenced() {
|
||||
System.err.println("unreferenced() method invoked");
|
||||
synchronized (lock) {
|
||||
unreferencedInvoked = true;
|
||||
lock.notify();
|
||||
}
|
||||
System.err.println("[" + Instant.now() + "] unreferenced() method invoked");
|
||||
callbackInvocationLatch.countDown();
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
System.err.println("\nRegression test for bug 4285878\n");
|
||||
|
||||
/*
|
||||
* Set the duration of leases granted to a very small value, so that
|
||||
* we can test if expirations are detected in a roughly comparable
|
||||
* time.
|
||||
*/
|
||||
System.setProperty("java.rmi.dgc.leaseValue",
|
||||
String.valueOf(LEASE_VALUE));
|
||||
|
||||
System.setProperty("java.rmi.dgc.leaseValue", String.valueOf(LEASE_VALUE));
|
||||
System.err.println("running test with java.rmi.dgc.leaseValue set to " + LEASE_VALUE);
|
||||
LeaseCheckInterval obj = new LeaseCheckInterval();
|
||||
JavaVM jvm = null;
|
||||
|
||||
@ -90,37 +88,32 @@ public class LeaseCheckInterval implements Remote, Unreferenced {
|
||||
|
||||
Registry localRegistry = TestLibrary.createRegistryOnEphemeralPort();
|
||||
int registryPort = TestLibrary.getRegistryPort(localRegistry);
|
||||
System.err.println("created local registry");
|
||||
System.err.println("created local registry on port " + registryPort);
|
||||
|
||||
localRegistry.bind(BINDING, obj);
|
||||
System.err.println("bound remote object in local registry");
|
||||
|
||||
synchronized (obj.lock) {
|
||||
System.err.println("starting remote client VM...");
|
||||
jvm = new JavaVM("SelfTerminator", "-Drmi.registry.port=" +
|
||||
registryPort, "");
|
||||
jvm.start();
|
||||
|
||||
System.err.println("waiting for unreferenced() callback...");
|
||||
obj.lock.wait(TIMEOUT);
|
||||
|
||||
if (obj.unreferencedInvoked) {
|
||||
System.err.println("TEST PASSED: " +
|
||||
"unreferenced() invoked in timely fashion");
|
||||
} else {
|
||||
throw new RuntimeException(
|
||||
"TEST FAILED: unreferenced() not invoked after " +
|
||||
((double) TIMEOUT / 1000.0) + " seconds");
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
if (e instanceof RuntimeException) {
|
||||
throw (RuntimeException) e;
|
||||
} else {
|
||||
throw new RuntimeException(
|
||||
"TEST FAILED: unexpected exception: " + e.toString());
|
||||
System.err.println("starting remote client VM...");
|
||||
jvm = new JavaVM("SelfTerminator", "-Drmi.registry.port=" + registryPort, "");
|
||||
// launch the self terminating java application which will lookup
|
||||
// the bound object (thus creating a lease) and then terminate itself (thus
|
||||
// creating the condition for a lease expiry).
|
||||
jvm.start();
|
||||
final Instant startTime = Instant.now();
|
||||
System.err.println("waiting for SelfTerminator process to complete");
|
||||
final int exitCode = jvm.waitFor();
|
||||
if (exitCode != 0) {
|
||||
throw new AssertionError("SelfTerminator process exited with" +
|
||||
" a non-zero exit code: " + exitCode);
|
||||
}
|
||||
System.err.println("SelfTerminator process completed in "
|
||||
+ Duration.between(startTime, Instant.now())
|
||||
+ ", now waiting for Unreferenced.unreferenced() callback to be invoked");
|
||||
callbackInvocationLatch.await();
|
||||
final Instant waitEndedAt = Instant.now();
|
||||
final Duration waitDuration = assertWithinExpectedTimeLimit(waitEndedAt, startTime);
|
||||
System.err.println("TEST PASSED: unreferenced() invoked in timely" +
|
||||
" fashion (duration=" + waitDuration + ")");
|
||||
} finally {
|
||||
if (jvm != null) {
|
||||
jvm.destroy();
|
||||
@ -135,4 +128,22 @@ public class LeaseCheckInterval implements Remote, Unreferenced {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Verifies that the duration between the lease expiration and the callback
|
||||
* invocation is within the expected limit. Throws an exception if the wait
|
||||
* duration is larger than expected limit, else returns the actual wait duration.
|
||||
*/
|
||||
private static Duration assertWithinExpectedTimeLimit(final Instant waitEndedAt,
|
||||
final Instant terminationStartedAt) {
|
||||
|
||||
final Duration waitDuration = Duration.between(terminationStartedAt, waitEndedAt);
|
||||
System.out.println("wait completed in " + waitDuration);
|
||||
if (waitDuration.compareTo(EXPECTED_MAX_DURATION) > 0) {
|
||||
throw new RuntimeException("Took unexpectedly long (duration=" +
|
||||
waitDuration + ") to invoke Unreferenced.unreferenced()," +
|
||||
" expected max duration=" + EXPECTED_MAX_DURATION);
|
||||
}
|
||||
return waitDuration;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -21,26 +21,32 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
import java.rmi.Remote;
|
||||
import java.rmi.registry.LocateRegistry;
|
||||
import java.rmi.registry.Registry;
|
||||
import java.time.Instant;
|
||||
|
||||
public class SelfTerminator {
|
||||
|
||||
public static void main(String[] args) {
|
||||
public static void main(String[] args) throws Exception {
|
||||
try {
|
||||
log("main() invoked");
|
||||
int registryPort =
|
||||
Integer.parseInt(System.getProperty("rmi.registry.port"));
|
||||
Registry registry =
|
||||
LocateRegistry.getRegistry("", registryPort);
|
||||
Remote stub = registry.lookup(LeaseCheckInterval.BINDING);
|
||||
log("looked up binding, now terminating the process");
|
||||
Runtime.getRuntime().halt(0);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} catch (Throwable t) {
|
||||
log("failure: " + t);
|
||||
t.printStackTrace();
|
||||
throw t; // propagate any failures and fail the process
|
||||
}
|
||||
}
|
||||
|
||||
private static void log(final String message) {
|
||||
final Instant now = Instant.now();
|
||||
System.err.println("[" + now + "] " + SelfTerminator.class.getName() + " - " + message);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user