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