You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

MoreOutputLocationManagerTests.java 15KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  1. /********************************************************************
  2. * Copyright (c) 2006 Contributors. All rights reserved.
  3. * This program and the accompanying materials are made available
  4. * under the terms of the Eclipse Public License v1.0
  5. * which accompanies this distribution and is available at
  6. * http://eclipse.org/legal/epl-v10.html
  7. *
  8. * Contributors: IBM Corporation - initial API and implementation
  9. * Helen Hawkins - initial version
  10. *******************************************************************/
  11. package org.aspectj.systemtest.incremental.tools;
  12. import java.io.File;
  13. import java.util.ArrayList;
  14. import java.util.HashSet;
  15. import java.util.Iterator;
  16. import java.util.List;
  17. import java.util.Map;
  18. import java.util.Set;
  19. import org.aspectj.ajde.core.IOutputLocationManager;
  20. import org.aspectj.ajdt.internal.core.builder.AjBuildConfig;
  21. import org.aspectj.ajdt.internal.core.builder.AjBuildManager;
  22. import org.aspectj.ajdt.internal.core.builder.AjState;
  23. import org.aspectj.ajdt.internal.core.builder.IncrementalStateManager;
  24. import org.aspectj.util.FileUtil;
  25. import org.aspectj.weaver.bcel.UnwovenClassFile;
  26. /**
  27. * Similar to OutputLocationManagerTests, however, tests the different
  28. * scenarios when no outputDir is set but instead there is an
  29. * OutputLocationManager which returns the same output location for all
  30. * files and resources.
  31. *
  32. * There are eight places where AjBuildConfig.getOutputDir() is called
  33. * that are tested here:
  34. *
  35. * AjBuildManager.getOutputClassFileName(..) - testCorrectInfoWhenNoOutputPath
  36. * AjBuildManager.initBcelWorld(..) - testPathResolutionWithInpathDirAndNoOutputPath
  37. * testPathResolutionWithInpathJarAndNoOutputPath
  38. * AjBuildManager.writeManifest(..) - testCopyManifest
  39. * AjBuildManager.writeOutxml(..) - testOutxml
  40. * - testOutXmlForAspectsWithDifferentOutputDirs
  41. * AjState.createUnwovenClassFile(..) - testPathResolutionAfterChangeInClassOnInpath
  42. * AjState.deleteResources(..) - testAjStateDeleteResources
  43. * AjState.maybeDeleteResources(..) - testAjStateDeleteResourcesInInputDir
  44. * AjState.removeAllResultsOfLastBuild(..) - testAllResourcesAreDeletedCorrectlyOnPathChange
  45. * IncrementalStateManager.findStateManagingOutputLocation(..) - testFindStateManagingOutputLocation
  46. *
  47. * The other three places are not tested here because they were implemented
  48. * when OutputLocationManager was introduced.
  49. *
  50. */
  51. public class MoreOutputLocationManagerTests extends AbstractMultiProjectIncrementalAjdeInteractionTestbed {
  52. private String inpathTestingDir;
  53. private String expectedOutputDir;
  54. protected void setUp() throws Exception {
  55. super.setUp();
  56. initialiseProject("inpathTesting");
  57. inpathTestingDir = getWorkingDir() + File.separator + "inpathTesting";
  58. expectedOutputDir = inpathTestingDir + File.separator + "bin";
  59. configureOutputLocationManager("inpathTesting",new SingleDirOutputLocMgr(inpathTestingDir));
  60. }
  61. /**
  62. * Tests that the UnwovenClassFiles have the correct path when there
  63. * is no outputDir but there is an OutputLocationManager. Is a simple
  64. * project that has no inpath setting
  65. */
  66. public void testCorrectInfoWhenNoOutputPath() {
  67. build("inpathTesting");
  68. AjState state = getState();
  69. Map classNameToFileMap = state.getClassNameToFileMap();
  70. assertFalse("expected there to be classes ",classNameToFileMap.isEmpty());
  71. Set entrySet = classNameToFileMap.entrySet();
  72. for (Iterator iterator = entrySet.iterator(); iterator.hasNext();) {
  73. Map.Entry entry = (Map.Entry) iterator.next();
  74. String className = (String) entry.getKey();
  75. String fullClassName = expectedOutputDir + File.separator + className.replace('.',File.separatorChar) + ".class";
  76. File file = (File) entry.getValue();
  77. assertEquals("expected file to have path \n" + fullClassName + ", but" +
  78. " found path \n" + file.getAbsolutePath(),fullClassName,
  79. file.getAbsolutePath());
  80. }
  81. }
  82. /**
  83. * Tests that can retieve the state that manages a given output location
  84. * when there is no outputDir set
  85. */
  86. public void testFindStateManagingOutputLocation() {
  87. build("inpathTesting");
  88. AjState state = IncrementalStateManager.findStateManagingOutputLocation(new File(expectedOutputDir));
  89. assertNotNull("Expected to find a state that managed output location " +
  90. expectedOutputDir + ", but did not", state);
  91. }
  92. /**
  93. * Tests that the UnwovenClassFiles corresponding to classes on the
  94. * inpath have the correct class name when there is no output directory
  95. * (ultimately tests AjBuildManager.initBcelWorld() when there is a
  96. * jar on the inpath). Only does one build.
  97. */
  98. public void testPathResolutionWithInpathDirAndNoOutputPath() {
  99. String inpathDir = inpathTestingDir + File.separator + "injarBin" + File.separator + "pkg";
  100. addInpathEntry(inpathDir);
  101. build("inpathTesting");
  102. // expect to compile the aspect in 'inpathTesting' project and weave
  103. // both the aspect and the class on the inpath.
  104. checkCompileWeaveCount("inpathTesting",1,2);
  105. // get hold of the state for this project - expect to find one
  106. AjState state = getState();
  107. // the classes onthe inpath are recorded against the AjBuildManager
  108. // (they are deleted from the ajstate whilst cleaning up after a build)
  109. Map binarySources = state.getAjBuildManager().getBinarySourcesForThisWeave();
  110. assertFalse("expected there to be binary sources from the inpath setting but didn't find any",binarySources.isEmpty());
  111. List unwovenClassFiles = (List) binarySources.get(inpathDir + File.separator + "InpathClass.class");
  112. List fileNames = new ArrayList();
  113. // the unwovenClassFiles should have filenames that point to the output dir
  114. // (which in this case is the sandbox dir) and not where they came from.
  115. for (Iterator iterator = unwovenClassFiles.iterator(); iterator.hasNext();) {
  116. UnwovenClassFile ucf = (UnwovenClassFile) iterator.next();
  117. if (ucf.getFilename().indexOf(expectedOutputDir) == -1) {
  118. fileNames.add(ucf.getFilename());
  119. }
  120. }
  121. assertTrue("expected to find UnwovenClassFile from directory\n" + expectedOutputDir +
  122. ", \n but found files " + fileNames, fileNames.isEmpty());
  123. }
  124. /**
  125. * Tests that the UnwovenClassFiles corresponding to classes on the
  126. * inpath have the correct class name when there is no output directory
  127. * (ultimately tests AjState.createUnwovenClassFile(BinarySourceFile)
  128. * and ensures the unwovenClassFile has the correct name. Makes a change to
  129. * a class file on the inpath to ensure we enter this method (there is a
  130. * check that says are we the first build))
  131. */
  132. public void testPathResolutionAfterChangeInClassOnInpath() throws Exception {
  133. String inpathDir = inpathTestingDir + File.separator + "injarBin" + File.separator + "pkg";
  134. addInpathEntry(inpathDir);
  135. build("inpathTesting");
  136. // build again so that we enter
  137. // AjState.createUnwovenClassFile(BinarySourceFile)
  138. File from = new File(testdataSrcDir+File.separatorChar+"inpathTesting"
  139. +File.separatorChar+"newInpathClass" + File.separatorChar + "InpathClass.class");
  140. File destination = new File(inpathDir + File.separatorChar + "InpathClass.class");
  141. FileUtil.copyFile(from,destination);
  142. // get hold of the state for this project - expect to find one
  143. AjState state = getState();
  144. AjBuildConfig buildConfig = state.getBuildConfig();
  145. state.prepareForNextBuild(buildConfig);
  146. Map binarySources = state.getBinaryFilesToCompile(true);
  147. assertFalse("expected there to be binary sources from the inpath setting but didn't find any",binarySources.isEmpty());
  148. List unwovenClassFiles = (List) binarySources.get(inpathDir + File.separator + "InpathClass.class");
  149. List fileNames = new ArrayList();
  150. // the unwovenClassFiles should have filenames that point to the output dir
  151. // (which in this case is the sandbox dir) and not where they came from.
  152. for (Iterator iterator = unwovenClassFiles.iterator(); iterator.hasNext();) {
  153. UnwovenClassFile ucf = (UnwovenClassFile) iterator.next();
  154. if (ucf.getFilename().indexOf(expectedOutputDir) == -1) {
  155. fileNames.add(ucf.getFilename());
  156. }
  157. }
  158. assertTrue("expected to find UnwovenClassFile from directory\n" + expectedOutputDir +
  159. ", \n but found files " + fileNames, fileNames.isEmpty());
  160. }
  161. /**
  162. * Tests that the UnwovenClassFiles corresponding to jars on the
  163. * inpath have the correct class name when there is no output path
  164. * (ultimately tests AjBuildManager.initBcelWorld() when there is a
  165. * jar on the inpath). Only does one build.
  166. */
  167. public void testPathResolutionWithInpathJarAndNoOutputPath() {
  168. String inpathDir = inpathTestingDir + File.separator + "inpathJar.jar";
  169. addInpathEntry(inpathDir);
  170. build("inpathTesting");
  171. // expect to compile the aspect in 'inpathTesting' project and weave
  172. // both the aspect and the class in the jar on the inpath.
  173. checkCompileWeaveCount("inpathTesting",1,2);
  174. AjState state = getState();
  175. // tests AjState.createUnwovenClassFile(BinarySourceFile)
  176. Map binarySources = state.getAjBuildManager().getBinarySourcesForThisWeave();
  177. assertFalse("expected there to be binary sources from the inpath setting but didn't find any",binarySources.isEmpty());
  178. List unwovenClassFiles = (List) binarySources.get(inpathDir);
  179. List fileNames = new ArrayList();
  180. for (Iterator iterator = unwovenClassFiles.iterator(); iterator.hasNext();) {
  181. UnwovenClassFile ucf = (UnwovenClassFile) iterator.next();
  182. if (ucf.getFilename().indexOf(expectedOutputDir) == -1) {
  183. fileNames.add(ucf.getFilename());
  184. }
  185. }
  186. assertTrue("expected to find UnwovenClassFile from directory\n" + expectedOutputDir +
  187. ", \n but found files " + fileNames, fileNames.isEmpty());
  188. }
  189. /**
  190. * A manifest file is in the jar on the inpath - check that it's
  191. * copied to the correct place
  192. */
  193. public void testCopyManifest() {
  194. String inpathDir = inpathTestingDir + File.separator + "inpathJar.jar";
  195. addInpathEntry(inpathDir);
  196. build("inpathTesting");
  197. String resource = expectedOutputDir + File.separator + "META-INF" + File.separator + "MANIFEST.MF";
  198. File f = new File(resource);
  199. assertTrue("expected file " + resource + " to exist but it did not",f.exists());
  200. }
  201. /**
  202. * "resources" are contained within inpath jars - check that
  203. * a text file contained within a jar is copied and then
  204. * deleted correctly. Essentially tests AjState.deleteResources().
  205. */
  206. public void testAjStateDeleteResources() {
  207. String inpathDir = inpathTestingDir + File.separator + "inpathJar.jar";
  208. addInpathEntry(inpathDir);
  209. build("inpathTesting");
  210. AjState state = getState();
  211. String resource = expectedOutputDir + File.separator + "inpathResource.txt";
  212. File f = new File(resource);
  213. assertTrue("expected file " + resource + " to exist but it did not",f.exists());
  214. // this call should delete the resources
  215. state.getFilesToCompile(true);
  216. assertFalse("did not expect the file " + resource + " to exist but it does",f.exists());
  217. }
  218. /**
  219. * Can set to copy resources that are in inpath dirs - check that
  220. * a text file contained within such a dir is copied and then
  221. * deleted correctly. Essentially tests AjState.maybeDeleteResources().
  222. */
  223. public void testAjStateDeleteResourcesInInputDir() {
  224. // temporary problem with this on linux, think it is a filesystem lastmodtime issue
  225. if (System.getProperty("os.name","").toLowerCase().equals("linux")) return;
  226. if (System.getProperty("os.name","").toLowerCase().indexOf("mac")!=-1) return;
  227. AjBuildManager.COPY_INPATH_DIR_RESOURCES = true;
  228. try {
  229. String inpathDir = inpathTestingDir + File.separator + "injarBin"
  230. + File.separator + "pkg";
  231. addInpathEntry(inpathDir);
  232. build("inpathTesting");
  233. AjState state = getState();
  234. String resource = "inDirResource.txt";
  235. assertTrue("expected state to have resource " + resource + "but it did not",
  236. state.hasResource(resource));
  237. // this call should delete the resources - tests AjState.deleteResources()
  238. state.getFilesToCompile(true);
  239. assertFalse("did not expect state to have resource " + resource +
  240. " but found that it did", state.hasResource(resource));
  241. } finally {
  242. AjBuildManager.COPY_INPATH_DIR_RESOURCES = false;
  243. }
  244. }
  245. /**
  246. * Changing inpath entry from a jar to a directory between builds means
  247. * that AjState should realise somethings changed. This causes all resources
  248. * (Manifest and txt files) to be deleted. Also should be a full build.
  249. * Essentially tests AjState.removeAllResultsFromLastBuild().
  250. */
  251. public void testAllResourcesAreDeletedCorrectlyOnPathChange() {
  252. String inpathJar = inpathTestingDir + File.separator + "inpathJar.jar";
  253. addInpathEntry(inpathJar);
  254. build("inpathTesting");
  255. String resource = expectedOutputDir + File.separator + "inpathResource.txt";
  256. File f = new File(resource);
  257. assertTrue("expected file " + resource + " to exist but it did not",f.exists());
  258. // this should force a change and the file is deleted
  259. // tests AjState.removeAllResultsFromLastBuild()
  260. addInpathEntry(null);
  261. build("inpathTesting");
  262. assertFalse("did not expect the file " + resource + " to exist but it does",f.exists());
  263. checkWasFullBuild();
  264. }
  265. public void testOutxml() {
  266. configureNonStandardCompileOptions("inpathTesting","-outxml");
  267. build("inpathTesting");
  268. String resource = expectedOutputDir + File.separator + "META-INF" + File.separator + "aop-ajc.xml";
  269. File f = new File(resource);
  270. assertTrue("expected file " + resource + " to exist but it did not",f.exists());
  271. }
  272. public void testAspectsRecordedOnlyOnceInState() {
  273. configureNonStandardCompileOptions("inpathTesting","-outxml");
  274. build("inpathTesting");
  275. AjState state = getState();
  276. Map m = state.getAspectNamesToFileNameMap();
  277. assertEquals("Expected only one aspect recored in the state but found " + m.size(),1,m.size());
  278. build("inpathTesting");
  279. m = state.getAspectNamesToFileNameMap();
  280. assertEquals("Expected only one aspect recored in the state but found " + m.size(),1,m.size());
  281. }
  282. private AjState getState() {
  283. // get hold of the state for this project - expect to find one
  284. AjState state = IncrementalStateManager.retrieveStateFor(inpathTestingDir);
  285. assertNotNull("expected to find AjState for build config " + inpathTestingDir
  286. + " but didn't", state);
  287. return state;
  288. }
  289. private void addInpathEntry(String entry) {
  290. if (entry == null) {
  291. configureInPath("inpathTesting",null);
  292. return;
  293. }
  294. File f = new File(entry);
  295. Set s = new HashSet();
  296. s.add(f);
  297. configureInPath("inpathTesting",s);
  298. }
  299. /**
  300. * Sends all output to the same directory
  301. */
  302. private static class SingleDirOutputLocMgr implements IOutputLocationManager {
  303. private File classOutputLoc;
  304. private File resourceOutputLoc;
  305. private String testProjectOutputPath;
  306. private List allOutputLocations;
  307. private File outputLoc;
  308. public SingleDirOutputLocMgr(String testProjectPath) {
  309. this.testProjectOutputPath = testProjectPath + File.separator + "bin";
  310. outputLoc = new File(testProjectOutputPath);
  311. allOutputLocations = new ArrayList();
  312. allOutputLocations.add(outputLoc);
  313. }
  314. public File getOutputLocationForClass(File compilationUnit) {
  315. return outputLoc;
  316. }
  317. public File getOutputLocationForResource(File resource) {
  318. return outputLoc;
  319. }
  320. public List /*File*/ getAllOutputLocations() {
  321. return allOutputLocations;
  322. }
  323. public File getDefaultOutputLocation() {
  324. return outputLoc;
  325. }
  326. }
  327. }