changeset 387:88480a85f888

Some exit codes mean errors
author Dmitry Neverov <dmitry.neverov@jetbrains.com>
date Thu, 16 Feb 2012 20:14:30 +0400
parents 62f273711a49 (current diff) 00d13c910f5d (diff)
children 7db31e2b1f90 85cc92fb5dfa
files mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CommandResult.java mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CommandResultTest.java
diffstat 2 files changed, 40 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CommandResult.java	Wed Feb 15 18:18:11 2012 +0400
+++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CommandResult.java	Thu Feb 16 20:14:30 2012 +0400
@@ -8,9 +8,11 @@
 import org.jetbrains.annotations.Nullable;
 
 import java.util.Collections;
+import java.util.HashSet;
 import java.util.Set;
 
 import static com.intellij.openapi.util.text.StringUtil.isEmpty;
+import static java.util.Arrays.asList;
 import static jetbrains.buildServer.buildTriggers.vcs.mercurial.command.CommandUtil.removePrivateData;
 
 /**
@@ -20,6 +22,14 @@
  */
 public class CommandResult {
 
+  //Mercurial returns -1 in the case of errors (see dispatch.py)
+  //and on some shells (e.g. windows cmd) it is truncated to 255.
+  //A non-zero exit code is not always an error:
+  //http://mercurial.selenic.com/bts/issue186
+  //http://mercurial.selenic.com/bts/issue2189
+  //e.g. pull command in hg 2.1 exits with 1 if no new changes were pulled.
+  private static final Set<Integer> ERROR_EXIT_CODES = setOf(-1, 255);
+
   private final Logger myLogger;
   private final String myCommand;
   private final ExecResult myDelegate;
@@ -82,11 +92,12 @@
   }
 
   private boolean isFailure() {
-    //A non-zero exit code is not an error:
-    //http://mercurial.selenic.com/bts/issue186
-    //http://mercurial.selenic.com/bts/issue2189
-    //E.g. pull command in hg 2.1 exits with 1 if no new changes were pulled
-    return getException() != null;
+    return getException() != null || isErrorExitCode();
+  }
+
+  private boolean isErrorExitCode() {
+    int exitCode = myDelegate.getExitCode();
+    return ERROR_EXIT_CODES.contains(exitCode);
   }
 
   private boolean shouldDetectErrors() {
@@ -161,4 +172,8 @@
       }
     }
   }
+
+  private static Set<Integer> setOf(Integer... ints) {
+    return new HashSet<Integer>(asList(ints));
+  }
 }
--- a/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CommandResultTest.java	Wed Feb 15 18:18:11 2012 +0400
+++ b/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CommandResultTest.java	Thu Feb 16 20:14:30 2012 +0400
@@ -8,6 +8,7 @@
 import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
 import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
 
 import java.io.ByteArrayInputStream;
@@ -38,6 +39,25 @@
     myLogger.assertLogMessagesDontContain(password);
   }
 
+  @DataProvider(name = "exitCodesForErrors")
+  public static Object[][] exitCodesForErrors() {
+    return new Object[][] {
+            new Object[] { -1 },
+            new Object[] { 255}};
+  }
+
+  @Test(expectedExceptions = VcsException.class,
+        dataProvider = "exitCodesForErrors")
+  public void should_detect_error_for_exit_code(int exitCode) throws VcsException {
+    CommandResult commandResult = commandResultFor(execResult().withExitCode(exitCode));
+    commandResult.checkCommandFailed();
+  }
+
+  public void exit_code_of_one_is_not_an_error() throws VcsException {
+    CommandResult commandResult = commandResultFor(execResult().withStdout("pull: no new changes").withExitCode(1));
+    commandResult.checkCommandFailed();
+  }
+
   @Test(expectedExceptions = UnrelatedRepositoryException.class)
   public void should_detect_unrelated_repository_error() throws VcsException {
     String unrelatedRepositoryStderr = "abort: repository is unrelated\n";
@@ -64,11 +84,6 @@
     commandResult.checkCommandFailed();
   }
 
-  public void should_detect_failure_with_non_zero_exit_code() throws VcsException {
-    CommandResult commandResult = commandResultFor(execResult().withExitCode(1));
-    commandResult.checkCommandFailed();
-  }
-
 
   ExecResultBuilder execResult() {
     return new ExecResultBuilder();