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