depot/third_party/copybara/javatests/com/google/copybara/hg/HgDestinationTest.java
Default email dfee7b6196 Project import generated by Copybara.
GitOrigin-RevId: b578e69f18a543889ded9c57a8f0dffacdb103d8
2020-05-15 16:19:19 -04:00

302 lines
12 KiB
Java

/*
* Copyright (C) 2018 Google Inc.
*
* 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 com.google.copybara.hg;
import static com.google.common.collect.Iterables.getOnlyElement;
import static com.google.common.truth.Truth.assertThat;
import static com.google.copybara.ChangeMessage.parseMessage;
import static com.google.copybara.testing.FileSubjects.assertThatPath;
import static org.junit.Assert.assertThrows;
import com.google.common.collect.ImmutableList;
import com.google.copybara.Destination.Writer;
import com.google.copybara.DestinationEffect;
import com.google.copybara.DestinationEffect.Type;
import com.google.copybara.TransformResult;
import com.google.copybara.WriterContext;
import com.google.copybara.authoring.Author;
import com.google.copybara.exception.RepoException;
import com.google.copybara.exception.ValidationException;
import com.google.copybara.hg.HgRepository.HgLogEntry;
import com.google.copybara.testing.DummyOrigin;
import com.google.copybara.testing.DummyRevision;
import com.google.copybara.testing.OptionsBuilder;
import com.google.copybara.testing.TransformResults;
import com.google.copybara.util.CommandRunner;
import com.google.copybara.util.Glob;
import com.google.copybara.util.console.testing.TestingConsole;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@RunWith(JUnit4.class)
public class HgDestinationTest {
private HgRepository remoteRepo;
private HgDestination destination;
private Glob destinationFiles;
private Path hgDestPath;
private Path workdir;
private TestingConsole console;
private OptionsBuilder options;
private String url;
private String fetch;
private String push;
private Writer<HgRevision> writer;
@Before
public void setup() throws Exception {
options = new OptionsBuilder()
.setHomeDir(Files.createTempDirectory("home").toString());
destinationFiles = Glob.ALL_FILES;
options.general.setFileSystemForTest(FileSystems.getDefault());
workdir = options.general.getDirFactory().newTempDir("workdir");
console = new TestingConsole();
hgDestPath = Files.createTempDirectory("HgDestinationTest-hgDestRepo");
url = "file://" + hgDestPath;
remoteRepo = new HgRepository(hgDestPath, /*verbose*/ false, CommandRunner.DEFAULT_TIMEOUT);
remoteRepo.init();
Files.write(hgDestPath.resolve("file.txt"), "first write".getBytes());
remoteRepo.hg(hgDestPath, "add");
remoteRepo.hg(hgDestPath, "commit", "-m", "first commit");
fetch = "tip";
push = "default";
destination = HgDestination.newHgDestination(url, fetch, push, options.general, options.hg);
writer = newWriter();
}
@Test
public void testWrite() throws Exception {
Files.write(workdir.resolve("file.txt"), "first write".getBytes());
Files.write(workdir.resolve("test.txt"), "test".getBytes());
ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(
Instant.ofEpochMilli(1496333940000L), ZoneId.of("-04:00"));
DummyRevision originRef = new DummyRevision("origin_ref")
.withAuthor(new Author("Copy Bara", "copy@bara.com"))
.withTimestamp(zonedDateTime);
TransformResult result = TransformResults.of(workdir, originRef);
ImmutableList<DestinationEffect> destinationResult =
writer.write(result, destinationFiles, console);
assertThat(destinationResult).hasSize(1);
assertThat(destinationResult.get(0).getErrors()).isEmpty();
assertThat(destinationResult.get(0).getType()).isEqualTo(Type.CREATED);
assertThat(destinationResult.get(0).getDestinationRef().getType()).isEqualTo("commit");
assertThat(destinationResult.get(0).getDestinationRef().getId()).matches("[0-9a-f]{40}");
ImmutableList<HgLogEntry> commits = remoteRepo.log().run();
assertThat(commits).hasSize(2);
assertThat(commits.get(0).getDescription()).isEqualTo(""
+ "test summary\n"
+ "\n"
+ "DummyOrigin-RevId: origin_ref");
assertThat(commits).hasSize(2);
assertThat(commits.get(0).getZonedDate()).isEqualTo(zonedDateTime);
assertThat(commits.get(0).getFiles()).hasSize(1);
assertThat(commits.get(0).getFiles().get(0)).isEqualTo("test.txt");
assertThat(commits.get(1).getFiles()).hasSize(1);
assertThat(commits.get(1).getFiles().get(0)).isEqualTo("file.txt");
}
@Test
public void testEmptyChange() throws Exception {
remoteRepo.archive(workdir.toString());
DummyRevision originRef = new DummyRevision("origin_ref");
TransformResult result = TransformResults.of(workdir, originRef);
RepoException expected =
assertThrows(RepoException.class, () -> writer.write(result, destinationFiles, console));
assertThat(expected.getMessage()).contains("Error executing hg");
}
@Test
public void testWriteDeletesAndAddsFiles() throws Exception {
Files.write(workdir.resolve("delete_me.txt"), "deleted content".getBytes());
DummyRevision deletedRef = new DummyRevision("delete_ref");
TransformResult result = TransformResults.of(workdir, deletedRef);
writer.write(result, destinationFiles, console);
workdir = options.general.getDirFactory().newTempDir("testWriteDeletesAndAddsFiles-workdir");
Files.write(workdir.resolve("add_me.txt"), "added content".getBytes());
createRevisionAndWrite("add_ref");
remoteRepo.cleanUpdate("tip");
ImmutableList<HgLogEntry> commits = remoteRepo.log().run();
assertThat(commits).hasSize(3);
assertThat(commits.get(0).getFiles()).hasSize(2);
assertThat(commits.get(0).getFiles().get(0)).isEqualTo("add_me.txt");
assertThat(commits.get(0).getFiles().get(1)).isEqualTo("delete_me.txt");
assertThat(commits.get(1).getFiles()).hasSize(2);
assertThat(commits.get(1).getFiles().get(0)).isEqualTo("delete_me.txt");
assertThat(commits.get(1).getFiles().get(1)).isEqualTo("file.txt");
assertThatPath(hgDestPath).containsFile("add_me.txt", "added content");
assertThatPath(hgDestPath).containsNoFiles("delete_me.txt");
assertThatPath(hgDestPath).containsNoFiles("file.txt");
}
@Test
public void testWriteModifyFiles() throws Exception {
Files.write(workdir.resolve("file.txt"), "modified content".getBytes());
createRevisionAndWrite("modified_ref");
remoteRepo.cleanUpdate("tip");
ImmutableList<HgLogEntry> commits = remoteRepo.log().run();
assertThat(commits).hasSize(2);
assertThatPath(hgDestPath).containsFile("file.txt", "modified content");
}
@Test
public void testWriteModifyExcluded() throws Exception {
destinationFiles = Glob.createGlob(ImmutableList.of("**"), ImmutableList.of("file.txt"));
writer = newWriter();
Files.write(workdir.resolve("file.txt"), "modified content".getBytes());
Files.write(workdir.resolve("other.txt"), "other content".getBytes());
createRevisionAndWrite("origin_ref");
remoteRepo.cleanUpdate("tip");
ImmutableList<HgLogEntry> commits = remoteRepo.log().run();
assertThat(commits).hasSize(2);
assertThatPath(hgDestPath).containsFile("file.txt", "first write");
assertThatPath(hgDestPath).containsFile("other.txt", "other content");
}
@Test
public void testWriteAddExcluded() throws Exception {
destinationFiles = Glob.createGlob(ImmutableList.of("**"), ImmutableList.of("excluded.txt"));
writer = newWriter();
Files.write(workdir.resolve("file.txt"), "modified content".getBytes());
Files.write(workdir.resolve("excluded.txt"), "excluded content".getBytes());
createRevisionAndWrite("origin_ref");
remoteRepo.cleanUpdate("tip");
ImmutableList<HgLogEntry> commits = remoteRepo.log().run();
assertThat(commits).hasSize(2);
assertThatPath(hgDestPath).containsFile("file.txt", "modified content");
// File that was excluded is still written because it didn't originally exist in the destination
assertThatPath(hgDestPath).containsFile("excluded.txt", "excluded content");
}
@Test
public void testWriteDeleteExcluded() throws Exception {
Files.write(hgDestPath.resolve("excluded.txt"), "content".getBytes(StandardCharsets.UTF_8));
destinationFiles = Glob.createGlob(ImmutableList.of("**"), ImmutableList.of("excluded.txt"));
writer = newWriter();
Files.write(workdir.resolve("file.txt"), "file".getBytes());
createRevisionAndWrite("origin_ref");
remoteRepo.cleanUpdate("tip");
ImmutableList<HgLogEntry> commits = remoteRepo.log().run();
assertThat(commits).hasSize(2);
assertThatPath(hgDestPath).containsFile("file.txt", "file");
assertThatPath(hgDestPath).containsFile("excluded.txt", "content");
}
@Test
public void testPreviousImportReference() throws Exception {
Path file = workdir.resolve("test.txt");
Files.write(file, "first write".getBytes(StandardCharsets.UTF_8));
writer = newWriter();
assertThat(writer.getDestinationStatus(destinationFiles, DummyOrigin.LABEL_NAME)).isNull();
createRevisionAndWrite("first_commit");
assertCommitHasOrigin(getLastCommit(fetch), "first_commit");
Files.write(file, "second write".getBytes(StandardCharsets.UTF_8));
assertThat(writer.getDestinationStatus(destinationFiles, DummyOrigin.LABEL_NAME).getBaseline())
.isEqualTo("first_commit");
createRevisionAndWrite("second_commit");
assertCommitHasOrigin(getLastCommit(fetch), "second_commit");
Path otherFile = workdir.resolve("other.txt");
Files.write(otherFile, "third write".getBytes(StandardCharsets.UTF_8));
assertThat(writer.getDestinationStatus(destinationFiles, DummyOrigin.LABEL_NAME).getBaseline())
.isEqualTo("second_commit");
createRevisionAndWrite("third_commit");
assertCommitHasOrigin(getLastCommit(fetch), "third_commit");
}
@Test
public void testPreviousImportReference_nonCopybaraCommitsSinceLastMigrate() throws Exception {
Files.write(workdir.resolve("file.txt"), "test write".getBytes(StandardCharsets.UTF_8));
writer = newWriter();
createRevisionAndWrite("first_commit");
// update the remote repo workdir to have new changes
remoteRepo.cleanUpdate(push);
Path scratchTree = Files.createTempDirectory(hgDestPath,"HgDestinationTest-scratchTree");
for (int i = 0; i < 20; i++) {
Path excludedFile = Files.write(scratchTree.resolve("excluded.dat"), new byte[] {(byte) i});
remoteRepo.hg(hgDestPath, "add", excludedFile.toString());
remoteRepo.hg(hgDestPath, "commit", "-m", "excluded #" + i);
}
assertThat(writer.getDestinationStatus(destinationFiles, DummyOrigin.LABEL_NAME).getBaseline())
.isEqualTo("first_commit");
}
private void createRevisionAndWrite(String referenceName)
throws RepoException, ValidationException, IOException {
DummyRevision originRef = new DummyRevision(referenceName);
TransformResult result = TransformResults.of(workdir, originRef);
writer.write(result, destinationFiles, console);
}
private void assertCommitHasOrigin(HgLogEntry commit, String originRef) {
assertThat(parseMessage(commit.getDescription())
.labelsAsMultimap()).containsEntry(DummyOrigin.LABEL_NAME, originRef);
}
private HgLogEntry getLastCommit(String ref) throws RepoException, ValidationException {
return getOnlyElement(remoteRepo.log().withReferenceExpression(ref).withLimit(1).run());
}
private Writer<HgRevision> newWriter() {
WriterContext writerContext = new WriterContext("", "Test", false, new HgRevision("test"),
Glob.ALL_FILES.roots());
return destination.newWriter(writerContext);
}
}