/* * 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.compara; import java.sql.Connection; import java.util.HashSet; import java.util.Set; 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.Team; import org.ensembl.healthcheck.testcase.SingleDatabaseTestCase; import org.ensembl.healthcheck.util.DBUtils; import org.ensembl.healthcheck.util.CollectionUtils; /** * An EnsEMBL Healthcheck test case that checks that the sizes of the * Compara tables are similar to the previous release */ public class CheckTableSizes extends SingleDatabaseTestCase { public CheckTableSizes() { setDescription("Checks the size of the Compara tables"); setTeamResponsible(Team.COMPARA); } /** * Define what tables are to be checked. */ private Set<String> getTablesToCheck(final DatabaseRegistryEntry dbre) { // get the full list of tables Set<String> tables = CollectionUtils.createLinkedHashSet(DBUtils.getTableNames(dbre.getConnection())); // remove views since we don't care if they're empty Set<String> views = CollectionUtils.createLinkedHashSet(DBUtils.getViews(dbre.getConnection()).toArray(new String[]{})); tables.removeAll(views); // Tables we don't want to check tables.remove( "meta" ); return tables; } /** * Kick-off a comparison between the current database and all the * previous ones */ public boolean run(final DatabaseRegistryEntry dbre) { // Get compara DB connection DatabaseRegistryEntry[] allSecondaryComparaDBs = DBUtils.getSecondaryDatabaseRegistry("compara").getAll(DatabaseType.COMPARA); if (allSecondaryComparaDBs.length == 0) { ReportManager.problem( this, dbre.getConnection(), "Cannot find the compara database in the secondary server. This check expects to find a previous version of the compara database for checking that all the *named* species_sets are still present in the current database."); return false; } // For each compara connection... boolean result = true; for (DatabaseRegistryEntry this_other_Compara_dbre : allSecondaryComparaDBs) { // Check vs previous compara DB. result &= compareTableSizes(dbre, this_other_Compara_dbre); } return result; } // run /** * Reports the tables that are now missing or empty, the new * tables, and the tables with a signficantly different size. * NB: Thresholds are -5% and +10% */ public boolean compareTableSizes(final DatabaseRegistryEntry primaryComparaDbre, final DatabaseRegistryEntry secondaryComparaDbre) { Set<String> tables1 = getTablesToCheck(primaryComparaDbre); Set<String> tables2 = getTablesToCheck(secondaryComparaDbre); Connection con1 = primaryComparaDbre.getConnection(); Connection con2 = secondaryComparaDbre.getConnection(); boolean result = true; for (String table : tables2) { int count2 = DBUtils.countRowsInTable(con2, table); if (tables1.contains(table)) { int count1 = DBUtils.countRowsInTable(con1, table); if (count1 == 0 && count2 > 0) { result = false; ReportManager.problem( this, con1, String.format("Table %s is now empty but had %,d rows in %s.", table, count2, DBUtils.getShortDatabaseName(con2))); } else if (count1 > 0 && count2 == 0) { result = false; ReportManager.problem( this, con1, String.format("Table %s has %,d rows but was empty in %s.", table, count1, DBUtils.getShortDatabaseName(con2))); } else if (count1 == count2 && count1 > 0) { result = false; ReportManager.problem( this, con1, String.format("Table %s has exactly the same number of rows (%,d) as in %s. Is it expected ?", table, count2, DBUtils.getShortDatabaseName(con2))); } else if (count1 < (int) (.95 * count2) || count2 > (int) (1.10 * count2)) { result = false; ReportManager.problem( this, con1, String.format("Table %s had %,d rows in %s, but now has %,d rows (%+,d = %+.2f %%)", table, count2, DBUtils.getShortDatabaseName(con2), count1, count1-count2, (100.*(count1-count2))/count2)); } } else { result = false; ReportManager.problem( this, con1, String.format("Table %s was in %s (and had %,d rows) but is now missing.", table, DBUtils.getShortDatabaseName(con2), count2)); } } for (String table : tables1) { if (! tables2.contains(table)) { result = false; int count1 = DBUtils.countRowsInTable(con1, table); if (count1 == 0) { ReportManager.problem( this, con1, String.format("Table %s is new (comparing to %s) but empty.", table, DBUtils.getShortDatabaseName(con2))); } else { ReportManager.problem( this, con1, String.format("Table %s is new (comparing to %s) and has %,d rows.", table, DBUtils.getShortDatabaseName(con2), count1)); } } } return result; } } // CheckEmptyTables