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 Repository r;
98
99 r = new FileKey(db.getDirectory(), db.getFS()).open(true);
100 assertNotNull(r);
101 assertEqualsFile(db.getDirectory(), r.getDirectory());
102 r.close();
103
104 r = new FileKey(db.getDirectory(), db.getFS()).open(false);
105 assertNotNull(r);
106 assertEqualsFile(db.getDirectory(), r.getDirectory());
107 r.close();
108 }
109
110 @Test
111 public void testFileKeyOpenNew() throws IOException {
112 final Repository n = createRepository(true, false);
113 final File gitdir = n.getDirectory();
114 n.close();
115 recursiveDelete(gitdir);
116 assertFalse(gitdir.exists());
117
118 try {
119 new FileKey(gitdir, db.getFS()).open(true);
120 fail("incorrectly opened a non existant repository");
121 } catch (RepositoryNotFoundException e) {
122 assertEquals("repository not found: " + gitdir.getCanonicalPath(),
123 e.getMessage());
124 }
125
126 final Repository o = new FileKey(gitdir, db.getFS()).open(false);
127 assertNotNull(o);
128 assertEqualsFile(gitdir, o.getDirectory());
129 assertFalse(gitdir.exists());
130 }
131
132 @Test
133 public void testCacheRegisterOpen() throws Exception {
134 final File dir = db.getDirectory();
135 RepositoryCache.register(db);
136 assertSame(db, RepositoryCache.open(FileKey.exact(dir, db.getFS())));
137
138 assertEquals(".git", dir.getName());
139 final File parent = dir.getParentFile();
140 assertSame(db, RepositoryCache.open(FileKey.lenient(parent, db.getFS())));
141 }
142
143 @Test
144 public void testCacheOpen() throws Exception {
145 final FileKey loc = FileKey.exact(db.getDirectory(), db.getFS());
146 final Repository d2 = RepositoryCache.open(loc);
147 assertNotSame(db, d2);
148 assertSame(d2, RepositoryCache.open(FileKey.exact(loc.getFile(), db.getFS())));
149 d2.close();
150 d2.close();
151 }
152
153 @Test
154 public void testGetRegisteredWhenEmpty() {
155 assertEquals(0, RepositoryCache.getRegisteredKeys().size());
156 }
157
158 @Test
159 public void testGetRegistered() {
160 RepositoryCache.register(db);
161
162 assertThat(RepositoryCache.getRegisteredKeys(),
163 hasItem(FileKey.exact(db.getDirectory(), db.getFS())));
164 assertEquals(1, RepositoryCache.getRegisteredKeys().size());
165 }
166
167 @Test
168 public void testUnregister() {
169 RepositoryCache.register(db);
170 RepositoryCache
171 .unregister(FileKey.exact(db.getDirectory(), db.getFS()));
172
173 assertEquals(0, RepositoryCache.getRegisteredKeys().size());
174 }
175
176 @Test
177 public void testRepositoryUsageCount() throws Exception {
178 FileKey loc = FileKey.exact(db.getDirectory(), db.getFS());
179 Repository d2 = RepositoryCache.open(loc);
180 assertEquals(1, d2.useCnt.get());
181 RepositoryCache.open(FileKey.exact(loc.getFile(), db.getFS()));
182 assertEquals(2, d2.useCnt.get());
183 d2.close();
184 assertEquals(1, d2.useCnt.get());
185 d2.close();
186 assertEquals(0, d2.useCnt.get());
187 }
188
189 @Test
190 public void testRepositoryUsageCountWithRegisteredRepository()
191 throws IOException {
192 Repository repo = createRepository(false, false);
193 assertEquals(1, repo.useCnt.get());
194 RepositoryCache.register(repo);
195 assertEquals(1, repo.useCnt.get());
196 repo.close();
197 assertEquals(0, repo.useCnt.get());
198 }
199
200 @Test
201 public void testRepositoryNotUnregisteringWhenClosing() throws Exception {
202 FileKey loc = FileKey.exact(db.getDirectory(), db.getFS());
203 Repository d2 = RepositoryCache.open(loc);
204 assertEquals(1, d2.useCnt.get());
205 assertThat(RepositoryCache.getRegisteredKeys(),
206 hasItem(FileKey.exact(db.getDirectory(), db.getFS())));
207 assertEquals(1, RepositoryCache.getRegisteredKeys().size());
208 d2.close();
209 assertEquals(0, d2.useCnt.get());
210 assertEquals(1, RepositoryCache.getRegisteredKeys().size());
211 assertTrue(RepositoryCache.isCached(d2));
212 }
213
214 @Test
215 public void testRepositoryUnregisteringWhenExpiredAndUsageCountNegative()
216 throws Exception {
217 Repository repoA = createBareRepository();
218 RepositoryCache.register(repoA);
219
220 assertEquals(1, RepositoryCache.getRegisteredKeys().size());
221 assertTrue(RepositoryCache.isCached(repoA));
222
223
224 repoA.close();
225 repoA.close();
226
227
228 repoA.closedAt.set(System.currentTimeMillis() - 65 * 60 * 1000);
229
230 RepositoryCache.clearExpired();
231
232 assertEquals(0, RepositoryCache.getRegisteredKeys().size());
233 }
234
235 @Test
236 public void testRepositoryUnregisteringWhenExpired() throws Exception {
237 Repository repoA = createRepository(true, false);
238 Repository repoB = createRepository(true, false);
239 Repository repoC = createBareRepository();
240 RepositoryCache.register(repoA);
241 RepositoryCache.register(repoB);
242 RepositoryCache.register(repoC);
243
244 assertEquals(3, RepositoryCache.getRegisteredKeys().size());
245 assertTrue(RepositoryCache.isCached(repoA));
246 assertTrue(RepositoryCache.isCached(repoB));
247 assertTrue(RepositoryCache.isCached(repoC));
248
249
250
251 repoA.close();
252 repoA.closedAt.set(System.currentTimeMillis() - 65 * 60 * 1000);
253
254 repoB.close();
255
256 assertEquals(3, RepositoryCache.getRegisteredKeys().size());
257 assertTrue(RepositoryCache.isCached(repoA));
258 assertTrue(RepositoryCache.isCached(repoB));
259 assertTrue(RepositoryCache.isCached(repoC));
260
261 RepositoryCache.clearExpired();
262
263 assertEquals(2, RepositoryCache.getRegisteredKeys().size());
264 assertFalse(RepositoryCache.isCached(repoA));
265 assertTrue(RepositoryCache.isCached(repoB));
266 assertTrue(RepositoryCache.isCached(repoC));
267 }
268
269 @Test
270 public void testReconfigure() throws InterruptedException, IOException {
271 Repository repo = createRepository(false, false);
272 RepositoryCache.register(repo);
273 assertTrue(RepositoryCache.isCached(repo));
274 repo.close();
275 assertTrue(RepositoryCache.isCached(repo));
276
277
278
279
280
281
282
283 RepositoryCacheConfig config = new RepositoryCacheConfig();
284 config.setExpireAfter(1);
285 config.setCleanupDelay(1);
286 config.install();
287
288
289
290
291 for (int i = 0; i <= 10; i++) {
292 Thread.sleep(1 << i);
293 if (!RepositoryCache.isCached(repo)) {
294 return;
295 }
296 }
297 fail("Repository should have been evicted from cache");
298 }
299 }