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/10/11 13:28:24 UTC

[commons-rng] 12/16: Added command to delete partial results files.

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 e4a980bed2769a608747fa67213ecafec25ede87
Author: aherbert <ah...@apache.org>
AuthorDate: Fri Oct 11 13:15:56 2019 +0100

    Added command to delete partial results files.
---
 .../rng/examples/stress/ResultsCommand.java        | 104 ++++++++++++++++-----
 1 file changed, 82 insertions(+), 22 deletions(-)

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 745b43e..03ee8d0 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
@@ -132,11 +132,17 @@ class ResultsCommand implements Callable<Void> {
                            "files when the path is output, e.g. for the APT report."})
     private String pathPrefix = "";
 
-    /** The flag to include the Dieharder sums test. */
+    /** The flag to ignore partial results. */
     @Option(names = {"-i", "--ignore"},
             description = "Ignore partial results.")
     private boolean ignorePartialResults;
 
+    /** The flag to delete partial results files. */
+    @Option(names = {"--delete"},
+            description = {"Delete partial results files.",
+                           "This is not reversible!"})
+    private boolean deletePartialResults;
+
     /**
      * The output mode for the results.
      */
@@ -283,7 +289,7 @@ class ResultsCommand implements Callable<Void> {
          * @return the test application name
          */
         String getTestApplicationName() {
-            return testApplicationName == null ? getTestFormat().toString() : testApplicationName;
+            return testApplicationName == null ? String.valueOf(getTestFormat()) : testApplicationName;
         }
 
         /**
@@ -315,6 +321,11 @@ class ResultsCommand implements Callable<Void> {
         // Read the results
         final List<TestResult> results = readResults();
 
+        if (deletePartialResults) {
+            deleteIfIncomplete(results);
+            return null;
+        }
+
         try (OutputStream out = createOutputStream()) {
             switch (outputFormat) {
             case CSV:
@@ -356,6 +367,7 @@ class ResultsCommand implements Callable<Void> {
      *
      * @param results Results.
      * @param resultFile Result file.
+     * @throws ApplicationException If the results cannot be parsed.
      */
     private void readResults(List<TestResult> results,
                              File resultFile) {
@@ -366,7 +378,11 @@ class ResultsCommand implements Callable<Void> {
             LogUtils.error("No test output in file: %s", resultFile);
         } else {
             for (final List<String> testOutput : outputs) {
-                results.add(readResult(resultFile, testOutput));
+                final TestResult result = readResult(resultFile, testOutput);
+                results.add(result);
+                if (!result.isComplete()) {
+                    LogUtils.info("Partial results in file: %s", resultFile);
+                }
             }
         }
     }
@@ -422,6 +438,7 @@ class ResultsCommand implements Callable<Void> {
      * @param resultFile Result file.
      * @param testOutput Test output.
      * @return the test result
+     * @throws ApplicationException If the result cannot be parsed.
      */
     private TestResult readResult(File resultFile,
                                   List<String> testOutput) {
@@ -429,17 +446,18 @@ class ResultsCommand implements Callable<Void> {
         final ListIterator<String> iter = testOutput.listIterator();
 
         // Identify the RandomSource and bit reversed flag from the header:
-        final RandomSource randomSource = getRandomSource(iter);
-        final boolean bitReversed = getBitReversed(iter);
-        // Identify the test application format
-        final TestFormat testFormat = getTestFormat(iter);
+        final RandomSource randomSource = getRandomSource(resultFile, iter);
+        final boolean bitReversed = getBitReversed(resultFile, iter);
+
+        // Identify the test application format. This may return null.
+        final TestFormat testFormat = getTestFormat(resultFile, iter);
 
         // Read the application results
         final TestResult testResult = new TestResult(resultFile, randomSource, bitReversed, testFormat);
         if (testFormat == TestFormat.DIEHARDER) {
             readDieharder(iter, testResult);
         } else {
-            readTestU01(iter, testResult);
+            readTestU01(resultFile, iter, testResult);
         }
         return testResult;
     }
@@ -447,42 +465,50 @@ class ResultsCommand implements Callable<Void> {
     /**
      * Gets the random source from the output header.
      *
+     * @param resultFile Result file (for the exception message).
      * @param iter Iterator of the test output.
      * @return the random source
+     * @throws ApplicationException If the RandomSource header line cannot be found.
      */
-    private static RandomSource getRandomSource(Iterator<String> iter) {
+    private static RandomSource getRandomSource(File resultFile, Iterator<String> iter) {
         while (iter.hasNext()) {
             final Matcher matcher = RANDOM_SOURCE_PATTERN.matcher(iter.next());
             if (matcher.matches()) {
                 return RandomSource.valueOf(matcher.group(1));
             }
         }
-        throw new ApplicationException("Failed to find RandomSource header line");
+        throw new ApplicationException("Failed to find RandomSource header line: " + resultFile);
     }
 
     /**
      * Gets the bit-reversed flag from the output header.
      *
+     * @param resultFile Result file (for the exception message).
      * @param iter Iterator of the test output.
      * @return the bit-reversed flag
+     * @throws ApplicationException If the RNG header line cannot be found.
      */
-    private static boolean getBitReversed(Iterator<String> iter) {
+    private static boolean getBitReversed(File resultFile, Iterator<String> iter) {
         while (iter.hasNext()) {
             final Matcher matcher = RNG_PATTERN.matcher(iter.next());
             if (matcher.matches()) {
                 return matcher.group(1).contains(BIT_REVERSED);
             }
         }
-        throw new ApplicationException("Failed to find RNG header line");
+        throw new ApplicationException("Failed to find RNG header line: " + resultFile);
     }
 
     /**
-     * Gets the test format from the output.
+     * Gets the test format from the output. This scans the stdout produced by a test application.
+     * If it is not recognised this may be a valid partial result or an unknown result. Throw
+     * an exception if not allowing partial results, otherwise log an error.
      *
+     * @param resultFile Result file (for the exception message).
      * @param iter Iterator of the test output.
-     * @return the test format
+     * @return the test format (or null)
+     * @throws ApplicationException If the test format cannot be found.
      */
-    private static TestFormat getTestFormat(Iterator<String> iter) {
+    private TestFormat getTestFormat(File resultFile, Iterator<String> iter) {
         while (iter.hasNext()) {
             final String line = iter.next();
             if (DIEHARDER_PATTERN.matcher(line).find()) {
@@ -492,7 +518,11 @@ class ResultsCommand implements Callable<Void> {
                 return TestFormat.TESTU01;
             }
         }
-        throw new ApplicationException("Failed to identify the test application format");
+        if (!ignorePartialResults) {
+            throw new ApplicationException("Failed to identify the test application format: " + resultFile);
+        }
+        LogUtils.error("Failed to identify the test application format: %s", resultFile);
+        return null;
     }
 
     /**
@@ -528,7 +558,7 @@ class ResultsCommand implements Callable<Void> {
                                          line.substring(index1 + 1, index2).trim());
             } else if (TEST_DURATION_PATTERN.matcher(line).find()) {
                 testResult.setComplete(true);
-                break;
+                return;
             }
         }
     }
@@ -539,11 +569,13 @@ class ResultsCommand implements Callable<Void> {
      * <p>Test U01 outputs a summary of results at the end of the test output. If this cannot
      * be found the method will throw an exception unless partial results are allowed.</p>
      *
+     * @param resultFile Result file (for the exception message).
      * @param iter Iterator of the test output.
      * @param testResult Test result.
      * @throws ApplicationException If the TestU01 summary cannot be found.
      */
-    private void readTestU01(ListIterator<String> iter,
+    private void readTestU01(File resultFile,
+                             ListIterator<String> iter,
                              TestResult testResult) {
         // Results are summarised at the end of the file:
         //========= Summary results of BigCrush =========
@@ -564,7 +596,7 @@ class ResultsCommand implements Callable<Void> {
         // 7  CollisionOver, t = 7             eps
 
         // Identify the summary line
-        final String testSuiteName = skipToTestU01Summary(iter);
+        final String testSuiteName = skipToTestU01Summary(resultFile, iter);
 
         // This may not be present if the results are not complete
         if (testSuiteName == null) {
@@ -588,7 +620,7 @@ class ResultsCommand implements Callable<Void> {
                 testResult.addFailedTest(matcher.group(1).trim());
             } else if (TEST_DURATION_PATTERN.matcher(line).find()) {
                 testResult.setComplete(true);
-                break;
+                return;
             }
         }
     }
@@ -609,17 +641,18 @@ class ResultsCommand implements Callable<Void> {
      * <p>If this cannot be found the method will throw an exception unless partial results
      * are allowed.</p>
      *
+     * @param resultFile Result file (for the exception message).
      * @param iter Iterator of the test output.
      * @return the name of the test suite
      * @throws ApplicationException If the TestU01 summary cannot be found.
      */
-    private String skipToTestU01Summary(Iterator<String> iter) {
+    private String skipToTestU01Summary(File resultFile, Iterator<String> iter) {
         final String testSuiteName = findMatcherGroup1(iter, TESTU01_SUMMARY_PATTERN);
         // Allow the partial result to be ignored
         if (testSuiteName != null || ignorePartialResults) {
             return testSuiteName;
         }
-        throw new ApplicationException("Failed to identify the Test U01 result summary");
+        throw new ApplicationException("Failed to identify the Test U01 result summary: " + resultFile);
     }
 
     /**
@@ -659,6 +692,33 @@ class ResultsCommand implements Callable<Void> {
     }
 
     /**
+     * Delete any result file if incomplete.
+     *
+     * @param results Results.
+     * @throws ApplicationException If a file could not be deleted.
+     */
+    private static void deleteIfIncomplete(List<TestResult> results) {
+        results.forEach(ResultsCommand::deleteIfIncomplete);
+    }
+
+    /**
+     * Delete the result file if incomplete.
+     *
+     * @param result Test result.
+     * @throws ApplicationException If the file could not be deleted.
+     */
+    private static void deleteIfIncomplete(TestResult result) {
+        if (!result.isComplete()) {
+            try {
+                Files.delete(result.getResultFile().toPath());
+                LogUtils.info("Deleted file: %s", result.getResultFile());
+            } catch (IOException ex) {
+                throw new ApplicationException("Failed to delete file: " + result.getResultFile(), ex);
+            }
+        }
+    }
+
+    /**
      * Creates the output stream. This will not be buffered.
      *
      * @return the output stream