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 = createBareRepository();
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 assertEquals(1, ((Repository) db).useCnt.get());
192 RepositoryCache.register(db);
193 assertEquals(1, ((Repository) db).useCnt.get());
194 db.close();
195 assertEquals(0, ((Repository) db).useCnt.get());
196 }
197
198 @Test
199 public void testRepositoryNotUnregisteringWhenClosing() throws Exception {
200 FileKey loc = FileKey.exact(db.getDirectory(), db.getFS());
201 Repository d2 = RepositoryCache.open(loc);
202 assertEquals(1, d2.useCnt.get());
203 assertThat(RepositoryCache.getRegisteredKeys(),
204 hasItem(FileKey.exact(db.getDirectory(), db.getFS())));
205 assertEquals(1, RepositoryCache.getRegisteredKeys().size());
206 d2.close();
207 assertEquals(0, d2.useCnt.get());
208 assertEquals(1, RepositoryCache.getRegisteredKeys().size());
209 assertTrue(RepositoryCache.isCached(d2));
210 }
211
212 @Test
213 public void testRepositoryUnregisteringWhenExpired() throws Exception {
214 Repository repoA = createBareRepository();
215 Repository repoB = createBareRepository();
216 Repository repoC = createBareRepository();
217 RepositoryCache.register(repoA);
218 RepositoryCache.register(repoB);
219 RepositoryCache.register(repoC);
220
221 assertEquals(3, RepositoryCache.getRegisteredKeys().size());
222 assertTrue(RepositoryCache.isCached(repoA));
223 assertTrue(RepositoryCache.isCached(repoB));
224 assertTrue(RepositoryCache.isCached(repoC));
225
226
227
228 repoA.close();
229 repoA.closedAt.set(System.currentTimeMillis() - 65 * 60 * 1000);
230
231 repoB.close();
232
233 assertEquals(3, RepositoryCache.getRegisteredKeys().size());
234 assertTrue(RepositoryCache.isCached(repoA));
235 assertTrue(RepositoryCache.isCached(repoB));
236 assertTrue(RepositoryCache.isCached(repoC));
237
238 RepositoryCache.clearExpired();
239
240 assertEquals(2, RepositoryCache.getRegisteredKeys().size());
241 assertFalse(RepositoryCache.isCached(repoA));
242 assertTrue(RepositoryCache.isCached(repoB));
243 assertTrue(RepositoryCache.isCached(repoC));
244 }
245
246 @Test
247 public void testReconfigure() throws InterruptedException {
248 RepositoryCache.register(db);
249 assertTrue(RepositoryCache.isCached(db));
250 db.close();
251 assertTrue(RepositoryCache.isCached(db));
252
253
254
255
256
257
258
259 RepositoryCacheConfig config = new RepositoryCacheConfig();
260 config.setExpireAfter(1);
261 config.setCleanupDelay(1);
262 config.install();
263
264
265
266
267 for (int i = 0; i <= 10; i++) {
268 Thread.sleep(1 << i);
269 if (!RepositoryCache.isCached(db)) {
270 return;
271 }
272 }
273 fail("Repository should have been evicted from cache");
274 }
275 }