123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381 |
- /********************************************************************
- * 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.Collections;
- import java.util.HashSet;
- import java.util.Iterator;
- import java.util.List;
- import java.util.Map;
- import java.util.Set;
-
- import org.aspectj.ajde.core.IOutputLocationManager;
- import org.aspectj.ajdt.internal.core.builder.AjBuildConfig;
- 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;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- initialiseProject("inpathTesting");
- inpathTestingDir = getWorkingDir() + File.separator + "inpathTesting";
- expectedOutputDir = inpathTestingDir + File.separator + "bin";
- configureOutputLocationManager("inpathTesting", new SingleDirOutputLocMgr(inpathTestingDir));
- }
-
- /**
- * 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<String,File> classNameToFileMap = state.getClassNameToFileMap();
- assertFalse("expected there to be classes ", classNameToFileMap.isEmpty());
- Set<Map.Entry<String,File>> entrySet = classNameToFileMap.entrySet();
- for (Map.Entry<String, File> entry : entrySet) {
- String className = entry.getKey();
- String fullClassName = expectedOutputDir + File.separator + className.replace('.', File.separatorChar) + ".class";
- 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("inpathTesting", 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<String,List<UnwovenClassFile>> binarySources = state.getAjBuildManager().getBinarySourcesForThisWeave();
- assertFalse("expected there to be binary sources from the inpath setting but didn't find any", binarySources.isEmpty());
-
- List<UnwovenClassFile> unwovenClassFiles = binarySources.get(inpathDir + File.separator + "InpathClass.class");
- List<String> 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 (UnwovenClassFile ucf: unwovenClassFiles) {
- if (!ucf.getFilename().contains(expectedOutputDir)) {
- 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<String, List<UnwovenClassFile>> binarySources = state.getBinaryFilesToCompile(true);
- assertFalse("expected there to be binary sources from the inpath setting but didn't find any", binarySources.isEmpty());
-
- List<UnwovenClassFile> unwovenClassFiles = binarySources.get(inpathDir + File.separator + "InpathClass.class");
- List<String> 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 (UnwovenClassFile ucf: unwovenClassFiles) {
- if (!ucf.getFilename().contains(expectedOutputDir)) {
- 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("inpathTesting", 1, 2);
-
- AjState state = getState();
-
- // tests AjState.createUnwovenClassFile(BinarySourceFile)
- Map<String,List<UnwovenClassFile>> binarySources = state.getAjBuildManager().getBinarySourcesForThisWeave();
- assertFalse("expected there to be binary sources from the inpath setting but didn't find any", binarySources.isEmpty());
-
- List<UnwovenClassFile> unwovenClassFiles = binarySources.get(inpathDir);
- List<String> fileNames = new ArrayList<>();
-
- for (UnwovenClassFile ucf: unwovenClassFiles) {
- if (!ucf.getFilename().contains(expectedOutputDir)) {
- 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().
- */
- // see 243376: for now don't do this, waste of cpu - ajdt better for handling resources - but is that true for inpath resources?
- // 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().
- */
- // see 243376: for now don't do this, waste of cpu - ajdt better for handling resources - but is that true for inpath resources?
- // public void testAjStateDeleteResourcesInInputDir() {
- // // temporary problem with this on linux, think it is a filesystem lastmodtime issue
- // if (System.getProperty("os.name","").toLowerCase().equals("linux")) return;
- // if (System.getProperty("os.name","").toLowerCase().indexOf("mac")!=-1) return;
- //
- // 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("inpathTesting", "-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("inpathTesting", "-outxml");
- build("inpathTesting");
- AjState state = getState();
- Map<String,char[]> 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);
- assertNotNull("expected to find AjState for build config " + inpathTestingDir + " but didn't", state);
- return state;
- }
-
- private void addInpathEntry(String entry) {
- if (entry == null) {
- configureInPath("inpathTesting", (Set)null);
- return;
- }
- File f = new File(entry);
- Set<File> s = new HashSet<>();
- s.add(f);
- configureInPath("inpathTesting", s);
- }
-
- /**
- * Sends all output to the same directory
- */
- private static class SingleDirOutputLocMgr implements IOutputLocationManager {
-
- private File classOutputLoc;
- private File resourceOutputLoc;
- private String testProjectOutputPath;
- private List<File> allOutputLocations;
- private File outputLoc;
-
- public SingleDirOutputLocMgr(String testProjectPath) {
- this.testProjectOutputPath = testProjectPath + File.separator + "bin";
- outputLoc = new File(testProjectOutputPath);
-
- allOutputLocations = new ArrayList<>();
- allOutputLocations.add(outputLoc);
- }
-
- @Override
- public File getOutputLocationForClass(File compilationUnit) {
- return outputLoc;
- }
-
- @Override
- public Map<File,String> getInpathMap() {
- return Collections.emptyMap();
- }
-
-
- @Override
- public File getOutputLocationForResource(File resource) {
- return outputLoc;
- }
-
- @Override
- public List<File> getAllOutputLocations() {
- return allOutputLocations;
- }
-
- @Override
- public File getDefaultOutputLocation() {
- return outputLoc;
- }
-
- @Override
- public void reportFileWrite(String outputfile, int filetype) {
- }
-
- @Override
- public void reportFileRemove(String outputfile, int filetype) {
- }
-
- @Override
- public String getSourceFolderForFile(File sourceFile) {
- return null; // no impl
- }
-
- @Override
- public int discoverChangesSince(File dir, long buildtime) {
- return 0; // no impl
- }
- }
-
- }
|