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
9 * Adrian Colyer initial implementation
10 * Helen Hawkins Converted to new interface (bug 148190)
11 *******************************************************************/
12 package org.aspectj.systemtest.incremental.tools;
14 import java.io.BufferedReader;
15 import java.io.ByteArrayOutputStream;
16 import java.io.DataOutputStream;
18 import java.io.FileOutputStream;
19 import java.io.FileReader;
20 import java.io.IOException;
21 import java.io.PrintStream;
22 import java.io.PrintWriter;
24 import java.net.URLClassLoader;
25 import java.util.ArrayList;
26 import java.util.Iterator;
27 import java.util.List;
30 import org.aspectj.ajdt.internal.core.builder.AjState;
31 import org.aspectj.asm.IProgramElement;
32 import org.aspectj.asm.IRelationship;
33 import org.aspectj.asm.IRelationshipMap;
34 import org.aspectj.testing.util.FileUtil;
36 public class AbstractMultiProjectIncrementalAjdeInteractionTestbed extends AjdeInteractionTestbed {
38 public static boolean VERBOSE = false;
40 public static void dumptree(IProgramElement node, int indent) {
41 for (int i = 0; i < indent; i++) {
42 System.out.print(" ");
46 if (node.getSourceLocation() != null) {
47 loc = Integer.toString(node.getSourceLocation().getLine());
50 // System.out.println(node + " [" + (node == null ? "null" : node.getKind().toString()) + "] " + loc);
51 System.out.println(node + " [" + (node == null ? "null" : node.getKind().toString()) + "] " + loc
52 + (node == null ? "" : " hid:" + node.getHandleIdentifier()));
54 // for (int i = 0; i < indent; i++)
55 // System.out.print(" ");
56 // System.out.println(" hid is " + node.getHandleIdentifier());
57 // Map m = ((ProgramElement) node).kvpairs;
59 // Set keys = m.keySet();
60 // for (Iterator iterator = keys.iterator(); iterator.hasNext();) {
61 // Object object = (Object) iterator.next();
63 // for (int i = 0; i < indent; i++)
64 // System.out.print(" ");
65 // System.out.println("kvp: " + object + " = " + m.get(object));
68 for (IProgramElement iProgramElement : node.getChildren()) {
69 dumptree(iProgramElement, indent + 2);
74 protected void setUp() throws Exception {
76 AjdeInteractionTestbed.VERBOSE = VERBOSE;
77 AjState.FORCE_INCREMENTAL_DURING_TESTING = true;
80 protected void tearDown() throws Exception {
82 AjState.FORCE_INCREMENTAL_DURING_TESTING = false;
85 protected String runMethod(String projectName, String classname, String methodname) throws Exception {
86 File f = getProjectOutputRelativePath(projectName, "");
87 ClassLoader cl = new URLClassLoader(new URL[] { f.toURI().toURL() });
88 Class<?> clazz = Class.forName(classname, false, cl);
89 ByteArrayOutputStream baos = new ByteArrayOutputStream();
90 PrintStream realOut = System.out;
92 System.setOut(new PrintStream(baos));
93 clazz.getDeclaredMethod(methodname).invoke(null);
95 System.setOut(realOut);
97 return new String(baos.toByteArray());
100 protected File getProjectOutputRelativePath(String p, String filename) {
101 File projDir = new File(getWorkingDir(), p);
102 return new File(projDir, "bin" + File.separator + filename);
105 public void build(String projectName) {
106 constructUpToDateLstFile(projectName, "build.lst");
107 doBuild(projectName);
108 if (AjdeInteractionTestbed.VERBOSE)
109 printBuildReport(projectName);
112 public int getRelationshipCount(String project) {
113 IRelationshipMap relmap = getModelFor(project).getRelationshipMap();
115 Set<String> entries = relmap.getEntries();
116 for (String hid : entries) {
117 List<IRelationship> rels = relmap.get(hid);
118 for (IRelationship rel : rels) {
119 ctr += rel.getTargets().size();
125 public void fullBuild(String projectName) {
126 constructUpToDateLstFile(projectName, "build.lst");
127 doFullBuild(projectName);
128 if (AjdeInteractionTestbed.VERBOSE)
129 printBuildReport(projectName);
132 private void constructUpToDateLstFile(String pname, String configname) {
133 File projectBase = new File(sandboxDir, pname);
134 File toConstruct = new File(projectBase, configname);
135 List<String> filesForCompilation = new ArrayList<String>();
136 collectUpFiles(projectBase, projectBase, filesForCompilation);
139 FileOutputStream fos = new FileOutputStream(toConstruct);
140 DataOutputStream dos = new DataOutputStream(fos);
141 for (String file: filesForCompilation) {
142 dos.writeBytes(file + "\n");
145 } catch (IOException ioe) {
146 ioe.printStackTrace();
150 private void collectUpFiles(File location, File base, List<String> collectionPoint) {
151 String contents[] = location.list();
152 if (contents == null)
154 for (String string : contents) {
155 File f = new File(location, string);
156 if (f.isDirectory()) {
157 collectUpFiles(f, base, collectionPoint);
158 } else if (f.isFile() && (f.getName().endsWith(".aj") || f.getName().endsWith(".java"))) {
161 fileFound = f.getCanonicalPath();
162 String toRemove = base.getCanonicalPath();
163 if (!fileFound.startsWith(toRemove))
164 throw new RuntimeException("eh? " + fileFound + " " + toRemove);
165 collectionPoint.add(fileFound.substring(toRemove.length() + 1));// +1 captures extra separator
166 } catch (IOException e) {
174 * Fill in the working directory with the project base files, from the 'base' folder.
176 protected void initialiseProject(String p) {
177 File projectSrc = new File(testdataSrcDir + File.separatorChar + p + File.separatorChar + "base");
178 File destination = new File(getWorkingDir(), p);
179 if (!destination.exists()) {
182 copy(projectSrc, destination);// ,false);
183 // create the AjCompiler instance associated with this project
184 // (has id of the form c:\temp\ajcSandbox\<workspace_name>\<project_name>)
185 CompilerFactory.getCompilerForProjectWithDir(sandboxDir + File.separator + p);
189 * Applies an overlay onto the project being tested - copying the contents of the specified overlay directory.
191 public void alter(String projectName, String overlayDirectory) {
192 File projectSrc = new File(testdataSrcDir + File.separatorChar + projectName + File.separatorChar + overlayDirectory);
193 File destination = new File(getWorkingDir(), projectName);
195 if (AjdeInteractionTestbed.VERBOSE)
196 System.out.println("Altering project " + projectName);
197 copy(projectSrc, destination);
201 * Copy the contents of some directory to another location - the copy is recursive.
203 protected void copy(File from, File to) {
204 String contents[] = from.list();
205 if (contents == null)
207 for (String string : contents) {
208 File f = new File(from, string);
209 File t = new File(to, string);
211 if (f.isDirectory() && !f.getName().startsWith("inc")) {
214 } else if (f.isFile()) {
215 StringBuffer sb = new StringBuffer();
216 // if (VERBOSE) System.err.println("Copying "+f+" to "+t);
217 FileUtil.copyFile(f, t, sb);
218 if (sb.length() != 0) {
219 System.err.println(sb.toString());
226 * Count the number of times a specified aspectName appears in the default aop.xml file and compare with the expected number of
227 * occurrences. If just want to count the number of aspects mentioned within the file then pass "" for the aspectName,
228 * otherwise, specify the name of the aspect interested in.
230 protected void checkXMLAspectCount(String projectName, String aspectName, int expectedOccurrences, String outputDir) {
232 File aopXML = new File(outputDir + File.separatorChar + "META-INF" + File.separatorChar + "aop-ajc.xml");
234 if (!aopXML.exists()) {
235 fail("Expected file " + aopXML.getAbsolutePath() + " to exist but it doesn't");
238 BufferedReader reader = new BufferedReader(new FileReader(aopXML));
239 String line = reader.readLine();
240 while (line != null) {
241 if (aspectName.equals("") && line.indexOf("aspect name=\"") != -1) {
243 } else if (line.indexOf("aspect name=\"" + aspectName + "\"") != -1) {
246 line = reader.readLine();
249 } catch (IOException ie) {
250 ie.printStackTrace();
252 if (aspectCount != expectedOccurrences) {
253 fail("Expected aspect " + aspectName + " to appear " + expectedOccurrences + " times"
254 + " in the aop.xml file but found " + aspectCount + " occurrences");
258 protected void assertContains(String expectedSubstring, Object object) {
259 String actualString = object.toString();
260 if (actualString.indexOf(expectedSubstring) == -1) {
261 fail("Expected to find '" + expectedSubstring + "' in '" + actualString + "'");
265 /** @return the number of relationship pairs */
266 protected void printModel(String projectName) throws Exception {
267 dumptree(getModelFor(projectName).getHierarchy().getRoot(), 0);
268 PrintWriter pw = new PrintWriter(System.out);
269 getModelFor(projectName).dumprels(pw);
273 protected File getProjectRelativePath(String p, String filename) {
274 File projDir = new File(getWorkingDir(), p);
275 return new File(projDir, filename);
278 protected void assertNoErrors(String projectName) {
279 assertTrue("Should be no errors, but got " + getErrorMessages(projectName), getErrorMessages(projectName).size() == 0);