sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1392801 - in /sis/trunk/sis-utility/src/test/java/org/apache/sis/test: DependsOn.java DependsOnMethod.java TestRunner.java
Date Tue, 02 Oct 2012 09:18:31 GMT
Author: desruisseaux
Date: Tue Oct  2 09:18:30 2012
New Revision: 1392801

URL: http://svn.apache.org/viewvc?rev=1392801&view=rev
Log:
Added support for class dependencies in the test suite, and added verification of method existence
in method dependencies.

Added:
    sis/trunk/sis-utility/src/test/java/org/apache/sis/test/DependsOn.java   (with props)
Modified:
    sis/trunk/sis-utility/src/test/java/org/apache/sis/test/DependsOnMethod.java
    sis/trunk/sis-utility/src/test/java/org/apache/sis/test/TestRunner.java

Added: sis/trunk/sis-utility/src/test/java/org/apache/sis/test/DependsOn.java
URL: http://svn.apache.org/viewvc/sis/trunk/sis-utility/src/test/java/org/apache/sis/test/DependsOn.java?rev=1392801&view=auto
==============================================================================
--- sis/trunk/sis-utility/src/test/java/org/apache/sis/test/DependsOn.java (added)
+++ sis/trunk/sis-utility/src/test/java/org/apache/sis/test/DependsOn.java Tue Oct  2 09:18:30
2012
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.test;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+
+/**
+ * Declares that a test class depends on an other test class. If any test method in any
+ * dependency failed, then all tests in the annotated class will be skipped.
+ *
+ * @author  Martin Desruisseaux
+ * @since   0.3 (derived from geotk-3.00)
+ * @version 0.3
+ * @module
+ */
+@Inherited
+@Documented
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface DependsOn {
+    /**
+     * The other test classes on which this test depends.
+     *
+     * @return The test dependencies.
+     */
+    Class<?>[] value();
+}

Propchange: sis/trunk/sis-utility/src/test/java/org/apache/sis/test/DependsOn.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/trunk/sis-utility/src/test/java/org/apache/sis/test/DependsOn.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: sis/trunk/sis-utility/src/test/java/org/apache/sis/test/DependsOnMethod.java
URL: http://svn.apache.org/viewvc/sis/trunk/sis-utility/src/test/java/org/apache/sis/test/DependsOnMethod.java?rev=1392801&r1=1392800&r2=1392801&view=diff
==============================================================================
--- sis/trunk/sis-utility/src/test/java/org/apache/sis/test/DependsOnMethod.java (original)
+++ sis/trunk/sis-utility/src/test/java/org/apache/sis/test/DependsOnMethod.java Tue Oct 
2 09:18:30 2012
@@ -25,9 +25,9 @@ import java.lang.annotation.Target;
 
 
 /**
- * Identifies the dependencies of a test. If any of the dependencies of a test can not be
- * executed successfully, (i.e. those tests failed, threw an error, or were skipped) then
- * the annotated test will be skipped.
+ * Declares that a test method depends on an other test method. If any of the dependencies
of
+ * a test can not be executed successfully, (i.e. those tests failed, threw an error, or
were
+ * skipped) then the annotated test will be skipped.
  *
  * @author  Stephen Connolly
  * @since   0.3 (derived from <a href="http://github.com/junit-team/junit.contrib/tree/master/assumes">junit-team</a>)
@@ -44,5 +44,5 @@ public @interface DependsOnMethod {
      *
      * @return The names of test methods on which the annotated method depends.
      */
-    public String[] value();
+    String[] value();
 }

Modified: sis/trunk/sis-utility/src/test/java/org/apache/sis/test/TestRunner.java
URL: http://svn.apache.org/viewvc/sis/trunk/sis-utility/src/test/java/org/apache/sis/test/TestRunner.java?rev=1392801&r1=1392800&r2=1392801&view=diff
==============================================================================
--- sis/trunk/sis-utility/src/test/java/org/apache/sis/test/TestRunner.java (original)
+++ sis/trunk/sis-utility/src/test/java/org/apache/sis/test/TestRunner.java Tue Oct  2 09:18:30
2012
@@ -23,6 +23,7 @@ import java.util.Arrays;
 import java.util.Comparator;
 import net.jcip.annotations.NotThreadSafe;
 
+import org.junit.Test;
 import org.junit.runner.Description;
 import org.junit.runner.manipulation.Filter;
 import org.junit.runner.manipulation.NoTestsRemainException;
@@ -34,8 +35,11 @@ import org.junit.runners.BlockJUnit4Clas
 import org.junit.runners.model.FrameworkMethod;
 import org.junit.runners.model.InitializationError;
 import org.junit.runners.model.Statement;
+import org.junit.runners.model.TestClass;
 
 import static org.apache.sis.util.Arrays.resize;
+import static org.apache.sis.util.collection.Collections.isNullOrEmpty;
+import static org.apache.sis.util.collection.Collections.hashMapCapacity;
 
 
 /**
@@ -43,7 +47,7 @@ import static org.apache.sis.util.Arrays
  * This class extends the JUnit standard test runner with additional features:
  * <p>
  * <ul>
- *   <li>Support of the {@link DependsOnMethod} annotation.</li>
+ *   <li>Support of the {@link DependsOn} and {@link DependsOnMethod} annotations.</li>
  * </ul>
  * <p>
  * This runner is not designed for parallel execution of tests.
@@ -67,7 +71,22 @@ public final class TestRunner extends Bl
      *
      * @see #addDependencyFailure(String)
      */
