view mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/CleanupTest.java @ 579:da75e774d237

Clean mirrors on the server relying on last used time
author Dmitry Neverov <dmitry.neverov@jetbrains.com>
date Wed, 27 Mar 2013 21:49:46 +0400
parents 04eab204ba39
children 49a03af60439
line wrap: on
line source
package jetbrains.buildServer.buildTriggers.vcs.mercurial;

import jetbrains.buildServer.TempFiles;
import jetbrains.buildServer.util.FileUtil;
import org.hamcrest.Description;
import org.hamcrest.TypeSafeMatcher;
import org.jetbrains.annotations.NotNull;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import static java.util.Arrays.asList;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.testng.AssertJUnit.assertFalse;
import static org.testng.AssertJUnit.assertTrue;

/**
 * @author dmitry.neverov
 */
@Test
public class CleanupTest {

  private TempFiles myTempFiles;
  private File myCachesDir;
  private Cleanup myCleanup;
  private MirrorManager myMirrorManager;
  private long myMirrorExpirationTimeout = 2000L;

  @BeforeMethod
  public void setUp() throws Exception {
    myTempFiles = new TempFiles();
    myCachesDir = myTempFiles.createTempDir();

    ServerPluginConfig config = new ServerPluginConfigBuilder().cachesDir(myCachesDir).withMirrorExpirationTimeout(myMirrorExpirationTimeout).build();
    myMirrorManager = new MirrorManagerImpl(config);

    myCleanup = new Cleanup(myMirrorManager, config);
  }

  @AfterMethod
  public void tearDown() {
    myTempFiles.cleanup();
  }


  public void cleanup_should_remove_directories_by_timestamp() throws Exception {
    final String url1 = "http://some.org/repository1";
    final String url2 = "http://some.org/repository2";
    final String url3 = "http://some.org/repository3";
    File mirror1 = createDirFor(url1);
    File mirror2 = createDirFor(url2);
    File mirror3 = createDirFor(url3);

    updateTimestamp(mirror1, new Date().getTime());
    updateTimestamp(mirror2, new Date().getTime() - myMirrorExpirationTimeout);
    deleteTimestamp(mirror3);

    myCleanup.run();

    assertTrue(mirror1.exists());
    assertFalse(mirror2.exists());
    assertFalse(mirror3.exists());

    assertThat(myMirrorManager, knowsAboutAll(directoriesInside(myCachesDir)));
    assertThat(mappingsFile(), containsOnly(directoriesInside(myCachesDir)));
  }


  private void updateTimestamp(@NotNull File mirror, @NotNull long time) throws IOException {
    File dotHg = new File(mirror, ".hg");
    dotHg.mkdirs();
    File timestamp = new File(dotHg, "timestamp");
    timestamp.createNewFile();
    FileUtil.writeFileAndReportErrors(timestamp, String.valueOf(time));
  }


  private void deleteTimestamp(@NotNull File mirror) {
    FileUtil.delete(new File(new File(mirror, ".hg"), "timestamp"));
  }


  private File createDirFor(@NotNull String url) {
    return myMirrorManager.getMirrorDir(url);
  }


  private List<File> directoriesInside(@NotNull File dir) {
    return asList(dir.listFiles(new FileFilter() {
      public boolean accept(File f) {
        return f.isDirectory();
      }
    }));
  }

  private List<File> mappingsFile() throws IOException {
    File mappingFile = new File(myCachesDir, "map");
    List<File> files = new ArrayList<File>();
    for (String line : FileUtil.readFile(mappingFile)) {
      String[] fields = line.split("=");
      files.add(new File(mappingFile.getParentFile(), fields[1].trim()));
    }
    return files;
  }


  static MirrorManagerKnowsAboutDirectories knowsAboutAll(@NotNull List<File> dirs) {
    return new MirrorManagerKnowsAboutDirectories(dirs);
  }

  static class MirrorManagerKnowsAboutDirectories extends TypeSafeMatcher<MirrorManager> {
    private final List<File> myActualMirrorDirs;

    MirrorManagerKnowsAboutDirectories(@NotNull List<File> actualMirrorDirs) {
      myActualMirrorDirs = actualMirrorDirs;
    }

    @Override
    public boolean matchesSafely(MirrorManager mirrorManager) {
      List<File> knownMirrors = mirrorManager.getMirrors();
      return knownMirrors.size() == myActualMirrorDirs.size() && knownMirrors.containsAll(myActualMirrorDirs);
    }

    public void describeTo(Description description) {
      description.appendText("mirrorManager knows following directories: ");
      for (File dir : myActualMirrorDirs) {
        description.appendText(dir.getAbsolutePath()).appendText("\n");
      }
    }
  }


  private static <T> ContainsOnly<T> containsOnly(Collection<T> expected) {
    return new ContainsOnly<T>(expected);
  }

  static class ContainsOnly<T> extends TypeSafeMatcher<Collection<T>> {
    private final Collection<T> myExpected;

    ContainsOnly(@NotNull Collection<T> expected) {
      myExpected = expected;
    }

    @Override
    public boolean matchesSafely(Collection<T> col) {
      return col.size() == myExpected.size() && col.containsAll(myExpected);
    }

    public void describeTo(Description description) {
      description.appendText(myExpected.toString());
    }
  }
}