test/java/lang/invoke/LFCaching/LambdaFormTestCase.java

Print this page

        

@@ -29,10 +29,11 @@
 import java.lang.reflect.Method;
 import java.util.Collection;
 import java.util.List;
 import java.util.function.Function;
 import jdk.testlibrary.Utils;
+import jdk.testlibrary.TimeLimitedRunner;
 
 /**
  * Lambda forms caching test case class. Contains all necessary test routines to
  * test lambda forms caching in method handles returned by methods of
  * MethodHandles class.

@@ -43,11 +44,11 @@
 
     private final static String METHOD_HANDLE_CLASS_NAME = "java.lang.invoke.MethodHandle";
     private final static String INTERNAL_FORM_METHOD_NAME = "internalForm";
     private static final double ITERATIONS_TO_CODE_CACHE_SIZE_RATIO
             = 45 / (128.0 * 1024 * 1024);
-    private static final long TIMEOUT = Utils.adjustTimeout(Utils.DEFAULT_TEST_TIMEOUT);
+    private static final long TIMEOUT = Helper.IS_THOROUGH ? 0L : (long) (Utils.adjustTimeout(Utils.DEFAULT_TEST_TIMEOUT) * 0.9);
 
     /**
      * Reflection link to {@code j.l.i.MethodHandle.internalForm} method. It is
      * used to get a lambda form from a method handle.
      */

@@ -73,46 +74,24 @@
         }
     }
 
     private final TestMethods testMethod;
     private long gcCountAtStart;
-    /**
-     * Test case constructor. Generates test cases with random method types for
-     * given methods form {@code j.l.i.MethodHandles} class.
-     *
-     * @param testMethod A method from {@code j.l.i.MethodHandles} class which
-     * returns a {@code j.l.i.MethodHandle}.
-     */
-    protected LambdaFormTestCase(TestMethods testMethod) {
-        this.testMethod = testMethod;
-        this.gcCountAtStart = gcCount();
-    }
-
-    public TestMethods getTestMethod() {
-        return testMethod;
-    }
 
-    protected boolean noGCHappened() {
-        return gcCount() == gcCountAtStart;
-    }
+    private static class TestRun {
 
-    /**
-     * Routine that executes a test case.
-     */
-    public abstract void doTest();
-
-    /**
-     * Runs a number of test cases defined by the size of testCases list.
-     *
-     * @param ctor constructor of LambdaFormCachingTest or its child classes
-     * object.
-     * @param testMethods list of test methods
-     */
-    public static void runTests(Function<TestMethods, LambdaFormTestCase> ctor, Collection<TestMethods> testMethods) {
-        boolean passed = true;
-        int testCounter = 0;
-        int failCounter = 0;
+        final Function<TestMethods, LambdaFormTestCase> ctor;
+        final Collection<TestMethods> testMethods;
+        final long totalIterations;
+        long doneIterations;
+        long testCounter;
+        long failCounter;
+        boolean passed;
+
+        TestRun(Function<TestMethods, LambdaFormTestCase> ctor, Collection<TestMethods> testMethods) {
+            this.ctor = ctor;
+            this.testMethods = testMethods;
         long testCaseNum = testMethods.size();
         long iterations = Math.max(1, Helper.TEST_LIMIT / testCaseNum);
         System.out.printf("Number of iterations according to -DtestLimit is %d (%d cases)%n",
                 iterations, iterations * testCaseNum);
         HotSpotDiagnosticMXBean hsDiagBean = ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class);

@@ -138,41 +117,92 @@
             iterations = 1;
         }
         System.out.printf("Number of iterations is set to %d (%d cases)%n",
                 iterations, iterations * testCaseNum);
         System.out.flush();
-        long startTime = System.currentTimeMillis();
-        for (long i = 0; i < iterations; i++) {
-            System.err.println(String.format("Iteration %d:", i));
+            totalIterations = iterations;
+            doneIterations = 0L;
+            testCounter = 0L;
+            failCounter = 0L;
+            passed = true;
+        }
+        
+        Boolean doIteration() {
+            if (doneIterations >= totalIterations) {
+                return false;
+            }
+            System.err.println(String.format("Iteration %d:", doneIterations));
             for (TestMethods testMethod : testMethods) {
                 LambdaFormTestCase testCase = ctor.apply(testMethod);
                 try {
                     System.err.printf("Tested LF caching feature with MethodHandles.%s method.%n",
                             testCase.getTestMethod().name);
                     testCase.doTest();
                     System.err.println("PASSED");
                 } catch (Throwable t) {
                     t.printStackTrace();
-                    System.err.println("FAILED");
+                    System.err.printf("FAILED. Caused by %s%n", t.getMessage());
                     passed = false;
                     failCounter++;
                 }
                 testCounter++;
             }
-            long passedTime = System.currentTimeMillis() - startTime;
-            long avgIterTime = passedTime / (i + 1);
-            long remainTime = TIMEOUT - passedTime;
-            if (avgIterTime > 2 * remainTime) {
-                System.err.printf("Stopping iterations because of lack of time.%n"
-                        + "Increase timeout factor for more iterations.%n");
-                break;
-            }
+            doneIterations++;
+            return true;
         }
+        
+        void checkPassed() {
         if (!passed) {
             throw new Error(String.format("%d of %d test cases FAILED! %n"
                     + "Rerun the test with the same \"-Dseed=\" option as in the log file!",
                     failCounter, testCounter));
         } else {
-            System.err.println(String.format("All %d test cases PASSED!", testCounter));
+                System.err.printf("All %d test cases PASSED!%n", testCounter);
+            }
+        }
+    }
+
+    /**
+     * Test case constructor. Generates test cases with random method types for
+     * given methods form {@code j.l.i.MethodHandles} class.
+     *
+     * @param testMethod A method from {@code j.l.i.MethodHandles} class which
+     * returns a {@code j.l.i.MethodHandle}.
+     */
+    protected LambdaFormTestCase(TestMethods testMethod) {
+        this.testMethod = testMethod;
+        this.gcCountAtStart = gcCount();
+    }
+
+    public TestMethods getTestMethod() {
+        return testMethod;
+    }
+
+    protected boolean noGCHappened() {
+        return gcCount() == gcCountAtStart;
+    }
+
+    /**
+     * Routine that executes a test case.
+     */
+    public abstract void doTest();
+
+    /**
+     * Runs a number of test cases defined by the size of testCases list.
+     *
+     * @param ctor constructor of LambdaFormCachingTest or its child classes
+     * object.
+     * @param testMethods list of test methods
+     */
+    public static void runTests(Function<TestMethods, LambdaFormTestCase> ctor, Collection<TestMethods> testMethods) {
+        LambdaFormTestCase.TestRun run =
+                new LambdaFormTestCase.TestRun(ctor, testMethods);
+        TimeLimitedRunner runner = new TimeLimitedRunner(TIMEOUT, 4.0d, run::doIteration);
+        try {
+            runner.call();
+        } catch (Exception ex) {
+            System.err.println("FAILED");
+            throw new Error("Unexpected error!", ex);
         }
+        run.checkPassed();
     }
 }