Path: blob/master/test/hotspot/jtreg/vmTestbase/vm/mlvm/share/MlvmTest.java
41155 views
/*1* Copyright (c) 2010, 2020, 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*/2223package vm.mlvm.share;2425import java.util.Random;26import java.util.concurrent.atomic.AtomicBoolean;27import java.util.List;28import java.util.ArrayList;29import java.util.Arrays;3031import nsk.share.ArgumentParser;32import nsk.share.Log;33import nsk.share.Log.TraceLevel;34import nsk.share.test.StressOptions;35import nsk.share.test.Stresser;36import vm.share.options.Option;37import vm.mlvm.share.ExceptionsOptionObjectFactory;3839/**40* The base class for MLVM tests.41* Subclasses need to override {@link #run()} method to implement test logic.42*/43public abstract class MlvmTest {4445/**46* MLVM tests are expected to implement this method to provide the logic.47*48* @return true if test passed, false if failed49* @throws Throwable any subclass of Throwable to indicate test failure50*/51public abstract boolean run() throws Throwable;5253/** Performs pre-run (prolog) actions in MlvmTest subclasses.54* The default implementation does nothing.55* Sublcasses may override this method to perform custom actions after test is initialized56* (initialization order is described in MlvmTestExecutor class) but before {@link run()} method is invoked.57* @throws Throwable in case of problem, which is interpreted as a test failure58* @see MlvmTestExecutor59*/60protected void initializeTest() throws Throwable {61}6263/** Performs post-run (epilog) actions.64* This method is executed after the {@link #run()} method.65* Does nothing by default.66* Subclasses may override this method when some finalization actions are required.67* Test fails if this method throws exception.68* @param result test execution status: true, if test passed, false otherwise69* @throws Throwable may throw any subclass of Throwable to indicate test failure (regardless of run() method result)70* @see MlvmTestExecutor71*/72protected void finalizeTest(boolean result) throws Throwable {73}7475/**76* Resets the tests between runs.77* You may override this method, especially if your test supports -stressRunsFactor option78* @throws Throwable may throw any subclass of Throwable to indicate test failure (regardless of run() method result)79* @see MlvmTestExecutor80*/81protected void resetTest() throws Throwable {82testMarkedFailed = false;83}8485// Options for all MlvmTests86@Option(name = "requireExceptions", default_value = "", factory = ExceptionsOptionObjectFactory.class,87description = "Specifying this option turns test into negative one: "88+ "the specified exception class names separated with commas have to be caught for the test to pass")89private List<Class<? extends Throwable>> requiredExceptionClasses = new ArrayList<>();9091@Option(name = "runs", default_value = "1", description = "How many times the test should be re-run")92private int runs = 1;9394// Some internal stuff95private static MlvmTest instance;9697/**98* Sets internal static variable to instance of the test.99* Used in debugger/debuggee tests.100* Not intended to work if there are several MlvmTests created.101* @param inst Instance of the test102*/103public static void setInstance(MlvmTest inst) {104instance = inst;105}106107/**108* Returns internal static variable holding instance of the test, which was set using {@link #setInstance()}.109* Used in debugger/debuggee tests.110* Not intended to work if there are several MlvmTests created.111* @return Instance of the test112*/113public static MlvmTest getInstance() {114return instance;115}116117private static String name = "Test";118119/**120* Sets internal static variable to the name of the test.121* Debugger/debuggee MLVM tests use this feature to differentiate logging from debugger and debuggee122* Not intended to work if there are several MlvmTests created123* @param n Name of the test124*/125public static void setName(String n) {126name = n;127}128129/**130* Returns internal static variable holding the name of the test.131* Debugger/debuggee MLVM tests use this feature to differentiate logging from debugger and debuggee132* Not intended to work if there are several MlvmTests created133* @return Name of the test134*/135public static String getName() {136return name;137}138139/**140* Sets number of test runs141* @param r Number of test runs142*/143public void setRunsNumber(int r) {144runs = r;145}146147/**148* Return number of test runs149* @return Number of test runs150*/151public int getRunsNumber() {152return runs;153}154155// Sugar...156/**157* Provides Random Number Generator for the test. The tests should always use this generator158* to guarantee repeatability, especially in multi-threaded usages159* @return Random number generator for this thread, seeded with command-line option, if provided160*/161public static Random getRNG() {162return Env.getRNG();163}164165/**166* Returns logger, which is used in all MLVM framework. This guarantees correct ordering of messages167* @return Logger object168*/169public static Log getLog() {170return Env.getLog();171}172173/**174* ArgumentParser is the old implementation of command-line parser (the new tests should use175* vm.share.options framework). However it is maintained, because nsk JDI/SAJDI framework is built176* on ArgumentParser.177* @return ArgumentParser object created with command-line options (see {@link MlvmTestExecutor}178* for details)179*/180public static ArgumentParser getArgumentParser() {181return Env.getArgParser();182}183184// ...and spice185186/* Makes the test "negative": one of the specified exception classes has to be thrown by the test to pass.187* Test fails if exception has not been thrown.188* Boolean value returned by {@link run()} method is ignored.189* Calling {@link #markTestFailed()} causes test to fail anyway.190* <p>191* Invoke this method BEFORE run() method (e.g., in prolog) to instruct launcher192* to anticipate the exception instead of the positive (normal) mode.193* @param classes The list of exception classes194* Empty list or null indicates that test is positive.195*/196@SafeVarargs197public final void setRequiredExceptions(Class<? extends Throwable>... classes) {198setRequiredExceptions(Arrays.asList(classes));199}200201/* Makes the test "negative": one of the specified exception classes has to be thrown by the test to pass.202* Test fails if exception has not been thrown.203* Boolean value returned by {@link run()} method is ignored.204* Calling {@link #markTestFailed()} causes test to fail anyway.205* <p>206* Invoke this method BEFORE run() method (e.g., in prolog) to instruct launcher207* @param classes The list of exception classes.208* Empty list or null indicates that test is positive (in its standard form)209*/210public final void setRequiredExceptions(List<Class<? extends Throwable>> classes) {211if (requiredExceptionClasses.size() > 0) {212Env.traceNormal("Expected exceptions specified in the test are overridden in command-line");213return;214}215216requiredExceptionClasses = classes;217}218219/**220* Returns the list of required exceptions221* (please see {@link #setRequiredExceptions(Class<? extends Throwable>... classes)} method for details.222* @return The list of exception classes. Empty list or null indicates that test is positive (in its standard form)223*/224public final List<Class<? extends Throwable>> getRequiredExceptions() {225return requiredExceptionClasses;226}227228private boolean testMarkedFailed = false;229230/**231* Marks the test as failed.232* Regardless of run() method return value, the test is considered failed. Operation is not reversible.233* Can be called from multiple threads234*/235protected final void markTestFailed() {236markTestFailed(null, null);237}238239/**240* Marks the test as failed, indicating falure reason.241* Regardless of run() method return value, the test is considered failed. Operation is not reversible.242* Can be called from multiple threads243* @param msg A message to log (using Log.complain() method)244*/245protected final void markTestFailed(String msg) {246markTestFailedImpl(msg, null);247}248249/**250* Marks the test as failed, indicating falure reason and exception, which caused it.251* Regardless of run() method return value, the test is considered failed. Operation is not reversible.252* Can be called from multiple threads253* @param msg A message to log (using Log.complain() method)254* @param t An exception to log255*/256protected final void markTestFailed(String msg, Throwable t) {257markTestFailedImpl(msg, t);258}259260private synchronized void markTestFailedImpl(String msg, Throwable t) {261testMarkedFailed = true;262263StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();264Env.complain(t, "%s marked failed at %s%s", getName(), stackTrace[3],265msg == null ? "" : ":\n" + msg);266267}268269/**270* Checks if the test has marked failed.271* @return true, if the test marked failed272*/273protected final synchronized boolean isMarkedFailed() {274return testMarkedFailed;275}276277private static boolean dumpHeapAfter = false;278279/**280* Checks if heap dump requestd after running the test.281* @return true, if the test marked failed282* @see MlvmTestExecutor for heap dumping details.283*/284public static synchronized boolean getHeapDumpAfter() {285return dumpHeapAfter;286}287288/**289* Sets or clears heap dumping request. Heap is dumped in MlvmTestExecutor after running the test.290*291* NB. heap dumping uses ProcessUtils libraries, so it should be added to library path in cfg-file:292* {@code export LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${COMMON_LIBS_LOCATION}/lib/${ARCH}/vm/share"}293* @param enable true, if heap should be dumped, false if not294* @see MlvmTestExecutor for heap dumping details.295*/296public static synchronized void setHeapDumpAfter(boolean enable) {297dumpHeapAfter = enable;298}299300protected static Stresser createStresser() {301Stresser s = new Stresser(getArgumentParser().getStressOptions());302if (getLog().getTraceLevel() >= TraceLevel.TRACE_VERBOSE) {303s.printStressInfo(getLog().getOutStream());304}305return s;306}307308protected static StressOptions getStressOptions() {309return getArgumentParser().getStressOptions();310}311312// Launchers are left here for compatibility. Launching code has been moved to MlvmTestExecutor313// TODO: A minor bug has to be filed to replace MlvmTest.launch() calls with MlvmTestExecutor.launch()314315protected static void launch(ArgumentParser argumentParser) {316MlvmTestExecutor.launch(argumentParser);317}318319protected static void launch(ArgumentParser argumentParser, Object[] constructorArgs) {320MlvmTestExecutor.launch(argumentParser, constructorArgs);321}322323protected static void launch(String[] args) {324MlvmTestExecutor.launch(args, null);325}326327protected static void launch(String[] args, Object[] constructorArgs) {328MlvmTestExecutor.launch(args, constructorArgs);329}330331}332333334