/* * Copyright [1999-2015] Wellcome Trust Sanger Institute and the EMBL-European Bioinformatics Institute * Copyright [2016-2017] EMBL-European Bioinformatics Institute * * 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.ensembl.healthcheck; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.logging.Logger; import org.ensembl.healthcheck.configuration.ConfigureTestGroups; import org.ensembl.healthcheck.testcase.EnsTestCase; import org.ensembl.healthcheck.testcase.MultiDatabaseTestCase; import org.ensembl.healthcheck.testcase.OrderedDatabaseTestCase; import org.ensembl.healthcheck.testcase.SingleDatabaseTestCase; import org.ensembl.healthcheck.util.CollectionUtils; /** * A test registry that returns tests based on a configuration file instead of * letting the tests register themselves. * */ public class ConfigurationBasedTestRegistry implements TestRegistry { /** The logger to use for this class */ protected static Logger logger = Logger.getLogger("HealthCheckLogger"); // // Begin getters and setters // private GroupOfTests getUserDefinedGroupOfTests() { return userDefinedGroupOfTests; } private void setUserDefinedGroupOfTests(GroupOfTests userDefinedGroupOfTests) { this.userDefinedGroupOfTests = userDefinedGroupOfTests; } private List<SingleDatabaseTestCase> getSingleDatabaseTestCaseList() { return singleDatabaseTestCaseList; } private void setSingleDatabaseTestCaseList( List<SingleDatabaseTestCase> singleDatabaseTestCaseList) { this.singleDatabaseTestCaseList = singleDatabaseTestCaseList; } private List<MultiDatabaseTestCase> getMultiDatabaseTestCaseList() { return multiDatabaseTestCaseList; } private void setMultiDatabaseTestCaseList( List<MultiDatabaseTestCase> multiDatabaseTestCaseList) { this.multiDatabaseTestCaseList = multiDatabaseTestCaseList; } private List<OrderedDatabaseTestCase> getOrderedDatabaseTestCaseList() { return orderedDatabaseTestCaseList; } private void setOrderedDatabaseTestCaseList( List<OrderedDatabaseTestCase> orderedDatabaseTestCaseList) { this.orderedDatabaseTestCaseList = orderedDatabaseTestCaseList; } private List<EnsTestCase> getDatabaseTestCaseList() { return databaseTestCaseList; } private void setDatabaseTestCaseList(List<EnsTestCase> databaseTestCaseList) { this.databaseTestCaseList = databaseTestCaseList; } // // End getters and setters // private GroupOfTests userDefinedGroupOfTests; private List<EnsTestCase> databaseTestCaseList; private List<SingleDatabaseTestCase> singleDatabaseTestCaseList; private List<MultiDatabaseTestCase> multiDatabaseTestCaseList; private List<OrderedDatabaseTestCase> orderedDatabaseTestCaseList; /** * @param params ConfigurationUserParameters object * */ public ConfigurationBasedTestRegistry(ConfigureTestGroups params) throws UnknownTestTypeException, InstantiationException, IllegalAccessException, ClassNotFoundException { initGroupSet(params); this.setDatabaseTestCaseList(new ArrayList<EnsTestCase>(userDefinedGroupOfTests.getTests())); initDatabaseLists(); } protected boolean isEmptyList(List<String> l) { return l.size()==1 && l.get(0).equals(""); } /** * The user can specify * * - groups of tests which should be run * - groups of tests which should not be run * - single tests which should be run * - single tests which should not be run * * This method initialises the "userDefinedGroupOfTests" which has the * tests that satisfy theses conditions. * */ private void initGroupSet(ConfigureTestGroups params) throws InstantiationException, IllegalAccessException, ClassNotFoundException { // TODO: Must make this configurable String packageWithHealthchecks = "org.ensembl.healthcheck.testcase"; String packageWithTestgroups = "org.ensembl.healthcheck.testgroup"; GroupOfTests userDefinedGroupOfTests = new GroupOfTests(); TestInstantiator testInstantiator = new TestInstantiator( packageWithHealthchecks, packageWithTestgroups ); // The following tests do // // if (params.isXXX() && params.getXXX().size()>0) { // ... // } // // Which seems to be a redundant test, but it is not. A parameter // can be set like this: // // test = // // Which would make params.isTest() to be true, but the following // attempt to load the class "" fail. if (params.isGroups() && !isEmptyList(params.getGroups())) { for (String groupName : params.getGroups()) { //GroupOfTests groupOfTests = (GroupOfTests) testInstantiator.forName(groupName).newInstance(); GroupOfTests groupOfTests = testInstantiator.instanceByName(groupName, GroupOfTests.class); userDefinedGroupOfTests.addTest(groupOfTests); } } if (params.isTests() && !isEmptyList(params.getTests())) { for (String testName : params.getTests()) { Class<EnsTestCase> singleTestClass = (Class<EnsTestCase>) testInstantiator.forName(testName); userDefinedGroupOfTests.addTest(singleTestClass); } } if (params.isExcludeGroups() && !isEmptyList(params.getExcludeGroups())) { for (String groupName : params.getExcludeGroups()) { //GroupOfTests groupOfTests = (GroupOfTests) testInstantiator.forName(groupName).newInstance(); GroupOfTests groupOfTests = testInstantiator.instanceByName(groupName, GroupOfTests.class); userDefinedGroupOfTests.removeTest(groupOfTests); } } if (params.isExcludeTests() && !isEmptyList(params.getExcludeTests())) { for (String testName : params.getExcludeTests()) { Class<EnsTestCase> singleTestClass = (Class<EnsTestCase>) testInstantiator.forName(testName); userDefinedGroupOfTests.removeTest(singleTestClass); } } setUserDefinedGroupOfTests(userDefinedGroupOfTests); } /** * The tests that should be run are divided here into three lists: * * - SingleDatabaseTestCase * - MultiDatabaseTestCase and * - OrderedDatabaseTestCase * * which is how they will be retrieved by the users of this class. * */ private void initDatabaseLists() throws UnknownTestTypeException { List<EnsTestCase> listOfTests = this.getDatabaseTestCaseList(); List<SingleDatabaseTestCase> single = new ArrayList<SingleDatabaseTestCase>(); List<MultiDatabaseTestCase> multi = new ArrayList<MultiDatabaseTestCase>(); List<OrderedDatabaseTestCase> ordered = new ArrayList<OrderedDatabaseTestCase>(); for (EnsTestCase currentTest : listOfTests) { boolean testWasAddedToAList = false; if (currentTest instanceof SingleDatabaseTestCase) { single.add((SingleDatabaseTestCase) currentTest); testWasAddedToAList = true; } if (currentTest instanceof MultiDatabaseTestCase) { multi.add((MultiDatabaseTestCase) currentTest); testWasAddedToAList = true; } if (currentTest instanceof OrderedDatabaseTestCase) { ordered.add((OrderedDatabaseTestCase) currentTest); testWasAddedToAList = true; } if (!testWasAddedToAList) { throw new UnknownTestTypeException("Could not add this test to a list: " + currentTest); } } this.setSingleDatabaseTestCaseList(single); this.setMultiDatabaseTestCaseList(multi); this.setOrderedDatabaseTestCaseList(ordered); } public String toString() { StringBuffer result = new StringBuffer(); result.append( "DatabaseTestCaseList: \n" + listToString(this.getDatabaseTestCaseList()) + "\n" ); result.append( "Single database testcases: \n" + listToString(this.getAllSingle(null, null)) + "\n" ); result.append( "Multi database testcases: \n" + listToString(this.getAllMulti(null)) + "\n" ); result.append( "Ordered database testcases: \n" + listToString(this.getAllOrdered(null)) + "\n" ); return result.toString(); } protected String listToString(List<? extends EnsTestCase> l) { StringBuffer s = new StringBuffer(); if (l.size()==0) return " - none - "; for (EnsTestCase e : l) { s.append(" - " + e.getClass().getName() + "\n"); } return s.toString(); } public List<EnsTestCase> getAll() { return new ArrayList<EnsTestCase>(this.getUserDefinedGroupOfTests().getTests()); } public List<MultiDatabaseTestCase> getAllMulti(List<String> groupsToRun) { return new ArrayList<MultiDatabaseTestCase>(this.getMultiDatabaseTestCaseList()); } public List<OrderedDatabaseTestCase> getAllOrdered(List<String> groups) { return new ArrayList<OrderedDatabaseTestCase>(this.getOrderedDatabaseTestCaseList()); } public List<SingleDatabaseTestCase> getAllSingle(List<String> groupsToRun, DatabaseType type) { if(groupsToRun!=null && groupsToRun.size()>0) { throw new UnsupportedOperationException("Group selection not supported for "+this.getClass().getName()+".getAllSingle()"); } return getSingle(type); } private Map<DatabaseType,List<SingleDatabaseTestCase>> singleTestsByType; protected Map<DatabaseType,List<SingleDatabaseTestCase>> getSingleTestsByType() { if(singleTestsByType==null) { singleTestsByType = CollectionUtils.createHashMap(); for(SingleDatabaseTestCase test: this.getSingleDatabaseTestCaseList()) { for(DatabaseType type: test.getAppliesToTypes()) { List<SingleDatabaseTestCase> tests = singleTestsByType.get(type); if(tests==null) { tests = CollectionUtils.createArrayList(); singleTestsByType.put(type,tests); } tests.add(test); } } } return singleTestsByType; } public List<SingleDatabaseTestCase> getSingle(DatabaseType type) { if(type==null) { return this.getSingleDatabaseTestCaseList(); } else { List<SingleDatabaseTestCase> ts = getSingleTestsByType().get(type); if(ts==null) { logger.warning("Couldn't find any tests for database type "+type.getName()); ts = CollectionUtils.createArrayList(); } return ts; } } public String[] getGroups(DatabaseType type) { throw new UnsupportedOperationException(this.getClass().getName()+".getGroups() not yet implemented"); } public EnsTestCase[] getTestsInGroup(String string, DatabaseType type) { throw new UnsupportedOperationException(this.getClass().getName()+".getTestsInGroup() not yet implemented"); } public DatabaseType[] getTypes() { throw new UnsupportedOperationException(this.getClass().getName()+".getTypes() not yet implemented"); } }