-    private Set<String> dependencyFailures;
+    private Set<String> methodDependencyFailures;
+
+    /**
+     * The dependency classes that failed. This set will be created only when first needed.
+     *
+     * @see #addDependencyFailure(String)
+     */
+    private static Set<Class<?>> classDependencyFailures;
+
+    /**
+     * {@code true} if every tests shall be skipped. This happen if at least one test failure
+     * occurred in at least one class listed in the {@link DependsOn} annotation.
+     *
+     * @see #checkClassDependencies()
+     */
+    private boolean skipAll;
 
     /**
      * The listener to use for keeping trace of methods that failed.
@@ -100,6 +119,35 @@ public final class TestRunner extends Bl
     }
 
     /**
+     * Validates all tests methods in the test class. This method first performs the default
+     * verification documented in {@link BlockJUnit4ClassRunner#validateTestMethods()}, then
+     * ensures that all {@link DependsOnMethod} annotations refer to an existing method.
+     *
+     * @param errors The list where to report any problem found.
+     */
+    @Override
+    protected void validateTestMethods(final List<Throwable> errors) {
+        super.validateTestMethods(errors);
+        final TestClass testClass = getTestClass();
+        final List<FrameworkMethod> depends = testClass.getAnnotatedMethods(DependsOnMethod.class);
+        if (!isNullOrEmpty(depends)) {
+            final Set<String> dependencies = new HashSet<String>(hashMapCapacity(depends.size()));
+            for (final FrameworkMethod method : depends) {
+                for (final String value : method.getAnnotation(DependsOnMethod.class).value())
{
+                    dependencies.add(value);
+                }
+            }
+            for (final FrameworkMethod method : testClass.getAnnotatedMethods(Test.class))
{
+                dependencies.remove(method.getName());
+            }
+            for (final String notFound : dependencies) {
+                errors.add(new NoSuchMethodException("@DependsOnMethod(\"" + notFound + "\"):
"
+                        + "method not found in " + testClass.getName()));
+            }
+        }
+    }
+
+    /**
      * Returns the test methods to be executed, with dependencies sorted before dependant
tests.
      *
      * @return The test method to be executed in dependencies order.
@@ -215,6 +263,7 @@ public final class TestRunner extends Bl
         return new Statement() {
             @Override
             public void evaluate() throws Throwable {
+                checkClassDependencies();
                 notifier.addListener(listener);
                 try {
                     stmt.evaluate();
@@ -234,12 +283,16 @@ public final class TestRunner extends Bl
      */
     @Override
     protected void runChild(final FrameworkMethod method, final RunNotifier notifier) {
-        if (dependencyFailures != null) {
+        if (skipAll) {
+            notifier.fireTestIgnored(describeChild(method));
+            return;
+        }
+        if (methodDependencyFailures != null) {
             final DependsOnMethod assumptions = method.getAnnotation(DependsOnMethod.class);
             if (assumptions != null) {
                 for (final String assumption : assumptions.value()) {
-                    if (dependencyFailures.contains(assumption)) {
-                        dependencyFailures.add(method.getName());
+                    if (methodDependencyFailures.contains(assumption)) {
+                        methodDependencyFailures.add(method.getName());
                         notifier.fireTestIgnored(describeChild(method));
                         return;
                     }
@@ -256,9 +309,37 @@ public final class TestRunner extends Bl
      * @param methodName The name of the method that failed.
      */
     final void addDependencyFailure(final String methodName) {
-        if (dependencyFailures == null) {
-            dependencyFailures = new HashSet<String>();
+        if (methodDependencyFailures == null) {
+            methodDependencyFailures = new HashSet<String>();
+        }
+        methodDependencyFailures.add(methodName);
+        synchronized (TestRunner.class) {
+            if (classDependencyFailures == null) {
+                classDependencyFailures = new HashSet<Class<?>>();
+            }
+            classDependencyFailures.add(getTestClass().getJavaClass());
+        }
+    }
+
+    /**
+     * If at least one test failure occurred in at least one class listed in the {@link DependsOn}
+     * annotation, set the {@link #skipAll} field to {@code true}. This method shall be invoked
+     * before the tests are run.
+     */
+    final void checkClassDependencies() {
+        final Class<?> testClass = getTestClass().getJavaClass();
+        final DependsOn dependsOn = testClass.getAnnotation(DependsOn.class);
+        if (dependsOn != null) {
+            synchronized (TestRunner.class) {
+                if (classDependencyFailures != null) {
+                    for (final Class<?> dependency : dependsOn.value()) {
+                        if (classDependencyFailures.contains(dependency)) {
+                            classDependencyFailures.add(testClass);
+                            skipAll = true;
+                        }
+                    }
+                }
+            }
         }
-        dependencyFailures.add(methodName);
     }
 }



Mime
View raw message