view mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/AgentSideCheckoutWithSubreposTest.java @ 976:7bf4d943d5bb

Update copyright
author pavel.sher
date Mon, 22 Jan 2018 11:39:20 +0100
parents c28e68e22272
children 10dc26b32c35
line wrap: on
line source
/*
 * Copyright 2000-2018 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.agent.AgentRunningBuild;
import jetbrains.buildServer.agent.BuildAgentConfiguration;
import jetbrains.buildServer.agent.BuildProgressLogger;
import jetbrains.buildServer.agent.FlowLogger;
import jetbrains.buildServer.agent.vcs.UpdateByIncludeRules2;
import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.*;
import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.exception.ConnectionRefusedException;
import jetbrains.buildServer.buildTriggers.vcs.mercurial.ext.MercurialExtensionManager;
import jetbrains.buildServer.util.FileUtil;
import jetbrains.buildServer.vcs.CheckoutRules;
import jetbrains.buildServer.vcs.IncludeRule;
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.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import static java.util.Arrays.asList;
import static jetbrains.buildServer.buildTriggers.vcs.mercurial.Util.getHgPath;
import static jetbrains.buildServer.buildTriggers.vcs.mercurial.VcsRootBuilder.vcsRoot;
import static junit.framework.Assert.assertTrue;
import static junit.framework.Assert.fail;

/**
 * @author dmitry.neverov
 */
@Test
public class AgentSideCheckoutWithSubreposTest extends BaseMercurialTestCase {

  private File myOriginalRepositoriesParentDir;
  private File myWorkDir;
  private Mockery myContext;
  private BuildProgressLogger myLogger;
  private UpdateByIncludeRules2 myVcsSupport;
  private int myBuildCounter = 0;
  private List<Process> myProcesses;
  private File myDefaultWorkDir;
  private MirrorManagerImpl myMirrorManager;

  @BeforeMethod
  public void setUp() throws Exception {
    super.setUp();
    myProcesses = new ArrayList<Process>();
    myOriginalRepositoriesParentDir = myTempFiles.createTempDir();
    myDefaultWorkDir = new File(myOriginalRepositoriesParentDir, "agentWorkDir");
    myWorkDir = myDefaultWorkDir;
    myContext = new Mockery();

    final BuildAgentConfiguration agentConfig = myContext.mock(BuildAgentConfiguration.class);
    myContext.checking(new Expectations() {{
      allowing(agentConfig).getCacheDirectory("mercurial"); will(returnValue(myTempFiles.createTempDir()));
      allowing(agentConfig).getParametersResolver(); will(returnValue(new HgPathResolver()));
    }});

    final AgentPluginConfigImpl pluginConfig = new AgentPluginConfigImpl(agentConfig);
    myMirrorManager = new MirrorManagerImpl(pluginConfig);
    myVcsSupport = new MercurialAgentSideVcsSupport(pluginConfig,
            myMirrorManager,
            new AgentRepoFactory(pluginConfig, new CommandSettingsForRootImpl(new TestCommandSettingsFactory(), new ExtensionsWeaver(), new CommandlineViaFileWrapperWeaver()),
                    new AgentHgPathProvider(agentConfig)),
            new MercurialExtensionManager());

    myLogger = myContext.mock(FlowLogger.class);
    myContext.checking(new Expectations() {{
      allowing(myLogger).message(with(any(String.class)));
      allowing(myLogger).warning(with(any(String.class)));
      allowing(myLogger).activityStarted(with(any(String.class)), with(any(String.class)));
      allowing(myLogger).activityFinished(with(any(String.class)), with(any(String.class)));
      allowing(myLogger).getFlowLogger(with(any(String.class))); will(returnValue(myLogger));
    }});
  }

  @AfterMethod
  public void tearDown() {
    super.tearDown();
    for (Process p : myProcesses) {
      p.destroy();
    }
  }


