You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by ah...@apache.org on 2019/09/27 13:49:12 UTC
[commons-rng] 02/05: Fix PMD errors in stress test code.
This is an automated email from the ASF dual-hosted git repository.
aherbert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-rng.git
commit bf55f9444b38cda328cd1d9ca9731a65cc72922e
Author: aherbert <ah...@apache.org>
AuthorDate: Fri Sep 27 14:09:37 2019 +0100
Fix PMD errors in stress test code.
---
.../rng/examples/stress/BridgeTestCommand.java | 18 ++-
.../examples/stress/ExamplesStressApplication.java | 2 +-
.../commons/rng/examples/stress/ListCommand.java | 6 +-
.../examples/stress/ManifestVersionProvider.java | 2 +-
.../commons/rng/examples/stress/OutputCommand.java | 35 +++--
.../commons/rng/examples/stress/ProcessUtils.java | 4 +-
.../rng/examples/stress/ResultsCommand.java | 141 ++++++++++++---------
.../rng/examples/stress/StressTestCommand.java | 126 ++++++++++--------
8 files changed, 191 insertions(+), 143 deletions(-)
diff --git a/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/BridgeTestCommand.java b/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/BridgeTestCommand.java
index 311eff9..b0cc26e 100644
--- a/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/BridgeTestCommand.java
+++ b/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/BridgeTestCommand.java
@@ -87,7 +87,7 @@ class BridgeTestCommand implements Callable<Void> {
* of the executable. Captures stdout of the executable to a file.
*/
private void runBridgeTest() {
- final ArrayList<String> command = ProcessUtils.buildSubProcessCommand(executable, executableArguments);
+ final List<String> command = ProcessUtils.buildSubProcessCommand(executable, executableArguments);
try {
final File dataFile = new File(fileOutputPrefix + ".data");
@@ -123,17 +123,17 @@ class BridgeTestCommand implements Callable<Void> {
}
}
- Integer exitValue = ProcessUtils.getExitValue(testingProcess);
- if (exitValue != null) {
+ final Integer exitValue = ProcessUtils.getExitValue(testingProcess);
+ if (exitValue == null) {
+ LogUtils.error("%s did not exit. Process was killed.", command.get(0));
+ } else {
if (exitValue.intValue() != 0) {
LogUtils.error("%s exit code = %d", command.get(0), exitValue.intValue());
}
- } else {
- LogUtils.error("%s did not exit. Process was killed.", command.get(0));
}
} catch (IOException ex) {
- throw new ApplicationException("Failed to run process: " + ex.getMessage());
+ throw new ApplicationException("Failed to run process: " + ex.getMessage(), ex);
}
}
@@ -154,9 +154,7 @@ class BridgeTestCommand implements Callable<Void> {
int value,
boolean littleEndian) throws IOException {
OutputCommand.writeInt(textOutput, value);
- if (littleEndian) {
- value = Integer.reverseBytes(value);
- }
- dataOutput.writeInt(value);
+ final int binaryValue = littleEndian ? Integer.reverseBytes(value) : value;
+ dataOutput.writeInt(binaryValue);
}
}
diff --git a/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/ExamplesStressApplication.java b/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/ExamplesStressApplication.java
index 495dfec..83f7f2b 100644
--- a/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/ExamplesStressApplication.java
+++ b/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/ExamplesStressApplication.java
@@ -73,7 +73,7 @@ public final class ExamplesStressApplication {
try {
// Parse the command line and invokes the Callable program (RNGUtilities)
cmd.parseWithHandler(new RunLast(), args);
- } catch (final picocli.CommandLine.ExecutionException ex) {
+ } catch (final CommandLine.ExecutionException ex) {
final Throwable cause = ex.getCause();
if (cause != null) {
// If this was an exception generated by the application then the full
diff --git a/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/ListCommand.java b/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/ListCommand.java
index 5f774e4..16fa969 100644
--- a/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/ListCommand.java
+++ b/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/ListCommand.java
@@ -167,10 +167,10 @@ class ListCommand implements Callable<Void> {
format = String.format("%%-%ds %%-%ds ", idWidth + 2, randomSourceWidth);
for (final StressTestData data : testData) {
formatter.format(format, data.getId(), data.getRandomSource().name());
- if (data.getArgs() != null) {
- formatter.format("%-7d %s", data.getTrials(), Arrays.toString(data.getArgs()));
- } else {
+ if (data.getArgs() == null) {
appendable.append(Integer.toString(data.getTrials()));
+ } else {
+ formatter.format("%-7d %s", data.getTrials(), Arrays.toString(data.getArgs()));
}
appendable.append(newLine);
}
diff --git a/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/ManifestVersionProvider.java b/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/ManifestVersionProvider.java
index 52b55c9..608197d 100644
--- a/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/ManifestVersionProvider.java
+++ b/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/ManifestVersionProvider.java
@@ -36,7 +36,7 @@ class ManifestVersionProvider implements IVersionProvider {
/** {@inheritDoc} */
@Override
public String[] getVersion() throws Exception {
- final Enumeration<URL> resources = ManifestVersionProvider.class.getClassLoader()
+ final Enumeration<URL> resources = Thread.currentThread().getContextClassLoader()
.getResources("META-INF/MANIFEST.MF");
while (resources.hasMoreElements()) {
final URL url = resources.nextElement();
diff --git a/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/OutputCommand.java b/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/OutputCommand.java
index f5d46cb..6e15d3a 100644
--- a/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/OutputCommand.java
+++ b/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/OutputCommand.java
@@ -28,8 +28,6 @@ import java.io.BufferedOutputStream;
import java.io.BufferedWriter;
import java.io.DataOutputStream;
import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
@@ -37,6 +35,7 @@ import java.io.OutputStreamWriter;
import java.io.Writer;
import java.nio.ByteOrder;
import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Formatter;
import java.util.List;
@@ -52,6 +51,10 @@ import java.util.concurrent.Callable;
class OutputCommand implements Callable<Void> {
/** The new line characters. */
private static final String NEW_LINE = System.lineSeparator();
+ /** Character '['. */
+ private static final char LEFT_SQUARE_BRACKET = '[';
+ /** Character ']'. */
+ private static final char RIGHT_SQUARE_BRACKET = ']';
/** Lookup table for binary representation of bytes. */
private static final String[] BIT_REP = {
@@ -170,7 +173,7 @@ class OutputCommand implements Callable<Void> {
// Strip these for convenience.
stripArrayFormatting(arguments);
- for (String argument : arguments) {
+ for (final String argument : arguments) {
data.add(RNGUtils.parseArgument(argument));
}
try {
@@ -193,11 +196,11 @@ class OutputCommand implements Callable<Void> {
if (size > 1) {
// These will not be empty as they were created from command-line args.
final String first = arguments.get(0);
- if (first.charAt(0) == '[') {
+ if (first.charAt(0) == LEFT_SQUARE_BRACKET) {
arguments.set(0, first.substring(1));
}
final String last = arguments.get(size - 1);
- if (last.charAt(last.length() - 1) == ']') {
+ if (last.charAt(last.length() - 1) == RIGHT_SQUARE_BRACKET) {
arguments.set(size - 1, last.substring(0, last.length() - 1));
}
}
@@ -217,8 +220,8 @@ class OutputCommand implements Callable<Void> {
private OutputStream createOutputStream() {
if (fileOutput != null) {
try {
- return new FileOutputStream(fileOutput);
- } catch (FileNotFoundException ex) {
+ Files.newOutputStream(fileOutput.toPath());
+ } catch (IOException ex) {
throw new ApplicationException("Failed to create output: " + fileOutput, ex);
}
}
@@ -283,12 +286,11 @@ class OutputCommand implements Callable<Void> {
output.write(NEW_LINE);
output.write("numbit: 32");
output.write(NEW_LINE);
- while (count > 0) {
- count--;
+ for (long c = 0; c < count; c++) {
// Unsigned integers
final String text = Long.toString(rng.nextInt() & 0xffffffffL);
// Left pad with spaces
- for (int i = 10 - text.length(); i-- > 0;) {
+ for (int i = 10 - text.length(); i > 0; i--) {
output.write(' ');
}
output.write(text);
@@ -319,14 +321,12 @@ class OutputCommand implements Callable<Void> {
static void writeBinaryIntData(final UniformRandomProvider rng,
long count,
final OutputStream out) throws IOException {
- if (count < 1) {
- // Effectively unlimited: program must be killed
- count = Long.MAX_VALUE;
- }
+ // If count is not positive use max value.
+ // This is effectively unlimited: program must be killed.
+ final long limit = (count < 1) ? Long.MAX_VALUE : count;
try (DataOutputStream data = new DataOutputStream(
new BufferedOutputStream(out))) {
- while (count > 0) {
- count--;
+ for (long c = 0; c < limit; c++) {
data.writeInt(rng.nextInt());
}
}
@@ -347,8 +347,7 @@ class OutputCommand implements Callable<Void> {
checkCount(count, OutputFormat.BITS);
try (BufferedWriter output = new BufferedWriter(new OutputStreamWriter(out, StandardCharsets.UTF_8))) {
- while (count > 0) {
- count--;
+ for (long c = 0; c < count; c++) {
writeInt(output, rng.nextInt());
}
}
diff --git a/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/ProcessUtils.java b/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/ProcessUtils.java
index b07aab1..3c94cc0 100644
--- a/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/ProcessUtils.java
+++ b/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/ProcessUtils.java
@@ -67,8 +67,8 @@ final class ProcessUtils {
* @return the command
* @throws ApplicationException If the executable path cannot be resolved
*/
- static ArrayList<String> buildSubProcessCommand(File executable,
- List<String> executableArguments) {
+ static List<String> buildSubProcessCommand(File executable,
+ List<String> executableArguments) {
final ArrayList<String> command = new ArrayList<>();
try {
command.add(executable.getCanonicalPath());
diff --git a/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/ResultsCommand.java b/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/ResultsCommand.java
index a564617..2f20252 100644
--- a/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/ResultsCommand.java
+++ b/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/ResultsCommand.java
@@ -26,8 +26,6 @@ import picocli.CommandLine.Parameters;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
@@ -80,6 +78,12 @@ class ResultsCommand implements Callable<Void> {
private static final String DIEHARDER_SUMS = "diehard_sums";
/** The string identifying a bit-reversed generator. */
private static final String BIT_REVERSED = "Bit-reversed";
+ /** Character '\'. */
+ private static final char FORWARD_SLASH = '\\';
+ /** Character '/'. */
+ private static final char BACK_SLASH = '\\';
+ /** Character '|'. */
+ private static final char PIPE = '|';
/** The standard options. */
@Mixin
@@ -154,7 +158,7 @@ class ResultsCommand implements Callable<Void> {
/** The test application format. */
private final TestFormat testFormat;
/** The names of the failed tests. */
- private final ArrayList<String> failedTests = new ArrayList<>();
+ private final List<String> failedTests = new ArrayList<>();
/** The test application name. */
private String testApplicationName;
/** Flag to indicate results are complete (i.e. not still in progress). */
@@ -226,7 +230,7 @@ class ResultsCommand implements Callable<Void> {
*
* @return the failed tests
*/
- ArrayList<String> getFailedTests() {
+ List<String> getFailedTests() {
return failedTests;
}
@@ -263,7 +267,7 @@ class ResultsCommand implements Callable<Void> {
* @return the test application name
*/
String getTestApplicationName() {
- return testApplicationName != null ? testApplicationName : getTestFormat().toString();
+ return testApplicationName == null ? getTestFormat().toString() : testApplicationName;
}
/**
@@ -309,7 +313,7 @@ class ResultsCommand implements Callable<Void> {
default:
throw new ApplicationException("Unknown output format: " + outputFormat);
}
- } catch (IOException ex) {
+ } catch (final IOException ex) {
throw new ApplicationException("IO error: " + ex.getMessage(), ex);
}
return null;
@@ -322,7 +326,7 @@ class ResultsCommand implements Callable<Void> {
*/
private List<TestResult> readResults() {
final ArrayList<TestResult> results = new ArrayList<>();
- for (File resultFile : resultsFiles) {
+ for (final File resultFile : resultsFiles) {
readResults(results, resultFile);
}
return results;
@@ -336,13 +340,13 @@ class ResultsCommand implements Callable<Void> {
*/
private void readResults(List<TestResult> results,
File resultFile) {
- final ArrayList<String> contents = readFileContents(resultFile);
+ final List<String> contents = readFileContents(resultFile);
// Files may have multiple test results per file (i.e. appended output)
final List<List<String>> outputs = splitContents(contents);
if (outputs.isEmpty()) {
- LogUtils.error("No test output in file: " + resultFile);
+ LogUtils.error("No test output in file: %s", resultFile);
} else {
- for (List<String> testOutput : outputs) {
+ for (final List<String> testOutput : outputs) {
results.add(readResult(resultFile, testOutput));
}
}
@@ -355,14 +359,13 @@ class ResultsCommand implements Callable<Void> {
* @return the file contents
* @throws ApplicationException If the file cannot be read.
*/
- private static ArrayList<String> readFileContents(File resultFile) {
+ private static List<String> readFileContents(File resultFile) {
final ArrayList<String> contents = new ArrayList<>();
try (BufferedReader reader = Files.newBufferedReader(resultFile.toPath())) {
- String line;
- while ((line = reader.readLine()) != null) {
+ for (String line = reader.readLine(); line != null; line = reader.readLine()) {
contents.add(line);
}
- } catch (IOException ex) {
+ } catch (final IOException ex) {
throw new ApplicationException("Failed to read file contents: " + resultFile, ex);
}
return contents;
@@ -544,8 +547,8 @@ class ResultsCommand implements Callable<Void> {
// Note:
// This will count sub-parts of the same test as distinct failures.
while (iter.hasNext()) {
- String line = iter.next();
- Matcher matcher = TESTU01_TEST_RESULT_PATTERN.matcher(line);
+ final String line = iter.next();
+ final Matcher matcher = TESTU01_TEST_RESULT_PATTERN.matcher(line);
if (matcher.find()) {
testResult.addFailedTest(matcher.group(1).trim());
} else if (TEST_DURATION_PATTERN.matcher(line).find()) {
@@ -580,8 +583,8 @@ class ResultsCommand implements Callable<Void> {
private OutputStream createOutputStream() {
if (fileOutput != null) {
try {
- return new FileOutputStream(fileOutput);
- } catch (FileNotFoundException ex) {
+ Files.newOutputStream(fileOutput.toPath());
+ } catch (final IOException ex) {
throw new ApplicationException("Failed to create output: " + fileOutput, ex);
}
}
@@ -674,8 +677,8 @@ class ResultsCommand implements Callable<Void> {
.append(result.getFailureCountString()).append("}}");
// Convert to web-link name separators
for (int i = 0; i < sb.length(); i++) {
- if (sb.charAt(i) == '\\') {
- sb.setCharAt(i, '/');
+ if (sb.charAt(i) == BACK_SLASH) {
+ sb.setCharAt(i, FORWARD_SLASH);
}
}
return sb.toString();
@@ -697,14 +700,14 @@ class ResultsCommand implements Callable<Void> {
output.write(separator);
// This will collate results for each combination of 'RandomSource + bitReversed'
- for (RandomSource randomSource : randomSources) {
- for (boolean reversed : bitReversed) {
+ for (final RandomSource randomSource : randomSources) {
+ for (final boolean reversed : bitReversed) {
output.write('|');
writeAPTColumn(output, randomSource.toString());
if (showBitReversedColumn) {
writeAPTColumn(output, Boolean.toString(reversed));
}
- for (String testName : testNames) {
+ for (final String testName : testNames) {
final List<TestResult> testResults = getTestResults(results, randomSource, reversed, testName);
writeAPTColumn(output, testResults.stream()
.map(toAPTString)
@@ -725,7 +728,7 @@ class ResultsCommand implements Callable<Void> {
*/
private static List<RandomSource> getRandomSources(List<TestResult> results) {
final EnumSet<RandomSource> set = EnumSet.noneOf(RandomSource.class);
- for (TestResult result : results) {
+ for (final TestResult result : results) {
set.add(result.getRandomSource());
}
final ArrayList<RandomSource> list = new ArrayList<>(set);
@@ -741,18 +744,18 @@ class ResultsCommand implements Callable<Void> {
*/
private static List<Boolean> getBitReversed(List<TestResult> results) {
final ArrayList<Boolean> list = new ArrayList<>(2);
- if (!results.isEmpty()) {
+ if (results.isEmpty()) {
+ // Default to no bit-reversed results
+ list.add(Boolean.FALSE);
+ } else {
final boolean first = results.get(0).isBitReversed();
list.add(first);
- for (TestResult result : results) {
+ for (final TestResult result : results) {
if (first != result.isBitReversed()) {
list.add(!first);
break;
}
}
- } else {
- // Default to no bit-reversed results
- list.add(Boolean.FALSE);
}
Collections.sort(list);
return list;
@@ -766,7 +769,7 @@ class ResultsCommand implements Callable<Void> {
*/
private static List<String> getTestNames(List<TestResult> results) {
final HashSet<String> set = new HashSet<>();
- for (TestResult result : results) {
+ for (final TestResult result : results) {
set.add(result.getTestApplicationName());
}
final ArrayList<String> list = new ArrayList<>(set);
@@ -808,7 +811,7 @@ class ResultsCommand implements Callable<Void> {
*/
private static String getPathPrefix(TestResult testResult) {
final String parent = testResult.getResultFile().getParent();
- return parent != null ? parent : "";
+ return parent == null ? "" : parent;
}
/**
@@ -820,11 +823,11 @@ class ResultsCommand implements Callable<Void> {
*/
private static String createAPTHeader(boolean showBitReversedColumn,
List<String> testNames) {
- final StringBuilder sb = new StringBuilder("|| RNG identifier ||");
+ final StringBuilder sb = new StringBuilder(100).append("|| RNG identifier ||");
if (showBitReversedColumn) {
- sb.append(' ').append("Bit-reversed ||");
+ sb.append(" Bit-reversed ||");
}
- for (String name : testNames) {
+ for (final String name : testNames) {
sb.append(' ').append(name).append(" ||");
}
return sb.toString();
@@ -843,7 +846,7 @@ class ResultsCommand implements Callable<Void> {
// character, "+-" for all other occurrences except "-+" at the end
final StringBuilder sb = new StringBuilder(header);
for (int i = 0; i < header.length(); i++) {
- if (sb.charAt(i) == '|') {
+ if (sb.charAt(i) == PIPE) {
sb.setCharAt(i, i == 0 ? '*' : '+');
sb.setCharAt(i + 1, '-');
} else {
@@ -885,7 +888,7 @@ class ResultsCommand implements Callable<Void> {
boolean bitReversed,
String testName) {
final ArrayList<TestResult> list = new ArrayList<>();
- for (TestResult result : results) {
+ for (final TestResult result : results) {
if (result.getRandomSource() == randomSource &&
result.bitReversed == bitReversed &&
result.getTestApplicationName().equals(testName)) {
@@ -914,14 +917,7 @@ class ResultsCommand implements Callable<Void> {
// Make bit-reversed column optional if no generators are bit reversed.
final boolean showBitReversedColumn = bitReversed.contains(Boolean.TRUE);
- final ArrayList<List<String>> columns = new ArrayList<>();
- columns.add(createColumn("RNG"));
- if (showBitReversedColumn) {
- columns.add(createColumn(BIT_REVERSED));
- }
- for (String testName : testNames) {
- columns.add(createColumn(testName));
- }
+ final List<List<String>> columns = createColumns(testNames, showBitReversedColumn);
// Add all data
// This will collate results for each combination of 'RandomSource + bitReversed'
@@ -932,7 +928,7 @@ class ResultsCommand implements Callable<Void> {
if (showBitReversedColumn) {
columns.get(i++).add(Boolean.toString(reversed));
}
- for (String testName : testNames) {
+ for (final String testName : testNames) {
final List<TestResult> testResults = getTestResults(results, randomSource,
reversed, testName);
columns.get(i++).add(testResults.stream()
@@ -943,17 +939,7 @@ class ResultsCommand implements Callable<Void> {
}
// Create format using the column widths
- final StringBuilder sb = new StringBuilder();
- try (Formatter formatter = new Formatter(sb)) {
- for (int i = 0; i < columns.size(); i++) {
- if (i != 0) {
- sb.append('\t');
- }
- formatter.format("%%-%ds", getColumnWidth(columns.get(i)));
- }
- }
- sb.append(System.lineSeparator());
- final String format = sb.toString();
+ final String format = createTextFormatFromColumnWidths(columns);
// Output
try (BufferedWriter output = new BufferedWriter(new OutputStreamWriter(out, StandardCharsets.UTF_8));
@@ -970,6 +956,26 @@ class ResultsCommand implements Callable<Void> {
}
/**
+ * Creates the columns.
+ *
+ * @param testNames the test names
+ * @param showBitReversedColumn Set to true to show the bit reversed column
+ * @return the list of columns
+ */
+ private static List<List<String>> createColumns(final List<String> testNames,
+ final boolean showBitReversedColumn) {
+ final ArrayList<List<String>> columns = new ArrayList<>();
+ columns.add(createColumn("RNG"));
+ if (showBitReversedColumn) {
+ columns.add(createColumn(BIT_REVERSED));
+ }
+ for (final String testName : testNames) {
+ columns.add(createColumn(testName));
+ }
+ return columns;
+ }
+
+ /**
* Creates the column.
*
* @param columnName Column name.
@@ -981,6 +987,27 @@ class ResultsCommand implements Callable<Void> {
return list;
}
+
+ /**
+ * Creates the text format from column widths.
+ *
+ * @param columns Columns.
+ * @return the text format string
+ */
+ private static String createTextFormatFromColumnWidths(final List<List<String>> columns) {
+ final StringBuilder sb = new StringBuilder();
+ try (Formatter formatter = new Formatter(sb)) {
+ for (int i = 0; i < columns.size(); i++) {
+ if (i != 0) {
+ sb.append('\t');
+ }
+ formatter.format("%%-%ds", getColumnWidth(columns.get(i)));
+ }
+ }
+ sb.append(System.lineSeparator());
+ return sb.toString();
+ }
+
/**
* Gets the column width using the maximum length of the column items.
*
@@ -989,7 +1016,7 @@ class ResultsCommand implements Callable<Void> {
*/
private static int getColumnWidth(List<String> column) {
int width = 0;
- for (String text : column) {
+ for (final String text : column) {
width = Math.max(width, text.length());
}
return width;
diff --git a/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/StressTestCommand.java b/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/StressTestCommand.java
index 9eaa405..2bc87fd 100644
--- a/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/StressTestCommand.java
+++ b/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/StressTestCommand.java
@@ -44,6 +44,7 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.ReentrantLock;
/**
* Specification for the "stress" command.
@@ -57,6 +58,9 @@ import java.util.concurrent.TimeUnit;
description = {"Run repeat trials of random data generators using a provided test application.",
"Data is transferred to the application sub-process via standard input."})
class StressTestCommand implements Callable<Void> {
+ /** 1000. Any value below this can be exactly represented to 3 significant figures. */
+ private static final int ONE_THOUSAND = 1000;
+
/** The standard options. */
@Mixin
private StandardOptions reusableOptions;
@@ -160,11 +164,16 @@ class StressTestCommand implements Callable<Void> {
@Option(names = {"--dry-run"},
description = "Perform a dry run where the generators and output files are created " +
"but the stress test is not executed.")
- private boolean dryRun = false;
+ private boolean dryRun;
- /** The stop file exists flag. This is set in a synchronised method. */
+ /** The locl to hold when checking the stop file. */
+ private ReentrantLock stopFileLock = new ReentrantLock(false);
+ /** The stop file exists flag. This should be read/updated when holding the lock. */
private boolean stopFileExists;
- /** The timestamp when the stop file was last checked. */
+ /**
+ * The timestamp when the stop file was last checked.
+ * This should be read/updated when holding the lock.
+ */
private long stopFileTimestamp;
/**
@@ -215,26 +224,41 @@ class StressTestCommand implements Callable<Void> {
/**
* Check if the stop file exists.
*
- * <p>This method is synchronized. It will log a message if the file exists one time only.
+ * <p>This method is thread-safe. It will log a message if the file exists one time only.
*
* @return true if the stop file exists
*/
- private synchronized boolean stopFileExists() {
- if (!stopFileExists) {
- // This should hit the filesystem each time it is called.
- // To prevent this happening a lot when all the first set of tasks run use
- // a timestamp to limit the check to 1 time each interval.
- final long timestamp = System.currentTimeMillis();
- if (timestamp > stopFileTimestamp) {
- stopFileTimestamp = timestamp + TimeUnit.SECONDS.toMillis(2);
- stopFileExists = stopFile.exists();
- if (stopFileExists) {
- LogUtils.info("Stop file detected: " + stopFile);
- LogUtils.info("No further tasks will start");
+ private boolean isStopFileExists() {
+ stopFileLock.lock();
+ try {
+ if (!stopFileExists) {
+ // This should hit the filesystem each time it is called.
+ // To prevent this happening a lot when all the first set of tasks run use
+ // a timestamp to limit the check to 1 time each interval.
+ final long timestamp = System.currentTimeMillis();
+ if (timestamp > stopFileTimestamp) {
+ checkStopFile(timestamp);
}
}
+ return stopFileExists;
+ } finally {
+ stopFileLock.unlock();
+ }
+ }
+
+ /**
+ * Check if the stop file exists. Update the timestamp for the next check. If the stop file
+ * does exists then log a message.
+ *
+ * @param timestamp Timestamp of the last check.
+ */
+ private void checkStopFile(final long timestamp) {
+ stopFileTimestamp = timestamp + TimeUnit.SECONDS.toMillis(2);
+ stopFileExists = stopFile.exists();
+ if (stopFileExists) {
+ LogUtils.info("Stop file detected: %s", stopFile);
+ LogUtils.info("No further tasks will start");
}
- return stopFileExists;
}
/**
@@ -282,14 +306,14 @@ class StressTestCommand implements Callable<Void> {
* @param stressTestData List of generators to be tested.
*/
private void runStressTest(Iterable<StressTestData> stressTestData) {
- final ArrayList<String> command = ProcessUtils.buildSubProcessCommand(executable, executableArguments);
+ final List<String> command = ProcessUtils.buildSubProcessCommand(executable, executableArguments);
// Check existing output files before starting the tasks.
final String basePath = fileOutputPrefix.getAbsolutePath();
checkExistingOutputFiles(basePath, stressTestData);
LogUtils.info("Running stress test ...");
- LogUtils.info("Shutdown by creating stop file: " + stopFile);
+ LogUtils.info("Shutdown by creating stop file: %s", stopFile);
final ProgressTracker progressTracker = new ProgressTracker(countTrials(stressTestData));
// Run tasks with parallel execution.
@@ -398,7 +422,7 @@ class StressTestCommand implements Callable<Void> {
*/
private void submitTasks(ExecutorService service,
List<Future<?>> taskList,
- ArrayList<String> command,
+ List<String> command,
String basePath,
StressTestData testData,
ProgressTracker progressTracker) {
@@ -472,9 +496,11 @@ class StressTestCommand implements Callable<Void> {
/**
* Increment the progress.
*/
- synchronized void incrementProgress() {
- count++;
- showProgress();
+ void incrementProgress() {
+ synchronized (this) {
+ count++;
+ showProgress();
+ }
}
/**
@@ -558,7 +584,7 @@ class StressTestCommand implements Callable<Void> {
/** {@inheritDoc} */
@Override
public void run() {
- if (cmd.stopFileExists()) {
+ if (cmd.isStopFileExists()) {
// Do nothing
return;
}
@@ -609,7 +635,7 @@ class StressTestCommand implements Callable<Void> {
sink.writeInt(rng.nextInt());
numbersUsed++;
}
- } catch (final IOException e) {
+ } catch (final IOException ignored) {
// Hopefully getting here when the analyzing software terminates.
}
@@ -624,33 +650,32 @@ class StressTestCommand implements Callable<Void> {
* {@code output} file.
*/
private void printHeader() throws IOException {
- final StringBuilder sb = new StringBuilder();
- sb.append(C).append(N);
- sb.append(C).append("RandomSource: ").append(randomSource.name()).append(N);
- sb.append(C).append("RNG: ").append(rng.toString()).append(N);
- sb.append(C).append("Seed: ").append(RNGUtils.encodeHex(seed)).append(N);
- sb.append(C).append(N);
+ final StringBuilder sb = new StringBuilder(200);
+ sb.append(C).append(N)
+ .append(C).append("RandomSource: ").append(randomSource.name()).append(N)
+ .append(C).append("RNG: ").append(rng.toString()).append(N)
+ .append(C).append("Seed: ").append(RNGUtils.encodeHex(seed)).append(N)
+ .append(C).append(N)
// Match the output of 'java -version', e.g.
// java version "1.8.0_131"
// Java(TM) SE Runtime Environment (build 1.8.0_131-b11)
// Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, mixed mode)
- sb.append(C).append("Java: ").append(System.getProperty("java.version")).append(N);
+ .append(C).append("Java: ").append(System.getProperty("java.version")).append(N);
appendNameAndVersion(sb, "Runtime", "java.runtime.name", "java.runtime.version");
appendNameAndVersion(sb, "JVM", "java.vm.name", "java.vm.version", "java.vm.info");
sb.append(C).append("OS: ").append(System.getProperty("os.name"))
.append(' ').append(System.getProperty("os.version"))
- .append(' ').append(System.getProperty("os.arch")).append(N);
- sb.append(C).append("Native byte-order: ").append(ByteOrder.nativeOrder()).append(N);
- sb.append(C).append(N);
-
- sb.append(C).append("Analyzer: ");
+ .append(' ').append(System.getProperty("os.arch")).append(N)
+ .append(C).append("Native byte-order: ").append(ByteOrder.nativeOrder()).append(N)
+ .append(C).append(N)
+ .append(C).append("Analyzer: ");
for (final String s : command) {
sb.append(s).append(' ');
}
- sb.append(N);
- sb.append(C).append(N);
+ sb.append(N)
+ .append(C).append(N);
appendDate(sb, "Start").append(C).append(N);
@@ -667,21 +692,20 @@ class StressTestCommand implements Callable<Void> {
*/
private void printFooter(long nanoTime,
Object exitValue) throws IOException {
- final StringBuilder sb = new StringBuilder();
+ final StringBuilder sb = new StringBuilder(200);
sb.append(C).append(N);
appendDate(sb, "End").append(C).append(N);
- sb.append(C).append("Exit value: ").append(exitValue).append(N);
- sb.append(C).append("Numbers used: ").append(numbersUsed)
- .append(" >= 2^").append(log2(numbersUsed))
- .append(" (").append(bytesToString(numbersUsed * 4)).append(')').append(N);
- sb.append(C).append(N);
+ sb.append(C).append("Exit value: ").append(exitValue).append(N)
+ .append(C).append("Numbers used: ").append(numbersUsed)
+ .append(" >= 2^").append(log2(numbersUsed))
+ .append(" (").append(bytesToString(numbersUsed * 4)).append(')').append(N)
+ .append(C).append(N);
final double duration = nanoTime * 1e-9 / 60;
- sb.append(C).append("Test duration: ").append(duration).append(" minutes").append(N);
-
- sb.append(C).append(N);
+ sb.append(C).append("Test duration: ").append(duration).append(" minutes").append(N)
+ .append(C).append(N);
write(sb, output, true);
}
@@ -726,7 +750,7 @@ class StressTestCommand implements Callable<Void> {
.append(System.getProperty(nameKey, "?"))
.append(" (build ")
.append(System.getProperty(versionKey, "?"));
- for (String key : infoKeys) {
+ for (final String key : infoKeys) {
final String value = System.getProperty(key, "");
if (!value.isEmpty()) {
sb.append(", ").append(value);
@@ -748,7 +772,7 @@ class StressTestCommand implements Callable<Void> {
private static StringBuilder appendDate(StringBuilder sb,
String prefix) {
// Use local date format. It is not thread safe.
- final SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT);
+ final SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT, Locale.US);
return appendPrefix(sb, prefix).append(dateFormat.format(new Date())).append(N);
}
@@ -796,7 +820,7 @@ class StressTestCommand implements Callable<Void> {
*/
static String bytesToString(long bytes) {
// When using the smallest unit no decimal point is needed, because it's the exact number.
- if (bytes < 1000) {
+ if (bytes < ONE_THOUSAND) {
return bytes + " " + SI_UNITS[0];
}