View Javadoc
1   /*
2    * Copyright (C) 2020, Lee Worrall 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.transport;
11  
12  import static org.hamcrest.MatcherAssert.assertThat;
13  import static org.hamcrest.Matchers.hasKey;
14  import static org.hamcrest.Matchers.instanceOf;
15  import static org.hamcrest.Matchers.not;
16  import static org.junit.Assert.assertEquals;
17  import static org.junit.Assert.assertSame;
18  
19  import java.util.Arrays;
20  import java.util.HashMap;
21  import java.util.LinkedHashMap;
22  import java.util.Map;
23  
24  import org.eclipse.jgit.lib.ObjectId;
25  import org.eclipse.jgit.lib.ObjectIdRef;
26  import org.eclipse.jgit.lib.Ref;
27  import org.eclipse.jgit.lib.SymbolicRef;
28  import org.junit.Test;
29  
30  public class BasePackConnectionTest {
31  
32  	@Test
33  	public void testExtractSymRefsFromCapabilities() {
34  		final Map<String, String> symRefs = BasePackConnection
35  				.extractSymRefsFromCapabilities(
36  						Arrays.asList("symref=HEAD:refs/heads/main",
37  								"symref=refs/heads/sym:refs/heads/other"));
38  
39  		assertEquals(2, symRefs.size());
40  		assertEquals("refs/heads/main", symRefs.get("HEAD"));
41  		assertEquals("refs/heads/other", symRefs.get("refs/heads/sym"));
42  	}
43  
44  	@Test
45  	public void testUpdateWithSymRefsAdds() {
46  		final Ref mainRef = new ObjectIdRef.Unpeeled(Ref.Storage.LOOSE,
47  				"refs/heads/main", ObjectId.fromString(
48  						"0000000000000000000000000000000000000001"));
49  
50  		final Map<String, Ref> refMap = new HashMap<>();
51  		refMap.put(mainRef.getName(), mainRef);
52  		refMap.put("refs/heads/other",
53  				new ObjectIdRef.Unpeeled(Ref.Storage.LOOSE, "refs/heads/other",
54  						ObjectId.fromString(
55  								"0000000000000000000000000000000000000002")));
56  
57  		final Map<String, String> symRefs = new HashMap<>();
58  		symRefs.put("HEAD", "refs/heads/main");
59  
60  		BasePackConnection.updateWithSymRefs(refMap, symRefs);
61  
62  		assertThat(refMap, hasKey("HEAD"));
63  		final Ref headRef = refMap.get("HEAD");
64  		assertThat(headRef, instanceOf(SymbolicRef.class));
65  		final SymbolicRef headSymRef = (SymbolicRef) headRef;
66  		assertEquals("HEAD", headSymRef.getName());
67  		assertSame(mainRef, headSymRef.getTarget());
68  	}
69  
70  	@Test
71  	public void testUpdateWithSymRefsReplaces() {
72  		final Ref mainRef = new ObjectIdRef.Unpeeled(Ref.Storage.LOOSE,
73  				"refs/heads/main", ObjectId.fromString(
74  						"0000000000000000000000000000000000000001"));
75  
76  		final Map<String, Ref> refMap = new HashMap<>();
77  		refMap.put(mainRef.getName(), mainRef);
78  		refMap.put("HEAD", new ObjectIdRef.Unpeeled(Ref.Storage.LOOSE, "HEAD",
79  				mainRef.getObjectId()));
80  		refMap.put("refs/heads/other",
81  				new ObjectIdRef.Unpeeled(Ref.Storage.LOOSE, "refs/heads/other",
82  						ObjectId.fromString(
83  								"0000000000000000000000000000000000000002")));
84  
85  		final Map<String, String> symRefs = new HashMap<>();
86  		symRefs.put("HEAD", "refs/heads/main");
87  
88  		BasePackConnection.updateWithSymRefs(refMap, symRefs);
89  
90  		assertThat(refMap, hasKey("HEAD"));
91  		final Ref headRef = refMap.get("HEAD");
92  		assertThat(headRef, instanceOf(SymbolicRef.class));
93  		final SymbolicRef headSymRef = (SymbolicRef) headRef;
94  		assertEquals("HEAD", headSymRef.getName());
95  		assertSame(mainRef, headSymRef.getTarget());
96  	}
97  
98  	@Test
99  	public void testUpdateWithSymRefsWithIndirectsAdds() {
100 		final Ref mainRef = new ObjectIdRef.Unpeeled(Ref.Storage.LOOSE,
101 				"refs/heads/main", ObjectId.fromString(
102 						"0000000000000000000000000000000000000001"));
103 
104 		final Map<String, Ref> refMap = new HashMap<>();
105 		refMap.put(mainRef.getName(), mainRef);
106 		refMap.put("refs/heads/other",
107 				new ObjectIdRef.Unpeeled(Ref.Storage.LOOSE, "refs/heads/other",
108 						ObjectId.fromString(
109 								"0000000000000000000000000000000000000002")));
110 
111 		final Map<String, String> symRefs = new LinkedHashMap<>(); // Ordered
112 		symRefs.put("refs/heads/sym3", "refs/heads/sym2"); // Forward reference
113 		symRefs.put("refs/heads/sym1", "refs/heads/main");
114 		symRefs.put("refs/heads/sym2", "refs/heads/sym1"); // Backward reference
115 
116 		BasePackConnection.updateWithSymRefs(refMap, symRefs);
117 
118 		assertThat(refMap, hasKey("refs/heads/sym1"));
119 		final Ref sym1Ref = refMap.get("refs/heads/sym1");
120 		assertThat(sym1Ref, instanceOf(SymbolicRef.class));
121 		final SymbolicRef sym1SymRef = (SymbolicRef) sym1Ref;
122 		assertEquals("refs/heads/sym1", sym1SymRef.getName());
123 		assertSame(mainRef, sym1SymRef.getTarget());
124 
125 		assertThat(refMap, hasKey("refs/heads/sym2"));
126 		final Ref sym2Ref = refMap.get("refs/heads/sym2");
127 		assertThat(sym2Ref, instanceOf(SymbolicRef.class));
128 		final SymbolicRef sym2SymRef = (SymbolicRef) sym2Ref;
129 		assertEquals("refs/heads/sym2", sym2SymRef.getName());
130 		assertSame(sym1SymRef, sym2SymRef.getTarget());
131 
132 		assertThat(refMap, hasKey("refs/heads/sym3"));
133 		final Ref sym3Ref = refMap.get("refs/heads/sym3");
134 		assertThat(sym3Ref, instanceOf(SymbolicRef.class));
135 		final SymbolicRef sym3SymRef = (SymbolicRef) sym3Ref;
136 		assertEquals("refs/heads/sym3", sym3SymRef.getName());
137 		assertSame(sym2SymRef, sym3SymRef.getTarget());
138 	}
139 
140 	@Test
141 	public void testUpdateWithSymRefsWithIndirectsReplaces() {
142 		final Ref mainRef = new ObjectIdRef.Unpeeled(Ref.Storage.LOOSE,
143 				"refs/heads/main", ObjectId.fromString(
144 						"0000000000000000000000000000000000000001"));
145 
146 		final Map<String, Ref> refMap = new HashMap<>();
147 		refMap.put(mainRef.getName(), mainRef);
148 		refMap.put("refs/heads/sym1", new ObjectIdRef.Unpeeled(
149 				Ref.Storage.LOOSE, "refs/heads/sym1", mainRef.getObjectId()));
150 		refMap.put("refs/heads/sym2", new ObjectIdRef.Unpeeled(
151 				Ref.Storage.LOOSE, "refs/heads/sym2", mainRef.getObjectId()));
152 		refMap.put("refs/heads/sym3", new ObjectIdRef.Unpeeled(
153 				Ref.Storage.LOOSE, "refs/heads/sym3", mainRef.getObjectId()));
154 		refMap.put("refs/heads/other",
155 				new ObjectIdRef.Unpeeled(Ref.Storage.LOOSE, "refs/heads/other",
156 						ObjectId.fromString(
157 								"0000000000000000000000000000000000000002")));
158 
159 		final Map<String, String> symRefs = new LinkedHashMap<>(); // Ordered
160 		symRefs.put("refs/heads/sym3", "refs/heads/sym2"); // Forward reference
161 		symRefs.put("refs/heads/sym1", "refs/heads/main");
162 		symRefs.put("refs/heads/sym2", "refs/heads/sym1"); // Backward reference
163 
164 		BasePackConnection.updateWithSymRefs(refMap, symRefs);
165 
166 		assertThat(refMap, hasKey("refs/heads/sym1"));
167 		final Ref sym1Ref = refMap.get("refs/heads/sym1");
168 		assertThat(sym1Ref, instanceOf(SymbolicRef.class));
169 		final SymbolicRef sym1SymRef = (SymbolicRef) sym1Ref;
170 		assertEquals("refs/heads/sym1", sym1SymRef.getName());
171 		assertSame(mainRef, sym1SymRef.getTarget());
172 
173 		assertThat(refMap, hasKey("refs/heads/sym2"));
174 		final Ref sym2Ref = refMap.get("refs/heads/sym2");
175 		assertThat(sym2Ref, instanceOf(SymbolicRef.class));
176 		final SymbolicRef sym2SymRef = (SymbolicRef) sym2Ref;
177 		assertEquals("refs/heads/sym2", sym2SymRef.getName());
178 		assertSame(sym1SymRef, sym2SymRef.getTarget());
179 
180 		assertThat(refMap, hasKey("refs/heads/sym3"));
181 		final Ref sym3Ref = refMap.get("refs/heads/sym3");
182 		assertThat(sym3Ref, instanceOf(SymbolicRef.class));
183 		final SymbolicRef sym3SymRef = (SymbolicRef) sym3Ref;
184 		assertEquals("refs/heads/sym3", sym3SymRef.getName());
185 		assertSame(sym2SymRef, sym3SymRef.getTarget());
186 	}
187 
188 	@Test
189 	public void testUpdateWithSymRefsIgnoresSelfReference() {
190 		final Ref mainRef = new ObjectIdRef.Unpeeled(Ref.Storage.LOOSE,
191 				"refs/heads/main", ObjectId.fromString(
192 						"0000000000000000000000000000000000000001"));
193 
194 		final Map<String, Ref> refMap = new HashMap<>();
195 		refMap.put(mainRef.getName(), mainRef);
196 		refMap.put("refs/heads/other",
197 				new ObjectIdRef.Unpeeled(Ref.Storage.LOOSE, "refs/heads/other",
198 						ObjectId.fromString(
199 								"0000000000000000000000000000000000000002")));
200 
201 		final Map<String, String> symRefs = new LinkedHashMap<>();
202 		symRefs.put("refs/heads/sym1", "refs/heads/sym1");
203 
204 		BasePackConnection.updateWithSymRefs(refMap, symRefs);
205 
206 		assertEquals(2, refMap.size());
207 		assertThat(refMap, not(hasKey("refs/heads/sym1")));
208 	}
209 
210 	@Test
211 	public void testUpdateWithSymRefsIgnoreCircularReference() {
212 		final Ref mainRef = new ObjectIdRef.Unpeeled(Ref.Storage.LOOSE,
213 				"refs/heads/main", ObjectId.fromString(
214 						"0000000000000000000000000000000000000001"));
215 
216 		final Map<String, Ref> refMap = new HashMap<>();
217 		refMap.put(mainRef.getName(), mainRef);
218 		refMap.put("refs/heads/other",
219 				new ObjectIdRef.Unpeeled(Ref.Storage.LOOSE, "refs/heads/other",
220 						ObjectId.fromString(
221 								"0000000000000000000000000000000000000002")));
222 
223 		final Map<String, String> symRefs = new LinkedHashMap<>();
224 		symRefs.put("refs/heads/sym2", "refs/heads/sym1");
225 		symRefs.put("refs/heads/sym1", "refs/heads/sym2");
226 
227 		BasePackConnection.updateWithSymRefs(refMap, symRefs);
228 
229 		assertEquals(2, refMap.size());
230 		assertThat(refMap, not(hasKey("refs/heads/sym1")));
231 		assertThat(refMap, not(hasKey("refs/heads/sym2")));
232 	}
233 }