/* * RHQ Management Platform * Copyright (C) 2011 Red Hat, Inc. * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.rhq.enterprise.server.drift; import static java.util.Arrays.asList; import static org.rhq.core.domain.common.EntityContext.forResource; import static org.rhq.core.domain.drift.DriftCategory.FILE_ADDED; import static org.rhq.core.domain.drift.DriftChangeSetCategory.COVERAGE; import static org.rhq.core.domain.drift.DriftChangeSetCategory.DRIFT; import static org.rhq.core.domain.drift.DriftConfigurationDefinition.BaseDirValueContext.fileSystem; import static org.rhq.core.domain.drift.DriftConfigurationDefinition.DriftHandlingMode.normal; import static org.rhq.core.domain.drift.DriftConfigurationDefinition.DriftHandlingMode.plannedChanges; import static org.rhq.core.domain.drift.DriftDefinitionComparator.CompareMode.BOTH_BASE_INFO_AND_DIRECTORY_SPECIFICATIONS; import static org.rhq.enterprise.server.safeinvoker.HibernateDetachUtility.SerializationType.SERIALIZATION; import static org.rhq.enterprise.server.util.LookupUtil.getDriftManager; import static org.rhq.enterprise.server.util.LookupUtil.getDriftTemplateManager; import static org.rhq.test.AssertUtils.assertPropertiesMatch; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import org.testng.annotations.Test; import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.criteria.DriftDefinitionCriteria; import org.rhq.core.domain.criteria.DriftDefinitionTemplateCriteria; import org.rhq.core.domain.criteria.GenericDriftChangeSetCriteria; import org.rhq.core.domain.criteria.JPADriftChangeSetCriteria; import org.rhq.core.domain.drift.Drift; import org.rhq.core.domain.drift.DriftChangeSet; import org.rhq.core.domain.drift.DriftDefinition; import org.rhq.core.domain.drift.DriftDefinitionComparator; import org.rhq.core.domain.drift.DriftDefinitionTemplate; import org.rhq.core.domain.drift.DriftSnapshot; import org.rhq.core.domain.drift.Filter; import org.rhq.core.domain.drift.JPADrift; import org.rhq.core.domain.drift.JPADriftChangeSet; import org.rhq.core.domain.drift.JPADriftFile; import org.rhq.core.domain.drift.JPADriftSet; import org.rhq.core.domain.resource.ResourceType; import org.rhq.core.domain.util.PageList; import org.rhq.enterprise.server.safeinvoker.HibernateDetachUtility; import org.rhq.enterprise.server.test.TransactionCallback; import org.rhq.test.AssertUtils; public class DriftTemplateManagerBeanTest extends AbstractDriftServerTest { private static final String drift1Path = "drift.1"; private static final String drift2Path = "drift.2"; private final String TEST_CREATE_TEMPLATE = NAME_PREFIX + "createTemplateForNegativeUpdateTests"; private final String TEST_PIN_TEMPLATE = NAME_PREFIX + "pinTemplate"; private final String driftFile1Hash = NAME_PREFIX + "a1b2c3"; private final String driftFile2Hash = NAME_PREFIX + "1a2b3c"; private DriftTemplateManagerLocal templateMgr; private DriftManagerLocal driftMgr; // Note: Arquillian currently (1.0.2) runs each test in its own testng lifecycle. Think of it as each // test being in its own suite, and the test class being new'd for each test. Instance variables // don't retain their set values between tests. We must reset these from the db, as necessary, when // tests have dependencies on other tests. private JPADrift drift1; private JPADrift drift2; private JPADriftFile driftFile1; private JPADriftFile driftFile2; @Override protected void beforeMethod(Method testMethod) throws Exception { super.beforeMethod(testMethod); templateMgr = getDriftTemplateManager(); driftMgr = getDriftManager(); } @Override protected void initDB() throws Exception { super.initDB(); agentServiceContainer.driftService = new TestDefService() { @Override public void unscheduleDriftDetection(int resourceId, DriftDefinition driftDef) { detach(driftDef); } @Override public void updateDriftDetection(int resourceId, DriftDefinition driftDef) { detach(driftDef); } @Override public void updateDriftDetection(int resourceId, DriftDefinition driftDef, DriftSnapshot driftSnapshot) { detach(driftDef); detach(driftSnapshot); } private void detach(Object object) { try { HibernateDetachUtility.nullOutUninitializedFields(object, SERIALIZATION); } catch (Exception e) { throw new RuntimeException(e); } } }; } @Test(dependsOnGroups = "pinning") public void createNewTemplate() { final DriftDefinition definition = new DriftDefinition(new Configuration()); definition.setName(NAME_PREFIX + "createNewTemplate"); definition.setEnabled(true); definition.setDriftHandlingMode(normal); definition.setInterval(2400L); definition.setBasedir(new DriftDefinition.BaseDirectory(fileSystem, "/foo/bar/test")); final DriftDefinitionTemplate newTemplate = templateMgr.createTemplate(getOverlord(), resourceType.getId(), true, definition); executeInTransaction(false, new TransactionCallback() { @Override public void execute() throws Exception { ResourceType updatedType = em.find(ResourceType.class, resourceType.getId()); assertEquals("Failed to add new drift definition to resource type", 1, updatedType .getDriftDefinitionTemplates().size()); DriftDefinitionTemplate expectedTemplate = new DriftDefinitionTemplate(); expectedTemplate.setTemplateDefinition(definition); expectedTemplate.setUserDefined(true); assertDriftTemplateEquals("Failed to save template", expectedTemplate, newTemplate); assertTrue("The template should have its id set", newTemplate.getId() > 0); } }); } // I had to restructure several tests below into a single test because the approach previously // taken was flawed. It depended on no interaction between test classes derived from // AbstractDriftServerTest. Once the classes interact a test method in another class could // wipe the DB of the test objects these tests needed. That is a false assumption. @Test(groups = "negativeUpdate") public void consolidatedNegativeUpdatesTest() { String testClass = "Running Test: " + this.getClass().getSimpleName() + "."; String testMethod = "createTemplateForNegativeUpdateTests()"; System.out.println(testClass + testMethod); createTemplateForNegativeUpdateTests(); testMethod = "createTemplateForNegativeUpdateTests()"; System.out.println(testClass + testMethod); try { doNotAllowBaseDirToBeUpdated(); fail(testMethod + ": Should have thrown exception"); } catch (Exception e) { String msg = e.getMessage(); if (!msg.matches(".*base directory.*cannot be modified")) { fail(testMethod + ": Wrong Exception: " + e.getMessage()); } } testMethod = "doNotAllowBaseDirToBeUpdated()"; System.out.println(testClass + testMethod); try { doNotAllowBaseDirToBeUpdated(); fail(testMethod + ": Should have thrown exception"); } catch (Exception e) { String msg = e.getMessage(); if (!msg.matches(".*base directory.*cannot be modified")) { fail(testMethod + ": Wrong Exception: " + e.getMessage()); } } testMethod = "doNotAllowFiltersToBeUpdated()"; System.out.println(testClass + testMethod); try { doNotAllowFiltersToBeUpdated(); fail(testMethod + ": Should have thrown exception"); } catch (Exception e) { String msg = e.getMessage(); if (!msg.matches(".*filters.*cannot be modified")) { fail(testMethod + ": Wrong Exception: " + e.getMessage()); } } testMethod = "doNotAllowTemplateNameToBeUpdated()"; System.out.println(testClass + testMethod); try { doNotAllowTemplateNameToBeUpdated(); fail(testMethod + ": Should have thrown exception"); } catch (Exception e) { String msg = e.getMessage(); if (!msg.matches(".*name.*cannot be modified")) { fail(testMethod + ": Wrong Exception: " + e.getMessage()); } } testMethod = "doNotAllowDuplicateTemplateNames()"; System.out.println(testClass + testMethod); try { doNotAllowDuplicateTemplateNames(); fail(testMethod + ": Should have thrown exception"); } catch (Exception e) { String msg = e.getMessage(); if (!msg.matches(".*template name must be unique.*")) { fail(testMethod + ": Wrong Exception: " + e.getMessage()); } } } //@Test(groups = "negativeUpdate") private void createTemplateForNegativeUpdateTests() { DriftDefinition definition = new DriftDefinition(new Configuration()); definition.setName(TEST_CREATE_TEMPLATE); definition.setEnabled(true); definition.setDriftHandlingMode(normal); definition.setInterval(2400L); definition.setBasedir(new DriftDefinition.BaseDirectory(fileSystem, "/foo/bar/test")); templateMgr.createTemplate(getOverlord(), resourceType.getId(), true, definition); DriftDefinitionTemplate template = loadTemplate(definition.getName()); assertNotNull("Failed to load template", template); //em.clear(); //System.out.println("Created " + template.toString(false)); } //@Test(groups = "negativeUpdate", dependsOnMethods = "createTemplateForNegativeUpdateTests", expectedExceptions = EJBException.class, expectedExceptionsMessageRegExp = ".*base directory.*cannot be modified") private void doNotAllowBaseDirToBeUpdated() { DriftDefinitionTemplate template = loadTemplate(TEST_CREATE_TEMPLATE); DriftDefinition definition = template.getTemplateDefinition(); definition.setBasedir(new DriftDefinition.BaseDirectory(fileSystem, "/foo/bar/TEST")); templateMgr.updateTemplate(getOverlord(), template); } //@Test(groups = "negativeUpdate", dependsOnMethods = "createTemplateForNegativeUpdateTests", expectedExceptions = EJBException.class, expectedExceptionsMessageRegExp = ".*filters.*cannot be modified") private void doNotAllowFiltersToBeUpdated() { DriftDefinitionTemplate template = loadTemplate(TEST_CREATE_TEMPLATE); DriftDefinition definition = template.getTemplateDefinition(); definition.addExclude(new Filter("/foo/bar/TEST/conf", "*.xml")); templateMgr.updateTemplate(getOverlord(), template); } //@Test(groups = "negativeUpdate", dependsOnMethods = "createTemplateForNegativeUpdateTests", expectedExceptions = EJBException.class, expectedExceptionsMessageRegExp = ".*name.*cannot be modified") private void doNotAllowTemplateNameToBeUpdated() { DriftDefinitionTemplate template = loadTemplate(TEST_CREATE_TEMPLATE); template.setName(NAME_PREFIX + "A new name"); templateMgr.updateTemplate(getOverlord(), template); } //@Test(groups = "negativeUpdate", dependsOnMethods = "createTemplateForNegativeUpdateTests", expectedExceptions = EJBException.class, expectedExceptionsMessageRegExp = ".*template name must be unique.*") private void doNotAllowDuplicateTemplateNames() { DriftDefinition definition = new DriftDefinition(new Configuration()); definition.setName(TEST_CREATE_TEMPLATE); definition.setEnabled(true); definition.setDriftHandlingMode(normal); definition.setInterval(2400L); definition.setBasedir(new DriftDefinition.BaseDirectory(fileSystem, "/foo/bar/test")); templateMgr.createTemplate(getOverlord(), resourceType.getId(), true, definition); } @Test(dependsOnGroups = "pinning") public void createAndUpdateTemplate() { // create the template DriftDefinition definition = new DriftDefinition(new Configuration()); definition.setName(NAME_PREFIX + "test-updateTemplate"); definition.setDescription("update template test"); definition.setEnabled(true); definition.setDriftHandlingMode(normal); definition.setInterval(2400L); definition.setBasedir(new DriftDefinition.BaseDirectory(fileSystem, "/foo/bar/test")); DriftDefinitionTemplate template = templateMgr.createTemplate(getOverlord(), resourceType.getId(), true, definition); // next create some definitions from the template final DriftDefinition attachedDef1 = createDefinition(template, NAME_PREFIX + "attachedDef1", true); final DriftDefinition attachedDef2 = createDefinition(template, NAME_PREFIX + "attachedDef2", true); final DriftDefinition detachedDef1 = createDefinition(template, NAME_PREFIX + "detachedDef1", false); final DriftDefinition detachedDef2 = createDefinition(template, NAME_PREFIX + "detachedDef2", false); driftMgr.updateDriftDefinition(getOverlord(), forResource(resource.getId()), attachedDef1); driftMgr.updateDriftDefinition(getOverlord(), forResource(resource.getId()), attachedDef2); driftMgr.updateDriftDefinition(getOverlord(), forResource(resource.getId()), detachedDef1); driftMgr.updateDriftDefinition(getOverlord(), forResource(resource.getId()), detachedDef2); // update the template final DriftDefinition newTemplateDef = template.getTemplateDefinition(); newTemplateDef.setInterval(4800L); newTemplateDef.setDriftHandlingMode(plannedChanges); newTemplateDef.setEnabled(false); templateMgr.updateTemplate(getOverlord(), template); // verify that the template has been updated final DriftDefinitionTemplate updatedTemplate = loadTemplate(template.getName()); AssertUtils.assertPropertiesMatch("Failed to update template", template, updatedTemplate, "resourceType", "driftDefinitions", "templateDefinition"); // verify that attached definitions are updated. for (DriftDefinition def : asList(attachedDef1, attachedDef2)) { DriftDefinition updatedDef = loadDefinition(def.getId()); String msg = "Failed to propagate update to attached definition " + toString(updatedDef) + " - "; DriftDefinition updatedTemplateDef = updatedTemplate.getTemplateDefinition(); assertEquals(msg + "enabled property not updated", updatedTemplateDef.isEnabled(), updatedDef.isEnabled()); assertEquals(msg + "driftHandlingMode property not updated", updatedTemplateDef.getDriftHandlingMode(), updatedDef.getDriftHandlingMode()); assertEquals(msg + "interval property not updated", updatedTemplateDef.getInterval(), updatedDef.getInterval()); } // verify that the detached definitions have not been updated. for (DriftDefinition def : asList(detachedDef1, detachedDef2)) { DriftDefinition defAfterUpdate = loadDefinition(def.getId()); String msg = "Detached definition " + toString(def) + " should not get updated - "; assertEquals(msg + "enabled property was modified", def.isEnabled(), defAfterUpdate.isEnabled()); assertEquals(msg + "driftHandlingMode property was modified", def.getDriftHandlingMode(), defAfterUpdate.getDriftHandlingMode()); assertEquals(msg + "interval property was modified", def.getInterval(), defAfterUpdate.getInterval()); } } // I had to restructure several tests below into a single test because the approach previously // taken was flawed. It depended on no interaction between test classes derived from // AbstractDriftServerTest. Once the classes interact a test method in another class could // wipe the DB of the test objects these tests needed. That is a false assumption. @Test(groups = "pinning", dependsOnGroups = "negativeUpdate") public void consolidatedPinningTest() throws Exception { String testClass = "Running Test: " + this.getClass().getSimpleName() + "."; String testMethod = "pinTemplate()"; System.out.println(testClass + testMethod); pinTemplate(); testMethod = "persistChangeSetWhenTemplateGetsPinned()"; System.out.println(testClass + testMethod); persistChangeSetWhenTemplateGetsPinned(); testMethod = "updateAttachedDefinitionsWhenTemplateGetsPinned()"; System.out.println(testClass + testMethod); updateAttachedDefinitionsWhenTemplateGetsPinned(); testMethod = "doNotUpdateDetachedDefinitionsWhenTemplateGetsPinned()"; System.out.println(testClass + testMethod); doNotUpdateDetachedDefinitionsWhenTemplateGetsPinned(); } //@Test(groups = "pinning", dependsOnGroups = "negativeUpdate") private void pinTemplate() throws Exception { // First create the template final DriftDefinition templateDef = new DriftDefinition(new Configuration()); templateDef.setName(TEST_PIN_TEMPLATE); templateDef.setEnabled(true); templateDef.setDriftHandlingMode(normal); templateDef.setInterval(2400L); templateDef.setBasedir(new DriftDefinition.BaseDirectory(fileSystem, "/foo/bar/test")); final DriftDefinitionTemplate template = templateMgr.createTemplate(getOverlord(), resourceType.getId(), true, templateDef); // next create some resource level definitions final DriftDefinition attachedDef1 = createDefinition(template, NAME_PREFIX + "attachedDef1", true); final DriftDefinition attachedDef2 = createDefinition(template, NAME_PREFIX + "attachedDef2", true); final DriftDefinition detachedDef1 = createDefinition(template, NAME_PREFIX + "detachedDef1", false); final DriftDefinition detachedDef2 = createDefinition(template, NAME_PREFIX + "detachedDef2", false); // create initial change set from which the snapshot will be generated final JPADriftChangeSet changeSet0 = new JPADriftChangeSet(resource, 0, COVERAGE, attachedDef1); driftFile1 = new JPADriftFile(driftFile1Hash); drift1 = new JPADrift(changeSet0, drift1Path, FILE_ADDED, null, driftFile1); final JPADriftSet driftSet = new JPADriftSet(); driftSet.addDrift(drift1); // create change set v1 driftFile2 = new JPADriftFile(driftFile2Hash); final JPADriftChangeSet changeSet1 = new JPADriftChangeSet(resource, 1, DRIFT, attachedDef1); drift2 = new JPADrift(changeSet1, drift2Path, FILE_ADDED, null, driftFile2); executeInTransaction(false, new TransactionCallback() { @Override public void execute() throws Exception { em.persist(attachedDef1); em.persist(driftFile1); em.persist(driftFile2); em.persist(changeSet0); em.persist(driftSet); changeSet0.setInitialDriftSet(driftSet); em.merge(changeSet0); em.persist(changeSet1); em.persist(drift2); em.persist(attachedDef2); em.persist(detachedDef1); em.persist(detachedDef2); } }); // now we pin the snapshot to the template templateMgr.pinTemplate(getOverlord(), template.getId(), attachedDef1.getId(), 1); // verify that the template is now pinned DriftDefinitionTemplate updatedTemplate = loadTemplate(template.getName()); assertTrue("Template should be marked pinned", updatedTemplate.isPinned()); } @SuppressWarnings("unchecked") //@Test(groups = "pinning", dependsOnMethods = "pinTemplate") private void persistChangeSetWhenTemplateGetsPinned() throws Exception { DriftDefinitionTemplate template = loadTemplate(TEST_PIN_TEMPLATE); GenericDriftChangeSetCriteria criteria = new GenericDriftChangeSetCriteria(); criteria.addFilterId(template.getChangeSetId()); PageList<? extends DriftChangeSet<?>> changeSets = driftMgr.findDriftChangeSetsByCriteria(getOverlord(), criteria); assertEquals("Expected to find change set for pinned template", 1, changeSets.size()); JPADriftChangeSet expectedChangeSet = new JPADriftChangeSet(resource, 1, COVERAGE, null); List<? extends Drift> expectedDrifts = asList(new JPADrift(expectedChangeSet, drift1Path, FILE_ADDED, null, driftFile1), new JPADrift(expectedChangeSet, drift2.getPath(), FILE_ADDED, null, driftFile2)); DriftChangeSet<?> actualChangeSet = changeSets.get(0); List<? extends Drift> actualDrifts = new ArrayList(actualChangeSet.getDrifts()); AssertUtils.assertCollectionMatchesNoOrder( "Expected to find drifts from change sets 1 and 2 in the template change set", (List<Drift>) expectedDrifts, (List<Drift>) actualDrifts, "id", "ctime", "changeSet", "newDriftFile"); // we need to compare the newDriftFile properties separately because // assertCollectionMatchesNoOrder compares properties via equals() and JPADriftFile // does not implement equals. assertPropertiesMatch(drift1.getNewDriftFile(), findDriftByPath(actualDrifts, drift1Path).getNewDriftFile(), "The newDriftFile property was not set correctly for " + drift1); assertPropertiesMatch(drift2.getNewDriftFile(), findDriftByPath(actualDrifts, drift2Path).getNewDriftFile(), "The newDriftFile property was not set correctly for " + drift1); } //@Test(groups = "pinning", dependsOnMethods = "pinTemplate") private void updateAttachedDefinitionsWhenTemplateGetsPinned() throws Exception { DriftDefinitionTemplate template = loadTemplate(TEST_PIN_TEMPLATE); // get the attached definitions List<DriftDefinition> attachedDefs = new LinkedList<DriftDefinition>(); for (DriftDefinition d : template.getDriftDefinitions()) { if (d.isAttached() && (d.getName().equals(NAME_PREFIX + "attachedDef1") || d.getName() .equals(NAME_PREFIX + "attachedDef2"))) { attachedDefs.add(d); } } assertEquals("Failed to get attached definitions for " + toString(template), 2, attachedDefs.size()); assertDefinitionIsPinned(attachedDefs.get(0)); assertDefinitionIsPinned(attachedDefs.get(1)); } //@Test(groups = "pinning", dependsOnMethods = "pinTemplate") private void doNotUpdateDetachedDefinitionsWhenTemplateGetsPinned() throws Exception { DriftDefinitionTemplate template = loadTemplate(TEST_PIN_TEMPLATE); // get the detached definitions List<DriftDefinition> detachedDefs = new LinkedList<DriftDefinition>(); for (DriftDefinition d : template.getDriftDefinitions()) { if (!d.isAttached() && (d.getName().equals(NAME_PREFIX + "detachedDef1") || d.getName() .equals(NAME_PREFIX + "detachedDef2"))) { detachedDefs.add(d); } } assertEquals("Failed to get detached definitions for " + toString(template), 2, detachedDefs.size()); assertDefinitionIsNotPinned(detachedDefs.get(0)); assertDefinitionIsNotPinned(detachedDefs.get(1)); } @Test(dependsOnGroups = "pinning") public void deleteTemplate() throws Exception { // first create the template final DriftDefinition templateDef = new DriftDefinition(new Configuration()); templateDef.setName(TEST_PIN_TEMPLATE); templateDef.setEnabled(true); templateDef.setDriftHandlingMode(normal); templateDef.setInterval(2400L); templateDef.setBasedir(new DriftDefinition.BaseDirectory(fileSystem, "/foo/bar/test")); final DriftDefinitionTemplate template = templateMgr.createTemplate(getOverlord(), resourceType.getId(), true, templateDef); // next create some resource level definitions final DriftDefinition attachedDef1 = createDefinition(template, NAME_PREFIX + "attachedDef1", true); final DriftDefinition attachedDef2 = createDefinition(template, NAME_PREFIX + "attachedDef2", true); final DriftDefinition detachedDef1 = createDefinition(template, NAME_PREFIX + "detachedDef1", false); final DriftDefinition detachedDef2 = createDefinition(template, NAME_PREFIX + "detachedDef2", false); // create some change sets final JPADriftChangeSet changeSet0 = new JPADriftChangeSet(resource, 0, COVERAGE, attachedDef1); driftFile1 = new JPADriftFile(driftFile1Hash); drift1 = new JPADrift(changeSet0, drift1Path, FILE_ADDED, null, driftFile1); final JPADriftSet driftSet0 = new JPADriftSet(); driftSet0.addDrift(drift1); final JPADriftChangeSet changeSet1 = new JPADriftChangeSet(resource, 0, DRIFT, detachedDef1); driftFile2 = new JPADriftFile(driftFile2Hash); drift2 = new JPADrift(changeSet1, drift2Path, FILE_ADDED, null, driftFile2); final JPADriftSet driftSet1 = new JPADriftSet(); driftSet1.addDrift(drift2); executeInTransaction(false, new TransactionCallback() { @Override public void execute() throws Exception { em.persist(attachedDef1); em.persist(attachedDef2); em.persist(detachedDef1); em.persist(detachedDef2); em.persist(driftFile1); em.persist(driftFile2); em.persist(changeSet0); em.persist(driftSet0); changeSet0.setInitialDriftSet(driftSet0); em.merge(changeSet0); em.persist(changeSet1); em.persist(driftSet1); changeSet1.setInitialDriftSet(driftSet1); em.merge(changeSet1); } }); // delete the template templateMgr.deleteTemplate(getOverlord(), template.getId()); // verify that attached definitions along with their change sets have // been deleted assertNull("Change sets belonging to attached definitions should be deleted", loadChangeSet(changeSet0.getId())); assertNull("Attached definition " + toString(attachedDef1) + " should be deleted", loadDefinition(attachedDef1.getId())); assertNull("Attached definition " + toString(attachedDef2) + " should be deleted", loadDefinition(attachedDef2.getId())); // verify that detached definitions along with their change sets have not been deleted assertNotNull("Change sets belonging to detached definitions should not be deleted", loadChangeSet(changeSet1.getId())); assertDetachedDefinitionNotDeleted(detachedDef1.getId()); assertDetachedDefinitionNotDeleted(detachedDef2.getId()); // verify that the template itself has been deleted assertNull("The template " + toString(template) + " should have been deleted", loadTemplate(template.getName(), false)); } @SuppressWarnings("unchecked") private void assertDefinitionIsPinned(DriftDefinition definition) throws Exception { // verify that the definition is marked as pinned assertTrue("Expected " + toString(definition) + " to be pinned", definition.isPinned()); // verify that the initial change set is generated for the definition JPADriftChangeSetCriteria criteria = new JPADriftChangeSetCriteria(); criteria.addFilterDriftDefinitionId(definition.getId()); criteria.addFilterCategory(COVERAGE); criteria.fetchDrifts(true); PageList<? extends DriftChangeSet<?>> changeSets = driftMgr.findDriftChangeSetsByCriteria(getOverlord(), criteria); assertEquals("Expected to find one change set", 1, changeSets.size()); JPADriftChangeSet expectedChangeSet = new JPADriftChangeSet(resource, 1, COVERAGE, null); List<? extends Drift> expectedDrifts = asList(new JPADrift(expectedChangeSet, drift1.getPath(), FILE_ADDED, null, driftFile1), new JPADrift(expectedChangeSet, drift2.getPath(), FILE_ADDED, null, driftFile2)); DriftChangeSet<?> actualChangeSet = changeSets.get(0); List<? extends Drift> actualDrifts = new ArrayList(actualChangeSet.getDrifts()); AssertUtils.assertCollectionMatchesNoOrder( "Expected to find drifts from change sets 1 and 2 in the template change set", (List<Drift>) expectedDrifts, (List<Drift>) actualDrifts, "id", "ctime", "changeSet", "newDriftFile"); // Finally make sure that there are no other change sets criteria = new JPADriftChangeSetCriteria(); criteria.addFilterStartVersion(1); criteria.addFilterDriftDefinitionId(definition.getId()); assertEquals("There should not be any drift change sets", 0, driftMgr.findDriftChangeSetsByCriteria(getOverlord(), criteria).size()); } private void assertDefinitionIsNotPinned(DriftDefinition definition) throws Exception { // verify that the definition is not pinned assertFalse("Expected " + toString(definition) + " to be unpinned", definition.isPinned()); // Note that this method assumes that the definition has no change sets // associated with it and therefore checks that there are no change sets. JPADriftChangeSetCriteria criteria = new JPADriftChangeSetCriteria(); criteria.addFilterDriftDefinitionId(definition.getId()); PageList<? extends DriftChangeSet<?>> changeSets = driftMgr.findDriftChangeSetsByCriteria(getOverlord(), criteria); assertEquals("Did not expect to find any change sets for " + toString(definition) + ". Note that this " + "assertion method assumes that the definition you are testing is not supposed to have any change sets.", 0, changeSets.size()); } private void assertDriftTemplateEquals(String msg, DriftDefinitionTemplate expected, DriftDefinitionTemplate actual) { AssertUtils.assertPropertiesMatch(msg + ": basic drift definition template properties do not match", expected, actual, "id", "resourceType", "ctime", "templateDefinition"); assertDriftDefEquals(msg + ": template definitions do not match", expected.getTemplateDefinition(), actual.getTemplateDefinition()); } private void assertDriftDefEquals(String msg, DriftDefinition expected, DriftDefinition actual) { DriftDefinitionComparator comparator = new DriftDefinitionComparator( BOTH_BASE_INFO_AND_DIRECTORY_SPECIFICATIONS); assertEquals(msg, 0, comparator.compare(expected, actual)); } private void assertDetachedDefinitionNotDeleted(int definitionId) { DriftDefinition definition = loadDefinition(definitionId); assertNotNull("Detached definition " + toString(definition) + " should not be deleted", definition); assertNull("The detached definition's template reference should be set to null when the template is deleted", definition.getTemplate()); } private DriftDefinition createDefinition(DriftDefinitionTemplate template, String defName, boolean isAttached) { DriftDefinition def = template.createDefinition(); def.setName(defName); def.setAttached(isAttached); def.setTemplate(template); def.setResource(resource); return def; } private DriftDefinitionTemplate loadTemplate(String name) { return loadTemplate(name, true); } private DriftDefinitionTemplate loadTemplate(String name, boolean verifyResultsUnique) { DriftDefinitionTemplateCriteria criteria = new DriftDefinitionTemplateCriteria(); criteria.addFilterResourceTypeId(resourceType.getId()); criteria.addFilterName(name); criteria.fetchDriftDefinitions(true); criteria.fetchResourceType(true); PageList<DriftDefinitionTemplate> templates = templateMgr.findTemplatesByCriteria(getOverlord(), criteria); if (verifyResultsUnique) { assertEquals("Expected to find one template", 1, templates.size()); } if (templates.isEmpty()) { return null; } return templates.get(0); } private DriftDefinition loadDefinition(int definitionId) { DriftDefinitionCriteria criteria = new DriftDefinitionCriteria(); criteria.addFilterId(definitionId); criteria.fetchConfiguration(true); criteria.fetchTemplate(true); PageList<DriftDefinition> definitions = driftMgr.findDriftDefinitionsByCriteria(getOverlord(), criteria); if (definitions.isEmpty()) { return null; } return definitions.get(0); } private DriftChangeSet<?> loadChangeSet(String id) throws Exception { GenericDriftChangeSetCriteria criteria = new GenericDriftChangeSetCriteria(); criteria.addFilterId(id); PageList<? extends DriftChangeSet<?>> changeSets = driftMgr.findDriftChangeSetsByCriteria(getOverlord(), criteria); if (changeSets.isEmpty()) { return null; } return changeSets.get(0); } }