diff --git a/jcstress-core/src/main/java/org/openjdk/jcstress/Options.java b/jcstress-core/src/main/java/org/openjdk/jcstress/Options.java index 90c97825..e6d8f10d 100644 --- a/jcstress-core/src/main/java/org/openjdk/jcstress/Options.java +++ b/jcstress-core/src/main/java/org/openjdk/jcstress/Options.java @@ -30,6 +30,7 @@ import joptsimple.OptionSpec; import org.openjdk.jcstress.infra.runners.SpinLoopStyle; import org.openjdk.jcstress.os.AffinityMode; +import org.openjdk.jcstress.properties.UsedProperties; import org.openjdk.jcstress.util.OptionFormatter; import org.openjdk.jcstress.util.StringUtils; import org.openjdk.jcstress.util.TimeValue; @@ -46,6 +47,8 @@ * @author Aleksey Shipilev (aleksey.shipilev@oracle.com) */ public class Options { + public static final String TIME_BUDGET_SWITCH = "tb"; + private String resultDir; private String testFilter; private int strideSize; @@ -93,7 +96,7 @@ public boolean parse() throws IOException { .withRequiredArg().ofType(Integer.class).describedAs("N"); OptionSpec strideCount = parser.accepts("strideCount", "Internal stride count per epoch. " + - "Larger value increases cache footprint.") + "Larger value increases cache footprint.") .withRequiredArg().ofType(Integer.class).describedAs("N"); OptionSpec optTime = parser.accepts("time", "(Deprecated, to be removed in next releases.)") @@ -144,13 +147,13 @@ public boolean parse() throws IOException { OptionSpec optPretouchHeap = parser.accepts("pth", "Pre-touch Java heap, if possible.") .withOptionalArg().ofType(Boolean.class).describedAs("bool"); - OptionSpec optTimeBudget = parser.accepts("tb", "Time budget to run the tests. Harness code would try to fit the entire " + + OptionSpec optTimeBudget = parser.accepts(TIME_BUDGET_SWITCH, "Time budget to run the tests. Harness code would try to fit the entire " + "run in the desired timeframe. This value is expected to be reasonable, as it is not guaranteed that tests would succeed " + "in arbitrarily low time budget. If not set, harness would try to decide a reasonable time, given the number of tests to run. " + "Common time suffixes (s/m/h/d) are accepted.") .withRequiredArg().ofType(TimeValue.class).describedAs("time"); - parser.accepts("v", "Be verbose."); + parser.accepts("v", "Be verbose. Will print known properties in help"); parser.accepts("vv", "Be extra verbose."); parser.accepts("vvv", "Be extra extra verbose."); parser.accepts("h", "Print this help."); @@ -161,12 +164,13 @@ public boolean parse() throws IOException { } catch (OptionException e) { System.err.println("ERROR: " + e.getMessage()); System.err.println(); - parser.printHelpOn(System.err); + printHelp(parser, System.err); return false; } + setVerbosity(set); if (set.has("h")) { - parser.printHelpOn(System.out); + printHelp(parser, System.out); return false; } @@ -185,15 +189,6 @@ public boolean parse() throws IOException { this.resultFile = "jcstress-results-" + timestamp + ".bin.gz"; } this.list = orDefault(set.has(list), false); - if (set.has("vvv")) { - this.verbosity = new Verbosity(3); - } else if (set.has("vv")) { - this.verbosity = new Verbosity(2); - } else if (set.has("v")) { - this.verbosity = new Verbosity(1); - } else { - this.verbosity = new Verbosity(0); - } int totalCpuCount = VMSupport.figureOutHotCPUs(); cpuCount = orDefault(set.valueOf(cpus), totalCpuCount); @@ -201,7 +196,7 @@ public boolean parse() throws IOException { if (cpuCount > totalCpuCount) { System.err.println("Requested to use " + cpuCount + " CPUs, but system has only " + totalCpuCount + " CPUs."); System.err.println(); - parser.printHelpOn(System.err); + printHelp(parser, System.err); return false; } @@ -227,21 +222,21 @@ public boolean parse() throws IOException { if (optModeStr.value(set) != null) { System.err.println("-m option is not supported anymore, please use -tb."); System.err.println(); - parser.printHelpOn(System.err); + printHelp(parser, System.err); return false; } if (optTime.value(set) != null) { System.err.println("-time option is not supported anymore, please use -tb."); System.err.println(); - parser.printHelpOn(System.err); + printHelp(parser, System.err); return false; } if (optIters.value(set) != null) { System.err.println("-iters option is not supported anymore, please use -tb."); System.err.println(); - parser.printHelpOn(System.err); + printHelp(parser, System.err); return false; } @@ -263,6 +258,26 @@ public boolean parse() throws IOException { return true; } + private void setVerbosity(OptionSet set) { + if (set.has("vvv")) { + this.verbosity = new Verbosity(3); + } else if (set.has("vv")) { + this.verbosity = new Verbosity(2); + } else if (set.has("v")) { + this.verbosity = new Verbosity(1); + } else { + this.verbosity = new Verbosity(0); + } + } + + private void printHelp(OptionParser parser, PrintStream ouer) throws IOException { + parser.printHelpOn(ouer); + ouer.println(); + if (verbosity != null && verbosity.printAllTests()) { + UsedProperties.printHelpOn(ouer); + } + } + private List processArgs(OptionSpec op, OptionSet set) { if (set.hasArgument(op)) { try { @@ -297,7 +312,7 @@ public void printSettingsOn(PrintStream out) { out.printf(" Hardware CPUs in use: %d%n", getCPUCount()); out.printf(" Spinning style: %s%n", getSpinStyle()); out.printf(" Test selection: \"%s\"%n", getTestFilter()); - out.printf(" Forks per test: %d normal, %d stress%n", getForks(), getForks()*getForksStressMultiplier()); + out.printf(" Forks per test: %d normal, %d stress%n", getForks(), getForks() * getForksStressMultiplier()); out.printf(" Test stride: %d strides x %d tests, but taking no more than %d Mb%n", getStrideCount(), getStrideSize(), getMaxFootprintMb()); out.printf(" Test result blob: \"%s\"%n", resultFile); out.printf(" Test results: \"%s\"%n", resultDir); @@ -392,6 +407,8 @@ public boolean isPretouchHeap() { return pretouchHeap; } - public TimeValue timeBudget() { return timeBudget; } + public TimeValue timeBudget() { + return timeBudget; + } } diff --git a/jcstress-core/src/main/java/org/openjdk/jcstress/TimeBudget.java b/jcstress-core/src/main/java/org/openjdk/jcstress/TimeBudget.java index 4b885ad1..e7c9019d 100644 --- a/jcstress-core/src/main/java/org/openjdk/jcstress/TimeBudget.java +++ b/jcstress-core/src/main/java/org/openjdk/jcstress/TimeBudget.java @@ -25,6 +25,7 @@ package org.openjdk.jcstress; import org.openjdk.jcstress.infra.grading.ReportUtils; +import org.openjdk.jcstress.properties.UsedProperties; import org.openjdk.jcstress.util.TimeValue; import org.openjdk.jcstress.vm.VMSupport; @@ -34,9 +35,9 @@ public class TimeBudget { - static final int DEFAULT_PER_TEST_MS = Integer.getInteger("jcstress.timeBudget.defaultPerTestMs", 3000); - static final int MIN_TIME_MS = Integer.getInteger("jcstress.timeBudget.minTimeMs", 30); - static final int MAX_TIME_MS = Integer.getInteger("jcstress.timeBudget.maxTimeMs", 60_000); + static final int DEFAULT_PER_TEST_MS = UsedProperties.getJcstressTimeBudgetDefaultPerTestMs(); + static final int MIN_TIME_MS = UsedProperties.getJcstressTimeBudgetMinTimeMs(); + static final int MAX_TIME_MS = UsedProperties.getJcstressTimeBudgetMaxTimeMs(); final long endTime; final int expectedTests; diff --git a/jcstress-core/src/main/java/org/openjdk/jcstress/infra/grading/ConsoleReportPrinter.java b/jcstress-core/src/main/java/org/openjdk/jcstress/infra/grading/ConsoleReportPrinter.java index bda69cb7..7a6603a8 100644 --- a/jcstress-core/src/main/java/org/openjdk/jcstress/infra/grading/ConsoleReportPrinter.java +++ b/jcstress-core/src/main/java/org/openjdk/jcstress/infra/grading/ConsoleReportPrinter.java @@ -27,6 +27,7 @@ import org.openjdk.jcstress.Options; import org.openjdk.jcstress.TestExecutor; import org.openjdk.jcstress.TimeBudget; +import org.openjdk.jcstress.properties.UsedProperties; import org.openjdk.jcstress.Verbosity; import org.openjdk.jcstress.infra.collectors.TestResult; import org.openjdk.jcstress.infra.collectors.TestResultCollector; @@ -43,8 +44,6 @@ */ public class ConsoleReportPrinter implements TestResultCollector { - private static final Integer PRINT_INTERVAL_MS = Integer.getInteger("jcstress.console.printIntervalMs"); - private final Verbosity verbosity; private final PrintWriter output; @@ -80,13 +79,11 @@ public ConsoleReportPrinter(Options opts, PrintWriter pw, long expectedForks, Ti Arrays.fill(progressLen, 1); progressFirstLine = true; - progressInteractive = (System.console() != null); + progressInteractive = UsedProperties.isProgressInteractive(); progressAnsi = VMSupport.isLinux(); output.println(" Attached the " + (progressInteractive ? "interactive console" : "non-interactive output stream") + "."); - printIntervalMs = (PRINT_INTERVAL_MS != null) ? - PRINT_INTERVAL_MS : - progressInteractive ? 1_000 : 15_000; + printIntervalMs = UsedProperties.getPrintIntervalMs(); output.println(" Printing the progress line at most every " + printIntervalMs + " milliseconds."); output.println(); diff --git a/jcstress-core/src/main/java/org/openjdk/jcstress/link/BinaryLinkClient.java b/jcstress-core/src/main/java/org/openjdk/jcstress/link/BinaryLinkClient.java index 3033647d..18d188e7 100644 --- a/jcstress-core/src/main/java/org/openjdk/jcstress/link/BinaryLinkClient.java +++ b/jcstress-core/src/main/java/org/openjdk/jcstress/link/BinaryLinkClient.java @@ -24,6 +24,7 @@ */ package org.openjdk.jcstress.link; +import org.openjdk.jcstress.properties.UsedProperties; import org.openjdk.jcstress.infra.collectors.TestResult; import org.openjdk.jcstress.infra.runners.ForkedTestConfig; @@ -32,7 +33,7 @@ public final class BinaryLinkClient { - private static final int LINK_TIMEOUT_MS = Integer.getInteger("jcstress.link.timeoutMs", 30 * 1000); + private static final int LINK_TIMEOUT_MS = UsedProperties.getJcstressLinkTimeoutMs(); private final String hostName; private final int hostPort; diff --git a/jcstress-core/src/main/java/org/openjdk/jcstress/link/BinaryLinkServer.java b/jcstress-core/src/main/java/org/openjdk/jcstress/link/BinaryLinkServer.java index a7c74335..8e66c8da 100644 --- a/jcstress-core/src/main/java/org/openjdk/jcstress/link/BinaryLinkServer.java +++ b/jcstress-core/src/main/java/org/openjdk/jcstress/link/BinaryLinkServer.java @@ -24,6 +24,7 @@ */ package org.openjdk.jcstress.link; +import org.openjdk.jcstress.properties.UsedProperties; import org.openjdk.jcstress.infra.collectors.TestResult; import org.openjdk.jcstress.infra.runners.ForkedTestConfig; @@ -37,9 +38,8 @@ */ public final class BinaryLinkServer { - private static final String LINK_ADDRESS = System.getProperty("jcstress.link.address"); - private static final int LINK_PORT = Integer.getInteger("jcstress.link.port", 0); - private static final int LINK_TIMEOUT_MS = Integer.getInteger("jcstress.link.timeoutMs", 30 * 1000); + private static final int LINK_PORT = UsedProperties.getJcstressLinkPort(); + private static final int LINK_TIMEOUT_MS = UsedProperties.getJcstressLinkTimeoutMs(); private final ServerSocket server; private final InetAddress listenAddress; @@ -49,7 +49,7 @@ public final class BinaryLinkServer { public BinaryLinkServer(ServerListener listener) throws IOException { this.listener = listener; - listenAddress = getListenAddress(); + listenAddress = UsedProperties.getListenAddress(); server = new ServerSocket(LINK_PORT, 50, listenAddress); server.setSoTimeout(LINK_TIMEOUT_MS); @@ -57,19 +57,7 @@ public BinaryLinkServer(ServerListener listener) throws IOException { handler.start(); } - private InetAddress getListenAddress() { - // Try to use user-provided override first. - if (LINK_ADDRESS != null) { - try { - return InetAddress.getByName(LINK_ADDRESS); - } catch (UnknownHostException e) { - // override failed, notify user - throw new IllegalStateException("Can not initialize binary link.", e); - } - } - return InetAddress.getLoopbackAddress(); - } public void terminate() { // set interrupt flag diff --git a/jcstress-core/src/main/java/org/openjdk/jcstress/properties/ForkedVmProperties.java b/jcstress-core/src/main/java/org/openjdk/jcstress/properties/ForkedVmProperties.java new file mode 100644 index 00000000..c2d7cf03 --- /dev/null +++ b/jcstress-core/src/main/java/org/openjdk/jcstress/properties/ForkedVmProperties.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package org.openjdk.jcstress.properties; + +import java.util.Arrays; +import java.util.List; + +class ForkedVmProperties implements UsedProperties.ProeprtiesHelpProvider { + + static final UsedProperties.StringJcstressProperty LINK_ADDRESS = new UsedProperties.StringJcstressProperty("jcstress.link.address", new String[]{null}) { + @Override + public String getDescription() { + return getKey() + " is address where to connect to forked VMs. Defaults to loop-back. Set to '" + getListenAddressForInfo() + "'"; + } + }; + + + static final UsedProperties.IntJcstressProperty LINK_PORT = new UsedProperties.IntJcstressProperty("jcstress.link.port", 0) { + @Override + public String getDescription() { + return getKey() + " is port where to connect to forked VMs on " + LINK_ADDRESS.getKey() + ". Defaults to " + getDefault() + " (random free port)." + + " Set to " + UsedProperties.getJcstressLinkPort(); + } + }; + + static final UsedProperties.IntJcstressProperty LINK_TIMEOUTMS = new UsedProperties.IntJcstressProperty("jcstress.link.timeoutMs", 30 * 1000) { + @Override + public String getDescription() { + return getKey() + " set timeout to forked VM communication ms." + + " Defaults to " + getDefault() + "ms. Set to " + getValue() + "ms."; + } + }; + + + private static String getListenAddressForInfo() { + try { + return UsedProperties.getListenAddress().toString(); + } catch (Exception ex) { + return ex.getMessage(); + } + } + + @Override + public List getHelp() { + return Arrays.asList( + LINK_ADDRESS.getDescription(), + LINK_PORT.getDescription(), + LINK_TIMEOUTMS.getDescription()); + } + + @Override + public String getTitle() { + return "Properties handling forked VMs. Modify only if you are sure what youa re doing"; + } + +} diff --git a/jcstress-core/src/main/java/org/openjdk/jcstress/properties/TestTimeProperties.java b/jcstress-core/src/main/java/org/openjdk/jcstress/properties/TestTimeProperties.java new file mode 100644 index 00000000..98afb622 --- /dev/null +++ b/jcstress-core/src/main/java/org/openjdk/jcstress/properties/TestTimeProperties.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package org.openjdk.jcstress.properties; + +import org.openjdk.jcstress.Options; + +import java.util.Arrays; +import java.util.List; + +class TestTimeProperties implements UsedProperties.ProeprtiesHelpProvider { + + static final UsedProperties.IntJcstressProperty TIMEBUDGET_DEFAULTPERTESTMS = new UsedProperties.IntJcstressProperty("jcstress.timeBudget.defaultPerTestMs", 3000) { + @Override + public String getDescription() { + return getKey() + " set default time the individual test executes. Defaults to " + getDefault() + + "ms set to " + getValue() + "ms"; + } + }; + + static final UsedProperties.IntJcstressProperty TIMEBUDGET_MINTIMEMS = new UsedProperties.IntJcstressProperty("jcstress.timeBudget.minTimeMs", 30) { + @Override + public String getDescription() { + return getKey() + " set minimal time the individual test executes. Defaults to " + getDefault() + + "ms set to " + getValue() + "ms"; + } + }; + + static final UsedProperties.IntJcstressProperty TIMEBUDGET_MAXTIMEMS = new UsedProperties.IntJcstressProperty("jcstress.timeBudget.maxTimeMs", 60_000) { + @Override + public String getDescription() { + return getKey() + + " set maximum time the individual test executes. Defaults to " + getDefault() + + "ms set to " + getValue() + "ms"; + } + }; + + static final String TIMEBUDGET_ADDITIONAL_COMMENT = "The time each test is run is (simplified) calculated as value of " + Options.TIME_BUDGET_SWITCH + " switch divided by number of tests (after all filters applied)" + + " If te resulting time is smaller then " + TIMEBUDGET_MINTIMEMS.getKey() + ", it is used. If it si bigger then " + TIMEBUDGET_MAXTIMEMS.getKey() + " it is used. If no " + Options.TIME_BUDGET_SWITCH + " is set," + + " then " + TIMEBUDGET_DEFAULTPERTESTMS.getKey() + " is used. See " + Options.TIME_BUDGET_SWITCH + " for more info. Properties do not accept unit suffixes."; + + @Override + public List getHelp() { + return Arrays.asList( + TIMEBUDGET_DEFAULTPERTESTMS.getDescription(), + TIMEBUDGET_MINTIMEMS.getDescription(), + TIMEBUDGET_MAXTIMEMS.getDescription(), + TIMEBUDGET_ADDITIONAL_COMMENT); + } + + @Override + public String getTitle() { + return "Individual test time execution properties"; + } +} diff --git a/jcstress-core/src/main/java/org/openjdk/jcstress/properties/UiProperties.java b/jcstress-core/src/main/java/org/openjdk/jcstress/properties/UiProperties.java new file mode 100644 index 00000000..c20d8c90 --- /dev/null +++ b/jcstress-core/src/main/java/org/openjdk/jcstress/properties/UiProperties.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package org.openjdk.jcstress.properties; + +import java.util.Arrays; +import java.util.List; + +class UiProperties implements UsedProperties.ProeprtiesHelpProvider { + + static final UsedProperties.LongJcstressProperty CONSOLE_PRINTINTERVALMS = new UsedProperties.LongJcstressProperty("jcstress.console.printIntervalMs", 1_000L, 15_000L) { + + @Override + public Long getValue() { + return Long.getLong(getKey(), null); + } + + @Override + public String getDescription() { + return getKey() + " sets interval how often to print results to console in ms. Have two defaults: " + + getDefaults().get(0) + "ms in interactive mode and " + + getDefaults().get(1) + "ms in noninteractive mode. Set to " + + UsedProperties.getPrintIntervalMs() + "ms"; + } + }; + + @Override + public List getHelp() { + return Arrays.asList(CONSOLE_PRINTINTERVALMS.getDescription()); + } + + @Override + public String getTitle() { + return "Properties modyfying user appearance"; + } +} diff --git a/jcstress-core/src/main/java/org/openjdk/jcstress/properties/UsedProperties.java b/jcstress-core/src/main/java/org/openjdk/jcstress/properties/UsedProperties.java new file mode 100644 index 00000000..9a6a80f6 --- /dev/null +++ b/jcstress-core/src/main/java/org/openjdk/jcstress/properties/UsedProperties.java @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.openjdk.jcstress.properties; + + +import java.io.PrintStream; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import static org.openjdk.jcstress.properties.TestTimeProperties.*; +import static org.openjdk.jcstress.properties.ForkedVmProperties.*; +import static org.openjdk.jcstress.properties.UiProperties.*; + +/** + * Known Properties affecting JCStress. Some of them publicly document themselves, some do not need to. + */ +public class UsedProperties { + + interface ProeprtiesHelpProvider { + List getHelp(); + + String getTitle(); + } + + static abstract class JcstressProperty { + private final String key; + private final List defaults; + + public JcstressProperty(String key, T[] defaults) { + this.key = key; + this.defaults = Collections.unmodifiableList(Arrays.asList(defaults)); + } + + public String getKey() { + return key; + } + + public List getDefaults() { + return defaults; + } + + public T getDefault() { + return defaults.get(0); + } + + public boolean isCustom() { + return System.getProperty(getKey()) != null; + } + + public abstract String getDescription(); + + public abstract T getValue(); + } + + static abstract class IntJcstressProperty extends JcstressProperty { + + public IntJcstressProperty(String key, Integer... defaults) { + super(key, defaults); + } + + @Override + public Integer getValue() { + return Integer.getInteger(getKey(), getDefault()); + } + } + + static abstract class LongJcstressProperty extends JcstressProperty { + + public LongJcstressProperty(String key, Long... defaults) { + super(key, defaults); + } + + @Override + public Long getValue() { + return Long.getLong(getKey(), getDefault()); + } + } + + + static abstract class StringJcstressProperty extends JcstressProperty { + + public StringJcstressProperty(String key, String... defaults) { + super(key, defaults); + } + + @Override + public String getValue() { + return System.getProperty(getKey(), getDefault()); + } + } + + /** + * utility class + */ + private UsedProperties() { + } + + public static int getJcstressTimeBudgetDefaultPerTestMs() { + return TIMEBUDGET_DEFAULTPERTESTMS.getValue(); + } + + public static int getJcstressTimeBudgetMinTimeMs() { + return TIMEBUDGET_MINTIMEMS.getValue(); + } + + public static int getJcstressTimeBudgetMaxTimeMs() { + return TIMEBUDGET_MAXTIMEMS.getValue(); + } + + private static String getJcstressLinkAddress() { + return LINK_ADDRESS.getValue(); + } + + public static InetAddress getListenAddress() { + // Try to use user-provided override first. + if (UsedProperties.getJcstressLinkAddress() != null) { + try { + return InetAddress.getByName(UsedProperties.getJcstressLinkAddress()); + } catch (UnknownHostException e) { + // override failed, notify user + throw new IllegalStateException("Can not initialize binary link.", e); + } + } + + return InetAddress.getLoopbackAddress(); + } + + + public static int getJcstressLinkPort() { + return LINK_PORT.getValue(); + } + + + public static int getJcstressLinkTimeoutMs() { + return LINK_TIMEOUTMS.getValue(); + } + + public static boolean isProgressInteractive() { + return System.console() != null; + } + + public static long getPrintIntervalMs() { + return (CONSOLE_PRINTINTERVALMS.isCustom()) ? + CONSOLE_PRINTINTERVALMS.getValue() : + isProgressInteractive() ? CONSOLE_PRINTINTERVALMS.getDefaults().get(0) : CONSOLE_PRINTINTERVALMS.getDefaults().get(1); + } + + public static void printHelpOn(PrintStream ouer) { + ouer.println("JCStress recognize several internal properties:"); + for (ProeprtiesHelpProvider provider : new ProeprtiesHelpProvider[]{new TestTimeProperties(), new ForkedVmProperties(), new UiProperties()}) { + ouer.println(" " + provider.getTitle()); + for (String line : provider.getHelp()) { + ouer.println(" * " + line); + } + } + } +} \ No newline at end of file diff --git a/jcstress-core/src/main/java/org/openjdk/jcstress/util/OptionFormatter.java b/jcstress-core/src/main/java/org/openjdk/jcstress/util/OptionFormatter.java index 51823f52..e1702f49 100644 --- a/jcstress-core/src/main/java/org/openjdk/jcstress/util/OptionFormatter.java +++ b/jcstress-core/src/main/java/org/openjdk/jcstress/util/OptionFormatter.java @@ -35,7 +35,7 @@ public class OptionFormatter implements HelpFormatter { public String format(Map options) { StringBuilder sb = new StringBuilder(); - sb.append("Usage: java -jar jcstress.jar [options]"); + sb.append("Usage: java [properties] -jar jcstress.jar [options]"); sb.append(System.lineSeparator()); sb.append(" [opt] means optional argument."); sb.append(System.lineSeparator());