/* * 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; } }