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.junit.TestRepository.CommitBuilder;
23 import org.eclipse.jgit.revwalk.ObjectReachabilityChecker;
24 import org.eclipse.jgit.revwalk.RevBlob;
25 import org.eclipse.jgit.revwalk.RevCommit;
26 import org.eclipse.jgit.revwalk.RevObject;
27 import org.junit.Before;
28 import org.junit.Test;
29
30 public abstract class ObjectReachabilityTestCase
31 extends LocalDiskRepositoryTestCase {
32
33 private TestRepository<FileRepository> repo;
34 private AddressableRevCommit baseCommit;
35 private AddressableRevCommit branchACommit;
36 private AddressableRevCommit branchBCommit;
37 private AddressableRevCommit mergeCommit;
38
39 abstract ObjectReachabilityChecker getChecker(
40 TestRepository<FileRepository> repository) throws Exception;
41
42
43 protected static class AddressableRevCommit {
44 RevCommit commit;
45
46 RevBlob blob;
47
48 AddressableRevCommit(RevCommit commit, RevBlob blob) {
49 this.commit = commit;
50 this.blob = blob;
51 }
52 }
53
54
55 @Override
56 @Before
57 public void setUp() throws Exception {
58 super.setUp();
59 FileRepository db = createWorkRepository();
60 repo = new TestRepository<>(db);
61 prepareRepo();
62 }
63
64 @Test
65 public void blob_in_base_reachable_from_branches() throws Exception {
66 ObjectReachabilityChecker checker = getChecker(repo);
67
68 RevObject baseBlob = baseCommit.blob;
69 assertReachable("reachable from one branch", checker.areAllReachable(
70 Arrays.asList(baseBlob), Stream.of(branchACommit.commit)));
71 assertReachable("reachable from another branch",
72 checker.areAllReachable(
73 Arrays.asList(baseBlob),
74 Stream.of(branchBCommit.commit)));
75 }
76
77 @Test
78 public void blob_reachable_from_owning_commit() throws Exception {
79 ObjectReachabilityChecker checker = getChecker(repo);
80
81 RevObject branchABlob = branchACommit.blob;
82 assertReachable("reachable from itself",
83 checker.areAllReachable(Arrays.asList(branchABlob),
84 Stream.of(branchACommit.commit)));
85 }
86
87 @Test
88 public void blob_in_branch_reachable_from_merge() throws Exception {
89 ObjectReachabilityChecker checker = getChecker(repo);
90
91 RevObject branchABlob = branchACommit.blob;
92 assertReachable("reachable from merge", checker.areAllReachable(
93 Arrays.asList(branchABlob), Stream.of(mergeCommit.commit)));
94 }
95
96 @Test
97 public void blob_unreachable_from_earlier_commit() throws Exception {
98 ObjectReachabilityChecker checker = getChecker(repo);
99
100 RevObject branchABlob = branchACommit.blob;
101 assertUnreachable("unreachable from earlier commit",
102 checker.areAllReachable(Arrays.asList(branchABlob),
103 Stream.of(baseCommit.commit)));
104 }
105
106 @Test
107 public void blob_unreachable_from_parallel_branch() throws Exception {
108 ObjectReachabilityChecker checker = getChecker(repo);
109
110 RevObject branchABlob = branchACommit.blob;
111 assertUnreachable("unreachable from another branch",
112 checker.areAllReachable(Arrays.asList(branchABlob),
113 Stream.of(branchBCommit.commit)));
114 }
115
116 private void prepareRepo() throws Exception {
117 baseCommit = createCommit("base");
118 branchACommit = createCommit("branchA", baseCommit);
119 branchBCommit = createCommit("branchB", baseCommit);
120 mergeCommit = createCommit("merge", branchACommit, branchBCommit);
121
122
123 repo.update("refs/heads/a", branchACommit.commit);
124 repo.update("refs/heads/b", branchBCommit.commit);
125 repo.update("refs/heads/merge", mergeCommit.commit);
126 }
127
128 private AddressableRevCommit createCommit(String blobPath, AddressableRevCommit... parents) throws Exception {
129 RevBlob blob = repo.blob(blobPath + " content");
130 CommitBuilder commitBuilder = repo.commit();
131 for (int i = 0; i < parents.length; i++) {
132 commitBuilder.parent(parents[i].commit);
133 }
134 commitBuilder.add(blobPath, blob);
135
136 RevCommit commit = commitBuilder.create();
137 return new AddressableRevCommit(commit, blob);
138 }
139
140 private static void assertReachable(String msg, Optional<RevObject> result) {
141 assertFalse(msg, result.isPresent());
142 }
143
144 private static void assertUnreachable(String msg, Optional<RevObject> result) {
145 assertTrue(msg, result.isPresent());
146 }
147 }