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