/* * Copyright 2016 Crown Copyright * * 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 uk.gov.gchq.gaffer.integration; import org.junit.runner.RunWith; import org.junit.runners.Suite; import org.junit.runners.model.InitializationError; import org.junit.runners.model.RunnerBuilder; import org.reflections.Reflections; import uk.gov.gchq.gaffer.integration.AbstractStoreITs.StoreTestSuite; import uk.gov.gchq.gaffer.store.StoreProperties; import uk.gov.gchq.gaffer.store.schema.Schema; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Set; import java.util.function.Consumer; /** * Runs the full suite of gaffer store integration tests. To run the tests against * a specific store, simply extend this class - you don't need to annotate * your class. */ @RunWith(StoreTestSuite.class) public abstract class AbstractStoreITs { private final StoreProperties storeProperties; private final Schema schema; private final Collection<Class<? extends AbstractStoreIT>> extraTests; private final Map<Class<? extends AbstractStoreIT>, String> skipTests = new HashMap<>(); private Class<? extends AbstractStoreIT> singleTestClass; private String singleTestMethod; public AbstractStoreITs(final StoreProperties storeProperties, final Schema schema, final Collection<Class<? extends AbstractStoreIT>> extraTests) { this.schema = schema; this.storeProperties = storeProperties; this.extraTests = extraTests; } public AbstractStoreITs(final StoreProperties storeProperties, final Collection<Class<? extends AbstractStoreIT>> extraTests) { this(storeProperties, new Schema(), extraTests); } public AbstractStoreITs(final StoreProperties storeProperties, final Schema schema) { this(storeProperties, schema, new ArrayList<Class<? extends AbstractStoreIT>>()); } public AbstractStoreITs(final StoreProperties storeProperties) { this(storeProperties, new Schema()); } public void singleTest(final Class<? extends AbstractStoreIT> testClass) { singleTest(testClass, null); } public void singleTest(final Class<? extends AbstractStoreIT> testClass, final String testMethod) { this.singleTestClass = testClass; this.singleTestMethod = testMethod; } public Schema getStoreSchema() { return schema; } public StoreProperties getStoreProperties() { return storeProperties; } public void addExtraTest(final Class<? extends AbstractStoreIT> extraTest) { extraTests.add(extraTest); } public Collection<? extends Class> getExtraTests() { return extraTests; } public Map<? extends Class<? extends AbstractStoreIT>, String> getSkipTests() { return skipTests; } protected void skipTest(final Class<? extends AbstractStoreIT> testClass, final String justification) { skipTests.put(testClass, justification); } public static class StoreTestSuite extends Suite { private Consumer<String> cleanUpFunction; public StoreTestSuite(final Class<?> clazz, final RunnerBuilder builder) throws InitializationError, IllegalAccessException, InstantiationException { super(builder, clazz, getTestClasses(clazz)); final AbstractStoreITs runner = clazz.asSubclass(AbstractStoreITs.class).newInstance(); Schema storeSchema = runner.getStoreSchema(); if (null == storeSchema) { storeSchema = new Schema(); } AbstractStoreIT.setStoreSchema(storeSchema); AbstractStoreIT.setStoreProperties(runner.getStoreProperties()); AbstractStoreIT.setSkipTests(runner.getSkipTests()); AbstractStoreIT.setSingleTestMethod(runner.singleTestMethod); } private static Class[] getTestClasses(final Class<?> clazz) throws IllegalAccessException, InstantiationException { final AbstractStoreITs runner = clazz.asSubclass(AbstractStoreITs.class).newInstance(); if (null == runner.singleTestClass) { final Set<Class<? extends AbstractStoreIT>> classes = new Reflections(AbstractStoreIT.class.getPackage().getName()).getSubTypesOf(AbstractStoreIT.class); keepPublicConcreteClasses(classes); classes.addAll((Collection<? extends Class<? extends AbstractStoreIT>>) runner.getExtraTests()); return classes.toArray(new Class[classes.size()]); } return new Class[]{runner.singleTestClass}; } private static void keepPublicConcreteClasses(final Set<Class<? extends AbstractStoreIT>> classes) { if (null != classes) { final Iterator<Class<? extends AbstractStoreIT>> itr = classes.iterator(); for (Class clazz = null; itr.hasNext(); clazz = itr.next()) { if (null != clazz) { final int modifiers = clazz.getModifiers(); if (Modifier.isAbstract(modifiers) || Modifier.isInterface(modifiers) || Modifier.isPrivate(modifiers) || Modifier.isProtected(modifiers)) { itr.remove(); } } } } } } }