View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  
19  package org.apache.hadoop.hbase;
20  
21  import java.lang.reflect.Method;
22  import java.lang.reflect.Modifier;
23  import java.util.regex.Pattern;
24  
25  import org.apache.hadoop.hbase.ClassFinder.ClassFilter;
26  import org.apache.hadoop.hbase.ClassFinder.FileNameFilter;
27  import org.junit.Test;
28  import org.junit.experimental.categories.Category;
29  import org.junit.runners.Suite;
30  
31  /**
32   * ClassFinder that is pre-configured with filters that will only allow test classes.
33   * The name is strange because a logical name would start with "Test" and be confusing.
34   */
35  public class ClassTestFinder extends ClassFinder {
36  
37    public ClassTestFinder() {
38      super(new TestFileNameFilter(), new TestFileNameFilter(), new TestClassFilter());
39    }
40  
41    public ClassTestFinder(Class<?> category) {
42      super(new TestFileNameFilter(), new TestFileNameFilter(), new TestClassFilter(category));
43    }
44  
45    public static Class<?>[] getCategoryAnnotations(Class<?> c) {
46      Category category = c.getAnnotation(Category.class);
47      if (category != null) {
48        return category.value();
49      }
50      return new Class<?>[0];
51    }
52  
53    /** Filters both test classes and anything in the hadoop-compat modules */
54    public static class TestFileNameFilter implements FileNameFilter, ResourcePathFilter {
55      private static final Pattern hadoopCompactRe =
56          Pattern.compile("hbase-hadoop\\d?-compat");
57  
58      @Override
59      public boolean isCandidateFile(String fileName, String absFilePath) {
60        boolean isTestFile = fileName.startsWith("Test")
61            || fileName.startsWith("IntegrationTest");
62        return isTestFile && !hadoopCompactRe.matcher(absFilePath).find();
63      }
64  
65      @Override
66      public boolean isCandidatePath(String resourcePath, boolean isJar) {
67        return !hadoopCompactRe.matcher(resourcePath).find();
68      }
69    };
70  
71    /*
72    * A class is considered as a test class if:
73     *  - it's not Abstract AND
74     *  - one or more of its methods is annotated with org.junit.Test OR
75     *  - the class is annotated with Suite.SuiteClasses
76    * */
77    public static class TestClassFilter implements ClassFilter {
78      private Class<?> categoryAnnotation = null;
79      public TestClassFilter(Class<?> categoryAnnotation) {
80        this.categoryAnnotation = categoryAnnotation;
81      }
82  
83      public TestClassFilter() {
84        this(null);
85      }
86  
87      @Override
88      public boolean isCandidateClass(Class<?> c) {
89        return isTestClass(c) && isCategorizedClass(c);
90      }
91  
92      private boolean isTestClass(Class<?> c) {
93        if (Modifier.isAbstract(c.getModifiers())) {
94          return false;
95        }
96  
97        if (c.getAnnotation(Suite.SuiteClasses.class) != null) {
98          return true;
99        }
100 
101       for (Method met : c.getMethods()) {
102         if (met.getAnnotation(Test.class) != null) {
103           return true;
104         }
105       }
106 
107       return false;
108     }
109 
110     private boolean isCategorizedClass(Class<?> c) {
111       if (this.categoryAnnotation == null) {
112         return true;
113       }
114       for (Class<?> cc : getCategoryAnnotations(c)) {
115         if (cc.equals(this.categoryAnnotation)) {
116           return true;
117         }
118       }
119       return false;
120     }
121   };
122 };