RetryDirtyCalls.java revision 169
/*
* Copyright 1999 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/* @test
* @bug 4268258
* @summary When a DGC dirty call fails, RMI's client-side DGC implementation
* should attempt to retry the same dirty call a few times, at least until the
* known lease for that endpoint has expired, instead of just giving up
* renewing that lease at all after the first failure.
* @author Peter Jones (inspired by Adrian Colley's test case in 4268258)
*
* @build RetryDirtyCalls
* @build RetryDirtyCalls_Stub
*/
}
/** how long we wait before declaring that this test has passed */
private final static long TIMEOUT = 20000;
/** true if this object's unreferenced method has been called */
private boolean unreferenced = false;
/**
* Return this object. The need for this method is explained below.
*/
return this;
}
public void unreferenced() {
synchronized (this) {
unreferenced = true;
notifyAll();
}
}
/*
* Set properties to tweak DGC behavior so that this test will execute
* quickly: set the granted lease duration to 10 seconds, the interval
* that leases are checked to 3 seconds.
*/
/*
* Make idle connections time out almost instantly (0.1 seconds) so
* that the DGC implementation will have to make a new connection for
* each dirty call, thus going through the socket factory, where we
* can easily cause the operation to fail.
*/
try {
/*
* The stub returned by UnicastRemoteObject.exportObject() does
* not participate in DGC, but it does allow us to invoke a method
* on the remote object through RMI. Therefore, we invoke the
* getSelf() method through RMI, which returns an equivalent stub
* that does participate in DGC.
*/
/*
* Set the socket factory to cause 3 connections attempts in a row
* to fail before allowing a connection to succeed, expecting the
* client-side DGC implementation to make at least four attempts.
*/
final int FLAKE_FACTOR = 3;
boolean unreferenced;
synchronized (impl) {
if (timeToWait > 0) {
} else {
break;
}
}
}
if (unreferenced) {
throw new RuntimeException("remote object unreferenced");
}
if (createCount == 0) {
throw new RuntimeException("test socket factory never used");
/*
* The unreferenced method was not invoked for some reason,
* but the dirty calls were clearly not retried well enough.
*/
throw new RuntimeException(
"test failed because dirty calls not retried enough, " +
"but remote object not unreferenced");
}
"TEST PASSED: remote object not unreferenced");
} catch (Exception e) {
e.printStackTrace();
} finally {
/*
* When all is said and done, try to unexport the remote object
* so that the VM has a chance to exit.
*/
try {
} catch (Exception e) {
}
}
}
}
class TestSF extends RMISocketFactory {
private int flakeFactor = 0;
private int flakeState = 0;
private int createCount = 0;
public synchronized void setFlakeFactor(int newFlakeFactor) {
}
public synchronized int getCreateCount() {
return createCount;
}
throws IOException
{
createCount++;
if (++flakeState > flakeFactor) {
flakeState = 0;
}
if (flakeState == 0) {
} else {
throw new IOException("random network failure");
}
}
return new ServerSocket(port);
}
}