changeset 913:ed4ae4bfd691 Hajipur-9.0.x

TW-39482 recover from abandoned transaction error in local mirror
author Dmitry Neverov <dmitry.neverov@gmail.com>
date Fri, 02 Jan 2015 12:24:21 +0100
parents 15fce0c26e18
children 66cc56a53d8a 6b5e83970a26
files mercurial-agent/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialIncludeRuleUpdater.java mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/HgRepo.java mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/RecoverCommand.java mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/AgentSideCheckoutWithSharedMirrorsTest.java
diffstat 4 files changed, 84 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial-agent/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialIncludeRuleUpdater.java	Tue Dec 16 20:45:00 2014 +0100
+++ b/mercurial-agent/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialIncludeRuleUpdater.java	Fri Jan 02 12:24:21 2015 +0100
@@ -21,6 +21,8 @@
 import jetbrains.buildServer.agent.vcs.IncludeRuleUpdater;
 import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.AuthSettings;
 import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.HgVcsRoot;
+import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.PullCommand;
+import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.exception.AbandonedTransactionFound;
 import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.exception.UnrelatedRepositoryException;
 import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.exception.WrongSubrepoUrlException;
 import jetbrains.buildServer.buildTriggers.vcs.mercurial.ext.BeforeWorkingDirUpdateExtension;
@@ -124,11 +126,17 @@
     if (mirrorRepo.containsRevision(revision)) {
       myLogger.message("Local mirror is already up-to-date");
     } else {
-      mirrorRepo.pull().fromRepository(repositoryUrl)
+      PullCommand pull = mirrorRepo.pull().fromRepository(repositoryUrl)
               .withTraceback(myUseTraceback)
               .withProfile(myProfile)
-              .withTimeout(myPullTimeout)
-              .call();
+              .withTimeout(myPullTimeout);
+      try {
+        pull.call();
+      } catch (AbandonedTransactionFound e) {
+        myLogger.message("Abandoned transaction found, trying to recover");
+        mirrorRepo.recover().call();
+        pull.call();
+      }
     }
   }
 
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/HgRepo.java	Tue Dec 16 20:45:00 2014 +0100
+++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/HgRepo.java	Fri Jan 02 12:24:21 2015 +0100
@@ -159,6 +159,10 @@
     return new AddRemoveCommand(myCommandSettingsFactory.create(), myHgPath, myWorkingDir);
   }
 
+  public RecoverCommand recover() {
+    return new RecoverCommand(myCommandSettingsFactory.create(), myHgPath, myWorkingDir);
+  }
+
   public String path() {
     return myWorkingDir.getAbsolutePath();
   }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/RecoverCommand.java	Fri Jan 02 12:24:21 2015 +0100
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2000-2015 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package jetbrains.buildServer.buildTriggers.vcs.mercurial.command;
+
+import jetbrains.buildServer.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+
+public class RecoverCommand extends BaseCommand {
+  public RecoverCommand(@NotNull CommandSettings commandSettings,
+                        @NotNull String hgPath,
+                        @NotNull File workingDir) {
+    super(commandSettings, hgPath, workingDir);
+  }
+
+  public void call() throws VcsException {
+    MercurialCommandLine cmd = createCommandLine();
+    cmd.addParameter("recover");
+    runCommand(cmd);
+  }
+
+  @NotNull
+  @Override
+  protected String getDescription() {
+    return "hg recover";
+  }
+}
--- a/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/AgentSideCheckoutWithSharedMirrorsTest.java	Tue Dec 16 20:45:00 2014 +0100
+++ b/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/AgentSideCheckoutWithSharedMirrorsTest.java	Fri Jan 02 12:24:21 2015 +0100
@@ -20,12 +20,10 @@
 import jetbrains.buildServer.agent.BuildAgentConfiguration;
 import jetbrains.buildServer.agent.BuildProgressLogger;
 import jetbrains.buildServer.agent.FlowLogger;
-import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.CommandSettingsForRootImpl;
-import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.CommandlineViaFileWrapperWeaver;
-import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.ExtensionsWeaver;
-import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.TestCommandSettingsFactory;
+import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.*;
 import jetbrains.buildServer.buildTriggers.vcs.mercurial.ext.MercurialExtensionManager;
 import jetbrains.buildServer.util.FileUtil;
+import jetbrains.buildServer.util.TestFor;
 import jetbrains.buildServer.vcs.CheckoutRules;
 import jetbrains.buildServer.vcs.IncludeRule;
 import jetbrains.buildServer.vcs.VcsException;
@@ -47,6 +45,7 @@
 @Test
 public class AgentSideCheckoutWithSharedMirrorsTest extends BaseMercurialPatchTestCase {
 
+  private MirrorManager myMirrorManager;
   private File myOriginalRepositoriesParentDir;
   private MercurialAgentSideVcsSupport myVcsSupport;
   private File myWorkDir;
@@ -73,8 +72,9 @@
     }});
 
     final AgentPluginConfigImpl pluginConfig = new AgentPluginConfigImpl(agentConfig);
+    myMirrorManager = new MirrorManagerImpl(pluginConfig);
     myVcsSupport = new MercurialAgentSideVcsSupport(pluginConfig,
-            new MirrorManagerImpl(pluginConfig),
+            myMirrorManager,
             new AgentRepoFactory(pluginConfig, new CommandSettingsForRootImpl(new TestCommandSettingsFactory(), new ExtensionsWeaver(),
                     new CommandlineViaFileWrapperWeaver()), new AgentHgPathProvider(agentConfig)),
             new MercurialExtensionManager());
@@ -133,6 +133,28 @@
   }
 
 
+  @TestFor(issues = "TW-39482")
+  public void should_recover_from_abandoned_transaction() throws Exception {
+    File remoteRepo = myTempFiles.createTempDir();
+    Util.copyRepository(new File("mercurial-tests/testData/bookmarks/1"), remoteRepo);
+    VcsRootImpl root = vcsRoot().withUrl(remoteRepo).build();
+
+    //checkout sources, so that shared mirror is created
+    update(root, "5:e052c89b1159");
+
+    //make next pull fail
+    File mirror = myMirrorManager.getMirrorDir(new HgVcsRoot(root).getRepository());
+    FileUtil.writeFile(new File(new File(new File(mirror, ".hg"), "store"), "journal"), "", "UTF-8");
+
+    //update remote repo so that next build requires pull
+    FileUtil.delete(remoteRepo);
+    Util.copyRepository(new File("mercurial-tests/testData/bookmarks/2"), remoteRepo);
+
+    //run build which require pull
+    update(root, "6:7597a4da7195");
+  }
+
+
   @NotNull
   private File[] listFiles(@NotNull File dir) {
     File[] files = dir.listFiles();