jdk/test/java/rmi/dgc/retryDirtyCalls/RetryDirtyCalls.java
changeset 309 bda219d843f6
parent 2 90ce3da70b43
child 715 f16baef3a20e
equal deleted inserted replaced
308:33a1639d64a5 309:bda219d843f6
     1 /* 
     1 /*
     2  * Copyright 1999 Sun Microsystems, Inc.  All Rights Reserved.
     2  * Copyright 1999 Sun Microsystems, Inc.  All Rights Reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     6  * under the terms of the GNU General Public License version 2 only, as
    53 
    53 
    54     /**
    54     /**
    55      * Return this object.  The need for this method is explained below.
    55      * Return this object.  The need for this method is explained below.
    56      */
    56      */
    57     public Self getSelf() {
    57     public Self getSelf() {
    58 	return this;
    58         return this;
    59     }
    59     }
    60 
    60 
    61     public void unreferenced() {
    61     public void unreferenced() {
    62 	synchronized (this) {
    62         synchronized (this) {
    63 	    unreferenced = true;
    63             unreferenced = true;
    64 	    notifyAll();
    64             notifyAll();
    65 	}
    65         }
    66     }
    66     }
    67 
    67 
    68     public static void main(String[] args) {
    68     public static void main(String[] args) {
    69 
    69 
    70 	System.err.println("\nRegression test for bug 4268258\n");
    70         System.err.println("\nRegression test for bug 4268258\n");
    71 
    71 
    72 	/*
    72         /*
    73 	 * Set properties to tweak DGC behavior so that this test will execute
    73          * Set properties to tweak DGC behavior so that this test will execute
    74 	 * quickly: set the granted lease duration to 10 seconds, the interval
    74          * quickly: set the granted lease duration to 10 seconds, the interval
    75 	 * that leases are checked to 3 seconds.
    75          * that leases are checked to 3 seconds.
    76 	 */
    76          */
    77 	System.setProperty("java.rmi.dgc.leaseValue", "10000");
    77         System.setProperty("java.rmi.dgc.leaseValue", "10000");
    78 	System.setProperty("sun.rmi.dgc.checkInterval", "3000");
    78         System.setProperty("sun.rmi.dgc.checkInterval", "3000");
    79 
    79 
    80 	/*
    80         /*
    81 	 * Make idle connections time out almost instantly (0.1 seconds) so
    81          * Make idle connections time out almost instantly (0.1 seconds) so
    82 	 * that the DGC implementation will have to make a new connection for
    82          * that the DGC implementation will have to make a new connection for
    83 	 * each dirty call, thus going through the socket factory, where we
    83          * each dirty call, thus going through the socket factory, where we
    84 	 * can easily cause the operation to fail.
    84          * can easily cause the operation to fail.
    85 	 */
    85          */
    86 	System.setProperty("sun.rmi.transport.connectionTimeout", "100");
    86         System.setProperty("sun.rmi.transport.connectionTimeout", "100");
    87 
    87 
    88 	RetryDirtyCalls impl = new RetryDirtyCalls();
    88         RetryDirtyCalls impl = new RetryDirtyCalls();
    89 
    89 
    90 	try {
    90         try {
    91 	    TestSF sf = new TestSF();
    91             TestSF sf = new TestSF();
    92 	    RMISocketFactory.setSocketFactory(sf);
    92             RMISocketFactory.setSocketFactory(sf);
    93 
    93 
    94 	    /*
    94             /*
    95 	     * The stub returned by UnicastRemoteObject.exportObject() does
    95              * The stub returned by UnicastRemoteObject.exportObject() does
    96 	     * not participate in DGC, but it does allow us to invoke a method
    96              * not participate in DGC, but it does allow us to invoke a method
    97 	     * on the remote object through RMI.  Therefore, we invoke the
    97              * on the remote object through RMI.  Therefore, we invoke the
    98 	     * getSelf() method through RMI, which returns an equivalent stub
    98              * getSelf() method through RMI, which returns an equivalent stub
    99 	     * that does participate in DGC.
    99              * that does participate in DGC.
   100 	     */
   100              */
   101 	    Self stub = (Self) UnicastRemoteObject.exportObject(impl);
   101             Self stub = (Self) UnicastRemoteObject.exportObject(impl);
   102 	    Self dgcStub = stub.getSelf();
   102             Self dgcStub = stub.getSelf();
   103 	    stub = null;		// in case 4114579 has been fixed
   103             stub = null;                // in case 4114579 has been fixed
   104 
   104 
   105 	    /*
   105             /*
   106 	     * Set the socket factory to cause 3 connections attempts in a row
   106              * Set the socket factory to cause 3 connections attempts in a row
   107 	     * to fail before allowing a connection to succeed, expecting the
   107              * to fail before allowing a connection to succeed, expecting the
   108 	     * client-side DGC implementation to make at least four attempts.
   108              * client-side DGC implementation to make at least four attempts.
   109 	     */
   109              */
   110 	    final int FLAKE_FACTOR = 3;
   110             final int FLAKE_FACTOR = 3;
   111 	    sf.setFlakeFactor(FLAKE_FACTOR);
   111             sf.setFlakeFactor(FLAKE_FACTOR);
   112 
   112 
   113 	    long deadline = System.currentTimeMillis() + TIMEOUT;
   113             long deadline = System.currentTimeMillis() + TIMEOUT;
   114 	    boolean unreferenced;
   114             boolean unreferenced;
   115 
   115 
   116 	    synchronized (impl) {
   116             synchronized (impl) {
   117 		while (!(unreferenced = impl.unreferenced)) {
   117                 while (!(unreferenced = impl.unreferenced)) {
   118 		    long timeToWait = deadline - System.currentTimeMillis();
   118                     long timeToWait = deadline - System.currentTimeMillis();
   119 		    if (timeToWait > 0) {
   119                     if (timeToWait > 0) {
   120 			impl.wait(timeToWait);
   120                         impl.wait(timeToWait);
   121 		    } else {
   121                     } else {
   122 			break;
   122                         break;
   123 		    }
   123                     }
   124 		}
   124                 }
   125 	    }
   125             }
   126 
   126 
   127 	    if (unreferenced) {
   127             if (unreferenced) {
   128 		throw new RuntimeException("remote object unreferenced");
   128                 throw new RuntimeException("remote object unreferenced");
   129 	    }
   129             }
   130 
   130 
   131 	    int createCount = sf.getCreateCount();
   131             int createCount = sf.getCreateCount();
   132 	    if (createCount == 0) {
   132             if (createCount == 0) {
   133 		throw new RuntimeException("test socket factory never used");
   133                 throw new RuntimeException("test socket factory never used");
   134 	    } else if (createCount < (FLAKE_FACTOR + 3)) {
   134             } else if (createCount < (FLAKE_FACTOR + 3)) {
   135 		/*
   135                 /*
   136 		 * The unreferenced method was not invoked for some reason,
   136                  * The unreferenced method was not invoked for some reason,
   137 		 * but the dirty calls were clearly not retried well enough.
   137                  * but the dirty calls were clearly not retried well enough.
   138 		 */
   138                  */
   139 		throw new RuntimeException(
   139                 throw new RuntimeException(
   140 		    "test failed because dirty calls not retried enough, " +
   140                     "test failed because dirty calls not retried enough, " +
   141 		    "but remote object not unreferenced");
   141                     "but remote object not unreferenced");
   142 	    }
   142             }
   143 
   143 
   144 	    System.err.println(
   144             System.err.println(
   145 		"TEST PASSED: remote object not unreferenced");
   145                 "TEST PASSED: remote object not unreferenced");
   146 
   146 
   147 	} catch (Exception e) {
   147         } catch (Exception e) {
   148 	    e.printStackTrace();
   148             e.printStackTrace();
   149 	    throw new RuntimeException("TEST FAILED: " + e.toString());
   149             throw new RuntimeException("TEST FAILED: " + e.toString());
   150 	} finally {
   150         } finally {
   151 	    /*
   151             /*
   152 	     * When all is said and done, try to unexport the remote object
   152              * When all is said and done, try to unexport the remote object
   153 	     * so that the VM has a chance to exit.
   153              * so that the VM has a chance to exit.
   154 	     */
   154              */
   155 	    try {
   155             try {
   156 		UnicastRemoteObject.unexportObject(impl, true);
   156                 UnicastRemoteObject.unexportObject(impl, true);
   157 	    } catch (Exception e) {
   157             } catch (Exception e) {
   158 	    }
   158             }
   159 	}
   159         }
   160     }
   160     }
   161 }
   161 }
   162 
   162 
   163 class TestSF extends RMISocketFactory {
   163 class TestSF extends RMISocketFactory {
   164 
   164 
   167     private int flakeState = 0;
   167     private int flakeState = 0;
   168 
   168 
   169     private int createCount = 0;
   169     private int createCount = 0;
   170 
   170 
   171     public synchronized void setFlakeFactor(int newFlakeFactor) {
   171     public synchronized void setFlakeFactor(int newFlakeFactor) {
   172 	flakeFactor = newFlakeFactor;
   172         flakeFactor = newFlakeFactor;
   173     }
   173     }
   174 
   174 
   175     public synchronized int getCreateCount() {
   175     public synchronized int getCreateCount() {
   176 	return createCount;
   176         return createCount;
   177     }
   177     }
   178 
   178 
   179     public synchronized Socket createSocket(String host, int port)
   179     public synchronized Socket createSocket(String host, int port)
   180 	throws IOException
   180         throws IOException
   181     {
   181     {
   182 	createCount++;
   182         createCount++;
   183 
   183 
   184 	if (++flakeState > flakeFactor) {
   184         if (++flakeState > flakeFactor) {
   185 	    flakeState = 0;
   185             flakeState = 0;
   186 	}
   186         }
   187 
   187 
   188 	if (flakeState == 0) {
   188         if (flakeState == 0) {
   189 	    return new Socket(host, port);
   189             return new Socket(host, port);
   190 	} else {
   190         } else {
   191 	    throw new IOException("random network failure");
   191             throw new IOException("random network failure");
   192 	}
   192         }
   193     }
   193     }
   194 
   194 
   195     public ServerSocket createServerSocket(int port) throws IOException {
   195     public ServerSocket createServerSocket(int port) throws IOException {
   196 	return new ServerSocket(port);
   196         return new ServerSocket(port);
   197     }
   197     }
   198 }
   198 }