package net.sourceforge.cobertura.test.util;
import groovy.util.AntBuilder;
import groovy.util.Node;
import groovy.util.XmlParser;
import net.sourceforge.cobertura.ant.InstrumentTask;
import org.apache.tools.ant.DefaultLogger;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Javac;
import org.apache.tools.ant.taskdefs.Zip;
import org.apache.tools.ant.taskdefs.optional.junit.FormatterElement;
import org.apache.tools.ant.taskdefs.optional.junit.FormatterElement.TypeAttribute;
import org.apache.tools.ant.taskdefs.optional.junit.JUnitTask;
import org.apache.tools.ant.taskdefs.optional.junit.JUnitTest;
import org.apache.tools.ant.types.DirSet;
import org.apache.tools.ant.types.FileSet;
import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.types.Path.PathElement;
import org.codehaus.groovy.ant.Groovyc;
import org.xml.sax.SAXException;
import javax.xml.parsers.ParserConfigurationException;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.net.ConnectException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.*;
import static org.junit.Assert.*;
public class TestUtils {
private static final String SRC_DIR = "src/main/java";
static File coberturaClassDir;
public static final AntBuilder antBuilder = new AntBuilder();
public static final Project project = new Project();
public static final String SIMPLE_SOURCE_PATHNAME = "a/mypackage/SimpleSource.java";
public static final String SOURCE_TEXT = "\n package a.mypackage;" + "\n "
+ "\n public class SimpleSource {"
+ "\n public void aSimpleMethod() { " + "\n }" + "\n }";
static {
DefaultLogger consoleLogger = new DefaultLogger();
consoleLogger.setErrorPrintStream(System.err);
consoleLogger.setOutputPrintStream(System.out);
consoleLogger.setMessageOutputLevel(Project.MSG_INFO);
project.addBuildListener(consoleLogger);
}
public synchronized static File getCoberturaClassDir() {
if (coberturaClassDir == null) {
coberturaClassDir = new File("target/test/cobertura_classes");
coberturaClassDir.mkdirs();
Javac javac = new Javac();
javac.setProject(project);
javac.setSrcdir(new Path(project, SRC_DIR));
javac.setDestdir(coberturaClassDir);
javac.setDebug(true);
javac.setTarget("1.5");
javac.execute();
}
return coberturaClassDir;
}
public static DirSet getCoberturaClassDirSet() {
DirSet dirSet = new DirSet();
dirSet.setDir(getCoberturaClassDir());
return dirSet;
}
public static AntBuilder getCoberturaAntBuilder(File coberturaClassdir) {
Project project = new Project();
project.addTaskDefinition("groovyc",
org.codehaus.groovy.ant.Groovyc.class);
AntBuilder antBuilder = new AntBuilder(project);
return antBuilder;
}
public static File getTempDir() {
return new File("target/tmp", "cobertura");
}
public static Node getXMLReportDOM(File xmlReport)
throws ParserConfigurationException, SAXException, IOException {
return getXMLReportDOM(xmlReport.getAbsolutePath());
}
public static Node getXMLReportDOM(String xmlReport)
throws ParserConfigurationException, SAXException, IOException {
XmlParser parser = new XmlParser();
parser
.setFeature(
"http://apache.org/xml/features/nonvalidating/load-external-dtd",
false);
return parser.parse(xmlReport);
}
public static int getHitCount(Node dom, String className, String methodName) {
for (Iterator<Node> packagesIterator = dom.iterator(); packagesIterator
.hasNext();) {
Node packagesNode = packagesIterator.next();
if ("packages".equals(packagesNode.name())) {
for (Iterator<Node> packageIterator = packagesNode.iterator(); packageIterator
.hasNext();) {
Node packageNode = packageIterator.next();
if ("package".equals(packageNode.name())) {
for (Iterator<Node> classesIterator = packageNode
.iterator(); classesIterator.hasNext();) {
Node classesNode = classesIterator.next();
if ("classes".equals(classesNode.name())) {
for (Iterator<Node> classIterator = classesNode
.iterator(); classIterator.hasNext();) {
Node classNode = classIterator.next();
if ("class".equals(classNode.name())) {
if (className.equals(classNode
.attribute("name"))) {
for (Iterator<Node> methodsIterator = classNode
.iterator(); methodsIterator
.hasNext();) {
Node methodsNode = methodsIterator
.next();
if ("methods"
.equals(methodsNode
.name())) {
for (Iterator<Node> methodIterator = methodsNode
.iterator(); methodIterator
.hasNext();) {
Node methodNode = methodIterator
.next();
if ("method"
.equals(methodNode
.name())) {
if (methodName
.equals(methodNode
.attribute("name"))) {
for (Iterator<Node> linesIterator = methodNode
.iterator(); linesIterator
.hasNext();) {
Node linesNode = linesIterator
.next();
if ("lines"
.equals(linesNode
.name())) {
for (Iterator<Node> lineIterator = linesNode
.iterator(); lineIterator
.hasNext();) {
Node lineNode = lineIterator
.next();
if ("line"
.equals(lineNode
.name())) {
return Integer
.valueOf((String) lineNode
.attribute("hits"));
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
return 0;
}
public static int getTotalHitCount(Node dom, String className,
String methodName) {
int sum = 0;
for (Iterator<Node> packagesIterator = dom.iterator(); packagesIterator
.hasNext();) {
Node packagesNode = packagesIterator.next();
if ("packages".equals(packagesNode.name())) {
for (Iterator<Node> packageIterator = packagesNode.iterator(); packageIterator
.hasNext();) {
Node packageNode = packageIterator.next();
if ("package".equals(packageNode.name())) {
for (Iterator<Node> classesIterator = packageNode
.iterator(); classesIterator.hasNext();) {
Node classesNode = classesIterator.next();
if ("classes".equals(classesNode.name())) {
for (Iterator<Node> classIterator = classesNode
.iterator(); classIterator.hasNext();) {
Node classNode = classIterator.next();
if ("class".equals(classNode.name())) {
if (className.equals(classNode
.attribute("name"))) {
for (Iterator<Node> methodsIterator = classNode
.iterator(); methodsIterator
.hasNext();) {
Node methodsNode = methodsIterator
.next();
if ("methods"
.equals(methodsNode
.name())) {
for (Iterator<Node> methodIterator = methodsNode
.iterator(); methodIterator
.hasNext();) {
Node methodNode = methodIterator
.next();
if ("method"
.equals(methodNode
.name())) {
if (methodName
.equals(methodNode
.attribute("name"))) {
for (Iterator<Node> linesIterator = methodNode
.iterator(); linesIterator
.hasNext();) {
Node linesNode = linesIterator
.next();
if ("lines"
.equals(linesNode
.name())) {
for (Iterator<Node> lineIterator = linesNode
.iterator(); lineIterator
.hasNext();) {
Node lineNode = lineIterator
.next();
if ("line"
.equals(lineNode
.name())) {
sum += Integer
.valueOf((String) lineNode
.attribute("hits"));
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
return sum;
}
public static void instrumentClasses(AntBuilder ant, File srcDir,
File datafile, File instrumentDir, Map arguments) {
FileSet fileSet = new FileSet();
fileSet.setDir(srcDir);
fileSet.setIncludes("**/*.class");
InstrumentTask instrumentTask = new InstrumentTask();
instrumentTask.setProject(project);
instrumentTask.addFileset(fileSet);
instrumentTask.createIncludeClasses().setRegex("mypackage.*");
instrumentTask.setDataFile(datafile.getAbsolutePath());
instrumentTask.setToDir(instrumentDir);
instrumentTask.setThreadsafeRigorous(arguments != null
&& arguments.containsKey("threadsafeRigorous")
? (Boolean) arguments.get("threadsafeRigorous")
: false);
instrumentTask.setIgnoreTrivial(arguments != null
&& arguments.containsKey("ignoretrivial") ? (Boolean) arguments
.get("ignoretrivial") : false);
if (arguments != null && arguments.containsKey("ignoreAnnotationNames")) {
List<String> ignoreAnnotations = (List<String>) arguments
.get("ignoreAnnotationNames");
for (String annotation : ignoreAnnotations) {
instrumentTask.createIgnoreMethodAnnotation()
.setAnnotationName(annotation);
}
}
if (arguments != null
&& arguments.containsKey("excludeClassesRegexList")) {
instrumentTask.createExcludeClasses().setRegex(
(String) arguments.get("excludeClassesRegexList"));
}
instrumentTask.execute();
}
public static void compileSource(AntBuilder ant, File srcDir) {
compileSource(ant, srcDir, "1.7");
}
public static void compileSource(AntBuilder ant, File srcDir,
String jdkVersion) {
Javac javac = new Javac();
javac.setDebug(true);
javac.setSource(jdkVersion);
javac.setTarget(jdkVersion);
javac.setProject(project);
javac.setSrcdir(new Path(project, srcDir.getAbsolutePath()));
javac.setDestdir(srcDir);
javac.execute();
}
public static void compileGroovy(AntBuilder ant, File srcDir) {
Javac javac = new Javac();
javac.setDebug(true);
Groovyc groovyc = new Groovyc();
groovyc.setProject(project);
groovyc.setSrcdir(new Path(project, srcDir.getAbsolutePath()));
groovyc.setDestdir(srcDir);
groovyc.addConfiguredJavac(javac);
groovyc.execute();
}
public static List<Node> getLineCounts(Node dom, String className,
String methodName, String signature) {
List<Node> returnList = new ArrayList<Node>();
for (Iterator<Node> packagesIterator = dom.iterator(); packagesIterator
.hasNext();) {
Node packagesNode = packagesIterator.next();
if ("packages".equals(packagesNode.name())) {
for (Iterator<Node> packageIterator = packagesNode.iterator(); packageIterator
.hasNext();) {
Node packageNode = packageIterator.next();
if ("package".equals(packageNode.name())) {
for (Iterator<Node> classesIterator = packageNode
.iterator(); classesIterator.hasNext();) {
Node classesNode = classesIterator.next();
if ("classes".equals(classesNode.name())) {
for (Iterator<Node> classIterator = classesNode
.iterator(); classIterator.hasNext();) {
Node classNode = classIterator.next();
if ("class".equals(classNode.name())) {
if (className.equals(classNode
.attribute("name"))) {
for (Iterator<Node> methodsIterator = classNode
.iterator(); methodsIterator
.hasNext();) {
Node methodsNode = methodsIterator
.next();
if ("methods"
.equals(methodsNode
.name())) {
for (Iterator<Node> methodIterator = methodsNode
.iterator(); methodIterator
.hasNext();) {
Node methodNode = methodIterator
.next();
if ("method"
.equals(methodNode
.name())) {
if (methodName
.equals(methodNode
.attribute("name"))) {
if (signature != null) {
returnList
.clear();
} // Keep clearing if signature isn't null
for (Iterator<Node> linesIterator = methodNode
.iterator(); linesIterator
.hasNext();) {
Node linesNode = linesIterator
.next();
if ("lines"
.equals(linesNode
.name())) {
for (Iterator<Node> lineIterator = linesNode
.iterator(); lineIterator
.hasNext();) {
Node lineNode = lineIterator
.next();
if ("line"
.equals(lineNode
.name())) {
returnList
.add(lineNode);
}
}
}
}
if (signature != null) {
if (signature
.equals(methodNode
.attribute("signature"))) {
return returnList;
} else {
returnList
.clear();
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
return returnList;
}
public static File createSourceArchive(File dir) throws IOException {
File sourceDir = new File(dir, SRC_DIR);
File sourceFile = new File(sourceDir, SIMPLE_SOURCE_PATHNAME);
sourceFile.getParentFile().mkdirs();
BufferedWriter bw = null;
try {
bw = new BufferedWriter(new FileWriter(sourceFile));
bw.write(SOURCE_TEXT);
} finally {
if (bw != null)
bw.close();
}
File zipDir = new File(dir, "zip");
zipDir.mkdirs();
File zipFile = new File(zipDir, "source.zip");
Zip zip = new Zip();
zip.setProject(project);
zip.setDestFile(zipFile);
zip.setBasedir(sourceDir);
zip.execute();
assertTrue(sourceFile.delete());
return zipFile;
}
public static void instrumentClasses(AntBuilder ant, File srcDir,
File datafile, File instrumentDir) {
instrumentClasses(ant, srcDir, datafile, instrumentDir, null);
}
public static void checkFrameSummaryHtmlFile(File frameSummaryFile)
throws Exception {
XmlParser parser = new XmlParser();
// the next line is to suppress loading the dtd
parser
.setFeature(
"http://apache.org/xml/features/nonvalidating/load-external-dtd",
false);
Node doc = parser.parse(frameSummaryFile);
List<Node> list = doc.depthFirst();
int totalClasses = 0;
int expectedTotalNumberOfClasses = 0;
for (Iterator<Node> tableIterator = list.iterator(); tableIterator
.hasNext();) {
Node tableNode = tableIterator.next();
if ("table".equals(tableNode.name())) {
if ("report".equals(tableNode.attribute("class"))) {
for (Iterator<Node> tbodyIterator = tableNode.iterator(); tbodyIterator
.hasNext();) {
Node tbodyNode = tbodyIterator.next();
if ("tbody".equals(tbodyNode.name())) {
for (Iterator<Node> trIterator = tbodyNode
.iterator(); trIterator.hasNext();) {
Node trNode = trIterator.next();
if ("tr".equals(trNode.name())) {
String tdClassString = "td[attributes={class=value}; value=[";
int tdClassLength = tdClassString.length();
String value = trNode.value().toString();
int tdClassFirstOccurance = value
.indexOf(tdClassString);
String tdClassStart = value
.substring(tdClassFirstOccurance);
int tdClassElement = Integer
.valueOf(tdClassStart
.substring(
tdClassString
.length(),
tdClassStart
.indexOf("]],")));
if (trNode.value().toString().contains(
"All Packages")) {
expectedTotalNumberOfClasses = tdClassElement;
} else {
totalClasses += tdClassElement;
}
}
}
}
}
}
}
}
assertFalse("All classes should not be 0.",
0 == expectedTotalNumberOfClasses);
assertEquals(
"Class count in All Packages of frame-summary.html does not match the sum of the package class counts",
expectedTotalNumberOfClasses, totalClasses);
}
public static Path getCoberturaDefaultClasspath() {
Path classpath = new Path(TestUtils.project);
DirSet dirSetInstrumentDir = new DirSet();
DirSet dirSetSrcDir = new DirSet();
dirSetInstrumentDir.setDir(new File(getTempDir(), "instrument"));
dirSetSrcDir.setDir(new File(getTempDir(), "src"));
classpath.addDirset(dirSetInstrumentDir);
classpath.addDirset(dirSetSrcDir);
classpath.addDirset(TestUtils.getCoberturaClassDirSet());
return classpath;
}
/**
* Run Ant's junit task. Typical usage:
*
* testUtil.junit( Types
* testClass : 'mypackage.MyTest', String
* ant : ant, AntBuilder
* buildDir : buildDir, File
* instrumentDir : instrumentDir, File
* reportDir : reportDir, File
* )
*
* 'ant' is the AntBuilder that is used. Instrumented classes are in
* instrumentDir; The remaining classes are in buildDir.
* An XML report is created in reportDir.
*
* @param hashMap
* @return
* @throws Exception
*/
public static void junit(HashMap hashMap) throws Exception {
Path classpath = new Path(project);
PathElement instDirPathElement = classpath.new PathElement();
PathElement buildDirPathElement = classpath.new PathElement();
PathElement coberturaClassDirPathElement = classpath.new PathElement();
PathElement computerClasspath = classpath.new PathElement();
FileSet fileSet = new FileSet();
instDirPathElement.setLocation((File) hashMap.get("instrumentDir"));
buildDirPathElement.setLocation((File) hashMap.get("buildDir"));
coberturaClassDirPathElement.setLocation(getCoberturaClassDir());
computerClasspath.setPath(System.getProperty("java.class.path"));
fileSet.setDir(new File("src/test/resources/antLibrary/common/groovy"));
fileSet.setIncludes("*.jar");
classpath.add(instDirPathElement);
classpath.add(buildDirPathElement);
classpath.add(coberturaClassDirPathElement);
classpath.add(computerClasspath);
classpath.addFileset(fileSet);
// Create junitTask
JUnitTask junit = new JUnitTask();
junit.setProject(project);
junit.setHaltonfailure(true);
junit.setDir((File) hashMap.get("buildDir"));
junit.setFork(true);
// Add formatter to junitTask
FormatterElement formatter = new FormatterElement();
TypeAttribute type = new TypeAttribute();
type.setValue("xml");
formatter.setType(type);
junit.addFormatter(formatter);
// Add test to junitTask
JUnitTest test = new JUnitTest((String) hashMap.get("testClass"));
test.setTodir((File) hashMap.get("reportDir"));
junit.addTest(test);
junit.setShowOutput(true);
// Add classpath to junitTask
junit.createClasspath().add(classpath);
System.out.println(classpath);
// Finally execute junitTask
junit.execute();
}
public static List<Node> getLineCounts(Node dom, String className,
String methodName) {
return getLineCounts(dom, className, methodName, null);
}
public static void waitForLiveServer(String webContainerHostname,
int webContainerPort, int timeoutMin) {
InetSocketAddress address = new InetSocketAddress(webContainerHostname,
webContainerPort);
System.out.println("Waiting " + timeoutMin + " min for web server...");
long beginTime = System.currentTimeMillis();
long endTime = System.currentTimeMillis() + (timeoutMin * 60 * 1000);
boolean portOpened = false;
while ((!portOpened) && (System.currentTimeMillis() < endTime)) {
portOpened = trySocket(address);
if (portOpened) {
System.out.println("Web server has opened the port in "
+ (System.currentTimeMillis() - beginTime) / 1000.0
/ 60.0 + " min.");
} else {
try {
Thread.sleep(2000); // 2 seconds
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
if (!portOpened) {
throw new RuntimeException(
"Timed out waiting for webapp server to initialize");
}
}
private static boolean trySocket(InetSocketAddress address) {
boolean success = false;
Socket socket = null;
try {
socket = new Socket();
socket.connect(address);
success = true;
} catch (ConnectException e) {
// this is expected
} catch (Throwable e) {
e.printStackTrace();
} finally {
if (socket != null && !socket.isClosed()) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return success;
}
public static boolean isMethodHit(Node dom, String className,
String methodName) {
List<Node> methods = TestUtils
.getLineCounts(dom, className, methodName);
assertNotNull(methods);
assertTrue(!methods.isEmpty());
return Integer.valueOf((String) methods.get(0).attribute("hits")) >= 1;
}
}