blob: 83f7f2bb7f63c7ad2c4c53015bc0ee2d999f3684 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.rng.examples.stress;
import picocli.CommandLine;
import picocli.CommandLine.RunLast;
/**
* Executes testing utilities for the random number generators in the Commons RNG library.
*
* <p>The principle action is testing a generator by piping the values returned by its
* {@link org.apache.commons.rng.UniformRandomProvider#nextInt()
* UniformRandomProvider.nextInt()} method to a program that reads {@code int} values from
* its standard input and writes an analysis report to standard output. The <a
* href="http://www.phy.duke.edu/~rgb/General/dieharder.php"> "Dieharder"</a> test suite
* is such a software.</p>
*
* <p>Example of command line, assuming that "examples-stress.jar" specifies this
* class as the "main" class (see {@link #main(String[]) main} method):</p>
*
* <pre>{@code $ java -jar examples-stress.jar stress /usr/bin/dieharder -a -g 200 -Y 1 -k 2}</pre>
*
* <p>Other functionality includes:</p>
*
* <ul>
* <li>Listing all the available generators
* <li>Collating results from known stress test applications
* <li>Outputting data from a random generator
* <li>Showing the platform native byte order
* <li>Testing data transfer to an application sub-process via its standard input
* </ul>
*/
public final class ExamplesStressApplication {
/** No public constructor. */
private ExamplesStressApplication() {}
/**
* Run the RNG examples stress command line application.
*
* @param args Application's arguments.
*/
public static void main(String[] args) {
// Build the command line manually so we can configure options.
final CommandLine cmd = new CommandLine(new ExamplesStressCommand())
.addSubcommand("bridge", new CommandLine(new BridgeTestCommand())
.setStopAtPositional(true))
.addSubcommand("endian", new EndianessCommand())
.addSubcommand("list", new ListCommand())
.addSubcommand("output", new CommandLine(new OutputCommand())
// Allow the input seed using hex (0x, 0X, #)
// or octal (starting with 0)
.registerConverter(Long.class, Long::decode))
.addSubcommand("results", new ResultsCommand())
.addSubcommand("stress", new CommandLine(new StressTestCommand())
.setStopAtPositional(true))
// Call last to apply to all sub-commands
.setCaseInsensitiveEnumValuesAllowed(true);
try {
// Parse the command line and invokes the Callable program (RNGUtilities)
cmd.parseWithHandler(new RunLast(), args);
} 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
// stack trace is not needed depending on log level. This limits stack
// trace output to unexpected errors in the common use case.
if (cause instanceof ApplicationException &&
!LogUtils.isLoggable(LogUtils.LogLevel.DEBUG)) {
LogUtils.error(cause.getMessage());
} else {
LogUtils.error(cause, cause.getMessage());
}
System.exit(1);
}
// No cause so re-throw. This may be a Picocli parsing error.
throw ex;
}
}
}