From 2679e77604bf50748ec715206258dd8a3586fb87 Mon Sep 17 00:00:00 2001 From: avasseur Date: Wed, 4 May 2005 14:57:21 +0000 Subject: LTW modules + AntSpec to test LTW in the sandbox + code cleanup in my FIXME + fix in error handling when no debug info can be read from @Aj aspect (many files modified since refactored IMessageHanlder for LTW dontIgnore method) --- testing/newsrc/org/aspectj/testing/AntSpec.java | 187 +++++++++++++++++++++ .../org/aspectj/testing/XMLBasedAjcTestCase.java | 11 ++ testing/src/org/aspectj/testing/run/RunStatus.java | 14 +- 3 files changed, 207 insertions(+), 5 deletions(-) create mode 100644 testing/newsrc/org/aspectj/testing/AntSpec.java (limited to 'testing') diff --git a/testing/newsrc/org/aspectj/testing/AntSpec.java b/testing/newsrc/org/aspectj/testing/AntSpec.java new file mode 100644 index 000000000..84abb4b2a --- /dev/null +++ b/testing/newsrc/org/aspectj/testing/AntSpec.java @@ -0,0 +1,187 @@ +/******************************************************************************* + * Copyright (c) 2005 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: + * Alexandre Vasseur initial implementation + *******************************************************************************/ +package org.aspectj.testing; + +import org.aspectj.tools.ajc.AjcTestCase; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.ProjectHelper; +import org.apache.tools.ant.DefaultLogger; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.BuildEvent; +import org.apache.tools.ant.types.Path; + +import java.io.File; +import java.util.StringTokenizer; + +/** + * Element that allow to run an abritrary Ant target in a sandbox. + *

+ * Such a spec is used in a " XML element. + * The "target" is optional. If not set, default myAnt.xml target is used. + * The "file" file is looked up from the attribute. + * If "verbose" is set to "true", the ant -v output is piped, else nothing is reported except errors. + *

+ * The called Ant target benefits from 2 implicit variables: + * "${aj.sandbox}" points to the test current sandbox folder. + * "aj.path" is an Ant refid on the classpath formed with the sandbox folder + ltw + the AjcTestCase classpath + * (ie usually aspectjrt, junit, and testing infra) + *

+ * Element "" and "" can be used. For now a full match + * is performed on the output of the runned target only (not the whole Ant invocation). This is experimental + * and advised to use a "" task instead or a "" whose main that throws some exception upon failure. + * + * + * @author Alexandre Vasseur + */ +public class AntSpec implements ITestStep { + + private final static String DEFAULT_LTW_CLASSPATH_ENTRIES = + ".." + File.separator + "_IDE"//ALEX hack since IntelliJ does not produce modules/bin/ + + File.pathSeparator + ".." + File.separator + "asm/bin" + + File.pathSeparator + ".." + File.separator + "bridge/bin" + + File.pathSeparator + ".." + File.separator + "loadtime/bin" + + File.pathSeparator + ".." + File.separator + "loadtime5/bin" + + File.pathSeparator + ".." + File.separator + "weaver/bin" + + File.pathSeparator + ".." + File.separator + "lib/bcel/bcel.jar"; + + + private boolean m_verbose = false; + private AjcTest m_ajcTest; + private OutputSpec m_stdErrSpec; + private OutputSpec m_stdOutSpec; + private String m_antFile; + private String m_antTarget; + + public void execute(AjcTestCase inTestCase) { + final String failMessage = "test \"" + m_ajcTest.getTitle() + "\" failed: "; + + File buildFile = new File(m_ajcTest.getDir() + File.separatorChar + m_antFile); + if (!buildFile.exists()) { + AjcTestCase.fail(failMessage + "no such Ant file " + buildFile.getAbsolutePath()); + } + Project p = new Project(); + final StringBuffer stdout = new StringBuffer(); + final StringBuffer stderr = new StringBuffer(); + try { + // read the Ant file + p.init(); + p.setUserProperty("ant.file", buildFile.getAbsolutePath()); + // setup aj.sandbox + p.setUserProperty("aj.sandbox", inTestCase.getSandboxDirectory().getAbsolutePath()); + // setup aj.dir "modules" folder + p.setUserProperty("aj.root", new File("..").getAbsolutePath()); + + ProjectHelper helper = ProjectHelper.getProjectHelper(); + helper.parse(p, buildFile); + + // use default target if no target specified + if (m_antTarget == null) { + m_antTarget = p.getDefaultTarget(); + } + + // make sure we listen for failure + DefaultLogger consoleLogger = new DefaultLogger() { + public void targetFinished(BuildEvent event) { + super.targetFinished(event); + if (event.getException() != null) { + AjcTestCase.fail(failMessage + "failure in '" + event.getTarget() + "' " + event.getException()); + } + } + public void messageLogged(BuildEvent event) { + super.messageLogged(event); + if (event.getTarget() != null && event.getPriority() >= Project.MSG_INFO && m_antTarget.equals(event.getTarget().getName())) { + if (event.getException() == null) { + stdout.append(event.getMessage()).append('\n'); + } else { + stderr.append(event.getMessage()); + } + } + } + }; + consoleLogger.setErrorPrintStream(System.err); + consoleLogger.setOutputPrintStream(System.out); + consoleLogger.setMessageOutputLevel(m_verbose?Project.MSG_VERBOSE:Project.MSG_ERR); + p.addBuildListener(consoleLogger); + + // create the test implicit path aj.path that contains the sandbox + regular test infra path + Path path = new Path(p, inTestCase.getSandboxDirectory().getAbsolutePath()); + populatePath(path, DEFAULT_LTW_CLASSPATH_ENTRIES); + populatePath(path, AjcTestCase.DEFAULT_CLASSPATH_ENTRIES); + p.addReference("aj.path", path); + } catch (Throwable t) { + AjcTestCase.fail(failMessage + "invalid Ant script :" + t.toString()); + } + try { + p.fireBuildStarted(); + p.executeTarget(m_antTarget); + p.fireBuildFinished(null); + } catch (BuildException e) { + p.fireBuildFinished(e); + } catch (Throwable t) { + AjcTestCase.fail(failMessage + "error when invoking target :" + t.toString()); + } + + // match lines + //TODO AV experimental: requires full match so rather useless. + // if someone needs it, we ll have to impl a "include / exclude" stuff + if (m_stdOutSpec != null) + m_stdOutSpec.matchAgainst(stdout.toString()); + // match lines + if (m_stdErrSpec != null) + m_stdErrSpec.matchAgainst(stdout.toString()); + } + + public void addStdErrSpec(OutputSpec spec) { + if (m_stdErrSpec!=null) + throw new UnsupportedOperationException("only one 'stderr' allowed in 'ant'"); + m_stdErrSpec = spec; + } + + public void addStdOutSpec(OutputSpec spec) { + if (m_stdOutSpec!=null) + throw new UnsupportedOperationException("only one 'stdout' allowed in 'ant'"); + m_stdOutSpec = spec; + } + + public void setVerbose(String verbose) { + if (verbose != null && "true".equalsIgnoreCase(verbose)) { + m_verbose = true; + } + } + + public void setFile(String file) { + m_antFile = file; + } + + public void setTarget(String target) { + m_antTarget = target; + } + + public void addExpectedMessage(ExpectedMessageSpec message) { + throw new UnsupportedOperationException("don't use 'message' in 'ant' specs."); + } + + public void setBaseDir(String dir) { + ; + } + + public void setTest(AjcTest test) { + m_ajcTest = test; + } + + private static void populatePath(Path path, String pathEntries) { + StringTokenizer st = new StringTokenizer(pathEntries, File.pathSeparator); + while (st.hasMoreTokens()) { + path.setPath(new File(st.nextToken()).getAbsolutePath()); + } + } +} diff --git a/testing/newsrc/org/aspectj/testing/XMLBasedAjcTestCase.java b/testing/newsrc/org/aspectj/testing/XMLBasedAjcTestCase.java index 91ded4c1a..2f00a3c1b 100644 --- a/testing/newsrc/org/aspectj/testing/XMLBasedAjcTestCase.java +++ b/testing/newsrc/org/aspectj/testing/XMLBasedAjcTestCase.java @@ -145,6 +145,17 @@ public abstract class XMLBasedAjcTestCase extends AjcTestCase { digester.addObjectCreate("suite/ajc-test/weave",WeaveSpec.class); digester.addSetProperties("suite/ajc-test/weave"); digester.addSetNext("suite/ajc-test/weave","addTestStep","org.aspectj.testing.ITestStep"); + + digester.addObjectCreate("suite/ajc-test/ant",AntSpec.class); + digester.addSetProperties("suite/ajc-test/ant"); + digester.addSetNext("suite/ajc-test/ant","addTestStep","org.aspectj.testing.ITestStep"); + digester.addObjectCreate("suite/ajc-test/ant/stderr",OutputSpec.class); + digester.addSetProperties("suite/ajc-test/ant/stderr"); + digester.addSetNext("suite/ajc-test/ant/stderr","addStdErrSpec","org.aspectj.testing.OutputSpec"); + digester.addObjectCreate("suite/ajc-test/ant/stdout",OutputSpec.class); + digester.addSetProperties("suite/ajc-test/ant/stdout"); + digester.addSetNext("suite/ajc-test/ant/stdout","addStdOutSpec","org.aspectj.testing.OutputSpec"); + digester.addObjectCreate("suite/ajc-test/run/stderr",OutputSpec.class); digester.addSetProperties("suite/ajc-test/run/stderr"); digester.addSetNext("suite/ajc-test/run/stderr","addStdErrSpec","org.aspectj.testing.OutputSpec"); diff --git a/testing/src/org/aspectj/testing/run/RunStatus.java b/testing/src/org/aspectj/testing/run/RunStatus.java index ce3bff73a..71fd63612 100644 --- a/testing/src/org/aspectj/testing/run/RunStatus.java +++ b/testing/src/org/aspectj/testing/run/RunStatus.java @@ -224,7 +224,7 @@ public class RunStatus implements IRunStatus { * @return true if completed, not aborted, no thrown, no * messages of kind ERROR, FAIL or ABORT, and * result object is not IRunStatus.FAIL. - * @see org.aspectj.testing.harness.newbridge.IRunStatus#runResult() + * @see org.aspectj.testing.run.IRunStatus#runResult() */ public boolean runResult() { return validator.runPassed(this); @@ -277,23 +277,27 @@ public class RunStatus implements IRunStatus { public boolean isIgnoring(IMessage.Kind kind) { return messageHolder.isIgnoring(kind); } - + + public void dontIgnore(IMessage.Kind kind) { + messageHolder.dontIgnore(kind); + } + /** - * @see org.aspectj.bridge.IMessageHolder#hasAnyMessage(Kind, boolean) + * @see org.aspectj.bridge.IMessageHolder#hasAnyMessage(org.aspectj.bridge.IMessage.Kind, boolean) */ public boolean hasAnyMessage(IMessage.Kind kind, boolean orGreater) { return messageHolder.hasAnyMessage(kind, orGreater); } /** - * @see org.aspectj.bridge.IMessageHolder#getMessages(Kind) + * @see org.aspectj.bridge.IMessageHolder#getMessages(org.aspectj.bridge.IMessage.Kind, boolean) */ public IMessage[] getMessages(IMessage.Kind kind, boolean orGreater) { return messageHolder.getMessages(kind, orGreater); } /** - * @see org.aspectj.bridge.IMessageHolder#numMessages(Kind) + * @see org.aspectj.bridge.IMessageHolder#numMessages(org.aspectj.bridge.IMessage.Kind, boolean) */ public int numMessages(IMessage.Kind kind, boolean orGreater) { return messageHolder.numMessages(kind, orGreater); -- cgit v1.2.3