
org.eclipse.jgit.junit.RepositoryTestCase Maven / Gradle / Ivy
Show all versions of org.eclipse.jgit.junit Show documentation
/*
* Copyright (C) 2009, Google Inc.
* Copyright (C) 2007-2008, Robin Rosenberg
* Copyright (C) 2006-2007, Shawn O. Pearce
* Copyright (C) 2009, Yann Simon and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0 which is available at
* https://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.junit;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.junit.Assert.assertEquals;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.file.Path;
import java.time.Instant;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.dircache.DirCacheBuilder;
import org.eclipse.jgit.dircache.DirCacheCheckout;
import org.eclipse.jgit.dircache.DirCacheEntry;
import org.eclipse.jgit.internal.storage.file.FileRepository;
import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.FileMode;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectInserter;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.RefUpdate;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.treewalk.FileTreeIterator;
import org.eclipse.jgit.util.FS;
import org.eclipse.jgit.util.FileUtils;
import org.junit.After;
import org.junit.Before;
/**
* Base class for most JGit unit tests.
*
* Sets up a predefined test repository and has support for creating additional
* repositories and destroying them when the tests are finished.
*/
public abstract class RepositoryTestCase extends LocalDiskRepositoryTestCase {
/**
* Copy a file
*
* @param src
* file to copy
* @param dst
* destination of the copy
* @throws IOException
* if an IO error occurred
*/
protected static void copyFile(File src, File dst)
throws IOException {
try (FileInputStream fis = new FileInputStream(src);
FileOutputStream fos = new FileOutputStream(dst)) {
final byte[] buf = new byte[4096];
int r;
while ((r = fis.read(buf)) > 0) {
fos.write(buf, 0, r);
}
}
}
/**
* Write a trash file
*
* @param name
* file name
* @param data
* file content
* @return the trash file
* @throws IOException
* if an IO error occurred
*/
protected File writeTrashFile(String name, String data)
throws IOException {
return JGitTestUtil.writeTrashFile(db, name, data);
}
/**
* Create a symbolic link
*
* @param link
* the path of the symbolic link to create
* @param target
* the target of the symbolic link
* @return the path to the symbolic link
* @throws Exception
* if an error occurred
* @since 4.2
*/
protected Path writeLink(String link, String target)
throws Exception {
return JGitTestUtil.writeLink(db, link, target);
}
/**
* Write a trash file
*
* @param subdir
* in working tree
* @param name
* file name
* @param data
* file content
* @return the trash file
* @throws IOException
* if an IO error occurred
*/
protected File writeTrashFile(final String subdir, final String name,
final String data)
throws IOException {
return JGitTestUtil.writeTrashFile(db, subdir, name, data);
}
/**
* Read content of a file
*
* @param name
* file name
* @return the file's content
* @throws IOException
* if an IO error occurred
*/
protected String read(String name) throws IOException {
return JGitTestUtil.read(db, name);
}
/**
* Check if file exists
*
* @param name
* file name
* @return if the file exists
*/
protected boolean check(String name) {
return JGitTestUtil.check(db, name);
}
/**
* Delete a trash file
*
* @param name
* file name
* @throws IOException
* if an IO error occurred
*/
protected void deleteTrashFile(String name) throws IOException {
JGitTestUtil.deleteTrashFile(db, name);
}
/**
* Check content of a file.
*
* @param f
* file
* @param checkData
* expected content
* @throws IOException
* if an IO error occurred
*/
protected static void checkFile(File f, String checkData)
throws IOException {
try (Reader r = new InputStreamReader(new FileInputStream(f),
UTF_8)) {
if (checkData.length() > 0) {
char[] data = new char[checkData.length()];
assertEquals(data.length, r.read(data));
assertEquals(checkData, new String(data));
}
assertEquals(-1, r.read());
}
}
/** Test repository, initialized for this test case. */
protected FileRepository db;
/** Working directory of {@link #db}. */
protected File trash;
@Override
@Before
public void setUp() throws Exception {
super.setUp();
db = createWorkRepository();
trash = db.getWorkTree();
}
@Override
@After
public void tearDown() throws Exception {
db.close();
super.tearDown();
}
/**
* Represent the state of the index in one String. This representation is
* useful when writing tests which do assertions on the state of the index.
* By default information about path, mode, stage (if different from 0) is
* included. A bitmask controls which additional info about
* modificationTimes, smudge state and length is included.
*
* The format of the returned string is described with this BNF:
*
*
* result = ( "[" path mode stage? time? smudge? length? sha1? content? "]" )* .
* mode = ", mode:" number .
* stage = ", stage:" number .
* time = ", time:t" timestamp-index .
* smudge = "" | ", smudged" .
* length = ", length:" number .
* sha1 = ", sha1:" hex-sha1 .
* content = ", content:" blob-data .
*
*
* 'stage' is only presented when the stage is different from 0. All
* reported time stamps are mapped to strings like "t0", "t1", ... "tn". The
* smallest reported time-stamp will be called "t0". This allows to write
* assertions against the string although the concrete value of the time
* stamps is unknown.
*
* @param includedOptions
* a bitmask constructed out of the constants {@link #MOD_TIME},
* {@link #SMUDGE}, {@link #LENGTH}, {@link #CONTENT_ID} and
* {@link #CONTENT} controlling which info is present in the
* resulting string.
* @return a string encoding the index state
* @throws IOException
* if an IO error occurred
*/
public String indexState(int includedOptions)
throws IOException {
return indexState(db, includedOptions);
}
/**
* Resets the index to represent exactly some filesystem content. E.g. the
* following call will replace the index with the working tree content:
*
* resetIndex(new FileSystemIterator(db))
*
* This method can be used by testcases which first prepare a new commit
* somewhere in the filesystem (e.g. in the working-tree) and then want to
* have an index which matches their prepared content.
*
* @param treeItr
* a {@link org.eclipse.jgit.treewalk.FileTreeIterator} which
* determines which files should go into the new index
* @throws FileNotFoundException
* file was not found
* @throws IOException
* if an IO error occurred
*/
protected void resetIndex(FileTreeIterator treeItr)
throws FileNotFoundException, IOException {
try (ObjectInserter inserter = db.newObjectInserter()) {
DirCacheBuilder builder = db.lockDirCache().builder();
DirCacheEntry dce;
while (!treeItr.eof()) {
long len = treeItr.getEntryLength();
dce = new DirCacheEntry(treeItr.getEntryPathString());
dce.setFileMode(treeItr.getEntryFileMode());
dce.setLastModified(treeItr.getEntryLastModifiedInstant());
dce.setLength((int) len);
try (FileInputStream in = new FileInputStream(
treeItr.getEntryFile())) {
dce.setObjectId(
inserter.insert(Constants.OBJ_BLOB, len, in));
}
builder.add(dce);
treeItr.next(1);
}
builder.commit();
inserter.flush();
}
}
/**
* Helper method to map arbitrary objects to user-defined names. This can be
* used create short names for objects to produce small and stable debug
* output. It is guaranteed that when you lookup the same object multiple
* times even with different nameTemplates this method will always return
* the same name which was derived from the first nameTemplate.
* nameTemplates can contain "%n" which will be replaced by a running number
* before used as a name.
*
* @param l
* the object to lookup
* @param lookupTable
* a table storing object-name mappings.
* @param nameTemplate
* the name for that object. Can contain "%n" which will be
* replaced by a running number before used as a name. If the
* lookup table already contains the object this parameter will
* be ignored
* @return a name of that object. Is not guaranteed to be unique. Use
* nameTemplates containing "%n" to always have unique names
*/
public static String lookup(Object l, String nameTemplate,
Map