View Javadoc
1   /*
2    * Copyright (C) 2012, Christian Halstrick <christian.halstrick@sap.com> and others
3    *
4    * This program and the accompanying materials are made available under the
5    * terms of the Eclipse Distribution License v. 1.0 which is available at
6    * https://www.eclipse.org/org/documents/edl-v10.php.
7    *
8    * SPDX-License-Identifier: BSD-3-Clause
9    */
10  
11  package org.eclipse.jgit.internal.storage.file;
12  
13  import java.io.IOException;
14  
15  import org.eclipse.jgit.internal.storage.file.GC.RepoStatistics;
16  import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase;
17  import org.eclipse.jgit.junit.RepositoryTestCase;
18  import org.eclipse.jgit.junit.TestRepository;
19  import org.eclipse.jgit.junit.TestRepository.CommitBuilder;
20  import org.eclipse.jgit.lib.AnyObjectId;
21  import org.eclipse.jgit.revwalk.RevCommit;
22  import org.eclipse.jgit.revwalk.RevWalk;
23  import org.junit.After;
24  import org.junit.Before;
25  
26  public abstract class GcTestCase extends LocalDiskRepositoryTestCase {
27  	protected TestRepository<FileRepository> tr;
28  	protected FileRepository repo;
29  	protected GC gc;
30  	protected RepoStatistics stats;
31  
32  	@Override
33  	@Before
34  	public void setUp() throws Exception {
35  		super.setUp();
36  		repo = createWorkRepository();
37  		tr = new TestRepository<>(repo, new RevWalk(repo),
38  				mockSystemReader);
39  		gc = new GC(repo);
40  	}
41  
42  	@Override
43  	@After
44  	public void tearDown() throws Exception {
45  		super.tearDown();
46  	}
47  
48  	/**
49  	 * Create a chain of commits of given depth.
50  	 * <p>
51  	 * Each commit contains one file named "a" containing the index of the
52  	 * commit in the chain as its content. The created commit chain is
53  	 * referenced from any ref.
54  	 * <p>
55  	 * A chain of depth = N will create 3*N objects in Gits object database. For
56  	 * each depth level three objects are created: the commit object, the
57  	 * top-level tree object and a blob for the content of the file "a".
58  	 *
59  	 * @param depth
60  	 *            the depth of the commit chain.
61  	 * @return the commit that is the tip of the commit chain
62  	 * @throws Exception
63  	 */
64  	protected RevCommit commitChain(int depth) throws Exception {
65  		if (depth <= 0)
66  			throw new IllegalArgumentException("Chain depth must be > 0");
67  		CommitBuilder cb = tr.commit();
68  		RevCommit tip;
69  		do {
70  			--depth;
71  			tip = cb.add("a", "" + depth).message("" + depth).create();
72  			cb = cb.child();
73  		} while (depth > 0);
74  		return tip;
75  	}
76  
77  	/**
78  	 * Create a chain of commits of given depth with given number of added files
79  	 * per commit.
80  	 * <p>
81  	 * Each commit contains {@code files} files as its content. The created
82  	 * commit chain is referenced from any ref.
83  	 * <p>
84  	 * A chain will create {@code (2 + files) * depth} objects in Gits object
85  	 * database. For each depth level the following objects are created: the
86  	 * commit object, the top-level tree object and @code files} blobs for the
87  	 * content of the file "a".
88  	 *
89  	 * @param depth
90  	 *            the depth of the commit chain.
91  	 * @param width
92  	 *            number of files added per commit
93  	 * @return the commit that is the tip of the commit chain
94  	 * @throws Exception
95  	 */
96  	protected RevCommit commitChain(int depth, int width) throws Exception {
97  		if (depth <= 0) {
98  			throw new IllegalArgumentException("Chain depth must be > 0");
99  		}
100 		if (width <= 0) {
101 			throw new IllegalArgumentException("Number of files per commit must be > 0");
102 		}
103 		CommitBuilder cb = tr.commit();
104 		RevCommit tip = null;
105 		do {
106 			--depth;
107 			for (int i=0; i < width; i++) {
108 				String id = depth + "-" + i;
109 				cb.add("a" + id, id).message(id);
110 			}
111 			tip = cb.create();
112 			cb = cb.child();
113 		} while (depth > 0);
114 		return tip;
115 	}
116 
117 	protected long lastModified(AnyObjectId objectId) {
118 		return repo.getFS()
119 				.lastModifiedInstant(repo.getObjectDatabase().fileFor(objectId))
120 				.toEpochMilli();
121 	}
122 
123 	protected static void fsTick() throws InterruptedException, IOException {
124 		RepositoryTestCase.fsTick(null);
125 	}
126 }