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    public static class TestFileNameFilter implements FileNameFilter, ResourcePathFilter {
54      private static final Pattern hadoopCompactRe =
55          Pattern.compile("hbase-hadoop\\d?-compat");
56  
57      @Override
58      public boolean isCandidateFile(String fileName, String absFilePath) {
59        boolean isTestFile = fileName.startsWith("Test")
60            || fileName.startsWith("IntegrationTest");
61        return isTestFile && !hadoopCompactRe.matcher(absFilePath).find();
62      }
63  
64      @Override
65      public boolean isCandidatePath(String resourcePath, boolean isJar) {
66        return !hadoopCompactRe.matcher(resourcePath).find();
67      }
68    };
69  
70    /*
71    * A class is considered as a test class if:
72     *  - it's not Abstract AND
73     *  - one or more of its methods is annotated with org.junit.Test OR
74     *  - the class is annotated with Suite.SuiteClasses
75    * */
76    public static class TestClassFilter implements ClassFilter {
77      private Class<?> categoryAnnotation = null;
78      public TestClassFilter(Class<?> categoryAnnotation) {
79        this.categoryAnnotation = categoryAnnotation;
80      }
81  
82      public TestClassFilter() {
83        this(null);
84      }
85  
86      @Override
87      public boolean isCandidateClass(Class<?> c) {
88        return isTestClass(c) && isCategorizedClass(c);
89      }
90  
91      private boolean isTestClass(Class<?> c) {
92        if (Modifier.isAbstract(c.getModifiers())) {
93          return false;
94        }
95  
96        if (c.getAnnotation(Suite.SuiteClasses.class) != null) {
97          return true;
98        }
99  
100       for (Method met : c.getMethods()) {
101         if (met.getAnnotation(Test.class) != null) {
102           return true;
103         }
104       }
105 
106       return false;
107     }
108 
109     private boolean isCategorizedClass(Class<?> c) {
110       if (this.categoryAnnotation == null) {
111         return true;
112       }
113       for (Class<?> cc : getCategoryAnnotations(c)) {
114         if (cc.equals(this.categoryAnnotation)) {
115           return true;
116         }
117       }
118       return false;
119     }
120   };
121 };