modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/resource/metadata/MetadataBeanTest.java
| 73 +++
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/resource/metadata/PluginScanningExtensionMetadataTest.java
| 224 ++++++++++
modules/enterprise/server/jar/src/test/resources/org/rhq/enterprise/server/resource/metadata/PluginScanningExtensionMetadataTest/child1_plugin_v1.xml
| 19
modules/enterprise/server/jar/src/test/resources/org/rhq/enterprise/server/resource/metadata/PluginScanningExtensionMetadataTest/child2_plugin_v1.xml
| 19
modules/enterprise/server/jar/src/test/resources/org/rhq/enterprise/server/resource/metadata/PluginScanningExtensionMetadataTest/parent_plugin_v1.xml
| 18
modules/enterprise/server/jar/src/test/resources/org/rhq/enterprise/server/resource/metadata/PluginScanningExtensionMetadataTest/parent_plugin_v2.xml
| 18
6 files changed, 368 insertions(+), 3 deletions(-)
New commits:
commit 0828271307406c60c1c4da9a529dc02228be427c
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Tue Feb 28 10:09:50 2012 -0500
[BZ 747925] add more tests that simulate what the server does when it scans/registers
plugins. this uses the actual scanner and deployer classes that the server does
diff --git
a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/resource/metadata/MetadataBeanTest.java
b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/resource/metadata/MetadataBeanTest.java
index c93dd1f..bade273 100644
---
a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/resource/metadata/MetadataBeanTest.java
+++
b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/resource/metadata/MetadataBeanTest.java
@@ -3,6 +3,8 @@ package org.rhq.enterprise.server.resource.metadata;
import static org.rhq.core.clientapi.shared.PluginDescriptorUtil.loadPluginDescriptor;
import java.io.File;
+import java.io.FileOutputStream;
+import java.io.InputStream;
import java.net.URL;
import java.sql.Connection;
import java.util.ArrayList;
@@ -10,6 +12,8 @@ import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
+import java.util.jar.JarEntry;
+import java.util.jar.JarOutputStream;
import org.apache.commons.beanutils.MethodUtils;
import org.apache.commons.beanutils.PropertyUtils;
@@ -36,6 +40,7 @@ import org.rhq.core.domain.criteria.ResourceTypeCriteria;
import org.rhq.core.domain.plugin.Plugin;
import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.util.MessageDigestGenerator;
+import org.rhq.core.util.stream.StreamUtil;
import org.rhq.enterprise.server.auth.SubjectManagerLocal;
import org.rhq.enterprise.server.bundle.TestBundleServerPluginService;
import org.rhq.enterprise.server.resource.ResourceTypeManagerLocal;
@@ -168,12 +173,11 @@ public class MetadataBeanTest extends AbstractEJB3Test {
return getClass().getResource(dir + "/" + descriptor);
}
- @SuppressWarnings("unused")
- private String getPluginWorkDir() throws Exception {
+ protected String getPluginWorkDir() throws Exception {
return getCurrentWorkingDir() + "/work";
}
- private String getCurrentWorkingDir() throws Exception {
+ protected String getCurrentWorkingDir() throws Exception {
return getClass().getResource(".").toURI().getPath();
}
@@ -250,4 +254,67 @@ public class MetadataBeanTest extends AbstractEJB3Test {
}
return false;
}
+
+ /**
+ * This actually creates a .jar file on the file system but doesn't register it.
+ *
+ * @param jarName the name to be given to the new jar file
+ * @param descriptorXmlFilename where the descriptor XML can be found on the test
classloader
+ * @return the location of the new jar file
+ * @throws Exception
+ */
+ protected File createPluginJarFile(String jarName, String descriptorXmlFilename)
throws Exception {
+ FileOutputStream stream = null;
+ JarOutputStream out = null;
+ InputStream in = null;
+
+ try {
+ String pluginDirPath = getPluginWorkDir();
+ File pluginDir = new File(pluginDirPath);
+ pluginDir.mkdirs();
+ File jarFile = new File(pluginDir, jarName);
+ jarFile.delete(); // in case some older file is hanging around, get rid of
it
+ stream = new FileOutputStream(jarFile);
+ out = new JarOutputStream(stream);
+
+ // Add archive entry for the descriptor
+ JarEntry jarAdd = new JarEntry("META-INF/rhq-plugin.xml");
+ jarAdd.setTime(System.currentTimeMillis());
+ out.putNextEntry(jarAdd);
+
+ // Write the descriptor - note that we assume the xml file is in the test
classloader
+ URL descriptorURL = getDescriptorURL(descriptorXmlFilename);
+ in = descriptorURL.openStream();
+ StreamUtil.copy(in, out, false);
+
+ return jarFile;
+ } finally {
+ if (in != null) {
+ in.close();
+ }
+ if (out != null) {
+ out.close();
+ }
+ if (stream != null) {
+ stream.close();
+ }
+ }
+ }
+
+ /**
+ * Tests can use this to let us know that a plugin has been deployed and needs to
+ * be cleaned up/removed at the end of the test.
+ *
+ * @param pluginName
+ */
+ protected void pluginDeployed(String pluginName) {
+ try {
+ PluginManagerLocal pluginMgr = LookupUtil.getPluginManager();
+ Plugin plugin = pluginMgr.getPlugin(pluginName);
+ if (plugin != null) {
+ this.pluginIds.add(plugin.getId());
+ }
+ } catch (Exception ignore) {
+ }
+ }
}
diff --git
a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/resource/metadata/PluginScanningExtensionMetadataTest.java
b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/resource/metadata/PluginScanningExtensionMetadataTest.java
new file mode 100644
index 0000000..a8a652d
--- /dev/null
+++
b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/resource/metadata/PluginScanningExtensionMetadataTest.java
@@ -0,0 +1,224 @@
+package org.rhq.enterprise.server.resource.metadata;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import org.rhq.core.domain.criteria.ResourceTypeCriteria;
+import org.rhq.core.domain.operation.OperationDefinition;
+import org.rhq.core.domain.resource.ResourceType;
+import org.rhq.enterprise.server.auth.SubjectManagerLocal;
+import org.rhq.enterprise.server.core.plugin.PluginDeploymentScanner;
+import org.rhq.enterprise.server.resource.ResourceTypeManagerLocal;
+import org.rhq.enterprise.server.util.LookupUtil;
+
+/**
+ * This test shows a plugin extended multiple times via the embedded extension model,
+ * but it tests starting with the server's plugin scanner service. This helps
+ * simulate more closely the full end-to-end agent plugin scanning and deployment
+ * mechanism during which resource types are registered.
+ *
+ * There is one parent plugin and two child plugins. This test makes sure multiple
+ * plugins can extend and be updated; it won't test a full comprehensive set of
+ * metadata being upgraded. See {@link PluginExtensionMetadataTest} for a
+ * comprehensive test showing all the different kinds of metadata being updated.
+ *
+ * @author John Mazzitelli
+ */
+@Test(groups = { "plugin.extension.scanning.metadata",
"plugin.metadata" })
+public class PluginScanningExtensionMetadataTest extends MetadataBeanTest {
+
+ private static final String PLUGIN_NAME_PARENT =
"PluginScanningExtensionMetadataParentTestPlugin";
+ private static final String PLUGIN_NAME_CHILD1 =
"PluginScanningExtensionMetadataChild1TestPlugin";
+ private static final String PLUGIN_NAME_CHILD2 =
"PluginScanningExtensionMetadataChild2TestPlugin";
+ private static final String TYPE_NAME_PARENT = "ParentServerA";
+ private static final String TYPE_NAME_CHILD1 = "Child1ServerA";
+ private static final String TYPE_NAME_CHILD2 = "Child2ServerA";
+
+ // names of things from the first version of the plugin metadata
+ private static final String OP_NAME = "A-op";
+ private static final int OP_TIMEOUT = 123456;
+ private static final String OP_DESC = "a op";
+
+ // names of things from the second, updated version of the plugin metadata
+ // updated operations
+ private static final String NEW_OP_NAME = "A-op-NEW";
+ private static final int NEW_OP_TIMEOUT = 987654;
+ private static final String NEW_OP_DESC = "a new op";
+
+ private SubjectManagerLocal subjectMgr;
+ private ResourceTypeManagerLocal resourceTypeMgr;
+
+ private List<File> createdJarFiles = new ArrayList<File>();
+ private PluginDeploymentScanner pluginScanner;
+
+ @BeforeMethod
+ public void prepareBeforeTestMethod() {
+ subjectMgr = LookupUtil.getSubjectManager();
+ resourceTypeMgr = LookupUtil.getResourceTypeManager();
+
+ // clean up any old previously generated jar files so they don't get in the
way
+ if (!createdJarFiles.isEmpty()) {
+ for (File doomed : createdJarFiles) {
+ doomed.delete();
+ }
+ }
+ createdJarFiles.clear();
+ }
+
+ @AfterMethod(alwaysRun = true)
+ public void cleanUpAfterTestMethod() {
+ // clean up any generated jar files - we want to remove these so they don't
get in the way of a future test run
+ if (!createdJarFiles.isEmpty()) {
+ for (File doomed : createdJarFiles) {
+ doomed.delete();
+ }
+ }
+ createdJarFiles.clear();
+ }
+
+ @Override
+ @Test(enabled = false)
+ // this method isn't a test method
+ public void preparePluginScannerService() {
+ if (this.pluginScanner == null) {
+ this.pluginScanner = new PluginDeploymentScanner();
+
+ String pluginDirPath = null;
+ try {
+ pluginDirPath = getPluginWorkDir();
+ } catch (Exception e) {
+ throw new RuntimeException("Cannot determine where to put the plugin
jar files", e);
+ }
+ this.pluginScanner.setAgentPluginDir(new File(pluginDirPath)); // we
don't want to scan for these
+ this.pluginScanner.setServerPluginDir(null); // we don't want to scan for
these
+ this.pluginScanner.setScanPeriod(9999999L); // we want to manually scan -
don't allow for auto-scan to happen
+ }
+ super.preparePluginScannerService(this.pluginScanner);
+
+ try {
+ this.pluginScanner.start();
+ } catch (Exception e) {
+ throw new RuntimeException(e); // should never really happen
+ }
+
+ }
+
+ public void testRegisterPlugins() throws Exception {
+ try {
+ registerParentPluginV1(); // create an initial type (called the parent)
+ registerChild1PluginV1(); // using plugin extension mechanism, create child
#1 type that extends that parent type
+ registerChild2PluginV1(); // using plugin extension mechanism, create child
#2 type that extends that parent type
+ registerParentPluginV2(); // update the parent type
+ checkChild1Plugin(); // check that the changes to the parent type propogated
to the child #1
+ checkChild2Plugin(); // check that the changes to the parent type propogated
to the child #2
+ } finally {
+ // let our superclass know about our plugins so it can clean them up
+ pluginDeployed(PLUGIN_NAME_PARENT);
+ pluginDeployed(PLUGIN_NAME_CHILD1);
+ pluginDeployed(PLUGIN_NAME_CHILD2);
+ }
+ }
+
+ private void registerParentPluginV1() throws Exception {
+ // register the plugin, load the new type and test to make sure its what we
expect
+ createdJarFiles.add(createPluginJarFile("parent-plugin.jar",
"parent_plugin_v1.xml"));
+ this.pluginScanner.startDeployment(); // first time we need to scan so call
startDeployment which will call scanAndRegister
+ ResourceType resourceType = loadResourceTypeFully(TYPE_NAME_PARENT,
PLUGIN_NAME_PARENT);
+ assert resourceType.getName().equals(TYPE_NAME_PARENT);
+ assert resourceType.getPlugin().equals(PLUGIN_NAME_PARENT);
+ assertVersion1(resourceType);
+ }
+
+ private void registerChild1PluginV1() throws Exception {
+ // register the plugin, load the new type and test to make sure its what we
expect
+ createdJarFiles.add(createPluginJarFile("child1-plugin.jar",
"child1_plugin_v1.xml"));
+ this.pluginScanner.scanAndRegister();
+ ResourceType resourceType = loadResourceTypeFully(TYPE_NAME_CHILD1,
PLUGIN_NAME_CHILD1);
+ assert resourceType.getName().equals(TYPE_NAME_CHILD1);
+ assert resourceType.getPlugin().equals(PLUGIN_NAME_CHILD1);
+ assertVersion1(resourceType);
+
+ // in our child #1 plugin, our extended type is actually a child of child #1
plugin's root type
+ // here we want to make sure that hierarchy remains intact with our extended type
- the parent
+ // of our extended type should be this child #1 root type
+ assert resourceType.getParentResourceTypes() != null;
+ assert resourceType.getParentResourceTypes().size() == 1;
+ assert
resourceType.getParentResourceTypes().iterator().next().getName().equals("OuterServerA");
+ }
+
+ private void registerChild2PluginV1() throws Exception {
+ // register the plugin, load the new type and test to make sure its what we
expect
+ createdJarFiles.add(createPluginJarFile("child2-plugin.jar",
"child2_plugin_v1.xml"));
+ this.pluginScanner.scanAndRegister();
+ ResourceType resourceType = loadResourceTypeFully(TYPE_NAME_CHILD2,
PLUGIN_NAME_CHILD2);
+ assert resourceType.getName().equals(TYPE_NAME_CHILD2);
+ assert resourceType.getPlugin().equals(PLUGIN_NAME_CHILD2);
+ assertVersion1(resourceType);
+ }
+
+ private void registerParentPluginV2() throws Exception {
+ // register the plugin, load the new type and test to make sure its what we
expect
+ createdJarFiles.add(createPluginJarFile("parent-plugin.jar",
"parent_plugin_v2.xml"));
+ this.pluginScanner.scanAndRegister();
+ ResourceType resourceType = loadResourceTypeFully(TYPE_NAME_PARENT,
PLUGIN_NAME_PARENT);
+ assert resourceType.getName().equals(TYPE_NAME_PARENT);
+ assert resourceType.getPlugin().equals(PLUGIN_NAME_PARENT);
+ assertVersion2(resourceType);
+ }
+
+ private void checkChild1Plugin() throws Exception {
+ // load the child #1 type and test to make sure it has been updated to what we
expect
+ ResourceType resourceType = loadResourceTypeFully(TYPE_NAME_CHILD1,
PLUGIN_NAME_CHILD1);
+ assert resourceType.getName().equals(TYPE_NAME_CHILD1);
+ assert resourceType.getPlugin().equals(PLUGIN_NAME_CHILD1);
+ assertVersion2(resourceType);
+
+ // in our child #1 plugin, our extended type is actually a child of child #1
plugin's root type
+ // here we want to make sure that hierarchy remains intact with our extended type
- the parent
+ // of our extended type should be this child #1 root type
+ assert resourceType.getParentResourceTypes() != null;
+ assert resourceType.getParentResourceTypes().size() == 1;
+ assert
resourceType.getParentResourceTypes().iterator().next().getName().equals("OuterServerA");
+ }
+
+ private void checkChild2Plugin() throws Exception {
+ // load the child #2 type and test to make sure it has been updated to what we
expect
+ ResourceType resourceType = loadResourceTypeFully(TYPE_NAME_CHILD2,
PLUGIN_NAME_CHILD2);
+ assert resourceType.getName().equals(TYPE_NAME_CHILD2);
+ assert resourceType.getPlugin().equals(PLUGIN_NAME_CHILD2);
+ assertVersion2(resourceType);
+ }
+
+ private void assertVersion1(ResourceType resourceType) {
+ assert resourceType.getOperationDefinitions().size() == 1;
+ OperationDefinition op =
resourceType.getOperationDefinitions().iterator().next();
+ assert op.getName().equals(OP_NAME);
+ assert op.getTimeout().intValue() == OP_TIMEOUT;
+ assert op.getDescription().equals(OP_DESC);
+ }
+
+ private void assertVersion2(ResourceType resourceType) {
+ assert resourceType.getOperationDefinitions().size() == 1;
+ OperationDefinition op =
resourceType.getOperationDefinitions().iterator().next();
+ assert op.getName().equals(NEW_OP_NAME);
+ assert op.getTimeout().intValue() == NEW_OP_TIMEOUT;
+ assert op.getDescription().equals(NEW_OP_DESC);
+ }
+
+ private ResourceType loadResourceTypeFully(String typeName, String typePlugin) {
+ ResourceTypeCriteria c = new ResourceTypeCriteria();
+ c.addFilterName(typeName);
+ c.addFilterPluginName(typePlugin);
+ c.setStrict(true);
+ c.fetchParentResourceTypes(true);
+ c.fetchOperationDefinitions(true);
+ List<ResourceType> t =
resourceTypeMgr.findResourceTypesByCriteria(subjectMgr.getOverlord(), c);
+ ResourceType resourceType = t.get(0);
+ return resourceType;
+ }
+}
diff --git
a/modules/enterprise/server/jar/src/test/resources/org/rhq/enterprise/server/resource/metadata/PluginScanningExtensionMetadataTest/child1_plugin_v1.xml
b/modules/enterprise/server/jar/src/test/resources/org/rhq/enterprise/server/resource/metadata/PluginScanningExtensionMetadataTest/child1_plugin_v1.xml
new file mode 100644
index 0000000..e006bc9
--- /dev/null
+++
b/modules/enterprise/server/jar/src/test/resources/org/rhq/enterprise/server/resource/metadata/PluginScanningExtensionMetadataTest/child1_plugin_v1.xml
@@ -0,0 +1,19 @@
+<plugin name="PluginScanningExtensionMetadataChild1TestPlugin"
+ version="1.0"
+ displayName="Plugin Scanning Extension Metadata Child 1 Test Plugin"
+ package="org.rhq.plugins.test.child1"
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="urn:xmlns:rhq-plugin"
+ xmlns:c="urn:xmlns:rhq-configuration">
+
+ <server name="OuterServerA">
+ <server name="Child1ServerA"
+ description="Child 1 Server type that extends Parent Server
type"
+ discovery="Child1DiscoveryComponent"
+ class="Child1Component"
+ sourcePlugin="PluginScanningExtensionMetadataParentTestPlugin"
+ sourceType="ParentServerA">
+ </server>
+ </server>
+
+</plugin>
\ No newline at end of file
diff --git
a/modules/enterprise/server/jar/src/test/resources/org/rhq/enterprise/server/resource/metadata/PluginScanningExtensionMetadataTest/child2_plugin_v1.xml
b/modules/enterprise/server/jar/src/test/resources/org/rhq/enterprise/server/resource/metadata/PluginScanningExtensionMetadataTest/child2_plugin_v1.xml
new file mode 100644
index 0000000..18436bc
--- /dev/null
+++
b/modules/enterprise/server/jar/src/test/resources/org/rhq/enterprise/server/resource/metadata/PluginScanningExtensionMetadataTest/child2_plugin_v1.xml
@@ -0,0 +1,19 @@
+<plugin name="PluginScanningExtensionMetadataChild2TestPlugin"
+ version="1.0"
+ displayName="Plugin Scanning Extension Metadata Child 2 Test Plugin"
+ package="org.rhq.plugins.test.child2"
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="urn:xmlns:rhq-plugin"
+ xmlns:c="urn:xmlns:rhq-configuration">
+
+
+ <server name="Child2ServerA"
+ description="Child 2 Server type that extends Parent Server
type"
+ discovery="Child2DiscoveryComponent"
+ class="Child2Component"
+ sourcePlugin="PluginScanningExtensionMetadataParentTestPlugin"
+ sourceType="ParentServerA">
+ </server>
+
+
+</plugin>
\ No newline at end of file
diff --git
a/modules/enterprise/server/jar/src/test/resources/org/rhq/enterprise/server/resource/metadata/PluginScanningExtensionMetadataTest/parent_plugin_v1.xml
b/modules/enterprise/server/jar/src/test/resources/org/rhq/enterprise/server/resource/metadata/PluginScanningExtensionMetadataTest/parent_plugin_v1.xml
new file mode 100644
index 0000000..1622baa
--- /dev/null
+++
b/modules/enterprise/server/jar/src/test/resources/org/rhq/enterprise/server/resource/metadata/PluginScanningExtensionMetadataTest/parent_plugin_v1.xml
@@ -0,0 +1,18 @@
+<plugin name="PluginScanningExtensionMetadataParentTestPlugin"
+ version="1.0"
+ displayName="Plugin Scanning Extension Metadata Parent Test Plugin"
+ package="org.rhq.plugins.test.parent"
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="urn:xmlns:rhq-plugin"
+ xmlns:c="urn:xmlns:rhq-configuration">
+
+ <server name="ParentServerA"
+ description="Parent Server type that can be extended by a Child Server
type"
+ discovery="ParentDiscoveryComponent"
+ class="ParentComponent">
+
+ <operation name="A-op" timeout="123456"
description="a op"></operation>
+
+ </server>
+
+</plugin>
\ No newline at end of file
diff --git
a/modules/enterprise/server/jar/src/test/resources/org/rhq/enterprise/server/resource/metadata/PluginScanningExtensionMetadataTest/parent_plugin_v2.xml
b/modules/enterprise/server/jar/src/test/resources/org/rhq/enterprise/server/resource/metadata/PluginScanningExtensionMetadataTest/parent_plugin_v2.xml
new file mode 100644
index 0000000..b119590
--- /dev/null
+++
b/modules/enterprise/server/jar/src/test/resources/org/rhq/enterprise/server/resource/metadata/PluginScanningExtensionMetadataTest/parent_plugin_v2.xml
@@ -0,0 +1,18 @@
+<plugin name="PluginScanningExtensionMetadataParentTestPlugin"
+ version="2.0"
+ displayName="Plugin Scanning Extension Metadata Parent Test Plugin"
+ package="org.rhq.plugins.test.parent"
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="urn:xmlns:rhq-plugin"
+ xmlns:c="urn:xmlns:rhq-configuration">
+
+ <server name="ParentServerA"
+ description="Parent Server type that can be extended by a Child Server
type"
+ discovery="ParentDiscoveryComponent"
+ class="ParentComponent">
+
+ <operation name="A-op-NEW" timeout="987654"
description="a new op"></operation>
+
+ </server>
+
+</plugin>
\ No newline at end of file