--- /dev/null
- checker.areAllReachable(Arrays.asList(a), Stream.of(b2)));
+/*
+ * 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.internal.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.eclipse.jgit.revwalk.ReachabilityChecker;
+import org.eclipse.jgit.revwalk.RevCommit;
+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(a)));
+ }
+
+ @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());
+ }
+}