InpathTest.java
/* *******************************************************************
* Copyright (c) 2003 Contributors.
* All rights reserved.
* This program and the accompanying materials are made available
* under the terms of the Eclipse Public License v 2.0
* which accompanies this distribution and is available at
* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt
*
* Contributors:
* Mik Kersten initial implementation
* Andy Clement Copied/changed for -inpath testing
* Helen Hawkins Changed to use new ajde interface (bug 148190)
* ******************************************************************/
package org.aspectj.ajde.core.tests;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
import java.util.jar.JarInputStream;
import java.util.zip.ZipEntry;
import org.aspectj.ajde.core.AjdeCoreTestCase;
import org.aspectj.ajde.core.TestCompilerConfiguration;
import org.aspectj.ajde.core.TestMessageHandler;
import org.aspectj.util.FileUtil;
public class InpathTest extends AjdeCoreTestCase {
public static final FileFilter aspectjResourceFileFilter = new FileFilter() {
@Override
public boolean accept(File pathname) {
String name = pathname.getName().toLowerCase();
return (!name.endsWith(".class") && !name.endsWith(".java") && !name.endsWith(".aj"));
}
};
public static final String indir1Name = "indir1";
public static final String indir2Name = "indir2";
public static final String injarName = "injar.jar";
public static final String outjarName = "/bin/output.jar";
private String[] build1 = new String[] { "src1" + File.separator + "Main.java" };
private String[] build2 = new String[] { "src2" + File.separator + "Aspect.java" };
private TestMessageHandler handler;
private TestCompilerConfiguration compilerConfig;
@Override
protected void setUp() throws Exception {
super.setUp();
initialiseProject("InpathTest");
handler = (TestMessageHandler) getCompiler().getMessageHandler();
compilerConfig = (TestCompilerConfiguration) getCompiler().getCompilerConfiguration();
}
@Override
protected void tearDown() throws Exception {
super.tearDown();
handler = null;
compilerConfig = null;
}
/**
* Inputs to the compiler: inpath = 'indir1/' source = 'src' output = a jar file
*
* Expected result = output jar file contains contents of indir1 and class file for source that was in src
*/
public void testInpathToOutjar() {
Set<File> inpath = new HashSet<>();
File indir1 = openFile(indir1Name);
inpath.add(indir1);
compilerConfig.setInpath(inpath);
File outjar = openFile(outjarName);
compilerConfig.setOutjar(outjar.getAbsolutePath());
compilerConfig.setProjectSourceFiles(getSourceFileList(build1));
doBuild(true);
assertTrue("Expected no compiler errors or warnings but found " + handler.getMessages(), handler.getMessages().isEmpty());
Set<String> expectedOutputJarContents = new HashSet<>();
// From indir1
// If we don't copy resources, these next three files won't make it.
// expectedOutputJarContents.add("META-INF/MANIFEST.MF");
// expectedOutputJarContents.add("META-INF/test.xml");
// expectedOutputJarContents.add("test/test.props");
expectedOutputJarContents.add("test/TestProperties.class");
// From src
expectedOutputJarContents.add("Main.class");
compareJars(indir1, "src", outjar, expectedOutputJarContents);
}
/**
* Similar to the first test but outputs to a directory rather than a jar.
*
*/
public void testInpathToBin() {
Set<File> inpath = new HashSet<>();
File indir1 = openFile(indir1Name);
inpath.add(indir1);
compilerConfig.setInpath(inpath);
compilerConfig.setProjectSourceFiles(getSourceFileList(build1));
doBuild(true);
assertTrue("Expected no compiler errors or warnings but found " + handler.getMessages(), handler.getMessages().isEmpty());
Set<String> expectedBindirContents = new HashSet<>();
// From indir1
// If we don't copy resources, these next three files won't make it
// expectedBindirContents.add("META-INF/MANIFEST.MF");
// expectedBindirContents.add("META-INF/test.xml");
// expectedBindirContents.add("test/test.props");
expectedBindirContents.add("test/TestProperties.class");
// From src
expectedBindirContents.add("Main.class");
compareIndirToBin(indir1, "src", "bin", expectedBindirContents);
}
/**
* Inputs to the compiler: inpath is 'indir2' that contains a helloworld source file and class file. source is 'src2' which
* contains Aspect.java which weaves before advice into the HelloWorld code from 'indir2'
*
* Expected result: HelloWorld copied through to output jar and 'weaved'. Compiled version of Aspect.java put into the output
* jar. The HelloWorld.java source file is also copied through to the output jar.
*
* An extra check is done at the end of this test to verify that HelloWorld has changed size (due to the weaving).
*/
public void testInpathToOutjar2() {
Set<File> inpath = new HashSet<>();
File indir2 = openFile(indir2Name);
inpath.add(indir2);
compilerConfig.setInpath(inpath);
File outjar = openFile(outjarName);
compilerConfig.setOutjar(outjar.getAbsolutePath());
compilerConfig.setProjectSourceFiles(getSourceFileList(build2));
doBuild(true);
assertTrue("Expected no compiler errors or warnings but found " + handler.getMessages(), handler.getMessages().isEmpty());
Set<String> expectedOutputJarContents = new HashSet<>();
// From indir1
expectedOutputJarContents.add("example/HelloWorld.class");
// If we don't copy resources, this file won't make it
// expectedOutputJarContents.add("example/HelloWorld.java");
// From src
expectedOutputJarContents.add("Aspect.class");
compareJars(indir2, "src", outjar, expectedOutputJarContents);
// Extra test. The HelloWorld class from the input directory should have been woven
// by the aspect - verify that the size of the HelloWorld class in the output directory
// is a different size to the input version.
int outputsize = fetchFromJar(outjar, "example/HelloWorld.class");
try {
FileInputStream fis = new FileInputStream(openFile(indir2Name + "/example/HelloWorld.class"));
byte[] filedata = FileUtil.readAsByteArray(fis);
int inputsize = filedata.length;
assertTrue("Weaving of Aspect should have occurred but the input and output size for HelloWorld.class are the same",
(inputsize != outputsize));
} catch (Exception e) {
e.printStackTrace();
fail();
}
}
/**
* More complex inpath - a jar and a directory
*
* Inputs: -inpath injar.jar;indir2 source is 'src2' which contains Aspect.java
*
* Expected result: Result should be a directory containing the contents of injar.jar and indir2 and the Aspect.class file.
*
*/
public void testInpathAndInjarToBin() {
Set<File> inpath = new HashSet<>();
File indir2 = openFile(indir2Name);
inpath.add(indir2);
inpath.add(openFile(injarName));
compilerConfig.setInpath(inpath);
compilerConfig.setProjectSourceFiles(getSourceFileList(build2));
doBuild(true);
assertTrue("Expected no compiler errors or warnings but found " + handler.getMessages(), handler.getMessages().isEmpty());
Set<String> expectedBindirContents = new HashSet<>();
// From indir1
expectedBindirContents.add("example/HelloWorld.class");
// If we don't copy resources, this file won't make it
// expectedBindirContents.add("example/HelloWorld.java");
// From injar.jar
expectedBindirContents.add("props/resources.properties");
// From src
expectedBindirContents.add("Aspect.class");
compareIndirToBin(indir2, "src", "bin", expectedBindirContents);
// Check the input and output versions of HelloWorld.class are different sizes
try {
FileInputStream fis1 = new FileInputStream(openFile("indir2/example/HelloWorld.class"));
byte[] filedata1 = FileUtil.readAsByteArray(fis1);
int inputsize = filedata1.length;
FileInputStream fis2 = new FileInputStream(openFile("bin/example/HelloWorld.class"));
byte[] filedata2 = FileUtil.readAsByteArray(fis2);
int outputsize = filedata2.length;
assertTrue("Weaving of Aspect should have occurred but the input and output size for HelloWorld.class are the same",
(outputsize != inputsize));
fis1.close();
fis2.close();
} catch (Exception e) {
e.printStackTrace();
fail();
}
}
/*
* Ensure -outjar contains all non-Java resouces from injars
*/
public void compareJars(File dirFile, String sourceDir, File outjarFile, Set<String> expectedOutputJarContents) {
try {
assertTrue(
"outjar older than injar: outjarLastMod=" + outjarFile.lastModified() + " injarLastMod="
+ dirFile.lastModified(), (outjarFile.lastModified() >= dirFile.lastModified()));
// Go through the output jar file, for each element, remove it from
// the expectedOutputJarContents - when we finish, the expectedOutputJarContents
// set should be empty!
JarInputStream outjar = new JarInputStream(new java.io.FileInputStream(outjarFile));
ZipEntry entry;
while (null != (entry = outjar.getNextEntry())) {
String fileName = entry.getName();
fileName = fileName.replace('\\', '/');
if (!fileName.contains("CVS")) {
boolean b = expectedOutputJarContents.remove(fileName);
assertTrue("Unexpectedly found : " + fileName + " in outjar", b);
}
outjar.closeEntry();
}
outjar.close();
assertTrue("Didnt make it into the output jar: " + expectedOutputJarContents.toString(),
expectedOutputJarContents.isEmpty());
} catch (IOException ex) {
fail(ex.toString());
}
}
/*
* Ensure -outjar contains all non-Java resouces from source and injars
*/
public void compareSourceToOutjar(String indirName, File outjarFile) {
HashSet<String> resources = new HashSet<>();
listSourceResources(indirName, resources);
try {
JarInputStream outjar = new JarInputStream(new java.io.FileInputStream(outjarFile));
ZipEntry entry;
while (null != (entry = outjar.getNextEntry())) {
String fileName = entry.getName();
if (!fileName.endsWith(".class")) {
boolean b = resources.remove(fileName);
assertTrue(fileName, b);
}
outjar.closeEntry();
}
outjar.close();
assertTrue("Missing resources: " + resources.toString(), resources.isEmpty());
} catch (IOException ex) {
fail(ex.toString());
}
}
/*
* Ensure bin contains all non-Java resouces from source and injars
*/
public void compareIndirToBin(File indirFile, String sourceDir, String outdirName, Set<String> expectedOutdirContents) {
// byte[] inManifest = null;
File binBase = openFile(outdirName);
String[] toResources = FileUtil.listFiles(binBase);
for (String fileName : toResources) {
if (!fileName.contains("CVS")) {
boolean b = expectedOutdirContents.remove(fileName);
assertTrue("Extraneous resources: " + fileName, b);
}
}
assertTrue("Missing resources: " + expectedOutdirContents.toString(), expectedOutdirContents.isEmpty());
}
private void listSourceResources(String indirName, Set<String> resources) {
File srcBase = openFile(indirName);
File[] fromResources = FileUtil.listFiles(srcBase, aspectjResourceFileFilter);
for (File fromResource : fromResources) {
String name = FileUtil.normalizedPath(fromResource, srcBase);
// System.err.println("Checking "+name);
if (!name.startsWith("CVS/") && (!name.contains("/CVS/")) && !name.endsWith("/CVS")) {
resources.add(name);
}
}
}
// Return the size of specified entry from the output jar file
public int fetchFromJar(File outjarFile, String filename) {
int ret = -1;
try {
JarInputStream outjar;
outjar = new JarInputStream(new java.io.FileInputStream(outjarFile));
ZipEntry entry;
while (null != (entry = outjar.getNextEntry())) {
String zipentryname = entry.getName();
if (zipentryname.equals(filename)) {
byte[] filedata = FileUtil.readAsByteArray(outjar);
ret = filedata.length;
outjar.closeEntry();
break;
}
outjar.closeEntry();
}
outjar.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return ret;
}
}