You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@ant.apache.org by gs...@apache.org on 2009/02/14 11:32:46 UTC
svn commit: r744468 - in /ant/antlibs/antunit/trunk/src:
main/org/apache/ant/antunit/ main/org/apache/ant/antunit/junit3/
main/org/apache/ant/antunit/junit4/
tests/junit/org/apache/ant/antunit/junit3/
Author: gscokart
Date: Sat Feb 14 10:32:46 2009
New Revision: 744468
URL: http://svn.apache.org/viewvc?rev=744468&view=rev
Log:
Add error handling in the initalisation of the project
Modified:
ant/antlibs/antunit/trunk/src/main/org/apache/ant/antunit/AntUnitScriptRunner.java
ant/antlibs/antunit/trunk/src/main/org/apache/ant/antunit/ProjectFactory.java
ant/antlibs/antunit/trunk/src/main/org/apache/ant/antunit/junit3/AntUnitSuite.java
ant/antlibs/antunit/trunk/src/main/org/apache/ant/antunit/junit3/AntUnitTestCase.java
ant/antlibs/antunit/trunk/src/main/org/apache/ant/antunit/junit4/AntUnitSuiteRunner.java
ant/antlibs/antunit/trunk/src/tests/junit/org/apache/ant/antunit/junit3/AntUnitSuiteTest.java
ant/antlibs/antunit/trunk/src/tests/junit/org/apache/ant/antunit/junit3/AntUnitTestCaseTest.java
Modified: ant/antlibs/antunit/trunk/src/main/org/apache/ant/antunit/AntUnitScriptRunner.java
URL: http://svn.apache.org/viewvc/ant/antlibs/antunit/trunk/src/main/org/apache/ant/antunit/AntUnitScriptRunner.java?rev=744468&r1=744467&r2=744468&view=diff
==============================================================================
--- ant/antlibs/antunit/trunk/src/main/org/apache/ant/antunit/AntUnitScriptRunner.java (original)
+++ ant/antlibs/antunit/trunk/src/main/org/apache/ant/antunit/AntUnitScriptRunner.java Sat Feb 14 10:32:46 2009
@@ -97,8 +97,9 @@
* Create a new AntScriptRunner on the given environment.
* @param prjFactory A factory for the ant project that will contains the antunit test to execute.
* The factory might be invoked multiple time in order to provide test isolation.
+ * @throws BuildException The project can not be parsed
*/
- public AntUnitScriptRunner(ProjectFactory prjFactory) {
+ public AntUnitScriptRunner(ProjectFactory prjFactory) throws BuildException {
this.prjFactory = prjFactory;
Project newProject = getCurrentProject();
Map targets = newProject.getTargets();
@@ -119,8 +120,9 @@
/**
* Get the project currently in use. The caller is not allowed to invoke a target or
* do anything that would break the isolation of the test targets.
+ * @throws BuildException The project can not be parsed
*/
- public final Project getCurrentProject() {
+ public final Project getCurrentProject() throws BuildException {
//Method is final because it is called from the constructor
if (project == null) {
project = prjFactory.createProject();
Modified: ant/antlibs/antunit/trunk/src/main/org/apache/ant/antunit/ProjectFactory.java
URL: http://svn.apache.org/viewvc/ant/antlibs/antunit/trunk/src/main/org/apache/ant/antunit/ProjectFactory.java?rev=744468&r1=744467&r2=744468&view=diff
==============================================================================
--- ant/antlibs/antunit/trunk/src/main/org/apache/ant/antunit/ProjectFactory.java (original)
+++ ant/antlibs/antunit/trunk/src/main/org/apache/ant/antunit/ProjectFactory.java Sat Feb 14 10:32:46 2009
@@ -1,5 +1,6 @@
package org.apache.ant.antunit;
+import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
/**
@@ -14,7 +15,8 @@
/**
* Creates a new project instance and configures it according to the execution context.
+ * @throws BuildException The project can not be created (probably parsed)
*/
- public Project createProject();
+ public Project createProject() throws BuildException;
}
Modified: ant/antlibs/antunit/trunk/src/main/org/apache/ant/antunit/junit3/AntUnitSuite.java
URL: http://svn.apache.org/viewvc/ant/antlibs/antunit/trunk/src/main/org/apache/ant/antunit/junit3/AntUnitSuite.java?rev=744468&r1=744467&r2=744468&view=diff
==============================================================================
--- ant/antlibs/antunit/trunk/src/main/org/apache/ant/antunit/junit3/AntUnitSuite.java (original)
+++ ant/antlibs/antunit/trunk/src/main/org/apache/ant/antunit/junit3/AntUnitSuite.java Sat Feb 14 10:32:46 2009
@@ -28,11 +28,13 @@
import java.util.List;
import junit.framework.Test;
+import junit.framework.TestCase;
import junit.framework.TestResult;
import junit.framework.TestSuite;
import org.apache.ant.antunit.AntUnitScriptRunner;
import org.apache.ant.antunit.ProjectFactory;
+import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DefaultLogger;
import org.apache.tools.ant.MagicNames;
import org.apache.tools.ant.Project;
@@ -47,6 +49,7 @@
private final AntUnitScriptRunner antScriptRunner;
private final MultiProjectDemuxOutputStream stderr;
private final MultiProjectDemuxOutputStream stdout;
+ private final Test initializationReportingTest;
/**
* Create a JUnit TestSuite that when executed will run the given ant
@@ -62,48 +65,85 @@
* The test class that creates this suite. This is used to give
* a name to the suite so that an IDE can reexecute this suite.
*/
- public AntUnitSuite(final File scriptFile, Class rootClass) {
- this(scriptFile);
+ public AntUnitSuite(File scriptFile, Class rootClass) {
+ AntUnitScriptRunner createdScriptRunner = null;
+ try {
+ MyProjectFactory prjFactory = new MyProjectFactory(scriptFile);
+ createdScriptRunner = new AntUnitScriptRunner(prjFactory);
+ } catch (BuildException e) {
+ antScriptRunner = null;
+ stdout = null;
+ stderr = null;
+ initializationReportingTest = error(e);
+ addTest(initializationReportingTest);
+ return;
+ }
+ antScriptRunner = createdScriptRunner;
+ initializationReportingTest = null;
+ stdout = new MultiProjectDemuxOutputStream(antScriptRunner, false);
+ stderr = new MultiProjectDemuxOutputStream(antScriptRunner, true);
+ setName(antScriptRunner.getName() + "[" + scriptFile + "]");
setName(rootClass.getName());// Allows eclipse to reexecute the test
+ List testTargets = antScriptRunner.getTestTartgets();
+ for (Iterator it = testTargets.iterator(); it.hasNext();) {
+ String target = (String) it.next();
+ AntUnitTestCase tc = new AntUnitTestCase(this, scriptFile, target);
+ addTest(tc);
+ }
}
/**
* Constructor used by AntUnitTestCase when a single test case is created.
* The difference with the public constructor is this version doesn't set
* the name.
+ * @throws BuildException when the file project can not be create (parsed/read)
*/
- AntUnitSuite(final File scriptFile) {
+ AntUnitSuite(AntUnitTestCase singleTc , File scriptFile) throws BuildException {
MyProjectFactory prjFactory = new MyProjectFactory(scriptFile);
antScriptRunner = new AntUnitScriptRunner(prjFactory);
+ //the exception is throwed, and it is up to the AntUnitTestCase to handle it.
+ initializationReportingTest = null;
stdout = new MultiProjectDemuxOutputStream(antScriptRunner, false);
stderr = new MultiProjectDemuxOutputStream(antScriptRunner, true);
- setName(antScriptRunner.getName() + "[" + scriptFile + "]");
- List testTargets = antScriptRunner.getTestTartgets();
- for (Iterator it = testTargets.iterator(); it.hasNext();) {
- String target = (String) it.next();
- AntUnitTestCase tc = new AntUnitTestCase(this, scriptFile, target);
- addTest(tc);
- }
+ setName(antScriptRunner.getName() + "[" + scriptFile + "]");
+ addTest(singleTc);
}
-
+
/**
* @Override Run the full AntUnit suite
*/
public void run(TestResult testResult) {
- List testTartgets = antScriptRunner.getTestTartgets();
- runInContainer(testTartgets, testResult, tests());
+ if (initializationReportingTest!=null) {
+ initializationReportingTest.run(testResult);
+ } else {
+ List testTartgets = antScriptRunner.getTestTartgets();
+ runInContainer(testTartgets, testResult);
+ }
+ }
+
+
+ private static Test error(final BuildException ex) {
+ return new TestCase("warning") {
+ protected void runTest() throws BuildException {
+ throw ex;
+ }
+ };
}
+
+
/**
* @Override Run a single test target of the AntUnit suite. suiteSetUp,
* setUp, tearDown and suiteTearDown are executed around it.
*/
public void runTest(Test test, TestResult result) {
- String targetName = ((AntUnitTestCase) test).getTarget();
- List singleTargetList = Collections.singletonList(targetName);
- Enumeration singleTestList = Collections.enumeration(Collections
- .singletonList(test));
- runInContainer(singleTargetList, result, singleTestList);
+ if (initializationReportingTest!=null) {
+ initializationReportingTest.run(result);
+ } else {
+ String targetName = ((AntUnitTestCase) test).getTarget();
+ List singleTargetList = Collections.singletonList(targetName);
+ runInContainer(singleTargetList, result);
+ }
}
/**
@@ -119,10 +159,9 @@
* @param tests
* The JUnit3 Test classes instances to use in the notification.
*/
- private void runInContainer(List targetList, TestResult result,
- Enumeration/*<Test>*/tests) {
+ private void runInContainer(List targetList, TestResult result) {
JUnitNotificationAdapter notifier = new JUnitNotificationAdapter(
- result, tests);
+ result, tests());
PrintStream savedErr = System.err;
PrintStream savedOut = System.out;
try {
Modified: ant/antlibs/antunit/trunk/src/main/org/apache/ant/antunit/junit3/AntUnitTestCase.java
URL: http://svn.apache.org/viewvc/ant/antlibs/antunit/trunk/src/main/org/apache/ant/antunit/junit3/AntUnitTestCase.java?rev=744468&r1=744467&r2=744468&view=diff
==============================================================================
--- ant/antlibs/antunit/trunk/src/main/org/apache/ant/antunit/junit3/AntUnitTestCase.java (original)
+++ ant/antlibs/antunit/trunk/src/main/org/apache/ant/antunit/junit3/AntUnitTestCase.java Sat Feb 14 10:32:46 2009
@@ -22,6 +22,8 @@
import java.io.File;
+import org.apache.tools.ant.BuildException;
+
import junit.framework.TestCase;
import junit.framework.TestResult;
@@ -49,6 +51,15 @@
private final String target;
/**
+ * Store the exception when the project can not be parsed, but only if this
+ * class has been created directly by the IDE from its name.
+ * In case of initialisation problem when the test is build from the suite,
+ * the problem is handled at the level of the suite (and this object is never
+ * created)
+ */
+ private final BuildException initialisationException;
+
+ /**
* Prepare an AntUnitTestCase that will be executed alone. This constructor
* is typically used by a junit 3 runner that will reexecute a specific
* test.</br>
@@ -59,10 +70,19 @@
*/
public AntUnitTestCase(String name) {
super(name);
- TestCaseName nameParser = new TestCaseName(name);
- target = nameParser.getTarget();
- suite = new AntUnitSuite(nameParser.getScript());
- // TODO : check that target is in the list
+ BuildException catchedEx = null;
+ AntUnitSuite createdSuite = null;
+ TestCaseName nameParser = new TestCaseName(name);
+ try {
+ createdSuite = new AntUnitSuite(this, nameParser.getScript());
+ } catch (BuildException e) {
+ catchedEx = e;
+ }
+ this.initialisationException = catchedEx;
+ this.suite = createdSuite;
+ this.target = nameParser.getTarget();
+ //There is no need to check here if the target still exists. This check
+ //will be done during execution, and we will get a very nice error
}
/**
@@ -80,6 +100,7 @@
super(new TestCaseName(scriptFile, target).getName());
this.target = target;
this.suite = suite;
+ this.initialisationException = null;
}
/** Get the AntUnit test target name */
@@ -87,12 +108,35 @@
return target;
}
- /** @overwrite */
+ /**
+ * Called by a Junit Runner that want to executes specifically
+ * this test target.
+ * This implementation delegates the call to the suite.
+ * @Overwrite
+ */
public void run(TestResult result) {
- suite.runTest(this, result);
+ if (initialisationException==null && suite!=null) {
+ //normal case, the test is executed from the suite
+ suite.runTest(this, result);
+ } else {
+ //special case, the suite failed to be created
+ //the execution will be handled by this object
+ //directly
+ super.run(result);
+ }
}
/**
+ * Normally never used because this object delegates all execution
+ * to an AntUnitSuite. However, when the suite can not be created
+ * (because the ant project is invalid), this object is executed
+ * and just throws the exception.
+ */
+ protected void runTest() throws BuildException {
+ throw initialisationException;
+ }
+
+ /**
* Handle the serialization and the parsing of the name of a TestCase. The
* name of the TestCase contains the filename of the script and the target,
* so that the name uniquely identify the TestCase, and a TestCase can be
Modified: ant/antlibs/antunit/trunk/src/main/org/apache/ant/antunit/junit4/AntUnitSuiteRunner.java
URL: http://svn.apache.org/viewvc/ant/antlibs/antunit/trunk/src/main/org/apache/ant/antunit/junit4/AntUnitSuiteRunner.java?rev=744468&r1=744467&r2=744468&view=diff
==============================================================================
--- ant/antlibs/antunit/trunk/src/main/org/apache/ant/antunit/junit4/AntUnitSuiteRunner.java (original)
+++ ant/antlibs/antunit/trunk/src/main/org/apache/ant/antunit/junit4/AntUnitSuiteRunner.java Sat Feb 14 10:32:46 2009
@@ -44,6 +44,9 @@
super(suite.getName());
Enumeration tests = suite.tests();
while (tests.hasMoreElements()) {
+ //TODO Handle the the case of FileNotFound.
+ //In that case the suite contains an error Test and we have
+ //a ClassCastException instead of a nice & clear error
AntUnitTestCase tc = (AntUnitTestCase) tests.nextElement();
add(new AntUnitTestCaseRunner(tc, junitTestClass));
}
Modified: ant/antlibs/antunit/trunk/src/tests/junit/org/apache/ant/antunit/junit3/AntUnitSuiteTest.java
URL: http://svn.apache.org/viewvc/ant/antlibs/antunit/trunk/src/tests/junit/org/apache/ant/antunit/junit3/AntUnitSuiteTest.java?rev=744468&r1=744467&r2=744468&view=diff
==============================================================================
--- ant/antlibs/antunit/trunk/src/tests/junit/org/apache/ant/antunit/junit3/AntUnitSuiteTest.java (original)
+++ ant/antlibs/antunit/trunk/src/tests/junit/org/apache/ant/antunit/junit3/AntUnitSuiteTest.java Sat Feb 14 10:32:46 2009
@@ -27,6 +27,7 @@
import java.util.Enumeration;
import junit.framework.TestCase;
+import junit.framework.TestFailure;
import junit.framework.TestResult;
import org.apache.tools.ant.util.FileUtils;
@@ -34,7 +35,7 @@
public class AntUnitSuiteTest extends TestCase {
AntUnitSuite suite = new AntUnitSuite(new File(
- "src/etc/testcases/antunit/junit.xml"));
+ "src/etc/testcases/antunit/junit.xml"), AntUnitSuiteTest.class);
File outFile = new File("target/test_output/junit_out.xml");
public void testRunSuiteSetUp() throws FileNotFoundException, IOException {
@@ -51,8 +52,8 @@
}
public void testSuiteName() {
- assertTrue("Expected non empty suite name", suite.getName().trim()
- .length() > 0);
+ assertTrue("Expected non empty suite name",
+ suite.getName().trim().length() > 0);
}
public void testChildNames() {
@@ -84,4 +85,16 @@
"suiteSetUp-setUp-test1-tearDown-suiteTearDown".equals(output));
}
+ public void testFileNotFound() throws Exception {
+ suite = new AntUnitSuite(new File("xxxx"), AntUnitSuiteTest.class);
+ TestResult testResult = new TestResult();
+ suite.run(testResult);
+
+ assertEquals(1 , testResult.errorCount());
+ TestFailure error = (TestFailure) testResult.errors().nextElement();
+ assertTrue("Unexpected error : " + error.exceptionMessage(),
+ error.exceptionMessage().contains("xxxx"));
+ }
+
+ //TODO test missing target error reporting
}
Modified: ant/antlibs/antunit/trunk/src/tests/junit/org/apache/ant/antunit/junit3/AntUnitTestCaseTest.java
URL: http://svn.apache.org/viewvc/ant/antlibs/antunit/trunk/src/tests/junit/org/apache/ant/antunit/junit3/AntUnitTestCaseTest.java?rev=744468&r1=744467&r2=744468&view=diff
==============================================================================
--- ant/antlibs/antunit/trunk/src/tests/junit/org/apache/ant/antunit/junit3/AntUnitTestCaseTest.java (original)
+++ ant/antlibs/antunit/trunk/src/tests/junit/org/apache/ant/antunit/junit3/AntUnitTestCaseTest.java Sat Feb 14 10:32:46 2009
@@ -30,12 +30,16 @@
import junit.framework.Assert;
import junit.framework.Test;
import junit.framework.TestCase;
+import junit.framework.TestFailure;
import junit.framework.TestResult;
public class AntUnitTestCaseTest extends TestCase {
File f = new File("src/etc/testcases/antunit/junit.xml");
+ File invalidF = new File("invalidFile");
String test1Name = new AntUnitTestCase.TestCaseName(f, "test1").getName();
+ String unknownName = new AntUnitTestCase.TestCaseName(f, "unknown").getName();
+ String nameForInvalidF = new AntUnitTestCase.TestCaseName(invalidF, "x").getName();
File outFile = new File("target/test_output/junit_out.xml");
@@ -84,7 +88,38 @@
AntUnitTestCase antUnitTestCase = new AntUnitTestCase(test1Name);
antUnitTestCase.run(testResultMock);
- Assert.assertSame(antUnitTestCase, startedTest);
- Assert.assertSame(antUnitTestCase, endedTest);
+ assertSame(antUnitTestCase, startedTest);
+ assertSame(antUnitTestCase, endedTest);
}
+
+ public void testUnknownTarget() {
+ //when the antscript has changed (the target has been removed) and the user try
+ //to rerun this target.
+ TestResult testResult = new TestResult();
+
+ AntUnitTestCase antUnitTestCase = new AntUnitTestCase(unknownName);
+ antUnitTestCase.run(testResult);
+
+ assertEquals(1 , testResult.errorCount());
+ TestFailure error = (TestFailure) testResult.errors().nextElement();
+ assertSame(antUnitTestCase, error.failedTest());
+ assertTrue("Unexpected error : " + error.exceptionMessage(),
+ error.exceptionMessage().contains("unknown"));
+ }
+
+ public void testInvalidFile() {
+ //when the ant script has changed (or just disappeared) and the user try
+ //to rerun this target.
+ TestResult testResult = new TestResult();
+
+ AntUnitTestCase antUnitTestCase = new AntUnitTestCase(nameForInvalidF);
+ antUnitTestCase.run(testResult);
+
+ assertEquals(1 , testResult.errorCount());
+ TestFailure error = (TestFailure) testResult.errors().nextElement();
+ assertSame(antUnitTestCase, error.failedTest());
+ assertTrue("Unexpected error : " + error.exceptionMessage(),
+ error.exceptionMessage().contains("invalidFile"));
+ }
+
}