  public void subrepository_url_changed() throws Exception {
    File myR1Dir = copy(new File("mercurial-tests/testData/subrepos/r1"));
    copy(new File("mercurial-tests/testData/subrepos/r2"));
    copy(new File("mercurial-tests/testData/subrepos/r3"));
    VcsRootImpl root = vcsRoot().withUrl(myR1Dir.getAbsolutePath()).build();
    doUpdate(root, "34017377d9c3", true);
    doUpdate(root, "d350e7209906", true);
  }


  private void should_support_local_mirrors_for_subrepos() throws Exception {
    File r1 = copy(new File("mercurial-tests/testData/subrepos/http_r1"));
    File r2 = copy(new File("mercurial-tests/testData/subrepos/http_r2"));
    File r3 = copy(new File("mercurial-tests/testData/subrepos/http_r3"));
    Process server1 = serve(r1, 8001);
    Process server2 = serve(r2, 8002);
    Process server3 = serve(r3, 8003);
    myProcesses.addAll(asList(server1, server2, server3));

    final String url1 = "http://localhost:8001";
    final String url2 = "http://localhost:8002";
    final String url3 = "http://localhost:8003";
    VcsRoot root1 = vcsRoot().withUrl(url1).build();
    VcsRoot root3 = vcsRoot().withUrl(url3).build();

    myWorkDir = new File(myDefaultWorkDir, "1");
    doUpdate(root1, "3d6694af00e4", true);
    server1.destroy();

    HgRepo mirror1 = new HgRepo(new AgentCommandSettingsFactory(), myMirrorManager.getMirrorDir(url1), getHgPath(), new AuthSettings());
    assertTrue("R1 mirror not updated to the latest revision", mirror1.containsRevision("3d6694af00e4"));

    try {
      myWorkDir = new File(myDefaultWorkDir, "3");
      doUpdate(root3, "e1dc5eeb1bec", true);
      doUpdate(root3, "999fb1eb9735", true);
    } catch (ConnectionRefusedException e) {
      fail("Contact remote repository when up-to-date subrepo local mirror exists");
    }

    HgRepo mirror2 = new HgRepo(new AgentCommandSettingsFactory(), myMirrorManager.getMirrorDir(url2), getHgPath(), new AuthSettings());
    assertTrue("R2 mirror not updated to the latest revision", mirror2.containsRevision("7de2f844e1a2"));
  }

  private Process serve(@NotNull File repo, int port) throws IOException {
    return new ProcessBuilder(getHgPath(), "serve", "-a", "localhost", "-p", String.valueOf(port)).directory(repo).start();
  }


  private void doUpdate(final VcsRoot vcsRoot, final String toVersion) throws VcsException {
    doUpdate(vcsRoot, toVersion, false);
  }

  private void doUpdate(final VcsRoot vcsRoot, final String toVersion, final boolean useLocalMirrors) throws VcsException {
    final AgentRunningBuild build = myContext.mock(AgentRunningBuild.class, "build" + myBuildCounter++);
    myContext.checking(new Expectations() {{
      allowing(build).getBuildLogger(); will(returnValue(myLogger));
      allowing(build).getSharedConfigParameters(); will(returnValue(new HashMap<String, String>() {{
        put("teamcity.hg.use.local.mirrors", useLocalMirrors ? "true" : "false");
      }}));
    }});
    myVcsSupport.getUpdater(vcsRoot, CheckoutRules.DEFAULT, toVersion, myWorkDir, build, false).process(IncludeRule.createDefaultInstance(), myWorkDir);
  }


  private File copy(@NotNull File originalRepositoryDir) throws IOException {
    String dirName = originalRepositoryDir.getName();
    File copyDir = new File(myOriginalRepositoriesParentDir, dirName);
    FileUtil.copyDir(originalRepositoryDir, copyDir);
    if (new File(copyDir, "hg").isDirectory()) {
      FileUtil.rename(new File(copyDir, "hg"), new File(copyDir, ".hg"));
    }
    return copyDir;
  }


}