1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 package org.apache.commons.rng.examples.stress; 18 19 import picocli.CommandLine; 20 import picocli.CommandLine.RunLast; 21 22 /** 23 * Executes testing utilities for the random number generators in the Commons RNG library. 24 * 25 * <p>The principle action is testing a generator by piping the values returned by its 26 * {@link org.apache.commons.rng.UniformRandomProvider#nextInt() 27 * UniformRandomProvider.nextInt()} method to a program that reads {@code int} values from 28 * its standard input and writes an analysis report to standard output. The <a 29 * href="http://www.phy.duke.edu/~rgb/General/dieharder.php"> "Dieharder"</a> test suite 30 * is such a software.</p> 31 * 32 * <p>Example of command line, assuming that "examples-stress.jar" specifies this 33 * class as the "main" class (see {@link #main(String[]) main} method):</p> 34 * 35 * <pre>{@code $ java -jar examples-stress.jar stress /usr/bin/dieharder -a -g 200 -Y 1 -k 2}</pre> 36 * 37 * <p>Other functionality includes:</p> 38 * 39 * <ul> 40 * <li>Listing all the available generators 41 * <li>Collating results from known stress test applications 42 * <li>Outputting data from a random generator 43 * <li>Showing the platform native byte order 44 * <li>Testing data transfer to an application sub-process via its standard input 45 * </ul> 46 */ 47 public final class ExamplesStressApplication { 48 /** No public constructor. */ 49 private ExamplesStressApplication() {} 50 51 /** 52 * Run the RNG examples stress command line application. 53 * 54 * @param args Application's arguments. 55 */ 56 public static void main(String[] args) { 57 // Build the command line manually so we can configure options. 58 final CommandLine cmd = new CommandLine(new ExamplesStressCommand()) 59 .addSubcommand("bridge", new CommandLine(new BridgeTestCommand()) 60 .setStopAtPositional(true)) 61 .addSubcommand("endian", new EndianessCommand()) 62 .addSubcommand("list", new ListCommand()) 63 .addSubcommand("output", new CommandLine(new OutputCommand()) 64 // Allow the input seed using hex (0x, 0X, #) 65 // or octal (starting with 0) 66 .registerConverter(Long.class, Long::decode)) 67 .addSubcommand("results", new ResultsCommand()) 68 .addSubcommand("stress", new CommandLine(new StressTestCommand()) 69 .setStopAtPositional(true)) 70 // Call last to apply to all sub-commands 71 .setCaseInsensitiveEnumValuesAllowed(true); 72 73 try { 74 // Parse the command line and invokes the Callable program (RNGUtilities) 75 cmd.parseWithHandler(new RunLast(), args); 76 } catch (final CommandLine.ExecutionException ex) { 77 final Throwable cause = ex.getCause(); 78 if (cause != null) { 79 // If this was an exception generated by the application then the full 80 // stack trace is not needed depending on log level. This limits stack 81 // trace output to unexpected errors in the common use case. 82 if (cause instanceof ApplicationException && 83 !LogUtils.isLoggable(LogUtils.LogLevel.DEBUG)) { 84 LogUtils.error(cause.getMessage()); 85 } else { 86 LogUtils.error(cause, cause.getMessage()); 87 } 88 System.exit(1); 89 } 90 // No cause so re-throw. This may be a Picocli parsing error. 91 throw ex; 92 } 93 } 94 }