1
2
3
4
5
6
7
8
9
10 package org.eclipse.jgit.internal.revwalk;
11
12 import static org.junit.Assert.assertFalse;
13 import static org.junit.Assert.assertTrue;
14
15 import java.util.Arrays;
16 import java.util.Optional;
17 import java.util.stream.Stream;
18
19 import org.eclipse.jgit.internal.storage.file.FileRepository;
20 import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase;
21 import org.eclipse.jgit.junit.TestRepository;
22 import org.eclipse.jgit.revwalk.ReachabilityChecker;
23 import org.eclipse.jgit.revwalk.RevCommit;
24 import org.junit.Before;
25 import org.junit.Test;
26
27 public abstract class ReachabilityCheckerTestCase
28 extends LocalDiskRepositoryTestCase {
29
30 protected abstract ReachabilityChecker getChecker(
31 TestRepository<FileRepository> repository) throws Exception;
32
33 TestRepository<FileRepository> repo;
34
35
36 @Override
37 @Before
38 public void setUp() throws Exception {
39 super.setUp();
40 FileRepository db = createWorkRepository();
41 repo = new TestRepository<>(db);
42 }
43
44 @Test
45 public void reachable() throws Exception {
46 RevCommit a = repo.commit().create();
47 RevCommit b1 = repo.commit(a);
48 RevCommit b2 = repo.commit(b1);
49 RevCommit c1 = repo.commit(a);
50 RevCommit c2 = repo.commit(c1);
51 repo.update("refs/heads/checker", b2);
52
53 ReachabilityChecker checker = getChecker(repo);
54
55 assertReachable("reachable from one tip",
56 checker.areAllReachable(Arrays.asList(a), Stream.of(c2)));
57 assertReachable("reachable from another tip",
58 checker.areAllReachable(Arrays.asList(a), Stream.of(b2)));
59 assertReachable("reachable from itself",
60 checker.areAllReachable(Arrays.asList(a), Stream.of(a)));
61 }
62
63 @Test
64 public void reachable_merge() throws Exception {
65 RevCommit a = repo.commit().create();
66 RevCommit b1 = repo.commit(a);
67 RevCommit b2 = repo.commit(b1);
68 RevCommit c1 = repo.commit(a);
69 RevCommit c2 = repo.commit(c1);
70 RevCommit merge = repo.commit(c2, b2);
71 repo.update("refs/heads/checker", merge);
72
73 ReachabilityChecker checker = getChecker(repo);
74
75 assertReachable("reachable through one branch",
76 checker.areAllReachable(Arrays.asList(b1),
77 Stream.of(merge)));
78 assertReachable("reachable through another branch",
79 checker.areAllReachable(Arrays.asList(c1),
80 Stream.of(merge)));
81 assertReachable("reachable, before the branching",
82 checker.areAllReachable(Arrays.asList(a),
83 Stream.of(merge)));
84 }
85
86 @Test
87 public void unreachable_isLaterCommit() throws Exception {
88 RevCommit a = repo.commit().create();
89 RevCommit b1 = repo.commit(a);
90 RevCommit b2 = repo.commit(b1);
91 repo.update("refs/heads/checker", b2);
92
93 ReachabilityChecker checker = getChecker(repo);
94
95 assertUnreachable("unreachable from the future",
96 checker.areAllReachable(Arrays.asList(b2), Stream.of(b1)));
97 }
98
99 @Test
100 public void unreachable_differentBranch() throws Exception {
101 RevCommit a = repo.commit().create();
102 RevCommit b1 = repo.commit(a);
103 RevCommit b2 = repo.commit(b1);
104 RevCommit c1 = repo.commit(a);
105 repo.update("refs/heads/checker", b2);
106
107 ReachabilityChecker checker = getChecker(repo);
108
109 assertUnreachable("unreachable from different branch",
110 checker.areAllReachable(Arrays.asList(c1), Stream.of(b2)));
111 }
112
113 @Test
114 public void reachable_longChain() throws Exception {
115 RevCommit root = repo.commit().create();
116 RevCommit head = root;
117 for (int i = 0; i < 10000; i++) {
118 head = repo.commit(head);
119 }
120 repo.update("refs/heads/master", head);
121
122 ReachabilityChecker checker = getChecker(repo);
123
124 assertReachable("reachable with long chain in the middle", checker
125 .areAllReachable(Arrays.asList(root), Stream.of(head)));
126 }
127
128 private static void assertReachable(String msg,
129 Optional<RevCommit> result) {
130 assertFalse(msg, result.isPresent());
131 }
132
133 private static void assertUnreachable(String msg,
134 Optional<RevCommit> result) {
135 assertTrue(msg, result.isPresent());
136 }
137 }