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