1
2
3
4
5
6
7
8
9
10
11
12
13
14 package org.eclipse.jgit.junit;
15
16 import static java.nio.charset.StandardCharsets.UTF_8;
17 import static org.junit.Assert.assertEquals;
18
19 import java.io.File;
20 import java.io.FileInputStream;
21 import java.io.FileNotFoundException;
22 import java.io.FileOutputStream;
23 import java.io.IOException;
24 import java.io.InputStreamReader;
25 import java.io.Reader;
26 import java.nio.file.Path;
27 import java.time.Instant;
28 import java.util.Map;
29 import java.util.concurrent.TimeUnit;
30
31 import org.eclipse.jgit.api.Git;
32 import org.eclipse.jgit.api.errors.GitAPIException;
33 import org.eclipse.jgit.dircache.DirCacheBuilder;
34 import org.eclipse.jgit.dircache.DirCacheCheckout;
35 import org.eclipse.jgit.dircache.DirCacheEntry;
36 import org.eclipse.jgit.internal.storage.file.FileRepository;
37 import org.eclipse.jgit.lib.Constants;
38 import org.eclipse.jgit.lib.FileMode;
39 import org.eclipse.jgit.lib.ObjectId;
40 import org.eclipse.jgit.lib.ObjectInserter;
41 import org.eclipse.jgit.lib.RefUpdate;
42 import org.eclipse.jgit.lib.Repository;
43 import org.eclipse.jgit.revwalk.RevCommit;
44 import org.eclipse.jgit.revwalk.RevWalk;
45 import org.eclipse.jgit.treewalk.FileTreeIterator;
46 import org.eclipse.jgit.util.FS;
47 import org.eclipse.jgit.util.FileUtils;
48 import org.junit.Before;
49
50
51
52
53
54
55
56 public abstract class RepositoryTestCase extends LocalDiskRepositoryTestCase {
57
58
59
60
61
62
63
64 protected static void copyFile(File src, File dst)
65 throws IOException {
66 try (FileInputStream fis = new FileInputStream(src);
67 FileOutputStream fos = new FileOutputStream(dst)) {
68 final byte[] buf = new byte[4096];
69 int r;
70 while ((r = fis.read(buf)) > 0) {
71 fos.write(buf, 0, r);
72 }
73 }
74 }
75
76
77
78
79
80
81
82
83
84 protected File writeTrashFile(String name, String data)
85 throws IOException {
86 return JGitTestUtil.writeTrashFile(db, name, data);
87 }
88
89
90
91
92
93
94
95
96
97
98
99
100 protected Path writeLink(String link, String target)
101 throws Exception {
102 return JGitTestUtil.writeLink(db, link, target);
103 }
104
105
106
107
108
109
110
111
112
113
114 protected File writeTrashFile(final String subdir, final String name,
115 final String data)
116 throws IOException {
117 return JGitTestUtil.writeTrashFile(db, subdir, name, data);
118 }
119
120
121
122
123
124
125
126
127 protected String read(String name) throws IOException {
128 return JGitTestUtil.read(db, name);
129 }
130
131
132
133
134
135
136
137
138 protected boolean check(String name) {
139 return JGitTestUtil.check(db, name);
140 }
141
142
143
144
145
146
147
148
149 protected void deleteTrashFile(String name) throws IOException {
150 JGitTestUtil.deleteTrashFile(db, name);
151 }
152
153
154
155
156
157
158
159
160
161 protected static void checkFile(File f, String checkData)
162 throws IOException {
163 try (Reader r = new InputStreamReader(new FileInputStream(f),
164 UTF_8)) {
165 if (checkData.length() > 0) {
166 char[] data = new char[checkData.length()];
167 assertEquals(data.length, r.read(data));
168 assertEquals(checkData, new String(data));
169 }
170 assertEquals(-1, r.read());
171 }
172 }
173
174
175 protected FileRepository db;
176
177
178 protected File trash;
179
180
181 @Override
182 @Before
183 public void setUp() throws Exception {
184 super.setUp();
185 db = createWorkRepository();
186 trash = db.getWorkTree();
187 }
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224 public String indexState(int includedOptions)
225 throws IllegalStateException, IOException {
226 return indexState(db, includedOptions);
227 }
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245 protected void resetIndex(FileTreeIterator treeItr)
246 throws FileNotFoundException, IOException {
247 try (ObjectInserter inserter = db.newObjectInserter()) {
248 DirCacheBuilder builder = db.lockDirCache().builder();
249 DirCacheEntry dce;
250
251 while (!treeItr.eof()) {
252 long len = treeItr.getEntryLength();
253
254 dce = new DirCacheEntry(treeItr.getEntryPathString());
255 dce.setFileMode(treeItr.getEntryFileMode());
256 dce.setLastModified(treeItr.getEntryLastModifiedInstant());
257 dce.setLength((int) len);
258 try (FileInputStream in = new FileInputStream(
259 treeItr.getEntryFile())) {
260 dce.setObjectId(
261 inserter.insert(Constants.OBJ_BLOB, len, in));
262 }
263 builder.add(dce);
264 treeItr.next(1);
265 }
266 builder.commit();
267 inserter.flush();
268 }
269 }
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292 public static String lookup(Object l, String nameTemplate,
293 Map<Object, String> lookupTable) {
294 String name = lookupTable.get(l);
295 if (name == null) {
296 name = nameTemplate.replaceAll("%n",
297 Integer.toString(lookupTable.size()));
298 lookupTable.put(l, name);
299 }
300 return name;
301 }
302
303
304
305
306
307
308
309
310
311 public static String slashify(String str) {
312 str = str.replace('\\', '/');
313 return str;
314 }
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333 public static Instant fsTick(File lastFile)
334 throws InterruptedException,
335 IOException {
336 File tmp;
337 FS fs = FS.DETECTED;
338 if (lastFile == null) {
339 lastFile = tmp = File
340 .createTempFile("fsTickTmpFile", null);
341 } else {
342 if (!fs.exists(lastFile)) {
343 throw new FileNotFoundException(lastFile.getPath());
344 }
345 tmp = File.createTempFile("fsTickTmpFile", null,
346 lastFile.getParentFile());
347 }
348 long res = FS.getFileStoreAttributes(tmp.toPath())
349 .getFsTimestampResolution().toNanos();
350 long sleepTime = res / 10;
351 try {
352 Instant startTime = fs.lastModifiedInstant(lastFile);
353 Instant actTime = fs.lastModifiedInstant(tmp);
354 while (actTime.compareTo(startTime) <= 0) {
355 TimeUnit.NANOSECONDS.sleep(sleepTime);
356 FileUtils.touch(tmp.toPath());
357 actTime = fs.lastModifiedInstant(tmp);
358 }
359 return actTime;
360 } finally {
361 FileUtils.delete(tmp);
362 }
363 }
364
365
366
367
368
369
370
371
372 protected void createBranch(ObjectId objectId, String branchName)
373 throws IOException {
374 RefUpdate updateRef = db.updateRef(branchName);
375 updateRef.setNewObjectId(objectId);
376 updateRef.update();
377 }
378
379
380
381
382
383
384
385
386 protected void checkoutBranch(String branchName)
387 throws IllegalStateException, IOException {
388 try (RevWalk walk = new RevWalk(db)) {
389 RevCommit head = walk.parseCommit(db.resolve(Constants.HEAD));
390 RevCommit branch = walk.parseCommit(db.resolve(branchName));
391 DirCacheCheckout dco = new DirCacheCheckout(db,
392 head.getTree().getId(), db.lockDirCache(),
393 branch.getTree().getId());
394 dco.setFailOnConflict(true);
395 dco.checkout();
396 }
397
398 RefUpdate refUpdate = db.updateRef(Constants.HEAD);
399 refUpdate.setRefLogMessage("checkout: moving to " + branchName, false);
400 refUpdate.link(branchName);
401 }
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419 protected File writeTrashFiles(boolean ensureDistinctTimestamps,
420 String... contents)
421 throws IOException, InterruptedException {
422 File f = null;
423 for (int i = 0; i < contents.length; i++)
424 if (contents[i] != null) {
425 if (ensureDistinctTimestamps && (f != null))
426 fsTick(f);
427 f = writeTrashFile(Integer.toString(i), contents[i]);
428 }
429 return f;
430 }
431
432
433
434
435
436
437
438
439
440
441
442
443
444 protected RevCommit commitFile(String filename, String contents, String branch) {
445 try (Git git = new Git(db)) {
446 Repository repo = git.getRepository();
447 String originalBranch = repo.getFullBranch();
448 boolean empty = repo.resolve(Constants.HEAD) == null;
449 if (!empty) {
450 if (repo.findRef(branch) == null)
451 git.branchCreate().setName(branch).call();
452 git.checkout().setName(branch).call();
453 }
454
455 writeTrashFile(filename, contents);
456 git.add().addFilepattern(filename).call();
457 RevCommit commit = git.commit()
458 .setMessage(branch + ": " + filename).call();
459
460 if (originalBranch != null)
461 git.checkout().setName(originalBranch).call();
462 else if (empty)
463 git.branchCreate().setName(branch).setStartPoint(commit).call();
464
465 return commit;
466 } catch (IOException | GitAPIException e) {
467 throw new RuntimeException(e);
468 }
469 }
470
471
472
473
474
475
476
477
478 protected DirCacheEntry createEntry(String path, FileMode mode) {
479 return createEntry(path, mode, DirCacheEntry.STAGE_0, path);
480 }
481
482
483
484
485
486
487
488
489
490 protected DirCacheEntry createEntry(final String path, final FileMode mode,
491 final String content) {
492 return createEntry(path, mode, DirCacheEntry.STAGE_0, content);
493 }
494
495
496
497
498
499
500
501
502
503
504 protected DirCacheEntry createEntry(final String path, final FileMode mode,
505 final int stage, final String content) {
506 final DirCacheEntry entry = new DirCacheEntry(path, stage);
507 entry.setFileMode(mode);
508 try (ObjectInserter.Formatter formatter = new ObjectInserter.Formatter()) {
509 entry.setObjectId(formatter.idFor(
510 Constants.OBJ_BLOB, Constants.encode(content)));
511 }
512 return entry;
513 }
514
515
516
517
518
519
520
521
522 public static void assertEqualsFile(File expected, File actual)
523 throws IOException {
524 assertEquals(expected.getCanonicalFile(), actual.getCanonicalFile());
525 }
526 }