modules/core/client-api-test-utils/pom.xml | 44 modules/core/client-api-test-utils/src/main/java/org/rhq/enterprise/server/configuration/metadata/PluginDescriptorUtil.java | 144 ++ modules/core/client-api/pom.xml | 7 modules/core/client-api/src/test/groovy/org/rhq/core/clientapi/agent/metadata/PluginMetadataParserTest.groovy | 30 modules/enterprise/server/jar/pom.xml | 39 modules/enterprise/server/jar/src/test/groovy/org/rhq/enterprise/server/resource/metadata/ResourceMetadataManagerBeanTest.groovy | 512 ++++++++++ pom.xml | 2 7 files changed, 761 insertions(+), 17 deletions(-)
New commits: commit 7b5ab536af92182ad9b9a3bf17d767bd57454a0b Author: John Sanda jsanda@redhat.com Date: Wed Oct 27 15:44:28 2010 -0400
Updating tests in ResourceMetadataManagerBeanTest
Moving PluginDescriptorUtil into a separate test module making it easier to re-use across modules.
diff --git a/modules/core/client-api-test-utils/pom.xml b/modules/core/client-api-test-utils/pom.xml new file mode 100644 index 0000000..a7ba0a3 --- /dev/null +++ b/modules/core/client-api-test-utils/pom.xml @@ -0,0 +1,44 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.rhq</groupId> + <artifactId>rhq-core-parent</artifactId> + <version>4.0.0-SNAPSHOT</version> + </parent> + + <groupId>org.rhq</groupId> + <artifactId>rhq-core-client-api-test-utils</artifactId> + + <name>RHQ Client API Test Utils</name> + <description>Provides a test utility library for client API classes</description> + + <dependencies> + <dependency> + <groupId>${rhq.groupId}</groupId> + <artifactId>rhq-core-domain</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>${rhq.groupId}</groupId> + <artifactId>rhq-core-client-api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>commons-jxpath</groupId> + <artifactId>commons-jxpath</artifactId> + <version>1.3</version> + </dependency> + <dependency> + <groupId>javax.persistence</groupId> + <artifactId>persistence-api</artifactId> + <version>1.0</version> + </dependency> + <dependency> + <groupId>jboss.jboss-embeddable-ejb3</groupId> + <artifactId>hibernate-all</artifactId> + <version>1.0.0.Alpha9</version> + </dependency> + </dependencies> +</project> diff --git a/modules/core/client-api-test-utils/src/main/java/org/rhq/enterprise/server/configuration/metadata/PluginDescriptorUtil.java b/modules/core/client-api-test-utils/src/main/java/org/rhq/enterprise/server/configuration/metadata/PluginDescriptorUtil.java new file mode 100644 index 0000000..b67d904 --- /dev/null +++ b/modules/core/client-api-test-utils/src/main/java/org/rhq/enterprise/server/configuration/metadata/PluginDescriptorUtil.java @@ -0,0 +1,144 @@ +package org.rhq.enterprise.server.configuration.metadata; + +import java.io.FileNotFoundException; +import java.io.StringReader; +import java.net.URL; + +import javax.xml.XMLConstants; +import javax.xml.bind.JAXBContext; +import javax.xml.bind.Unmarshaller; +import javax.xml.bind.util.ValidationEventCollector; +import javax.xml.validation.Schema; +import javax.xml.validation.SchemaFactory; + +import org.apache.commons.jxpath.JXPathContext; + +import org.rhq.core.clientapi.agent.metadata.ConfigurationMetadataParser; +import org.rhq.core.clientapi.agent.metadata.PluginMetadataParser; +import org.rhq.core.clientapi.descriptor.DescriptorPackages; +import org.rhq.core.clientapi.descriptor.plugin.PluginDescriptor; +import org.rhq.core.clientapi.descriptor.plugin.ResourceDescriptor; +import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; + +public class PluginDescriptorUtil { + + /** + * Loads the plugin descriptor from the specified file. The file path specified should + * be a class path relative path. For example, if the descriptor file is located at + * org.rhq.enterprise.server.configuration.my-descriptor.xml, then you should specify + * /org/rhq/enterprise/server/configuration/my-descriptor.xml. + * + * @param file The class path relative path of the descriptor file + * @return The {@link PluginDescriptor} + */ + public static PluginDescriptor loadPluginDescriptor(String file) { + try { + URL pluginDescriptorURL = PluginDescriptorUtil.class.getResource(file); + if (pluginDescriptorURL == null) { + throw new FileNotFoundException("File " + file + " not found"); + } + + JAXBContext jaxbContext = JAXBContext.newInstance(DescriptorPackages.PC_PLUGIN); + URL pluginSchemaURL = PluginDescriptorUtil.class.getClassLoader().getResource("rhq-plugin.xsd"); + Schema pluginSchema = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI).newSchema( + pluginSchemaURL); + Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); + ValidationEventCollector vec = new ValidationEventCollector(); + unmarshaller.setEventHandler(vec); + unmarshaller.setSchema(pluginSchema); + + return (PluginDescriptor) unmarshaller.unmarshal(pluginDescriptorURL.openStream()); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + /** + * Transforms the given string into a plugin descriptor object. + * + * @param string The plugin descriptor specified as a string + * @return The {@link PluginDescriptor} + */ + public static PluginDescriptor toPluginDescriptor(String string) { + try { + JAXBContext jaxbContext = JAXBContext.newInstance(DescriptorPackages.PC_PLUGIN); + URL pluginSchemaURL = PluginMetadataParser.class.getClassLoader().getResource("rhq-plugin.xsd"); + Schema pluginSchema = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI).newSchema(pluginSchemaURL); + + Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); + ValidationEventCollector vec = new ValidationEventCollector(); + unmarshaller.setEventHandler(vec); + unmarshaller.setSchema(pluginSchema); + + StringReader reader = new StringReader(string); + + return (PluginDescriptor) unmarshaller.unmarshal(reader); + } + catch (Exception e) { + throw new RuntimeException(e); + } + } + + /** + * Searches for and returns the matching descriptor element (or elements) from the plugin + * descriptor. <code>path</code> should be an XPath-like expression. See + * http://commons.apache.org/jxpath/users-guide.html for more information on supported syntax. + * + * @param descriptor The plugin descriptor + * @param path The XPath-ish search expression + * @return The matching element or elements from the descriptor + */ + public static Object find(PluginDescriptor descriptor, String path) { + JXPathContext context = JXPathContext.newContext(descriptor); + return context.getValue(path); + } + + /** + * This method does a few things. It first searches the descriptor with the specified + * <code>path</code>. When a matching element is found, which is presumably either a + * {@link org.rhq.core.clientapi.descriptor.plugin.ServerDescriptor} or a + * {@link org.rhq.core.clientapi.descriptor.plugin.ServerDescriptor}, its plugin + * configuration is retrieved. It then gets parsed and the resulting + * {@link ConfigurationDefinition} is returned. + * + * @param descriptor The plugin descriptor + * @param path The XPath-ish expression that specifies the path to the element from which + * the plugin configuration should be loaded + * @param configName A name to give the configuration definition + * @return The parsed {@link ConfigurationDefinition} + */ + public static ConfigurationDefinition loadPluginConfigDefFor(PluginDescriptor descriptor, String path, + String configName) { + try { + ResourceDescriptor resourceDescriptor = (ResourceDescriptor) find(descriptor, path); + return ConfigurationMetadataParser.parse(configName, resourceDescriptor.getPluginConfiguration()); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + /** + * This method does a few things. It first searches the descriptor with the specified + * <code>path</code>. When a matching element is found, which is presumably either a + * {@link org.rhq.core.clientapi.descriptor.plugin.ServerDescriptor} or a + * {@link org.rhq.core.clientapi.descriptor.plugin.ServerDescriptor}, its resource + * configuration is retrieved. It then gets parsed and the resulting + * {@link ConfigurationDefinition} is returned. + * + * @param descriptor The plugin descriptor + * @param path The XPath-ish expression that specifies the path to the element from which + * the resource configuration should be loaded + * @param configName A name to give the configuration definition + * @return The parsed {@link ConfigurationDefinition} + */ + public static ConfigurationDefinition loadResourceConfigDefFor(PluginDescriptor descriptor, String path, + String configName) { + try { + ResourceDescriptor resourceDescriptor = (ResourceDescriptor) find(descriptor, path); + return ConfigurationMetadataParser.parse(configName, resourceDescriptor.getResourceConfiguration()); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + +} diff --git a/modules/core/client-api/pom.xml b/modules/core/client-api/pom.xml index 4617b45..80dda55 100644 --- a/modules/core/client-api/pom.xml +++ b/modules/core/client-api/pom.xml @@ -63,6 +63,13 @@ </dependency>
<dependency> + <groupId>${groupId}</groupId> + <artifactId>rhq-core-client-api-test-utils</artifactId> + <version>${version}</version> + <scope>test</scope> + </dependency> + + <dependency> <groupId>org.codehaus.groovy</groupId> <artifactId>groovy-all</artifactId> <scope>test</scope> diff --git a/modules/core/client-api/src/test/groovy/org/rhq/core/clientapi/agent/metadata/PluginMetadataParserTest.groovy b/modules/core/client-api/src/test/groovy/org/rhq/core/clientapi/agent/metadata/PluginMetadataParserTest.groovy index e5bf3c5..2b28537 100644 --- a/modules/core/client-api/src/test/groovy/org/rhq/core/clientapi/agent/metadata/PluginMetadataParserTest.groovy +++ b/modules/core/client-api/src/test/groovy/org/rhq/core/clientapi/agent/metadata/PluginMetadataParserTest.groovy @@ -31,6 +31,8 @@ import org.rhq.core.clientapi.descriptor.plugin.PluginDescriptor import org.testng.annotations.Test import org.rhq.core.domain.configuration.definition.ConfigurationFormat
+import static org.rhq.enterprise.server.configuration.metadata.PluginDescriptorUtil.toPluginDescriptor + class PluginMetadataParserTest {
@@ -374,19 +376,19 @@ class PluginMetadataParserTest {
}
- static PluginDescriptor toPluginDescriptor(String string) { - JAXBContext jaxbContext = JAXBContext.newInstance(DescriptorPackages.PC_PLUGIN) - URL pluginSchemaURL = PluginMetadataParser.class.getClassLoader().getResource("rhq-plugin.xsd") - Schema pluginSchema = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI).newSchema(pluginSchemaURL) - - Unmarshaller unmarshaller = jaxbContext.createUnmarshaller() - ValidationEventCollector vec = new ValidationEventCollector() - unmarshaller.setEventHandler(vec) - unmarshaller.setSchema(pluginSchema) - - StringReader reader = new StringReader(string) - - return (PluginDescriptor) unmarshaller.unmarshal(reader); - } +// static PluginDescriptor toPluginDescriptor(String string) { +// JAXBContext jaxbContext = JAXBContext.newInstance(DescriptorPackages.PC_PLUGIN) +// URL pluginSchemaURL = PluginMetadataParser.class.getClassLoader().getResource("rhq-plugin.xsd") +// Schema pluginSchema = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI).newSchema(pluginSchemaURL) +// +// Unmarshaller unmarshaller = jaxbContext.createUnmarshaller() +// ValidationEventCollector vec = new ValidationEventCollector() +// unmarshaller.setEventHandler(vec) +// unmarshaller.setSchema(pluginSchema) +// +// StringReader reader = new StringReader(string) +// +// return (PluginDescriptor) unmarshaller.unmarshal(reader); +// }
} diff --git a/modules/enterprise/server/jar/pom.xml b/modules/enterprise/server/jar/pom.xml index 060a8f6..123d42e 100644 --- a/modules/enterprise/server/jar/pom.xml +++ b/modules/enterprise/server/jar/pom.xml @@ -352,6 +352,13 @@ <!--================ Test Deps ================-->
<dependency> + <groupId>${groupId}</groupId> + <artifactId>rhq-core-client-api-test-utils</artifactId> + <version>${version}</version> + <scope>test</scope> + </dependency> + + <dependency> <groupId>jboss.jboss-embeddable-ejb3</groupId> <artifactId>jboss-ejb3-all</artifactId> <version>${jboss-embeddable-ejb3.version}</version> @@ -407,16 +414,25 @@ <artifactId>opencsv</artifactId> <version>1.8</version> <scope>test</scope> - </dependency> + </dependency>
<dependency> <groupId>org.rhq.helpers</groupId> <artifactId>perftest-support</artifactId> <version>${project.version}</version> <scope>test</scope> + <exclusions> + <exclusion> + <groupId>ant</groupId> + <artifactId>ant</artifactId> + </exclusion> + <exclusion> + <groupId>ant</groupId> + <artifactId>ant-launcher</artifactId> + </exclusion> + </exclusions> </dependency>
- <dependency> <groupId>commons-jxpath</groupId> <artifactId>commons-jxpath</artifactId> @@ -424,6 +440,12 @@ <scope>test</scope> </dependency>
+ <dependency> + <groupId>org.codehaus.groovy</groupId> + <artifactId>groovy-all</artifactId> + <scope>test</scope> + </dependency> + </dependencies>
<build> @@ -554,6 +576,19 @@ Build-OS-Version=${os.version} </executions> </plugin>
+ <plugin> + <groupId>org.codehaus.groovy.maven</groupId> + <artifactId>gmaven-plugin</artifactId> + <executions> + <execution> + <goals> + <goal>testCompile</goal> + </goals> + </execution> + </executions> + + </plugin> + </plugins> </build>
diff --git a/modules/enterprise/server/jar/src/test/groovy/org/rhq/enterprise/server/resource/metadata/ResourceMetadataManagerBeanTest.groovy b/modules/enterprise/server/jar/src/test/groovy/org/rhq/enterprise/server/resource/metadata/ResourceMetadataManagerBeanTest.groovy new file mode 100644 index 0000000..f7ea824 --- /dev/null +++ b/modules/enterprise/server/jar/src/test/groovy/org/rhq/enterprise/server/resource/metadata/ResourceMetadataManagerBeanTest.groovy @@ -0,0 +1,512 @@ +package org.rhq.enterprise.server.resource.metadata + +import org.testng.annotations.Test +import org.testng.Assert + +import static org.rhq.enterprise.server.configuration.metadata.PluginDescriptorUtil.toPluginDescriptor +import org.rhq.core.domain.plugin.Plugin +import org.rhq.core.clientapi.descriptor.plugin.PluginDescriptor +import org.apache.maven.artifact.versioning.ComparableVersion +import org.rhq.core.util.MessageDigestGenerator +import org.rhq.enterprise.server.test.AbstractEJB3Test +import org.rhq.enterprise.server.util.LookupUtil +import org.rhq.core.domain.resource.ResourceType +import org.rhq.test.AssertUtils +import org.rhq.core.domain.criteria.ResourceTypeCriteria +import org.rhq.core.domain.criteria.OperationDefinitionCriteria + +class ResourceMetadataManagerBeanTest extends AbstractEJB3Test { + + @Test(groups = ['NewPlugin']) + void registerPlugin() { + def pluginDescriptor = + """ + <plugin name="TestPlugin" displayName="Test Plugin" package="org.rhq.plugins.test" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns="urn:xmlns:rhq-plugin" + xmlns:c="urn:xmlns:rhq-configuration"> + <server name="ServerA" + description="Server A description" + class="org.rhq.plugins.test.ServerA" + discovery="org.rhq.plugins.test.ServerADiscoveryComponent"> + + <subcategories> + <subcategory name="Resources" description="Resources subcategory"/> + <subcategory name="Applications" description="Applications subcategory"/> + </subcategories> + + <plugin-configuration> + <c:simple-property name="connectionPropertyX" default="x"/> + <c:simple-property name="connectionPropertyY" default="y"/> + </plugin-configuration> + + <process-scan name="serverA" query="process|basename|match=^java.*,arg|org.jboss.Main|match=.*"/> + + <operation name="start"> + <parameters> + <c:simple-property name="immediate" type="boolean"/> + </parameters> + <results> + <c:simple-property name="exitCode" type="integer"/> + </results> + </operation> + + <operation name="stop"> + <parameters> + <c:simple-property name="immediate" type="boolean"/> + </parameters> + <results> + <c:simple-property name="exitCode" type="integer"/> + </results> + </operation> + + <metric displayName="Metric 1" property="metric1" displayType="summary" defaultInterval="300000"/> + <metric displayName="Metric 2" property="metric2" displayType="summary" defaultInterval="300000"/> + + <event name="logAEntry" description="an entry was appended to a log file"/> + <event name="logBEntry" description="an entry was appended to a log file"/> + + <service name="Child1" + description="Child 1 description" + class="org.rhq.plugins.test.Child1" + discovery="org.rhq.plugins.test.Child1ServiceDiscoveryComponent"/> + <service name="Child2" + description="Child 2 description" + class="org.rhq.plugins.test.Child2" + discovery="org.rhq.plugins.test.Child2ServiceDiscoveryComponent"/> + </server> + + <server name="ServerB" + description="Server B description" + class="org.rhq.plugins.test.ServerB" + discovery="org.rhq.plugins.test.ServerBDiscoveryComponent"/> + + <server name="ServerC" + description="Server C description" + class="org.rhq.plugins.test.ServerC" + discovery="org.rhq.plugins.test.ServerCDiscoveryComponent"> + + <operation name="run"> + <parameters> + <c:simple-property name="script"/> + </parameters> + <results> + <c:simple-property name="errors"/> + </results> + </operation> + + <event name="serverCEvent" description="an entry was appended to a log file"/> + </server> + </plugin> + """ + + def args = createPlugin("test-plugin", pluginDescriptor, "1.0") + Assert.assertNotNull args.plugin + Assert.assertNotNull args.pluginFile + Assert.assertNotNull args.pluginDescriptor + + def subjectMgr = LookupUtil.subjectManager + def resourceMetadataMgr = LookupUtil.resourceMetadataManager + + resourceMetadataMgr.registerPlugin(subjectMgr.overlord, args.plugin, args.pluginDescriptor, args.pluginFile, false) + } + + @Test(dependsOnMethods = ['registerPlugin'], groups = ['NewPlugin']) + void persistNewTypes() { + def newTypes = ['ServerA', 'ServerB'] + assertTypesPersisted "Failed to persist new types", newTypes, 'TestPlugin' + } + + @Test(dependsOnMethods = ['persistNewTypes'], groups = ['NewPlugin']) + void persistSubcategories() { + assertAssociationEquals( + 'ServerA', + 'subCategories', + ['Resources', 'Applications'] + ) + } + + @Test(dependsOnMethods = ['persistNewTypes'], groups = ['NewPlugin']) + void persistMeasurementDefinitions() { + assertAssociationEquals( + 'ServerA', + 'metricDefinitions', + ['metric1', 'metric2'] + ) + } + + @Test(dependsOnMethods = ['persistNewTypes'], groups = ['NewPlugin']) + void persistEventDefinitions() { + assertAssociationEquals( + 'ServerA', + 'eventDefinitions', + ['logAEntry', 'logBEntry'] + ) + } + + @Test(dependsOnMethods = ['persistNewTypes'], groups = ['NewPlugin']) + void persistOperationDefinitions() { + assertAssociationEquals( + 'ServerA', + 'operationDefinitions', + ['start', 'stop'] + ) + } + + @Test(dependsOnMethods = ['persistNewTypes'], groups = ['NewPlugin']) + void persistProcessScans() { + assertAssociationEquals( + 'ServerA', + 'processScans', + ['serverA'] + ) + } + + @Test(dependsOnMethods = ['persistNewTypes'], groups = ['NewPlugin']) + void persistChildTypes() { + assertAssociationEquals( + 'ServerA', + 'childResourceTypes', + ['Child1', 'Child2'] + ) + + @Test(dependsOnMethods = ['persistNewTypes'], groups = ['NewPlugin']) + void persistPluginConfigurationDefinition + assertAssociationExists('ServerA', 'pluginConfigurationDefinition') + } + + @Test(groups = ['UpgradePlugin'], dependsOnGroups = ['NewPlugin']) + void upgradePlugin() { + def pluginDescriptor = + """ + <plugin name="TestPlugin" displayName="Test Plugin" package="org.rhq.plugins.test" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns="urn:xmlns:rhq-plugin" + xmlns:c="urn:xmlns:rhq-configuration"> + <server name="ServerA" + description="Server A description" + class="org.rhq.plugins.test.ServerA" + discovery="org.rhq.plugins.test.ServerADiscoveryComponent"> + + <subcategories> + <subcategory name="Resources" description="Resources subcategory"/> + <subcategory name="Applications" description="Applications subcategory"/> + </subcategories> + + <plugin-configuration> + <c:simple-property name="connectionPropertyX" default="x"/> + <c:simple-property name="connectionPropertyY" default="y"/> + </plugin-configuration> + + <process-scan name="processA" query="process|basename|match=^java.*,arg|org.jboss.MainA|match=.*"/> + <process-scan name="processB" query="process|basename|match=^java.*,arg|org.jboss.MainB|match=.*"/> + + <operation name="start"> + <parameters> + <c:simple-property name="immediate" type="boolean"/> + </parameters> + <results> + <c:simple-property name="exitCode" type="integer"/> + </results> + </operation> + + <operation name="shutdown"> + <parameters> + <c:simple-property name="immediate" type="boolean"/> + </parameters> + <results> + <c:simple-property name="exitCode" type="integer"/> + </results> + </operation> + + <operation name="restart"> + <parameters> + <c:simple-property name="immediate" type="boolean"/> + </parameters> + <results> + <c:simple-property name="exitCode" type="integer"/> + </results> + </operation> + + <metric displayName="Metric 1" property="metric1" displayType="summary" defaultInterval="300000"/> + <metric displayName="Metric 2" property="metric2" displayType="summary" defaultInterval="300000"/> + + <event name="logAEntry" description="an entry was appended to a log file"/> + <event name="logCEntry" description="an entry was appended to a log file"/> + + <service name="Child1" + description="Child 1 description" + class="org.rhq.plugins.test.Child1" + discovery="org.rhq.plugins.test.Child1ServiceDiscoveryComponent"/> + + <service name="Child3" + description="Child 3 description" + class="org.rhq.plugins.test.Child3" + discovery="org.rhq.plugins.test.Child3ServiceDiscoveryComponent"/> + </server> + <server name="ServerB" + description="Server B description" + class="org.rhq.plugins.test.ServerB" + discovery="org.rhq.plugins.test.ServerBDiscoveryComponent"> + <service name="Child2" + description="Child 2 description" + class="org.rhq.plugins.test.Child2" + discovery="org.rhq.plugins.test.Child2ServiceDiscoveryComponent"/> + </server> + </plugin> + """ + + def args = createPlugin("test-plugin", pluginDescriptor, "2.0") + Assert.assertNotNull args.plugin + Assert.assertNotNull args.pluginFile + Assert.assertNotNull args.pluginDescriptor + + def subjectMgr = LookupUtil.subjectManager + def resourceMetadataMgr = LookupUtil.resourceMetadataManager + + resourceMetadataMgr.registerPlugin(subjectMgr.overlord, args.plugin, args.pluginDescriptor, args.pluginFile, true) + } + + @Test(dependsOnMethods = ['upgradePlugin'], groups = ['UpgradePlugin']) + void upgradeOperationDefinitions() { + assertAssociationEquals( + 'ServerA', + 'operationDefinitions', + ['start', 'shutdown', 'restart'] + ) + } + + @Test(dependsOnMethods = ['upgradePlugin'], groups = ['UpgradePlugin']) + void upgradeChildResources() { + assertAssociationEquals( + 'ServerA', + 'childResourceTypes', + ['Child1', 'Child3'] + ) + } + + @Test(dependsOnMethods = ['upgradePlugin'], groups = ['UpgradePlugin']) + void upgradeParentType() { + assertAssociationEquals( + 'ServerB', + 'childResourceTypes', + ['Child2'] + ) + } + + @Test(dependsOnMethods = ['upgradePlugin'], groups = ['UpgradePlugin']) + void upgradeEventDefinitions() { + assertAssociationEquals( + 'ServerA', + 'eventDefinitions', + ['logAEntry', 'logCEntry'] + ) + } + + @Test(dependsOnMethods = ['upgradePlugin'], groups = ['UpgradePlugin']) + void upgradeProcessScans() { + assertAssociationEquals( + 'ServerA', + 'processScans', + ['processA', 'processB'] + ) + } + + @Test(dependsOnMethods = ['upgradePlugin'], groups = ['UpgradePlugin']) + void deleteOperationDefsForRemovedType() { + def operationMgr = LookupUtil.operationManager + def subjectMgr = LookupUtil.subjectManager + + def criteria = new OperationDefinitionCriteria() + criteria.addFilterResourceTypeName 'ServerC' + criteria.addFilterName 'run' + + def operationDefs = operationMgr.findOperationDefinitionsByCriteria(subjectMgr.overlord, criteria) + + assertEquals "The operation definition should have been deleted", 0, operationDefs.size() + } + + @Test(dependsOnMethods = ['upgradePlugin'], groups = ['UpgradePlugin']) + void deleteEventDefsForRemovedType() { + def results = entityManager.createQuery( + "from EventDefinition e where e.name = :ename and e.resourceType.name = :rname") + .setParameter("ename", "serverCEvent") + .setParameter("rname", "ServerC") + .getResultList() + + assertEquals "The event definition(s) should have been deleted", 0, results.size() + } + + def buildPlugin(String pluginFileName, String version, String descriptor) { + def args = createPlugin("test-plugin", pluginDescriptor, "2.0") + Assert.assertNotNull args.plugin + Assert.assertNotNull args.pluginFile + Assert.assertNotNull args.pluginDescriptor + + def subjectMgr = LookupUtil.subjectManager + def resourceMetadataMgr = LookupUtil.resourceMetadataManager + + resourceMetadataMgr.registerPlugin(subjectMgr.overlord, args.plugin, args.pluginDescriptor, args.pluginFile, true) + } + + /** + * This method creates the plugin-related artifacts that are need to call + * ResourceMetadataManager.registerPlugin. It creates the PluginDescriptor object, and + * then it generates the plugin jar file. Lastly, the Plugin object is created. A map + * is returned containing these generated artifacts. The map keys are pluginDescriptor, + * pluginFile, and plugin. + * + * @param pluginFileName The name to give the generated plugin file. This should not + * include the file extension, i.e., the '.jar' + * + * @param descriptor The plugin descriptor as a string + * + * @param version The plugin version which will be the version stored in MANIFEST.MF + * + * @return A map containing the generated artifacts. The maps keys are pluginDescriptor, + * pluginFile, and plugin + */ + def createPlugin(String pluginFileName, String descriptor, String version) { + def pluginDescriptor = toPluginDescriptor(descriptor) + def pluginFilePath = "$currentWorkingDir/${pluginFileName}.jar" + + def ant = new AntBuilder() + ant.delete(dir: "$pluginWorkDir") + ant.delete(file: pluginFilePath) + + ant.mkdir(dir: "$pluginWorkDir/META-INF") + new File("$pluginWorkDir/META-INF/rhq-plugin.xml").text = descriptor + ant.jar(destfile: "$currentWorkingDir/${pluginFileName}.jar", basedir: "$pluginWorkDir") { + manifest { + attribute(name: "Specification-Version", value: version) + attribute(name: "Implementation-Version", value: version) + } + } + + def pluginFile = new File(pluginFilePath) + + def plugin = new Plugin(pluginDescriptor.name, pluginFilePath) + plugin.displayName = pluginDescriptor.name + plugin.enabled = true + plugin.description = pluginDescriptor.description + plugin.ampsVersion = getAmpsVersion(pluginDescriptor) + plugin.version = pluginDescriptor.version + plugin.MD5 = MessageDigestGenerator.getDigestString(pluginFile) + + return [pluginDescriptor: pluginDescriptor, pluginFile: pluginFile, plugin: plugin] + } + + String getPluginWorkDir() { + "${currentWorkingDir}/work" + } + + String getCurrentWorkingDir() { + getClass().getResource(".").toURI().path + } + + String getAmpsVersion(PluginDescriptor pluginDescriptor) { + if (pluginDescriptor.ampsVersion == null) { + return "2.0" + } + + ComparableVersion version = new ComparableVersion(pluginDescriptor.ampsVersion) + ComparableVersion version2 = new ComparableVersion("2.0") + + if (version.compareTo(version2) <= 0) { + return "2.0" + } + + return pluginDescriptor.ampsVersion + } + + void assertTypesPersisted(msg, types, plugin) { + def typesNotFound = [] + def resourceTypeMgr = LookupUtil.resourceTypeManager + + types.each { + if (resourceTypeMgr.getResourceTypeByNameAndPlugin(it, plugin) == null) { + typesNotFound << it + } + } + + if (typesNotFound.size() > 0) { + fail "$msg: The following types were not found: $typesNotFound" + } + } + + /** + * This custom assertion looks up the specified resource type and then looks at the value + * of the specified property name which is assumed to be a collection. It is also assumed + * that each element in the collection has a name property, and it is the value of the name + * property that is compared against the expected values. + * + * This method fails if either any of the expected names is not found or if one of the + * actual names does not exist in the expected list. + * + * @param resourceTypeName The resource type to look up + * @param propertyName The name of the property to be inspected + * @param expected A list of names expected to be found in each of the elements of the property + */ + void assertAssociationEquals(String resourceTypeName, String propertyName, List expected) { + def subjectMgr = LookupUtil.subjectManager + def resourceTypeMgr = LookupUtil.resourceTypeManager + + def fetch = "fetch${propertyName.capitalize()}" + def criteria = new ResourceTypeCriteria() + criteria.addFilterName resourceTypeName + criteria.addFilterPluginName 'TestPlugin' + criteria."$fetch" true + + def resourceTypes = resourceTypeMgr.findResourceTypesByCriteria(subjectMgr.overlord, criteria) + def resourceType = resourceTypes[0] + def expectedSet = expected as Set + def missing = [] + def unexpected = [] + + expectedSet.each { expectedProperty -> + if (resourceType[propertyName].find { it.name == expectedProperty } == null) { + missing << it + } + } + + resourceType[propertyName].each { actualProperty -> + if (expectedSet.find { it == actualProperty.name } == null) { + unexpected << actualProperty.name + } + } + + def errors = "" + if (missing.size() > 0) { + errors = "Failed to find the following $propertyName(s) for type '$resourceTypeName': $missing" + } + if (unexpected.size() > 0) { + errors += "\n The following $propertyName(s) were found but not expected for type '$resourceTypeName': $unexpected" + } + + assertTrue(errors, errors.length() == 0) + } + + void assertAssociationExists(String resourceTypeName, String propertyName) { + def subjectMgr = LookupUtil.subjectManager + def resourceTypeMgr = LookupUtil.resourceTypeManager + + def fetch = "fetch${propertyName.capitalize()}" + def criteria = new ResourceTypeCriteria() + criteria.addFilterName resourceTypeName + criteria.addFilterPluginName 'TestPlugin' + criteria."$fetch" true + + def resourceTypes = resourceTypeMgr.findResourceTypesByCriteria(subjectMgr.overlord, criteria) + def resourceType = resourceTypes[0] + + assertNotNull("Failed to find $propertyName for type '$resourceTypeName'", resourceType[propertyName]) + } + + void assertResourceTypeEquals(String msg, ResourceType expected, ResourceType actual) { + AssertUtils.assertPropertiesMatch(msg, expected, actual, "childResourceTypes", "parentResourceTypes", + "pluginConfigurationDefinition", "resourceConfigurationDefinition", "subCategory", "metricDefinitions", + "eventDefinitions", "operationDefinitions", "processScans", "packageTypes", "resources", "resourceGroups", + "productVersions", "bundleType", "childSubCategories", "helpText", "classLoaderType") + } + +} diff --git a/pom.xml b/pom.xml index f95c754..cd3f6ab 100644 --- a/pom.xml +++ b/pom.xml @@ -406,7 +406,7 @@ <dependency> <groupId>org.codehaus.groovy</groupId> <artifactId>groovy-all</artifactId> - <version>1.6.0</version> + <version>1.7.5</version> </dependency>
<dependency>