/** * Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.util.test; import static org.testng.AssertJUnit.assertEquals; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.lang.StringUtils; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.opengamma.util.ArgumentChecker; import com.opengamma.util.db.script.DbSchemaGroupMetadata; import com.opengamma.util.db.script.DbScriptUtils; import com.opengamma.util.db.tool.DbTool; import com.opengamma.util.db.tool.DbTool.TableCreationCallback; import com.opengamma.util.time.DateUtils; import com.opengamma.util.tuple.Triple; /** * Tests the creation + upgrade sequence results in the same structure as a pure create. */ public abstract class AbstractDbUpgradeTest implements TableCreationCallback { private static final Map<String, Map<String, String>> s_targetSchema = Maps.newHashMap(); private final List<Triple<String, String, String>> _comparisons = Lists.newLinkedList(); private final String _schemaGroupName; private final String _databaseType; private final int _targetVersion; private final int _createVersion; private volatile DbTool _dbTool; static { // initialize the clock DateUtils.initTimeZone(); } /** * Creates an instance. * * @param databaseType the database type, not null * @param schemaGroupName the schema group name, not null * @param targetVersion the target version * @param createVersion the create version */ protected AbstractDbUpgradeTest(String databaseType, String schemaGroupName, final int targetVersion, final int createVersion) { ArgumentChecker.notNull(schemaGroupName, "schameGroupName"); ArgumentChecker.notNull(databaseType, "databaseType"); _schemaGroupName = schemaGroupName; _databaseType = databaseType; _targetVersion = targetVersion; _createVersion = createVersion; } //------------------------------------------------------------------------- @BeforeMethod(alwaysRun = true) public void setUp() throws Exception { DbTool dbTool = getDbTool(); dbTool.setTargetVersion(_targetVersion); dbTool.setCreateVersion(_createVersion); dbTool.dropTestSchema(); dbTool.createTestSchema(); dbTool.createTables(DbScriptUtils.getDbSchemaGroupMetadata(_schemaGroupName), dbTool.getTestCatalog(), dbTool.getTestSchema(), _targetVersion, _createVersion, this); dbTool.clearTestTables(); } @AfterMethod(alwaysRun = true) public void tearDown() { // need to clear version cache from here // this is messy but necessary AbstractDbTest.s_databaseTypeVersion.clear(); } //------------------------------------------------------------------------- protected DbTool getDbTool() { return initDbTool(); } /** * Initializes the DBTool outside the constructor. * This works better with TestNG and Maven, where the constructor is called * even if the test is never run. */ private DbTool initDbTool() { DbTool dbTool = _dbTool; if (dbTool == null) { synchronized (this) { dbTool = _dbTool; if (dbTool == null) { _dbTool = dbTool = DbTest.createDbTool(_databaseType, null); // CSIGNORE } } } return dbTool; } //------------------------------------------------------------------------- protected Map<String, String> getVersionSchemas() { Map<String, String> versionSchema = s_targetSchema.get(_databaseType); if (versionSchema == null) { versionSchema = new HashMap<>(); s_targetSchema.put(_databaseType, versionSchema); } return versionSchema; } //------------------------------------------------------------------------- @Test(groups = TestGroup.UNIT_DB) public void testDatabaseUpgrade() { for (Triple<String, String, String> comparison : _comparisons) { /* * System.out.println(comparison.getFirst() + " expected:"); * System.out.println(comparison.getSecond()); * System.out.println(comparison.getFirst() + " found:"); * System.out.println(comparison.getThird()); */ int diff = StringUtils.indexOfDifference(comparison.getSecond(), comparison.getThird()); if (diff >= 0) { System.err.println("Difference at " + diff + "in " + _databaseType + "/" + comparison.getFirst()); System.err.println("Upgraded --->..." + StringUtils.substring(comparison.getSecond(), diff - 200, diff) + "<-!!!->" + StringUtils.substring(comparison.getSecond(), diff, diff + 200) + "..."); System.err.println(" Created --->..." + StringUtils.substring(comparison.getThird(), diff - 200, diff) + "<-!!!->" + StringUtils.substring(comparison.getThird(), diff, diff + 200) + "..."); } assertEquals(_databaseType + ": " + comparison.getFirst(), comparison.getSecond(), comparison.getThird()); } } @Override public void tablesCreatedOrUpgraded(final int version, final DbSchemaGroupMetadata schemaGroupMetadata) { final Map<String, String> versionSchemas = getVersionSchemas(); String key = schemaGroupMetadata.getSchemaGroupName() + "_" + version; if (versionSchemas.containsKey(key)) { // if we've already done the full schema, then we want to test that this upgrade has given us the same (but defer the comparison) _comparisons.add(Triple.of(key, versionSchemas.get(key), _dbTool.describeDatabase(schemaGroupMetadata.getSchemaGroupName()))); } else { // tests are run with most recent full schema first, so we can store that as a reference versionSchemas.put(key, _dbTool.describeDatabase(schemaGroupMetadata.getSchemaGroupName())); } } @Override public String toString() { return _databaseType + "/" + _schemaGroupName + ":" + _createVersion + " >>> " + _targetVersion; } }