/* * RHQ Management Platform * Copyright (C) 2005-2008 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, version 2, as * published by the Free Software Foundation, and/or the GNU Lesser * General Public License, version 2.1, also as published by the Free * Software Foundation. * * 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 and the GNU Lesser General Public License * for more details. * * You should have received a copy of the GNU General Public License * and the GNU Lesser General Public License along with this program; * if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ package org.rhq.enterprise.server.configuration.metadata; import static java.util.Arrays.asList; import static org.rhq.core.clientapi.shared.PluginDescriptorUtil.loadPluginConfigDefFor; import static org.rhq.core.clientapi.shared.PluginDescriptorUtil.loadPluginDescriptor; import java.util.List; import java.util.Map; import javax.persistence.EntityManager; import javax.transaction.SystemException; import org.testng.annotations.Test; import org.rhq.core.clientapi.descriptor.plugin.PluginDescriptor; import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; import org.rhq.core.domain.configuration.definition.PropertyDefinition; import org.rhq.core.domain.configuration.definition.PropertyDefinitionEnumeration; import org.rhq.core.domain.configuration.definition.PropertyDefinitionList; import org.rhq.core.domain.configuration.definition.PropertyDefinitionMap; import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple; import org.rhq.core.domain.configuration.definition.PropertyGroupDefinition; import org.rhq.core.domain.configuration.definition.PropertyOptionsSource; import org.rhq.enterprise.server.test.AbstractEJB3Test; import org.rhq.enterprise.server.util.LookupUtil; import org.rhq.test.AssertUtils; /** * These are data-driven tests that exercise the plugin upgrade functionality around configurations such as plugin * configurations and resource configurations. The data sets that are used are defined in two plugin descriptors. One * is the original version and the other is the upgraded version. In order to avoid inter-dependencies between test * methods, a separate plugin configuration should be used for each test method. A separate resource type is declared * for each test, further documenting and delinating where each configuration is used. In the test methods, the * original and updated configuration definitions are initialized with an xpath expression that specifies the owning * resource type. */ public class ConfigurationMetadataManagerBeanTest extends AbstractEJB3Test { private static final boolean ENABLED = true; PluginDescriptor originalDescriptor; PluginDescriptor updatedDescriptor; ConfigurationDefinition originalConfigDef; ConfigurationDefinition updatedConfigDef; @Override protected void beforeMethod() { String pluginFileBaseName = "configuration_metadata_manager_bean_test"; String version1 = pluginFileBaseName + "_v1.xml"; String version2 = pluginFileBaseName + "_v2.xml"; originalDescriptor = loadPluginDescriptor(getClass().getResource(version1)); updatedDescriptor = loadPluginDescriptor(getClass().getResource(version2)); } @Test(enabled = ENABLED) public void addNewUngroupedSimplePropertyDef() { initConfigDefs("servers[name='MyServer1']", "test"); String propertyName = "newUngroupedProperty"; PropertyDefinitionSimple expected = updatedConfigDef.getPropertyDefinitionSimple(propertyName); PropertyDefinitionSimple actual = originalConfigDef.getPropertyDefinitionSimple(propertyName); assertPropertyDefinitionMatches("New ungrouped property defs should be added to the configuration definition", expected, actual); } @Test(enabled = ENABLED) public void removePropertyDefThatIsNotInNewDescriptor() { initConfigDefs("servers[name='MyServer1']", "test"); assertNull("The property exists in version 1 but not in version 2 of the plugin; therefore, it should be " + "removed the configuration definition", originalConfigDef.get("v1OnlyProperty")); } @Test(enabled = ENABLED) public void doNotModifyExistingPropertyDefThatIsNotModifiedInUpgrade() { initConfigDefs("servers[name='MyServer1']", "test"); String propertyName = "myExistingProperty"; PropertyDefinitionSimple expected = updatedConfigDef.getPropertyDefinitionSimple(propertyName); PropertyDefinitionSimple actual = originalConfigDef.getPropertyDefinitionSimple(propertyName); assertPropertyDefinitionMatches("Existing property that is not changed in new version of pluign should " + "not change", expected, actual); } @Test(enabled = ENABLED) public void updatePropertyWithAddedOptions() { initConfigDefs("servers[name='ServerWithAddedOptions']", "UpdatedPropertyWithAddedOptions"); String propertyName = "mySimple"; PropertyDefinitionSimple expectedProperty = updatedConfigDef.getPropertyDefinitionSimple(propertyName); List<PropertyDefinitionEnumeration> expected = expectedProperty.getEnumeratedValues(); PropertyDefinitionSimple actualProperty = originalConfigDef.getPropertyDefinitionSimple(propertyName); List<PropertyDefinitionEnumeration> actual = actualProperty.getEnumeratedValues(); // TODO Need to verify order here as well AssertUtils.assertCollectionEqualsNoOrder(expected, actual, "Options should have been added to property"); } @Test(enabled = ENABLED) public void addNewGroup() { initConfigDefs("servers[name='GroupTests']", "GroupTests"); assertNotNull("The new property should be added to the configuration definition", findGroup("newGroup", originalConfigDef)); } @Test(enabled = ENABLED) public void replaceMemberDefinitionOfPropertyList() { initConfigDefs("servers[name='UpdatedPropertyList']", "ReplaceMemberDefinitionOfPropertyList"); String propertyName = "myList"; PropertyDefinitionList expectedList = updatedConfigDef.getPropertyDefinitionList(propertyName); PropertyDefinitionList actualList = originalConfigDef.getPropertyDefinitionList(propertyName); assertPropertyDefinitionMatches("The member definition should be replaced with the new version", expectedList, actualList); } @Test(enabled = ENABLED) public void mapPropertyOrderTest() { initConfigDefs("servers[name='UnchangedMap']", "UnchangedMap"); String propertyName = "myMap"; PropertyDefinitionMap map = originalConfigDef.getPropertyDefinitionMap(propertyName); Map<String, PropertyDefinition> propDefs = map.getMap(); assertEquals("Expected three properties in unchanged map", 2, propDefs.size()); assertEquals("Expected property to be kept", "property1ToKeep", propDefs.get("property1ToKeep").getName()); assertEquals("Expected property to be kept", "property2ToKeep", propDefs.get("property2ToKeep").getName()); assertEquals("Expected order_index to be 0", 0, propDefs.get("property1ToKeep").getOrder()); assertEquals("Expected order_index to be 1", 1, propDefs.get("property2ToKeep").getOrder()); } @Test(enabled = ENABLED) public void updateMapWithAddRemoveProperty() { initConfigDefs("servers[name='UpdatedMapWithAddRemoveProperty']", "UpdateMapWithAddRemoveProperty"); String propertyName = "myMap"; PropertyDefinitionMap map = originalConfigDef.getPropertyDefinitionMap(propertyName); Map<String, PropertyDefinition> propDefs = map.getMap(); assertEquals("Expected three properties in updated map", 3, propDefs.size()); assertEquals("Expected property to be kept", "property1ToKeep", propDefs.get("property1ToKeep").getName()); assertEquals("Expected property to be added", "propertyToAdd", propDefs.get("propertyToAdd").getName()); assertEquals("Expected property to be kept", "property2ToKeep", propDefs.get("property2ToKeep").getName()); assertEquals("Expected order_index to be 0", 0, propDefs.get("property1ToKeep").getOrder()); assertEquals("Expected order_index to be 1", 1, propDefs.get("propertyToAdd").getOrder()); assertEquals("Expected order_index to be 2", 2, propDefs.get("property2ToKeep").getOrder()); } @Test(enabled = ENABLED) public void updateMapWithUpdatedProperty() { initConfigDefs("servers[name='UpdatedMapWithUpdatedProperty']", "UpdateMapWithUpdatedProperty"); String propertyName = "propertyToUpdate"; String mapPropertyName = "myMap"; PropertyDefinitionMap expectedMap = updatedConfigDef.getPropertyDefinitionMap(mapPropertyName); PropertyDefinitionSimple expected = expectedMap.getPropertyDefinitionSimple(propertyName); PropertyDefinitionMap actualMap = originalConfigDef.getPropertyDefinitionMap(mapPropertyName); PropertyDefinitionSimple actual = actualMap.getPropertyDefinitionSimple(propertyName); List<String> ignoredProperties = asList("id", "parentPropertyMapDefinition"); assertPropertyDefinitionMatches("Expected property who is a child of map to get updated and remain in the map", expected, actual, ignoredProperties); assertEquals("Expected order_index to be 0", 0, actualMap.getMap().get("propertyToUpdate") .getOrder()); } @Test(enabled = ENABLED) public void updatePropertyDefinitionOptionSource() { initConfigDefs("servers[name='OptionSourceTest']", "OptionSourceTest"); // now check the upgrades PropertyDefinitionSimple prop1 = (PropertyDefinitionSimple) updatedConfigDef.get("prop1"); assert prop1 != null; assert prop1.getEnumeratedValues().size() == 0 : "Found an option value. "; PropertyOptionsSource source = prop1.getOptionsSource(); assert source != null : "PropertyOptionSource was not persisted"; assert source.getFilter() == null : "Assumed filter to be null, but was " + source.getFilter(); PropertyDefinitionSimple prop2 = (PropertyDefinitionSimple) updatedConfigDef.get("prop2"); assert prop2 != null; assert prop2.getEnumeratedValues().size() == 1; assert prop2.getOptionsSource() != null; assert prop2.getOptionsSource().getExpression().equals("*"); } private void initConfigDefs(String path, String configName) { loadAndPersistConfigDefs(path, configName); updateConfigDef(); } private void loadAndPersistConfigDefs(String path, String configName) { originalConfigDef = loadPluginConfigDefFor(originalDescriptor, path, configName); assertNotNull(originalConfigDef); updatedConfigDef = loadPluginConfigDefFor(updatedDescriptor, path, configName); assertNotNull(updatedConfigDef); try { getTransactionManager().begin(); EntityManager entityMgr = getEntityManager(); entityMgr.persist(originalConfigDef); getTransactionManager().commit(); } catch (Exception e) { try { getTransactionManager().rollback(); } catch (SystemException e1) { throw new RuntimeException(e1); } throw new RuntimeException(e); } } private void updateConfigDef() { ConfigurationMetadataManagerLocal configMetadataMgr = LookupUtil.getConfigurationMetadataManager(); // The next line updates originalConfigDef with the content of updatedConfigDef configMetadataMgr.updateConfigurationDefinition(updatedConfigDef, originalConfigDef); } private String getPackagePath() { return "/" + getClass().getPackage().getName().replace('.', '/') + "/"; } private PropertyGroupDefinition findGroup(String name, ConfigurationDefinition configDef) { for (PropertyGroupDefinition groupDef : configDef.getGroupDefinitions()) { if (groupDef.getName().equals(name)) { return groupDef; } } return null; } void assertPropertyDefinitionMatches(String msg, PropertyDefinition expected, PropertyDefinition actual) { AssertUtils.assertPropertiesMatch(msg, expected, actual, "id", "configurationDefinition"); } void assertPropertyDefinitionMatches(String msg, PropertyDefinition expected, PropertyDefinition actual, List<String> ignoredProperties) { AssertUtils.assertPropertiesMatch(msg, expected, actual, ignoredProperties); } }