001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase; 019 020import java.lang.reflect.Method; 021import java.lang.reflect.Modifier; 022import java.util.regex.Pattern; 023import org.junit.Test; 024import org.junit.experimental.categories.Category; 025import org.junit.runners.Suite; 026 027/** 028 * ClassFinder that is pre-configured with filters that will only allow test classes. The name is 029 * strange because a logical name would start with "Test" and be confusing. 030 */ 031public class ClassTestFinder extends ClassFinder { 032 033 public ClassTestFinder() { 034 super(new TestFileNameFilter(), new TestFileNameFilter(), new TestClassFilter()); 035 } 036 037 public ClassTestFinder(Class<?> category) { 038 super(new TestFileNameFilter(), new TestFileNameFilter(), new TestClassFilter(category)); 039 } 040 041 public static Class<?>[] getCategoryAnnotations(Class<?> c) { 042 Category category = c.getAnnotation(Category.class); 043 if (category != null) { 044 return category.value(); 045 } 046 return new Class<?>[0]; 047 } 048 049 /** Filters both test classes and anything in the hadoop-compat modules */ 050 public static class TestFileNameFilter implements FileNameFilter, ResourcePathFilter { 051 private static final Pattern hadoopCompactRe = Pattern.compile("hbase-hadoop\\d?-compat"); 052 053 @Override 054 public boolean isCandidateFile(String fileName, String absFilePath) { 055 boolean isTestFile = fileName.startsWith("Test") || fileName.startsWith("IntegrationTest"); 056 return isTestFile && !hadoopCompactRe.matcher(absFilePath).find(); 057 } 058 059 @Override 060 public boolean isCandidatePath(String resourcePath, boolean isJar) { 061 return !hadoopCompactRe.matcher(resourcePath).find(); 062 } 063 } 064 065 /* 066 * A class is considered as a test class if: - it's not Abstract AND - one or more of its methods 067 * is annotated with org.junit.Test OR - the class is annotated with Suite.SuiteClasses 068 */ 069 public static class TestClassFilter implements ClassFilter { 070 private Class<?> categoryAnnotation = null; 071 072 public TestClassFilter(Class<?> categoryAnnotation) { 073 this.categoryAnnotation = categoryAnnotation; 074 } 075 076 public TestClassFilter() { 077 this(null); 078 } 079 080 @Override 081 public boolean isCandidateClass(Class<?> c) { 082 return isTestClass(c) && isCategorizedClass(c); 083 } 084 085 private boolean isTestClass(Class<?> c) { 086 if (Modifier.isAbstract(c.getModifiers())) { 087 return false; 088 } 089 090 if (c.getAnnotation(Suite.SuiteClasses.class) != null) { 091 return true; 092 } 093 094 for (Method met : c.getMethods()) { 095 if (met.getAnnotation(Test.class) != null) { 096 return true; 097 } 098 } 099 100 return false; 101 } 102 103 private boolean isCategorizedClass(Class<?> c) { 104 if (this.categoryAnnotation == null) { 105 return true; 106 } 107 for (Class<?> cc : getCategoryAnnotations(c)) { 108 if (cc.equals(this.categoryAnnotation)) { 109 return true; 110 } 111 } 112 return false; 113 } 114 } 115}