diff options
author | Andy Clement <aclement@pivotal.io> | 2019-01-30 16:15:14 -0800 |
---|---|---|
committer | Andy Clement <aclement@pivotal.io> | 2019-01-30 16:15:14 -0800 |
commit | f4d5e9485ae910220e06b0b6c778587ed6b4ebb3 (patch) | |
tree | 077bc311c2f2532a81483ad8c05fa898c6b40269 /testing/src/test/java/org/aspectj/internal/tools/ant | |
parent | cda73a6a5864b76e252ed0d3b69ff4b55a6def4b (diff) | |
download | aspectj-f4d5e9485ae910220e06b0b6c778587ed6b4ebb3.tar.gz aspectj-f4d5e9485ae910220e06b0b6c778587ed6b4ebb3.zip |
mavenizing testing - done
Diffstat (limited to 'testing/src/test/java/org/aspectj/internal/tools/ant')
-rw-r--r-- | testing/src/test/java/org/aspectj/internal/tools/ant/taskdefs/Ajctest.java | 1900 | ||||
-rw-r--r-- | testing/src/test/java/org/aspectj/internal/tools/ant/taskdefs/MainWrapper.java | 181 |
2 files changed, 2081 insertions, 0 deletions
diff --git a/testing/src/test/java/org/aspectj/internal/tools/ant/taskdefs/Ajctest.java b/testing/src/test/java/org/aspectj/internal/tools/ant/taskdefs/Ajctest.java new file mode 100644 index 000000000..8fb274176 --- /dev/null +++ b/testing/src/test/java/org/aspectj/internal/tools/ant/taskdefs/Ajctest.java @@ -0,0 +1,1900 @@ +/* ******************************************************************* + * Copyright (c) 1999-2001 Xerox Corporation, + * 2002 Palo Alto Research Center, Incorporated (PARC). + * 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://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Xerox/PARC initial implementation + * ******************************************************************/ + + +package org.aspectj.internal.tools.ant.taskdefs; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Font; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.awt.LayoutManager; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintStream; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.text.DateFormat; +//import java.util.Collection; +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.StringTokenizer; +import java.util.Vector; + +import javax.swing.BorderFactory; +import javax.swing.BoxLayout; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JSplitPane; +import javax.swing.JTable; +import javax.swing.JTextArea; +import javax.swing.JTextField; +import javax.swing.ListSelectionModel; +import javax.swing.border.BevelBorder; +import javax.swing.event.ListSelectionEvent; +import javax.swing.table.DefaultTableModel; +import javax.swing.table.TableModel; +import javax.swing.text.StyleContext; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Location; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.Target; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.taskdefs.Delete; +//import org.apache.tools.ant.taskdefs.ExecTask; +import org.apache.tools.ant.taskdefs.Java; +import org.apache.tools.ant.taskdefs.LogOutputStream; +import org.apache.tools.ant.taskdefs.Mkdir; +import org.apache.tools.ant.taskdefs.StreamPumper; +import org.apache.tools.ant.types.Commandline; +import org.apache.tools.ant.types.FileSet; +import org.apache.tools.ant.types.Path; +import org.apache.tools.ant.types.Reference; +import org.aspectj.util.LangUtil; + +public class Ajctest extends Task implements PropertyChangeListener { + private static Ajctest CURRENT_AJCTEST; + + // todo shutdown hook assumes one task per VM + public Ajctest() { + super(); + CURRENT_AJCTEST = this; + } + + private static boolean firstTime = true; + + public final PropertyChangeSupport bean = new PropertyChangeSupport(this); + + { + bean.addPropertyChangeListener(this); + } + + public void propertyChange(PropertyChangeEvent evt) { + String name = evt.getPropertyName(); + if ("ajdoc.good".equals(name)) ajdocStats.goods++; + else if ("ajc.good".equals(name)) ajcStats.goods++; + else if ("run.good".equals(name)) runStats.goods++; + if ("ajdoc.fail".equals(name)) ajdocStats.fails++; + else if ("ajc.fail".equals(name)) ajcStats.fails++; + else if ("run.fail".equals(name)) runStats.fails++; + } + + private void fire(String prop, Object oldval, Object newval) { + bean.firePropertyChange(prop, oldval, newval); + } + + private void fire(String prop) { + fire(prop, "dummy-old", "dummy-new"); + } + + private static boolean dumpresults = false; + private Stats ajdocStats = new Stats(); + private Stats ajcStats = new Stats(); + private Stats runStats = new Stats(); +// private Stats errorStats = new Stats(); + private static final String NO_TESTID = "NONE"; + private File workingdir = new File("ajworkingdir"); //XXX + + //fields + private String testId = NO_TESTID; + private List<Argument> args = new Vector<>(); + private List<Testset> testsets = new Vector<>(); + private Path classpath; + private Path internalclasspath; + private File destdir; + private File dir; + private File errorfile; + private List<Run> testclasses = new Vector<>(); + private boolean nocompile; + private Ajdoc ajdoc = null; + private boolean noclean; + private boolean noverify; + private List<String> depends = new Vector<>(); + //end-fields + + public Argfile createArgfile() { + return createTestset().createArgfile(); + } + + public void setNoverify(boolean input) { + if (input != noverify) noverify = input; + } + + public void setOwningTarget(Target target) { + super.setOwningTarget(target); + if (null != target) { + //setTestId(target.getName()); + } + } + + public void setTestId(String str) { + if ((null != str) && (0 < str.trim().length())) { + testId = str; + } + } + + public void setArgs(String str) { + if (str == null || str.length() < 1) return; + StringTokenizer tok = new StringTokenizer(str, ",", false); + while (tok.hasMoreTokens()) { + String name = tok.nextToken().trim(); + if (0 < name.length()) { + parse(name.startsWith("J") ? createJarg() : createArg(), name); + } + } + } + + private void parse(Argument arg, String name) { + int itilde = name.lastIndexOf("~"); + if (itilde != -1) { + name = name.substring(0, itilde) + name.substring(itilde+1); + } + int ieq = name.lastIndexOf("="); + int icolon = name.lastIndexOf(":"); + int ileft = name.lastIndexOf("["); + int iright = name.lastIndexOf("]"); + boolean always = true; + String rest = ""; + String newName = name; + if (ieq != -1) { + rest = name.substring(ieq+1); + newName = name.substring(0, ieq); + always = true; + } else if (icolon != -1) { + rest = name.substring(icolon+1); + newName = name.substring(0, icolon); + always = false; + } else if (ileft != -1) { + newName = name.substring(0, ileft); + always = true; + } + String values = ileft == -1 ? rest : + name.substring(ileft+1, iright > ileft ? iright : rest.length()-1); + String value = null; + if (itilde != -1) { + String prop = project.getUserProperty(values); + if (prop == null) { + prop = project.getProperty(values); + } + if (prop != null) { + value = prop; + } + } + if (value != null) { + arg.setValue(value); + } else { + arg.setValues(values); + } + arg.setName(newName); + arg.setAlways(always); + } + + public Argument createJarg() { + Argument arg = new Argument(true); + args.add(arg); + return arg; + } + + + public Argument createArg() { + Argument arg = new Argument(false); + args.add(arg); + return arg; + } + + public void setClasspath(Path path) { + if (classpath == null) { + classpath = path; + } else { + classpath.append(path); + } + } + + public Path createClasspath() { + if (classpath == null) { + classpath = new Path(project); + } + return classpath.createPath(); + } + + public void setClasspathRef(Reference r) { + createClasspath().setRefid(r); + } + + public void setInternalclasspath(Path path) { + if (internalclasspath == null) { + internalclasspath = path; + } else { + internalclasspath.append(path); + } + } + + public Path createInternalclasspath() { + if (internalclasspath == null) { + internalclasspath = new Path(project); + } + return internalclasspath.createPath(); + } + + public void setInternalclasspathRef(Reference r) { + createInternalclasspath().setRefid(r); + } + + public void setDestdir(String destdir) { + this.destdir = project.resolveFile(destdir); + } + + public void setDir(File dir) { + this.dir = dir; + } + + public void setErrorfile(File errorfile) { + this.errorfile = errorfile; + } + + public Run createJava() { + Run testclass = new Run(project); + testclasses.add(testclass); + return testclass; + } + + public void setClasses(String str) { + for (StringTokenizer t = new StringTokenizer(str, ", ", false); + t.hasMoreTokens();) { + createJava().setClassname(t.nextToken().trim()); + } + } + + public void setTestclass(String testclass) { + createJava().setClassname(testclass); + } + + public void setAjdoc(boolean b) { + if (b && ajdoc == null) { + createAjdoc(); + } else if (!b) { + ajdoc = null; + } + } + + public void setAjdocargs(String str) { + createAjdoc(); + for (StringTokenizer t = new StringTokenizer(str, ", ", false); + t.hasMoreTokens();) { + ajdoc.createArg().setValue(t.nextToken().trim()); + } + } + + public void addAjdoc(Ajdoc ajdoc) { + this.ajdoc = ajdoc; + } + + public Ajdoc createAjdoc() { + return ajdoc = new Ajdoc(); + } + + public static class Argument { + private String name; + private List<String> values = new Vector<>(); + private boolean always = true; + final boolean isj; + public Argument(boolean isj) { + this.isj = isj; + } + public void setName(String str) { + this.name = str.startsWith("-") ? str : + ("-" + (str.startsWith("J") ? str.substring(1) : str)); + } + public void setValues(String str) { + values = new Vector<>(); + StringTokenizer tok = new StringTokenizer(str, ", ", false); + while (tok.hasMoreTokens()) { + values.add(tok.nextToken().trim()); + } + } + public void setValue(String value) { + (values = new Vector<>()).add(value); + } + public void setAlways(boolean always) { + this.always = always; + } + public String toString() { return name + ":" + values; } + } + + public void setNocompile(boolean nocompile) { + this.nocompile = nocompile; + } + + private static class Stats { + int goods = 0; + int fails = 0; + } + + private static class Arg { + final String name; + final String value; + final boolean isj; + Arg(String name, String value, boolean isj) { + this.name = name; + this.value = value; + this.isj = isj; + } + public String toString() { + return name + (!"".equals(value) ? " " + value : ""); + } + } + + public Testset createTestset() { + Testset testset = new Testset(); + testsets.add(testset); + return testset; + } + + public void setNoclean(boolean noclean) { + this.noclean = noclean; + } + + public void setDepends(String depends) { + for (StringTokenizer t = new StringTokenizer(depends, ", ", false); + t.hasMoreTokens();) { + this.depends.add(t.nextToken().trim()); + } + } + //end-methods + + public static class Argfile { + private String name; + public void setName(String name) { this.name = name; } + } + + public class Ajdoc { + private Commandline cmd = new Commandline(); + public Commandline.Argument createArg() { return cmd.createArgument(); } + public Commandline getCommandline() { return cmd; } + public String toString() { return cmd + ""; } + } + + public class Testset extends FileSet { + private List<Argfile> argfileNames = new Vector<>(); + public List<File> argfiles; + public List<File> files; + public List<Argument> args = new Vector<>(); + public String classname; + private boolean havecludes = false; + private List<Run> testclasses = new Vector<>(); + private Path classpath; + private Path internalclasspath; + private Ajdoc ajdoc = null; + private boolean fork = false; + private boolean noclean; + private List<String> depends = new Vector<>(); + public String toString() { + String str = ""; + if (files.size() > 0) { + str += "files:" + "\n"; + for (Iterator<File> i = files.iterator(); i.hasNext();) { + str += "\t" + i.next() + "\n"; + } + } + if (argfiles.size() > 0) { + str += "argfiles:" + "\n"; + for (Iterator<File> i = argfiles.iterator(); i.hasNext();) { + str += "\t" + i.next() + "\n"; + } + } + if (args.size() > 0) { + str += "args:" + "\n"; + for (Iterator i = args.iterator(); i.hasNext();) { + str += "\t" + i.next() + "\n"; + } + } + if (testclasses.size() > 0) { + str += "classes:" + "\n"; + for (Iterator i = testclasses.iterator(); i.hasNext();) { + str += "\t" + i.next() + "\n"; + } + } + return str; + } + public void setIncludes(String includes) { + super.setIncludes(includes); + havecludes = true; + } + public void setExcludes(String excludes) { + super.setExcludes(excludes); + havecludes = true; + } + public void setIncludesfile(File includesfile) { + super.setIncludesfile(includesfile); + havecludes = true; + } + public void setExcludesfile(File excludesfile) { + super.setExcludesfile(excludesfile); + havecludes = true; + } + + public void setArgfile(String name) { + createArgfile().setName(name); + } + + public void setArgfiles(String str) { + StringTokenizer tok = new StringTokenizer(str, ", ", false); + while (tok.hasMoreTokens()) { + createArgfile().setName(tok.nextToken().trim()); + } + + } + public Argfile createArgfile() { + Argfile argfile = new Argfile(); + argfileNames.add(argfile); + return argfile; + } + public Run createJava() { + // See crashing note + //Run testclass = new Run(); + Run testclass = new Run(project); + this.testclasses.add(testclass); + return testclass; + } + public void addJava(Run run) { + this.testclasses.add(run); + } + public void setJava(String str) { + StringTokenizer t = new StringTokenizer(str, " "); + Run run = createJava(); + run.setClassname(t.nextToken().trim()); + while (t.hasMoreTokens()) { + run.createArg().setValue(t.nextToken().trim()); + } + } + public void setTestclass(String testclass) { + createJava().setClassname(testclass); + } + + public void setClasses(String str) { + for (StringTokenizer t = new StringTokenizer(str, ", ", false); + t.hasMoreTokens();) { + createJava().setClassname(t.nextToken().trim()); + } + } + public void setClasspath(Path path) { + if (classpath == null) { + classpath = path; + } else { + classpath.append(path); + } + } + + public Path createClasspath() { + if (classpath == null) { + classpath = new Path(project); + } + return classpath.createPath(); + } + + public void setClasspathRef(Reference r) { + createClasspath().setRefid(r); + } + public void setInternalclasspath(Path path) { + if (internalclasspath == null) { + internalclasspath = path; + } else { + internalclasspath.append(path); + } + } + + public Path createInternalclasspath() { + if (internalclasspath == null) { + internalclasspath = new Path(project); + } + return internalclasspath.createPath(); + } + + public void setInternalclasspathRef(Reference r) { + createInternalclasspath().setRefid(r); + } + + public void setAjdoc(boolean b) { + if (b && ajdoc == null) { + createAjdoc(); + } else if (!b) { + this.ajdoc = null; + } + } + public Ajdoc getAjdoc() { return this.ajdoc; } + public void setAjdocargs(String str) { + createAjdoc(); + for (StringTokenizer t = new StringTokenizer(str, ", ", false); + t.hasMoreTokens();) { + this.ajdoc.createArg().setValue(t.nextToken().trim()); + } + } + public void addAjdoc(Ajdoc ajdoc) { + this.ajdoc = ajdoc; + } + public Ajdoc createAjdoc() { + return this.ajdoc = new Ajdoc(); + } + public void setFork(boolean fork) { + this.fork = fork; + } + public void setNoclean(boolean noclean) { + this.noclean = noclean; + } + public void setDepends(String depends) { + for (StringTokenizer t = new StringTokenizer(depends, ", ", false); + t.hasMoreTokens();) { + this.depends.add(t.nextToken().trim()); + } + } + //end-testset-methods + + public void resolve() throws BuildException { + if (dir != null) this.setDir(dir); + File src = getDir(project); + argfiles = new Vector<>(); + files = new Vector<>(); + for(Iterator<Argfile> iter = argfileNames.iterator(); iter.hasNext();) { + String name = iter.next().name; + File argfile = new File(src, name); + if (check(argfile, name, location)) argfiles.add(argfile); + } + if (havecludes || argfiles.size() <= 0) { + String[] filenames = + getDirectoryScanner(project).getIncludedFiles(); + for (int j = 0; j < filenames.length; j++) { + String name = filenames[j]; + if (name.endsWith(".java")) { + File file = new File(src, name); + if (check(file, name, location)) files.add(file); + } + } + } + for (Iterator i = Ajctest.this.testclasses.iterator(); + i.hasNext();) { + this.testclasses.add((Run)i.next()); + } + if (this.classpath == null) { + setClasspath(Ajctest.this.classpath); + } + if (this.internalclasspath == null) { + setInternalclasspath(Ajctest.this.internalclasspath); + } + if (this.ajdoc == null) { + this.ajdoc = Ajctest.this.ajdoc; + } + if (this.fork) { + for (Iterator<Run> i = this.testclasses.iterator(); i.hasNext();) { + i.next().setFork(fork); + } + } + if (!this.noclean) { + this.noclean = Ajctest.this.noclean; + } + this.depends.addAll(Ajctest.this.depends); + } + private boolean check(File file, String name, Location loc) + throws BuildException { + loc = loc != null ? loc : location; + if (file == null) { + throw new BuildException + ("file " + name + " is null!", loc); + } + if (!file.exists()) { + throw new BuildException + ("file " + file + " with name " + name + + " doesn't exist!", loc); + } + return true; + } + public void setArgs(String str) { + if (str == null || str.length() < 1) return; + StringTokenizer tok = new StringTokenizer(str, ",", false); + while (tok.hasMoreTokens()) { + String name = tok.nextToken().trim(); + parse(name.startsWith("J") ? createJarg() : createArg(), name); + } + } + + public Argument createJarg() { + Argument arg = new Argument(true); + args.add(arg); + return arg; + } + + public Argument createArg() { + Argument arg = new Argument(false); + args.add(arg); + return arg; + } + } + + private void prepare() throws BuildException { + + } + + private void finish() throws BuildException { + if (errors.size() > 0) { + log(""); + log("There " + w(errors) + " " + errors.size() + " errors:"); + for (int i = 0; i < errors.size(); i++) { + log(" ", (Failure)errors.get(i), i); + } + } + allErrors.addAll(errors); + } + + private void log(String space, Failure failure, int num) { + String number = "[" + num + "] "; + log(enough(number, 60, '-')); + for (int i = number.length()-1; i > 0; i--) space += " "; + log(space, failure.testset.files, "files:"); + log(space, failure.testset.argfiles, "argfiles:"); + log(space, failure.args, "args:"); + log(space + "msgs:" + failure.msgs); + } + + + private String enough(String str, int size, char filler) { + while (str.length() < size) str += filler; + return str; + } + + + private void log(String space, List<?> list, String title) { + if (list == null || list.size() < 1) return; + log(space + title); + for (Iterator<?> i = list.iterator(); i.hasNext();) { + log(space + " " + i.next()); + } + } + + private void execute(Testset testset, List<Arg> args) throws BuildException { + if (testset.files.size() > 0) { + log("\tfiles:"); + for (Iterator<File> i = testset.files.iterator(); i.hasNext();) { + log("\t " + i.next()); + } + } + if (testset.argfiles.size() > 0) { + log("\targfiles:"); + for (Iterator<File> i = testset.argfiles.iterator(); i.hasNext();) { + log("\t " + i.next()); + } + } + if (args.size() > 0) { + log("\targs:"); + for (Iterator<Arg> i = args.iterator(); i.hasNext();) { + log("\t " + i.next()); + } + } + if (testset.testclasses.size() > 0) { + log("\tclasses:"); + for (Iterator<Run> i = testset.testclasses.iterator(); i.hasNext();) { + log("\t " + i.next()); + } + } + if (!testset.noclean && + (!isSet("noclean") && !isSet("nocompile"))) { + delete(destdir); + make(destdir); + } + delete(workingdir); + make(workingdir); + for (Iterator<String> i = testset.depends.iterator(); i.hasNext();) { + String target = i.next()+""; + // todo: capture failures here? + project.executeTarget(target); + } + int exit; + if (!isSet("nodoc") && testset.ajdoc != null) { + log("\tdoc... " + testset.ajdoc); + AjdocWrapper ajdoc = new AjdocWrapper(testset, args); + if ((exit = ajdoc.run()) != 0) { + post(testset, args, ajdoc.msgs, exit, "ajdoc"); + } else { + fire("ajdoc.good"); + } + fire("ajdoc.done"); + log("\tdone with ajdoc."); + } + boolean goodCompile = true; + if (!isSet("nocompile") && !nocompile) { + log("\tcompile" + + (testset.noclean ? "(boostrapped)" : "") + "..."); + //AjcWrapper ajc = new AjcWrapper(testset, args); + JavaCommandWrapper ajc; + // XXX dependency on Ant property ajctest.compiler + final String compiler = getAntProperty("ajctest.compiler"); + if ("eclipse".equals(compiler) || "eajc".equals(compiler)) { + ajc = new EAjcWrapper(testset, args); + } else if ((null == compiler) || "ajc".equals(compiler)) { + ajc = new AjcWrapper(testset, args); + } else if ("javac".equals(compiler)) { + throw new Error("javac not supported"); + //ajc = new JavacWrapper(testset, args); + } else { + throw new Error("unknown compiler: " + compiler); + } + + System.out.println("using compiler: " + ajc); + try { + if ((exit = ajc.run()) != 0) { + post(testset, args, ajc.msgs, exit, "ajc"); + goodCompile = false; + } else { + fire("ajc.good"); + } + fire("ajc.done"); + } catch (Throwable ___) { + post(testset, args, ___+"", -1, "ajc"); + goodCompile = false; + } + } + if (!goodCompile) { + post(testset, new Vector(), + "couldn't run classes " + testset.testclasses + + "due to failed compile", + -1, "run"); + + } else if (!isSet("norun")) { + for (Iterator<Run> i = testset.testclasses.iterator(); i.hasNext();) { + Run testclass = i.next(); + log("\ttest..." + testclass.classname()); + if (null != destdir) { + testclass.setClassesDir(destdir.getAbsolutePath()); + } + if ((exit = testclass.executeJava()) != 0) { + post(testset, new Vector(), testclass.msgs, exit, "run"); + } else { + fire("run.good"); + } + fire("run.done"); + } + } + log(""); + } + + public void execute() throws BuildException { + gui(this); + dumpresults = isSet("dumpresults"); + prepare(); + log(testsets.size() + " testset" + s(testsets), + Project.MSG_VERBOSE); + Map<Testset,List<List<Arg>>> testsetToArgcombo = new HashMap<>(); + List<Integer> argcombos = new Vector<>(); + for (Testset testset: testsets) { + testset.resolve(); + List<Argument> bothargs = new Vector<>(args); + bothargs.addAll(testset.args); + List<List<Arg>> argcombo = argcombo(bothargs); + argcombos.add(new Integer(argcombo.size())); + testsetToArgcombo.put(testset, argcombo); + } + while (!testsetToArgcombo.isEmpty()) { + int testsetCounter = 1; + for (Iterator<Testset> iter = testsets.iterator(); iter.hasNext(); testsetCounter++) { + Testset testset = iter.next(); + List<List<Arg>> argcombo = testsetToArgcombo.get(testset); + if (argcombo.size() == 0) { + testsetToArgcombo.remove(testset); + continue; + } + List<Arg> args = argcombo.remove(0); + final String startStr = "Testset " + testsetCounter + " of " + testsets.size(); + String str = startStr + " / Combo " + testsetCounter + " of " + argcombos.size(); + log("---------- " + str + " ----------"); + execute(testset, args); + } + } + +// for (Iterator iter = testsets.iterator(); iter.hasNext(); _++) { +// Testset testset = (Testset)iter.next(); +// testset.resolve(); +// List bothargs = new Vector(args); +// bothargs.addAll(testset.args); +// int __ = 1; +// List argcombo = argcombo(bothargs); +// log(argcombo.size() + " combination" + s(argcombo), +// Project.MSG_VERBOSE); +// final String startStr = "Testset " + _ + " of " + testsets.size(); +// for (Iterator comboiter = argcombo.iterator(); +// comboiter.hasNext(); __++) { +// List args = (List)comboiter.next(); +// execute(testset, args); +// log(""); +// } +// } + finish(); + } + + private void delete(File dir) throws BuildException { + Delete delete = (Delete)project.createTask("delete"); + delete.setDir(dir); + delete.execute(); + } + + private void make(File dir) throws BuildException { + Mkdir mkdir = (Mkdir)project.createTask("mkdir"); + mkdir.setDir(dir); + mkdir.execute(); + } + + private String getAntProperty(String name) { + String uprop = project.getUserProperty(name); + if (null == uprop) { + uprop = project.getProperty(name); + } + return uprop; + } + + private boolean isSet(String name) { + String uprop = project.getUserProperty(name); + if (uprop == null || + "no".equals(uprop) || + "false".equals(uprop)) return false; + String prop = project.getProperty(name); + if (prop == null || + "no".equals(prop) || + "false".equals(prop)) return false; + return true; + } + + /** + * Interpose Wrapper class to catch and report exceptions + * by setting a positive value for System.exit(). + * (In some cases it seems that Exceptions are not being reported + * as errors in the tests.) + * This forces the VM to fork. A forked VM is required for + * two reasons: + * (1) The wrapper class may have been defined by a different + * class loader than the target class, so it would not be able + * to load the target class; + * <p> + * (2) Since the wrapper class is generic, we have to pass in + * the name of the target class. I choose to do this using + * VM properties rather than hacking up the arguments. + * <p>todo: relies on name/value of property "taskdef.jar" + * to add jar with wrapper to invoking classpath. + * <p> + * It is beneficial for another reason: + * (3) The wrapper class can be asked to test-load all classes + * in a classes dir, by setting a VM property. This class + * sets up the property if the value is defined using + * <code>setClassesDir(String)</code> + * <p>todo: if more tunnelling, generalize and parse. + */ + public class RunWrapper extends Java { + public final Class LINK_WRAPPER_CLASS = MainWrapper.class; + /** tracked in MainWrapper.PROP_NAME */ // todo: since reflective, avoid direct + public final String PROP_NAME = "MainWrapper.classname"; + /** tracked in MainWrapper.CLASSDIR_NAME */ + public final String CLASSDIR_NAME = "MainWrapper.classdir"; + public final String WRAPPER_CLASS + = "org.aspectj.internal.tools.ant.taskdefs.MainWrapper"; + private String classname; + protected String classesDir; + /** capture classname here, replace with WRAPPER_CLASS */ + public void setClassname(String classname) { + super.setClassname(WRAPPER_CLASS); + this.classname = classname; + } + + /** + * Setup the requirements for the wrapper class: + * <li>fork to get classpath and VM properties right</li> + * <li>set VM property</li> + * <li>add ${ajctest.wrapper.jar} (with wrapper class) to the classpath</li> + */ + private void setup() { + setFork(true); + Commandline.Argument cname = createJvmarg(); + cname.setValue("-D"+PROP_NAME+"="+classname); + if (!noverify) { + cname = createJvmarg(); + cname.setValue("-Xfuture"); // todo: 1.2 or later.. + } + if (null != classesDir) { + cname = createJvmarg(); + cname.setValue("-D"+CLASSDIR_NAME+"="+classesDir); + } + // todo dependence on name/setting of ajctest.wrapper.jar + String value = project.getProperty("ajctest.wrapper.jar"); + if (null != value) { + Path wrapperPath = new Path(project, value); + RunWrapper.this.createClasspath().append(wrapperPath); + } + } + + /** do setup, then super.execute() */ + public int executeJava() { + setup(); + int result = super.executeJava(); + // snarf - also load all classes? + return result; + } + + /** set directory to scan for classes */ + public void setClassesDir(String dir) { + classesDir = dir; + } + } + + public class Run extends RunWrapper { + //public class Run extends Java + private Path bootclasspath; + public void setBootbootclasspath(Path path) { + if (bootclasspath == null) { + bootclasspath = path; + } else { + bootclasspath.append(path); + } + } + public Path createBootbootclasspath() { + if (bootclasspath == null) bootclasspath = new Path(this.project); + return bootclasspath.createPath(); + } + public void setBootbootclasspathRef(Reference r) { + createBootbootclasspath().setRefid(r); + } + private Path bootclasspatha; + public void setBootbootclasspatha(Path path) { + if (bootclasspatha == null) { + bootclasspatha = path; + } else { + bootclasspatha.append(path); + } + } + public Path createBootbootclasspatha() { + if (bootclasspatha == null) bootclasspatha = new Path(this.project); + return bootclasspatha.createPath(); + } + public void setBootbootclasspathaRef(Reference r) { + createBootbootclasspatha().setRefid(r); + } + private Path bootclasspathp; + public void setBootbootclasspathp(Path path) { + if (bootclasspathp == null) { + bootclasspathp = path; + } else { + bootclasspathp.append(path); + } + } + public Path createBootbootclasspathp() { + if (bootclasspathp == null) bootclasspathp = new Path(this.project); + return bootclasspathp.createPath(); + } + public void setBootbootclasspathpRef(Reference r) { + createBootbootclasspathp().setRefid(r); + } + public Run(Project project) { + super(); + //this.project = Ajctest.this.project; + this.setTaskName("ajcjava"); + this.project = project; + } + public String msgs = ""; + public int executeJava() { + Path cp = Ajctest.this.classpath != null ? Ajctest.this.classpath : + new Path(this.project, destdir.getAbsolutePath()); + cp.append(Path.systemClasspath); + this.setClasspath(cp); + if (bootclasspath != null) { + setFork(true); + createJvmarg().setValue("-Xbootclasspath:" + bootclasspath); + } + if (bootclasspatha != null) { + setFork(true); + createJvmarg().setValue("-Xbootclasspath/a:" + bootclasspatha); + } + if (bootclasspathp != null) { + setFork(true); + createJvmarg().setValue("-Xbootclasspath/p:" + bootclasspathp); + } + int exit = -1; + // todo: add timeout feature todo: this or below? + try { + exit = super.executeJava(); + } catch (Throwable t) { + StringWriter sw = new StringWriter(); + PrintWriter out = new PrintWriter(sw); + t.printStackTrace(out); + msgs = sw.toString(); + out.close(); + // todo: return exit code + } + return exit; + } + public String _classname; + public String classname() { return _classname; } + public void setClassname(String classname) { + super.setClassname(_classname = classname); + } + public String toString() { return _classname; } + } + // class Run + // todo: need to run in a wrapper which report non-zero int on exception + // todo: unused method? see executeJava above. +// private int java(String classname, Collection args) throws BuildException { +// Java java = (Java)project.createTask("java"); +// java.setClassname(classname); +// for (Iterator i = args.iterator(); i.hasNext();) { +// Object o = i.next(); +// Commandline.Argument arg = java.createArg(); +// if (o instanceof File) { +// arg.setFile((File)o); +// } else if (o instanceof Path) { +// arg.setPath((Path)o); +// } else { +// arg.setValue(o+""); +// } +// } +// return java.executeJava(); +// } + + private static List allErrors = new Vector(); + private List<Failure> errors = new Vector<>(); + + private void post(Testset testset, List args, + String msgs, int exit, String type) { + errors.add(new Failure(testset, args, msgs, exit, type, testId)); + fire(type + ".fail"); + } + + private static long startTime; + private static long stopTime; + + private static String date(long time) { + return DateFormat.getDateTimeInstance + (DateFormat.FULL, DateFormat.FULL). + format(new Date(time)); + } + + static { + final PrintStream err = System.err; + startTime = System.currentTimeMillis(); + Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() { + private String ms(long start, long stop) { + long rest = Math.abs(stop-start) / 1000; + long days = rest / 86400; + long hours = (rest -= days*86400) / 3600; + long mins = (rest -= hours*3600) / 60; + long secs = (rest -= mins*60); + boolean req = false; + String str = ""; + if (req || days > 0) { + req = true; + str += days + " day" + (days != 1 ? "s" : "") + " "; + } + if (req || hours > 0) { + req = true; + str += hours + " hour" + (hours != 1 ? "s" : "") + " "; + } + if (req || mins > 0) { + req = true; + str += mins + " minute" + (mins != 1 ? "s" : "") + " "; + } + str += secs + " second" + (secs != 1 ? "s" : "") + " "; + return str; + } + + public void run() { + Ajctest current = CURRENT_AJCTEST; + String oneLine = "warning: oneLine not set."; + String multiLine = "warning: multiLine not set."; + + // setup oneLine + if (null == current) { + oneLine = "\nRESULT=\"ERROR\" null ACJTEST"; + } else { + StringBuffer sb = new StringBuffer("\n"); + int errs = Ajctest.allErrors.size(); + int allFails = errs + + current.ajdocStats.fails + + current.ajcStats.fails + + current.runStats.fails; + if (1 > allFails) { + sb.append("RESULT=\"PASS\"\terrors=\""); + } else { + sb.append("RESULT=\"FAIL\"\terrors=\""); + } + sb.append(""+errs); + sb.append("\"\tajdoc.pass=\""); + sb.append(""+current.ajdocStats.goods); + sb.append("\"\tajdoc.fail=\""); + sb.append(""+current.ajdocStats.fails); + sb.append("\"\tajc.pass=\""); + sb.append(""+current.ajcStats.goods); + sb.append("\"\tajc.fail=\""); + sb.append(""+current.ajcStats.fails); + sb.append("\"\trun.pass=\""); + sb.append(""+current.runStats.goods); + sb.append("\"\trun.fail=\""); + sb.append(""+current.runStats.fails); + sb.append("\"\ttestId=\""); + sb.append(current.testId); + sb.append("\"\tproject=\""); + Project p = current.getProject(); + if (null != p) sb.append(p.getName()); + sb.append("\"\tfile=\""); + sb.append(""+current.getLocation()); + sb.append("\""); + oneLine = sb.toString(); + } + + // setup multiLine + { + stopTime = System.currentTimeMillis(); + String str = ""; + str += "\n"; + str += + "===================================" + + "===================================" + "\n"; + str += "Test started : " + date(startTime) + "\n"; + str += "Test ended : " + date(stopTime) + "\n"; + str += "Total time : " + ms(startTime, stopTime) + "\n"; + str += + "------------------------------" + + " Summary " + + "------------------------------" + "\n"; + str += "Task\tPassed\tFailed" + "\n"; + Object[] os = new Object[] { + "ajdoc", current.ajdocStats.goods+"", current.ajdocStats.fails+"", + "ajc", current.ajcStats.goods +"", current.ajcStats.fails +"", + "run", current.runStats.goods +"", current.runStats.fails +"", + }; + for (int i = 0; i < os.length; i += 3) { + str += os[i] + "\t" + os[i+1] + "\t" + os[i+2] + "\n"; + } + if (allErrors.size() > 0) { + str += "" + "\n"; + str += + "There " + w(allErrors) + " " + + allErrors.size() + " error" + + s(allErrors) + ":" + "\n"; + for (int i = 0; i < allErrors.size(); i++) { + Failure failure = (Failure)allErrors.get(i); + str += + "---------- Error " + i + " [" + + failure.testId + "]" + + " ------------------------------" + "\n"; + str += " " + failure + "\n\n"; + } + } else { + str += "No errors." + "\n"; + } + str += "--------------------------" + + " End of Summary " + + "---------------------------" + "\n"; + multiLine = str; + } + + // print both multiLine and oneLine + err.println(multiLine); + err.println(oneLine); + if (dumpresults && (allErrors.size() + + current.ajdocStats.fails + + current.ajcStats.fails + + current.runStats.fails) > 0) { + String date = date(System.currentTimeMillis()); + String filename = "ajc-errors"; + for (StringTokenizer t = new StringTokenizer(date, ",: "); + t.hasMoreTokens();) { + filename += "-" + t.nextToken().trim(); + } + filename += ".txt"; + PrintWriter out = null; + File file = new File(filename); + System.err.println("dumping results to " + file); + try { + out = new PrintWriter(new FileWriter(file)); + out.println(multiLine); + out.println(oneLine); + System.err.println("dumped results to " + file); + } catch (IOException ioe) { + if (out != null) out.close(); + } + } + } + })); + } + + private static String w(List list) { return a(list, "were", "was"); } + private static String s(List list) { return a(list, "s", ""); } + + private static String a(List list, String some, String one) { + return list == null || list.size() != 1 ? some : one; + } + + static class Failure { + public final Testset testset; + public final List args; + public final String msgs; + public final int exit; + public final String type; + public final long time; + public final String testId; + public Failure(Testset testset, List args, + String msgs, int exit, String type, + String testId) { + this.testset = testset; + this.args = args; + this.msgs = msgs; + this.exit = exit; + this.type = type; + this.time = System.currentTimeMillis(); + this.testId = testId; + } + public String toString() { + String str = "testId:" + testId+ "\n"; + str += "type:" + type + "\n"; + str += testset + "\n"; + if (args.size() > 0) { + str += " args: " + args + "\n";; + } + str += " msgs:" + msgs + "\n"; + str += " exit:" + exit; + return str; + } + } + + private List<List<Arg>> argcombo(List<Argument> arguments) { + List<Argument> combos = new Vector<>(); + List<Arg> always = new Vector<>(); + for (Iterator<Argument> iter = arguments.iterator(); iter.hasNext();) { + Argument arg = iter.next(); + if (arg.values.size() == 0) arg.values.add(""); + if (!arg.always && !arg.values.contains(null)) arg.values.add(null); + if (arg.values.size() > 0) { + combos.add(arg); + } else if (arg.always) { + always.add(new Arg(arg.name, arg.values.get(0)+"", arg.isj)); + } + } + List<List<Arg>> argcombo = combinations(combos); + for (Iterator<Arg> iter = always.iterator(); iter.hasNext();) { + Arg arg = iter.next(); + for (Iterator<List<Arg>> comboiter = argcombo.iterator(); comboiter.hasNext();) { + comboiter.next().add(arg); + } + } + return argcombo; + } + + private abstract class ExecWrapper { + public String msgs; + public int run() { + return run(createCommandline()); + } + protected abstract Commandline createCommandline(); + protected final int run(Commandline cmd) { + Process process = null; + int exit = Integer.MIN_VALUE; + final StringBuffer buf = new StringBuffer(); + Thread errPumper = null; + Thread outPumper = null; + try { + log("\tcalling " + cmd, Project.MSG_VERBOSE); + process = Runtime.getRuntime().exec(cmd.getCommandline()); + OutputStream os = new OutputStream() { + StringBuffer sb = new StringBuffer(); + public void write(int b) throws IOException { + final char c = (char)b; + buf.append(c); + if (c != '\n') { + sb.append(c); + } else { + System.err.println(sb.toString()); + sb = new StringBuffer(); + } + } + }; + OutputStream los = new LogOutputStream(Ajctest.this, + Project.MSG_INFO); + outPumper = new Thread(new StreamPumper(process.getInputStream(), + los)); + errPumper = new Thread(new StreamPumper(process.getErrorStream(), + os)); + outPumper.setDaemon(true); + errPumper.setDaemon(true); + outPumper.start(); + errPumper.start(); + process.waitFor(); + } catch (Exception e) { + e.printStackTrace(); + //throw e; + } finally { + try { + if (outPumper != null) outPumper.join(); + if (errPumper != null) errPumper.join(); + } catch (InterruptedException ie) { + } finally { + outPumper = null; + errPumper = null; + } + exit = process.exitValue(); + msgs = buf.toString(); + if (exit != 0) { + log("Test failed with exit value: " + exit); + } else { + log("Success!", Project.MSG_VERBOSE); + } + if (process != null) process.destroy(); + process = null; + System.err.flush(); + System.out.flush(); + } + return exit; + } + } + + private class AjcWrapper extends JavaCommandWrapper { + public AjcWrapper(Testset testset, List args) { + super(testset, args, false); + if (testset.noclean) { + setExtraclasspath(new Path(project, + destdir.getAbsolutePath())); + } + } + String getMainClassName() { + return "org.aspectj.tools.ajc.Main"; + } + } + + private class EAjcWrapper extends JavaCommandWrapper { + public EAjcWrapper(Testset testset, List args) { + super(testset, args, false); + if (testset.noclean) { + setExtraclasspath(new Path(project, + destdir.getAbsolutePath())); + } + } + String getMainClassName() { + return "org.aspectj.ajdt.ajc.Main"; + } + } + + static List ajdocArgs(List args) { + List newargs = new Vector(); + for (Iterator i = args.iterator(); i.hasNext();) { + String arg = i.next() + ""; + if (arg.startsWith("-X")) { + newargs.add(arg); + } else if (arg.equals("-public") || + arg.equals("-package") || + arg.equals("-protected") || + arg.equals("-private")) { + newargs.add(arg); + } else if (arg.equals("-d") || + arg.equals("-classpath") || + arg.equals("-cp") || + arg.equals("-sourcepath") || + arg.equals("-bootclasspath") || + arg.equals("-argfile")) { + newargs.add(arg); + newargs.add(i.next()+""); + } else if (arg.startsWith("@")) { + newargs.add(arg); + } + } + return newargs; + } + + private class AjdocWrapper extends JavaCommandWrapper { + public AjdocWrapper(Testset testset, List args) { + super(testset, ajdocArgs(args), true); + String[] cmds = testset.getAjdoc().getCommandline().getCommandline(); + for (int i = 0; i < cmds.length; i++) { + this.args.add(cmds[i]); + } + } + String getMainClassName() { + return "org.aspectj.tools.ajdoc.Main"; + } + } + + private abstract class JavaCommandWrapper extends ExecWrapper { + abstract String getMainClassName(); + protected Testset testset; + protected List args; + protected boolean needsClasspath; + protected Path extraClasspath; + + public JavaCommandWrapper(Testset testset, List args, + boolean needsClasspath) { + this.testset = testset; + this.args = args; + this.needsClasspath = needsClasspath; + this.extraClasspath = testset.internalclasspath; + } + public void setExtraclasspath(Path extraClasspath) { + this.extraClasspath = extraClasspath; + } + + public String toString() { + return LangUtil.unqualifiedClassName(getClass()) + + "(" + getMainClassName() + ")"; + } + + protected Commandline createCommandline() { + Commandline cmd = new Commandline(); + cmd.setExecutable("java"); + cmd.createArgument().setValue("-classpath"); + Path cp = null; + if (extraClasspath != null) { + cp = extraClasspath; + } + if (extraClasspath == null) { + Path aspectjBuildDir = + new Path(project, + project.getProperty("ajctest.pathelement")); + // todo: dependency on ant script variable name ajctest.pathelement + if (cp == null) cp = aspectjBuildDir; + else cp.append(aspectjBuildDir); + } + if (cp == null) { + cp = Path.systemClasspath; + } else { + cp.append(Path.systemClasspath); + } + cmd.createArgument().setPath(cp); + for (Iterator iter = args.iterator(); iter.hasNext();) { + Arg arg = (Arg)iter.next(); + if (arg.isj) { + cmd.createArgument().setValue(arg.name); + if (!arg.value.equals("")) { + cmd.createArgument().setValue(arg.value); + } + } + } + cmd.createArgument().setValue(getMainClassName()); + boolean alreadySetDestDir = false; + boolean alreadySetClasspath = false; + for (Iterator iter = args.iterator(); iter.hasNext();) { + Arg arg = (Arg)iter.next(); + if (!arg.isj) { + cmd.createArgument().setValue(arg.name); + if (arg.name.equals("-d")) { + setDestdir(arg.value+""); + alreadySetDestDir = true; + } + if (arg.name.equals("-classpath")) { + alreadySetClasspath = true; + } + if (!arg.value.equals("")) { + cmd.createArgument().setValue(arg.value); + } + } + } + if (destdir == null) { + setDestdir("."); + } + if (!alreadySetDestDir) { + cmd.createArgument().setValue("-d"); + cmd.createArgument().setFile(destdir); + } + if (!alreadySetClasspath && testset.classpath != null) { + cmd.createArgument().setValue("-classpath"); + cmd.createArgument().setPath(testset.classpath); + } else if (needsClasspath) { + Path _cp = Ajctest.this.classpath != null ? Ajctest.this.classpath : + new Path(project, destdir.getAbsolutePath()); + _cp.append(Path.systemClasspath); + cmd.createArgument().setValue("-classpath"); + cmd.createArgument().setPath(_cp); + } + for (Iterator iter = testset.files.iterator(); iter.hasNext();) { + cmd.createArgument().setFile((File)iter.next()); + } + for (Iterator iter = testset.argfiles.iterator(); iter.hasNext();) { + cmd.createArgument().setValue("-argfile"); + cmd.createArgument().setFile((File)iter.next()); + } + return cmd; + } + } + + /** implement invocation of ajc */ +// private void java(Testset testset, List args) throws BuildException { +// Java java = (Java)project.createTask("java"); +// java.setClassname("org.aspectj.tools.ajc.Main"); +// if (classpath != null) { +// java.setClasspath(classpath); +// } +// for (Iterator iter = args.iterator(); iter.hasNext();) { +// Arg arg = (Arg)iter.next(); +// if (arg.isj) { +// java.createJvmarg().setValue(arg.name); +// if (!arg.value.equals("")) { +// java.createJvmarg().setValue(arg.value); +// } +// } +// } +// for (Iterator iter = args.iterator(); iter.hasNext();) { +// Arg arg = (Arg)iter.next(); +// if (!arg.isj) { +// java.createArg().setValue(arg.name); +// if (!arg.value.equals("")) { +// java.createArg().setValue(arg.value); +// } +// } +// } +// for (Iterator iter = testset.files.iterator(); iter.hasNext();) { +// java.createArg().setFile((File)iter.next()); +// } +// for (Iterator iter = testset.argfiles.iterator(); iter.hasNext();) { +// java.createArg().setValue("-argfile"); +// java.createArg().setFile((File)iter.next()); +// } +// java.setFork(true); +// java.execute(); +// } +// +// private void exec(Testset testset, List args) throws BuildException { +// ExecTask exec = (ExecTask)project.createTask("exec"); +// exec.setExecutable("java"); +// if (classpath != null) { +// exec.createArg().setValue("-classpath"); +// exec.createArg().setPath(classpath); +// } +// for (Iterator iter = args.iterator(); iter.hasNext();) { +// Arg arg = (Arg)iter.next(); +// if (arg.isj) { +// exec.createArg().setValue(arg.name); +// if (!arg.value.equals("")) { +// exec.createArg().setValue(arg.value); +// } +// } +// } +// exec.createArg().setValue("org.aspectj.tools.ajc.Main"); +// for (Iterator iter = args.iterator(); iter.hasNext();) { +// Arg arg = (Arg)iter.next(); +// if (!arg.isj) { +// exec.createArg().setValue(arg.name); +// if (!arg.value.equals("")) { +// exec.createArg().setValue(arg.value); +// } +// } +// } +// for (Iterator iter = testset.files.iterator(); iter.hasNext();) { +// exec.createArg().setFile((File)iter.next()); +// } +// for (Iterator iter = testset.argfiles.iterator(); iter.hasNext();) { +// exec.createArg().setValue("-argfile"); +// exec.createArg().setFile((File)iter.next()); +// } +// exec.execute(); +// } +// + public void handle(Throwable t) { + log("handling " + t); + if (t != null) t.printStackTrace(); + log("done handling " + t); + } + + private List<List<Arg>> combinations(List<Argument> arglist) { + List<List<Arg>> result = new Vector<>(); + result.add(new Vector<Arg>()); + for (Iterator<Argument> iter = arglist.iterator(); iter.hasNext();) { + Argument arg = iter.next(); + int N = result.size(); + for (int i = 0; i < N; i++) { + List<Arg> to = result.remove(0); + for (Iterator<String> valiter = arg.values.iterator(); valiter.hasNext();) { + List<Arg> newlist = new Vector<>(to); + Object val = valiter.next(); + if (val != null) newlist.add(new Arg(arg.name, val+"", arg.isj)); + result.add(newlist); + } + } + } + return result; + } + + /////////////////////// GUI support ////////////////////////////// + private static Gui gui; + + private static void gui(Ajctest ajc) { + if (firstTime && ajc.isSet("gui")) { + JFrame f = new JFrame("AspectJ Test Suite"); + f.getContentPane().add(BorderLayout.CENTER, gui = new Gui()); + f.pack(); + f.setVisible(true); + } + if (gui != null) { + ajc.bean.addPropertyChangeListener(gui); + } + firstTime = false; + } + + private static class Gui extends JPanel implements PropertyChangeListener { + private FailurePanel fail = new FailurePanel(); + private TablePanel table = new TablePanel(); + private StatusPanel status = new StatusPanel(); + public Gui() { + super(new BorderLayout()); + JSplitPane split = new JSplitPane(JSplitPane.VERTICAL_SPLIT); + split.setPreferredSize(new Dimension(500, 300)); + split.add(JSplitPane.BOTTOM, fail); + split.add(JSplitPane.TOP, table); + split.setDividerLocation(200); + add(BorderLayout.CENTER, split); + add(BorderLayout.SOUTH, status); + setPreferredSize(new Dimension(640, 680)); + } + public void propertyChange(PropertyChangeEvent evt) { + String name = evt.getPropertyName(); + if ("ajdoc.good".equals(name)) { + status.ajc.goods.inc(); + } else if ("ajc.good".equals(name)) { + status.ajc.goods.inc(); + } else if ("run.good".equals(name)) { + status.runs.goods.inc(); + } + if ("ajdoc.done".equals(name)) { + status.ajc.total.inc(); + } else if ("ajc.done".equals(name)) { + status.ajc.total.inc(); + } else if ("run.done".equals(name)) { + status.runs.total.inc(); + } + if ("ajdoc.fail".equals(name)) { + status.ajc.fails.inc(); + } else if ("ajc.fail".equals(name)) { + status.ajc.fails.inc(); + } else if ("run.fail".equals(name)) { + status.runs.fails.inc(); + } + } + + private abstract static class TitledPanel extends JPanel { + public TitledPanel(LayoutManager layout, String title) { + super(layout); + setBorder(BorderFactory.createTitledBorder(title)); + } + } + + private static class StatusPanel extends TitledPanel { + StatusInnerPanel ajdoc = new StatusInnerPanel("Ajdoc"); + StatusInnerPanel runs = new StatusInnerPanel("Runs"); + StatusInnerPanel ajc = new StatusInnerPanel("Ajc"); + + public StatusPanel() { + super(new FlowLayout(), "Status"); + add(ajdoc); + add(runs); + add(ajc); + } + + private static class StatusInnerPanel extends TitledPanel { + IntField goods = new IntField(5, Color.green.darker()); + IntField fails = new IntField(5, Color.red.darker()); + IntField total = new IntField(5, Color.blue.darker()); + public StatusInnerPanel(String str) { + super(null, str); + this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); + Object[] os = new Object[] { + "Passed", goods, + "Failed", fails, + "Totals", total, + }; + for (int i = 0; i < os.length; i += 2) { + JPanel p = p(); + p.add(new JLabel(os[i]+":")); + p.add((Component)os[i+1]); + this.add(p); + } + } + + private JPanel p() { + JPanel p = new JPanel(); + p.setLayout(new FlowLayout(FlowLayout.LEFT)); + return p; + } + + private class IntField extends JTextField { + public IntField(int i, Color fg) { + super("0", i); + this.setBackground(StatusInnerPanel.this.getBackground()); + this.setForeground(fg); + this.setEditable(false); + this.setBorder(BorderFactory.createEmptyBorder()); + } + public void add(int i) { + setText((Integer.parseInt(getText().trim())+i)+""); + } + public void inc() { add(1); } + } + } + } + + private class TablePanel extends TitledPanel { + private DefaultTableModel model = new DefaultTableModel(); + private TJable table; + private List failures = new Vector(); + public TablePanel() { + super(new BorderLayout(), "Failures"); + Object[] names = new String[] { + "Task", "Type", "Number", "Time" + }; + for (int i = 0; i < names.length; i++) { + model.addColumn(names[i]); + } + table = new TJable(model, failures); + this.add(new JScrollPane(table), BorderLayout.CENTER); + } + + private class TJable extends JTable { + private List list; + public TJable(TableModel model, List list) { + super(model); + this.list = list; + setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + } + public void valueChanged(ListSelectionEvent e) { + super.valueChanged(e); + if (list == null) return; + int i = (e.getFirstIndex()-e.getLastIndex())/2; + if (list.size() > 0) { + Failure f = (Failure)list.get(i); + fail.setFailure(f); + } + } + } + + public void add(Failure f, String taskname, String type, + int num, long time) { + model.addRow(new Object[]{taskname, type, + new Integer(num), date(time)}); + failures.add(f); + } + } + + private static class FailurePanel extends TitledPanel { + private JTextArea msgs = new JTextArea(10,50); + private InfoPanel info = new InfoPanel(); + + public FailurePanel() { + super(new BorderLayout(), "Failure"); + msgs.setFont(StyleContext.getDefaultStyleContext(). + getFont("SansSerif", Font.PLAIN, 10)); + add(BorderLayout.NORTH, info); + JScrollPane sc = new JScrollPane(msgs); + sc.setBorder(BorderFactory.createTitledBorder("Messages")); + add(BorderLayout.CENTER, sc); + } + + public void setText(String str) { + msgs.setText(str); + } + + public void setFailure(Failure f) { + msgs.setText(f.msgs); + info.setText("Type" , f.type); + info.setText("Args" , f.args); + info.setText("Exit" , f.exit+""); + info.setText("Time" , date(f.time)); + info.setText("Files" , f.testset.files); + info.setText("Classnames" , f.testset.testclasses); + } + + private static class InfoPanel extends JPanel { + Map fields = new HashMap(); + public void setText(String key, Object str) { + ((JTextField)fields.get(key)).setText(str+""); + } + public InfoPanel() { + super(new GridBagLayout()); + LabelFieldGBC gbc = new LabelFieldGBC(); + Object[] os = new Object[] { + "Type", + "Args", + "Exit", + "Time", + "Files", + "Classnames", + }; + for (int i = 0; i < os.length; i++) { + String name = os[i]+""; + JLabel label = new JLabel(name+":"); + JTextField comp = new JTextField(25); + comp.setEditable(false); + comp.setBackground(Color.white); + comp.setBorder(BorderFactory. + createBevelBorder(BevelBorder.LOWERED)); + label.setLabelFor(comp); + fields.put(name, comp); + add(label, gbc.forLabel()); + add(comp, gbc.forField()); + } + add(new JLabel(), gbc.forLastLabel()); + } + } + + private static class LabelFieldGBC extends GridBagConstraints { + public LabelFieldGBC() { + insets = new Insets(1,3,1,3); + gridy = RELATIVE; + gridheight = 1; + gridwidth = 1; + } + public LabelFieldGBC forLabel() { + fill = NONE; + gridx = 0; + anchor = NORTHEAST; + weightx = 0.0; + return this; + } + + public LabelFieldGBC forLastLabel() { + forLabel(); + fill = VERTICAL; + weighty = 1.0; + return this; + } + + public LabelFieldGBC forField() { + fill = HORIZONTAL; + gridx = 1; + anchor = CENTER; + weightx = 1.0; + return this; + } + + public LabelFieldGBC forLastField() { + forField(); + fill = BOTH; + weighty = 1.0; + return this; + } + } + } + } + +} diff --git a/testing/src/test/java/org/aspectj/internal/tools/ant/taskdefs/MainWrapper.java b/testing/src/test/java/org/aspectj/internal/tools/ant/taskdefs/MainWrapper.java new file mode 100644 index 000000000..6ce22df24 --- /dev/null +++ b/testing/src/test/java/org/aspectj/internal/tools/ant/taskdefs/MainWrapper.java @@ -0,0 +1,181 @@ +/* ******************************************************************* + * Copyright (c) 1999-2001 Xerox Corporation, + * 2002 Palo Alto Research Center, Incorporated (PARC). + * 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://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Xerox/PARC initial implementation + * ******************************************************************/ + + + +package org.aspectj.internal.tools.ant.taskdefs; + +import java.io.File; +import java.io.PrintStream; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; + +import org.aspectj.testing.util.LangUtil; + +/** + * Wrapper to invoke class identified by setting VM argument. + * Caller must set a system property "MainWrapper.classname" + * to the fully-qualified name of the target class to invoke, + * and the target class must be resolvable from the defining + * class loader of this class. + * VM argument name is available as <code>PROP_NAME</code>, but + * is set by adding the following to the command line: + * <code>-DMainWrapper.classname="fully.qualified.Classname"</code>. + * This returns -1 if unable to load the main method, + * 1 if the invoked method throws an exception, and 0 otherwise. + */ +public class MainWrapper { + /** MUST set the fully-qualified name of class to invoke using + * a VM property of this name + * tracked in Ajctest.java */ + public static final String PROP_NAME = "MainWrapper.classname"; + /** May set the path to a classes diretory, + * to interpret class names and load classes. + * Tracked in Ajctest.java */ + public static final String CLASSDIR_NAME = "MainWrapper.classdir"; + + /** to disable returning int via System.exit, set to boolean true value (todo: ignored) */ + public static final String SIGNAL_EXCEPTION_NAME = "MainWrapper.signalException"; + + /** to disable returning via System.exit on first Throwable, set to boolean true value (todo: ignored) */ + public static final String FAIL_ON_EXCEPTION_NAME = "MainWrapper.failOnException"; + + /** quit on first exception */ // todo public class controls - yuck + public static boolean FAIL_ON_EXCEPTION = true; + + /** signal number of exceptions with int return value */ + public static boolean SIGNAL_EXCEPTION = true; + + /** redirect messages for exceptions; if null, none printed */ + public static PrintStream OUT_STREAM = System.err; + + /** result accumulated, possibly from multiple threads */ + private static int result; + + /** + * Run target class's main(args), doing a System.exit() with + * a value > 0 for the number of Throwable that + * the target class threw that + * makes it through to a top-level ThreadGroup. (This is + * strictly speaking not correct since applications can live + * after their exceptions stop a thread.) + * Exit with a value < 0 if there were exceptions in loading + * the target class. Messages are printed to OUT_STREAM. + */ + public static void main(String[] args) { + String classname = "no property : " + PROP_NAME; + Method main = null; + // setup: this try block is for loading main method - return -1 if fail + try { + // access classname from jvm arg + classname = System.getProperty(PROP_NAME); + // this will fail if the class is not available from this classloader + Class<?> cl = Class.forName(classname); + final Class<?>[] argTypes = new Class[] {String[].class}; + // will fail if no main method + main = cl.getMethod("main", argTypes); + if (!Modifier.isStatic(main.getModifiers())) { + PrintStream outStream = OUT_STREAM; + if (null != outStream) outStream.println("main is not static"); + result = -1; + } + // if user also request loading of all classes... + String classesDir = System.getProperty(CLASSDIR_NAME); + if ((null != classesDir) && (0 < classesDir.length())) { + MainWrapper.loadAllClasses(new File(classesDir)); + } + } catch (Throwable t) { + if (1 != result) result--; + reportException("setup Throwable invoking class " + classname, t); + } + // run: this try block is for running things - get Throwable from our thread here + if ((null != main) && (0 == result)) { + try { + runInOurThreadGroup(main, args); + } catch (Throwable t) { + if (result > -1) { + result++; + } + reportException("run Throwable invoking class " + classname, t); + } + } + if ((0 != result) && (SIGNAL_EXCEPTION)) { + System.exit(result); + } + } + + static void runInOurThreadGroup(final Method main, final String[] args) { + final String classname = main.getDeclaringClass().getName(); + ThreadGroup ourGroup = new ThreadGroup("MainWrapper ThreadGroup") { + public void uncaughtException(Thread t, Throwable e) { + reportException("uncaughtException invoking " + classname, e); + result++; + if (FAIL_ON_EXCEPTION) { + System.exit((SIGNAL_EXCEPTION ? result : 0)); + } + } + }; + Runnable runner = new Runnable() { + public void run() { + try { + main.invoke(null, new Object[] {args}); + } catch (InvocationTargetException e) { + result = -1; + reportException("InvocationTargetException invoking " + classname, e); + } catch (IllegalAccessException e) { + result = -1; + reportException("IllegalAccessException invoking " + classname, e); + } + } + }; + Thread newMain = new Thread(ourGroup, runner, "pseudo-main"); + newMain.start(); + try { + newMain.join(); + } catch (InterruptedException e) { + result = -1; // todo: InterruptedException might be benign - retry? + reportException("Interrupted while waiting for to join " + newMain, e); + } + } + + /** + * Try to load all classes in a directory. + * @throws Error if any failed + */ + static protected void loadAllClasses(File classesDir) { + if (null != classesDir) { + String[] names = LangUtil.classesIn(classesDir); + StringBuffer err = new StringBuffer(); + LangUtil.loadClasses(names, null, err); + if (0 < err.length()) { + throw new Error("MainWrapper Errors loading classes: " + + err.toString()); + } + } + } + + static void reportException(String context, Throwable t) { + PrintStream outStream = OUT_STREAM; + if (null != outStream) { + while ((null != t) && + (InvocationTargetException.class.isAssignableFrom(t.getClass()))) { + t = ((InvocationTargetException) t).getTargetException(); + } + outStream.println(" context: " + context); + outStream.println(" message: " + t.getMessage()); + t.printStackTrace(outStream); + } + } + +} // MainWrapper |