/*
* 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.testcase;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.sql.Statement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.ensembl.healthcheck.DatabaseRegistry;
import org.ensembl.healthcheck.DatabaseRegistryEntry;
import org.ensembl.healthcheck.DatabaseType;
import org.ensembl.healthcheck.ReportManager;
import org.ensembl.healthcheck.Species;
import org.ensembl.healthcheck.util.Utils;
import org.ensembl.healthcheck.util.DBUtils;
/**
* Subclass of EnsTestCase for tests that apply to <em>multiple</em> databases. Such tests should subclass <em>this</em> class and
* implement the <code>run</code> method.
*/
public abstract class MultiDatabaseTestCase extends EnsTestCase {
/**
* This method should be overridden by subclasses.
*
* @param dbr
* The database registry containing all the matched databases.
* @return true if the test passed.
*/
public abstract boolean run(DatabaseRegistry dbr) throws SQLException;
// ---------------------------------------------------------------------
/**
* Check that the same piece of SQL gives the same result across several species.
*
* @param sql
* The SQL to check.
* @param dbr
* The registry containing the databases to check.
* @param types
* Only databases from the registry whose types are contined in this array will be used.
* @return true if SQL returns the same for all databases for each species in dbr.
*/
public boolean checkSQLAcrossSpecies(String sql, DatabaseRegistry dbr, DatabaseType[] types, boolean comparingSchema) {
boolean result = true;
// Use whole registry to access all databases, but restrict to species of interest
DatabaseRegistry mainDbr = DBUtils.getMainDatabaseRegistry();
for (Species species : dbr.getUniqueSpecies()) {
// filter by database type
DatabaseRegistryEntry[] filteredDBs = filterByType(mainDbr.getAll(species), types);
result &= checkSameSQLResult(sql, filteredDBs, comparingSchema);
} // foreach species
return result;
}
// ---------------------------------------------------------------------
/**
* Check that the contents of a table are the same across each of the species currently defined.
*
* @param table
* The table to check.
* @param dbr
* The registry containing the databases to check.
* @param types
* The DatabaseTypes to look at.
* @return true if the table is the same across all species.
*/
public boolean checkTableAcrossSpecies(String table, DatabaseRegistry dbr, DatabaseType[] types, String correct, String problem, String extraSQL) {
String sql = "SELECT COUNT(*) FROM " + table + " " + extraSQL;
boolean result = checkSQLAcrossSpecies(sql, dbr, types, false);
return result;
}
// -----------------------------------------------------------------
/**
* Filter an array of DatabaseRegistryEntries.
*
* @param The
* databases to check.
* @param types
* The types to look for.
* @return Those entries in databases that have a type that is in types.
*/
private DatabaseRegistryEntry[] filterByType(DatabaseRegistryEntry[] databases, DatabaseType[] types) {
List filtered = new ArrayList();
for (int i = 0; i < databases.length; i++) {
if (Utils.objectInArray(databases[i].getType(), types)) {
filtered.add(databases[i]);
}
}
return (DatabaseRegistryEntry[]) filtered.toArray(new DatabaseRegistryEntry[filtered.size()]);
}
}