@@ -0,0 +1,5 @@ | |||
package c; | |||
public class C { | |||
} |
@@ -0,0 +1,10 @@ | |||
package b; | |||
public class ClassContainingAspect { | |||
static aspect InnerAspect { | |||
} | |||
} |
@@ -0,0 +1,8 @@ | |||
package c; | |||
public class C { | |||
static aspect AnAspect { | |||
} | |||
} |
@@ -0,0 +1,9 @@ | |||
package pkg; | |||
public class C1 { | |||
public void foo() { | |||
} | |||
} |
@@ -0,0 +1,9 @@ | |||
package pkg; | |||
public class C2 { | |||
public void foo() { | |||
} | |||
} |
@@ -0,0 +1,9 @@ | |||
package pkg; | |||
public class C1 { | |||
public void foo() { | |||
System.out.println("blah"); | |||
} | |||
} |
@@ -8,4 +8,10 @@ To regenerate the class copied over as part of the test: | |||
javac newInpathClass\InpathClass.java | |||
To regenerate the jar file base\inpathJar.jar | |||
javac origInpathClass\InpathClass.java | |||
cd origInpathClass | |||
jar cf inpathJar.jar InpathClass.class inpathResource.txt | |||
copy resultant jar file to ..\base |
@@ -0,0 +1 @@ | |||
resource in directory on inpath |
@@ -0,0 +1 @@ | |||
resource on inpath... |
@@ -11,8 +11,10 @@ import org.aspectj.systemtest.ajc150.ataspectj.AtAjAnnotationGenTests; | |||
import org.aspectj.systemtest.ajc151.AllTestsAspectJ151; | |||
import org.aspectj.systemtest.ajc152.AllTestsAspectJ152; | |||
import org.aspectj.systemtest.ajc153.AllTestsAspectJ153; | |||
import org.aspectj.systemtest.model.Model5Tests; | |||
import org.aspectj.systemtest.incremental.tools.IncrementalOutputLocationManagerTests; | |||
import org.aspectj.systemtest.incremental.tools.MoreOutputLocationManagerTests; | |||
import org.aspectj.systemtest.incremental.tools.MultiProjectIncrementalTests; | |||
import org.aspectj.systemtest.model.Model5Tests; | |||
import org.aspectj.systemtest.xlint.XLint5Tests; | |||
public class AllTests15 { | |||
@@ -33,6 +35,8 @@ public class AllTests15 { | |||
* for the moment. | |||
*/ | |||
suite.addTestSuite(MultiProjectIncrementalTests.class); | |||
suite.addTestSuite(MoreOutputLocationManagerTests.class); | |||
suite.addTestSuite(IncrementalOutputLocationManagerTests.class); | |||
suite.addTest(XLint5Tests.suite()); | |||
//$JUnit-END$ | |||
return suite; |
@@ -1,8 +1,10 @@ | |||
package org.aspectj.systemtest.incremental.tools; | |||
import java.io.BufferedReader; | |||
import java.io.DataOutputStream; | |||
import java.io.File; | |||
import java.io.FileOutputStream; | |||
import java.io.FileReader; | |||
import java.io.IOException; | |||
import java.util.ArrayList; | |||
import java.util.Iterator; | |||
@@ -103,6 +105,17 @@ public class AbstractMultiProjectIncrementalAjdeInteractionTestbed extends | |||
copy(projectSrc,destination);//,false); | |||
} | |||
/* | |||
* Applies an overlay onto the project being tested - copying | |||
* the contents of the specified overlay directory. | |||
*/ | |||
public void alter(String projectName,String overlayDirectory) { | |||
File projectSrc =new File(testdataSrcDir+File.separatorChar+projectName+ | |||
File.separatorChar+overlayDirectory); | |||
File destination=new File(getWorkingDir(),projectName); | |||
copy(projectSrc,destination); | |||
} | |||
/** | |||
* Copy the contents of some directory to another location - the | |||
* copy is recursive. | |||
@@ -127,4 +140,40 @@ public class AbstractMultiProjectIncrementalAjdeInteractionTestbed extends | |||
} | |||
} | |||
/** | |||
* Count the number of times a specified aspectName appears in the default | |||
* aop.xml file and compare with the expected number of occurrences. If just | |||
* want to count the number of aspects mentioned within the file then | |||
* pass "" for the aspectName, otherwise, specify the name of the | |||
* aspect interested in. | |||
*/ | |||
protected void checkXMLAspectCount(String projectName, String aspectName, | |||
int expectedOccurrences, String outputDir) { | |||
int aspectCount = 0; | |||
File aopXML = new File(outputDir + File.separatorChar + "META-INF" + File.separatorChar + "aop-ajc.xml"); | |||
if (!aopXML.exists()) { | |||
fail("Expected file " + aopXML.getAbsolutePath() + " to exist but it doesn't"); | |||
} | |||
try { | |||
BufferedReader reader = new BufferedReader(new FileReader(aopXML)); | |||
String line = reader.readLine(); | |||
while (line != null) { | |||
if (aspectName.equals("") && line.indexOf("aspect name=\"") != -1) { | |||
aspectCount++; | |||
} else if (line.indexOf("aspect name=\""+aspectName+"\"") != -1) { | |||
aspectCount++; | |||
} | |||
line = reader.readLine(); | |||
} | |||
reader.close(); | |||
} catch (IOException ie) { | |||
ie.printStackTrace(); | |||
} | |||
if (aspectCount != expectedOccurrences) { | |||
fail("Expected aspect " + aspectName + " to appear " + expectedOccurrences + " times" + | |||
" in the aop.xml file but found " + aspectCount + " occurrences"); | |||
} | |||
} | |||
} |
@@ -83,6 +83,10 @@ public class AjdeInteractionTestbed extends TestCase { | |||
MyProjectPropertiesAdapter.setOutputLocationManager(mgr); | |||
} | |||
public static void configureOutputLocationManager(OutputLocationManager mgr, boolean hasOutputPath) { | |||
MyProjectPropertiesAdapter.setOutputLocationManager(mgr,hasOutputPath); | |||
} | |||
public static void configureResourceMap(Map resourcesMap) { | |||
MyProjectPropertiesAdapter.setSourcePathResources(resourcesMap); | |||
} | |||
@@ -101,11 +105,14 @@ public class AjdeInteractionTestbed extends TestCase { | |||
// Create a sandbox in which to work | |||
sandboxDir = Ajc.createEmptySandbox(); | |||
IncrementalStateManager.debugIncrementalStates = true; | |||
} | |||
protected void tearDown() throws Exception { | |||
super.tearDown(); | |||
AjState.stateListener=null; | |||
IncrementalStateManager.clearIncrementalStates(); | |||
} | |||
/** Drives a build */ | |||
@@ -284,6 +291,26 @@ public class AjdeInteractionTestbed extends TestCase { | |||
System.out.println("============================================="); | |||
} | |||
/** | |||
* Check we compiled/wove the right number of files, passing '-1' indicates you don't care about | |||
* that number. | |||
*/ | |||
public void checkCompileWeaveCount(int expCompile,int expWoven) { | |||
if (expCompile!=-1 && getCompiledFiles().size()!=expCompile) | |||
fail("Expected compilation of "+expCompile+" files but compiled "+getCompiledFiles().size()+ | |||
"\n"+printCompiledAndWovenFiles()); | |||
if (expWoven!=-1 && getWovenClasses().size()!=expWoven) | |||
fail("Expected weaving of "+expWoven+" files but wove "+getWovenClasses().size()+ | |||
"\n"+printCompiledAndWovenFiles()); | |||
} | |||
public void checkWasntFullBuild() { | |||
assertTrue("Shouldn't have been a full (batch) build",!wasFullBuild()); | |||
} | |||
public void checkWasFullBuild() { | |||
assertTrue("Should have been a full (batch) build",wasFullBuild()); | |||
} | |||
public boolean wasFullBuild() { | |||
// alternatives: statelistener is debug interface, progressmonitor is new proper interface (see pr145689) | |||
@@ -361,7 +388,6 @@ public class AjdeInteractionTestbed extends TestCase { | |||
static MyProjectPropertiesAdapter _instance = new MyProjectPropertiesAdapter(); | |||
private MyProjectPropertiesAdapter() {} | |||
public static MyProjectPropertiesAdapter getInstance() { | |||
return _instance; | |||
} | |||
@@ -371,14 +397,18 @@ public class AjdeInteractionTestbed extends TestCase { | |||
_instance.inpath = null; | |||
_instance.sourcePathResources=null; | |||
_instance.outputLocationManager=null; | |||
_instance.hasOutputPath = true; | |||
_instance.outputPath = null; | |||
} | |||
private String projectName = null; | |||
private String outputPath = null; | |||
private String classPath = ""; | |||
private Set aspectPath = null; | |||
private Set inpath = null; | |||
private Map sourcePathResources = null; | |||
private OutputLocationManager outputLocationManager = null; | |||
private boolean hasOutputPath = true; | |||
public static void setActiveProject(String n) { | |||
_instance.projectName = n; | |||
@@ -409,10 +439,9 @@ public class AjdeInteractionTestbed extends TestCase { | |||
_instance.aspectPath = path; | |||
} | |||
public static void setInpath(Set inpath) { | |||
_instance.inpath = inpath; | |||
public static void setInpath(Set path) { | |||
_instance.inpath = path; | |||
} | |||
// interface impl below | |||
@@ -457,7 +486,22 @@ public class AjdeInteractionTestbed extends TestCase { | |||
// DOESSOMETHING | |||
public String getClasspath() { | |||
log("MyProjectProperties.getClasspath()"); | |||
// AJDT has all the output directories on it's classpath | |||
StringBuffer sb = new StringBuffer(); | |||
String outputPath = getOutputPath(); | |||
sb.append(outputPath); | |||
if (outputLocationManager != null) { | |||
List allOutputPaths = outputLocationManager.getAllOutputLocations(); | |||
for (Iterator iterator = allOutputPaths.iterator(); iterator | |||
.hasNext();) { | |||
File dir = (File) iterator.next(); | |||
if (!dir.getAbsolutePath().equals(getOutputPath())) { | |||
sb.append(File.pathSeparator + dir.getAbsolutePath()); | |||
} | |||
} | |||
} | |||
String cp = | |||
sb.toString() + File.pathSeparator + | |||
new File(testdataSrcDir) + File.pathSeparator + | |||
System.getProperty("sun.boot.class.path") + | |||
File.pathSeparator + "../runtime/bin" + | |||
@@ -482,9 +526,17 @@ public class AjdeInteractionTestbed extends TestCase { | |||
} | |||
public String getOutputPath() { | |||
if (!hasOutputPath) return null; | |||
String dir = getFile(projectName,"bin"); | |||
log("MyProjectProperties.getOutputPath() [returning "+dir+"]"); | |||
return dir; | |||
//return null; | |||
} | |||
public static void setOutputLocationManager(OutputLocationManager mgr,boolean hasOutputPath ) { | |||
_instance.hasOutputPath = hasOutputPath; | |||
_instance.outputLocationManager = mgr; | |||
} | |||
public static void setOutputLocationManager(OutputLocationManager mgr) { | |||
@@ -492,7 +544,11 @@ public class AjdeInteractionTestbed extends TestCase { | |||
} | |||
public OutputLocationManager getOutputLocationManager() { | |||
return this.outputLocationManager; | |||
return outputLocationManager; | |||
// if (testHasSetOutputLocationManager) { | |||
// return outputLocationManager; | |||
// } | |||
// return new MyOutputLocationManager(sandboxDir + File.separator + projectName); | |||
} | |||
public String getBootClasspath() { | |||
@@ -521,7 +577,7 @@ public class AjdeInteractionTestbed extends TestCase { | |||
} | |||
public Set getInpath() { | |||
log("MyProjectProperties.getInPath(" + inpath +")"); | |||
log("MyProjectProperties.getInPath(" + inpath + ")"); | |||
return inpath; | |||
} | |||
@@ -835,6 +891,44 @@ public class AjdeInteractionTestbed extends TestCase { | |||
return false; | |||
} | |||
} | |||
// ---- | |||
static class MyOutputLocationManager implements OutputLocationManager { | |||
private File classOutputLoc; | |||
private File resourceOutputLoc; | |||
private String testProjectOutputPath; | |||
private List allOutputLocations; | |||
private File outputLoc; | |||
public MyOutputLocationManager(String testProjectPath) { | |||
this.testProjectOutputPath = testProjectPath + File.separator + "bin"; | |||
outputLoc = new File(testProjectOutputPath); | |||
allOutputLocations = new ArrayList(); | |||
allOutputLocations.add(outputLoc); | |||
} | |||
public File getOutputLocationForClass(File compilationUnit) { | |||
return outputLoc; | |||
} | |||
public File getOutputLocationForResource(File resource) { | |||
return outputLoc; | |||
} | |||
public List /*File*/ getAllOutputLocations() { | |||
return allOutputLocations; | |||
} | |||
public File getDefaultOutputLocation() { | |||
return outputLoc; | |||
} | |||
} | |||
// ---- | |||
static class MyStateListener extends AbstractStateListener { | |||
@@ -0,0 +1,87 @@ | |||
/******************************************************************** | |||
* Copyright (c) 2006 Contributors. 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://eclipse.org/legal/epl-v10.html | |||
* | |||
* Contributors: IBM Corporation - initial API and implementation | |||
* Helen Hawkins - initial version | |||
*******************************************************************/ | |||
package org.aspectj.systemtest.incremental.tools; | |||
import java.io.File; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
import org.aspectj.ajde.OutputLocationManager; | |||
/** | |||
* OutputLocationManger tests which check whether the correct type of build has happened. | |||
*/ | |||
public class IncrementalOutputLocationManagerTests extends AbstractMultiProjectIncrementalAjdeInteractionTestbed { | |||
public void testPr166580() { | |||
initialiseProject("PR166580"); | |||
configureOutputLocationManager(new MyOutputLocationManager("PR166580",2)); | |||
build("PR166580"); | |||
checkWasFullBuild(); | |||
alter("PR166580","inc1"); | |||
build("PR166580"); | |||
checkWasntFullBuild(); | |||
} | |||
/** | |||
* Will send output from src dir 'srcX' to directory 'binX' | |||
*/ | |||
private class MyOutputLocationManager implements OutputLocationManager { | |||
private String projectDir; | |||
private int numberOfSrcDirs; | |||
private List allOutputDirs; | |||
public MyOutputLocationManager(String projectName, int numberOfSrcDirs) { | |||
projectDir = getWorkingDir() + File.separator + projectName; | |||
this.numberOfSrcDirs = numberOfSrcDirs; | |||
} | |||
public File getOutputLocationForClass(File compilationUnit) { | |||
String path = compilationUnit.getAbsolutePath(); | |||
int index = path.indexOf("src"); | |||
String number = path.substring(index +3,index + 4); | |||
File ret = new File(projectDir + File.separator + "bin" + number); | |||
if (!ret.exists()) { | |||
ret.mkdirs(); | |||
} | |||
return ret; | |||
} | |||
public File getOutputLocationForResource(File resource) { | |||
return getOutputLocationForClass(resource); | |||
} | |||
public List getAllOutputLocations() { | |||
if (allOutputDirs == null) { | |||
allOutputDirs = new ArrayList(); | |||
for (int i = 0; i < numberOfSrcDirs + 1; i++) { | |||
File f = null; | |||
if (i == 0) { | |||
f = new File(projectDir + File.separator + "bin"); | |||
} else { | |||
f = new File(projectDir + File.separator + "bin" + i); | |||
} | |||
allOutputDirs.add(f); | |||
} | |||
} | |||
return allOutputDirs; | |||
} | |||
public File getDefaultOutputLocation() { | |||
return new File(projectDir + File.separator + "bin"); | |||
} | |||
} | |||
} |
@@ -0,0 +1,375 @@ | |||
/******************************************************************** | |||
* Copyright (c) 2006 Contributors. 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://eclipse.org/legal/epl-v10.html | |||
* | |||
* Contributors: IBM Corporation - initial API and implementation | |||
* Helen Hawkins - initial version | |||
*******************************************************************/ | |||
package org.aspectj.systemtest.incremental.tools; | |||
import java.io.File; | |||
import java.util.ArrayList; | |||
import java.util.HashSet; | |||
import java.util.Iterator; | |||
import java.util.List; | |||
import java.util.Map; | |||
import java.util.Set; | |||
import org.aspectj.ajde.OutputLocationManager; | |||
import org.aspectj.ajdt.internal.core.builder.AjBuildConfig; | |||
import org.aspectj.ajdt.internal.core.builder.AjBuildManager; | |||
import org.aspectj.ajdt.internal.core.builder.AjState; | |||
import org.aspectj.ajdt.internal.core.builder.IncrementalStateManager; | |||
import org.aspectj.util.FileUtil; | |||
import org.aspectj.weaver.bcel.UnwovenClassFile; | |||
/** | |||
* Similar to OutputLocationManagerTests, however, tests the different | |||
* scenarios when no outputDir is set but instead there is an | |||
* OutputLocationManager which returns the same output location for all | |||
* files and resources. | |||
* | |||
* There are eight places where AjBuildConfig.getOutputDir() is called | |||
* that are tested here: | |||
* | |||
* AjBuildManager.getOutputClassFileName(..) - testCorrectInfoWhenNoOutputPath | |||
* AjBuildManager.initBcelWorld(..) - testPathResolutionWithInpathDirAndNoOutputPath | |||
* testPathResolutionWithInpathJarAndNoOutputPath | |||
* AjBuildManager.writeManifest(..) - testCopyManifest | |||
* AjBuildManager.writeOutxml(..) - testOutxml | |||
* - testOutXmlForAspectsWithDifferentOutputDirs | |||
* AjState.createUnwovenClassFile(..) - testPathResolutionAfterChangeInClassOnInpath | |||
* AjState.deleteResources(..) - testAjStateDeleteResources | |||
* AjState.maybeDeleteResources(..) - testAjStateDeleteResourcesInInputDir | |||
* AjState.removeAllResultsOfLastBuild(..) - testAllResourcesAreDeletedCorrectlyOnPathChange | |||
* IncrementalStateManager.findStateManagingOutputLocation(..) - testFindStateManagingOutputLocation | |||
* | |||
* The other three places are not tested here because they were implemented | |||
* when OutputLocationManager was introduced. | |||
* | |||
*/ | |||
public class MoreOutputLocationManagerTests extends AbstractMultiProjectIncrementalAjdeInteractionTestbed { | |||
private String inpathTestingDir; | |||
private String expectedOutputDir; | |||
protected void setUp() throws Exception { | |||
super.setUp(); | |||
initialiseProject("inpathTesting"); | |||
inpathTestingDir = getWorkingDir() + File.separator + "inpathTesting"; | |||
expectedOutputDir = inpathTestingDir + File.separator + "bin"; | |||
configureOutputLocationManager(new MyOutputLocationManager(inpathTestingDir), false); | |||
} | |||
/** | |||
* Tests that the UnwovenClassFiles have the correct path when there | |||
* is no outputDir but there is an OutputLocationManager. Is a simple | |||
* project that has no inpath setting | |||
*/ | |||
public void testCorrectInfoWhenNoOutputPath() { | |||
build("inpathTesting"); | |||
AjState state = getState(); | |||
Map classNameToFileMap = state.getClassNameToFileMap(); | |||
assertFalse("expected there to be classes ",classNameToFileMap.isEmpty()); | |||
Set entrySet = classNameToFileMap.entrySet(); | |||
for (Iterator iterator = entrySet.iterator(); iterator.hasNext();) { | |||
Map.Entry entry = (Map.Entry) iterator.next(); | |||
String className = (String) entry.getKey(); | |||
String fullClassName = expectedOutputDir + File.separator + className.replace('.',File.separatorChar) + ".class"; | |||
File file = (File) entry.getValue(); | |||
assertEquals("expected file to have path \n" + fullClassName + ", but" + | |||
" found path \n" + file.getAbsolutePath(),fullClassName, | |||
file.getAbsolutePath()); | |||
} | |||
} | |||
/** | |||
* Tests that can retieve the state that manages a given output location | |||
* when there is no outputDir set | |||
*/ | |||
public void testFindStateManagingOutputLocation() { | |||
build("inpathTesting"); | |||
AjState state = IncrementalStateManager.findStateManagingOutputLocation(new File(expectedOutputDir)); | |||
assertNotNull("Expected to find a state that managed output location " + | |||
expectedOutputDir + ", but did not", state); | |||
} | |||
/** | |||
* Tests that the UnwovenClassFiles corresponding to classes on the | |||
* inpath have the correct class name when there is no output directory | |||
* (ultimately tests AjBuildManager.initBcelWorld() when there is a | |||
* jar on the inpath). Only does one build. | |||
*/ | |||
public void testPathResolutionWithInpathDirAndNoOutputPath() { | |||
String inpathDir = inpathTestingDir + File.separator + "injarBin" + File.separator + "pkg"; | |||
addInpathEntry(inpathDir); | |||
build("inpathTesting"); | |||
// expect to compile the aspect in 'inpathTesting' project and weave | |||
// both the aspect and the class on the inpath. | |||
checkCompileWeaveCount(1,2); | |||
// get hold of the state for this project - expect to find one | |||
AjState state = getState(); | |||
// the classes onthe inpath are recorded against the AjBuildManager | |||
// (they are deleted from the ajstate whilst cleaning up after a build) | |||
Map binarySources = state.getAjBuildManager().getBinarySourcesForThisWeave(); | |||
assertFalse("expected there to be binary sources from the inpath setting but didn't find any",binarySources.isEmpty()); | |||
List unwovenClassFiles = (List) binarySources.get(inpathDir + File.separator + "InpathClass.class"); | |||
List fileNames = new ArrayList(); | |||
// the unwovenClassFiles should have filenames that point to the output dir | |||
// (which in this case is the sandbox dir) and not where they came from. | |||
for (Iterator iterator = unwovenClassFiles.iterator(); iterator.hasNext();) { | |||
UnwovenClassFile ucf = (UnwovenClassFile) iterator.next(); | |||
if (ucf.getFilename().indexOf(expectedOutputDir) == -1) { | |||
fileNames.add(ucf.getFilename()); | |||
} | |||
} | |||
assertTrue("expected to find UnwovenClassFile from directory\n" + expectedOutputDir + | |||
", \n but found files " + fileNames, fileNames.isEmpty()); | |||
} | |||
/** | |||
* Tests that the UnwovenClassFiles corresponding to classes on the | |||
* inpath have the correct class name when there is no output directory | |||
* (ultimately tests AjState.createUnwovenClassFile(BinarySourceFile) | |||
* and ensures the unwovenClassFile has the correct name. Makes a change to | |||
* a class file on the inpath to ensure we enter this method (there is a | |||
* check that says are we the first build)) | |||
*/ | |||
public void testPathResolutionAfterChangeInClassOnInpath() throws Exception { | |||
String inpathDir = inpathTestingDir + File.separator + "injarBin" + File.separator + "pkg"; | |||
addInpathEntry(inpathDir); | |||
build("inpathTesting"); | |||
// build again so that we enter | |||
// AjState.createUnwovenClassFile(BinarySourceFile) | |||
File from = new File(testdataSrcDir+File.separatorChar+"inpathTesting" | |||
+File.separatorChar+"newInpathClass" + File.separatorChar + "InpathClass.class"); | |||
File destination = new File(inpathDir + File.separatorChar + "InpathClass.class"); | |||
FileUtil.copyFile(from,destination); | |||
// get hold of the state for this project - expect to find one | |||
AjState state = getState(); | |||
AjBuildConfig buildConfig = state.getBuildConfig(); | |||
state.prepareForNextBuild(buildConfig); | |||
Map binarySources = state.getBinaryFilesToCompile(true); | |||
assertFalse("expected there to be binary sources from the inpath setting but didn't find any",binarySources.isEmpty()); | |||
List unwovenClassFiles = (List) binarySources.get(inpathDir + File.separator + "InpathClass.class"); | |||
List fileNames = new ArrayList(); | |||
// the unwovenClassFiles should have filenames that point to the output dir | |||
// (which in this case is the sandbox dir) and not where they came from. | |||
for (Iterator iterator = unwovenClassFiles.iterator(); iterator.hasNext();) { | |||
UnwovenClassFile ucf = (UnwovenClassFile) iterator.next(); | |||
if (ucf.getFilename().indexOf(expectedOutputDir) == -1) { | |||
fileNames.add(ucf.getFilename()); | |||
} | |||
} | |||
assertTrue("expected to find UnwovenClassFile from directory\n" + expectedOutputDir + | |||
", \n but found files " + fileNames, fileNames.isEmpty()); | |||
} | |||
/** | |||
* Tests that the UnwovenClassFiles corresponding to jars on the | |||
* inpath have the correct class name when there is no output path | |||
* (ultimately tests AjBuildManager.initBcelWorld() when there is a | |||
* jar on the inpath). Only does one build. | |||
*/ | |||
public void testPathResolutionWithInpathJarAndNoOutputPath() { | |||
String inpathDir = inpathTestingDir + File.separator + "inpathJar.jar"; | |||
addInpathEntry(inpathDir); | |||
build("inpathTesting"); | |||
// expect to compile the aspect in 'inpathTesting' project and weave | |||
// both the aspect and the class in the jar on the inpath. | |||
checkCompileWeaveCount(1,2); | |||
AjState state = getState(); | |||
// tests AjState.createUnwovenClassFile(BinarySourceFile) | |||
Map binarySources = state.getAjBuildManager().getBinarySourcesForThisWeave(); | |||
assertFalse("expected there to be binary sources from the inpath setting but didn't find any",binarySources.isEmpty()); | |||
List unwovenClassFiles = (List) binarySources.get(inpathDir); | |||
List fileNames = new ArrayList(); | |||
for (Iterator iterator = unwovenClassFiles.iterator(); iterator.hasNext();) { | |||
UnwovenClassFile ucf = (UnwovenClassFile) iterator.next(); | |||
if (ucf.getFilename().indexOf(expectedOutputDir) == -1) { | |||
fileNames.add(ucf.getFilename()); | |||
} | |||
} | |||
assertTrue("expected to find UnwovenClassFile from directory\n" + expectedOutputDir + | |||
", \n but found files " + fileNames, fileNames.isEmpty()); | |||
} | |||
/** | |||
* A manifest file is in the jar on the inpath - check that it's | |||
* copied to the correct place | |||
*/ | |||
public void testCopyManifest() { | |||
String inpathDir = inpathTestingDir + File.separator + "inpathJar.jar"; | |||
addInpathEntry(inpathDir); | |||
build("inpathTesting"); | |||
String resource = expectedOutputDir + File.separator + "META-INF" + File.separator + "MANIFEST.MF"; | |||
File f = new File(resource); | |||
assertTrue("expected file " + resource + " to exist but it did not",f.exists()); | |||
} | |||
/** | |||
* "resources" are contained within inpath jars - check that | |||
* a text file contained within a jar is copied and then | |||
* deleted correctly. Essentially tests AjState.deleteResources(). | |||
*/ | |||
public void testAjStateDeleteResources() { | |||
String inpathDir = inpathTestingDir + File.separator + "inpathJar.jar"; | |||
addInpathEntry(inpathDir); | |||
build("inpathTesting"); | |||
AjState state = getState(); | |||
String resource = expectedOutputDir + File.separator + "inpathResource.txt"; | |||
File f = new File(resource); | |||
assertTrue("expected file " + resource + " to exist but it did not",f.exists()); | |||
// this call should delete the resources | |||
state.getFilesToCompile(true); | |||
assertFalse("did not expect the file " + resource + " to exist but it does",f.exists()); | |||
} | |||
/** | |||
* Can set to copy resources that are in inpath dirs - check that | |||
* a text file contained within such a dir is copied and then | |||
* deleted correctly. Essentially tests AjState.maybeDeleteResources(). | |||
*/ | |||
public void testAjStateDeleteResourcesInInputDir() { | |||
AjBuildManager.COPY_INPATH_DIR_RESOURCES = true; | |||
try { | |||
String inpathDir = inpathTestingDir + File.separator + "injarBin" | |||
+ File.separator + "pkg"; | |||
addInpathEntry(inpathDir); | |||
build("inpathTesting"); | |||
AjState state = getState(); | |||
String resource = "inDirResource.txt"; | |||
assertTrue("expected state to have resource " + resource + "but it did not", | |||
state.hasResource(resource)); | |||
// this call should delete the resources - tests AjState.deleteResources() | |||
state.getFilesToCompile(true); | |||
assertFalse("did not expect state to have resource " + resource + | |||
" but found that it did", state.hasResource(resource)); | |||
} finally { | |||
AjBuildManager.COPY_INPATH_DIR_RESOURCES = false; | |||
} | |||
} | |||
/** | |||
* Changing inpath entry from a jar to a directory between builds means | |||
* that AjState should realise somethings changed. This causes all resources | |||
* (Manifest and txt files) to be deleted. Also should be a full build. | |||
* Essentially tests AjState.removeAllResultsFromLastBuild(). | |||
*/ | |||
public void testAllResourcesAreDeletedCorrectlyOnPathChange() { | |||
String inpathJar = inpathTestingDir + File.separator + "inpathJar.jar"; | |||
addInpathEntry(inpathJar); | |||
build("inpathTesting"); | |||
String resource = expectedOutputDir + File.separator + "inpathResource.txt"; | |||
File f = new File(resource); | |||
assertTrue("expected file " + resource + " to exist but it did not",f.exists()); | |||
// this should force a change and the file is deleted | |||
// tests AjState.removeAllResultsFromLastBuild() | |||
addInpathEntry(null); | |||
build("inpathTesting"); | |||
assertFalse("did not expect the file " + resource + " to exist but it does",f.exists()); | |||
checkWasFullBuild(); | |||
} | |||
public void testOutxml() { | |||
configureNonStandardCompileOptions("-outxml"); | |||
build("inpathTesting"); | |||
String resource = expectedOutputDir + File.separator + "META-INF" + File.separator + "aop-ajc.xml"; | |||
File f = new File(resource); | |||
assertTrue("expected file " + resource + " to exist but it did not",f.exists()); | |||
} | |||
public void testAspectsRecordedOnlyOnceInState() { | |||
configureNonStandardCompileOptions("-outxml"); | |||
build("inpathTesting"); | |||
AjState state = getState(); | |||
Map m = state.getAspectNamesToFileNameMap(); | |||
assertEquals("Expected only one aspect recored in the state but found " + m.size(),1,m.size()); | |||
build("inpathTesting"); | |||
m = state.getAspectNamesToFileNameMap(); | |||
assertEquals("Expected only one aspect recored in the state but found " + m.size(),1,m.size()); | |||
} | |||
private AjState getState() { | |||
// get hold of the state for this project - expect to find one | |||
AjState state = IncrementalStateManager.retrieveStateFor(inpathTestingDir + File.separator + "build.lst" ); | |||
assertNotNull("expected to find AjState for build config " + inpathTestingDir | |||
+ File.separator + "build.lst but didn't", state); | |||
return state; | |||
} | |||
private void addInpathEntry(String entry) { | |||
if (entry == null) { | |||
configureInPath(null); | |||
return; | |||
} | |||
File f = new File(entry); | |||
Set s = new HashSet(); | |||
s.add(f); | |||
configureInPath(s); | |||
} | |||
/** | |||
* Sends all output to the same directory | |||
*/ | |||
private static class SingleDirOutputLocMgr implements OutputLocationManager { | |||
private File classOutputLoc; | |||
private File resourceOutputLoc; | |||
private String testProjectOutputPath; | |||
private List allOutputLocations; | |||
private File outputLoc; | |||
public SingleDirOutputLocMgr(String testProjectPath) { | |||
this.testProjectOutputPath = testProjectPath + File.separator + "bin"; | |||
outputLoc = new File(testProjectOutputPath); | |||
allOutputLocations = new ArrayList(); | |||
allOutputLocations.add(outputLoc); | |||
} | |||
public File getOutputLocationForClass(File compilationUnit) { | |||
return outputLoc; | |||
} | |||
public File getOutputLocationForResource(File resource) { | |||
return outputLoc; | |||
} | |||
public List /*File*/ getAllOutputLocations() { | |||
return allOutputLocations; | |||
} | |||
public File getDefaultOutputLocation() { | |||
return outputLoc; | |||
} | |||
} | |||
} |
@@ -11,9 +11,7 @@ | |||
* ******************************************************************/ | |||
package org.aspectj.systemtest.incremental.tools; | |||
import java.io.BufferedReader; | |||
import java.io.File; | |||
import java.io.FileReader; | |||
import java.io.IOException; | |||
import java.util.ArrayList; | |||
import java.util.HashSet; | |||
@@ -1013,46 +1011,48 @@ public class MultiProjectIncrementalTests extends AbstractMultiProjectIncrementa | |||
initialiseProject("PR131505"); | |||
build("PR131505"); | |||
checkWasFullBuild(); | |||
String outputDir = getWorkingDir().getAbsolutePath() + File.separatorChar | |||
+ "PR131505" + File.separatorChar + "bin"; | |||
// aop.xml file shouldn't contain any aspects | |||
checkXMLAspectCount("PR131505","",0); | |||
checkXMLAspectCount("PR131505","",0, outputDir); | |||
// add a new aspect A which should be included in the aop.xml file | |||
alter("PR131505","inc1"); | |||
build("PR131505"); | |||
checkWasFullBuild(); | |||
checkXMLAspectCount("PR131505","",1); | |||
checkXMLAspectCount("PR131505","A",1); | |||
checkXMLAspectCount("PR131505","",1, outputDir); | |||
checkXMLAspectCount("PR131505","A",1, outputDir); | |||
// make changes to the class file which shouldn't affect the contents | |||
// of the aop.xml file | |||
alter("PR131505","inc2"); | |||
build("PR131505"); | |||
checkWasntFullBuild(); | |||
checkXMLAspectCount("PR131505","",1); | |||
checkXMLAspectCount("PR131505","A",1); | |||
checkXMLAspectCount("PR131505","",1, outputDir); | |||
checkXMLAspectCount("PR131505","A",1, outputDir); | |||
// add another new aspect A1 which should also be included in the aop.xml file | |||
// ...there should be no duplicate entries in the file | |||
alter("PR131505","inc3"); | |||
build("PR131505"); | |||
checkWasFullBuild(); | |||
checkXMLAspectCount("PR131505","",2); | |||
checkXMLAspectCount("PR131505","A1",1); | |||
checkXMLAspectCount("PR131505","A",1); | |||
checkXMLAspectCount("PR131505","",2, outputDir); | |||
checkXMLAspectCount("PR131505","A1",1, outputDir); | |||
checkXMLAspectCount("PR131505","A",1, outputDir); | |||
// delete aspect A1 which meanss that aop.xml file should only contain A | |||
File a1 = new File(getWorkingDir().getAbsolutePath() | |||
+ File.separatorChar + "PR131505" + File.separatorChar + "A1.aj"); | |||
a1.delete(); | |||
build("PR131505"); | |||
checkWasFullBuild(); | |||
checkXMLAspectCount("PR131505","",1); | |||
checkXMLAspectCount("PR131505","A1",0); | |||
checkXMLAspectCount("PR131505","A",1); | |||
checkXMLAspectCount("PR131505","",1, outputDir); | |||
checkXMLAspectCount("PR131505","A1",0, outputDir); | |||
checkXMLAspectCount("PR131505","A",1, outputDir); | |||
// add another aspect called A which is in a different package, both A | |||
// and pkg.A should be included in the aop.xml file | |||
alter("PR131505","inc4"); | |||
build("PR131505"); | |||
checkWasFullBuild(); | |||
checkXMLAspectCount("PR131505","",2); | |||
checkXMLAspectCount("PR131505","A",1); | |||
checkXMLAspectCount("PR131505","pkg.A",1); | |||
checkXMLAspectCount("PR131505","",2, outputDir); | |||
checkXMLAspectCount("PR131505","A",1, outputDir); | |||
checkXMLAspectCount("PR131505","pkg.A",1, outputDir); | |||
} | |||
public void testPr136585() { | |||
@@ -1673,7 +1673,7 @@ public class MultiProjectIncrementalTests extends AbstractMultiProjectIncrementa | |||
" error but only found that one",errors.size() > 1); | |||
} | |||
} | |||
public void testPr168840() throws Exception { | |||
initialiseProject("inpathTesting"); | |||
@@ -1800,26 +1800,6 @@ public class MultiProjectIncrementalTests extends AbstractMultiProjectIncrementa | |||
// --------------------------------------------------------------------------------------------------- | |||
/** | |||
* Check we compiled/wove the right number of files, passing '-1' indicates you don't care about | |||
* that number. | |||
*/ | |||
private void checkCompileWeaveCount(int expCompile,int expWoven) { | |||
if (expCompile!=-1 && getCompiledFiles().size()!=expCompile) | |||
fail("Expected compilation of "+expCompile+" files but compiled "+getCompiledFiles().size()+ | |||
"\n"+printCompiledAndWovenFiles()); | |||
if (expWoven!=-1 && getWovenClasses().size()!=expWoven) | |||
fail("Expected weaving of "+expWoven+" files but wove "+getWovenClasses().size()+ | |||
"\n"+printCompiledAndWovenFiles()); | |||
} | |||
private void checkWasntFullBuild() { | |||
assertTrue("Shouldn't have been a full (batch) build",!wasFullBuild()); | |||
} | |||
private void checkWasFullBuild() { | |||
assertTrue("Should have been a full (batch) build",wasFullBuild()); | |||
} | |||
private IProgramElement checkForNode(String packageName,String typeName,boolean shouldBeFound) { | |||
IProgramElement ipe = AsmManager.getDefault().getHierarchy().findElementForType(packageName,typeName); | |||
@@ -1842,59 +1822,10 @@ public class MultiProjectIncrementalTests extends AbstractMultiProjectIncrementa | |||
} | |||
} | |||
/* | |||
* Applies an overlay onto the project being tested - copying | |||
* the contents of the specified overlay directory. | |||
*/ | |||
private void alter(String projectName,String overlayDirectory) { | |||
File projectSrc =new File(testdataSrcDir+File.separatorChar+projectName+ | |||
File.separatorChar+overlayDirectory); | |||
File destination=new File(getWorkingDir(),projectName); | |||
copy(projectSrc,destination); | |||
} | |||
private static void log(String msg) { | |||
if (VERBOSE) System.out.println(msg); | |||
} | |||
/** | |||
* Count the number of times a specified aspectName appears in the default | |||
* aop.xml file and compare with the expected number of occurrences. If just | |||
* want to count the number of aspects mentioned within the file then | |||
* pass "" for the aspectName, otherwise, specify the name of the | |||
* aspect interested in. | |||
*/ | |||
private void checkXMLAspectCount(String projectName, String aspectName, int expectedOccurrences) { | |||
int aspectCount = 0; | |||
File aopXML = new File(getWorkingDir().getAbsolutePath() | |||
+ File.separatorChar + projectName + File.separatorChar | |||
+ "bin" + File.separatorChar + "META-INF" + File.separatorChar + "aop-ajc.xml"); | |||
if (!aopXML.exists()) { | |||
fail("Expected file " + aopXML.getAbsolutePath() + " to exist but it doesn't"); | |||
} | |||
try { | |||
BufferedReader reader = new BufferedReader(new FileReader(aopXML)); | |||
String line = reader.readLine(); | |||
while (line != null) { | |||
if (aspectName.equals("") && line.indexOf("aspect name=\"") != -1) { | |||
aspectCount++; | |||
} else if (line.indexOf("aspect name=\""+aspectName+"\"") != -1) { | |||
aspectCount++; | |||
} | |||
line = reader.readLine(); | |||
} | |||
reader.close(); | |||
} catch (IOException ie) { | |||
ie.printStackTrace(); | |||
} | |||
if (aspectCount != expectedOccurrences) { | |||
fail("Expected aspect " + aspectName + " to appear " + expectedOccurrences + " times" + | |||
" in the aop.xml file but found " + aspectCount + " occurrences"); | |||
} | |||
} | |||
private File getProjectRelativePath(String p,String filename) { | |||
File projDir = new File(getWorkingDir(),p); | |||
return new File(projDir,filename); |
@@ -12,7 +12,9 @@ | |||
package org.aspectj.systemtest.incremental.tools; | |||
import java.io.File; | |||
import java.util.ArrayList; | |||
import java.util.HashMap; | |||
import java.util.List; | |||
import java.util.Map; | |||
import org.aspectj.ajde.OutputLocationManager; | |||
@@ -64,6 +66,27 @@ public class OutputLocationManagerTests extends AbstractMultiProjectIncrementalA | |||
assertFileExists(PROJECT_NAME,"target/main/classes/a/A$AjcClosure1.class"); | |||
} | |||
/** | |||
* Tests the case when we have two aspects, each of which are | |||
* sent to a different output location. There should be an | |||
* aop.xml file in each of the two output directories. | |||
*/ | |||
public void testOutXmlForAspectsWithDifferentOutputDirs() { | |||
configureNonStandardCompileOptions("-outxml"); | |||
build(PROJECT_NAME); | |||
assertFileExists(PROJECT_NAME,"target/main/classes/META-INF/aop-ajc.xml"); | |||
assertFileExists(PROJECT_NAME,"target/test/classes/META-INF/aop-ajc.xml"); | |||
// aop.xml file should exist even if there aren't any aspects (mirrors | |||
// what happens when there's one output dir) | |||
checkXMLAspectCount(PROJECT_NAME,"",0,getFile(PROJECT_NAME,"target/anotherTest/classes")); | |||
// add aspects to the srcRootThree src dir and they should appear in the | |||
// corresponding aop.xml file | |||
alter(PROJECT_NAME,"inc1"); | |||
build(PROJECT_NAME); | |||
checkXMLAspectCount(PROJECT_NAME,"c.C$AnAspect",1,getFile(PROJECT_NAME,"target/anotherTest/classes")); | |||
} | |||
protected void assertFileExists(String project, String relativePath) { | |||
assertTrue("file " + relativePath + " should have been created as a result of building " + project, | |||
new File(getFile(project, relativePath)).exists()); | |||
@@ -72,9 +95,11 @@ public class OutputLocationManagerTests extends AbstractMultiProjectIncrementalA | |||
private static class MyOutputLocationManager implements OutputLocationManager { | |||
private File projectHome; | |||
private List allOutputDirs; | |||
public MyOutputLocationManager(File projectHome) { | |||
this.projectHome = projectHome; | |||
} | |||
public File getOutputLocationForClass(File compilationUnit) { | |||
@@ -84,6 +109,8 @@ public class OutputLocationManagerTests extends AbstractMultiProjectIncrementalA | |||
relativePath = "target/main/classes"; | |||
} else if (compilationUnitName.indexOf("srcRootTwo") != -1) { | |||
relativePath = "target/test/classes"; | |||
} else if (compilationUnitName.indexOf("srcRootThree") != -1) { | |||
relativePath = "target/anotherTest/classes"; | |||
} | |||
File ret = new File(projectHome,relativePath); | |||
if (!ret.exists()) { | |||
@@ -95,6 +122,19 @@ public class OutputLocationManagerTests extends AbstractMultiProjectIncrementalA | |||
public File getOutputLocationForResource(File resource) { | |||
return getOutputLocationForClass(resource); | |||
} | |||
public List getAllOutputLocations() { | |||
if (allOutputDirs == null) { | |||
allOutputDirs = new ArrayList(); | |||
allOutputDirs.add(new File(projectHome,"target/main/classes")); | |||
allOutputDirs.add(new File(projectHome,"target/test/classes")); | |||
allOutputDirs.add(new File(projectHome,"target/anotherTest/classes")); | |||
} | |||
return allOutputDirs; | |||
} | |||
public File getDefaultOutputLocation() { | |||
return new File(projectHome,"target/main/classes"); | |||
} | |||
} | |||
} |