1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44 package org.eclipse.jgit.lib;
45
46 import static org.hamcrest.CoreMatchers.hasItem;
47 import static org.junit.Assert.assertEquals;
48 import static org.junit.Assert.assertFalse;
49 import static org.junit.Assert.assertNotNull;
50 import static org.junit.Assert.assertNotSame;
51 import static org.junit.Assert.assertSame;
52 import static org.junit.Assert.assertThat;
53 import static org.junit.Assert.assertTrue;
54 import static org.junit.Assert.fail;
55
56 import java.io.File;
57 import java.io.IOException;
58
59 import org.eclipse.jgit.errors.RepositoryNotFoundException;
60 import org.eclipse.jgit.junit.RepositoryTestCase;
61 import org.eclipse.jgit.lib.RepositoryCache.FileKey;
62 import org.junit.Test;
63
64 public class RepositoryCacheTest extends RepositoryTestCase {
65 @Test
66 public void testNonBareFileKey() throws IOException {
67 File gitdir = db.getDirectory();
68 File parent = gitdir.getParentFile();
69 File other = new File(parent, "notagit");
70 assertEqualsFile(gitdir, FileKey.exact(gitdir, db.getFS()).getFile());
71 assertEqualsFile(parent, FileKey.exact(parent, db.getFS()).getFile());
72 assertEqualsFile(other, FileKey.exact(other, db.getFS()).getFile());
73
74 assertEqualsFile(gitdir, FileKey.lenient(gitdir, db.getFS()).getFile());
75 assertEqualsFile(gitdir, FileKey.lenient(parent, db.getFS()).getFile());
76 assertEqualsFile(other, FileKey.lenient(other, db.getFS()).getFile());
77 }
78
79 @Test
80 public void testBareFileKey() throws IOException {
81 Repository bare = createBareRepository();
82 File gitdir = bare.getDirectory();
83 File parent = gitdir.getParentFile();
84 String name = gitdir.getName();
85 assertTrue(name.endsWith(".git"));
86 name = name.substring(0, name.length() - 4);
87
88 assertEqualsFile(gitdir, FileKey.exact(gitdir, db.getFS()).getFile());
89
90 assertEqualsFile(gitdir, FileKey.lenient(gitdir, db.getFS()).getFile());
91 assertEqualsFile(gitdir,
92 FileKey.lenient(new File(parent, name), db.getFS()).getFile());
93 }
94
95 @Test
96 public void testFileKeyOpenExisting() throws IOException {
97 try (Repository r = new FileKey(db.getDirectory(), db.getFS())
98 .open(true)) {
99 assertNotNull(r);
100 assertEqualsFile(db.getDirectory(), r.getDirectory());
101 }
102
103 try (Repository r = new FileKey(db.getDirectory(), db.getFS())
104 .open(false)) {
105 assertNotNull(r);
106 assertEqualsFile(db.getDirectory(), r.getDirectory());
107 }
108 }
109
110 @Test
111 public void testFileKeyOpenNew() throws IOException {
112 File gitdir;
113 try (Repository n = createRepository(true)) {
114 gitdir = n.getDirectory();
115 }
116 recursiveDelete(gitdir);
117 assertFalse(gitdir.exists());
118
119 try {
120 new FileKey(gitdir, db.getFS()).open(true);
121 fail("incorrectly opened a non existant repository");
122 } catch (RepositoryNotFoundException e) {
123 assertEquals("repository not found: " + gitdir.getCanonicalPath(),
124 e.getMessage());
125 }
126
127 final Repository o = new FileKey(gitdir, db.getFS()).open(false);
128 assertNotNull(o);
129 assertEqualsFile(gitdir, o.getDirectory());
130 assertFalse(gitdir.exists());
131 }
132
133 @Test
134 public void testCacheRegisterOpen() throws Exception {
135 final File dir = db.getDirectory();
136 RepositoryCache.register(db);
137 assertSame(db, RepositoryCache.open(FileKey.exact(dir, db.getFS())));
138
139 assertEquals(".git", dir.getName());
140 final File parent = dir.getParentFile();
141 assertSame(db, RepositoryCache.open(FileKey.lenient(parent, db.getFS())));
142 }
143
144 @Test
145 public void testCacheOpen() throws Exception {
146 final FileKey loc = FileKey.exact(db.getDirectory(), db.getFS());
147 @SuppressWarnings("resource")
148 final Repository d2 = RepositoryCache.open(loc);
149 assertNotSame(db, d2);
150 assertSame(d2, RepositoryCache.open(FileKey.exact(loc.getFile(), db.getFS())));
151 d2.close();
152 d2.close();
153 }
154
155 @Test
156 public void testGetRegisteredWhenEmpty() {
157 assertEquals(0, RepositoryCache.getRegisteredKeys().size());
158 }
159
160 @Test
161 public void testGetRegistered() {
162 RepositoryCache.register(db);
163
164 assertThat(RepositoryCache.getRegisteredKeys(),
165 hasItem(FileKey.exact(db.getDirectory(), db.getFS())));
166 assertEquals(1, RepositoryCache.getRegisteredKeys().size());
167 }
168
169 @Test
170 public void testUnregister() {
171 RepositoryCache.register(db);
172 RepositoryCache
173 .unregister(FileKey.exact(db.getDirectory(), db.getFS()));
174
175 assertEquals(0, RepositoryCache.getRegisteredKeys().size());
176 }
177
178 @Test
179 public void testRepositoryUsageCount() throws Exception {
180 FileKey loc = FileKey.exact(db.getDirectory(), db.getFS());
181 @SuppressWarnings("resource")
182 Repository d2 = RepositoryCache.open(loc);
183 assertEquals(1, d2.useCnt.get());
184 RepositoryCache.open(FileKey.exact(loc.getFile(), db.getFS()));
185 assertEquals(2, d2.useCnt.get());
186 d2.close();
187 assertEquals(1, d2.useCnt.get());
188 d2.close();
189 assertEquals(0, d2.useCnt.get());
190 }
191
192 @Test
193 public void testRepositoryUsageCountWithRegisteredRepository()
194 throws IOException {
195 @SuppressWarnings({"resource", "deprecation"})
196 Repository repo = createRepository(false, false);
197 assertEquals(1, repo.useCnt.get());
198 RepositoryCache.register(repo);
199 assertEquals(1, repo.useCnt.get());
200 repo.close();
201 assertEquals(0, repo.useCnt.get());
202 }
203
204 @Test
205 public void testRepositoryNotUnregisteringWhenClosing() throws Exception {
206 FileKey loc = FileKey.exact(db.getDirectory(), db.getFS());
207 @SuppressWarnings("resource")
208 Repository d2 = RepositoryCache.open(loc);
209 assertEquals(1, d2.useCnt.get());
210 assertThat(RepositoryCache.getRegisteredKeys(),
211 hasItem(FileKey.exact(db.getDirectory(), db.getFS())));
212 assertEquals(1, RepositoryCache.getRegisteredKeys().size());
213 d2.close();
214 assertEquals(0, d2.useCnt.get());
215 assertEquals(1, RepositoryCache.getRegisteredKeys().size());
216 assertTrue(RepositoryCache.isCached(d2));
217 }
218
219 @Test
220 public void testRepositoryUnregisteringWhenExpiredAndUsageCountNegative()
221 throws Exception {
222 @SuppressWarnings("resource")
223 Repository repoA = createBareRepository();
224 RepositoryCache.register(repoA);
225
226 assertEquals(1, RepositoryCache.getRegisteredKeys().size());
227 assertTrue(RepositoryCache.isCached(repoA));
228
229
230 repoA.close();
231 repoA.close();
232
233
234 repoA.closedAt.set(System.currentTimeMillis() - 65 * 60 * 1000);
235
236 RepositoryCache.clearExpired();
237
238 assertEquals(0, RepositoryCache.getRegisteredKeys().size());
239 }
240
241 @Test
242 public void testRepositoryUnregisteringWhenExpired() throws Exception {
243 @SuppressWarnings({"resource", "deprecation"})
244 Repository repoA = createRepository(true, false);
245 @SuppressWarnings({"resource", "deprecation"})
246 Repository repoB = createRepository(true, false);
247 Repository repoC = createBareRepository();
248 RepositoryCache.register(repoA);
249 RepositoryCache.register(repoB);
250 RepositoryCache.register(repoC);
251
252 assertEquals(3, RepositoryCache.getRegisteredKeys().size());
253 assertTrue(RepositoryCache.isCached(repoA));
254 assertTrue(RepositoryCache.isCached(repoB));
255 assertTrue(RepositoryCache.isCached(repoC));
256
257
258
259 repoA.close();
260 repoA.closedAt.set(System.currentTimeMillis() - 65 * 60 * 1000);
261
262 repoB.close();
263
264 assertEquals(3, RepositoryCache.getRegisteredKeys().size());
265 assertTrue(RepositoryCache.isCached(repoA));
266 assertTrue(RepositoryCache.isCached(repoB));
267 assertTrue(RepositoryCache.isCached(repoC));
268
269 RepositoryCache.clearExpired();
270
271 assertEquals(2, RepositoryCache.getRegisteredKeys().size());
272 assertFalse(RepositoryCache.isCached(repoA));
273 assertTrue(RepositoryCache.isCached(repoB));
274 assertTrue(RepositoryCache.isCached(repoC));
275 }
276
277 @Test
278 public void testReconfigure() throws InterruptedException, IOException {
279 @SuppressWarnings({"resource", "deprecation"})
280 Repository repo = createRepository(false, false);
281 RepositoryCache.register(repo);
282 assertTrue(RepositoryCache.isCached(repo));
283 repo.close();
284 assertTrue(RepositoryCache.isCached(repo));
285
286
287
288
289
290
291
292 RepositoryCacheConfig config = new RepositoryCacheConfig();
293 config.setExpireAfter(1);
294 config.setCleanupDelay(1);
295 config.install();
296
297
298
299
300 for (int i = 0; i <= 10; i++) {
301 Thread.sleep(1 << i);
302 if (!RepositoryCache.isCached(repo)) {
303 return;
304 }
305 }
306 fail("Repository should have been evicted from cache");
307 }
308 }