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 67cd8613bfa719671026ea56627c8913a64f49e9
Author: aherbert <aherb...@apache.org>
AuthorDate: Wed Oct 9 12:39:09 2019 +0100

    Allow ignoring partial results files in the results report.
    
    This allows the results to be examined while the test application is
    still running.
---
 .../rng/examples/stress/ResultsCommand.java        | 97 +++++++++++++++++++---
 1 file changed, 87 insertions(+), 10 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 5f3eb9e..745b43e 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
@@ -40,6 +40,7 @@ import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
+import java.util.ListIterator;
 import java.util.Map.Entry;
 import java.util.concurrent.Callable;
 import java.util.function.Function;
@@ -76,6 +77,8 @@ class ResultsCommand implements Callable<Void> {
     private static final Pattern TESTU01_SUMMARY_PATTERN = 
Pattern.compile("^========= Summary results of (\\S*) ");
     /** The pattern to identify the Test U01 failed test result. */
     private static final Pattern TESTU01_TEST_RESULT_PATTERN = 
Pattern.compile("^  ?(\\d+  .*)    ");
+    /** The pattern to identify the Test U01 test starting entry. */
+    private static final Pattern TESTU01_STARTING_PATTERN = Pattern.compile("^ 
*Starting (\\S*)");
     /** The name of the Dieharder sums test. */
     private static final String DIEHARDER_SUMS = "diehard_sums";
     /** The string identifying a bit-reversed generator. */
@@ -129,6 +132,11 @@ 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. */
+    @Option(names = {"-i", "--ignore"},
+            description = "Ignore partial results.")
+    private boolean ignorePartialResults;
+
     /**
      * The output mode for the results.
      */
@@ -418,7 +426,7 @@ class ResultsCommand implements Callable<Void> {
     private TestResult readResult(File resultFile,
                                   List<String> testOutput) {
         // Use an iterator for a single pass over the test output
-        final Iterator<String> iter = testOutput.iterator();
+        final ListIterator<String> iter = testOutput.listIterator();
 
         // Identify the RandomSource and bit reversed flag from the header:
         final RandomSource randomSource = getRandomSource(iter);
@@ -491,7 +499,7 @@ class ResultsCommand implements Callable<Void> {
      * Read the result output from the Dieharder test application.
      *
      * @param iter Iterator of the test output.
-     * @param testResult the test result
+     * @param testResult Test result.
      */
     private void readDieharder(Iterator<String> iter,
                                TestResult testResult) {
@@ -528,11 +536,15 @@ class ResultsCommand implements Callable<Void> {
     /**
      * Read the result output from the Test U01 test application.
      *
+     * <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 iter Iterator of the test output.
-     * @param testResult the test result
+     * @param testResult Test result.
+     * @throws ApplicationException If the TestU01 summary cannot be found.
      */
-    private static void readTestU01(Iterator<String> iter,
-                                    TestResult testResult) {
+    private void readTestU01(ListIterator<String> iter,
+                             TestResult testResult) {
         // Results are summarised at the end of the file:
         //========= Summary results of BigCrush =========
         //
@@ -552,7 +564,19 @@ class ResultsCommand implements Callable<Void> {
         // 7  CollisionOver, t = 7             eps
 
         // Identify the summary line
-        testResult.setTestApplicationName("TestU01 (" + 
skipToTestU01Summary(iter) + ")");
+        final String testSuiteName = skipToTestU01Summary(iter);
+
+        // This may not be present if the results are not complete
+        if (testSuiteName == null) {
+            // Rewind
+            while (iter.hasPrevious()) {
+                iter.previous();
+            }
+            updateTestU01ApplicationName(iter, testResult);
+            return;
+        }
+
+        setTestU01ApplicationName(testResult, testSuiteName);
 
         // Read test results using the entire line except the p-value for the 
test Id
         // Note:
@@ -570,20 +594,68 @@ class ResultsCommand implements Callable<Void> {
     }
 
     /**
+     * Sets the Test U01 application name using the provide test suite name.
+     *
+     * @param testResult Test result.
+     * @param testSuiteName Test suite name.
+     */
+    private static void setTestU01ApplicationName(TestResult testResult, 
String testSuiteName) {
+        testResult.setTestApplicationName("TestU01 (" + testSuiteName + ")");
+    }
+
+    /**
      * Skip to the Test U01 result summary.
      *
+     * <p>If this cannot be found the method will throw an exception unless 
partial results
+     * are allowed.</p>
+     *
      * @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) {
+        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");
+    }
+
+    /**
+     * Update the test application name from the Test U01 results. This can be 
used to identify
+     * the test suite from the start of the results in the event that the 
results summary has
+     * not been output.
+     *
+     * @param iter Iterator of the test output.
+     * @param testResult Test result.
      */
-    private static String skipToTestU01Summary(Iterator<String> iter) {
+    private static void updateTestU01ApplicationName(Iterator<String> iter,
+                                                     TestResult testResult) {
+        final String testSuiteName = findMatcherGroup1(iter, 
TESTU01_STARTING_PATTERN);
+        if (testSuiteName != null) {
+            setTestU01ApplicationName(testResult, testSuiteName);
+        }
+    }
+
+    /**
+     * Create a matcher for each item in the iterator and if a match is 
identified return
+     * group 1.
+     *
+     * @param iter Iterator of text to match.
+     * @param pattern Pattern to match.
+     * @return the string (or null)
+     */
+    private static String findMatcherGroup1(Iterator<String> iter,
+                                            Pattern pattern) {
         while (iter.hasNext()) {
             final String line = iter.next();
-            final Matcher matcher = TESTU01_SUMMARY_PATTERN.matcher(line);
+            final Matcher matcher = pattern.matcher(line);
             if (matcher.find()) {
                 return matcher.group(1);
             }
         }
-        throw new ApplicationException("Failed to identify the Test U01 result 
summary");
+        return null;
     }
 
     /**
@@ -923,6 +995,10 @@ class ResultsCommand implements Callable<Void> {
     private static List<String> getSystematicFailures(List<TestResult> 
results) {
         final HashMap<String, Integer> map = new HashMap<>();
         for (final TestResult result : results) {
+            // Ignore partial results
+            if (!result.isComplete()) {
+                continue;
+            }
             // Some named tests can fail more than once on different 
statistics.
             // For example TestU01 BigCrush LongestHeadRun can output in the 
summary:
             // 86  LongestHeadRun, r = 0            eps
@@ -934,7 +1010,8 @@ class ResultsCommand implements Callable<Void> {
                 map.merge(test, 1, (i, j) -> i + j);
             }
         }
-        return map.entrySet().stream().filter(e -> e.getValue() == 
results.size())
+        final int completeCount = (int) 
results.stream().filter(TestResult::isComplete).count();
+        return map.entrySet().stream().filter(e -> e.getValue() == 
completeCount)
                                       .map(Entry::getKey)
                                       .collect(Collectors.toList());
     }

Reply via email to