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