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.internal.storage.file;
45
46 import static org.junit.Assert.assertEquals;
47 import static org.junit.Assert.assertFalse;
48 import static org.junit.Assert.assertTrue;
49
50 import java.io.File;
51 import java.io.IOException;
52 import java.util.ArrayList;
53 import java.util.Collection;
54 import java.util.Date;
55 import java.util.List;
56
57 import org.eclipse.jgit.junit.TestRepository.BranchBuilder;
58 import org.eclipse.jgit.lib.ConfigConstants;
59 import org.eclipse.jgit.lib.RefUpdate;
60 import org.eclipse.jgit.revwalk.RevCommit;
61 import org.eclipse.jgit.storage.file.FileBasedConfig;
62 import org.eclipse.jgit.storage.pack.PackConfig;
63 import org.junit.Test;
64 import org.junit.experimental.theories.DataPoints;
65 import org.junit.experimental.theories.Theories;
66 import org.junit.experimental.theories.Theory;
67 import org.junit.runner.RunWith;
68
69 @RunWith(Theories.class)
70 public class GcBasicPackingTest extends GcTestCase {
71 @DataPoints
72 public static boolean[] aggressiveValues = { true, false };
73
74 @Theory
75 public void repackEmptyRepo_noPackCreated(boolean aggressive)
76 throws IOException {
77 configureGc(gc, aggressive);
78 gc.repack();
79 assertEquals(0, repo.getObjectDatabase().getPacks().size());
80 }
81
82 @Theory
83 public void testPackRepoWithNoRefs(boolean aggressive) throws Exception {
84 tr.commit().add("A", "A").add("B", "B").create();
85 stats = gc.getStatistics();
86 assertEquals(4, stats.numberOfLooseObjects);
87 assertEquals(0, stats.numberOfPackedObjects);
88 configureGc(gc, aggressive);
89 gc.gc();
90 stats = gc.getStatistics();
91 assertEquals(4, stats.numberOfLooseObjects);
92 assertEquals(0, stats.numberOfPackedObjects);
93 assertEquals(0, stats.numberOfPackFiles);
94 assertEquals(0, stats.numberOfBitmaps);
95 }
96
97 @Theory
98 public void testPack2Commits(boolean aggressive) throws Exception {
99 BranchBuilder bb = tr.branch("refs/heads/master");
100 bb.commit().add("A", "A").add("B", "B").create();
101 bb.commit().add("A", "A2").add("B", "B2").create();
102
103 stats = gc.getStatistics();
104 assertEquals(8, stats.numberOfLooseObjects);
105 assertEquals(0, stats.numberOfPackedObjects);
106 configureGc(gc, aggressive);
107 gc.gc();
108 stats = gc.getStatistics();
109 assertEquals(0, stats.numberOfLooseObjects);
110 assertEquals(8, stats.numberOfPackedObjects);
111 assertEquals(1, stats.numberOfPackFiles);
112 assertEquals(2, stats.numberOfBitmaps);
113 }
114
115 @Theory
116 public void testPackAllObjectsInOnePack(boolean aggressive)
117 throws Exception {
118 tr.branch("refs/heads/master").commit().add("A", "A").add("B", "B")
119 .create();
120 stats = gc.getStatistics();
121 assertEquals(4, stats.numberOfLooseObjects);
122 assertEquals(0, stats.numberOfPackedObjects);
123 configureGc(gc, aggressive);
124 gc.gc();
125 stats = gc.getStatistics();
126 assertEquals(0, stats.numberOfLooseObjects);
127 assertEquals(4, stats.numberOfPackedObjects);
128 assertEquals(1, stats.numberOfPackFiles);
129 assertEquals(1, stats.numberOfBitmaps);
130
131
132 gc.gc();
133 stats = gc.getStatistics();
134 assertEquals(0, stats.numberOfLooseObjects);
135 assertEquals(4, stats.numberOfPackedObjects);
136 assertEquals(1, stats.numberOfPackFiles);
137 assertEquals(1, stats.numberOfBitmaps);
138 }
139
140 @Theory
141 public void testPackCommitsAndLooseOne(boolean aggressive)
142 throws Exception {
143 BranchBuilder bb = tr.branch("refs/heads/master");
144 RevCommit first = bb.commit().add("A", "A").add("B", "B").create();
145 bb.commit().add("A", "A2").add("B", "B2").create();
146 tr.update("refs/heads/master", first);
147
148 stats = gc.getStatistics();
149 assertEquals(8, stats.numberOfLooseObjects);
150 assertEquals(0, stats.numberOfPackedObjects);
151 configureGc(gc, aggressive);
152 gc.gc();
153 stats = gc.getStatistics();
154 assertEquals(0, stats.numberOfLooseObjects);
155 assertEquals(8, stats.numberOfPackedObjects);
156 assertEquals(2, stats.numberOfPackFiles);
157 assertEquals(1, stats.numberOfBitmaps);
158 }
159
160 @Theory
161 public void testNotPackTwice(boolean aggressive) throws Exception {
162 BranchBuilder bb = tr.branch("refs/heads/master");
163 RevCommit first = bb.commit().message("M").add("M", "M").create();
164 bb.commit().message("B").add("B", "Q").create();
165 bb.commit().message("A").add("A", "A").create();
166 RevCommit second = tr.commit().parent(first).message("R").add("R", "Q")
167 .create();
168 tr.update("refs/tags/t1", second);
169
170 Collection<PackFile> oldPacks = tr.getRepository().getObjectDatabase()
171 .getPacks();
172 assertEquals(0, oldPacks.size());
173 stats = gc.getStatistics();
174 assertEquals(11, stats.numberOfLooseObjects);
175 assertEquals(0, stats.numberOfPackedObjects);
176
177 gc.setExpireAgeMillis(0);
178 fsTick();
179 configureGc(gc, aggressive);
180 gc.gc();
181 stats = gc.getStatistics();
182 assertEquals(0, stats.numberOfLooseObjects);
183
184 List<PackFile> packs = new ArrayList<>(
185 repo.getObjectDatabase().getPacks());
186 assertEquals(11, packs.get(0).getObjectCount());
187 }
188
189 @Test
190 public void testDonePruneTooYoungPacks() throws Exception {
191 BranchBuilder bb = tr.branch("refs/heads/master");
192 bb.commit().message("M").add("M", "M").create();
193
194 String tempRef = "refs/heads/soon-to-be-unreferenced";
195 BranchBuilder bb2 = tr.branch(tempRef);
196 bb2.commit().message("M").add("M", "M").create();
197
198 gc.setExpireAgeMillis(0);
199 gc.gc();
200 stats = gc.getStatistics();
201 assertEquals(0, stats.numberOfLooseObjects);
202 assertEquals(4, stats.numberOfPackedObjects);
203 assertEquals(1, stats.numberOfPackFiles);
204 File oldPackfile = tr.getRepository().getObjectDatabase().getPacks()
205 .iterator().next().getPackFile();
206
207 fsTick();
208
209
210 RefUpdate update = tr.getRepository().getRefDatabase().newUpdate(tempRef, false);
211 update.setForceUpdate(true);
212 update.delete();
213
214 bb.commit().message("B").add("B", "Q").create();
215
216
217
218 gc.setExpire(new Date(oldPackfile.lastModified() - 1));
219 gc.gc();
220 stats = gc.getStatistics();
221 assertEquals(0, stats.numberOfLooseObjects);
222
223
224 assertEquals(10, stats.numberOfPackedObjects);
225 assertEquals(2, stats.numberOfPackFiles);
226
227
228
229 gc.setExpireAgeMillis(0);
230 gc.gc();
231 stats = gc.getStatistics();
232 assertEquals(0, stats.numberOfLooseObjects);
233
234
235 assertEquals(10, stats.numberOfPackedObjects);
236 assertEquals(2, stats.numberOfPackFiles);
237
238
239
240 gc.setPackExpireAgeMillis(0);
241
242
243 gc.setExpireAgeMillis(-1);
244
245 gc.gc();
246 stats = gc.getStatistics();
247 assertEquals(1, stats.numberOfLooseObjects);
248
249
250 assertEquals(6, stats.numberOfPackedObjects);
251 assertEquals(1, stats.numberOfPackFiles);
252 }
253
254 @Test
255 public void testImmediatePruning() throws Exception {
256 BranchBuilder bb = tr.branch("refs/heads/master");
257 bb.commit().message("M").add("M", "M").create();
258
259 String tempRef = "refs/heads/soon-to-be-unreferenced";
260 BranchBuilder bb2 = tr.branch(tempRef);
261 bb2.commit().message("M").add("M", "M").create();
262
263 gc.setExpireAgeMillis(0);
264 gc.gc();
265 stats = gc.getStatistics();
266
267 fsTick();
268
269
270 RefUpdate update = tr.getRepository().getRefDatabase().newUpdate(tempRef, false);
271 update.setForceUpdate(true);
272 update.delete();
273
274 bb.commit().message("B").add("B", "Q").create();
275
276
277 FileBasedConfig config = repo.getConfig();
278 config.setString(ConfigConstants.CONFIG_GC_SECTION, null,
279 ConfigConstants.CONFIG_KEY_PRUNEEXPIRE, "now");
280 config.save();
281
282
283 gc.setPackExpireAgeMillis(0);
284
285 gc.gc();
286 stats = gc.getStatistics();
287 assertEquals(0, stats.numberOfLooseObjects);
288 assertEquals(6, stats.numberOfPackedObjects);
289 assertEquals(1, stats.numberOfPackFiles);
290 }
291
292 @Test
293 public void testPreserveAndPruneOldPacks() throws Exception {
294 testPreserveOldPacks();
295 configureGc(gc, false).setPrunePreserved(true);
296 gc.gc();
297
298 assertFalse(repo.getObjectDatabase().getPreservedDirectory().exists());
299 }
300
301 private void testPreserveOldPacks() throws Exception {
302 BranchBuilder bb = tr.branch("refs/heads/master");
303 bb.commit().message("P").add("P", "P").create();
304
305
306 gc.setExpireAgeMillis(0);
307 gc.gc();
308 File oldPackfile = tr.getRepository().getObjectDatabase().getPacks()
309 .iterator().next().getPackFile();
310 assertTrue(oldPackfile.exists());
311
312 fsTick();
313 bb.commit().message("B").add("B", "Q").create();
314
315
316
317
318 gc.setPackExpireAgeMillis(0);
319 configureGc(gc, false).setPreserveOldPacks(true);
320 gc.gc();
321
322 File oldPackDir = repo.getObjectDatabase().getPreservedDirectory();
323 String oldPackFileName = oldPackfile.getName();
324 String oldPackName = oldPackFileName.substring(0,
325 oldPackFileName.lastIndexOf('.')) + ".old-pack";
326 File preservePackFile = new File(oldPackDir, oldPackName);
327 assertTrue(preservePackFile.exists());
328 }
329
330 private PackConfig configureGc(GC myGc, boolean aggressive) {
331 PackConfig pconfig = new PackConfig(repo);
332 if (aggressive) {
333 pconfig.setDeltaSearchWindowSize(250);
334 pconfig.setMaxDeltaDepth(250);
335 pconfig.setReuseObjects(false);
336 } else
337 pconfig = new PackConfig(repo);
338 myGc.setPackConfig(pconfig);
339 return pconfig;
340 }
341 }