/*******************************************************************************
*
* Copyright (c) 2010-2011 Sonatype, Inc.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*
*
*
*
*******************************************************************************/
package org.hudsonci.utils.test;
import java.io.File;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.Preconditions;
/**
* Test utilities.
*
* @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
* @since 2.1.0
*/
public class TestUtil {
private final Class owningClass;
/**
* The base-directory which tests should be run from.
*
* @see #initBaseDir() This field is initialized from the return of this
* method on instance construction.
*/
protected final File baseDir;
/**
* Instance logger which tests should use to produce tracing information.
*
* <p> Unless you have a really good reason to, do not change this field
* from your sub-class. And if you do, please document why you have done so.
*/
protected final Logger log;
public TestUtil(final Class owner) {
if (null == owner) {
throw new IllegalArgumentException("owner is required");
}
this.owningClass = owner;
baseDir = initBaseDir();
//
// NOTE: Logging must be initialized after BASEDIR has been discovered, as it is used
// by the log4j logging-config properties to set the target/test.log file.
//
log = LoggerFactory.getLogger(owner);
}
public TestUtil(final Object owner) {
this(owner.getClass());
}
public File getBaseDir() {
return baseDir;
}
public Logger getLog() {
return log;
}
/**
* Determine the value of <tt>${basedir}</tt>, which should be the base
* directory of the module which the concrete test class is defined in.
*
* <p> If The system property <tt>basedir</tt> is already set, then that
* value is used, otherwise we determine the value from the code-source of
* the containing concrete class and set the <tt>basedir</tt> system
* property to that value.
*
* @see #baseDir This field is always initialized to the value which this
* method returns.
*
* @return The base directory of the module which contains the concrete test
* class.
*/
protected final File initBaseDir() {
File dir;
// If ${basedir} is set, then honor it
String tmp = System.getProperty("basedir");
if (tmp != null) {
dir = new File(tmp);
} else {
// Find the directory which this class (or really the sub-class of TestSupport) is defined in.
String path = owningClass.getProtectionDomain().getCodeSource().getLocation().getFile();
// We expect the file to be in target/test-classes, so go up 2 dirs
dir = new File(path).getParentFile().getParentFile();
// Set ${basedir} which is needed by logging to initialize
System.setProperty("basedir", dir.getPath());
}
// System.err.println("Base Directory: " + dir);
return dir;
}
/**
* Resolve the given path to a file rooted to {@link #baseDir}.
*
* @param path The path to resolve.
* @return The resolved file for the given path.
*/
public final File resolveFile(final String path) {
Preconditions.checkNotNull(path);
File file = new File(path);
// Complain if the file is already absolute... probably an error
if (file.isAbsolute()) {
log.warn("Given path is already absolute; nothing to resolve: {}", file);
} else {
file = new File(baseDir, path);
}
return file;
}
/**
* Resolve the given path to a path rooted to {@link #baseDir}.
*
* @param path The path to resolve.
* @return The resolved path for the given path.
*
* @see #resolveFile(String)
*/
public final String resolvePath(final String path) {
Preconditions.checkNotNull(path);
return resolveFile(path).getPath();
}
}