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 package org.eclipse.jgit.internal.storage.file;
44
45 import static org.junit.Assert.assertFalse;
46 import static org.junit.Assert.assertTrue;
47
48 import java.io.File;
49 import java.io.FilenameFilter;
50 import java.io.IOException;
51 import java.io.PrintWriter;
52 import java.text.MessageFormat;
53 import java.util.Collection;
54 import java.util.Collections;
55 import java.util.Set;
56 import java.util.concurrent.Callable;
57 import java.util.concurrent.ExecutorService;
58 import java.util.concurrent.Executors;
59 import java.util.concurrent.Future;
60
61 import org.eclipse.jgit.internal.JGitText;
62 import org.eclipse.jgit.junit.RepositoryTestCase;
63 import org.eclipse.jgit.lib.ConfigConstants;
64 import org.eclipse.jgit.lib.Constants;
65 import org.eclipse.jgit.lib.ObjectId;
66 import org.eclipse.jgit.revwalk.RevCommit;
67 import org.eclipse.jgit.storage.file.FileBasedConfig;
68 import org.eclipse.jgit.util.FS;
69 import org.junit.Assume;
70 import org.junit.Rule;
71 import org.junit.Test;
72 import org.junit.rules.ExpectedException;
73
74 public class ObjectDirectoryTest extends RepositoryTestCase {
75
76 @Rule
77 public ExpectedException expectedEx = ExpectedException.none();
78
79 @Test
80 public void testConcurrentInsertionOfBlobsToTheSameNewFanOutDirectory()
81 throws Exception {
82 ExecutorService e = Executors.newCachedThreadPool();
83 for (int i=0; i < 100; ++i) {
84 ObjectDirectory dir = createBareRepository().getObjectDatabase();
85 for (Future f : e.invokeAll(blobInsertersForTheSameFanOutDir(dir))) {
86 f.get();
87 }
88 }
89 }
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106 @Test
107 public void testScanningForPackfiles() throws Exception {
108 ObjectId unknownID = ObjectId
109 .fromString("c0ffee09d0b63d694bf49bc1e6847473f42d4a8c");
110 GC gc = new GC(db);
111 gc.setExpireAgeMillis(0);
112 gc.setPackExpireAgeMillis(0);
113
114
115
116 try (FileRepository receivingDB = new FileRepository(
117 db.getDirectory())) {
118
119
120 FileBasedConfig cfg = receivingDB.getConfig();
121 cfg.setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null,
122 ConfigConstants.CONFIG_KEY_TRUSTFOLDERSTAT, true);
123 cfg.save();
124
125
126
127 ObjectId id = commitFile("file.txt", "test", "master").getId();
128 gc.gc();
129 assertFalse(receivingDB.hasObject(unknownID));
130 assertTrue(receivingDB.getObjectDatabase().hasPackedObject(id));
131
132
133 File packsFolder = receivingDB.getObjectDatabase()
134 .getPackDirectory();
135
136
137
138 File tmpFile = new File(packsFolder, "1.tmp");
139 RevCommit id2 = commitFile("file.txt", "test2", "master");
140
141
142
143 fsTick(null);
144
145
146
147
148
149
150
151
152 assertTrue(tmpFile.createNewFile());
153 assertFalse(receivingDB.hasObject(unknownID));
154
155
156
157 gc.gc();
158
159
160
161
162
163
164
165
166
167
168
169 Thread.sleep(2600);
170
171 File[] ret = packsFolder.listFiles(new FilenameFilter() {
172 @Override
173 public boolean accept(File dir, String name) {
174 return name.endsWith(".pack");
175 }
176 });
177 assertTrue(ret != null && ret.length == 1);
178 FS fs = db.getFS();
179 Assume.assumeTrue(fs.lastModifiedInstant(tmpFile)
180 .equals(fs.lastModifiedInstant(ret[0])));
181
182
183 assertFalse(receivingDB.hasObject(unknownID));
184 assertTrue(receivingDB.hasObject(id2));
185 }
186 }
187
188 @Test
189 public void testShallowFile()
190 throws Exception {
191 FileRepository repository = createBareRepository();
192 ObjectDirectory dir = repository.getObjectDatabase();
193
194 String commit = "d3148f9410b071edd4a4c85d2a43d1fa2574b0d2";
195 try (PrintWriter writer = new PrintWriter(
196 new File(repository.getDirectory(), Constants.SHALLOW))) {
197 writer.println(commit);
198 }
199 Set<ObjectId> shallowCommits = dir.getShallowCommits();
200 assertTrue(shallowCommits.remove(ObjectId.fromString(commit)));
201 assertTrue(shallowCommits.isEmpty());
202 }
203
204 @Test
205 public void testShallowFileCorrupt()
206 throws Exception {
207 FileRepository repository = createBareRepository();
208 ObjectDirectory dir = repository.getObjectDatabase();
209
210 String commit = "X3148f9410b071edd4a4c85d2a43d1fa2574b0d2";
211 try (PrintWriter writer = new PrintWriter(
212 new File(repository.getDirectory(), Constants.SHALLOW))) {
213 writer.println(commit);
214 }
215
216 expectedEx.expect(IOException.class);
217 expectedEx.expectMessage(MessageFormat
218 .format(JGitText.get().badShallowLine, commit));
219 dir.getShallowCommits();
220 }
221
222 private Collection<Callable<ObjectId>> blobInsertersForTheSameFanOutDir(
223 final ObjectDirectory dir) {
224 Callable<ObjectId> callable = new Callable<ObjectId>() {
225 @Override
226 public ObjectId call() throws Exception {
227 return dir.newInserter().insert(Constants.OBJ_BLOB, new byte[0]);
228 }
229 };
230 return Collections.nCopies(4, callable);
231 }
232
233 }