changeset 353:15c86ab0046c

TW-19703 add checks that repository and working dir are not locked
author Dmitry Neverov <dmitry.neverov@jetbrains.com>
date Wed, 18 Jan 2012 14:03:35 +0400
parents 1b3be513520e
children 5b3280c0fb2f
files mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/PullCommand.java mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/UpdateCommand.java mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/AgentSideCheckoutTest.java
diffstat 3 files changed, 72 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/PullCommand.java	Wed Jan 18 13:07:14 2012 +0400
+++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/PullCommand.java	Wed Jan 18 14:03:35 2012 +0400
@@ -21,6 +21,8 @@
 
 import java.io.File;
 
+import static com.intellij.openapi.util.io.FileUtil.delete;
+
 /**
  * @author Pavel.Sher
  *         Date: 14.07.2008
@@ -39,10 +41,22 @@
   }
 
   public void execute(int timeout) throws VcsException {
+    ensureRepositoryIsNotLocked();
     GeneralCommandLine cli = createCommandLine();
     cli.addParameter("pull");
     cli.addParameter(myPullUrl);
     CommandResult result = CommandUtil.runCommand(cli, timeout, getPrivateData(), false);
     CommandUtil.checkCommandFailed(result);
   }
+
+  private void ensureRepositoryIsNotLocked() {
+    File lock = getRepositoryLock();
+    if (lock.exists())
+      delete(lock);
+  }
+
+  @NotNull
+  private File getRepositoryLock() {
+    return new File(getWorkDirectory(), ".hg" + File.separator + "store" + File.separator + "lock");
+  }
 }
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/UpdateCommand.java	Wed Jan 18 13:07:14 2012 +0400
+++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/UpdateCommand.java	Wed Jan 18 14:03:35 2012 +0400
@@ -21,6 +21,8 @@
 
 import java.io.File;
 
+import static com.intellij.openapi.util.io.FileUtil.delete;
+
 public class UpdateCommand extends VcsRootCommand {
 
   private static final int UPDATE_TIMEOUT_SECONDS = 8 * 3600;//8 hours
@@ -36,6 +38,7 @@
   }
 
   public void execute() throws VcsException {
+    ensureWorkingDirIsNotLocked();
     GeneralCommandLine cli = createCommandLine();
     cli.addParameter("update");
     cli.addParameter("-C");
@@ -47,4 +50,15 @@
     }
     runCommand(cli, UPDATE_TIMEOUT_SECONDS);
   }
+
+  private void ensureWorkingDirIsNotLocked() {
+    File lock = getWorkingDirLock();
+    if (lock.exists())
+      delete(lock);
+  }
+
+  @NotNull
+  private File getWorkingDirLock() {
+    return new File(getWorkDirectory(), ".hg" + File.separator + "wlock");
+  }
 }
--- a/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/AgentSideCheckoutTest.java	Wed Jan 18 13:07:14 2012 +0400
+++ b/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/AgentSideCheckoutTest.java	Wed Jan 18 14:03:35 2012 +0400
@@ -24,6 +24,7 @@
 import jetbrains.buildServer.vcs.VcsException;
 import jetbrains.buildServer.vcs.VcsRoot;
 import jetbrains.buildServer.vcs.impl.VcsRootImpl;
+import org.jetbrains.annotations.NotNull;
 import org.jmock.Expectations;
 import org.jmock.Mockery;
 import org.testng.annotations.BeforeMethod;
@@ -34,6 +35,7 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.*;
 
 /**
  * @author Pavel.Sher
@@ -104,6 +106,24 @@
     checkDirectoriesAreEqual(new File(getTestDataPath(), expected), workDir);
   }
 
+  private File doUpdate(@NotNull final VcsRoot root, @NotNull final String version, int timeoutSeconds) throws Exception {
+    ExecutorService executor = Executors.newSingleThreadExecutor();
+    Future<File> future = executor.submit(new Callable<File>() {
+      public File call() throws Exception {
+        return doUpdate(root, version);
+      }
+    });
+    executor.shutdown();
+    executor.awaitTermination(timeoutSeconds, TimeUnit.SECONDS);
+    if (!future.isDone())
+      fail("Update failed due to timeout");
+    return future.get();
+  }
+
+  private File doUpdate(@NotNull VcsRoot root, @NotNull String version) throws VcsException {
+    return doUpdate(root, version, IncludeRule.createDefaultInstance());
+  }
+
   private File doUpdate(final VcsRoot vcsRoot, final String version, final IncludeRule includeRule) throws VcsException {
     return doUpdate(vcsRoot, version, includeRule, false);
   }
@@ -232,6 +252,30 @@
     assertTrue(hgrcContent.contains("default = " + root.getProperty(Constants.REPOSITORY_PROP)));
   }
 
+  //TW-19703
+  public void should_work_when_repository_is_locked() throws Exception{
+    VcsRootImpl root = new VcsRootBuilder()
+            .repository(LocalRepositoryUtil.prepareRepository(simpleRepo()).getAbsolutePath())
+            .hgPath(HG_PATH_REFERENCE).build();
+    File workingDir = doUpdate(root, "4:b06a290a363b");
+
+    lockRepository(workingDir);
+    doUpdate(root, "6:b9deb9a1c6f4", 10);
+
+    lockWorkingDir(workingDir);
+    doUpdate(root, "10:9c6a6b4aede0", 10);
+  }
+
+  private void lockRepository(@NotNull File workingDir) {
+    File lock = new File(workingDir, ".hg" + File.separator + "store" + File.separator + "lock");
+    FileUtil.writeFile(lock, "");
+  }
+
+  private void lockWorkingDir(@NotNull File workingDir) {
+    File lock = new File(workingDir, ".hg" + File.separator + "wlock");
+    FileUtil.writeFile(lock, "");
+  }
+
   protected String getTestDataPath() {
     return "mercurial-tests/testData";
   }