Fri, 24 Apr 2020 03:58:51 +0100
Merge
vromero@1482 | 1 | /* |
vromero@1482 | 2 | * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. |
vromero@1482 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
vromero@1482 | 4 | * |
vromero@1482 | 5 | * This code is free software; you can redistribute it and/or modify it |
vromero@1482 | 6 | * under the terms of the GNU General Public License version 2 only, as |
vromero@1482 | 7 | * published by the Free Software Foundation. |
vromero@1482 | 8 | * |
vromero@1482 | 9 | * This code is distributed in the hope that it will be useful, but WITHOUT |
vromero@1482 | 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
vromero@1482 | 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
vromero@1482 | 12 | * version 2 for more details (a copy is included in the LICENSE file that |
vromero@1482 | 13 | * accompanied this code). |
vromero@1482 | 14 | * |
vromero@1482 | 15 | * You should have received a copy of the GNU General Public License version |
vromero@1482 | 16 | * 2 along with this work; if not, write to the Free Software Foundation, |
vromero@1482 | 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
vromero@1482 | 18 | * |
vromero@1482 | 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
vromero@1482 | 20 | * or visit www.oracle.com if you need additional information or have any |
vromero@1482 | 21 | * questions. |
vromero@1482 | 22 | */ |
vromero@1482 | 23 | |
vromero@1482 | 24 | import java.io.PrintWriter; |
vromero@1482 | 25 | import java.io.StringWriter; |
vromero@1482 | 26 | import java.util.concurrent.ExecutorService; |
vromero@1482 | 27 | import java.util.concurrent.Executors; |
vromero@1482 | 28 | import java.util.concurrent.ThreadFactory; |
vromero@1520 | 29 | import java.util.concurrent.TimeUnit; |
vromero@1482 | 30 | import java.util.concurrent.atomic.AtomicInteger; |
vromero@1482 | 31 | import javax.tools.JavaCompiler; |
vromero@1482 | 32 | import javax.tools.StandardJavaFileManager; |
vromero@1482 | 33 | import javax.tools.ToolProvider; |
vromero@1482 | 34 | |
vromero@1482 | 35 | /** |
vromero@1482 | 36 | * An abstract superclass for threaded tests. |
vromero@1482 | 37 | * |
vromero@1482 | 38 | * This class will try to read a property named test.concurrency. |
vromero@1482 | 39 | * The property can be provided by passing this option to jtreg: |
vromero@1482 | 40 | * -javaoption:-Dtest.concurrency=# |
vromero@1482 | 41 | * |
vromero@1482 | 42 | * If the property is not set the class will use a heuristic to determine the |
vromero@1482 | 43 | * maximum number of threads that can be fired to execute a given test. |
vromero@1528 | 44 | * |
vromero@1528 | 45 | * This code will have to be revisited if jprt starts using concurrency for |
vromero@1528 | 46 | * for running jtreg tests. |
vromero@1482 | 47 | */ |
vromero@1482 | 48 | public abstract class JavacTestingAbstractThreadedTest { |
vromero@1482 | 49 | |
vromero@1528 | 50 | protected static AtomicInteger numberOfThreads = new AtomicInteger(); |
vromero@1528 | 51 | |
vromero@1482 | 52 | protected static int getThreadPoolSize() { |
vromero@1482 | 53 | Integer testConc = Integer.getInteger("test.concurrency"); |
vromero@1482 | 54 | if (testConc != null) return testConc; |
vromero@1482 | 55 | int cores = Runtime.getRuntime().availableProcessors(); |
vromero@1528 | 56 | numberOfThreads.set(Math.max(2, Math.min(8, cores / 2))); |
vromero@1528 | 57 | return numberOfThreads.get(); |
vromero@1482 | 58 | } |
vromero@1482 | 59 | |
vromero@1482 | 60 | protected static void checkAfterExec() throws InterruptedException { |
vromero@1482 | 61 | checkAfterExec(true); |
vromero@1482 | 62 | }; |
vromero@1482 | 63 | |
vromero@1482 | 64 | protected static boolean throwAssertionOnError = true; |
vromero@1482 | 65 | |
vromero@1482 | 66 | protected static boolean printAll = false; |
vromero@1482 | 67 | |
vromero@1482 | 68 | protected static StringWriter errSWriter = new StringWriter(); |
vromero@1482 | 69 | protected static PrintWriter errWriter = new PrintWriter(errSWriter); |
vromero@1482 | 70 | |
vromero@1482 | 71 | protected static StringWriter outSWriter = new StringWriter(); |
vromero@1482 | 72 | protected static PrintWriter outWriter = new PrintWriter(outSWriter); |
vromero@1482 | 73 | |
vromero@1482 | 74 | protected static void checkAfterExec(boolean printCheckCount) |
vromero@1482 | 75 | throws InterruptedException { |
vromero@1482 | 76 | pool.shutdown(); |
vromero@1520 | 77 | pool.awaitTermination(15, TimeUnit.MINUTES); |
vromero@1482 | 78 | if (errCount.get() > 0) { |
vromero@1482 | 79 | if (throwAssertionOnError) { |
vromero@1482 | 80 | closePrinters(); |
vromero@1482 | 81 | System.err.println(errSWriter.toString()); |
vromero@1482 | 82 | throw new AssertionError( |
vromero@1482 | 83 | String.format("%d errors found", errCount.get())); |
vromero@1482 | 84 | } else { |
vromero@1482 | 85 | System.err.println( |
vromero@1482 | 86 | String.format("%d errors found", errCount.get())); |
vromero@1482 | 87 | } |
vromero@1482 | 88 | } else if (printCheckCount) { |
vromero@1482 | 89 | outWriter.println("Total check executed: " + checkCount.get()); |
vromero@1482 | 90 | } |
vromero@1528 | 91 | /* |
vromero@1528 | 92 | * This output is for supporting debugging. It does not mean that a given |
vromero@1528 | 93 | * test had executed that number of threads concurrently. The value printed |
vromero@1528 | 94 | * here is the maximum possible amount. |
vromero@1528 | 95 | */ |
vromero@1482 | 96 | closePrinters(); |
vromero@1482 | 97 | if (printAll) { |
vromero@1482 | 98 | System.out.println(errSWriter.toString()); |
vromero@1482 | 99 | System.out.println(outSWriter.toString()); |
vromero@1482 | 100 | } |
vromero@1528 | 101 | System.out.println("Total number of threads in thread pool: " + |
vromero@1528 | 102 | numberOfThreads.get()); |
vromero@1482 | 103 | } |
vromero@1482 | 104 | |
vromero@1482 | 105 | protected static void closePrinters() { |
vromero@1482 | 106 | errWriter.close(); |
vromero@1482 | 107 | outWriter.close(); |
vromero@1482 | 108 | } |
vromero@1482 | 109 | |
vromero@1482 | 110 | protected static void processException(Throwable t) { |
vromero@1482 | 111 | errCount.incrementAndGet(); |
vromero@1482 | 112 | t.printStackTrace(errWriter); |
vromero@1482 | 113 | pool.shutdown(); |
vromero@1482 | 114 | } |
vromero@1482 | 115 | |
vromero@1482 | 116 | //number of checks executed |
vromero@1482 | 117 | protected static AtomicInteger checkCount = new AtomicInteger(); |
vromero@1482 | 118 | |
vromero@1482 | 119 | //number of errors found while running combo tests |
vromero@1482 | 120 | protected static AtomicInteger errCount = new AtomicInteger(); |
vromero@1482 | 121 | |
vromero@1482 | 122 | //create default shared JavaCompiler - reused across multiple compilations |
vromero@1482 | 123 | protected static JavaCompiler comp = ToolProvider.getSystemJavaCompiler(); |
vromero@1482 | 124 | |
vromero@1482 | 125 | protected static ExecutorService pool = Executors.newFixedThreadPool( |
vromero@1482 | 126 | getThreadPoolSize(), new ThreadFactory() { |
vromero@1482 | 127 | @Override |
vromero@1482 | 128 | public Thread newThread(Runnable r) { |
vromero@1482 | 129 | Thread t = new Thread(r); |
vromero@1482 | 130 | t.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { |
vromero@1482 | 131 | @Override |
vromero@1482 | 132 | public void uncaughtException(Thread t, Throwable e) { |
vromero@1482 | 133 | pool.shutdown(); |
vromero@1482 | 134 | errCount.incrementAndGet(); |
vromero@1482 | 135 | e.printStackTrace(System.err); |
vromero@1482 | 136 | } |
vromero@1482 | 137 | }); |
vromero@1482 | 138 | return t; |
vromero@1482 | 139 | } |
vromero@1482 | 140 | }); |
vromero@1482 | 141 | |
vromero@1482 | 142 | /* |
vromero@1482 | 143 | * File manager is not thread-safe so it cannot be re-used across multiple |
vromero@1482 | 144 | * threads. However we cache per-thread FileManager to avoid excessive |
vromero@1482 | 145 | * object creation |
vromero@1482 | 146 | */ |
vromero@1482 | 147 | protected static final ThreadLocal<StandardJavaFileManager> fm = |
vromero@1482 | 148 | new ThreadLocal<StandardJavaFileManager>() { |
vromero@1482 | 149 | @Override protected StandardJavaFileManager initialValue() { |
vromero@1482 | 150 | return comp.getStandardFileManager(null, null, null); |
vromero@1482 | 151 | } |
vromero@1482 | 152 | }; |
vromero@1482 | 153 | |
vromero@1482 | 154 | } |