View Javadoc
1   /*
2    * Copyright (C) 2019, Google LLC. and others
3    *
4    * This program and the accompanying materials are made available under the
5    * terms of the Eclipse Distribution License v. 1.0 which is available at
6    * https://www.eclipse.org/org/documents/edl-v10.php.
7    *
8    * SPDX-License-Identifier: BSD-3-Clause
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  	/** {@inheritDoc} */
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 }