/*
* Copyright (c) 2013 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.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
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.Host;
import com.emc.storageos.db.client.model.NamedURI;
import com.emc.storageos.db.client.model.Project;
import com.emc.storageos.db.client.model.ScopedLabel;
import com.emc.storageos.db.client.model.ScopedLabelSet;
import com.emc.storageos.db.client.model.TenantOrg;
import com.emc.storageos.db.client.model.Volume;
import com.emc.storageos.db.client.upgrade.BaseCustomMigrationCallback;
import com.emc.storageos.db.client.upgrade.callbacks.VolumeBootVolumeMigration;
import com.emc.storageos.db.server.DbsvcTestBase;
import com.emc.storageos.db.server.upgrade.DbSimpleMigrationTestBase;
/**
* Test upgrading a volume object to have a boot volume tag.
* - Volume that does not have tags at all yet
* - Volume that has other tags
* - Volume that isn't a boot volume in the first place
* - Volume not associated with a host in the first place
*/
public class VolumeBootVolumeMigrationTest extends DbSimpleMigrationTestBase {
private static final Logger log = LoggerFactory.getLogger(VolumeBootVolumeMigrationTest.class);
// Used for migrations tests related to boot volume
private static volatile HashMap<URI, URI> volumeToHostIds = new HashMap<URI, URI>();
@BeforeClass
public static void setup() throws IOException {
customMigrationCallbacks.put("1.1", new ArrayList<BaseCustomMigrationCallback>() {
{
add(new VolumeBootVolumeMigration());
}
});
DbsvcTestBase.setup();
}
@Override
protected void prepareData() throws Exception {
prepareVolumeData();
}
@Override
protected void verifyResults() throws Exception {
verifyVolumeResults();
}
/**
* Prepares the data for RP volume tests.
*
* @throws Exception When an error occurs preparing the RP volume data.
*/
private void prepareVolumeData() throws Exception {
log.info("Preparing Volumes for VolumeAccessStateLinkStatusMigration");
TenantOrg tenantOrg = new TenantOrg();
URI tenantOrgURI = URIUtil.createId(TenantOrg.class);
tenantOrg.setId(tenantOrgURI);
_dbClient.createObject(tenantOrg);
Project proj = new Project();
URI projectURI = URIUtil.createId(Project.class);
String projectLabel = "project";
proj.setId(projectURI);
proj.setLabel(projectLabel);
proj.setTenantOrg(new NamedURI(tenantOrgURI, projectLabel));
_dbClient.createObject(proj);
// Create a boot volume for a host with no tags
Volume vol1 = new Volume();
URI vol1URI = URIUtil.createId(Volume.class);
vol1.setId(vol1URI);
vol1.setLabel("VOL1-ABOOTVOLUME");
vol1.setTenant(new NamedURI(tenantOrgURI, "provider"));
_dbClient.createObject(vol1);
// Create a host object with a boot volume
Host host1 = new Host();
URI host1URI = URIUtil.createId(Host.class);
host1.setId(host1URI);
host1.setHostName("Host1WithBootVol");
host1.setBootVolumeId(vol1URI);
volumeToHostIds.put(vol1URI, host1URI);
_dbClient.createObject(host1);
// Create a boot volume for a host with existing tags
Volume vol2 = new Volume();
URI vol2URI = URIUtil.createId(Volume.class);
vol2.setId(vol2URI);
vol2.setLabel("VOL2-ABOOTVOLUME");
vol2.setTenant(new NamedURI(tenantOrgURI, "provider"));
ScopedLabel label = new ScopedLabel();
label.setScope(tenantOrg.getId().toASCIIString());
label.setLabel("vipr:someothertag="+vol2URI.toASCIIString());
ScopedLabelSet labelSet = new ScopedLabelSet();
labelSet.add(label);
vol2.setTag(labelSet);
_dbClient.createObject(vol2);
// Create a host object with a boot volume
Host host2 = new Host();
URI host2URI = URIUtil.createId(Host.class);
host2.setId(host2URI);
host2.setHostName("Host2WithBootVol");
host2.setBootVolumeId(vol2URI);
volumeToHostIds.put(vol2URI, host2URI);
_dbClient.createObject(host2);
// Create a volume with no host association
Volume vol3 = new Volume();
URI vol3URI = URIUtil.createId(Volume.class);
vol3.setId(vol3URI);
vol3.setLabel("VOL3-NOTABOOTVOLUME");
vol3.setTenant(new NamedURI(tenantOrgURI, "provider"));
volumeToHostIds.put(vol3URI, null);
_dbClient.createObject(vol3);
}
/**
* Verifies the results for migrating volumes
*
* @throws Exception When an error occurs verifying the Volume
* migration results.
*/
private void verifyVolumeResults() throws Exception {
log.info("Verifying updated Volume boot volume tag for VolumeBootVolumeMigration handler");
for (Entry<URI, URI> volumeToHostId : volumeToHostIds.entrySet()) {
Volume volume = _dbClient.queryObject(Volume.class, volumeToHostId.getKey());
if (volume.getLabel().equals("VOL1-ABOOTVOLUME")) {
// Make sure volume1 has the new tag
Assert.assertNotNull("Tag Set of volume 1 must be non-null", volume.getTag());
Assert.assertTrue("Tag set of volume 1 must be non-empty", !volume.getTag().isEmpty());
ScopedLabel sl = volume.getTag().iterator().next();
Assert.assertEquals(sl.getScope(), volume.getTenant().getURI().toASCIIString());
Assert.assertEquals(sl.getLabel(), "vipr:bootVolume=" + volumeToHostId.getValue().toASCIIString());
}
if (volume.getLabel().equals("VOL2-ABOOTVOLUME")) {
// Make sure volume1 has the new tag
Assert.assertNotNull("Tag Set of volume 1 must be non-null", volume.getTag());
Assert.assertTrue("Tag set of volume 2 must be non-empty", !volume.getTag().isEmpty());
boolean found = false;
Iterator<ScopedLabel> slIter = volume.getTag().iterator();
while (slIter.hasNext()) {
ScopedLabel sl = slIter.next();
if (sl.getScope().equals(volume.getTenant().getURI().toASCIIString()) &&
(sl.getLabel().equals("vipr:bootVolume=" + volumeToHostId.getValue().toASCIIString()))) {
found = true;
}
}
Assert.assertTrue("Tag not found in tag set", found);
}
if (volume.getLabel().equals("VOL3-NOTABOOTVOLUME")) {
// Make sure volume1 has no tags
Assert.assertNull("Tag Set of volume 3 must be null", volume.getTag());
}
}
}
}