Skip to content

Commit

Permalink
WELD-689 Add Performance Category
Browse files Browse the repository at this point in the history
Change contain
new category: Performance
new Suites:   NormalPerformanceSuite and IntegrationPerformanceSuite

Change Categories runner to support multiple Include/Exclude Categories pr Suite. Needed to support e.
@IncludeCategory({Integration.class, Performance.class})
@ExcludeCategory(Broken.class)
public class IntegrationPerformanceSuite

Contain locally changed/patched JUnit Categories runner.
Pushed upstream, see http://github.com/KentBeck/junit/issuesearch?state=open&q=category#issue/142
  • Loading branch information
aslakknutsen authored and pmuir committed Sep 21, 2010
1 parent e711374 commit bafa286
Show file tree
Hide file tree
Showing 9 changed files with 363 additions and 12 deletions.
241 changes: 241 additions & 0 deletions tests-arquillian/src/test/java/org/jboss/weld/tests/Categories.java
@@ -0,0 +1,241 @@
package org.jboss.weld.tests;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.junit.experimental.categories.Category;
import org.junit.runner.Description;
import org.junit.runner.manipulation.Filter;
import org.junit.runner.manipulation.NoTestsRemainException;
import org.junit.runners.Suite;
import org.junit.runners.model.InitializationError;
import org.junit.runners.model.RunnerBuilder;

/**
* From a given set of test classes, runs only the classes and methods that are
* annotated with either the category given with the @IncludeCategory
* annotation, or a subtype of that category.
*
* Note that, for now, annotating suites with {@code @Category} has no effect.
* Categories must be annotated on the direct method or class.
*
* Example:
*
* <pre>
* public interface FastTests {
* }
*
* public interface SlowTests {
* }
*
* public static class A {
* &#064;Test
* public void a() {
* fail();
* }
*
* &#064;Category(SlowTests.class)
* &#064;Test
* public void b() {
* }
* }
*
* &#064;Category( { SlowTests.class, FastTests.class })
* public static class B {
* &#064;Test
* public void c() {
*
* }
* }
*
* &#064;RunWith(Categories.class)
* &#064;IncludeCategory(SlowTests.class)
* &#064;SuiteClasses( { A.class, B.class })
* // Note that Categories is a kind of Suite
* public static class SlowTestSuite {
* }
* </pre>
*/
public class Categories extends Suite
{
@Retention(RetentionPolicy.RUNTIME)
public @interface IncludeCategory
{
public Class<?>[] value();
}

@Retention(RetentionPolicy.RUNTIME)
public @interface ExcludeCategory
{
public Class<?>[] value();
}

public static class CategoryFilter extends Filter
{
public static CategoryFilter include(Class<?>... categoryType)
{
return new CategoryFilter(categoryType, null);
}

public static CategoryFilter include(Class<?> categoryType)
{
return new CategoryFilter(new Class<?>[]{categoryType}, null);
}

private final Class<?>[] fIncluded;

private final Class<?>[] fExcluded;

public CategoryFilter(Class<?>[] includedCategory, Class<?>[] excludedCategory)
{
fIncluded = includedCategory;
fExcluded = excludedCategory;
}

@Override
public String describe()
{
return ((fIncluded == null || fIncluded.length == 1) ? "category " : "categories ") + join(", ", fIncluded);
}

private String join(String seperator, Class<?>... values)
{
if (values == null || values.length == 0)
{
return "";
}
StringBuilder sb = new StringBuilder(values[0].toString());
for (int i = 1; i < values.length; i++)
{
sb.append(seperator).append(values[i].toString());
}
return sb.toString();
}

@Override
public boolean shouldRun(Description description)
{
if (hasCorrectCategoryAnnotation(description))
{
return true;
}
for (Description each : description.getChildren())
{
if (shouldRun(each))
{
return true;
}
}
return false;
}

private boolean hasCorrectCategoryAnnotation(Description description)
{
List<Class<?>> categories = categories(description);
if (categories.isEmpty())
{
return fIncluded == null;
}

if (!methodContainsAnyExcludedCategories(categories, fExcluded))
{
return methodContainsAllIncludedCategories(categories, fIncluded);
}
return false;
}

private List<Class<?>> categories(Description description)
{
ArrayList<Class<?>> categories = new ArrayList<Class<?>>();
categories.addAll(Arrays.asList(directCategories(description)));
categories.addAll(Arrays.asList(directCategories(parentDescription(description))));
return categories;
}

private Description parentDescription(Description description)
{
// TODO: how heavy are we cringing?
return Description.createSuiteDescription(description.getTestClass());
}

private Class<?>[] directCategories(Description description)
{
Category annotation = description.getAnnotation(Category.class);
if (annotation == null)
{
return new Class<?>[0];
}
return annotation.value();
}

private boolean methodContainsAnyExcludedCategories(List<Class<?>> categories, Class<?>[] excludedCategories)
{
if (excludedCategories != null)
{
for (Class<?> eachExcluded : excludedCategories)
{
if (containsCategory(categories, eachExcluded))
{
return true;
}
}
}
return false;
}

private boolean methodContainsAllIncludedCategories(List<Class<?>> categories, Class<?>[] includedCategories)
{
if (includedCategories != null)
{
for (Class<?> eachIncluded : includedCategories)
{
if (!containsCategory(categories, eachIncluded))
{
return false;
}
}
}
return true;
}

private boolean containsCategory(List<Class<?>> categories, Class<?> categoryToMatch)
{
for (Class<?> each : categories)
{
if (categoryToMatch.isAssignableFrom(each))
{
return true;
}
}
return false;
}
}

public Categories(Class<?> klass, RunnerBuilder builder) throws InitializationError
{
super(klass, builder);
try
{
filter(new CategoryFilter(getIncludedCategory(klass), getExcludedCategory(klass)));
}
catch (NoTestsRemainException e)
{
throw new InitializationError(e);
}
}

private Class<?>[] getIncludedCategory(Class<?> klass)
{
IncludeCategory annotation = klass.getAnnotation(IncludeCategory.class);
return annotation == null ? null : annotation.value();
}

private Class<?>[] getExcludedCategory(Class<?> klass)
{
ExcludeCategory annotation = klass.getAnnotation(ExcludeCategory.class);
return annotation == null ? null : annotation.value();
}
}
@@ -0,0 +1,40 @@
/*
* JBoss, Home of Professional Open Source
* Copyright 2009, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed 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.jboss.weld.tests;

import org.jboss.weld.tests.Categories.ExcludeCategory;
import org.jboss.weld.tests.Categories.IncludeCategory;
import org.jboss.weld.tests.category.Broken;
import org.jboss.weld.tests.category.Integration;
import org.jboss.weld.tests.category.Performance;
import org.junit.runner.RunWith;
import org.junit.runners.Suite.SuiteClasses;

/**
* IntegrationSuite
*
* @author <a href="mailto:aslak@redhat.com">Aslak Knutsen</a>
* @version $Revision: $
*/
@RunWith(Categories.class)
@IncludeCategory({Integration.class, Performance.class})
@ExcludeCategory(Broken.class)
@SuiteClasses(AllTests.class)
public class IntegrationPerformanceSuite
{

}
Expand Up @@ -16,9 +16,9 @@
*/
package org.jboss.weld.tests;

