Path: blob/master/test/hotspot/jtreg/vmTestbase/vm/runtime/defmeth/StressTest.java
41159 views
/*1* Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25*26* @modules java.base/jdk.internal.org.objectweb.asm:+open java.base/jdk.internal.org.objectweb.asm.util:+open27* @library /vmTestbase /test/lib28*29* @comment build retransform.jar in current dir30* @run driver vm.runtime.defmeth.shared.BuildJar31*32* @run driver jdk.test.lib.FileInstaller . .33*34* @run main/othervm/native35* -agentlib:redefineClasses36* -javaagent:retransform.jar37* vm.runtime.defmeth.StressTest38*/39package vm.runtime.defmeth;4041import java.util.ArrayList;42import java.util.Arrays;43import java.util.List;44import java.util.Random;4546import nsk.share.TestFailure;47import nsk.share.test.StressOptions;48import nsk.share.test.Stresser;49import vm.runtime.defmeth.shared.Constants;50import vm.runtime.defmeth.shared.DefMethTest;51import vm.runtime.defmeth.shared.ExecutionMode;52import vm.share.options.Option;53import vm.share.options.OptionSupport;54import vm.share.options.Options;55import jdk.test.lib.Utils;5657import static jdk.internal.org.objectweb.asm.Opcodes.*;58import static vm.runtime.defmeth.shared.DefMethTest.MAX_MAJOR_VER;59import static vm.runtime.defmeth.shared.DefMethTest.MIN_MAJOR_VER;6061/*62* Stress test for default methods implementation.63*64* Stress scenario is the following:65* - in multiple threads ...66* - ... continuously run random tests ...67* - ... in random configuration ...68* - ... until predefined period of time is over...69* - ... or any failures occured.70*/71public class StressTest implements Runnable {72@Options73private StressOptions opts = new StressOptions();7475@Option(name="seed", default_value="0", description="force deterministic behavior")76private long seed;7778@Option(name="noredefine", default_value="false", description="skip scenarios w/ class redefinition")79private boolean noRedefine;8081@Option(name="ignoreTestFailures", default_value="false", description="ignore failures of the executed tests")82private boolean ignoreTestFailures;8384class Worker extends Thread {85private final Random rand;8687private volatile DefMethTest failedTest;88private Throwable reason;89private volatile long executedTests = 0;9091public Worker(String id, long seed) {92setName(id);93this.rand = new Random(seed);94}9596@Override97public void run() {98while (!Thread.interrupted()) {99int idx = rand.nextInt(testlist.size());100DefMethTest test = testlist.get(idx);101try {102test.run();103executedTests++;104if (test.isFailed()) {105throw new TestFailure(test.toString());106}107} catch (Throwable e) {108if (!ignoreTestFailures) {109failedTest = test;110reason = e;111break;112}113}114}115}116117public boolean isFailed() { return failedTest != null; }118public Throwable getReason() { return reason; }119public DefMethTest getFailedTest() { return failedTest; }120public long getExecutedTests() { return executedTests; }121}122123private List<DefMethTest> testlist;124125private Worker[] workers;126127Stresser stresser;128129public static void main(String[] args) {130StressTest test = new StressTest();131OptionSupport.setupAndRun(test, args);132}133134@Override135public void run() {136configureTests();137startWorkers();138139stresser = new Stresser(opts);140try {141stresser.start(0);142while (workersAlive() && stresser.continueExecution()) {143printStats();144145try {146Thread.sleep(1000);147} catch (InterruptedException ex) {}148}149} finally {150interruptWorkers();151joinWorkers();152153stresser.finish();154}155}156157private void configureTests() {158int[] majorVerValues = new int[MAX_MAJOR_VER - MIN_MAJOR_VER + 1];159for (int i = 0; i< majorVerValues.length; i++) {160majorVerValues[i] = MIN_MAJOR_VER + i;161}162163int[] flagsValues = new int[] {0, ACC_SYNCHRONIZED};164165boolean[] doRedefineValues;166if (noRedefine) {167doRedefineValues = new boolean[] { false };168} else {169doRedefineValues = new boolean[] { false, true };170}171172// Upper limit for test count173int testCount = DefMethTest.getTests().size() * majorVerValues.length174* flagsValues.length * doRedefineValues.length;175176testlist = new ArrayList<>(testCount);177178// Enumerate all tests in all possible modes179for (Class<? extends DefMethTest> testClass : DefMethTest.getTests()) {180for (ExecutionMode mode : ExecutionMode.values()) {181// Skip REDEFINITION execmode, the top README file indicates that it isn't a182// valid execution mode and there's also no code supporting this in the test generator.183if ("REDEFINITION".equals(mode.toString())) {184continue;185}186187for (int majorVer : majorVerValues) {188for (int flags : flagsValues ) {189for (boolean redefine : doRedefineValues) {190// RedefineTest isn't applicable to reflection-based execution scenario (REDEFINE & INVOKE_WITH_ARGS)191if (testClass == RedefineTest.class && mode.isReflectionBased()) {192continue;193}194195// Only run the RedefineTest tests when redefining196if (!redefine && testClass == RedefineTest.class) {197continue;198}199200try {201DefMethTest test = testClass.getDeclaredConstructor().newInstance();202203OptionSupport.setup(test, new String[] {204"-execMode", mode.toString(),205"-ver", Integer.toString(majorVer),206"-flags", Integer.toString(flags),207"-redefine", Boolean.toString(redefine),208"-silent",209"-failfast"});210211testlist.add(test);212} catch (ReflectiveOperationException ex) {213throw new TestFailure(ex);214}215}216}217}218}219}220221System.out.printf("Testlist size: %d\n", testlist.size());222}223224private void startWorkers() {225Random rand;226if (seed == 0) {227seed = Utils.SEED;228}229230System.out.printf("Seed: %d\n", seed);231rand = new Random(seed);232233int threadsCount = opts.getThreadsFactor();234if (threadsCount == 1) {235threadsCount = 5;236}237238workers = new Worker[threadsCount];239240System.out.printf("Spawning %d workers...\n", workers.length);241242for (int i = 0; i < workers.length; i++) {243workers[i] = new Worker(244String.format("Worker #%d/%d", i+1, workers.length),245rand.nextLong());246}247248for (Worker worker : workers) {249worker.start();250}251}252253private void interruptWorkers() {254for (Worker worker : workers) {255worker.interrupt();256}257}258259private void joinWorkers() {260boolean isFailed = false;261262for (Worker worker : workers) {263while (worker.isAlive()) {264try {265worker.join();266} catch (InterruptedException e) {}267}268269System.out.printf("%s: %s (executed: %d)\n",270worker.getName(),271worker.isFailed() ? "FAILED: " + worker.getFailedTest() : "PASSED",272worker.getExecutedTests());273274if (worker.isFailed()) {275if (Constants.PRINT_STACK_TRACE) {276worker.getReason().printStackTrace();277}278279isFailed = true;280}281}282283if (isFailed) {284throw new TestFailure("Some of the worker threads failed.");285}286}287288private boolean workersAlive() {289for (Worker worker : workers) {290if (!worker.isAlive()) {291return false;292}293}294295return true;296}297298private void printStats() {299long[] counts = new long[workers.length];300for (int i = 0; i < counts.length; i++) {301counts[i] = workers[i].executedTests;302}303304StringBuilder msg = new StringBuilder();305msg.append(stresser.getTimeLeft() / 1000).append("s left: ");306msg.append(Arrays.toString(counts));307308System.out.println(msg);309}310}311312313