blob: 4695eaa695b02ba61a499c38753215c5a90e3c4e [file] [log] [blame]
/*
* Copyright (C) 2019, Google LLC. and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0 which is available at
* https://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.revwalk;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.util.Arrays;
import java.util.Optional;
import java.util.stream.Stream;
import org.eclipse.jgit.internal.storage.file.FileRepository;
import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase;
import org.eclipse.jgit.junit.TestRepository;
import org.junit.Before;
import org.junit.Test;
public abstract class ReachabilityCheckerTestCase
extends LocalDiskRepositoryTestCase {
protected abstract ReachabilityChecker getChecker(
TestRepository<FileRepository> repository) throws Exception;
TestRepository<FileRepository> repo;
/** {@inheritDoc} */
@Override
@Before
public void setUp() throws Exception {
super.setUp();
FileRepository db = createWorkRepository();
repo = new TestRepository<>(db);
}
@Test
public void reachable() throws Exception {
RevCommit a = repo.commit().create();
RevCommit b1 = repo.commit(a);
RevCommit b2 = repo.commit(b1);
RevCommit c1 = repo.commit(a);
RevCommit c2 = repo.commit(c1);
repo.update("refs/heads/checker", b2);
ReachabilityChecker checker = getChecker(repo);
assertReachable("reachable from one tip",
checker.areAllReachable(Arrays.asList(a), Stream.of(c2)));
assertReachable("reachable from another tip",
checker.areAllReachable(Arrays.asList(a), Stream.of(b2)));
assertReachable("reachable from itself",
checker.areAllReachable(Arrays.asList(a), Stream.of(b2)));
}
@Test
public void reachable_merge() throws Exception {
RevCommit a = repo.commit().create();
RevCommit b1 = repo.commit(a);
RevCommit b2 = repo.commit(b1);
RevCommit c1 = repo.commit(a);
RevCommit c2 = repo.commit(c1);
RevCommit merge = repo.commit(c2, b2);
repo.update("refs/heads/checker", merge);
ReachabilityChecker checker = getChecker(repo);
assertReachable("reachable through one branch",
checker.areAllReachable(Arrays.asList(b1),
Stream.of(merge)));
assertReachable("reachable through another branch",
checker.areAllReachable(Arrays.asList(c1),
Stream.of(merge)));
assertReachable("reachable, before the branching",
checker.areAllReachable(Arrays.asList(a),
Stream.of(merge)));
}
@Test
public void unreachable_isLaterCommit() throws Exception {
RevCommit a = repo.commit().create();
RevCommit b1 = repo.commit(a);
RevCommit b2 = repo.commit(b1);
repo.update("refs/heads/checker", b2);
ReachabilityChecker checker = getChecker(repo);
assertUnreachable("unreachable from the future",
checker.areAllReachable(Arrays.asList(b2), Stream.of(b1)));
}
@Test
public void unreachable_differentBranch() throws Exception {
RevCommit a = repo.commit().create();
RevCommit b1 = repo.commit(a);
RevCommit b2 = repo.commit(b1);
RevCommit c1 = repo.commit(a);
repo.update("refs/heads/checker", b2);
ReachabilityChecker checker = getChecker(repo);
assertUnreachable("unreachable from different branch",
checker.areAllReachable(Arrays.asList(c1), Stream.of(b2)));
}
@Test
public void reachable_longChain() throws Exception {
RevCommit root = repo.commit().create();
RevCommit head = root;
for (int i = 0; i < 10000; i++) {
head = repo.commit(head);
}
repo.update("refs/heads/master", head);
ReachabilityChecker checker = getChecker(repo);
assertReachable("reachable with long chain in the middle", checker
.areAllReachable(Arrays.asList(root), Stream.of(head)));
}
private static void assertReachable(String msg,
Optional<RevCommit> result) {
assertFalse(msg, result.isPresent());
}
private static void assertUnreachable(String msg,
Optional<RevCommit> result) {
assertTrue(msg, result.isPresent());
}
}