/*
* Copyright (c) 2013-2014 EMC Corporation
* All Rights Reserved
*/
package com.emc.storageos.db.server.upgrade.impl.callback;
import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.emc.storageos.db.client.URIUtil;
import com.emc.storageos.db.client.model.DataObject.Flag;
import com.emc.storageos.db.client.model.ExportGroup;
import com.emc.storageos.db.client.model.Initiator;
import com.emc.storageos.db.client.model.NamedURI;
import com.emc.storageos.db.client.upgrade.BaseCustomMigrationCallback;
import com.emc.storageos.db.client.upgrade.callbacks.RpExportGroupInternalFlagMigration;
import com.emc.storageos.db.client.util.NullColumnValueGetter;
import com.emc.storageos.db.server.DbsvcTestBase;
import com.emc.storageos.db.server.upgrade.DbSimpleMigrationTestBase;
/**
* Test proper population of the new DataObject.internalFlags field
*
* Here's the basic execution flow for the test case:
* - setup() runs, bringing up a "pre-migration" version
* of the database, using the DbSchemaScannerInterceptor
* you supply to hide your new field or column family
* when generating the "before" schema.
* - Your implementation of prepareData() is called, allowing
* you to use the internal _dbClient reference to create any
* needed pre-migration test data.
* - The database is then shutdown and restarted (without using
* the interceptor this time), so the full "after" schema
* is available.
* - The dbsvc detects the diffs in the schema and executes the
* migration callbacks as part of the startup process.
* - Your implementation of verifyResults() is called to
* allow you to confirm that the migration of your prepared
* data went as expected.
*
*/
public class RpExportGroupInternalFlagMigrationTest extends DbSimpleMigrationTestBase {
private static final Logger log = LoggerFactory.getLogger(RpExportGroupInternalFlagMigrationTest.class);
// Used for migrations tests related to RP Export Groups.
private static List<URI> rpTestExportGroupURIs = new ArrayList<URI>();
// Used for migrations tests related to RP Initiators.
private static List<URI> rpTestInitiatorURIs = new ArrayList<URI>();
// Used for migrations tests related to RP Initiators and adding them to the Export Groups.
private static List<Initiator> rpTestInitiators = new ArrayList<Initiator>();
@BeforeClass
public static void setup() throws IOException {
customMigrationCallbacks.put("2.1", new ArrayList<BaseCustomMigrationCallback>() {
{
add(new RpExportGroupInternalFlagMigration());
}
});
DbsvcTestBase.setup();
}
@Override
protected String getSourceVersion() {
return "2.1";
}
@Override
protected String getTargetVersion() {
return "2.2";
}
@Override
protected void prepareData() throws Exception {
prepareInitiatorData();
prepareExportGroupData();
}
@Override
protected void verifyResults() throws Exception {
verifyInitiatorResults();
verifyExportGroupResults();
}
/**
* Prepares the data for volume tests.
*
* @throws Exception When an error occurs preparing the volume data.
*/
private void prepareInitiatorData() throws Exception {
String currentLabel = "RPInitiator1";
Initiator initiator = new Initiator();
initiator.setId(URIUtil.createId(Initiator.class));
initiator.setHostName(currentLabel);
initiator.setInitiatorPort("PORT");
initiator.setInitiatorNode("NODE");
initiator.setProtocol("FC");
initiator.setIsManualCreation(false);
_dbClient.createObject(initiator);
rpTestInitiatorURIs.add(initiator.getId());
rpTestInitiators.add(initiator);
currentLabel = "RPInitiator2";
initiator = new Initiator();
initiator.setId(URIUtil.createId(Initiator.class));
initiator.setHostName(currentLabel);
initiator.setInitiatorPort("PORT");
initiator.setInitiatorNode("NODE");
initiator.setProtocol("FC");
initiator.setIsManualCreation(false);
_dbClient.createObject(initiator);
rpTestInitiatorURIs.add(initiator.getId());
rpTestInitiators.add(initiator);
currentLabel = "RegularInitiator1";
initiator = new Initiator();
initiator.setId(URIUtil.createId(Initiator.class));
initiator.setHostName(NullColumnValueGetter.getNullStr());
initiator.setInitiatorPort("PORT");
initiator.setInitiatorNode("NODE");
initiator.setProtocol("FC");
initiator.setIsManualCreation(false);
_dbClient.createObject(initiator);
rpTestInitiatorURIs.add(initiator.getId());
rpTestInitiators.add(initiator);
currentLabel = "RegularInitiator2";
initiator = new Initiator();
initiator.setId(URIUtil.createId(Initiator.class));
initiator.setHostName(NullColumnValueGetter.getNullStr());
initiator.setInitiatorPort("PORT");
initiator.setInitiatorNode("NODE");
initiator.setProtocol("FC");
initiator.setIsManualCreation(false);
_dbClient.createObject(initiator);
rpTestInitiatorURIs.add(initiator.getId());
rpTestInitiators.add(initiator);
// Make sure our test data made it into the database as expected
List<URI> initiatorURIs = _dbClient.queryByType(Initiator.class, false);
int count = 0;
for (@SuppressWarnings("unused")
URI ignore : initiatorURIs) {
count++;
}
Assert.assertTrue("Expected 4 Initiators, found only " + count, count == 4);
}
/**
* Verifies the migration results for volumes.
*
* @throws Exception When an error occurs verifying the volume migration
* results.
*/
private void verifyInitiatorResults() throws Exception {
log.info("Verifying migration of Initiators for Flag.RECOVERPOINT.");
List<URI> initiatorURIs = _dbClient.queryByType(Initiator.class, false);
int count = 0;
Iterator<Initiator> initiatorsIter =
_dbClient.queryIterativeObjects(Initiator.class, initiatorURIs);
while (initiatorsIter.hasNext()) {
Initiator initiator = initiatorsIter.next();
count++;
if (initiator.getHostName().contains("RP")) {
Assert.assertTrue("RECOVERPOINT flag should be set on rp initiator",
initiator.checkInternalFlags(Flag.RECOVERPOINT));
} else if (initiator.getHostName().contains("null")) {
Assert.assertFalse("RECOVERPOINT flag should not be set on regular initiator",
initiator.checkInternalFlags(Flag.RECOVERPOINT));
}
}
Assert.assertTrue("Should still have 4 initiators after migration, not " + count, count == 4);
}
private void prepareExportGroupData() throws Exception {
String currentLabel = "RPExport1";
ExportGroup exportGroup = new ExportGroup();
exportGroup.setId(URIUtil.createId(ExportGroup.class));
exportGroup.addInternalFlags(Flag.INTERNAL_OBJECT, Flag.SUPPORTS_FORCE);
exportGroup.setLabel(currentLabel);
exportGroup.setProject(new NamedURI(URI.create("urn:" + currentLabel), currentLabel));
exportGroup.setGeneratedName(currentLabel);
exportGroup.addInitiator(rpTestInitiators.get(0));
_dbClient.createObject(exportGroup);
rpTestExportGroupURIs.add(exportGroup.getId());
currentLabel = "RPExport2";
exportGroup = new ExportGroup();
exportGroup.setId(URIUtil.createId(ExportGroup.class));
exportGroup.addInternalFlags(Flag.INTERNAL_OBJECT, Flag.SUPPORTS_FORCE);
exportGroup.setLabel(currentLabel);
exportGroup.setProject(new NamedURI(URI.create("urn:" + currentLabel), currentLabel));
exportGroup.setGeneratedName(currentLabel);
exportGroup.addInitiator(rpTestInitiators.get(1));
_dbClient.createObject(exportGroup);
rpTestExportGroupURIs.add(exportGroup.getId());
currentLabel = "RegularExport1";
exportGroup = new ExportGroup();
exportGroup.setId(URIUtil.createId(ExportGroup.class));
exportGroup.addInternalFlags(Flag.INTERNAL_OBJECT, Flag.SUPPORTS_FORCE);
exportGroup.setLabel(currentLabel);
exportGroup.setProject(new NamedURI(URI.create("urn:" + currentLabel), currentLabel));
exportGroup.setGeneratedName(currentLabel);
exportGroup.addInitiator(rpTestInitiators.get(2));
_dbClient.createObject(exportGroup);
rpTestExportGroupURIs.add(exportGroup.getId());
currentLabel = "RegularExport2";
exportGroup = new ExportGroup();
exportGroup.setId(URIUtil.createId(ExportGroup.class));
exportGroup.addInternalFlags(Flag.INTERNAL_OBJECT, Flag.SUPPORTS_FORCE);
exportGroup.setLabel(currentLabel);
exportGroup.setProject(new NamedURI(URI.create("urn:" + currentLabel), currentLabel));
exportGroup.setGeneratedName(currentLabel);
exportGroup.addInitiator(rpTestInitiators.get(3));
_dbClient.createObject(exportGroup);
rpTestExportGroupURIs.add(exportGroup.getId());
// Make sure our test data made it into the database as expected
List<URI> exportGroupURIs = _dbClient.queryByType(ExportGroup.class, false);
int count = 0;
for (@SuppressWarnings("unused")
URI ignore : exportGroupURIs) {
count++;
}
Assert.assertTrue("Expected 4 Export Groups, found only " + count, count == 4);
}
private void verifyExportGroupResults() throws Exception {
log.info("Verifying migration of ExportGroups for Flag.RECOVERPOINT.");
List<URI> exportGroupURIs = _dbClient.queryByType(ExportGroup.class, false);
int count = 0;
Iterator<ExportGroup> exportGroupsIter =
_dbClient.queryIterativeObjects(ExportGroup.class, exportGroupURIs);
while (exportGroupsIter.hasNext()) {
ExportGroup exportGroup = exportGroupsIter.next();
count++;
if (exportGroup.getLabel().contains("RP")) {
Assert.assertTrue("RECOVERPOINT flag should be set on rp export group",
exportGroup.checkInternalFlags(Flag.RECOVERPOINT));
} else if (exportGroup.getLabel().contains("Regular")) {
Assert.assertFalse("RECOVERPOINT flag should not be set on regular export group",
exportGroup.checkInternalFlags(Flag.RECOVERPOINT));
}
}
Assert.assertTrue("Should still have 4 initiators after migration, not " + count, count == 4);
}
}