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  		tr.close();
46  		super.tearDown();
47  	}
48  
49  	/**
50  	 * Create a chain of commits of given depth.
51  	 * <p>
52  	 * Each commit contains one file named "a" containing the index of the
53  	 * commit in the chain as its content. The created commit chain is
54  	 * referenced from any ref.
55  	 * <p>
56  	 * A chain of depth = N will create 3*N objects in Gits object database. For
57  	 * each depth level three objects are created: the commit object, the
58  	 * top-level tree object and a blob for the content of the file "a".
59  	 *
60  	 * @param depth
61  	 *            the depth of the commit chain.
62  	 * @return the commit that is the tip of the commit chain
63  	 * @throws Exception
64  	 */
65  	protected RevCommit commitChain(int depth) throws Exception {
66  		if (depth <= 0)
67  			throw new IllegalArgumentException("Chain depth must be > 0");
68  		CommitBuilder cb = tr.commit();
69  		RevCommit tip;
70  		do {
71  			--depth;
72  			tip = cb.add("a", "" + depth).message("" + depth).create();
73  			cb = cb.child();
74  		} while (depth > 0);
75  		return tip;
76  	}
77  
78  	/**
79  	 * Create a chain of commits of given depth with given number of added files
80  	 * per commit.
81  	 * <p>
82  	 * Each commit contains {@code files} files as its content. The created
83  	 * commit chain is referenced from any ref.
84  	 * <p>
85  	 * A chain will create {@code (2 + files) * depth} objects in Gits object
86  	 * database. For each depth level the following objects are created: the
87  	 * commit object, the top-level tree object and @code files} blobs for the
88  	 * content of the file "a".
89  	 *
90  	 * @param depth
91  	 *            the depth of the commit chain.
92  	 * @param width
93  	 *            number of files added per commit
94  	 * @return the commit that is the tip of the commit chain
95  	 * @throws Exception
96  	 */
97  	protected RevCommit commitChain(int depth, int width) throws Exception {
98  		if (depth <= 0) {
99  			throw new IllegalArgumentException("Chain depth must be > 0");
100 		}
101 		if (width <= 0) {
102 			throw new IllegalArgumentException("Number of files per commit must be > 0");
103 		}
104 		CommitBuilder cb = tr.commit();
105 		RevCommit tip = null;
106 		do {
107 			--depth;
108 			for (int i=0; i < width; i++) {
109 				String id = depth + "-" + i;
110 				cb.add("a" + id, id).message(id);
111 			}
112 			tip = cb.create();
113 			cb = cb.child();
114 		} while (depth > 0);
115 		return tip;
116 	}
117 
118 	protected long lastModified(AnyObjectId objectId) {
119 		return repo.getFS()
120 				.lastModifiedInstant(repo.getObjectDatabase().fileFor(objectId))
121 				.toEpochMilli();
122 	}
123 
124 	protected static void fsTick() throws InterruptedException, IOException {
125 		RepositoryTestCase.fsTick(null);
126 	}
127 }