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"));
+    }
+
 }