import org.jboss.weld.tests.Categories.ExcludeCategory;
import org.jboss.weld.tests.category.Broken;
import org.junit.experimental.categories.Categories;
import org.junit.experimental.categories.Categories.ExcludeCategory;
import org.jboss.weld.tests.category.Performance;
import org.junit.runner.RunWith;
import org.junit.runners.Suite.SuiteClasses;

Expand All @@ -29,8 +29,7 @@
* @version $Revision: $
*/
@RunWith(Categories.class)
//@IncludeCategory(Integration.class) // this will exclude un marked tests as well.
@ExcludeCategory(Broken.class)
@ExcludeCategory({Broken.class, Performance.class})
@SuiteClasses(AllTests.class)
public class IntegrationSuite
{
Expand Down
@@ -0,0 +1,39 @@
/*
* JBoss, Home of Professional Open Source
* Copyright 2009, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed 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.jboss.weld.tests;

import org.jboss.weld.tests.Categories.ExcludeCategory;
import org.jboss.weld.tests.Categories.IncludeCategory;
import org.jboss.weld.tests.category.Broken;
import org.jboss.weld.tests.category.Integration;
import org.jboss.weld.tests.category.Performance;
import org.junit.runner.RunWith;
import org.junit.runners.Suite.SuiteClasses;

/**
* IntegrationSuite
*
* @author <a href="mailto:aslak@redhat.com">Aslak Knutsen</a>
* @version $Revision: $
*/
@RunWith(Categories.class)
@IncludeCategory(Performance.class)
@ExcludeCategory({Broken.class, Integration.class})
@SuiteClasses(AllTests.class)
public class NormalPerformanceSuite
{
}
Expand Up @@ -16,9 +16,9 @@
*/
package org.jboss.weld.tests;

import org.jboss.weld.tests.category.ExcludeFromNormalSuite;
import org.junit.experimental.categories.Categories;
import org.junit.experimental.categories.Categories.ExcludeCategory;
import org.jboss.weld.tests.Categories.ExcludeCategory;
import org.jboss.weld.tests.category.Broken;
import org.jboss.weld.tests.category.Slow;
import org.junit.runner.RunWith;
import org.junit.runners.Suite.SuiteClasses;

Expand All @@ -29,7 +29,7 @@
* @version $Revision: $
*/
@RunWith(Categories.class)
@ExcludeCategory(ExcludeFromNormalSuite.class)
@ExcludeCategory({Broken.class, Slow.class})
@SuiteClasses(AllTests.class)
public class NormalSuite
{
Expand Down
Expand Up @@ -23,7 +23,7 @@
* @author <a href="mailto:aslak@redhat.com">Aslak Knutsen</a>
* @version $Revision: $
*/
public interface Broken extends ExcludeFromNormalSuite
public interface Broken
{

}
Expand Up @@ -22,7 +22,7 @@
* @author <a href="mailto:aslak@redhat.com">Aslak Knutsen</a>
* @version $Revision: $
*/
public interface Integration extends ExcludeFromNormalSuite
public interface Integration extends Slow
{

}

0 comments on commit bafa286

Please sign in to comment.