From 96af6ec27288abe6cf3f1b9b40ed0dc62217b87a Mon Sep 17 00:00:00 2001 From: August Shi Date: Tue, 14 Jun 2016 23:22:50 -0500 Subject: [PATCH 1/3] Made significant changes to support multiple single points for debugging, across all seeds --- .../edu/illinois/nondex/plugin/DebugTask.java | 105 +++++++++++------- 1 file changed, 64 insertions(+), 41 deletions(-) diff --git a/nondex-maven-plugin/src/main/java/edu/illinois/nondex/plugin/DebugTask.java b/nondex-maven-plugin/src/main/java/edu/illinois/nondex/plugin/DebugTask.java index 509dd0cc..f7068b62 100644 --- a/nondex-maven-plugin/src/main/java/edu/illinois/nondex/plugin/DebugTask.java +++ b/nondex-maven-plugin/src/main/java/edu/illinois/nondex/plugin/DebugTask.java @@ -73,28 +73,42 @@ public String debug() throws MojoExecutionException { assert (!this.failingConfigurations.isEmpty()); - Configuration failingOne = this.debugWithConfigurations(this.failingConfigurations); + List debuggedOnes = this.debugWithConfigurations(this.failingConfigurations); Logger.getGlobal().log(Level.SEVERE, "limits : " + limits.getLeft() + " " + limits.getRight()); - if (failingOne != null) { - return failingOne.toArgLine() + "\nDEBUG RESULTS FOR " + failingOne.testName + " AT: " - + failingOne.getDebugPath(); + if (debuggedOnes.size() > 0) { + return makeResultString(debuggedOnes); } // The seeds that failed with the full test-suite no longer fail // Searching for different seeds + Logger.getGlobal().log(Level.FINE, "TRYING NEW SEEDS"); List retryWOtherSeeds = this.createNewSeedsToRetry(); - failingOne = this.debugWithConfigurations(retryWOtherSeeds); + debuggedOnes = this.debugWithConfigurations(retryWOtherSeeds); - if (failingOne != null) { - return failingOne.toArgLine() + "\nDEBUG RESULTS FOR " + failingOne.testName + " AT: " - + failingOne.getDebugPath(); + if (debuggedOnes.size() > 0) { + return makeResultString(debuggedOnes); } return "cannot reproduce. may be flaky due to other causes"; } + private String makeResultString(List debuggedOnes) { + StringBuilder sb = new StringBuilder(); + for (Configuration config : debuggedOnes) { + sb.append(config.toArgLine()); + sb.append("\nDEBUG RESULTS FOR "); + sb.append(config.testName); + sb.append(" AND SEED: "); + sb.append(config.seed); + sb.append(" AT: "); + sb.append(config.getDebugPath()); + sb.append("\n"); + } + return sb.toString(); + } + private List createNewSeedsToRetry() { Configuration someFailingConfig = this.failingConfigurations.iterator().next(); int newSeed = someFailingConfig.seed * ConfigurationDefaults.SEED_FACTOR; @@ -110,55 +124,64 @@ private List createNewSeedsToRetry() { return retryWOtherSeeds; } - private Configuration debugWithConfigurations(List failingConfigurations) { - Configuration debConfig = null; + private List debugWithConfigurations(List failingConfigurations) { + //Configuration debConfig = null; + List allDebuggedConfigs = new LinkedList(); for (Configuration config : failingConfigurations) { Configuration dryConfig; if ((dryConfig = this.failsOnDry(config)) != null) { - Configuration failingConfig = this.startDebugBinary(dryConfig); - - // If debugged down to single choice point, then go ahead and return that - if (failingConfig != null && failingConfig.numChoices() == 0) { - return failingConfig; - } - // Otherwise should go on until finding better one - if (debConfig == null || failingConfig.hasFewerChoicePoints(debConfig)) { - debConfig = failingConfig; - } + // Get all debugged points and just add them to the full list + List debuggedConfigs = this.startDebugBinary(dryConfig); + allDebuggedConfigs.addAll(debuggedConfigs); } } - return debConfig; + return allDebuggedConfigs; } private Configuration failsOnDry(Configuration config) { return this.failsWithConfig(config, Integer.MIN_VALUE, Integer.MAX_VALUE); } - public Configuration startDebugBinary(Configuration config) { - long start = 0; - long end = config.getInvocationCount(); - Configuration failingConfiguration = null; - while (start < end) { - Logger.getGlobal().log(Level.INFO, "Debugging binary for " + this.test + " " + start + " : " + end); + public List startDebugBinary(Configuration config) { + List allFailingConfigurations = new LinkedList(); - long midPoint = (start + end) / 2; - if ((failingConfiguration = this.failsWithConfig(config, start, midPoint)) != null) { - end = midPoint; - continue; - } else if ((failingConfiguration = this.failsWithConfig(config, midPoint + 1, end)) != null) { - start = midPoint + 1; - continue; + List, Configuration>> pairs = new LinkedList, Configuration>>(); + pairs.add((Pair, Configuration>)Pair.of((Pair)Pair.of(0L, + (long)config.getInvocationCount()), (Configuration)null)); + + Configuration failingConfiguration = null; + while (pairs.size() > 0) { + Pair, Configuration> pair = pairs.remove(0); + Pair range = pair.getLeft(); + Configuration falingConfiguration = pair.getRight(); + long start = range.getLeft(); + long end = range.getRight(); + + if (start < end) { + Logger.getGlobal().log(Level.INFO, "Debugging binary for " + this.test + " " + start + " : " + end); + + long midPoint = (start + end) / 2; + if ((failingConfiguration = this.failsWithConfig(config, start, midPoint)) != null) { + pairs.add(Pair.of((Pair)Pair.of(start, midPoint), failingConfiguration)); + } + if ((failingConfiguration = this.failsWithConfig(config, midPoint + 1, end)) != null) { + pairs.add(Pair.of((Pair)Pair.of(midPoint + 1, end), failingConfiguration)); + } + /*{ + Logger.getGlobal().log(Level.FINE, "Binary splitting did not work. Going to linear"); + failingConfiguration = this.startDebugLinear(config, start, end); + break; + }*/ } else { - Logger.getGlobal().log(Level.FINE, "Binary splitting did not work. Going to linear"); - failingConfiguration = this.startDebugLinear(config, start, end); - break; + // Since start <= end is always true, this branch means start == end, so reached end + if (failingConfiguration != null) { + allFailingConfigurations.add(this.reportDebugInfo(failingConfiguration)); + } } } - if (failingConfiguration != null) { - return this.reportDebugInfo(failingConfiguration); - } - return failingConfiguration; + + return allFailingConfigurations; } private Configuration reportDebugInfo(Configuration failingConfiguration) { From 276a7d232651d4fe244a61c4a5cd1b459cd21d4b Mon Sep 17 00:00:00 2001 From: August Shi Date: Wed, 15 Jun 2016 00:29:55 -0500 Subject: [PATCH 2/3] Implemented logic for doing the linear stuff when binary does not work --- .../edu/illinois/nondex/plugin/DebugTask.java | 65 ++++++++++++------- 1 file changed, 43 insertions(+), 22 deletions(-) diff --git a/nondex-maven-plugin/src/main/java/edu/illinois/nondex/plugin/DebugTask.java b/nondex-maven-plugin/src/main/java/edu/illinois/nondex/plugin/DebugTask.java index f7068b62..62197446 100644 --- a/nondex-maven-plugin/src/main/java/edu/illinois/nondex/plugin/DebugTask.java +++ b/nondex-maven-plugin/src/main/java/edu/illinois/nondex/plugin/DebugTask.java @@ -154,25 +154,29 @@ public List startDebugBinary(Configuration config) { while (pairs.size() > 0) { Pair, Configuration> pair = pairs.remove(0); Pair range = pair.getLeft(); - Configuration falingConfiguration = pair.getRight(); + failingConfiguration = pair.getRight(); long start = range.getLeft(); long end = range.getRight(); if (start < end) { Logger.getGlobal().log(Level.INFO, "Debugging binary for " + this.test + " " + start + " : " + end); + boolean binarySuccess = false; long midPoint = (start + end) / 2; if ((failingConfiguration = this.failsWithConfig(config, start, midPoint)) != null) { pairs.add(Pair.of((Pair)Pair.of(start, midPoint), failingConfiguration)); + binarySuccess = true; } if ((failingConfiguration = this.failsWithConfig(config, midPoint + 1, end)) != null) { pairs.add(Pair.of((Pair)Pair.of(midPoint + 1, end), failingConfiguration)); + binarySuccess = true; + } + + // If both halves fail, try the entire range + if (!binarySuccess) { + Logger.getGlobal().log(Level.SEVERE, "Binary splitting did not work. Going to linear"); + allFailingConfigurations.addAll(this.startDebugLinear(config, start, end)); } - /*{ - Logger.getGlobal().log(Level.FINE, "Binary splitting did not work. Going to linear"); - failingConfiguration = this.startDebugLinear(config, start, end); - break; - }*/ } else { // Since start <= end is always true, this branch means start == end, so reached end if (failingConfiguration != null) { @@ -188,25 +192,42 @@ private Configuration reportDebugInfo(Configuration failingConfiguration) { return this.failsWithConfig(failingConfiguration, failingConfiguration.start, failingConfiguration.end, true); } - public Configuration startDebugLinear(Configuration config, long start, long end) { + public List startDebugLinear(Configuration config, long start, long end) { + List allFailingConfigurations = new LinkedList(); + + List, Configuration>> pairs = new LinkedList, Configuration>>(); + pairs.add((Pair, Configuration>)Pair.of((Pair)Pair.of(start, end), + (Configuration)null)); + Configuration failingConfiguration = null; - long localStart = start; - long localEnd = end; - while (localStart < localEnd) { - Logger.getGlobal().log(Level.INFO, "Debugging linear for " + this.test + " " + localStart + " : " + localEnd); - - if ((failingConfiguration = this.failsWithConfig(config, localStart, localEnd - 1)) != null) { - localEnd = localEnd - 1; - continue; - } else if ((failingConfiguration = this.failsWithConfig(config, localStart + 1, localEnd)) != null) { - localStart = localStart + 1; - continue; - } else { - Logger.getGlobal().log(Level.FINE, "Refining did not work. Does not fail with linear."); - break; + while (pairs.size() > 0) { + Pair, Configuration> pair = pairs.remove(0); + Pair range = pair.getLeft(); + failingConfiguration = pair.getRight(); + long localStart = range.getLeft(); + long localEnd = range.getRight(); + + if (localStart < localEnd) { + Logger.getGlobal().log(Level.INFO, "Debugging linear for " + this.test + " " + + localStart + " : " + localEnd); + + boolean found = false; + if ((failingConfiguration = this.failsWithConfig(config, localStart, localEnd - 1)) != null) { + pairs.add(Pair.of((Pair)Pair.of(localStart, localEnd - 1), failingConfiguration)); + found = true; + } + if ((failingConfiguration = this.failsWithConfig(config, localStart + 1, localEnd)) != null) { + pairs.add(Pair.of((Pair)Pair.of(localStart + 1, localEnd), failingConfiguration)); + found = true; + } + + if (!found) { + Logger.getGlobal().log(Level.FINE, "Refining did not work. Does not fail with linear on range " + + localStart + " : " + localEnd + "."); + } } } - return failingConfiguration; + return allFailingConfigurations; } private Configuration failsWithConfig(Configuration config, long start, long end) { From df9081bf6a01e5f40b754a6647fc66ae81a0c298 Mon Sep 17 00:00:00 2001 From: August Shi Date: Wed, 15 Jun 2016 00:41:31 -0500 Subject: [PATCH 3/3] Addressed warning from Codacy about characters appended to buffers --- .../src/main/java/edu/illinois/nondex/plugin/DebugTask.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nondex-maven-plugin/src/main/java/edu/illinois/nondex/plugin/DebugTask.java b/nondex-maven-plugin/src/main/java/edu/illinois/nondex/plugin/DebugTask.java index 62197446..3fb2c6b2 100644 --- a/nondex-maven-plugin/src/main/java/edu/illinois/nondex/plugin/DebugTask.java +++ b/nondex-maven-plugin/src/main/java/edu/illinois/nondex/plugin/DebugTask.java @@ -104,7 +104,7 @@ private String makeResultString(List debuggedOnes) { sb.append(config.seed); sb.append(" AT: "); sb.append(config.getDebugPath()); - sb.append("\n"); + sb.append('\n'); } return sb.toString(); }