Mercurial > hg > mercurial
view mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/SubrepoChangesTest.java @ 771:06dcc79b304d
use API only
author | eugene.petrenko@jetbrains.com |
---|---|
date | Tue, 25 Feb 2014 12:36:10 +0100 |
parents | 5abd4de360e8 |
children | ce67edf7bae9 |
line wrap: on
line source
/* * Copyright 2000-2014 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.*; import jetbrains.buildServer.vcs.*; import org.jetbrains.annotations.NotNull; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import java.io.File; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; import static jetbrains.buildServer.buildTriggers.vcs.mercurial.MercurialSupportBuilder.mercurialSupport; import static jetbrains.buildServer.buildTriggers.vcs.mercurial.ModificationDataMatcher.modificationData; import static jetbrains.buildServer.buildTriggers.vcs.mercurial.Util.copyRepository; import static jetbrains.buildServer.buildTriggers.vcs.mercurial.VcsRootBuilder.vcsRoot; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.*; import static org.testng.AssertJUnit.assertEquals; @RequiredHgVersion(min = "1.7.0") //support subrepos only for hg with revsets @Test(dataProviderClass = HgVersionConstraint.class, dataProvider = "installedHgVersion") public class SubrepoChangesTest extends BaseMercurialTestCase { private MercurialVcsSupport myVcs; private File myRemoteRepo1; private File myRemoteRepo2; private File myRemoteRepo3; private File myRepoNoSubs; private HgPathProvider myHgPathProvider; @BeforeMethod public void setUp() throws Exception { super.setUp(); ServerPluginConfig pluginConfig = new ServerPluginConfigBuilder() .cachesDir(myTempFiles.createTempDir()) .detectSubrepoChanges(true) .build(); File remoteRepoParentDir = myTempFiles.createTempDir(); myRemoteRepo1 = new File(remoteRepoParentDir, "r1"); myRemoteRepo2 = new File(remoteRepoParentDir, "r2"); myRemoteRepo3 = new File(remoteRepoParentDir, "r3"); myRepoNoSubs = new File(remoteRepoParentDir, "repo.no.subs"); copyRepository(new File("mercurial-tests/testData/subrepos/r1"), myRemoteRepo1); copyRepository(new File("mercurial-tests/testData/subrepos/r2"), myRemoteRepo2); copyRepository(new File("mercurial-tests/testData/subrepos/r3"), myRemoteRepo3); copyRepository(new File("mercurial-tests/testData/rep1"), myRepoNoSubs); MercurialSupportBuilder mercurialBuilder = mercurialSupport().withConfig(pluginConfig); myVcs = mercurialBuilder.build(); myHgPathProvider = mercurialBuilder.getHgPathProvider(); } public void should_report_changes_from_subrepos(@NotNull HgVersion _) throws Exception { VcsRoot root = vcsRoot().withUrl(myRemoteRepo1.getAbsolutePath()).withSubrepoChanges(true).build(); List<ModificationData> changes = myVcs.getCollectChangesPolicy().collectChanges(root, "d350e7209906", "09c256b6163e", CheckoutRules.DEFAULT); assertEquals(4, changes.size()); } public void should_include_from_revisions_into_changes_from_subrepos(@NotNull HgVersion _) throws Exception { //otherwise TeamCity won't show changes from subrepos in UI VcsRoot root = vcsRoot().withUrl(myRemoteRepo1.getAbsolutePath()).withSubrepoChanges(true).build(); List<ModificationData> changes = myVcs.getCollectChangesPolicy().collectChanges(root, "d350e7209906", "09c256b6163e", CheckoutRules.DEFAULT); assertThat(changes, hasItem(modificationData().withVersion("9e4a2fef1a1c"))); } public void should_not_report_any_changes_when_subrepo_removed(@NotNull HgVersion _) throws Exception { VcsRoot root = vcsRoot().withUrl(myRemoteRepo1.getAbsolutePath()).withSubrepoChanges(true).build(); List<ModificationData> changes = myVcs.getCollectChangesPolicy().collectChanges(root, "34017377d9c3", "4d7b3db8779f", CheckoutRules.DEFAULT); assertEquals(1, changes.size()); } public void should_not_report_any_changes_when_subrepo_added(@NotNull HgVersion _) throws Exception { VcsRoot root = vcsRoot().withUrl(myRemoteRepo1.getAbsolutePath()).withSubrepoChanges(true).build(); List<ModificationData> changes = myVcs.getCollectChangesPolicy().collectChanges(root, "4d7b3db8779f", "d350e7209906", CheckoutRules.DEFAULT); assertEquals(1, changes.size()); } public void should_report_subrepo_changes_recursevly(@NotNull HgVersion _) throws Exception { VcsRoot root = vcsRoot().withUrl(myRemoteRepo1.getAbsolutePath()).withSubrepoChanges(true).build(); List<ModificationData> changes = myVcs.getCollectChangesPolicy().collectChanges(root, "09c256b6163e", "d64d9799c143", CheckoutRules.DEFAULT); assertEquals(7, changes.size()); assertThat(changes, hasItem(modificationData().withVersion("d64d9799c143").withVcsRootProperties(root.getProperties()))); Map<String, String> s1props = new HashMap<String, String>(root.getProperties()); s1props.put("teamcity.internal.subrepo.path", "r2"); s1props.put(Constants.REPOSITORY_PROP, myRemoteRepo3.getCanonicalPath()); s1props.put("teamcity.internal.subrepo", "true"); assertThat(changes, hasItem(modificationData().withVersion("514c3e09cddf").withVcsRootProperties(s1props))); assertThat(changes, hasItem(modificationData().withVersion("1f9eb39a3921").withVcsRootProperties(s1props))); Map<String, String> s2props = new HashMap<String, String>(root.getProperties()); s2props.put("teamcity.internal.subrepo.path", "r2/r2"); s2props.put(Constants.REPOSITORY_PROP, myRemoteRepo2.getCanonicalPath()); s2props.put("teamcity.internal.subrepo", "true"); assertThat(changes, hasItem(modificationData().withVersion("ac0003deae69").withVcsRootProperties(s2props))); assertThat(changes, hasItem(modificationData().withVersion("29053b4b29ce").withVcsRootProperties(s2props))); } public void report_subrepo_changes_without_revsets(@NotNull HgVersion _) throws Exception { ServerPluginConfig pluginConfig = new ServerPluginConfigBuilder() .cachesDir(myTempFiles.createTempDir()) .detectSubrepoChanges(true) .dontUseRevsets() .build(); myVcs = mercurialSupport().withConfig(pluginConfig).build(); VcsRoot root = vcsRoot().withUrl(myRemoteRepo1.getAbsolutePath()).withSubrepoChanges(true).build(); List<ModificationData> changes = myVcs.getCollectChangesPolicy().collectChanges(root, "d350e7209906", "09c256b6163e", CheckoutRules.DEFAULT); assertEquals(3, changes.size()); } public void report_subrepo_changes(@NotNull HgVersion _) throws Exception { ServerPluginConfig pluginConfig = new ServerPluginConfigBuilder() .cachesDir(myTempFiles.createTempDir()) .detectSubrepoChanges(true) .dontUseRevsets() .build(); myVcs = mercurialSupport().withConfig(pluginConfig).build(); VcsRoot root = vcsRoot().withUrl(myRemoteRepo1.getAbsolutePath()).withSubrepoChanges(true).build(); List<ModificationData> changes = myVcs.getCollectChangesPolicy().collectChanges(root, "09c256b6163e", "d64d9799c143", CheckoutRules.DEFAULT); assertEquals(5, changes.size()); assertThat(changes, hasItem(modificationData().withVersion("d64d9799c143").withVcsRootProperties(root.getProperties()))); Map<String, String> subrepoRootProperties = new HashMap<String, String>(root.getProperties()); subrepoRootProperties.put("teamcity.internal.subrepo.path", "r2"); subrepoRootProperties.put(Constants.REPOSITORY_PROP, myRemoteRepo3.getCanonicalPath()); subrepoRootProperties.put("teamcity.internal.subrepo", "true"); assertThat(changes, hasItem(modificationData().withVersion("514c3e09cddf").withVcsRootProperties(subrepoRootProperties))); assertThat(changes, hasItem(modificationData().withVersion("1f9eb39a3921").withVcsRootProperties(subrepoRootProperties))); } public void report_subrepo_revision_in_each_main_root_commit(@NotNull HgVersion _) throws Exception { ServerPluginConfig pluginConfig = new ServerPluginConfigBuilder() .cachesDir(myTempFiles.createTempDir()) .detectSubrepoChanges(true) .dontUseRevsets() .build(); myVcs = mercurialSupport().withConfig(pluginConfig).build(); VcsRoot root = vcsRoot().withUrl(myRemoteRepo1.getAbsolutePath()).withSubrepoChanges(true).build(); List<ModificationData> changes = myVcs.getCollectChangesPolicy().collectChanges(root, "e4eced2b7381", "d64d9799c143", CheckoutRules.DEFAULT); assertThat(changes.size(), is(11)); SubrepoRevisionAttributesBuilder builder = new SubrepoRevisionAttributesBuilder(); builder.addSubrepo(new SubrepoConfig(root) .setSubrepoRootParamDiff(Constants.REPOSITORY_PROP, myRemoteRepo2.getCanonicalPath()) .setSubrepoPath("r2") .setSubrepoRevision("916933c1dd8e")); assertThat(changes, hasItem(modificationData().withVersion("34017377d9c3").withAttributes(builder.buildAttributes()))); builder = new SubrepoRevisionAttributesBuilder(); builder.addSubrepo(new SubrepoConfig(root) .setSubrepoRootParamDiff(Constants.REPOSITORY_PROP, myRemoteRepo3.getCanonicalPath()) .setSubrepoPath("r2") .setSubrepoRevision("9e4a2fef1a1c")); assertThat(changes, hasItem(modificationData().withVersion("d350e7209906").withAttributes(builder.buildAttributes()))); builder = new SubrepoRevisionAttributesBuilder(); builder.addSubrepo(new SubrepoConfig(root) .setSubrepoRootParamDiff(Constants.REPOSITORY_PROP, myRemoteRepo3.getCanonicalPath()) .setSubrepoPath("r2") .setSubrepoRevision("ebb884b1b691")); assertThat(changes, hasItem(modificationData().withVersion("09c256b6163e").withAttributes(builder.buildAttributes()))); builder = new SubrepoRevisionAttributesBuilder(); builder.addSubrepo(new SubrepoConfig(root) .setSubrepoRootParamDiff(Constants.REPOSITORY_PROP, myRemoteRepo3.getCanonicalPath()) .setSubrepoPath("r2") .setSubrepoRevision("514c3e09cddf")); assertThat(changes, hasItem(modificationData().withVersion("d64d9799c143").withAttributes(builder.buildAttributes()))); builder = new SubrepoRevisionAttributesBuilder(); builder.addSubrepo(new SubrepoConfig(root) .setSubrepoRootParamDiff(Constants.REPOSITORY_PROP, myRemoteRepo2.getCanonicalPath()) .setSubrepoPath("r2/r2") .setSubrepoRevision("916933c1dd8e")); assertThat(changes, hasItem(modificationData().withVersion("1f9eb39a3921").withAttributes(builder.buildAttributes()))); builder = new SubrepoRevisionAttributesBuilder(); builder.addSubrepo(new SubrepoConfig(root) .setSubrepoRootParamDiff(Constants.REPOSITORY_PROP, myRemoteRepo2.getCanonicalPath()) .setSubrepoPath("r2/r2") .setSubrepoRevision("ac0003deae69")); assertThat(changes, hasItem(modificationData().withVersion("514c3e09cddf").withAttributes(builder.buildAttributes()))); } public void should_retrieve_subrepo_config_only_when_necessary(@NotNull HgVersion _) throws Exception { //Every commit from a main repository has a table of subrepo revisions. //To build this table we call hg cat .hgsub .hgsubstate. -r <main root revision> //When main repository has a lot of new changes (thousands) calling 'hg cat' //for each main root revision becomes a bottleneck. We should call hg cat only //if a main root change has .hgsub/.hgsubstate among its changed files, //and reuse subrepo table from a parent commit if it doesn't. ServerPluginConfig pluginConfig = new ServerPluginConfigBuilder() .cachesDir(myTempFiles.createTempDir()) .detectSubrepoChanges(true) .dontUseRevsets() .build(); final AtomicInteger catCallCounter = new AtomicInteger(0); RepoFactory repoFactory = new RepoFactory(pluginConfig, new TestCommandSettingsFactory(), myHgPathProvider) { @NotNull @Override protected ServerHgRepo create(@NotNull File workingDir, @NotNull String hgPath, @NotNull AuthSettings authSettings, @NotNull CommandSettingsFactory commandSettingsFactory, @NotNull ServerPluginConfig config) { return new CountingServerHgRepo(commandSettingsFactory, config, workingDir, hgPath, authSettings, catCallCounter); } }; myVcs = mercurialSupport().withConfig(pluginConfig).withRepoFactory(repoFactory).build(); VcsRoot root = vcsRoot().withUrl(myRepoNoSubs.getAbsolutePath()).withSubrepoChanges(true).build(); myVcs.getCollectChangesPolicy().collectChanges(root, "1d446e82d356", "e6935c9c80bf", CheckoutRules.DEFAULT); //this root contains no subrepos, we should call getSubrepos just once and then reuse this info assertEquals(1, catCallCounter.intValue()); } protected static class CountingServerHgRepo extends ServerHgRepo { private final AtomicInteger myCatCallCounter; public CountingServerHgRepo(@NotNull CommandSettingsFactory commandSettingsFactory, @NotNull ServerPluginConfig config, @NotNull File workingDir, @NotNull String hgPath, @NotNull AuthSettings authSettings, @NotNull AtomicInteger catCallCounter) { super(commandSettingsFactory, config, workingDir, hgPath, authSettings); myCatCallCounter = catCallCounter; } @Override public CatCommand cat() { myCatCallCounter.incrementAndGet(); return super.cat(); } } }