blob: 11b66b3157ab64338df9d035bf55caa94e16c381 [file] [log] [blame]
/*
* 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.sling.testing.junit.rules;
import org.apache.sling.testing.junit.rules.annotation.IgnoreIf;
import org.apache.sling.testing.junit.rules.annotation.IgnoreIfProperties;
import org.apache.sling.testing.junit.rules.annotation.IgnoreIfProperty;
import org.apache.sling.testing.junit.rules.util.Match;
import org.apache.sling.testing.junit.rules.util.IgnoreTestsConfig;
import org.junit.AssumptionViolatedException;
import org.junit.experimental.categories.Category;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.junit.rules.TestRule;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class FilterRule implements TestRule {
private static final Logger LOG = LoggerFactory.getLogger(FilterRule.class);
public static final String CATEGORY_PROPERTY = "filterCategory";
public static final String INCLUDE_CATEGORY_PROPERTY = "runOnlyFilteredCategories";
private List<String> defaultCategories = new ArrayList<String>();
@Override
public Statement apply(Statement base, Description description) {
// get the annotations in order and skip the tests accordingly
// IgnoreIf
IgnoreIf ignoreIf = description.getAnnotation(IgnoreIf.class);
if (null != ignoreIf) {
for (Class condClass : Arrays.asList(ignoreIf.value())) {
try {
Constructor<? extends Condition> constructor = condClass.getConstructor();
Condition cond = constructor.newInstance();
if (cond.satisfy()) {
return emptyStatement("IgnoreIf condition met to skip: " + cond.description());
}
} catch (Exception e) {
LOG.error("Error getting condition object", e);
}
}
}
// IgnoreIfProperties
List<IgnoreIfProperty> ignoreIfPropertyList = new ArrayList<IgnoreIfProperty>();
IgnoreIfProperties ignoreIfProperties = description.getAnnotation(IgnoreIfProperties.class);
if (null != ignoreIfProperties) {
ignoreIfPropertyList.addAll(Arrays.asList(ignoreIfProperties.value()));
}
// IgnoreIfProperty
IgnoreIfProperty ignoreIfProperty = description.getAnnotation(IgnoreIfProperty.class);
if (null != ignoreIfProperty) {
ignoreIfPropertyList.add(ignoreIfProperty);
}
// Process the ignoreIfProperties
for (IgnoreIfProperty ignoreIfProp : ignoreIfPropertyList) {
if (null != System.getProperty(ignoreIfProp.name())
&& System.getProperty(ignoreIfProp.name()).equals(ignoreIfProp.value())) {
return emptyStatement("IgnoreIfProperty condition met to skip: system property '" + ignoreIfProp.name()
+ "' is equal to '" + ignoreIfProp.value() + "'.");
}
}
// Filter using IgnoreTestsConfig
String fqdn = description.getClassName();
String methodName = description.getMethodName();
if (null != methodName) {
fqdn += "#" + methodName;
}
Match match = IgnoreTestsConfig.get().match(fqdn);
if (match.isIgnored()) {
return emptyStatement(match.getReason());
}
// filterCategory processing
List<String> filteredCategories;
if (System.getProperty(CATEGORY_PROPERTY) != null) {
filteredCategories = Arrays.asList(System.getProperty(CATEGORY_PROPERTY).split(","));
} else {
filteredCategories = defaultCategories;
}
Category testCategory = description.getAnnotation(Category.class);
Class[] testCategories = new Class[0];
if (testCategory != null) {
testCategories = testCategory.value();
}
/*
* Category annotation exists and the -DfilterCategory property is also set. If test category exists
* in -DfilterCategory list & -DrunOnlyFilteredCategories is NOT set, then the test is skipped If test
* category exists in -DfilterCategory & -DrunOnlyFilteredCategories is set, then the test is included
*/
if ((System.getProperty(INCLUDE_CATEGORY_PROPERTY) == null)) {
// Skip Tests from CATEGORY_PROPERTY
for (Class<?> category : testCategories) {
if (filteredCategories.contains(category.getSimpleName())) {
return emptyStatement("Excluding category: " + category.getSimpleName());
}
}
} else {
// Run only Tests from CATEGORY_PROPERTY
boolean categorySelected = false;
for (Class<?> category : testCategories) {
if ((filteredCategories.contains(category.getSimpleName()))) {
categorySelected = true;
}
}
if (!categorySelected) {
// No @Category from Test is in CATEGORY_PROPERTY (which should be executed), so skip
return emptyStatement("Test has no category in (" + INCLUDE_CATEGORY_PROPERTY + "=true): '" + filteredCategories + "'");
}
}
// No Filter excluded this test, so execute
return base;
}
private Statement emptyStatement(final String reason) {
return new Statement() {
@Override
public void evaluate() throws Throwable {
throw new AssumptionViolatedException("Test was ignored by FilterRule: " + reason);
}
};
}
public FilterRule addDefaultIgnoreCategories(Class... ignoredCategories) {
for (Class c : ignoredCategories) {
this.defaultCategories.add(c.getSimpleName());
}
return this;
}
}