changeset 956:1ba5cc4c9ca4 Hajipur-9.1.x

TW-46340 compute from revisions more correctly Endpoints should contain minimal set of uniteresting revisions. Now we don't add endpoint if it is already filtered out by another endpoint.
author Dmitry Neverov <dmitry.neverov@gmail.com>
date Fri, 22 Jul 2016 12:26:37 +0200
parents 31ac1d822fd7
children a0bb066bda0e
files mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/CollectChangesContext.java mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/CollectChangesContextTest.java mercurial-tests/src/testng.xml mercurial-tests/testData/manyFromRevisions/hg/00changelog.i mercurial-tests/testData/manyFromRevisions/hg/branch mercurial-tests/testData/manyFromRevisions/hg/branchheads.cache mercurial-tests/testData/manyFromRevisions/hg/cache/branch2-base mercurial-tests/testData/manyFromRevisions/hg/cache/rbc-names-v1 mercurial-tests/testData/manyFromRevisions/hg/cache/rbc-revs-v1 mercurial-tests/testData/manyFromRevisions/hg/cache/tags2-visible mercurial-tests/testData/manyFromRevisions/hg/dirstate mercurial-tests/testData/manyFromRevisions/hg/hgrc mercurial-tests/testData/manyFromRevisions/hg/requires mercurial-tests/testData/manyFromRevisions/hg/store/00changelog.i mercurial-tests/testData/manyFromRevisions/hg/store/00manifest.i mercurial-tests/testData/manyFromRevisions/hg/store/data/a.i mercurial-tests/testData/manyFromRevisions/hg/store/fncache mercurial-tests/testData/manyFromRevisions/hg/tags.cache
diffstat 18 files changed, 132 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/CollectChangesContext.java	Fri Jul 22 10:43:41 2016 +0200
+++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/CollectChangesContext.java	Fri Jul 22 12:26:37 2016 +0200
@@ -256,8 +256,10 @@
   private final static class FindIntervalVisitor extends BFSVisitorAdapter<String> {
 
     private final DAG<String> myDag;
-    private final Collection<String> myUninterestingRevisions;
-    private final Set<String> myVisitedUninterestingRevisions = new HashSet<String>();
+    private final Collection<String> myUninterestingRevisions;//from state revisions
+    private final Set<String> myAllUninteresting = new HashSet<String>();//myUninterestingRevisions + all revisions reachable from them
+    private boolean myUninterestingInitialized = false;//become true when myAllUninteresting is computed
+    private final Set<String> myCoveredUninteresting = new HashSet<String>();//all revisions reachable from computed endpoints
     private final Set<String> myEndpoints = new HashSet<String>();
 
     private FindIntervalVisitor(@NotNull DAG<String> dag, @NotNull Collection<String> uninteresting) {
@@ -269,23 +271,27 @@
     public boolean discover(@NotNull String revision) {
       markUninteresting();
       if (!isInteresting(revision)) {
-        addEndpoint(revision);
+        if (!myCoveredUninteresting.contains(revision)) {
+          addEndpoint(revision);
+          myDag.breadthFirstSearch(revision, new MarkUninterestingRevisions(myCoveredUninteresting));
+        }
         return false;
       }
       return true;
     }
 
     private void markUninteresting() {
-      if (!myVisitedUninterestingRevisions.isEmpty())
+      if (myUninterestingInitialized)
         return;
       for (String rev : myUninterestingRevisions) {
         if (myDag.containsNode(rev))
-          myDag.breadthFirstSearch(rev, new MarkUninterestingRevisions());
+          myDag.breadthFirstSearch(rev, new MarkUninterestingRevisions(myAllUninteresting));
       }
+      myUninterestingInitialized = true;
     }
 
     private boolean isInteresting(@NotNull String revision) {
-      return !myVisitedUninterestingRevisions.contains(revision);
+      return !myAllUninteresting.contains(revision);
     }
 
     private void addEndpoint(@NotNull String revision) {
@@ -298,11 +304,17 @@
     }
 
     private class MarkUninterestingRevisions extends BFSVisitorAdapter<String> {
+      private final Set<String> myAccumulator;
+
+      public MarkUninterestingRevisions(@NotNull Set<String> accumulator) {
+        myAccumulator = accumulator;
+      }
+
       @Override
       public boolean discover(@NotNull String node) {
-        if (myVisitedUninterestingRevisions.contains(node))
+        if (myAccumulator.contains(node))
           return false;
-        myVisitedUninterestingRevisions.add(node);
+        myAccumulator.add(node);
         return true;
       }
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/CollectChangesContextTest.java	Fri Jul 22 12:26:37 2016 +0200
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2000-2016 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;
+
+import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.HgVcsRoot;
+import jetbrains.buildServer.util.TestFor;
+import jetbrains.buildServer.vcs.RepositoryStateData;
+import jetbrains.buildServer.vcs.impl.VcsRootImpl;
+import org.jetbrains.annotations.NotNull;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import java.io.File;
+import java.util.Collection;
+
+import static jetbrains.buildServer.buildTriggers.vcs.mercurial.MercurialSupportBuilder.mercurialSupport;
+import static jetbrains.buildServer.buildTriggers.vcs.mercurial.ServerPluginConfigBuilder.serverPluginConfig;
+import static jetbrains.buildServer.buildTriggers.vcs.mercurial.VcsRootBuilder.vcsRoot;
+import static jetbrains.buildServer.util.Util.map;
+import static junit.framework.Assert.assertTrue;
+
+
+@RequiredHgVersion(min = "1.7.0")
+@Test(dataProviderClass = HgVersionConstraint.class, dataProvider = "installedHgVersion")
+public class CollectChangesContextTest extends BaseMercurialTestCase {
+
+  private ServerPluginConfig myConfig;
+  private MercurialVcsSupport myVcs;
+  private MercurialSupportBuilder myVcsBuilder;
+
+  @BeforeMethod
+  public void setUp() throws Exception {
+    super.setUp();
+    myConfig = serverPluginConfig()
+            .cachesDir(myTempFiles.createTempDir())
+            .hgPath(Util.getHgPath())
+            .build();
+    myVcsBuilder = mercurialSupport().withConfig(myConfig);
+    myVcs = myVcsBuilder.build();
+  }
+
+
+  @TestFor(issues = "TW-46340")
+  public void test_many_from_revisions(@NotNull HgVersion _) throws Exception {
+    //default
+    // | branch1
+    // V  |
+    //    V
+    //   100
+    //  /|
+    //99 |
+    // | |
+    //..... total 100 merges from default into branch1 like this
+    // | 5
+    // |/|
+    // 4 |
+    // | 3
+    // |/|
+    // 2 |
+    // |/
+    // 1
+    // |
+    // 0
+    //
+    // we collect changes from {default:99} to {default:99, branch1: 100}
+    // when we compute from revisions for branch1 99 is enough (it will filter out all commits in the default branch)
+    File remoteRepository = myTempFiles.createTempDir();
+    Util.copyRepository(new File("mercurial-tests/testData/manyFromRevisions"), remoteRepository);
+    VcsRootImpl root = vcsRoot().withUrl(remoteRepository.getAbsolutePath()).build();
+    HgVcsRoot hgRoot = myVcsBuilder.getHgRootFactory().createHgRoot(root);
+
+    RepositoryStateData fromState = RepositoryStateData.createVersionState("default", map("default", "d847416dd2eb"));
+    RepositoryStateData toState = RepositoryStateData.createVersionState("default", map("default", "d847416dd2eb", "branch1", "8c990164b769"));
+    CollectChangesContext context = new CollectChangesContext(myConfig, myVcs, myVcsBuilder.getHgRepoFactory(), MercurialProgress.NO_OP, fromState);
+    Collection<String> fromRevisions = context.getFromRevisionsForBranch(hgRoot, "d847416dd2eb", "8c990164b769", toState);
+    assertTrue(fromRevisions.size() == 1);
+    assertTrue(fromRevisions.contains("d847416dd2eb"));
+  }
+
+}
--- a/mercurial-tests/src/testng.xml	Fri Jul 22 10:43:41 2016 +0200
+++ b/mercurial-tests/src/testng.xml	Fri Jul 22 12:26:37 2016 +0200
@@ -57,6 +57,7 @@
       <class name="jetbrains.buildServer.buildTriggers.vcs.mercurial.command.CommitsAndMountPointsCommandParserTest"/>
       <class name="jetbrains.buildServer.buildTriggers.vcs.mercurial.PurgeTest"/>
       <class name="jetbrains.buildServer.buildTriggers.vcs.mercurial.MercurialCommitSupportTest"/>
+      <class name="jetbrains.buildServer.buildTriggers.vcs.mercurial.CollectChangesContextTest"/>
     </classes>
   </test>
 </suite>
Binary file mercurial-tests/testData/manyFromRevisions/hg/00changelog.i has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial-tests/testData/manyFromRevisions/hg/branch	Fri Jul 22 12:26:37 2016 +0200
@@ -0,0 +1,1 @@
+default
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial-tests/testData/manyFromRevisions/hg/branchheads.cache	Fri Jul 22 12:26:37 2016 +0200
@@ -0,0 +1,3 @@
+8c990164b769e02a7b0536b7c6a3b0073620cd8f 200
+d847416dd2eb6f5cdce1f7c85075c07f4595f589 default
+8c990164b769e02a7b0536b7c6a3b0073620cd8f branch1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial-tests/testData/manyFromRevisions/hg/cache/branch2-base	Fri Jul 22 12:26:37 2016 +0200
@@ -0,0 +1,3 @@
+8c990164b769e02a7b0536b7c6a3b0073620cd8f 200
+8c990164b769e02a7b0536b7c6a3b0073620cd8f o branch1
+d847416dd2eb6f5cdce1f7c85075c07f4595f589 o default
Binary file mercurial-tests/testData/manyFromRevisions/hg/cache/rbc-names-v1 has changed
Binary file mercurial-tests/testData/manyFromRevisions/hg/cache/rbc-revs-v1 has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial-tests/testData/manyFromRevisions/hg/cache/tags2-visible	Fri Jul 22 12:26:37 2016 +0200
@@ -0,0 +1,1 @@
+200 8c990164b769e02a7b0536b7c6a3b0073620cd8f
Binary file mercurial-tests/testData/manyFromRevisions/hg/dirstate has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial-tests/testData/manyFromRevisions/hg/hgrc	Fri Jul 22 12:26:37 2016 +0200
@@ -0,0 +1,2 @@
+[paths]
+default = /Users/nd/p/test/fromRevisionsTest
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial-tests/testData/manyFromRevisions/hg/requires	Fri Jul 22 12:26:37 2016 +0200
@@ -0,0 +1,4 @@
+dotencode
+fncache
+revlogv1
+store
Binary file mercurial-tests/testData/manyFromRevisions/hg/store/00changelog.i has changed
Binary file mercurial-tests/testData/manyFromRevisions/hg/store/00manifest.i has changed
Binary file mercurial-tests/testData/manyFromRevisions/hg/store/data/a.i has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial-tests/testData/manyFromRevisions/hg/store/fncache	Fri Jul 22 12:26:37 2016 +0200
@@ -0,0 +1,1 @@
+data/a.i
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial-tests/testData/manyFromRevisions/hg/tags.cache	Fri Jul 22 12:26:37 2016 +0200
@@ -0,0 +1,2 @@
+200 8c990164b769e02a7b0536b7c6a3b0073620cd8f
+