blob: 61d3b860e9217218550152e5c1db8fb08e7a86c3 [file] [log] [blame]
/*
* Copyright (C) 2008-2009, Google Inc.
* Copyright (C) 2008, Imran M Yousuf <imyousuf@smartitengineering.com>
* Copyright (C) 2008, Jonas Fonseca <fonseca@diku.dk> 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 java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.lang.reflect.Method;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Path;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.util.FileUtils;
import org.eclipse.jgit.util.IO;
import org.eclipse.jgit.util.RawParseUtils;
import org.junit.Assert;
import org.junit.Test;
/**
* Abstract test util class
*/
public abstract class JGitTestUtil {
/** Constant <code>CLASSPATH_TO_RESOURCES="org/eclipse/jgit/test/resources/"</code> */
public static final String CLASSPATH_TO_RESOURCES = "org/eclipse/jgit/test/resources/";
private JGitTestUtil() {
throw new UnsupportedOperationException();
}
/**
* Get name of current test by inspecting stack trace
*
* @return the name
*/
public static String getName() {
GatherStackTrace stack;
try {
throw new GatherStackTrace();
} catch (GatherStackTrace wanted) {
stack = wanted;
}
try {
for (StackTraceElement stackTrace : stack.getStackTrace()) {
String className = stackTrace.getClassName();
String methodName = stackTrace.getMethodName();
Method method;
try {
method = Class.forName(className) //
.getMethod(methodName, (Class[]) null);
} catch (NoSuchMethodException e) {
// could be private, i.e. not a test method
// could have arguments, not handled
continue;
}
Test annotation = method.getAnnotation(Test.class);
if (annotation != null)
return methodName;
}
} catch (ClassNotFoundException shouldNeverOccur) {
// Fall through and crash.
}
throw new AssertionError("Cannot determine name of current test");
}
@SuppressWarnings("serial")
private static class GatherStackTrace extends Exception {
// Thrown above to collect the stack frame.
}
/**
* Assert byte arrays are equal
*
* @param exp
* expected value
* @param act
* actual value
*/
public static void assertEquals(byte[] exp, byte[] act) {
Assert.assertEquals(s(exp), s(act));
}
private static String s(byte[] raw) {
return RawParseUtils.decode(raw);
}
/**
* Get test resource file.
*
* @param fileName
* @return the test resource file
*/
public static File getTestResourceFile(String fileName) {
if (fileName == null || fileName.length() <= 0) {
return null;
}
final URL url = cl().getResource(CLASSPATH_TO_RESOURCES + fileName);
if (url == null) {
// If URL is null then try to load it as it was being
// loaded previously
return new File("tst", fileName);
}
if ("jar".equals(url.getProtocol())) {
try {
File tmp = File.createTempFile("tmp_", "_" + fileName);
copyTestResource(fileName, tmp);
return tmp;
} catch (IOException err) {
throw new RuntimeException("Cannot create temporary file", err);
}
}
try {
return new File(url.toURI());
} catch (IllegalArgumentException e) {
throw new IllegalArgumentException(e.getMessage() + " " + url);
} catch (URISyntaxException e) {
return new File(url.getPath());
}
}
/**
* Copy test resource.
*
* @param name
* @param dest
* @throws IOException
*/
public static void copyTestResource(String name, File dest)
throws IOException {
URL url = cl().getResource(CLASSPATH_TO_RESOURCES + name);
if (url == null)
throw new FileNotFoundException(name);
try (InputStream in = url.openStream();
FileOutputStream out = new FileOutputStream(dest)) {
byte[] buf = new byte[4096];
for (int n; (n = in.read(buf)) > 0;)
out.write(buf, 0, n);
}
}
private static ClassLoader cl() {
return JGitTestUtil.class.getClassLoader();
}
/**
* Write a trash file.
*
* @param db
* @param name
* @param data
* @return the trash file
* @throws IOException
*/
public static File writeTrashFile(final Repository db,
final String name, final String data) throws IOException {
File path = new File(db.getWorkTree(), name);
write(path, data);
return path;
}
/**
* Write a trash file.
*
* @param db
* @param subdir
* @param name
* @param data
* @return the trash file
* @throws IOException
*/
public static File writeTrashFile(final Repository db,
final String subdir,
final String name, final String data) throws IOException {
File path = new File(db.getWorkTree() + "/" + subdir, name);
write(path, data);
return path;
}
/**
* Write a string as a UTF-8 file.
*
* @param f
* file to write the string to. Caller is responsible for making
* sure it is in the trash directory or will otherwise be cleaned
* up at the end of the test. If the parent directory does not
* exist, the missing parent directories are automatically
* created.
* @param body
* content to write to the file.
* @throws IOException
* the file could not be written.
*/
public static void write(File f, String body)
throws IOException {
FileUtils.mkdirs(f.getParentFile(), true);
try (Writer w = new OutputStreamWriter(new FileOutputStream(f),
UTF_8)) {
w.write(body);
}
}
/**
* Fully read a UTF-8 file and return as a string.
*
* @param file
* file to read the content of.
* @return UTF-8 decoded content of the file, empty string if the file
* exists but has no content.
* @throws IOException
* the file does not exist, or could not be read.
*/
public static String read(File file) throws IOException {
final byte[] body = IO.readFully(file);
return new String(body, 0, body.length, UTF_8);
}
/**
* Read a file's content
*
* @param db
* @param name
* @return the content of the file
* @throws IOException
*/
public static String read(Repository db, String name)
throws IOException {
File file = new File(db.getWorkTree(), name);
return read(file);
}
/**
* Check if file exists
*
* @param db
* @param name
* name of the file
* @return {@code true} if the file exists
*/
public static boolean check(Repository db, String name) {
File file = new File(db.getWorkTree(), name);
return file.exists();
}
/**
* Delete a trash file.
*
* @param db
* @param name
* @throws IOException
*/
public static void deleteTrashFile(final Repository db,
final String name) throws IOException {
File path = new File(db.getWorkTree(), name);
FileUtils.delete(path);
}
/**
* Write a symbolic link
*
* @param db
* the repository
* @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
* @since 4.2
*/
public static Path writeLink(Repository db, String link,
String target) throws Exception {
return FileUtils.createSymLink(new File(db.getWorkTree(), link),
target);
}
/**
* Concatenate byte arrays.
*
* @param b
* byte arrays to combine together.
* @return a single byte array that contains all bytes copied from input
* byte arrays.
* @since 4.9
*/
public static byte[] concat(byte[]... b) {
int n = 0;
for (byte[] a : b) {
n += a.length;
}
byte[] data = new byte[n];
n = 0;
for (byte[] a : b) {
System.arraycopy(a, 0, data, n, a.length);
n += a.length;
}
return data;
}
}