/* * Copyright (c) 2017 EMC Corporation * All Rights Reserved */ package com.emc.storageos.db.server.upgrade.impl.callback; import java.net.URI; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.apache.commons.collections.SetUtils; import org.apache.commons.lang.math.RandomUtils; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import com.emc.storageos.db.client.URIUtil; import com.emc.storageos.db.client.model.BlockSnapshot; import com.emc.storageos.db.client.model.Cluster; import com.emc.storageos.db.client.model.DataObject; import com.emc.storageos.db.client.model.ExportGroup; import com.emc.storageos.db.client.model.ExportMask; import com.emc.storageos.db.client.model.Host; import com.emc.storageos.db.client.model.Initiator; import com.emc.storageos.db.client.model.StoragePort; import com.emc.storageos.db.client.model.StringSet; import com.emc.storageos.db.client.model.Volume; import com.emc.storageos.db.client.upgrade.callbacks.StaleRelationURICleanupMigration; import com.emc.storageos.db.server.DbsvcTestBase; import com.google.common.collect.Maps; public class StaleRelationURICleanupMigrationTest extends DbsvcTestBase { private StaleRelationURICleanupMigration callback; @Before public void setUp() throws Exception { callback = new StaleRelationURICleanupMigration(); callback.setCoordinatorClient(_coordinator); callback.setDbClient(_dbClient); } @Test public void testForExportMask() throws Exception { List<Initiator> existingInitiators = createActiveDataObject(Initiator.class, 2); Map<URI, Integer> existingVolumeMaps = createActiveDataObjectMap(Volume.class, 5); ExportMask exportMask = new ExportMask(); exportMask.setId(URIUtil.createId(ExportMask.class)); exportMask.setLabel("label"); exportMask.setInactive(false); exportMask.addInitiators(createFakeDataObject(Initiator.class, 5)); exportMask.addInitiators(createInactiveDataObject(Initiator.class, 5)); exportMask.addInitiators(existingInitiators); exportMask.setStoragePorts(retrieveIDStrings(createFakeDataObject(StoragePort.class, 5))); exportMask.addVolumes(createFakeDataObjectMap(Volume.class, 5)); exportMask.addVolumes(createInactiveDataObjectMap(Volume.class, 5)); exportMask.addVolumes(existingVolumeMaps); for (String initiator : exportMask.getInitiators()) { exportMask.addZoningMapEntry(initiator, new StringSet()); } _dbClient.updateObject(exportMask); ExportMask target = _dbClient.queryObject(ExportMask.class, exportMask.getId()); Assert.assertTrue(SetUtils.isEqualSet(target.getInitiators(), exportMask.getInitiators())); Assert.assertTrue(SetUtils.isEqualSet(target.getStoragePorts(), exportMask.getStoragePorts())); Assert.assertTrue(Maps.difference(target.getVolumes(), exportMask.getVolumes()).areEqual()); callback.process(); target = _dbClient.queryObject(ExportMask.class, exportMask.getId()); Assert.assertEquals(existingInitiators.size(), target.getInitiators().size()); for (Initiator initiator : existingInitiators) { Assert.assertTrue(target.getInitiators().contains(initiator.getId().toString())); } Assert.assertTrue(target.getStoragePorts() == null || target.getStoragePorts().isEmpty()); Assert.assertEquals(existingVolumeMaps.size(), target.getVolumes().size()); for (Entry<URI, Integer> entry : existingVolumeMaps.entrySet()) { Assert.assertEquals(entry.getValue().toString(), target.getVolumes().get(entry.getKey().toString())); } for (Initiator initiator : existingInitiators) { Assert.assertTrue(exportMask.getZoningMap().containsKey(initiator.getId().toString())); } } @Test public void testForExportGroup() throws Exception { List<Initiator> existingInitiators = createActiveDataObject(Initiator.class, 2); List<Host> existingHosts = createActiveDataObject(Host.class, 2); ExportMask exportMask = createActiveDataObject(ExportMask.class, 1).get(0); ExportGroup exportGroup = new ExportGroup(); exportGroup.setId(URIUtil.createId(ExportGroup.class)); exportGroup.setLabel("label"); exportGroup.setInactive(false); exportGroup.addInitiators(retrieveIDURIs(createFakeDataObject(Initiator.class, 5))); exportGroup.addInitiators(retrieveIDURIs(createInactiveDataObject(Initiator.class, 5))); exportGroup.addInitiators(retrieveIDURIs(existingInitiators)); exportGroup.addHosts(retrieveIDURIs(createFakeDataObject(Host.class, 1))); exportGroup.addHosts(retrieveIDURIs(createInactiveDataObject(Host.class, 1))); exportGroup.addHosts(retrieveIDURIs(existingHosts)); exportGroup.addVolumes(createFakeDataObjectMap(Volume.class, 5)); exportGroup.addVolumes(createInactiveDataObjectMap(Volume.class, 5)); exportGroup.setSnapshots(new StringSet()); exportGroup.getSnapshots().add(URIUtil.createId(BlockSnapshot.class).toString()); exportGroup.addClusters(retrieveIDURIs(createFakeDataObject(Cluster.class, 5))); exportGroup.addClusters(retrieveIDURIs(createInactiveDataObject(Cluster.class, 5))); exportGroup.addExportMask(exportMask.getId()); _dbClient.updateObject(exportGroup); ExportGroup target = _dbClient.queryObject(ExportGroup.class, exportGroup.getId()); Assert.assertTrue(SetUtils.isEqualSet(exportGroup.getInitiators(), target.getInitiators())); Assert.assertTrue(SetUtils.isEqualSet(exportGroup.getHosts(), target.getHosts())); Assert.assertTrue(Maps.difference(exportGroup.getVolumes(), target.getVolumes()).areEqual()); Assert.assertTrue(SetUtils.isEqualSet(exportGroup.getSnapshots(), target.getSnapshots())); Assert.assertTrue(SetUtils.isEqualSet(exportGroup.getClusters(), target.getClusters())); Assert.assertTrue(SetUtils.isEqualSet(exportGroup.getExportMasks(), target.getExportMasks())); callback.process(); target = _dbClient.queryObject(ExportGroup.class, exportGroup.getId()); Assert.assertEquals(existingInitiators.size(), target.getInitiators().size()); for (Initiator initiator : existingInitiators) { Assert.assertTrue(target.getInitiators().contains(initiator.getId().toString())); } Assert.assertEquals(existingHosts.size(), target.getHosts().size()); for (Host host : existingHosts) { Assert.assertTrue(target.getHosts().contains(host.getId().toString())); } Assert.assertTrue(target.getSnapshots() == null || target.getSnapshots().isEmpty()); Assert.assertTrue(target.getClusters() == null || target.getClusters().isEmpty()); Assert.assertEquals(1, target.getExportMasks().size()); Assert.assertEquals(exportMask.getId().toString(), target.getExportMasks().toArray()[0]); Assert.assertTrue(target.getVolumes() ==null || target.getVolumes().isEmpty()); } @Test public void testForExportGroup2() throws Exception{ Map<URI, Integer> existingVolumeMaps = createActiveDataObjectMap(Volume.class, 5); ExportGroup exportGroup = new ExportGroup(); exportGroup.setId(URIUtil.createId(ExportGroup.class)); exportGroup.setLabel("label"); exportGroup.setInactive(false); exportGroup.addVolumes(existingVolumeMaps); _dbClient.updateObject(exportGroup); callback.process(); exportGroup = _dbClient.queryObject(ExportGroup.class, exportGroup.getId()); Assert.assertEquals(existingVolumeMaps.size(), exportGroup.getVolumes().size()); for (Entry<URI, Integer> entry : existingVolumeMaps.entrySet()) { Assert.assertEquals(entry.getValue().toString(), exportGroup.getVolumes().get(entry.getKey().toString())); } } private <T extends DataObject> List<T> createFakeDataObject(Class<T> clazz, int count) throws InstantiationException, IllegalAccessException { List<T> result = new ArrayList<>(); for (int i = 0; i < count; i++) { T dataObject = clazz.newInstance(); dataObject.setId(URIUtil.createId(clazz)); dataObject.setLabel("Label for " + dataObject.getId()); dataObject.setInactive(false); result.add(dataObject); } return result; } private <T extends DataObject> List<T> createActiveDataObject(Class<T> clazz, int count) throws InstantiationException, IllegalAccessException { List<T> result = createFakeDataObject(clazz, count); _dbClient.updateObject(result); return result; } private <T extends DataObject> List<T> createInactiveDataObject(Class<T> clazz, int count) throws InstantiationException, IllegalAccessException { List<T> result = createActiveDataObject(clazz, count); _dbClient.markForDeletion(result); return result; } private <T extends DataObject> Map<URI, Integer> createFakeDataObjectMap(Class<T> clazz, int count) throws InstantiationException, IllegalAccessException { List<T> dataObjects = createFakeDataObject(clazz, count); return dataObjectList2Map(dataObjects); } private <T extends DataObject> Map<URI, Integer> createActiveDataObjectMap(Class<T> clazz, int count) throws InstantiationException, IllegalAccessException { List<T> dataObjects = createActiveDataObject(clazz, count); return dataObjectList2Map(dataObjects); } private <T extends DataObject> Map<URI, Integer> createInactiveDataObjectMap(Class<T> clazz, int count) throws InstantiationException, IllegalAccessException { List<T> dataObjects = createActiveDataObject(clazz, count); _dbClient.markForDeletion(dataObjects); return dataObjectList2Map(dataObjects); } private <T extends DataObject> Map<URI, Integer> dataObjectList2Map(List<T> dataObjects) { Map<URI, Integer> result = new HashMap<>(); for (T t : dataObjects) { result.put(t.getId(), RandomUtils.nextInt()); } return result; } private <T extends DataObject> List<String> retrieveIDStrings(List<T> dataObjects) { List<String> result = new ArrayList<>(); for (T t : dataObjects) { result.add(t.getId().toString()); } return result; } private <T extends DataObject> List<URI> retrieveIDURIs(List<T> dataObjects) { List<URI> result = new ArrayList<>(); for (T t : dataObjects) { result.add(t.getId()); } return result; } }