modules/core/domain/src/main/java/org/rhq/core/domain/drift/DriftDefinition.java | 18 modules/core/domain/src/main/java/org/rhq/core/domain/drift/JPADrift.java | 10 modules/enterprise/server/itests-2/pom.xml | 39 modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/TestServerPluginService.java | 148 + modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/TestServerPluginServiceMBean.java | 31 modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/alert/AlertDefinitionWithComplexNotificationsTest.java | 1433 ++++++++++ modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/alert/TestAlertSender.java | 107 modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/alert/TestAlertSenderPluginService.java | 67 modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/content/test/AdvisoryManagerBeanTest.java | 10 modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/drift/AbstractDriftServerTest.java | 264 + modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/drift/DriftServerPluginService.java | 63 modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/drift/DriftTemplateManagerBeanTest.java | 653 ++++ modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/drift/InitDB.java | 32 modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/drift/JPADriftServerBeanTest.java | 308 ++ modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/drift/ManageDriftDefinitionsTest.java | 338 ++ modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/drift/ManageSnapshotsTest.java | 275 + modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/measurement/test/AbstractMeasurementScheduleManagerTest.java | 15 modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/measurement/test/MeasurementScheduleManagerTest.java | 12 modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/test/AbstractEJB3Test.java | 163 - modules/enterprise/server/itests-2/src/test/resources/test-alert-sender-serverplugin.xml | 23 modules/enterprise/server/itests/src/test/java/org/rhq/enterprise/server/TestServerPluginService.java | 148 - modules/enterprise/server/itests/src/test/java/org/rhq/enterprise/server/TestServerPluginServiceMBean.java | 31 modules/enterprise/server/itests/src/test/java/org/rhq/enterprise/server/alert/AlertDefinitionWithComplexNotificationsTest.java | 712 ---- modules/enterprise/server/itests/src/test/java/org/rhq/enterprise/server/alert/TestAlertSender.java | 107 modules/enterprise/server/itests/src/test/java/org/rhq/enterprise/server/alert/TestAlertSenderPluginService.java | 67 modules/enterprise/server/itests/src/test/java/org/rhq/enterprise/server/drift/AbstractDriftServerTest.java | 238 - modules/enterprise/server/itests/src/test/java/org/rhq/enterprise/server/drift/DriftServerPluginService.java | 63 modules/enterprise/server/itests/src/test/java/org/rhq/enterprise/server/drift/DriftTemplateManagerBeanTest.java | 614 ---- modules/enterprise/server/itests/src/test/java/org/rhq/enterprise/server/drift/InitDB.java | 32 modules/enterprise/server/itests/src/test/java/org/rhq/enterprise/server/drift/JPADriftServerBeanTest.java | 311 -- modules/enterprise/server/itests/src/test/java/org/rhq/enterprise/server/drift/ManageDriftDefinitionsTest.java | 326 -- modules/enterprise/server/itests/src/test/java/org/rhq/enterprise/server/drift/ManageSnapshotsTest.java | 276 - 32 files changed, 3913 insertions(+), 3021 deletions(-)
New commits: commit 7ae9ffe028baf2cf98b6c49cd7920a41c5751231 Author: Jay Shaughnessy jshaughn@jshaughn.csb Date: Mon Nov 5 10:46:23 2012 -0500
- Migrate drift tests and AlertSender tests from server/itests to server/itests-2. This merges them with the other former server jar unit tests that are now arquillian based integration tests. And consolidates itests based on AbstractEJB3Test. - Convert AlertSender test structure to one big test to get around the current @BeforeClass and shared instance var issues with Arquillian and the testng lifdecycle. - Add SystemProperties section to standalone.xml, making project.version property available to test code. - Add support for prepareTestAgents in the new infra - add support for BeforeMethod overrides offering up the Method param
-
diff --git a/modules/enterprise/server/itests-2/pom.xml b/modules/enterprise/server/itests-2/pom.xml index c2fa2b1..e9c7f44 100644 --- a/modules/enterprise/server/itests-2/pom.xml +++ b/modules/enterprise/server/itests-2/pom.xml @@ -121,6 +121,13 @@
<dependency> <groupId>${project.groupId}</groupId> + <artifactId>rhq-serverplugin-drift</artifactId> + <version>${project.version}</version> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>${project.groupId}</groupId> <artifactId>rhq-core-client-api</artifactId> <version>${project.version}</version> <type>test-jar</type> @@ -400,7 +407,7 @@ </executions> </plugin> --> - + <plugin> <artifactId>maven-antrun-plugin</artifactId> <executions> @@ -409,7 +416,7 @@ <id>prepare AS container</id> <phase>process-test-resources</phase> <configuration> - <target> + <target> <echo>Unzipping JBossAS ${jboss.version} found at ${jboss.zip}</echo> <unzip src="${jboss.zip}" @@ -420,7 +427,18 @@ location="${jboss.unzip.location}/standalone/configuration/standalone.xml" /> <echo>Will now add test configuration to JBossAS config file: ${jboss.conf}</echo> <replace file="${jboss.conf}"> - + + <replacefilter> + <replacetoken></extensions></replacetoken> + <replacevalue><![CDATA[ + </extensions> + + <!-- FOR RHQ TESTING --> + <system-properties> + <property name="project.version" value="${project.version}"/> + </system-properties>]]></replacevalue> + </replacefilter> + <replacefilter> <replacetoken></security-domains></replacetoken> <replacevalue><![CDATA[ @@ -433,9 +451,9 @@ </login-module> </authentication> </security-domain> - </security-domains>]]></replacevalue> + </security-domains>]]></replacevalue> </replacefilter> - + <replacefilter> <replacetoken></session-bean></replacetoken> <replacevalue><![CDATA[ @@ -454,7 +472,7 @@ <extension module="org.jboss.as.messaging"/> <extension module="org.jboss.as.naming"/>]]></replacevalue> </replacefilter> - + <replacefilter> <replacetoken><socket-binding name="https" port="8443"/></replacetoken> <replacevalue><![CDATA[ @@ -463,7 +481,7 @@ <socket-binding name="messaging" port="${rhq.server.socket.binding.port.messaging:4445}"/> <socket-binding name="messaging-throughput" port="${rhq.server.socket.binding.port.messaging-throughput:4455}"/>]]></replacevalue> </replacefilter> - + <replacefilter> <replacetoken><subsystem xmlns="urn:jboss:domain:naming:1.1"/></replacetoken> <replacevalue><![CDATA[ @@ -629,8 +647,8 @@ <prepared-statement-cache-size>75</prepared-statement-cache-size> </statement> </xa-datasource>]]></replacevalue> - </replacefilter> - + </replacefilter> + <replacefilter> <replacetoken></drivers></replacetoken> <replacevalue><![CDATA[ @@ -705,7 +723,7 @@
</executions> </plugin> - + <plugin> <artifactId>maven-surefire-plugin</artifactId>
@@ -725,6 +743,7 @@ <hibernate.dialect>${rhq.test.ds.hibernate-dialect}</hibernate.dialect> <clean.db>${clean.db}</clean.db> <log4j.configDebug>false</log4j.configDebug> + <project.version>${project.version}</project.version> </systemPropertyVariables> <additionalClasspathElements> <!-- The below is required for tests to run against Oracle. --> diff --git a/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/TestServerPluginService.java b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/TestServerPluginService.java new file mode 100644 index 0000000..be9b752 --- /dev/null +++ b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/TestServerPluginService.java @@ -0,0 +1,148 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2012 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; + +import java.io.File; +import java.net.URL; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; +import org.rhq.core.domain.plugin.PluginKey; +import org.rhq.core.domain.plugin.PluginStatusType; +import org.rhq.core.domain.plugin.ServerPlugin; +import org.rhq.core.util.MessageDigestGenerator; +import org.rhq.enterprise.server.plugin.pc.AbstractTypeServerPluginContainer; +import org.rhq.enterprise.server.plugin.pc.MasterServerPluginContainer; +import org.rhq.enterprise.server.plugin.pc.MasterServerPluginContainerConfiguration; +import org.rhq.enterprise.server.plugin.pc.ServerPluginEnvironment; +import org.rhq.enterprise.server.plugin.pc.ServerPluginService; +import org.rhq.enterprise.server.plugin.pc.ServerPluginType; +import org.rhq.enterprise.server.xmlschema.ServerPluginDescriptorMetadataParser; +import org.rhq.enterprise.server.xmlschema.ServerPluginDescriptorUtil; +import org.rhq.enterprise.server.xmlschema.generated.serverplugin.ServerPluginDescriptorType; + +/** + * + * + * @author Lukas Krejci + */ +public abstract class TestServerPluginService extends ServerPluginService implements TestServerPluginServiceMBean { + public TestMasterServerPluginContainer master; + public MasterServerPluginContainerConfiguration masterConfig; + + protected TestServerPluginService() { + // build the config at constructor time so tests have it even before the PC is initialized + File dir = new File(System.getProperty("java.io.tmpdir"), "test-server-plugins"); + this.masterConfig = new MasterServerPluginContainerConfiguration(dir, dir, dir, null); + } + + @Override + public MasterServerPluginContainer createMasterPluginContainer() { + this.master = new TestMasterServerPluginContainer(); + this.master.initialize(this.masterConfig); + return this.master; + } + + protected abstract List<AbstractTypeServerPluginContainer> createPluginContainers(MasterServerPluginContainer master); + + public static ServerPlugin getPlugin(ServerPluginEnvironment env) { + return getPlugin(env.getPluginUrl(), env.getPluginDescriptor()); + } + + public static ServerPlugin getPlugin(URL pluginUrl, ServerPluginDescriptorType pluginDescriptor) { + try { + Configuration pluginConfig = null; + Configuration scheduledJobsConfig = null; + ConfigurationDefinition configDef; + + configDef = ServerPluginDescriptorMetadataParser.getPluginConfigurationDefinition(pluginDescriptor); + if (configDef != null) { + pluginConfig = configDef.getDefaultTemplate().createConfiguration(); + } + + configDef = ServerPluginDescriptorMetadataParser.getScheduledJobsDefinition(pluginDescriptor); + if (configDef != null) { + scheduledJobsConfig = configDef.getDefaultTemplate().createConfiguration(); + } + + File pluginFile = new File(pluginUrl.toURI()); + PluginKey pluginKey = PluginKey.createServerPluginKey(new ServerPluginType(pluginDescriptor).stringify(), pluginDescriptor.getName()); + ServerPlugin plugin = + new ServerPlugin(0, pluginKey.getPluginName(), pluginFile.getName(), + pluginDescriptor.getDisplayName(), true, PluginStatusType.INSTALLED, + pluginDescriptor.getDescription(), "", MessageDigestGenerator.getDigestString(pluginFile), + pluginDescriptor.getVersion(), pluginDescriptor.getVersion(), pluginConfig, + scheduledJobsConfig, new ServerPluginType(pluginDescriptor).stringify(), + System.currentTimeMillis(), System.currentTimeMillis()); + return plugin; + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public static ServerPlugin getPlugin(URL pluginUrl) throws Exception { + ServerPluginDescriptorType type = ServerPluginDescriptorUtil.loadPluginDescriptorFromUrl(pluginUrl); + + return getPlugin(pluginUrl, type); + } + + protected Map<URL, ? extends ServerPluginDescriptorType> preloadAllPlugins() throws Exception { + return null; + } + + private class TestMasterServerPluginContainer extends MasterServerPluginContainer { + + @Override + protected ClassLoader createRootServerPluginClassLoader() { + return getClass().getClassLoader(); + } + + @Override + protected Map<URL, ? extends ServerPluginDescriptorType> preloadAllPlugins() throws Exception { + Map<URL, ? extends ServerPluginDescriptorType> plugins = TestServerPluginService.this.preloadAllPlugins(); + if (plugins != null) { + return plugins; + } + + // if our test never setup any plugins, ignore it and just return an empty map + File pluginDir = getConfiguration().getPluginDirectory(); + if (pluginDir == null || pluginDir.listFiles() == null || pluginDir.listFiles().length == 0) { + return new HashMap<URL, ServerPluginDescriptorType>(); + } else { + return super.preloadAllPlugins(); + } + } + + @Override + protected List<PluginKey> getDisabledPluginKeys() { + // in the real world, the db is checked for enable flag, here we say all plugins are enabled + return new ArrayList<PluginKey>(); + } + + @Override + protected List<AbstractTypeServerPluginContainer> createPluginContainers() { + return TestServerPluginService.this.createPluginContainers(this); + } + } +} diff --git a/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/TestServerPluginServiceMBean.java b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/TestServerPluginServiceMBean.java new file mode 100644 index 0000000..5c478a9 --- /dev/null +++ b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/TestServerPluginServiceMBean.java @@ -0,0 +1,31 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2012 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; + +import org.rhq.enterprise.server.plugin.pc.ServerPluginServiceMBean; + +/** + * + * + * @author Lukas Krejci + */ +public interface TestServerPluginServiceMBean extends ServerPluginServiceMBean { + +} diff --git a/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/alert/AlertDefinitionWithComplexNotificationsTest.java b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/alert/AlertDefinitionWithComplexNotificationsTest.java new file mode 100644 index 0000000..f29e224 --- /dev/null +++ b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/alert/AlertDefinitionWithComplexNotificationsTest.java @@ -0,0 +1,1433 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2012 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.alert; + +import java.io.File; +import java.net.URL; +import java.util.Collections; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + +import javax.persistence.EntityManager; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.testng.annotations.Test; + +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.exporter.ZipExporter; +import org.jboss.shrinkwrap.api.spec.JavaArchive; + +import org.rhq.core.domain.alert.AlertDampening; +import org.rhq.core.domain.alert.AlertDefinition; +import org.rhq.core.domain.alert.AlertPriority; +import org.rhq.core.domain.alert.BooleanExpression; +import org.rhq.core.domain.alert.notification.AlertNotification; +import org.rhq.core.domain.auth.Subject; +import org.rhq.core.domain.authz.Permission; +import org.rhq.core.domain.authz.Role; +import org.rhq.core.domain.cloud.Server; +import org.rhq.core.domain.cloud.Server.OperationMode; +import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.configuration.PropertySimple; +import org.rhq.core.domain.criteria.AlertDefinitionCriteria; +import org.rhq.core.domain.criteria.ResourceCriteria; +import org.rhq.core.domain.plugin.ServerPlugin; +import org.rhq.core.domain.resource.Agent; +import org.rhq.core.domain.resource.InventoryStatus; +import org.rhq.core.domain.resource.Resource; +import org.rhq.core.domain.resource.ResourceType; +import org.rhq.core.domain.resource.group.ResourceGroup; +import org.rhq.core.domain.shared.ResourceBuilder; +import org.rhq.core.domain.shared.ResourceTypeBuilder; +import org.rhq.enterprise.server.TestServerPluginService; +import org.rhq.enterprise.server.auth.SessionManager; +import org.rhq.enterprise.server.test.AbstractEJB3Test; +import org.rhq.enterprise.server.test.TestServerCommunicationsService; +import org.rhq.enterprise.server.test.TransactionCallback; +import org.rhq.enterprise.server.util.LookupUtil; +import org.rhq.enterprise.server.util.ResourceTreeHelper; + +/** + * !!! README + * !!! The original version of this class is nicely written and is maintained at the bottom of this file in comments. + * !!! The issue is that Arquillian (1.0.2) does not honor the testNg lifecycle, on which the original + * !!! implementation heavily relies (i.e. Before/AfterClass and instance variables that span all tests). + * !!! The work needed to get it to work in a similar fashion was large, and Arquillian 2 promises to perhaps + * !!! honor the testNg lifecycle. So, for now, I've basically condensed this into one large test to + * !!! get it running. Sorry Lukas :( + * + * + * @author Lukas Krejci + */ +@Test(groups = "alert") +public class AlertDefinitionWithComplexNotificationsTest extends AbstractEJB3Test { + + private static final Log LOG = LogFactory.getLog(AlertDefinitionWithComplexNotificationsTest.class); + + private enum ParentType { + GROUP, TEMPLATE + } + + private String universalName; + + private Server server; + private Agent agent; + private Subject subject; + private Role role; + private ResourceType resourceType; + private ResourceGroup resourceGroup; + private Set<Resource> resources; + private AlertDefinition templateAlertDefinition; + private AlertDefinition groupAlertDefinition; + private AlertDefinition resourceAlertDefinition; + private ServerPlugin serverPlugin; + private Set<Object> junk = new LinkedHashSet<Object>(); + + private int resourceLevelAlertDefinitionId; + private int groupLevelAlertDefinitionId; + private int templateLevelAlertDefinitionId; + private Resource copyTestsResource; + + private TestAlertSenderPluginService alertSenderService; + private TestServerCommunicationsService agentService; + + @Test + public void singleMergedTest() throws Exception { + try { + prepareDB(); + containerSetup(); + login(); + + System.out.println("Running test: testNotificationsCopiedOnAlertTemplateApplication"); + testNotificationsCopiedOnAlertTemplateApplication(); + + System.out.println("Running test: testNotificationsCopiedOnGroupMemberAddition"); + testNotificationsCopiedOnGroupMemberAddition(); + + System.out.println("Running test: testCorrectSubjectPassedOnResourceLevelAlertDefinitionCreation"); + testCorrectSubjectPassedOnResourceLevelAlertDefinitionCreation(); + + System.out.println("Running test: testCorrectSubjectPassedOnGroupLevelAlertDefinitionCreation"); + testCorrectSubjectPassedOnGroupLevelAlertDefinitionCreation(); + + System.out.println("Running test: testCorrectSubjectPassedOnTemplateLevelAlertDefinitionCreation"); + testCorrectSubjectPassedOnTemplateLevelAlertDefinitionCreation(); + + System.out.println("Running test: testNoValidationWhenNoNotificationUpdateOnResourceLevel"); + testNoValidationWhenNoNotificationUpdateOnResourceLevel(); + + System.out.println("Running test: testNoValidationWhenNoNotificationUpdateOnGroupLevel"); + testNoValidationWhenNoNotificationUpdateOnGroupLevel(); + + System.out.println("Running test: testNoValidationWhenNoNotificationUpdateOnTemplateLevel"); + testNoValidationWhenNoNotificationUpdateOnTemplateLevel(); + + System.out.println("Running test: testCorrectSubjectPassedOnResourceLevelAlertDefinitionUpdate"); + testCorrectSubjectPassedOnResourceLevelAlertDefinitionUpdate(); + + System.out.println("Running test: testCorrectSubjectPassedOnGroupLevelAlertDefinitionUpdate"); + testCorrectSubjectPassedOnGroupLevelAlertDefinitionUpdate(); + + System.out.println("Running test: testCorrectSubjectPassedOnTemplateLevelAlertDefinitionUpdate"); + testCorrectSubjectPassedOnTemplateLevelAlertDefinitionUpdate(); + + } catch (Exception e) { + e.printStackTrace(); + throw e; + + } finally { + containerTearDown(); + logout(); + cleanDB(); + } + } + + //@BeforeClass + private void prepareDB() { + executeInTransaction(false, new TransactionCallback() { + @Override + public void execute() throws Exception { + EntityManager em = getEntityManager(); + + universalName = getClass().getName(); + + agent = new Agent("localhost", "localhost", 0, "foo", "bar"); + + server = new Server(); + server.setAddress("localhost"); + server.setName("localhost"); + server.setOperationMode(OperationMode.NORMAL); + + server.setAgents(Collections.singletonList(agent)); + + role = new Role(universalName); + role.addPermission(Permission.MANAGE_INVENTORY); + role.addPermission(Permission.MANAGE_SETTINGS); + + subject = new Subject(universalName, true, false); + subject.addRole(role); + + resourceType = new ResourceTypeBuilder().createPlatformResourceType().withId(0).withName(universalName) + .withPlugin(universalName).build(); + + resourceGroup = new ResourceGroup(universalName, resourceType); + + resources = new LinkedHashSet<Resource>(); + for (int i = 0; i < 10; ++i) { + Resource res = createResourceForTest(universalName + i); + + resources.add(res); + + resourceGroup.addExplicitResource(res); + } + + templateAlertDefinition = createDefinitionForTest(universalName + " template", true); + templateAlertDefinition.setResourceType(resourceType); + + groupAlertDefinition = createDefinitionForTest(universalName + " group", true); + groupAlertDefinition.setResourceGroup(resourceGroup); + + resourceAlertDefinition = createDefinitionForTest(universalName + " resource", true); + resourceAlertDefinition.setResource(resources.iterator().next()); + + em.persist(agent); + em.persist(server); + em.persist(role); + em.persist(subject); + em.persist(resourceType); + em.persist(resourceGroup); + for (Resource r : resources) { + em.persist(r); + } + em.persist(templateAlertDefinition); + em.persist(groupAlertDefinition); + em.persist(resourceAlertDefinition); + + //only need this for a short time now, so that we can precreate the plugin structure + alertSenderService = new TestAlertSenderPluginService(); + prepareCustomServerPluginService(alertSenderService); + alertSenderService.masterConfig.getPluginDirectory().mkdirs(); + unprepareServerPluginService(); + + JavaArchive archive = ShrinkWrap.create(JavaArchive.class); + //archive.addClass(TestAlertSender.class); + URL res = this.getClass().getClassLoader().getResource("test-alert-sender-serverplugin.xml"); + archive.addAsResource(res, "META-INF/rhq-serverplugin.xml"); + + File pluginFile = new File(alertSenderService.masterConfig.getPluginDirectory(), "test-aler-plugin.jar"); + + archive.as(ZipExporter.class).exportTo(pluginFile, true); + + //the alert sender plugin manager needs the plugins in the database... + serverPlugin = TestServerPluginService.getPlugin(pluginFile.toURI().toURL()); + em.persist(serverPlugin); + } + }); + } + + //@BeforeMethod + private void containerSetup() { + alertSenderService = new TestAlertSenderPluginService(); + prepareCustomServerPluginService(alertSenderService); + alertSenderService.masterConfig.getPluginDirectory().mkdirs(); + + alertSenderService.startMasterPluginContainer(); + + agentService = prepareForTestAgents(); + } + + //@AfterMethod + private void containerTearDown() throws Exception { + unprepareServerPluginService(); + unprepareForTestAgents(); + } + + //@AfterClass(alwaysRun = true) + private void cleanDB() throws Exception { + for (Object o : junk) { + removeNoExceptions(o); + } + + removeNoExceptions(resourceAlertDefinition); + removeNoExceptions(groupAlertDefinition); + removeNoExceptions(templateAlertDefinition); + removeNoExceptions(resourceGroup); + for (Resource r : resources) { + r.removeExplicitGroup(resourceGroup); + r.getAlertDefinitions().clear(); + removeNoExceptions(r); + } + removeNoExceptions(resourceType); + removeNoExceptions(subject); + removeNoExceptions(role); + removeNoExceptions(server); + removeNoExceptions(agent); + + removeNoExceptions(serverPlugin); + } + + //@BeforeMethod + private void login() throws Exception { + //the embedded server cannot do a full-blown login + //so we hack our way in + subject = SessionManager.getInstance().put(subject); + } + + //@AfterMethod(alwaysRun = true) + private void logout() throws Exception { + SessionManager.getInstance().invalidate(subject.getSessionId()); + } + + private Resource getCopyTestsResource() throws Exception { + if (copyTestsResource == null) { + final String keyAndName = universalName + "-copyTests"; + + LookupUtil.getResourceManager() + .createResource(subject, createResourceForTest(keyAndName), Resource.ROOT_ID); + + //ok, now the new resource should contain the alert definition defined by the template + ResourceCriteria crit = new ResourceCriteria(); + crit.addFilterResourceKey(keyAndName); + crit.fetchExplicitGroups(true); //so that cleanup works + crit.fetchAlertDefinitions(true); //so that cleanup works + + List<Resource> foundResources = LookupUtil.getResourceManager().findResourcesByCriteria(subject, crit); + + assertEquals("A new resource should have been created", 1, foundResources.size()); + + Resource res = foundResources.get(0); + resources.add(res); + + copyTestsResource = res; + } + + return copyTestsResource; + } + + private void testNotificationsCopiedOnAlertTemplateApplication() throws Exception { + TestAlertSender.setExpectedSubject(null); + TestAlertSender.resetValidateMethodCallCount(); + + Resource res = getCopyTestsResource(); + + //apply the template manually - this is done in server-agent back-and-forth that we + //don't test here and which is complex to mock out. + //this method has to be called using the overlord subject + LookupUtil.getAlertTemplateManager().updateAlertDefinitionsForResource( + LookupUtil.getSubjectManager().getOverlord(), res.getId()); + + assertEquals("No validation should occur on the copied notifications", 0, + TestAlertSender.getValidateMethodCallCount()); + + AlertDefinitionManagerLocal adm = LookupUtil.getAlertDefinitionManager(); + AlertDefinitionCriteria adCrit = new AlertDefinitionCriteria(); + adCrit.addFilterResourceIds(res.getId()); + adCrit.fetchAlertNotifications(true); + + List<AlertDefinition> foundAlertDefs = adm.findAlertDefinitionsByCriteria(subject, adCrit); + junk.addAll(foundAlertDefs); + + assertEquals("The new resource should have an alert definition obtained from the template.", 1, + foundAlertDefs.size()); + + AlertDefinition defWithNotifications = foundAlertDefs.get(0); + + testSingleDependentAlertDefinition(defWithNotifications, ParentType.TEMPLATE, + defWithNotifications.getParentId()); + } + + //@Test(dependsOnMethods = "testNotificationsCopiedOnAlertTemplateApplication") + private void testNotificationsCopiedOnGroupMemberAddition() throws Exception { + TestAlertSender.setExpectedSubject(null); + TestAlertSender.resetValidateMethodCallCount(); + + Resource res = getCopyTestsResource(); + + LookupUtil.getResourceGroupManager().addResourcesToGroup(subject, resourceGroup.getId(), + new int[] { res.getId() }); + + assertEquals("No validation should occur on the copied notifications", 0, + TestAlertSender.getValidateMethodCallCount()); + + AlertDefinitionManagerLocal adm = LookupUtil.getAlertDefinitionManager(); + AlertDefinitionCriteria adCrit = new AlertDefinitionCriteria(); + adCrit.addFilterResourceIds(res.getId()); + adCrit.fetchAlertNotifications(true); + + List<AlertDefinition> foundAlertDefs = adm.findAlertDefinitionsByCriteria(subject, adCrit); + junk.addAll(foundAlertDefs); + + //1 from the group, 1 from the template + assertEquals("The new resource should have an alert definition obtained from the group.", 2, + foundAlertDefs.size()); + + AlertDefinition groupOriginatingDef = null; + for (AlertDefinition d : foundAlertDefs) { + if ((universalName + " group").equals(d.getName())) { + groupOriginatingDef = d; + break; + } + } + + assertNotNull("The alert definition originating from the group not present on the resource.", + groupOriginatingDef); + + testSingleDependentAlertDefinition(groupOriginatingDef, ParentType.GROUP, groupOriginatingDef + .getGroupAlertDefinition().getId()); + } + + private void testCorrectSubjectPassedOnResourceLevelAlertDefinitionCreation() throws Exception { + TestAlertSender.setExpectedSubject(subject); + + AlertDefinitionManagerLocal adm = LookupUtil.getAlertDefinitionManager(); + + Resource res = resources.iterator().next(); + + AlertDefinition def = createDefinitionForTest("testCorrectSubjectPassedOnResourceLevelAlertDefinitionCreation", + false); + def.setResource(resources.iterator().next()); + + int id = adm.createAlertDefinition(subject, def, res.getId(), true); + def.setId(id); + + resourceLevelAlertDefinitionId = id; + + junk.add(def); + + testMainAlertDefinition(id); + } + + //@Test(dependsOnMethods = { "testNotificationsCopiedOnAlertTemplateApplication", + // "testNotificationsCopiedOnGroupMemberAddition" }) + private void testCorrectSubjectPassedOnGroupLevelAlertDefinitionCreation() throws Exception { + TestAlertSender.setExpectedSubject(subject); + + GroupAlertDefinitionManagerLocal gadm = LookupUtil.getGroupAlertDefinitionManager(); + + AlertDefinition def = createDefinitionForTest("testCorrectSubjectPassedOnGroupLevelAlertDefinitionCreation", + false); + def.setResourceGroup(resourceGroup); + + int id = gadm.createGroupAlertDefinitions(subject, def, resourceGroup.getId()); + def.setId(id); + + groupLevelAlertDefinitionId = id; + + junk.add(def); + + testMainAlertDefinition(id); + List<AlertDefinition> deps = testDependentAlertDefinitions(id, ParentType.GROUP); + + junk.addAll(deps); + } + + //@Test(dependsOnMethods = { "testNotificationsCopiedOnAlertTemplateApplication", + // "testNotificationsCopiedOnGroupMemberAddition" }) + private void testCorrectSubjectPassedOnTemplateLevelAlertDefinitionCreation() throws Exception { + TestAlertSender.setExpectedSubject(subject); + + AlertTemplateManagerLocal atm = LookupUtil.getAlertTemplateManager(); + + AlertDefinition def = createDefinitionForTest("testCorrectSubjectPassedOnTemplateLevelAlertDefinitionCreation", + false); + def.setResourceGroup(resourceGroup); + + int id = atm.createAlertTemplate(subject, def, resourceType.getId()); + def.setId(id); + + templateLevelAlertDefinitionId = id; + + junk.add(def); + + testMainAlertDefinition(id); + List<AlertDefinition> deps = testDependentAlertDefinitions(id, ParentType.TEMPLATE); + + junk.addAll(deps); + } + + //@Test(dependsOnMethods = "testCorrectSubjectPassedOnResourceLevelAlertDefinitionCreation") + private void testNoValidationWhenNoNotificationUpdateOnResourceLevel() throws Exception { + TestAlertSender.setExpectedSubject(subject); + TestAlertSender.resetValidateMethodCallCount(); + + AlertDefinitionManagerLocal adm = LookupUtil.getAlertDefinitionManager(); + + AlertDefinitionCriteria crit = new AlertDefinitionCriteria(); + crit.addFilterId(resourceLevelAlertDefinitionId); + crit.fetchAlertNotifications(true); + crit.fetchConditions(true); + + List<AlertDefinition> foundDefs = adm.findAlertDefinitionsByCriteria(subject, crit); + + assertEquals("Failed to find the previously created resource level alert definition.", 1, foundDefs.size()); + + AlertDefinition foundDef = foundDefs.get(0); + + foundDef.setEnabled(true); + + adm.updateAlertDefinition(subject, resourceLevelAlertDefinitionId, foundDef, false); + + assertEquals("The notification validation method shouldn't have been called", 0, + TestAlertSender.getValidateMethodCallCount()); + } + + //@Test(dependsOnMethods = "testCorrectSubjectPassedOnGroupLevelAlertDefinitionCreation") + private void testNoValidationWhenNoNotificationUpdateOnGroupLevel() throws Exception { + TestAlertSender.setExpectedSubject(subject); + TestAlertSender.resetValidateMethodCallCount(); + + AlertDefinitionManagerLocal adm = LookupUtil.getAlertDefinitionManager(); + + AlertDefinitionCriteria crit = new AlertDefinitionCriteria(); + crit.addFilterId(groupLevelAlertDefinitionId); + crit.fetchAlertNotifications(true); + crit.fetchConditions(true); + + List<AlertDefinition> foundDefs = adm.findAlertDefinitionsByCriteria(subject, crit); + + assertEquals("Failed to find the previously created group level alert definition.", 1, foundDefs.size()); + + AlertDefinition foundDef = foundDefs.get(0); + + foundDef.setEnabled(true); + + GroupAlertDefinitionManagerLocal gadm = LookupUtil.getGroupAlertDefinitionManager(); + gadm.updateGroupAlertDefinitions(subject, foundDef, true); + + assertEquals("The notification validation method shouldn't have been called", 0, + TestAlertSender.getValidateMethodCallCount()); + } + + //@Test(dependsOnMethods = "testCorrectSubjectPassedOnTemplateLevelAlertDefinitionCreation") + private void testNoValidationWhenNoNotificationUpdateOnTemplateLevel() throws Exception { + TestAlertSender.setExpectedSubject(subject); + TestAlertSender.resetValidateMethodCallCount(); + + AlertDefinitionManagerLocal adm = LookupUtil.getAlertDefinitionManager(); + + AlertDefinitionCriteria crit = new AlertDefinitionCriteria(); + crit.addFilterId(templateLevelAlertDefinitionId); + crit.fetchAlertNotifications(true); + crit.fetchConditions(true); + + List<AlertDefinition> foundDefs = adm.findAlertDefinitionsByCriteria(subject, crit); + + assertEquals("Failed to find the previously created resource level alert definition.", 1, foundDefs.size()); + + AlertDefinition foundDef = foundDefs.get(0); + + foundDef.setEnabled(true); + + AlertTemplateManagerLocal atm = LookupUtil.getAlertTemplateManager(); + + atm.updateAlertTemplate(subject, foundDef, true); + + assertEquals("The notification validation method shouldn't have been called", 0, + TestAlertSender.getValidateMethodCallCount()); + } + + //@Test(dependsOnMethods = "testNoValidationWhenNoNotificationUpdateOnResourceLevel") + private void testCorrectSubjectPassedOnResourceLevelAlertDefinitionUpdate() throws Exception { + TestAlertSender.setExpectedSubject(subject); + TestAlertSender.resetValidateMethodCallCount(); + + AlertDefinitionManagerLocal adm = LookupUtil.getAlertDefinitionManager(); + + AlertDefinitionCriteria crit = new AlertDefinitionCriteria(); + crit.addFilterId(resourceLevelAlertDefinitionId); + crit.fetchAlertNotifications(true); + crit.fetchConditions(true); + + List<AlertDefinition> foundDefs = adm.findAlertDefinitionsByCriteria(subject, crit); + + assertEquals("Failed to find the previously created resource level alert definition.", 1, foundDefs.size()); + + AlertDefinition foundDef = foundDefs.get(0); + + AlertNotification newNotif = createAlertNotificationForTest(foundDef, false); + //just add some dummy config property so that the 2 notifs are distinguishable from each other + //and are saved separately + newNotif.getConfiguration().put(new PropertySimple("foo-resource", "bar")); + + adm.updateAlertDefinition(subject, resourceLevelAlertDefinitionId, foundDef, false); + + assertEquals("Validation should have been called for a new notification during alert def update", 1, + TestAlertSender.getValidateMethodCallCount()); + } + + //@Test(dependsOnMethods = "testCorrectSubjectPassedOnGroupLevelAlertDefinitionCreation") + private void testCorrectSubjectPassedOnGroupLevelAlertDefinitionUpdate() throws Exception { + TestAlertSender.setExpectedSubject(subject); + TestAlertSender.resetValidateMethodCallCount(); + + AlertDefinitionManagerLocal adm = LookupUtil.getAlertDefinitionManager(); + + AlertDefinitionCriteria crit = new AlertDefinitionCriteria(); + crit.addFilterId(groupLevelAlertDefinitionId); + crit.fetchAlertNotifications(true); + crit.fetchConditions(true); + + List<AlertDefinition> foundDefs = adm.findAlertDefinitionsByCriteria(subject, crit); + + assertEquals("Failed to find the previously created group level alert definition.", 1, foundDefs.size()); + + AlertDefinition foundDef = foundDefs.get(0); + + AlertNotification newNotif = createAlertNotificationForTest(foundDef, false); + //just add some dummy config property so that the 2 notifs are distinguishable from each other + //and are saved separately + newNotif.getConfiguration().put(new PropertySimple("foo-group", "bar")); + + GroupAlertDefinitionManagerLocal gadm = LookupUtil.getGroupAlertDefinitionManager(); + gadm.updateGroupAlertDefinitions(subject, foundDef, true); + + //notice that the validation should be called just once, even though in effect we're creating 11 notifs + //1 for group and 10 for its members. + assertEquals("Validation should have been called for a new notification during alert def update", 1, + TestAlertSender.getValidateMethodCallCount()); + } + + //@Test(dependsOnMethods = "testCorrectSubjectPassedOnTemplateLevelAlertDefinitionCreation") + private void testCorrectSubjectPassedOnTemplateLevelAlertDefinitionUpdate() throws Exception { + TestAlertSender.setExpectedSubject(subject); + TestAlertSender.resetValidateMethodCallCount(); + + AlertDefinitionManagerLocal adm = LookupUtil.getAlertDefinitionManager(); + + AlertDefinitionCriteria crit = new AlertDefinitionCriteria(); + crit.addFilterId(templateLevelAlertDefinitionId); + crit.fetchAlertNotifications(true); + crit.fetchConditions(true); + + List<AlertDefinition> foundDefs = adm.findAlertDefinitionsByCriteria(subject, crit); + + assertEquals("Failed to find the previously created template level alert definition.", 1, foundDefs.size()); + + AlertDefinition foundDef = foundDefs.get(0); + + AlertNotification newNotif = createAlertNotificationForTest(foundDef, false); + //just add some dummy config property so that the 2 notifs are distinguishable from each other + //and are saved separately + newNotif.getConfiguration().put(new PropertySimple("foo-template", "bar")); + + AlertTemplateManagerLocal atm = LookupUtil.getAlertTemplateManager(); + atm.updateAlertTemplate(subject, foundDef, true); + + //notice that the validation should be called just once, even though in effect we're creating 11 notifs + //1 for template and 10 for its members. + assertEquals("Validation should have been called for a new notification during alert def update", 1, + TestAlertSender.getValidateMethodCallCount()); + } + + private void removeNoExceptions(final Object o) { + try { + executeInTransaction(new TransactionCallback() { + public void execute() { + EntityManager em = getEntityManager(); + Object o2 = em.merge(o); + + if (o2 instanceof Resource) { + ResourceTreeHelper.deleteResource(em, (Resource) o2); + } else { + em.remove(o2); + } + } + }); + } catch (Exception e) { + LOG.error("Failed to DELETE an object from database: " + o, e); + } + } + + private AlertDefinition createDefinition(String name) { + AlertDefinition ret = new AlertDefinition(); + ret.setName(name); + ret.setPriority(AlertPriority.MEDIUM); + ret.setAlertDampening(new AlertDampening(AlertDampening.Category.NONE)); + ret.setConditionExpression(BooleanExpression.ANY); + ret.setRecoveryId(0); + + return ret; + } + + private AlertDefinition createDefinitionForTest(String name, boolean precanned) { + AlertDefinition def = createDefinition(name); + createAlertNotificationForTest(def, precanned); + + return def; + } + + private AlertNotification createAlertNotificationForTest(AlertDefinition alertDefinition, boolean precanned) { + AlertNotification notif = new AlertNotification("Test Alert Sender"); + + Configuration alertConfig = new Configuration(); + + if (precanned) { + alertConfig.put(new PropertySimple(TestAlertSender.PERSISTENT_PROPERTY_NAME, + TestAlertSender.PERSISTEN_PROPERTY_EXPECTED_VALUE)); + } else { + alertConfig.put(new PropertySimple(TestAlertSender.PERSISTENT_PROPERTY_NAME, "persistent")); + alertConfig.put(new PropertySimple(TestAlertSender.EPHEMERAL_PROPERTY_NAME, "ephemeral")); + } + + Configuration extraConfig = new Configuration(); + + if (precanned) { + extraConfig.put(new PropertySimple(TestAlertSender.PERSISTENT_PROPERTY_NAME, + TestAlertSender.PERSISTEN_PROPERTY_EXPECTED_VALUE)); + } else { + extraConfig.put(new PropertySimple(TestAlertSender.PERSISTENT_PROPERTY_NAME, "persistent")); + extraConfig.put(new PropertySimple(TestAlertSender.EPHEMERAL_PROPERTY_NAME, "ephemeral")); + } + + notif.setConfiguration(alertConfig); + notif.setExtraConfiguration(extraConfig); + + alertDefinition.addAlertNotification(notif); + notif.setAlertDefinition(alertDefinition); + + return notif; + } + + private void testMainAlertDefinition(int id) { + AlertDefinitionCriteria crit = new AlertDefinitionCriteria(); + crit.addFilterId(id); + crit.fetchAlertNotifications(true); + + List<AlertDefinition> checkList = LookupUtil.getAlertDefinitionManager().findAlertDefinitionsByCriteria( + subject, crit); + + assertNotNull("Failed to retrieve the save alert definition", checkList); + assertEquals("The alert definition should have been saved.", 1, checkList.size()); + + AlertDefinition check = checkList.get(0); + + assertEquals("There should be exactly 1 notification on the definition", 1, check.getAlertNotifications() + .size()); + + Configuration config = check.getAlertNotifications().get(0).getConfiguration(); + assertEquals("Unexpected persistent value in notif config", TestAlertSender.PERSISTEN_PROPERTY_EXPECTED_VALUE, + config.getSimpleValue(TestAlertSender.PERSISTENT_PROPERTY_NAME, null)); + assertNull("Ephemeral property seems to have been saved", + config.getSimpleValue(TestAlertSender.EPHEMERAL_PROPERTY_NAME, null)); + } + + private List<AlertDefinition> testDependentAlertDefinitions(int expectedParentId, ParentType parentType) { + AlertDefinitionCriteria crit = new AlertDefinitionCriteria(); + + Set<Integer> resourceIds = new HashSet<Integer>(resources.size()); + for (Resource r : resources) { + resourceIds.add(r.getId()); + } + + if (parentType == ParentType.TEMPLATE) { + crit.addFilterAlertTemplateParentId(expectedParentId); + } else if (parentType == ParentType.GROUP) { + crit.addFilterGroupAlertDefinitionId(expectedParentId); + } + + crit.fetchAlertNotifications(true); + + List<AlertDefinition> checkList = LookupUtil.getAlertDefinitionManager().findAlertDefinitionsByCriteria( + subject, crit); + + assertNotNull("Failed to retrieve the save alert definition", checkList); + assertEquals("The dependent alert definitions should have been saved.", resources.size(), checkList.size()); + + for (AlertDefinition check : checkList) { + testSingleDependentAlertDefinition(check, parentType, expectedParentId); + } + + return checkList; + } + + private void testSingleDependentAlertDefinition(AlertDefinition alertDef, ParentType parentType, + int expectedParentId) { + assertEquals("There should be exactly 1 notification on the definition " + alertDef, 1, alertDef + .getAlertNotifications().size()); + + Configuration config = alertDef.getAlertNotifications().get(0).getConfiguration(); + assertEquals("Unexpected persistent value in notif config " + alertDef, + TestAlertSender.PERSISTEN_PROPERTY_EXPECTED_VALUE, + config.getSimpleValue(TestAlertSender.PERSISTENT_PROPERTY_NAME, null)); + assertNull("Ephemeral property seems to have been saved " + alertDef, + config.getSimpleValue(TestAlertSender.EPHEMERAL_PROPERTY_NAME, null)); + + if (parentType == ParentType.GROUP) { + assertEquals("The group parent id has unexpected value", expectedParentId, alertDef + .getGroupAlertDefinition().getId()); + } else if (parentType == ParentType.TEMPLATE) { + assertEquals("The parent id has unexpected value", Integer.valueOf(expectedParentId), + alertDef.getParentId()); + } + } + + private Resource createResourceForTest(String resourceKey) { + Resource res = new ResourceBuilder().createPlatform().withRandomUuid().withResourceKey(resourceKey) + .withResourceType(resourceType).withName(resourceKey).withInventoryStatus(InventoryStatus.COMMITTED) + .build(); + res.setAgent(agent); + + return res; + } +} + +///** +// * +// * +// * @author Lukas Krejci +// */ +//@Test(groups = "alert") +//public class AlertDefinitionWithComplexNotificationsTest extends AbstractEJB3Test { +// +// private static final Log LOG = LogFactory.getLog(AlertDefinitionWithComplexNotificationsTest.class); +// +// private enum ParentType { +// GROUP, TEMPLATE +// } +// +// private String universalName; +// +// private Server server; +// private Agent agent; +// private Subject subject; +// private Role role; +// private ResourceType resourceType; +// private ResourceGroup resourceGroup; +// private Set<Resource> resources; +// private AlertDefinition templateAlertDefinition; +// private AlertDefinition groupAlertDefinition; +// private AlertDefinition resourceAlertDefinition; +// private ServerPlugin serverPlugin; +// private Set<Object> junk = new LinkedHashSet<Object>(); +// +// private int resourceLevelAlertDefinitionId; +// private int groupLevelAlertDefinitionId; +// private int templateLevelAlertDefinitionId; +// private Resource copyTestsResource; +// +// private TestAlertSenderPluginService alertSenderService; +// private TestServerCommunicationsService agentService; +// +// @BeforeClass +// public void prepareDB() { +// executeInTransaction(new TransactionCallback() { +// @Override +// public void execute() throws Exception { +// EntityManager em = getEntityManager(); +// +// universalName = getClass().getName(); +// +// agent = new Agent("localhost", "localhost", 0, "foo", "bar"); +// +// server = new Server(); +// server.setAddress("localhost"); +// server.setName("localhost"); +// server.setOperationMode(OperationMode.NORMAL); +// +// server.setAgents(Collections.singletonList(agent)); +// +// role = new Role(universalName); +// role.addPermission(Permission.MANAGE_INVENTORY); +// role.addPermission(Permission.MANAGE_SETTINGS); +// +// subject = new Subject(universalName, true, false); +// subject.addRole(role); +// +// resourceType = +// new ResourceTypeBuilder().createPlatformResourceType().withId(0).withName(universalName) +// .withPlugin(universalName).build(); +// +// resourceGroup = new ResourceGroup(universalName, resourceType); +// +// resources = new LinkedHashSet<Resource>(); +// for (int i = 0; i < 10; ++i) { +// Resource res = createResourceForTest(universalName + i); +// +// resources.add(res); +// +// resourceGroup.addExplicitResource(res); +// } +// +// templateAlertDefinition = createDefinitionForTest(universalName + " template", true); +// templateAlertDefinition.setResourceType(resourceType); +// +// groupAlertDefinition = createDefinitionForTest(universalName + " group", true); +// groupAlertDefinition.setResourceGroup(resourceGroup); +// +// resourceAlertDefinition = createDefinitionForTest(universalName + " resource", true); +// resourceAlertDefinition.setResource(resources.iterator().next()); +// +// em.persist(agent); +// em.persist(server); +// em.persist(role); +// em.persist(subject); +// em.persist(resourceType); +// em.persist(resourceGroup); +// for (Resource r : resources) { +// em.persist(r); +// } +// em.persist(templateAlertDefinition); +// em.persist(groupAlertDefinition); +// em.persist(resourceAlertDefinition); +// +// //only need this for a short time now, so that we can precreate the plugin structure +// alertSenderService = new TestAlertSenderPluginService(); +// prepareCustomServerPluginService(alertSenderService); +// alertSenderService.masterConfig.getPluginDirectory().mkdirs(); +// unprepareServerPluginService(); +// +// JavaArchive archive = +// ShrinkWrap.create(JavaArchive.class).addClass(TestAlertSender.class) +// .addAsResource("test-alert-sender-serverplugin.xml", "META-INF/rhq-serverplugin.xml"); +// +// File pluginFile = +// new File(alertSenderService.masterConfig.getPluginDirectory(), "test-aler-plugin.jar"); +// +// archive.as(ZipExporter.class).exportTo(pluginFile, true); +// +// //the alert sender plugin manager needs the plugins in the database... +// serverPlugin = TestServerPluginService.getPlugin(pluginFile.toURI().toURL()); +// em.persist(serverPlugin); +// } +// }); +// } +// +// @BeforeMethod +// public void containerSetup() { +// alertSenderService = new TestAlertSenderPluginService(); +// prepareCustomServerPluginService(alertSenderService); +// alertSenderService.masterConfig.getPluginDirectory().mkdirs(); +// +// alertSenderService.startMasterPluginContainer(); +// +// agentService = prepareForTestAgents(); +// } +// +// @AfterMethod +// public void containerTearDown() throws Exception { +// unprepareServerPluginService(); +// unprepareForTestAgents(); +// } +// +// @AfterClass(alwaysRun = true) +// public void cleanDB() throws Exception { +// for (Object o : junk) { +// removeNoExceptions(o); +// } +// +// removeNoExceptions(resourceAlertDefinition); +// removeNoExceptions(groupAlertDefinition); +// removeNoExceptions(templateAlertDefinition); +// removeNoExceptions(resourceGroup); +// for (Resource r : resources) { +// r.removeExplicitGroup(resourceGroup); +// r.getAlertDefinitions().clear(); +// removeNoExceptions(r); +// } +// removeNoExceptions(resourceType); +// removeNoExceptions(subject); +// removeNoExceptions(role); +// removeNoExceptions(server); +// removeNoExceptions(agent); +// +// removeNoExceptions(serverPlugin); +// } +// +// @BeforeMethod +// public void login() throws Exception { +// //the embedded server cannot do a full-blown login +// //so we hack our way in +// subject = SessionManager.getInstance().put(subject); +// } +// +// @AfterMethod(alwaysRun = true) +// public void logout() throws Exception { +// SessionManager.getInstance().invalidate(subject.getSessionId()); +// } +// +// private Resource getCopyTestsResource() throws Exception { +// if (copyTestsResource == null) { +// final String keyAndName = universalName + "-copyTests"; +// +// LookupUtil.getResourceManager().createResource(subject, createResourceForTest(keyAndName), Resource.ROOT_ID); +// +// //ok, now the new resource should contain the alert definition defined by the template +// ResourceCriteria crit = new ResourceCriteria(); +// crit.addFilterResourceKey(keyAndName); +// crit.fetchExplicitGroups(true); //so that cleanup works +// crit.fetchAlertDefinitions(true); //so that cleanup works +// +// List<Resource> foundResources = LookupUtil.getResourceManager().findResourcesByCriteria(subject, crit); +// +// assertEquals("A new resource should have been created", 1, foundResources.size()); +// +// Resource res = foundResources.get(0); +// resources.add(res); +// +// copyTestsResource = res; +// } +// +// return copyTestsResource; +// } +// +// public void testNotificationsCopiedOnAlertTemplateApplication() throws Exception { +// TestAlertSender.setExpectedSubject(null); +// TestAlertSender.resetValidateMethodCallCount(); +// +// Resource res = getCopyTestsResource(); +// +// //apply the template manually - this is done in server-agent back-and-forth that we +// //don't test here and which is complex to mock out. +// //this method has to be called using the overlord subject +// LookupUtil.getAlertTemplateManager().updateAlertDefinitionsForResource(LookupUtil.getSubjectManager().getOverlord(), res.getId()); +// +// assertEquals("No validation should occur on the copied notifications", 0, TestAlertSender.getValidateMethodCallCount()); +// +// AlertDefinitionManagerLocal adm = LookupUtil.getAlertDefinitionManager(); +// AlertDefinitionCriteria adCrit = new AlertDefinitionCriteria(); +// adCrit.addFilterResourceIds(res.getId()); +// adCrit.fetchAlertNotifications(true); +// +// List<AlertDefinition> foundAlertDefs = adm.findAlertDefinitionsByCriteria(subject, adCrit); +// junk.addAll(foundAlertDefs); +// +// assertEquals("The new resource should have an alert definition obtained from the template.", 1, foundAlertDefs.size()); +// +// AlertDefinition defWithNotifications = foundAlertDefs.get(0); +// +// testSingleDependentAlertDefinition(defWithNotifications, ParentType.TEMPLATE, defWithNotifications.getParentId()); +// } +// +// @Test(dependsOnMethods = "testNotificationsCopiedOnAlertTemplateApplication") +// public void testNotificationsCopiedOnGroupMemberAddition() throws Exception { +// TestAlertSender.setExpectedSubject(null); +// TestAlertSender.resetValidateMethodCallCount(); +// +// Resource res = getCopyTestsResource(); +// +// LookupUtil.getResourceGroupManager().addResourcesToGroup(subject, resourceGroup.getId(), new int[] { res.getId() }); +// +// assertEquals("No validation should occur on the copied notifications", 0, TestAlertSender.getValidateMethodCallCount()); +// +// AlertDefinitionManagerLocal adm = LookupUtil.getAlertDefinitionManager(); +// AlertDefinitionCriteria adCrit = new AlertDefinitionCriteria(); +// adCrit.addFilterResourceIds(res.getId()); +// adCrit.fetchAlertNotifications(true); +// +// List<AlertDefinition> foundAlertDefs = adm.findAlertDefinitionsByCriteria(subject, adCrit); +// junk.addAll(foundAlertDefs); +// +// //1 from the group, 1 from the template +// assertEquals("The new resource should have an alert definition obtained from the group.", 2, foundAlertDefs.size()); +// +// AlertDefinition groupOriginatingDef = null; +// for(AlertDefinition d : foundAlertDefs) { +// if ((universalName + " group").equals(d.getName())) { +// groupOriginatingDef = d; +// break; +// } +// } +// +// assertNotNull("The alert definition originating from the group not present on the resource.", groupOriginatingDef); +// +// testSingleDependentAlertDefinition(groupOriginatingDef, ParentType.GROUP, groupOriginatingDef.getGroupAlertDefinition().getId()); +// } +// +// public void testCorrectSubjectPassedOnResourceLevelAlertDefinitionCreation() throws Exception { +// TestAlertSender.setExpectedSubject(subject); +// +// AlertDefinitionManagerLocal adm = LookupUtil.getAlertDefinitionManager(); +// +// Resource res = resources.iterator().next(); +// +// AlertDefinition def = createDefinitionForTest("testCorrectSubjectPassedOnResourceLevelAlertDefinitionCreation", false); +// def.setResource(resources.iterator().next()); +// +// int id = adm.createAlertDefinition(subject, def, res.getId(), true); +// def.setId(id); +// +// resourceLevelAlertDefinitionId = id; +// +// junk.add(def); +// +// testMainAlertDefinition(id); +// } +// +// @Test(dependsOnMethods = { "testNotificationsCopiedOnAlertTemplateApplication", "testNotificationsCopiedOnGroupMemberAddition" }) +// public void testCorrectSubjectPassedOnGroupLevelAlertDefinitionCreation() throws Exception { +// TestAlertSender.setExpectedSubject(subject); +// +// GroupAlertDefinitionManagerLocal gadm = LookupUtil.getGroupAlertDefinitionManager(); +// +// AlertDefinition def = createDefinitionForTest("testCorrectSubjectPassedOnGroupLevelAlertDefinitionCreation", false); +// def.setResourceGroup(resourceGroup); +// +// int id = gadm.createGroupAlertDefinitions(subject, def, resourceGroup.getId()); +// def.setId(id); +// +// groupLevelAlertDefinitionId = id; +// +// junk.add(def); +// +// testMainAlertDefinition(id); +// List<AlertDefinition> deps = testDependentAlertDefinitions(id, ParentType.GROUP); +// +// junk.addAll(deps); +// } +// +// @Test(dependsOnMethods = { "testNotificationsCopiedOnAlertTemplateApplication", "testNotificationsCopiedOnGroupMemberAddition" }) +// public void testCorrectSubjectPassedOnTemplateLevelAlertDefinitionCreation() throws Exception { +// TestAlertSender.setExpectedSubject(subject); +// +// AlertTemplateManagerLocal atm = LookupUtil.getAlertTemplateManager(); +// +// AlertDefinition def = createDefinitionForTest("testCorrectSubjectPassedOnTemplateLevelAlertDefinitionCreation", false); +// def.setResourceGroup(resourceGroup); +// +// int id = atm.createAlertTemplate(subject, def, resourceType.getId()); +// def.setId(id); +// +// templateLevelAlertDefinitionId = id; +// +// junk.add(def); +// +// testMainAlertDefinition(id); +// List<AlertDefinition> deps = testDependentAlertDefinitions(id, ParentType.TEMPLATE); +// +// junk.addAll(deps); +// } +// +// @Test(dependsOnMethods = "testCorrectSubjectPassedOnResourceLevelAlertDefinitionCreation") +// public void testNoValidationWhenNoNotificationUpdateOnResourceLevel() throws Exception { +// TestAlertSender.setExpectedSubject(subject); +// TestAlertSender.resetValidateMethodCallCount(); +// +// AlertDefinitionManagerLocal adm = LookupUtil.getAlertDefinitionManager(); +// +// AlertDefinitionCriteria crit = new AlertDefinitionCriteria(); +// crit.addFilterId(resourceLevelAlertDefinitionId); +// crit.fetchAlertNotifications(true); +// crit.fetchConditions(true); +// +// List<AlertDefinition> foundDefs = adm.findAlertDefinitionsByCriteria(subject, crit); +// +// assertEquals("Failed to find the previously created resource level alert definition.", 1, foundDefs.size()); +// +// AlertDefinition foundDef = foundDefs.get(0); +// +// foundDef.setEnabled(true); +// +// adm.updateAlertDefinition(subject, resourceLevelAlertDefinitionId, foundDef, false); +// +// assertEquals("The notification validation method shouldn't have been called", 0, TestAlertSender.getValidateMethodCallCount()); +// } +// +// @Test(dependsOnMethods = "testCorrectSubjectPassedOnGroupLevelAlertDefinitionCreation") +// public void testNoValidationWhenNoNotificationUpdateOnGroupLevel() throws Exception { +// TestAlertSender.setExpectedSubject(subject); +// TestAlertSender.resetValidateMethodCallCount(); +// +// AlertDefinitionManagerLocal adm = LookupUtil.getAlertDefinitionManager(); +// +// AlertDefinitionCriteria crit = new AlertDefinitionCriteria(); +// crit.addFilterId(groupLevelAlertDefinitionId); +// crit.fetchAlertNotifications(true); +// crit.fetchConditions(true); +// +// List<AlertDefinition> foundDefs = adm.findAlertDefinitionsByCriteria(subject, crit); +// +// assertEquals("Failed to find the previously created group level alert definition.", 1, foundDefs.size()); +// +// AlertDefinition foundDef = foundDefs.get(0); +// +// foundDef.setEnabled(true); +// +// GroupAlertDefinitionManagerLocal gadm = LookupUtil.getGroupAlertDefinitionManager(); +// gadm.updateGroupAlertDefinitions(subject, foundDef, true); +// +// assertEquals("The notification validation method shouldn't have been called", 0, TestAlertSender.getValidateMethodCallCount()); +// } +// +// @Test(dependsOnMethods = "testCorrectSubjectPassedOnTemplateLevelAlertDefinitionCreation") +// public void testNoValidationWhenNoNotificationUpdateOnTemplateLevel() throws Exception { +// TestAlertSender.setExpectedSubject(subject); +// TestAlertSender.resetValidateMethodCallCount(); +// +// AlertDefinitionManagerLocal adm = LookupUtil.getAlertDefinitionManager(); +// +// AlertDefinitionCriteria crit = new AlertDefinitionCriteria(); +// crit.addFilterId(templateLevelAlertDefinitionId); +// crit.fetchAlertNotifications(true); +// crit.fetchConditions(true); +// +// List<AlertDefinition> foundDefs = adm.findAlertDefinitionsByCriteria(subject, crit); +// +// assertEquals("Failed to find the previously created resource level alert definition.", 1, foundDefs.size()); +// +// AlertDefinition foundDef = foundDefs.get(0); +// +// foundDef.setEnabled(true); +// +// AlertTemplateManagerLocal atm = LookupUtil.getAlertTemplateManager(); +// +// atm.updateAlertTemplate(subject, foundDef, true); +// +// assertEquals("The notification validation method shouldn't have been called", 0, TestAlertSender.getValidateMethodCallCount()); +// } +// +// @Test(dependsOnMethods = "testNoValidationWhenNoNotificationUpdateOnResourceLevel") +// public void testCorrectSubjectPassedOnResourceLevelAlertDefinitionUpdate() throws Exception { +// TestAlertSender.setExpectedSubject(subject); +// TestAlertSender.resetValidateMethodCallCount(); +// +// AlertDefinitionManagerLocal adm = LookupUtil.getAlertDefinitionManager(); +// +// AlertDefinitionCriteria crit = new AlertDefinitionCriteria(); +// crit.addFilterId(resourceLevelAlertDefinitionId); +// crit.fetchAlertNotifications(true); +// crit.fetchConditions(true); +// +// List<AlertDefinition> foundDefs = adm.findAlertDefinitionsByCriteria(subject, crit); +// +// assertEquals("Failed to find the previously created resource level alert definition.", 1, foundDefs.size()); +// +// AlertDefinition foundDef = foundDefs.get(0); +// +// AlertNotification newNotif = createAlertNotificationForTest(foundDef, false); +// //just add some dummy config property so that the 2 notifs are distinguishable from each other +// //and are saved separately +// newNotif.getConfiguration().put(new PropertySimple("foo-resource", "bar")); +// +// adm.updateAlertDefinition(subject, resourceLevelAlertDefinitionId, foundDef, false); +// +// assertEquals("Validation should have been called for a new notification during alert def update", 1, TestAlertSender.getValidateMethodCallCount()); +// } +// +// @Test(dependsOnMethods = "testCorrectSubjectPassedOnGroupLevelAlertDefinitionCreation") +// public void testCorrectSubjectPassedOnGroupLevelAlertDefinitionUpdate() throws Exception { +// TestAlertSender.setExpectedSubject(subject); +// TestAlertSender.resetValidateMethodCallCount(); +// +// AlertDefinitionManagerLocal adm = LookupUtil.getAlertDefinitionManager(); +// +// AlertDefinitionCriteria crit = new AlertDefinitionCriteria(); +// crit.addFilterId(groupLevelAlertDefinitionId); +// crit.fetchAlertNotifications(true); +// crit.fetchConditions(true); +// +// List<AlertDefinition> foundDefs = adm.findAlertDefinitionsByCriteria(subject, crit); +// +// assertEquals("Failed to find the previously created group level alert definition.", 1, foundDefs.size()); +// +// AlertDefinition foundDef = foundDefs.get(0); +// +// AlertNotification newNotif = createAlertNotificationForTest(foundDef, false); +// //just add some dummy config property so that the 2 notifs are distinguishable from each other +// //and are saved separately +// newNotif.getConfiguration().put(new PropertySimple("foo-group", "bar")); +// +// GroupAlertDefinitionManagerLocal gadm = LookupUtil.getGroupAlertDefinitionManager(); +// gadm.updateGroupAlertDefinitions(subject, foundDef, true); +// +// //notice that the validation should be called just once, even though in effect we're creating 11 notifs +// //1 for group and 10 for its members. +// assertEquals("Validation should have been called for a new notification during alert def update", 1, TestAlertSender.getValidateMethodCallCount()); +// } +// +// @Test(dependsOnMethods = "testCorrectSubjectPassedOnTemplateLevelAlertDefinitionCreation") +// public void testCorrectSubjectPassedOnTemplateLevelAlertDefinitionUpdate() throws Exception { +// TestAlertSender.setExpectedSubject(subject); +// TestAlertSender.resetValidateMethodCallCount(); +// +// AlertDefinitionManagerLocal adm = LookupUtil.getAlertDefinitionManager(); +// +// AlertDefinitionCriteria crit = new AlertDefinitionCriteria(); +// crit.addFilterId(templateLevelAlertDefinitionId); +// crit.fetchAlertNotifications(true); +// crit.fetchConditions(true); +// +// List<AlertDefinition> foundDefs = adm.findAlertDefinitionsByCriteria(subject, crit); +// +// assertEquals("Failed to find the previously created template level alert definition.", 1, foundDefs.size()); +// +// AlertDefinition foundDef = foundDefs.get(0); +// +// AlertNotification newNotif = createAlertNotificationForTest(foundDef, false); +// //just add some dummy config property so that the 2 notifs are distinguishable from each other +// //and are saved separately +// newNotif.getConfiguration().put(new PropertySimple("foo-template", "bar")); +// +// AlertTemplateManagerLocal atm = LookupUtil.getAlertTemplateManager(); +// atm.updateAlertTemplate(subject, foundDef, true); +// +// //notice that the validation should be called just once, even though in effect we're creating 11 notifs +// //1 for template and 10 for its members. +// assertEquals("Validation should have been called for a new notification during alert def update", 1, TestAlertSender.getValidateMethodCallCount()); +// } +// +// private void removeNoExceptions(final Object o) { +// try { +// executeInTransaction(new TransactionCallback() { +// public void execute() { +// EntityManager em = getEntityManager(); +// Object o2 = em.merge(o); +// +// if (o2 instanceof Resource) { +// ResourceTreeHelper.deleteResource(em, (Resource) o2); +// } else { +// em.remove(o2); +// } +// } +// }); +// } catch (Exception e) { +// LOG.error("Failed to DELETE an object from database: " + o, e); +// } +// } +// +// private AlertDefinition createDefinition(String name) { +// AlertDefinition ret = new AlertDefinition(); +// ret.setName(name); +// ret.setPriority(AlertPriority.MEDIUM); +// ret.setAlertDampening(new AlertDampening(AlertDampening.Category.NONE)); +// ret.setConditionExpression(BooleanExpression.ANY); +// ret.setRecoveryId(0); +// +// return ret; +// } +// +// private AlertDefinition createDefinitionForTest(String name, boolean precanned) { +// AlertDefinition def = createDefinition(name); +// createAlertNotificationForTest(def, precanned); +// +// return def; +// } +// +// private AlertNotification createAlertNotificationForTest(AlertDefinition alertDefinition, boolean precanned) { +// AlertNotification notif = new AlertNotification("Test Alert Sender"); +// +// Configuration alertConfig = new Configuration(); +// +// if (precanned) { +// alertConfig.put(new PropertySimple(TestAlertSender.PERSISTENT_PROPERTY_NAME, TestAlertSender.PERSISTEN_PROPERTY_EXPECTED_VALUE)); +// } else { +// alertConfig.put(new PropertySimple(TestAlertSender.PERSISTENT_PROPERTY_NAME, "persistent")); +// alertConfig.put(new PropertySimple(TestAlertSender.EPHEMERAL_PROPERTY_NAME, "ephemeral")); +// } +// +// Configuration extraConfig = new Configuration(); +// +// if (precanned) { +// extraConfig.put(new PropertySimple(TestAlertSender.PERSISTENT_PROPERTY_NAME, TestAlertSender.PERSISTEN_PROPERTY_EXPECTED_VALUE)); +// } else { +// extraConfig.put(new PropertySimple(TestAlertSender.PERSISTENT_PROPERTY_NAME, "persistent")); +// extraConfig.put(new PropertySimple(TestAlertSender.EPHEMERAL_PROPERTY_NAME, "ephemeral")); +// } +// +// notif.setConfiguration(alertConfig); +// notif.setExtraConfiguration(extraConfig); +// +// alertDefinition.addAlertNotification(notif); +// notif.setAlertDefinition(alertDefinition); +// +// return notif; +// } +// +// private void testMainAlertDefinition(int id) { +// AlertDefinitionCriteria crit = new AlertDefinitionCriteria(); +// crit.addFilterId(id); +// crit.fetchAlertNotifications(true); +// +// List<AlertDefinition> checkList = +// LookupUtil.getAlertDefinitionManager().findAlertDefinitionsByCriteria(subject, crit); +// +// assertNotNull("Failed to retrieve the save alert definition", checkList); +// assertEquals("The alert definition should have been saved.", 1, checkList.size()); +// +// AlertDefinition check = checkList.get(0); +// +// assertEquals("There should be exactly 1 notification on the definition", 1, check.getAlertNotifications() +// .size()); +// +// Configuration config = check.getAlertNotifications().get(0).getConfiguration(); +// assertEquals("Unexpected persistent value in notif config", TestAlertSender.PERSISTEN_PROPERTY_EXPECTED_VALUE, +// config.getSimpleValue(TestAlertSender.PERSISTENT_PROPERTY_NAME, null)); +// assertNull("Ephemeral property seems to have been saved", +// config.getSimpleValue(TestAlertSender.EPHEMERAL_PROPERTY_NAME, null)); +// } +// +// private List<AlertDefinition> testDependentAlertDefinitions(int expectedParentId, ParentType parentType) { +// AlertDefinitionCriteria crit = new AlertDefinitionCriteria(); +// +// Set<Integer> resourceIds = new HashSet<Integer>(resources.size()); +// for (Resource r : resources) { +// resourceIds.add(r.getId()); +// } +// +// if (parentType == ParentType.TEMPLATE) { +// crit.addFilterAlertTemplateParentId(expectedParentId); +// } else if (parentType == ParentType.GROUP) { +// crit.addFilterGroupAlertDefinitionId(expectedParentId); +// } +// +// crit.fetchAlertNotifications(true); +// +// List<AlertDefinition> checkList = +// LookupUtil.getAlertDefinitionManager().findAlertDefinitionsByCriteria(subject, crit); +// +// assertNotNull("Failed to retrieve the save alert definition", checkList); +// assertEquals("The dependent alert definitions should have been saved.", resources.size(), checkList.size()); +// +// for (AlertDefinition check : checkList) { +// testSingleDependentAlertDefinition(check, parentType, expectedParentId); +// } +// +// return checkList; +// } +// +// private void testSingleDependentAlertDefinition(AlertDefinition alertDef, ParentType parentType, int expectedParentId) { +// assertEquals("There should be exactly 1 notification on the definition " + alertDef, 1, alertDef +// .getAlertNotifications().size()); +// +// Configuration config = alertDef.getAlertNotifications().get(0).getConfiguration(); +// assertEquals("Unexpected persistent value in notif config " + alertDef, +// TestAlertSender.PERSISTEN_PROPERTY_EXPECTED_VALUE, +// config.getSimpleValue(TestAlertSender.PERSISTENT_PROPERTY_NAME, null)); +// assertNull("Ephemeral property seems to have been saved " + alertDef, +// config.getSimpleValue(TestAlertSender.EPHEMERAL_PROPERTY_NAME, null)); +// +// if (parentType == ParentType.GROUP) { +// assertEquals("The group parent id has unexpected value", expectedParentId, alertDef.getGroupAlertDefinition().getId()); +// } else if (parentType == ParentType.TEMPLATE) { +// assertEquals("The parent id has unexpected value", Integer.valueOf(expectedParentId), alertDef.getParentId()); +// } +// } +// +// private Resource createResourceForTest(String resourceKey) { +// Resource res = new ResourceBuilder().createPlatform().withRandomUuid().withResourceKey(resourceKey) +// .withResourceType(resourceType).withName(resourceKey) +// .withInventoryStatus(InventoryStatus.COMMITTED).build(); +// res.setAgent(agent); +// +// return res; +// } +//} diff --git a/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/alert/TestAlertSender.java b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/alert/TestAlertSender.java new file mode 100644 index 0000000..900d74c --- /dev/null +++ b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/alert/TestAlertSender.java @@ -0,0 +1,107 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2012 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.alert; + +import org.testng.Assert; + +import org.rhq.core.domain.alert.Alert; +import org.rhq.core.domain.alert.notification.SenderResult; +import org.rhq.core.domain.auth.Subject; +import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.configuration.PropertySimple; +import org.rhq.enterprise.server.plugin.pc.ServerPluginComponent; +import org.rhq.enterprise.server.plugin.pc.alert.AlertSender; +import org.rhq.enterprise.server.plugin.pc.alert.AlertSenderValidationResults; + +/** + * + * + * @author Lukas Krejci + */ +public class TestAlertSender extends AlertSender<ServerPluginComponent> { + + public static final String NAME = "Test Alert Sender"; + + public static final String PERSISTENT_PROPERTY_NAME = "persistent"; + public static final String PERSISTEN_PROPERTY_EXPECTED_VALUE = "persistentephemeral"; + public static final String EPHEMERAL_PROPERTY_NAME = "ephemeral"; + + private static Subject EXPECTED_SUBJECT; + private static volatile int VALIDATE_METHOD_CALL_COUNT; + private static Runnable VALIDATION_CHECKER; + + public static void setExpectedSubject(Subject subject) { + EXPECTED_SUBJECT = subject; + } + + public static void setValidationChecker(Runnable validationChecker) { + VALIDATION_CHECKER = validationChecker; + } + + public static int getValidateMethodCallCount() { + return VALIDATE_METHOD_CALL_COUNT; + } + + public static void resetValidateMethodCallCount() { + VALIDATE_METHOD_CALL_COUNT = 0; + } + + @Override + public SenderResult send(Alert alert) { + SenderResult ret = new SenderResult(); + ret.addSuccessMessage("kachny"); + + return ret; + } + + @Override + public AlertSenderValidationResults validateAndFinalizeConfiguration(Subject subject) { + ++VALIDATE_METHOD_CALL_COUNT; + + if (EXPECTED_SUBJECT != null && !subject.equals(EXPECTED_SUBJECT)) { + throw new AssertionError("Unexpected subject. Expected " + EXPECTED_SUBJECT + " but was " + subject); + } + + if (VALIDATION_CHECKER != null) { + VALIDATION_CHECKER.run(); + } + + if (alertParameters.getSimple(EPHEMERAL_PROPERTY_NAME) == null) { + Assert.fail("Ephemeral property not present in alert parameters during validation. This should never happen."); + } + + if (extraParameters.getSimple(EPHEMERAL_PROPERTY_NAME) == null) { + Assert.fail("Ephemeral property not present in extra parameters during validation. This should never happen."); + } + + updateConfig(alertParameters); + updateConfig(extraParameters); + + return new AlertSenderValidationResults(alertParameters, extraParameters); + } + + private void updateConfig(Configuration configuration) { + String persistentValue = configuration.getSimpleValue(PERSISTENT_PROPERTY_NAME, ""); + String ephemeralValue = configuration.getSimpleValue(EPHEMERAL_PROPERTY_NAME, ""); + + configuration.put(new PropertySimple(PERSISTENT_PROPERTY_NAME, persistentValue + ephemeralValue)); + configuration.remove(EPHEMERAL_PROPERTY_NAME); + } +} diff --git a/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/alert/TestAlertSenderPluginService.java b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/alert/TestAlertSenderPluginService.java new file mode 100644 index 0000000..9aae985 --- /dev/null +++ b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/alert/TestAlertSenderPluginService.java @@ -0,0 +1,67 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2012 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.alert; + +import java.util.Collections; +import java.util.List; + +import org.rhq.core.domain.plugin.ServerPlugin; +import org.rhq.enterprise.server.TestServerPluginService; +import org.rhq.enterprise.server.plugin.pc.AbstractTypeServerPluginContainer; +import org.rhq.enterprise.server.plugin.pc.MasterServerPluginContainer; +import org.rhq.enterprise.server.plugin.pc.ServerPluginEnvironment; +import org.rhq.enterprise.server.plugin.pc.ServerPluginManager; +import org.rhq.enterprise.server.plugin.pc.alert.AlertSenderPluginManager; +import org.rhq.enterprise.server.plugin.pc.alert.AlertServerPluginContainer; + +/** + * + * + * @author Lukas Krejci + */ +public class TestAlertSenderPluginService extends TestServerPluginService { + + @Override + protected List<AbstractTypeServerPluginContainer> createPluginContainers(MasterServerPluginContainer master) { + return Collections.<AbstractTypeServerPluginContainer>singletonList(new TestAlertServerPluginContainer(master)); + } + + class TestAlertServerPluginContainer extends AlertServerPluginContainer { + public TestAlertServerPluginContainer(MasterServerPluginContainer master) { + super(master); + } + + @Override + protected ServerPluginManager createPluginManager() { + return new TestAlertServerPluginManager(this); + } + } + + class TestAlertServerPluginManager extends AlertSenderPluginManager { + public TestAlertServerPluginManager(AlertServerPluginContainer pc) { + super(pc); + } + + @Override + protected ServerPlugin getPlugin(ServerPluginEnvironment env) { + return TestServerPluginService.getPlugin(env); + } + } +} diff --git a/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/content/test/AdvisoryManagerBeanTest.java b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/content/test/AdvisoryManagerBeanTest.java index abbd145..e7c0b35 100644 --- a/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/content/test/AdvisoryManagerBeanTest.java +++ b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/content/test/AdvisoryManagerBeanTest.java @@ -3,8 +3,6 @@ package org.rhq.enterprise.server.content.test; import javax.persistence.EntityManager; import javax.transaction.TransactionManager;
-import org.testng.annotations.AfterMethod; -import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test;
import org.rhq.core.domain.auth.Subject; @@ -34,8 +32,8 @@ public class AdvisoryManagerBeanTest extends AbstractEJB3Test { private Subject overlord; private PackageType packageType1;
- @BeforeMethod - public void setupBeforeMethod() throws Exception { + @Override + protected void beforeMethod() throws Exception { TransactionManager tx = getTransactionManager(); tx.begin();
@@ -44,8 +42,8 @@ public class AdvisoryManagerBeanTest extends AbstractEJB3Test { overlord = LookupUtil.getSubjectManager().getOverlord(); }
- @AfterMethod - public void tearDownAfterMethod() throws Exception { + @Override + protected void afterMethod() throws Exception { TransactionManager tx = getTransactionManager(); if (tx != null) { tx.rollback(); diff --git a/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/drift/AbstractDriftServerTest.java b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/drift/AbstractDriftServerTest.java new file mode 100644 index 0000000..3f1fa2a --- /dev/null +++ b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/drift/AbstractDriftServerTest.java @@ -0,0 +1,264 @@ +/* + * 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 org.rhq.core.domain.resource.ResourceCategory.SERVER; +import static org.rhq.enterprise.server.util.LookupUtil.getSubjectManager; + +import java.io.File; +import java.lang.reflect.Method; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.NoResultException; +import javax.persistence.NonUniqueResultException; + +import org.apache.commons.io.FileUtils; +import org.testng.annotations.Test; + +import org.rhq.core.domain.auth.Subject; +import org.rhq.core.domain.criteria.ResourceCriteria; +import org.rhq.core.domain.drift.Drift; +import org.rhq.core.domain.drift.DriftDefinition; +import org.rhq.core.domain.drift.DriftDefinitionTemplate; +import org.rhq.core.domain.resource.Agent; +import org.rhq.core.domain.resource.Resource; +import org.rhq.core.domain.resource.ResourceType; +import org.rhq.core.domain.shared.ResourceBuilder; +import org.rhq.core.domain.shared.ResourceTypeBuilder; +import org.rhq.enterprise.server.plugin.ServerPluginsLocal; +import org.rhq.enterprise.server.test.AbstractEJB3Test; +import org.rhq.enterprise.server.test.TestServerCommunicationsService; +import org.rhq.enterprise.server.test.TransactionCallback; +import org.rhq.enterprise.server.util.LookupUtil; +import org.rhq.enterprise.server.util.ResourceTreeHelper; + +@Test(groups = "drift") +public abstract class AbstractDriftServerTest extends AbstractEJB3Test { + + protected final String RESOURCE_TYPE_NAME = getClass().getSimpleName() + "_RESOURCE_TYPE"; + + protected final String AGENT_NAME = getClass().getSimpleName() + "_AGENT"; + + protected final String RESOURCE_NAME = getClass().getSimpleName() + "_RESOURCE"; + + private ServerPluginsLocal serverPluginsMgr; + + protected DriftServerPluginService driftServerPluginService; + + protected TestServerCommunicationsService agentServiceContainer; + + protected ResourceType resourceType; + + protected Agent agent; + + protected Resource resource; + + // This is supposed to be an AfterClass method to do final cleanup, but Arquillian currently + // runs the entire Suite lifecycle on each test. So, Before/AfterXXX all act like Before/AfterMethod. + // So, it does nothing for now unless called from a superclass, and we simply leave junk in the DB. + //@AfterClass + protected void afterClass() throws Exception { + purgeDB(); + executeInTransaction(false, new TransactionCallback() { + @Override + public void execute() throws Exception { + purgeDB(getEntityManager()); + } + }); + } + + @Override + protected void beforeMethod(Method testMethod) throws Exception { + + initDriftServer(); + initAgentServices(); + + InitDB annotation = testMethod.getAnnotation(InitDB.class); + if (annotation == null || annotation.value()) { + initDB(); + } else { + fetchDB(); + } + } + + @Override + protected void afterMethod() throws Exception { + shutDownDriftServer(); + shutDownAgentServices(); + } + + private void initDriftServer() throws Exception { + driftServerPluginService = new DriftServerPluginService(); + prepareCustomServerPluginService(driftServerPluginService); + driftServerPluginService.masterConfig.getPluginDirectory().mkdirs(); + + String projectVersion = System.getProperty("project.version"); + + File jpaDriftPlugin = new File("../plugins/drift-rhq/target/rhq-serverplugin-drift-" + projectVersion + ".jar"); + assertTrue("Drift server plugin JAR file not found at" + jpaDriftPlugin.getPath(), jpaDriftPlugin.exists()); + FileUtils.copyFileToDirectory(jpaDriftPlugin, driftServerPluginService.masterConfig.getPluginDirectory()); + + driftServerPluginService.startMasterPluginContainer(); + + //serverPluginsMgr = LookupUtil.getServerPlugins(); + } + + private void initAgentServices() { + agentServiceContainer = prepareForTestAgents(); + agentServiceContainer.driftService = new TestDefService(); + } + + private void shutDownDriftServer() throws Exception { + unprepareServerPluginService(); + //already done by the above call + //driftServerPluginService.stopMasterPluginContainer(); + } + + private void shutDownAgentServices() { + agentServiceContainer = null; + unprepareForTestAgents(); + } + + private void initDB() throws Exception { + purgeDB(); + executeInTransaction(false, new TransactionCallback() { + @Override + public void execute() throws Exception { + EntityManager em = getEntityManager(); + initResourceType(); + initAgent(); + initResource(); + + em.persist(resourceType); + em.persist(agent); + resource.setAgent(agent); + em.persist(resource); + + initDB(em); + } + }); + } + + private void fetchDB() throws Exception { + executeInTransaction(false, new TransactionCallback() { + @Override + public void execute() throws Exception { + ResourceCriteria c = new ResourceCriteria(); + c.addFilterName(RESOURCE_NAME); + c.addFilterInventoryStatus(null); + resource = LookupUtil.getResourceManager().findResourcesByCriteria(getOverlord(), c).get(0); + resource = em.find(Resource.class, resource.getId()); + resourceType = resource.getResourceType(); + agent = resource.getAgent(); + + fetchDB(em); + } + }); + } + + protected void fetchDB(EntityManager em) throws Exception { + } + + private void purgeDB() { + executeInTransaction(false, new TransactionCallback() { + @Override + public void execute() throws Exception { + EntityManager em = getEntityManager(); + + em.createQuery("delete from JPADrift ").executeUpdate(); + em.createQuery("delete from JPADriftChangeSet").executeUpdate(); + em.createQuery("delete from JPADriftSet").executeUpdate(); + em.createQuery("delete from JPADriftFile").executeUpdate(); + em.createQuery("delete from DriftDefinition").executeUpdate(); + em.createQuery("delete from DriftDefinitionTemplate").executeUpdate(); + + deleteEntity(Resource.class, RESOURCE_NAME, em); + deleteEntity(Agent.class, AGENT_NAME, em); + deleteEntity(ResourceType.class, RESOURCE_TYPE_NAME, em); + + purgeDB(em); + } + }); + } + + protected void purgeDB(EntityManager em) { + } + + protected void initDB(EntityManager em) { + } + + protected void deleteEntity(Class<?> clazz, String name, EntityManager em) { + try { + Object entity = em + .createQuery("select entity from " + clazz.getSimpleName() + " entity where entity.name = :name") + .setParameter("name", name).getSingleResult(); + if (clazz.equals(Resource.class)) { + ResourceTreeHelper.deleteResource(em, (Resource) entity); + } else { + em.remove(entity); + } + } catch (NoResultException e) { + // we can ignore no results because this code will run when the db + // is empty and we expect no results in that case + } catch (NonUniqueResultException e) { + // we will fail here to let the person running the test know that + // the database may not be in a consistent state + fail("Purging " + name + " failed. Expected to find one instance of " + clazz.getSimpleName() + + " but found more than one. The database may not be in a consistent state."); + } + } + + protected void initResourceType() { + resourceType = new ResourceTypeBuilder().createResourceType().withId(0).withName(RESOURCE_TYPE_NAME) + .withCategory(SERVER).withPlugin(RESOURCE_TYPE_NAME.toLowerCase()).build(); + } + + protected void initAgent() { + agent = new Agent(AGENT_NAME, AGENT_NAME, 17080, "", AGENT_NAME + "_TOKEN"); + } + + protected void initResource() { + resource = new ResourceBuilder().createResource().withId(0).withName(RESOURCE_NAME) + .withResourceKey(RESOURCE_NAME).withRandomUuid().withResourceType(resourceType).build(); + } + + protected Subject getOverlord() { + return getSubjectManager().getOverlord(); + } + + protected String toString(DriftDefinition def) { + return "DriftDefinition[id: " + def.getId() + ", name: " + def.getName() + "]"; + } + + protected String toString(DriftDefinitionTemplate template) { + return DriftDefinitionTemplate.class.getSimpleName() + "[id: " + template.getId() + ", name: " + + template.getName() + "]"; + } + + protected Drift findDriftByPath(List<? extends Drift> drifts, String path) { + for (Drift drift : drifts) { + if (drift.getPath().equals(path)) { + return drift; + } + } + return null; + } + +} diff --git a/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/drift/DriftServerPluginService.java b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/drift/DriftServerPluginService.java new file mode 100644 index 0000000..46d725f --- /dev/null +++ b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/drift/DriftServerPluginService.java @@ -0,0 +1,63 @@ +/* + * 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 java.util.Collections; +import java.util.List; + +import org.rhq.core.domain.plugin.ServerPlugin; +import org.rhq.enterprise.server.TestServerPluginService; +import org.rhq.enterprise.server.plugin.pc.AbstractTypeServerPluginContainer; +import org.rhq.enterprise.server.plugin.pc.MasterServerPluginContainer; +import org.rhq.enterprise.server.plugin.pc.ServerPluginEnvironment; +import org.rhq.enterprise.server.plugin.pc.ServerPluginManager; +import org.rhq.enterprise.server.plugin.pc.drift.DriftServerPluginContainer; +import org.rhq.enterprise.server.plugin.pc.drift.DriftServerPluginManager; + +public class DriftServerPluginService extends TestServerPluginService { + + @Override + protected List<AbstractTypeServerPluginContainer> createPluginContainers(MasterServerPluginContainer master) { + return Collections.<AbstractTypeServerPluginContainer>singletonList(new TestDriftServerPluginContainer(master)); + } + + + class TestDriftServerPluginContainer extends DriftServerPluginContainer { + public TestDriftServerPluginContainer(MasterServerPluginContainer master) { + super(master); + } + + @Override + protected ServerPluginManager createPluginManager() { + return new TestDriftServerPluginManager(this); + } + } + + class TestDriftServerPluginManager extends DriftServerPluginManager { + public TestDriftServerPluginManager(DriftServerPluginContainer pc) { + super(pc); + } + + @Override + protected ServerPlugin getPlugin(ServerPluginEnvironment env) { + return TestServerPluginService.getPlugin(env); + } + } +} diff --git a/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/drift/DriftTemplateManagerBeanTest.java b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/drift/DriftTemplateManagerBeanTest.java new file mode 100644 index 0000000..14d7cc1 --- /dev/null +++ b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/drift/DriftTemplateManagerBeanTest.java @@ -0,0 +1,653 @@ +/* + * 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.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +import javax.ejb.EJBException; +import javax.persistence.EntityManager; + +import org.testng.annotations.Test; + +import org.rhq.core.domain.auth.Subject; +import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.criteria.DriftCriteria; +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.criteria.JPADriftCriteria; +import org.rhq.core.domain.drift.Drift; +import org.rhq.core.domain.drift.DriftCategory; +import org.rhq.core.domain.drift.DriftChangeSet; +import org.rhq.core.domain.drift.DriftConfigurationDefinition.DriftHandlingMode; +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.enterprise.server.util.LookupUtil; +import org.rhq.test.AssertUtils; + +public class DriftTemplateManagerBeanTest extends AbstractDriftServerTest { + + private static final String TEST_CREATE_TEMPLATE = "test-createTemplateForNegativeUpdateTests"; + private static final String TEST_PIN_TEMPLATE = "test-pinTemplate"; + + private DriftTemplateManagerLocal templateMgr; + private DriftManagerLocal driftMgr; + + private static final String drift1Path = "drift.1"; + private static final String drift2Path = "drift.2"; + + private static final String driftFile1Hash = "a1b2c3"; + private static final String driftFile2Hash = "1a2b3c"; + + // 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 thier 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() throws Exception { + super.beforeMethod(); + + templateMgr = getDriftTemplateManager(); + driftMgr = getDriftManager(); + } + + @Override + protected void initDB(EntityManager em) { + 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); + } + } + }; + } + + @Override + protected void fetchDB(EntityManager em) throws Exception { + Subject overlord = getOverlord(); + JPADriftServerLocal driftServer = LookupUtil.getJPADriftServer(); + driftFile1 = driftServer.getDriftFile(overlord, driftFile1Hash); + driftFile2 = driftServer.getDriftFile(overlord, driftFile2Hash); + DriftCriteria c = new JPADriftCriteria(); + c.addFilterDriftHandlingModes((DriftHandlingMode[]) null); + c.addFilterCategories((DriftCategory[]) null); + c.addFilterResourceIds((Integer[]) null); + c.addFilterPath(drift1Path); + List<JPADrift> drift = driftServer.findDriftsByCriteria(overlord, c); + if (0 != drift.size()) { + drift1 = em.find(JPADrift.class, drift.get(0).getId()); + } + c.addFilterPath(drift2Path); + drift = driftServer.findDriftsByCriteria(overlord, c); + if (0 != drift.size()) { + drift2 = em.find(JPADrift.class, drift.get(0).getId()); + } + } + + @Test(dependsOnGroups = "pinning") + public void createNewTemplate() { + final DriftDefinition definition = new DriftDefinition(new Configuration()); + definition.setName("test-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 { + EntityManager em = getEntityManager(); + + 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); + } + }); + } + + @Test(groups = "negativeUpdate") + public 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); + getEntityManager().clear(); + //System.out.println("Created " + template.toString(false)); + } + + @Test(groups = "negativeUpdate", dependsOnMethods = "createTemplateForNegativeUpdateTests", expectedExceptions = EJBException.class, expectedExceptionsMessageRegExp = ".*base directory.*cannot be modified") + @InitDB(false) + public 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") + @InitDB(false) + public 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") + @InitDB(false) + public void doNotAllowTemplateNameToBeUpdated() { + DriftDefinitionTemplate template = loadTemplate(TEST_CREATE_TEMPLATE); + template.setName("A new name"); + + templateMgr.updateTemplate(getOverlord(), template); + } + + @Test(groups = "negativeUpdate", dependsOnMethods = "createTemplateForNegativeUpdateTests", expectedExceptions = EJBException.class, expectedExceptionsMessageRegExp = ".*template name must be unique.*") + @InitDB(false) + public 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("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, "attachedDef1", true); + final DriftDefinition attachedDef2 = createDefinition(template, "attachedDef2", true); + final DriftDefinition detachedDef1 = createDefinition(template, "detachedDef1", false); + final DriftDefinition detachedDef2 = createDefinition(template, "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()); + } + } + + @Test(groups = "pinning", dependsOnGroups = "negativeUpdate") + public 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, "attachedDef1", true); + final DriftDefinition attachedDef2 = createDefinition(template, "attachedDef2", true); + final DriftDefinition detachedDef1 = createDefinition(template, "detachedDef1", false); + final DriftDefinition detachedDef2 = createDefinition(template, "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 { + EntityManager em = getEntityManager(); + + 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") + @InitDB(false) + public 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") + @InitDB(false) + public 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("attachedDef1") || d.getName().equals("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") + @InitDB(false) + public 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("detachedDef1") || d.getName().equals("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, "attachedDef1", true); + final DriftDefinition attachedDef2 = createDefinition(template, "attachedDef2", true); + final DriftDefinition detachedDef1 = createDefinition(template, "detachedDef1", false); + final DriftDefinition detachedDef2 = createDefinition(template, "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 { + EntityManager em = getEntityManager(); + + 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); + } + +} diff --git a/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/drift/InitDB.java b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/drift/InitDB.java new file mode 100644 index 0000000..65a6523 --- /dev/null +++ b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/drift/InitDB.java @@ -0,0 +1,32 @@ +/* + * 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.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +@Retention(RUNTIME) +@Target({ElementType.METHOD }) +public @interface InitDB { + boolean value() default true; +} diff --git a/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/drift/JPADriftServerBeanTest.java b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/drift/JPADriftServerBeanTest.java new file mode 100644 index 0000000..88a0143 --- /dev/null +++ b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/drift/JPADriftServerBeanTest.java @@ -0,0 +1,308 @@ +/* + * 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.apache.commons.io.IOUtils.toInputStream; +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.DriftConfigurationDefinition.BaseDirValueContext.fileSystem; +import static org.rhq.core.domain.drift.DriftConfigurationDefinition.DriftHandlingMode.normal; +import static org.rhq.core.domain.drift.DriftFileStatus.LOADED; +import static org.rhq.enterprise.server.util.LookupUtil.getJPADriftServer; +import static org.rhq.test.AssertUtils.assertPropertiesMatch; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import javax.persistence.EntityManager; + +import org.testng.annotations.Test; + +import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.criteria.JPADriftChangeSetCriteria; +import org.rhq.core.domain.drift.Drift; +import org.rhq.core.domain.drift.DriftDefinition; +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.drift.dto.DriftChangeSetDTO; +import org.rhq.core.domain.drift.dto.DriftDTO; +import org.rhq.core.domain.drift.dto.DriftFileDTO; +import org.rhq.core.domain.util.PageList; +import org.rhq.enterprise.server.test.TransactionCallback; +import org.rhq.test.AssertUtils; + +@Test +public class JPADriftServerBeanTest extends AbstractDriftServerTest { + + private JPADriftServerLocal jpaDriftServer; + + private final String DRIFT_FILE_1_ID = "a1b2c3d4"; + + private final String DRIFT_FILE_2_ID = "1ab2b3c4d"; + + private JPADriftFile driftFile1; + + private JPADriftFile driftFile2; + + @Override + public void beforeMethod() throws Exception { + super.beforeMethod(); + + jpaDriftServer = getJPADriftServer(); + + driftFile1 = jpaDriftServer.persistDriftFile(new JPADriftFile(DRIFT_FILE_1_ID)); + driftFile2 = jpaDriftServer.persistDriftFile(new JPADriftFile(DRIFT_FILE_2_ID)); + + String driftFile1Content = "drift file 1 content..."; + String driftFile2Content = "drift file 2 content..."; + + jpaDriftServer.persistDriftFileData(driftFile1, toInputStream(driftFile1Content), driftFile1Content.length()); + jpaDriftServer.persistDriftFileData(driftFile2, toInputStream(driftFile2Content), driftFile2Content.length()); + + driftFile1 = jpaDriftServer.getDriftFile(getOverlord(), DRIFT_FILE_1_ID); + driftFile2 = jpaDriftServer.getDriftFile(getOverlord(), DRIFT_FILE_2_ID); + + assertDriftFilePersisted(driftFile1, "driftFile1", driftFile1Content); + assertDriftFilePersisted(driftFile2, "driftFile2", driftFile2Content); + } + + public void persistResourceChangeSet() { + // first create and persist the drift definition + final DriftDefinition driftDef = new DriftDefinition(new Configuration()); + driftDef.setName("test::persistResourceChangeSet"); + driftDef.setEnabled(true); + driftDef.setDriftHandlingMode(normal); + driftDef.setInterval(2400L); + driftDef.setBasedir(new DriftDefinition.BaseDirectory(fileSystem, "/foo/bar/test")); + driftDef.setResource(resource); + + executeInTransaction(false, new TransactionCallback() { + @Override + public void execute() throws Exception { + EntityManager em = getEntityManager(); + em.persist(driftDef); + } + }); + + // create the change set to be persisted + DriftChangeSetDTO changeSet = new DriftChangeSetDTO(); + changeSet.setCategory(COVERAGE); + changeSet.setVersion(1); + changeSet.setDriftDefinitionId(driftDef.getId()); + changeSet.setResourceId(resource.getId()); + changeSet.setDriftHandlingMode(normal); + changeSet.setCtime(System.currentTimeMillis()); + + DriftDTO drift1 = new DriftDTO(); + drift1.setCategory(FILE_ADDED); + drift1.setPath("drift.1"); + drift1.setChangeSet(changeSet); + drift1.setCtime(System.currentTimeMillis()); + drift1.setNewDriftFile(toDTo(driftFile1)); + + DriftDTO drift2 = new DriftDTO(); + drift2.setCategory(FILE_ADDED); + drift2.setPath("drift.2"); + drift2.setChangeSet(changeSet); + drift2.setCtime(System.currentTimeMillis()); + drift2.setNewDriftFile(toDTo(driftFile2)); + + Set<DriftDTO> drifts = new HashSet<DriftDTO>(); + drifts.add(drift1); + drifts.add(drift2); + changeSet.setDrifts(drifts); + + String newChangeSetId = jpaDriftServer.persistChangeSet(getOverlord(), changeSet); + + // verify that the change set was persisted + JPADriftChangeSetCriteria criteria = new JPADriftChangeSetCriteria(); + criteria.addFilterId(newChangeSetId); + criteria.fetchDrifts(true); + + PageList<JPADriftChangeSet> changeSets = jpaDriftServer.findDriftChangeSetsByCriteria(getOverlord(), criteria); + assertEquals("Expected to find one change set", 1, changeSets.size()); + + JPADriftChangeSet jpaChangeSet = changeSets.get(0); + assertEquals("Expected change set to contain two drifts. This could be a result of the change set not being " + + "persisted correctly or the criteria fetch being done incorrectly.", 2, jpaChangeSet.getDrifts().size()); + + AssertUtils + .assertPropertiesMatch("The change set was not persisted correctly", changeSet, jpaChangeSet, "id", "drifts", + "class", "ctime"); + + List<? extends Drift> expectedDrifts = asList(drift1, drift2); + List<? extends Drift> actualDrifts = new ArrayList(jpaChangeSet.getDrifts()); + + // We ignore the id and ctime properties because those are set by JPADriftServerBean + // and are somewhat implmentation specific. We ignore the directory property because + // it is really a calculated property. newDriftFile has to be compared separately + // since it does not implement equals. + AssertUtils.assertCollectionMatchesNoOrder("The change set drifts were not persisted correctly", + (List<Drift>) expectedDrifts, (List<Drift>) actualDrifts, "id", "ctime", "changeSet", "directory", + "newDriftFile", "class"); + + assertPropertiesMatch("The newDriftFile property was not set correctly for " + drift1, drift1.getNewDriftFile(), + findDriftByPath(actualDrifts, "drift.1").getNewDriftFile(), "class", "ctime") ; + assertPropertiesMatch("The newDriftFile property was not set correctly for " + drift2, drift2.getNewDriftFile(), + findDriftByPath(actualDrifts, "drift.2").getNewDriftFile(), "class", "ctime") ; + } + + public void persistTemplateChangeSet() { + // create the change set to be persisted + // + // Note that we do not set the drift definition id or resource id since + // the change set is not owned by a resource. It is owned by the + // resource type. + DriftChangeSetDTO changeSet = new DriftChangeSetDTO(); + changeSet.setCategory(COVERAGE); + changeSet.setVersion(1); + changeSet.setDriftHandlingMode(normal); + changeSet.setCtime(System.currentTimeMillis()); + + DriftDTO drift1 = new DriftDTO(); + drift1.setCategory(FILE_ADDED); + drift1.setPath("drift.1"); + drift1.setChangeSet(changeSet); + drift1.setCtime(System.currentTimeMillis()); + drift1.setNewDriftFile(toDTo(driftFile1)); + + DriftDTO drift2 = new DriftDTO(); + drift2.setCategory(FILE_ADDED); + drift2.setPath("drift.2"); + drift2.setChangeSet(changeSet); + drift2.setCtime(System.currentTimeMillis()); + drift2.setNewDriftFile(toDTo(driftFile2)); + + Set<DriftDTO> drifts = new HashSet<DriftDTO>(); + drifts.add(drift1); + drifts.add(drift2); + changeSet.setDrifts(drifts); + + String newChangeSetId = jpaDriftServer.persistChangeSet(getOverlord(), changeSet); + + // verify that the change set was persisted + JPADriftChangeSetCriteria criteria = new JPADriftChangeSetCriteria(); + criteria.addFilterId(newChangeSetId); + criteria.fetchDrifts(true); + + PageList<JPADriftChangeSet> changeSets = jpaDriftServer.findDriftChangeSetsByCriteria(getOverlord(), criteria); + assertEquals("Expected to find one change set", 1, changeSets.size()); + + JPADriftChangeSet jpaChangeSet = changeSets.get(0); + assertEquals("Expected change set to contain two drifts. This could be a result of the change set not being " + + "persisted correctly or the criteria fetch being done incorrectly.", 2, jpaChangeSet.getDrifts().size()); + + AssertUtils + .assertPropertiesMatch("The change set was not persisted correctly", changeSet, jpaChangeSet, "id", "drifts", + "class", "ctime"); + + List<? extends Drift> expectedDrifts = asList(drift1, drift2); + List<? extends Drift> actualDrifts = new ArrayList(jpaChangeSet.getDrifts()); + + // We ignore the id and ctime properties because those are set by JPADriftServerBean + // and are somewhat implmentation specific. We ignore the directory property because + // it is really a calculated property. newDriftFile has to be compared separately + // since it does not implement equals. + AssertUtils.assertCollectionMatchesNoOrder("The change set drifts were not persisted correctly", + (List<Drift>) expectedDrifts, (List<Drift>) actualDrifts, "id", "ctime", "changeSet", "directory", + "newDriftFile", "class"); + + assertPropertiesMatch("The newDriftFile property was not set correctly for " + drift1, drift1.getNewDriftFile(), + findDriftByPath(actualDrifts, "drift.1").getNewDriftFile(), "class", "ctime") ; + assertPropertiesMatch("The newDriftFile property was not set correctly for " + drift2, drift2.getNewDriftFile(), + findDriftByPath(actualDrifts, "drift.2").getNewDriftFile(), "class", "ctime") ; + } + + public void copyChangeSet() { + // first create the change set that will be copied + final JPADriftChangeSet changeSet = new JPADriftChangeSet(null, 0, COVERAGE, null); + changeSet.setDriftHandlingMode(normal); + + final JPADrift drift1 = new JPADrift(changeSet, "drift.1", FILE_ADDED, null, driftFile1); + final JPADrift drift2 = new JPADrift(changeSet, "drift.2", FILE_ADDED, null, driftFile2); + + final JPADriftSet driftSet = new JPADriftSet(); + driftSet.addDrift(drift1); + driftSet.addDrift(drift2); + + // next create the drift definition + final DriftDefinition driftDef = new DriftDefinition(new Configuration()); + driftDef.setName("test::copyChangeSet"); + driftDef.setEnabled(true); + driftDef.setDriftHandlingMode(normal); + driftDef.setInterval(2400L); + driftDef.setBasedir(new DriftDefinition.BaseDirectory(fileSystem, "/foo/bar/test")); + driftDef.setResource(resource); + + // persist the change set and drift definition + executeInTransaction(false, new TransactionCallback() { + @Override + public void execute() throws Exception { + EntityManager em = getEntityManager(); + em.persist(changeSet); + em.persist(driftDef); + em.persist(driftSet); + changeSet.setInitialDriftSet(driftSet); + em.merge(changeSet); + } + }); + + jpaDriftServer.copyChangeSet(getOverlord(), changeSet.getId(), driftDef.getId(), resource.getId()); + + // verify that the change set was created for the definition + JPADriftChangeSetCriteria criteria = new JPADriftChangeSetCriteria(); + criteria.addFilterDriftDefinitionId(driftDef.getId()); + criteria.addFilterCategory(COVERAGE); + + PageList<JPADriftChangeSet> changeSets = jpaDriftServer.findDriftChangeSetsByCriteria(getOverlord(), criteria); + + assertEquals("Expected to get back one change set", 1,changeSets.size()); + + JPADriftChangeSet newChangeSet = changeSets.get(0); + Set<JPADrift> expectedDrifts = new HashSet<JPADrift>(asList(drift1, drift2)); + Set<JPADrift> actualDrifts = newChangeSet.getDrifts(); + + AssertUtils.assertCollectionMatchesNoOrder("The change set drifts were not copied correctly", expectedDrifts, + actualDrifts, + "changeSet", "newDriftFile"); + } + + private DriftFileDTO toDTo(JPADriftFile driftFile) { + DriftFileDTO dto = new DriftFileDTO(); + dto.setHashId(driftFile.getHashId()); + dto.setDataSize(driftFile.getDataSize()); + dto.setStatus(driftFile.getStatus()); + return dto; + } + + + private void assertDriftFilePersisted(JPADriftFile driftFile, String name, String content) { + assertNotNull("Failed to get " + name + " Was it persisted?", driftFile); + assertEquals("The content for " + name + " is wrong", content, jpaDriftServer.getDriftFileBits( + driftFile.getHashId())); + assertEquals("The drift file status is wrong", LOADED, driftFile.getStatus()); + } + +} diff --git a/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/drift/ManageDriftDefinitionsTest.java b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/drift/ManageDriftDefinitionsTest.java new file mode 100644 index 0000000..26ccf94 --- /dev/null +++ b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/drift/ManageDriftDefinitionsTest.java @@ -0,0 +1,338 @@ +/* + * 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.drift.DriftCategory.FILE_ADDED; +import static org.rhq.core.domain.drift.DriftChangeSetCategory.COVERAGE; +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.DriftDefinitionComparator.CompareMode.BOTH_BASE_INFO_AND_DIRECTORY_SPECIFICATIONS; +import static org.rhq.enterprise.server.util.LookupUtil.getDriftManager; +import static org.rhq.enterprise.server.util.LookupUtil.getDriftTemplateManager; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; + +import javax.persistence.EntityManager; + +import org.testng.annotations.Test; + +import org.rhq.core.domain.common.EntityContext; +import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.criteria.DriftDefinitionCriteria; +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.DriftComplianceStatus; +import org.rhq.core.domain.drift.DriftConfigurationDefinition; +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.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.Resource; +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; + +@Test +public class ManageDriftDefinitionsTest extends AbstractDriftServerTest { + + private final String DRIFT_NOT_SUPPORTED_TYPE = getClass().getSimpleName() + "DRIFT_NOT_SUPPORTED_RESOURCE_TYPE"; + + private final String DRIFT_NOT_SUPPORTED_RESOURCE = getClass().getSimpleName() + "DRIFT_NOT_SUPPORTED_RESOURCE"; + + private DriftManagerLocal driftMgr; + + private DriftTemplateManagerLocal templateMgr; + + private ResourceType driftNotSupportedType; + + private Resource driftNotSupportedResource; + + @Override + public void beforeMethod() throws Exception { + driftMgr = getDriftManager(); + templateMgr = getDriftTemplateManager(); + } + + @Override + protected void purgeDB(EntityManager em) { + deleteEntity(Resource.class, DRIFT_NOT_SUPPORTED_RESOURCE, em); + deleteEntity(ResourceType.class, DRIFT_NOT_SUPPORTED_TYPE, em); + } + + public void createDefinitionFromUnpinnedTemplate() { + // first create a template + final DriftDefinition templateDef = new DriftDefinition(new Configuration()); + templateDef.setName("test_createUnpinnedDefinition"); + templateDef.setEnabled(true); + templateDef.setDriftHandlingMode(normal); + templateDef.setInterval(2400L); + templateDef.setBasedir(new DriftDefinition.BaseDirectory(fileSystem, "/foo/bar/test")); + + // persist the template + DriftDefinitionTemplate template = templateMgr.createTemplate(getOverlord(), resourceType.getId(), false, + templateDef); + + // create and persist the definition + DriftDefinition definition = template.createDefinition(); + definition.setTemplate(template); + driftMgr.updateDriftDefinition(getOverlord(), EntityContext.forResource(resource.getId()), definition); + + // verify that the definition was created + DriftDefinition newDef = loadDefinition(definition.getName()); + DriftDefinitionComparator comparator = new DriftDefinitionComparator( + BOTH_BASE_INFO_AND_DIRECTORY_SPECIFICATIONS); + + assertEquals("The drift definition was not persisted correctly", 0, comparator.compare(definition, newDef)); + assertEquals("The template association was not set on the definition", template, newDef.getTemplate()); + } + + // The following two tests are commented out because when they are enabled + // and all tests in the itests module are run, the @AfterClass method for + // DriftTemplateManagerBeanTest does not run immediately after all of its + // test methods have finished running. Instead, some of the tests in + // ManageDriftDefinitionsTest start running. This leads to some database + // constraint violations because of how agents are created in the parent + // class, DriftServerTest. See http://groups.google.com/group/testng-users/browse_thread/thread/da2790679a430d51?pli=1 + // more info on the order in which TestNG executes tests. + +// public void createEntitiesThatDoNotSupportDrift() { +// // first create the resource type that does not support drift +// driftNotSupportedType = new ResourceTypeBuilder() +// .createResourceType() +// .withId(0) +// .withName(DRIFT_NOT_SUPPORTED_TYPE) +// .withCategory(SERVER) +// .withPlugin(DRIFT_NOT_SUPPORTED_TYPE.toLowerCase()) +// .build(); +// +// // create a resource of the type that does not support drift +// driftNotSupportedResource = new ResourceBuilder() +// .createResource() +// .withId(0) +// .withName(DRIFT_NOT_SUPPORTED_RESOURCE) +// .withResourceKey(DRIFT_NOT_SUPPORTED_RESOURCE) +// .withRandomUuid() +// .withResourceType(driftNotSupportedType) +// .build(); +// +// executeInTransaction(new TransactionCallback() { +// @Override +// public void execute() throws Exception { +// EntityManager em = getEntityManager(); +// em.persist(driftNotSupportedType); +// em.persist(driftNotSupportedResource); +// } +// }); +// } +// +// @Test(dependsOnMethods = "createEntitiesThatDoNotSupportDrift", +// expectedExceptions = EJBException.class, +// expectedExceptionsMessageRegExp = ".*Cannot create drift definition.*type.*does not support drift management") +// @InitDB(false) +// public void doNotAllowDefinitionToBeCreatedForTypeThatDoesNotSupportDrift() { +// DriftDefinition driftDef = new DriftDefinition(new Configuration()); +// driftDef.setName("test_typeDoesNotSupportDrift"); +// driftDef.setEnabled(true); +// driftDef.setInterval(1800L); +// driftDef.setDriftHandlingMode(normal); +// driftDef.setBasedir(new DriftDefinition.BaseDirectory(fileSystem, "/foo/bar/test")); +// +// driftMgr.updateDriftDefinition(getOverlord(), EntityContext.forResource(driftNotSupportedResource.getId()), +// driftDef); +// } + + @SuppressWarnings("unchecked") + public void createDefinitionFromPinnedTemplate() throws Exception { + // We first need to create a pinned template. Users can only create a pinned + // template from a snapshot of an existing resource-level drift definition. + // We are going to take a bit of a short cut though by directly creating + // and persisting the pinned change set. + + // first create the change set + final JPADriftChangeSet changeSet0 = new JPADriftChangeSet(null, 0, COVERAGE, null); + changeSet0.setDriftHandlingMode(DriftConfigurationDefinition.DriftHandlingMode.normal); + + final JPADriftFile driftFile1 = new JPADriftFile("a1b2c3"); + final JPADriftFile driftFile2 = new JPADriftFile("1a2b3c"); + + JPADrift drift1 = new JPADrift(changeSet0, "drift.1", FILE_ADDED, null, driftFile1); + JPADrift drift2 = new JPADrift(changeSet0, "drift.2", FILE_ADDED, null, driftFile2); + + final JPADriftSet driftSet = new JPADriftSet(); + driftSet.addDrift(drift1); + driftSet.addDrift(drift2); + + // create the template + final DriftDefinition templateDef = new DriftDefinition(new Configuration()); + templateDef.setName("test_createUnpinnedDefinition"); + templateDef.setEnabled(true); + templateDef.setDriftHandlingMode(normal); + templateDef.setInterval(2400L); + templateDef.setBasedir(new DriftDefinition.BaseDirectory(fileSystem, "/foo/bar/test")); + templateDef.setPinned(true); + + final DriftDefinitionTemplate template = templateMgr.createTemplate(getOverlord(), resourceType.getId(), true, + templateDef); + + executeInTransaction(false, new TransactionCallback() { + @Override + public void execute() throws Exception { + EntityManager em = getEntityManager(); + + em.persist(driftFile1); + em.persist(driftFile2); + em.persist(changeSet0); + em.persist(driftSet); + changeSet0.setInitialDriftSet(driftSet); + em.merge(changeSet0); + + // setting the change set id on the template is the last and the + // most important step in making the template pinned + template.setChangeSetId(changeSet0.getId()); + em.merge(template); + } + }); + + // Create and persist a resource-level definition. + final DriftDefinition definition = template.createDefinition(); + definition.setTemplate(template); + + final AtomicBoolean agentInvoked = new AtomicBoolean(false); + + agentServiceContainer.driftService = new TestDefService() { + @Override + public void updateDriftDetection(int resourceId, DriftDefinition driftDef, DriftSnapshot snapshot) { + try { + HibernateDetachUtility.nullOutUninitializedFields(driftDef, + HibernateDetachUtility.SerializationType.SERIALIZATION); + HibernateDetachUtility.nullOutUninitializedFields(snapshot, + HibernateDetachUtility.SerializationType.SERIALIZATION); + agentInvoked.set(true); + assertNotNull("Expected snapshot drift instances collection to be non-null", + snapshot.getDriftInstances()); + assertEquals("Expected snapshot to contain two drift entries", 2, snapshot.getDriftInstances().size()); + } catch (Exception e) { + String msg = "Do not pass attached entites to agent since those entities are outside of " + + "Hibernate's control. The persistence context should be flushed and cleared to ensure that " + + "only detached objects are sent to the agent"; + throw new RuntimeException(msg, e); + } + } + }; + + driftMgr.updateDriftDefinition(getOverlord(), EntityContext.forResource(resource.getId()), definition); + + DriftDefinition newDef = loadDefinition(definition.getName()); + + // verify that the definition is marked as pinned + assertTrue("The drift definition should be marked as pinned", newDef.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"); + + // lastly verify that the agent is called + assertTrue("Failed to send drift definition along with snapshot to agent", agentInvoked.get()); + } + + public void unpinDefinition() { + // First create the template + final DriftDefinition templateDef = new DriftDefinition(new Configuration()); + templateDef.setName("test_unpin_def_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); + + // First create the definition + DriftDefinition definition = template.createDefinition(); + definition.setName("test_unpin"); + definition.setEnabled(true); + definition.setBasedir(new DriftDefinition.BaseDirectory(fileSystem, "/foo/bar/test")); + definition.setComplianceStatus(DriftComplianceStatus.OUT_OF_COMPLIANCE_DRIFT); + definition.setInterval(1800L); + definition.setDriftHandlingMode(normal); + definition.setPinned(true); + + // persist the definition + driftMgr.updateDriftDefinition(getOverlord(), EntityContext.forResource(resource.getId()), definition); + + // now update the definition + DriftDefinition newDef = loadDefinition(definition.getName()); + assertNotNull("Failed to load new definition, " + toString(definition)); + newDef.setPinned(false); + + driftMgr.updateDriftDefinition(getOverlord(), EntityContext.forResource(resource.getId()), newDef); + + // now verify that the definition was updated + DriftDefinition updatedDef = loadDefinition(definition.getName()); + assertNotNull("Failed to load updated definition, " + toString(newDef)); + + assertFalse("The updated definition should be set to unpinned", updatedDef.isPinned()); + assertEquals("The updated definition should be set to in compliance", DriftComplianceStatus.IN_COMPLIANCE, + updatedDef.getComplianceStatus()); + } + + private DriftDefinition loadDefinition(String name) { + DriftDefinitionCriteria criteria = new DriftDefinitionCriteria(); + criteria.addFilterResourceIds(resource.getId()); + criteria.addFilterName(name); + criteria.fetchConfiguration(true); + criteria.fetchResource(true); + criteria.fetchTemplate(true); + + PageList<DriftDefinition> driftDefs = driftMgr.findDriftDefinitionsByCriteria(getOverlord(), criteria); + assertEquals("Expected to find one drift definition", 1, driftDefs.size()); + + return driftDefs.get(0); + } + +} diff --git a/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/drift/ManageSnapshotsTest.java b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/drift/ManageSnapshotsTest.java new file mode 100644 index 0000000..a7294bf --- /dev/null +++ b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/drift/ManageSnapshotsTest.java @@ -0,0 +1,275 @@ +/* + * 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.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.enterprise.server.util.LookupUtil.getDriftManager; +import static org.rhq.enterprise.server.util.LookupUtil.getDriftTemplateManager; +import static org.rhq.test.AssertUtils.assertPropertiesMatch; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; + +import javax.persistence.EntityManager; + +import org.testng.annotations.Test; + +import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.criteria.GenericDriftChangeSetCriteria; +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.DriftDefinitionTemplate; +import org.rhq.core.domain.drift.DriftSnapshot; +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.server.EntitySerializer; +import org.rhq.core.domain.util.PageList; +import org.rhq.enterprise.server.test.TransactionCallback; +import org.rhq.test.AssertUtils; + +@Test +public class ManageSnapshotsTest extends AbstractDriftServerTest { + + private DriftManagerLocal driftMgr; + + private DriftTemplateManagerLocal templateMgr; + + @Override + public void beforeMethod() throws Exception { + driftMgr = getDriftManager(); + templateMgr = getDriftTemplateManager(); + } + + public void pinningSnapshotShouldSetDriftDefAsPinned() { + final DriftDefinition driftDef = createAndPersistDriftDef("test::setPinnedFlag"); + + // create initial change set + final JPADriftChangeSet changeSet = new JPADriftChangeSet(resource, 0, COVERAGE, driftDef); + + final JPADriftFile driftFile1 = new JPADriftFile("a1b2c3"); + JPADrift drift = new JPADrift(changeSet, "drift.1", FILE_ADDED, null, driftFile1); + + final JPADriftSet driftSet = new JPADriftSet(); + driftSet.addDrift(drift); + + executeInTransaction(false, new TransactionCallback() { + @Override + public void execute() throws Exception { + EntityManager em = getEntityManager(); + em.persist(driftFile1); + em.persist(changeSet); + em.persist(driftSet); + changeSet.setInitialDriftSet(driftSet); + em.merge(changeSet); + } + }); + + driftMgr.pinSnapshot(getOverlord(), driftDef.getId(), 0); + DriftDefinition updatedDriftDef = driftMgr.getDriftDefinition(getOverlord(), driftDef.getId()); + + assertNotNull("Failed to get " + toString(driftDef), updatedDriftDef); + assertTrue("Failed to set pinned flag of " + toString(driftDef), updatedDriftDef.isPinned()); + } + + @SuppressWarnings("unchecked") + public void pinningSnapshotShouldMakeSnapshotTheInitialChangeSet() throws Exception { + final DriftDefinition driftDef = createAndPersistDriftDef("test::makeSnapshotVersionZero"); + + // create initial change set + final JPADriftChangeSet changeSet0 = new JPADriftChangeSet(resource, 0, COVERAGE, driftDef); + + final JPADriftFile driftFile1 = new JPADriftFile("a1b2c3"); + JPADrift drift1 = new JPADrift(changeSet0, "drift.1", FILE_ADDED, null, driftFile1); + + final JPADriftSet driftSet = new JPADriftSet(); + driftSet.addDrift(drift1); + + // create change set v1 + final JPADriftFile driftFile2 = new JPADriftFile("1a2b3c"); + final JPADriftChangeSet changeSet1 = new JPADriftChangeSet(resource, 1, DRIFT, driftDef); + final JPADrift drift2 = new JPADrift(changeSet1, "drift.2", FILE_ADDED, null, driftFile2); + + executeInTransaction(false, new TransactionCallback() { + @Override + public void execute() throws Exception { + EntityManager em = getEntityManager(); + em.persist(driftFile1); + em.persist(driftFile2); + em.persist(changeSet0); + em.persist(driftSet); + changeSet0.setInitialDriftSet(driftSet); + em.merge(changeSet0); + em.persist(changeSet1); + em.persist(drift2); + } + }); + + driftMgr.pinSnapshot(getOverlord(), driftDef.getId(), 1); + + // Verify that there is now only one change set for the drift def + GenericDriftChangeSetCriteria criteria = new GenericDriftChangeSetCriteria(); + criteria.addFilterDriftDefinitionId(driftDef.getId()); + + PageList<? extends DriftChangeSet<?>> changeSets = driftMgr.findDriftChangeSetsByCriteria(getOverlord(), + criteria); + assertEquals("All change sets except the change set representing the pinned snapshot should be removed", + 1, changeSets.size()); + DriftChangeSet<?> changeSet = changeSets.get(0); + + assertEquals("The pinned snapshot version should be reset to zero", 0, changeSet.getVersion()); + assertEquals("The change set category is wrong", COVERAGE, changeSet.getCategory()); + + JPADriftChangeSet expectedChangeSet = new JPADriftChangeSet(resource, 1, COVERAGE, driftDef); + List<? extends Drift> expectedDrifts = asList( + new JPADrift(expectedChangeSet, drift1.getPath(), FILE_ADDED, null, driftFile1), + new JPADrift(expectedChangeSet, drift2.getPath(), FILE_ADDED, null, driftFile2)); + + List<? extends Drift> actualDrifts = new ArrayList(changeSet.getDrifts()); + + AssertUtils.assertCollectionMatchesNoOrder( + "Expected to find drifts from change sets 1 and 2 in the new initial 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, "drift.1").getNewDriftFile(), + "The newDriftFile property was not set correctly for " + drift1); + assertPropertiesMatch(drift2.getNewDriftFile(), findDriftByPath(actualDrifts, "drift.2").getNewDriftFile(), + "The newDriftFile property was not set correctly for " + drift1); + } + + public void pinningSnapshotShouldSendRequestToAgent() { + final DriftDefinition driftDef = createAndPersistDriftDef("test::setPinnedFlag"); + + // create initial change set + final JPADriftChangeSet changeSet = new JPADriftChangeSet(resource, 0, COVERAGE, driftDef); + + final JPADriftFile driftFile1 = new JPADriftFile("a1b2c3"); + JPADrift drift = new JPADrift(changeSet, "drift.1", FILE_ADDED, null, driftFile1); + + final JPADriftSet driftSet = new JPADriftSet(); + driftSet.addDrift(drift); + + executeInTransaction(false, new TransactionCallback() { + @Override + public void execute() throws Exception { + EntityManager em = getEntityManager(); + em.persist(driftFile1); + em.persist(changeSet); + em.persist(driftSet); + changeSet.setInitialDriftSet(driftSet); + em.merge(changeSet); + } + }); + + final AtomicBoolean agentInvoked = new AtomicBoolean(false); + agentServiceContainer.driftService = new TestDefService() { + @Override + public void pinSnapshot(int resourceId, String configName, DriftSnapshot snapshot) { + try { + agentInvoked.set(true); + // serialize the method arguments here to more closely simulate what + // happens during the call. We cannot send hibernate-proxied objects + // to the agent. This is an attempt to catch that. + ObjectOutputStream stream = new ObjectOutputStream(new ByteArrayOutputStream()); + EntitySerializer.writeExternalRemote(resourceId, stream); + EntitySerializer.writeExternalRemote(configName, stream); + EntitySerializer.writeExternalRemote(snapshot, stream); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + }; + + driftMgr.pinSnapshot(getOverlord(), driftDef.getId(), 0); + + assertTrue("Failed to send request to agent to pin snapshot", agentInvoked.get()); + } + + @Test(expectedExceptions = IllegalArgumentException.class, + expectedExceptionsMessageRegExp = "Cannot repin.*definition.*") + public void doNotAllowSnapshotToBePinnedWhenDefinitionIsAttachedToPinnedTemplate() { + // First create the template + final DriftDefinition templateDef = new DriftDefinition(new Configuration()); + templateDef.setName("Template-Pinned_Test"); + 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); + + // Now we will pin the template. We are going to take a bit of a short cut + // here. Pinning a template requires a drift definition with at least one + // snapshot. For the purposes of this test we can simply set the + // changeSetId field of the template to indicate that it is pinned. + template.setChangeSetId("1234"); + + // Next create a resource-level definition from the template. + final DriftDefinition driftDef = template.createDefinition(); + driftDef.setResource(resource); + + executeInTransaction(false, new TransactionCallback() { + @Override + public void execute() throws Exception { + EntityManager em = getEntityManager(); + em.merge(template); + em.persist(driftDef); + } + }); + + // Now try resource-level pinning, i.e., pin a snapshot to the definition + driftMgr.pinSnapshot(getOverlord(), driftDef.getId(), 0); + } + + private DriftDefinition createAndPersistDriftDef(String name) { + final DriftDefinition driftDef = new DriftDefinition(new Configuration()); + driftDef.setName(name); + driftDef.setEnabled(true); + driftDef.setDriftHandlingMode(normal); + driftDef.setInterval(1800L); + driftDef.setBasedir(new DriftDefinition.BaseDirectory(fileSystem, "/foo/bar/test")); + + executeInTransaction(false, new TransactionCallback() { + @Override + public void execute() throws Exception { + driftDef.setResource(resource); + getEntityManager().persist(driftDef); + } + }); + + return driftDef; + } + +} diff --git a/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/measurement/test/AbstractMeasurementScheduleManagerTest.java b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/measurement/test/AbstractMeasurementScheduleManagerTest.java index b11102e..ab15fd5 100644 --- a/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/measurement/test/AbstractMeasurementScheduleManagerTest.java +++ b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/measurement/test/AbstractMeasurementScheduleManagerTest.java @@ -24,13 +24,10 @@ import java.util.ArrayList; import java.util.List; import java.util.Set;
-import javax.management.MBeanServer; - import org.rhq.core.domain.measurement.MeasurementScheduleRequest; import org.rhq.core.domain.measurement.ResourceMeasurementScheduleRequest; import org.rhq.core.domain.resource.Agent; import org.rhq.enterprise.server.agentclient.AgentClient; -import org.rhq.enterprise.server.core.comm.ServerCommunicationsServiceMBean; import org.rhq.enterprise.server.measurement.MeasurementConstants; import org.rhq.enterprise.server.test.AbstractEJB3Test; import org.rhq.enterprise.server.test.TestAgentClient; @@ -44,17 +41,7 @@ public class AbstractMeasurementScheduleManagerTest extends AbstractEJB3Test {
@Override public TestServerCommunicationsService prepareForTestAgents() { - try { - MBeanServer mbs = getPlatformMBeanServer(); - if (mbs.isRegistered(ServerCommunicationsServiceMBean.OBJECT_NAME)) { - mbs.unregisterMBean(ServerCommunicationsServiceMBean.OBJECT_NAME); - } - TestServerCommunicationsService testAgentContainer = new MeasurementScheduleTestServerCommunicationsService(); - mbs.registerMBean(testAgentContainer, ServerCommunicationsServiceMBean.OBJECT_NAME); - return testAgentContainer; - } catch (Exception e) { - throw new RuntimeException(e); - } + return prepareForTestAgents(new MeasurementScheduleTestServerCommunicationsService()); }
public static class MeasurementScheduleTestServerCommunicationsService extends TestServerCommunicationsService { diff --git a/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/measurement/test/MeasurementScheduleManagerTest.java b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/measurement/test/MeasurementScheduleManagerTest.java index e978521..f12c0f7 100644 --- a/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/measurement/test/MeasurementScheduleManagerTest.java +++ b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/measurement/test/MeasurementScheduleManagerTest.java @@ -28,8 +28,6 @@ import javax.persistence.Query;
import junit.framework.Assert;
-import org.testng.annotations.AfterMethod; -import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test;
import org.rhq.core.domain.auth.Subject; @@ -68,8 +66,8 @@ public class MeasurementScheduleManagerTest extends AbstractMeasurementScheduleM private Agent theAgent; private MeasurementScheduleTestServerCommunicationsService testCommService;
- @BeforeMethod - public void beforeMethod() { + @Override + protected void beforeMethod() { try { prepareScheduler(); testCommService = (MeasurementScheduleTestServerCommunicationsService) prepareForTestAgents(); @@ -84,8 +82,8 @@ public class MeasurementScheduleManagerTest extends AbstractMeasurementScheduleM } }
- @AfterMethod - public void afterMethod() { + @Override + protected void afterMethod() { EntityManager em = null;
try { @@ -356,7 +354,7 @@ public class MeasurementScheduleManagerTest extends AbstractMeasurementScheduleM try { if (null != em) { em.flush(); - getTransactionManager().commit(); + getTransactionManager().rollback(); em.close(); } } catch (Throwable t) { diff --git a/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/test/AbstractEJB3Test.java b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/test/AbstractEJB3Test.java index 8064bdc..b68a517 100644 --- a/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/test/AbstractEJB3Test.java +++ b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/test/AbstractEJB3Test.java @@ -2,6 +2,7 @@ package org.rhq.enterprise.server.test;
import java.io.File; import java.lang.management.ManagementFactory; +import java.lang.reflect.Method; import java.sql.Connection; import java.sql.SQLException; import java.util.Collection; @@ -25,22 +26,29 @@ import org.testng.annotations.BeforeMethod; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.test.api.ArquillianResource; import org.jboss.arquillian.testng.Arquillian; +import org.jboss.shrinkwrap.api.Archive; import org.jboss.shrinkwrap.api.ArchivePaths; import org.jboss.shrinkwrap.api.Filters; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; +import org.jboss.shrinkwrap.api.exporter.ZipExporter; import org.jboss.shrinkwrap.api.spec.EnterpriseArchive; import org.jboss.shrinkwrap.api.spec.JavaArchive; +import org.jboss.shrinkwrap.impl.base.exporter.zip.ZipExporterImpl; import org.jboss.shrinkwrap.resolver.api.DependencyResolvers; import org.jboss.shrinkwrap.resolver.api.maven.MavenDependencyResolver;
import org.rhq.core.db.DatabaseTypeFactory; import org.rhq.core.domain.auth.Subject; +import org.rhq.core.domain.shared.BuilderException; +import org.rhq.core.domain.shared.ResourceBuilder; +import org.rhq.core.domain.shared.ResourceTypeBuilder; import org.rhq.core.util.MessageDigestGenerator; import org.rhq.core.util.exception.ThrowableUtil; import org.rhq.core.util.stream.StreamUtil; import org.rhq.enterprise.server.RHQConstants; import org.rhq.enterprise.server.auth.SessionManager; +import org.rhq.enterprise.server.core.comm.ServerCommunicationsServiceMBean; import org.rhq.enterprise.server.core.plugin.PluginDeploymentScanner; import org.rhq.enterprise.server.core.plugin.PluginDeploymentScannerMBean; import org.rhq.enterprise.server.plugin.pc.ServerPluginService; @@ -57,6 +65,7 @@ public abstract class AbstractEJB3Test extends Arquillian {
protected static final String JNDI_RHQDS = "java:jboss/datasources/RHQDS";
+ private TestServerCommunicationsService agentService; private SchedulerService schedulerService; private ServerPluginService serverPluginService; private PluginDeploymentScannerMBean pluginScannerService; @@ -105,9 +114,13 @@ public abstract class AbstractEJB3Test extends Arquillian { testClassesJar.addClass(MessageDigestGenerator.class); testClassesJar.addClass(StreamUtil.class); testClassesJar.addClass(AssertUtils.class); + testClassesJar.addClass(ResourceBuilder.class); + testClassesJar.addClass(ResourceTypeBuilder.class); + testClassesJar.addClass(BuilderException.class); testClassesJar.addClasses(PropertyMatcher.class, MatchResult.class, PropertyMatchException.class); testClassesJar.addAsManifestResource(EmptyAsset.INSTANCE, ArchivePaths.create("beans.xml")); // add CDI injection (needed by arquillian injection); testClassesJar.addAsResource("test-scheduler.properties"); + testClassesJar.addAsResource("test-alert-sender-serverplugin.xml");
// create test ear by starting with rhq.ear and thinning it MavenDependencyResolver earResolver = DependencyResolvers.use(MavenDependencyResolver.class); @@ -144,6 +157,8 @@ public abstract class AbstractEJB3Test extends Arquillian { Collection<JavaArchive> dependencies = new HashSet<JavaArchive>(); dependencies.addAll(resolver.artifact("org.powermock:powermock-api-mockito").resolveAs(JavaArchive.class)); dependencies.addAll(resolver.artifact("org.liquibase:liquibase-core").resolveAs(JavaArchive.class)); + dependencies + .addAll(resolver.artifact("org.jboss.shrinkwrap:shrinkwrap-impl-base").resolveAs(JavaArchive.class)); dependencies.addAll(resolver.artifact("org.rhq:test-utils").resolveAs(JavaArchive.class)); dependencies.addAll(resolver.artifact("org.rhq.helpers:perftest-support").resolveAs(JavaArchive.class));
@@ -157,16 +172,21 @@ public abstract class AbstractEJB3Test extends Arquillian { // System.out.println("** The Deployment EAR: " + ear.toString(true) + "\n");
// Save the test EAR to a zip file for inspection (set file explicitly) - // try { - // ZipExporter exporter = new ZipExporterImpl(ear); - // exporter.exportTo(new File("/home/jshaughn/temp/test-ear.ear"), true); - // } catch (Exception e) { - // e.printStackTrace(); - // } + //exportZip(testEar, new File("/home/jshaughn/temp/test-ear.ear"));
return testEar; }
+ @SuppressWarnings("unused") + static private void exportZip(Archive<?> zipArchive, File outFile) { + try { + ZipExporter exporter = new ZipExporterImpl(zipArchive); + exporter.exportTo(outFile, true); + } catch (Exception e) { + e.printStackTrace(); + } + } + /** * @param dependencies The current set of deps - THIS IS FILTERED, not copied * @param filters regex filters @@ -241,7 +261,7 @@ public abstract class AbstractEJB3Test extends Arquillian { * and {@link #inContainer()} call. */ @BeforeMethod - protected void __beforeMethod() throws Throwable { + protected void __beforeMethod(Method method) throws Throwable { // Note that Arquillian calls the testng BeforeMethod twice (as of 1.0.2.Final, once // out of container and once in container. In general the expectation is to execute it // one time, and doing it in container allows for the expected injections and context. @@ -264,6 +284,7 @@ public abstract class AbstractEJB3Test extends Arquillian { }
beforeMethod(); + beforeMethod(method);
} catch (Throwable t) { // Arquillian is eating these, make sure they show up in some way @@ -299,6 +320,13 @@ public abstract class AbstractEJB3Test extends Arquillian { }
/** + * Override Point! Do not implement a @BeforeMethod, instead override this method. + */ + protected void beforeMethod(Method method) throws Exception { + // do nothing if we're not overridden + } + + /** * Override Point! Do not implement an @AfterMethod, instead override this method. */ protected void afterMethod() throws Exception { @@ -600,7 +628,83 @@ public abstract class AbstractEJB3Test extends Arquillian { } else { //MBeanServerFactory.releaseMBeanServer(mbs); } + } + } + + /** + * If you need to test round trips from server to agent and back, you first must install the server communications + * service that houses all the agent clients. Call this method and add your test agent services to the public fields + * in the returned object. + * + * @return the object that will house your test agent service impls and the agent clients. + * + * @throws RuntimeException + */ + public TestServerCommunicationsService prepareForTestAgents() { + if (agentService != null) { + return agentService; + } + + return prepareForTestAgents(new TestServerCommunicationsService()); + } + + /** + * If you need to test round trips from server to agent and back, you first must install the server communications + * service that houses all the agent clients. Call this method and add your test agent services to the public fields + * in the returned object. + * + * @return the object that will house your test agent service impls and the agent clients. + * + * @throws RuntimeException + */ + public TestServerCommunicationsService prepareForTestAgents(TestServerCommunicationsServiceMBean customAgentService) { + try { + if (agentService != null) { + return agentService; + } + + // first, unregister the real service... + MBeanServer mbs = getPlatformMBeanServer(); + if (mbs.isRegistered(ServerCommunicationsServiceMBean.OBJECT_NAME)) { + mbs.unregisterMBean(ServerCommunicationsServiceMBean.OBJECT_NAME); + } + + // Now replace with the test service... + TestServerCommunicationsService agentService = new TestServerCommunicationsService(); + mbs.registerMBean(customAgentService, ServerCommunicationsServiceMBean.OBJECT_NAME); + return agentService; + + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException(e); + } + }
+ /** + * Call this after your tests have finished. You only need to call this if your test previously called + * {@link #prepareForTestAgents()}. + */ + public void unprepareForTestAgents() { + unprepareForTestAgents(false); + } + + public void unprepareForTestAgents(boolean beanOnly) { + try { + if (agentService != null) { + agentService.stop(); + agentService = null; + + MBeanServer mbs = getPlatformMBeanServer(); + if (beanOnly) { + if (mbs.isRegistered(ServerCommunicationsServiceMBean.OBJECT_NAME)) { + mbs.unregisterMBean(ServerCommunicationsServiceMBean.OBJECT_NAME); + } + } else { + //MBeanServerFactory.releaseMBeanServer(mbs); + } + } + } catch (Exception e) { + throw new RuntimeException(e); } }
@@ -646,51 +750,6 @@ public abstract class AbstractEJB3Test extends Arquillian { pluginScannerService = null; }
- /** - * If you need to test round trips from server to agent and back, you first must install the server communications - * service that houses all the agent clients. Call this method and add your test agent services to the public fields - * in the returned object. - * - * @return the object that will house your test agent service impls and the agent clients. - * - * @throws RuntimeException - */ - public TestServerCommunicationsService prepareForTestAgents() { - try { - // MBeanServer mbs = getJBossMBeanServer(); - // if (mbs.isRegistered(ServerCommunicationsServiceMBean.OBJECT_NAME)) { - // mbs.unregisterMBean(ServerCommunicationsServiceMBean.OBJECT_NAME); - // } - TestServerCommunicationsService testAgentContainer = new TestServerCommunicationsService(); - // mbs.registerMBean(testAgentContainer, ServerCommunicationsServiceMBean.OBJECT_NAME); - return testAgentContainer; - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - /** - * Call this after your tests have finished. You only need to call this if your test previously called - * {@link #prepareForTestAgents()}. - */ - public void unprepareForTestAgents() { - unprepareForTestAgents(false); - } - - public void unprepareForTestAgents(boolean beanOnly) { - try { - if (beanOnly) { - // MBeanServer mbs = getJBossMBeanServer(); - // if (mbs.isRegistered(ServerCommunicationsServiceMBean.OBJECT_NAME)) { - // mbs.unregisterMBean(ServerCommunicationsServiceMBean.OBJECT_NAME); - // } - } else { - // releaseJBossMBeanServer(); - } - } catch (Exception e) { - throw new RuntimeException(e); - } - }
public MBeanServer getPlatformMBeanServer() { return ManagementFactory.getPlatformMBeanServer(); diff --git a/modules/enterprise/server/itests-2/src/test/resources/test-alert-sender-serverplugin.xml b/modules/enterprise/server/itests-2/src/test/resources/test-alert-sender-serverplugin.xml new file mode 100644 index 0000000..f6bf879 --- /dev/null +++ b/modules/enterprise/server/itests-2/src/test/resources/test-alert-sender-serverplugin.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<alert-plugin + name="alert-complex-test" + displayName="Alert:ComplexTest" + xmlns="urn:xmlns:rhq-serverplugin.alert" + xmlns:c="urn:xmlns:rhq-configuration" + xmlns:serverplugin="urn:xmlns:rhq-serverplugin" + package="org.rhq.enterprise.server.alert" + description="Alert sender plugin for testing the complex validation behavior." + > + + <!-- How does this sender show up in drop downs etc --> + <short-name>Test Alert Sender</short-name> + + <!-- Class that does the actual sending --> + <plugin-class>TestAlertSender</plugin-class> + + <alert-configuration> + <c:simple-property name="persistent" type="string" required="true" description="The property that is persisted into the database."/> + <c:simple-property name="ephemeral" type="string" required="true" description="The property used only at creation/update time. It is not stored into the datbase because the plugin actually removes it from the configuration." /> + </alert-configuration> +</alert-plugin> \ No newline at end of file diff --git a/modules/enterprise/server/itests/src/test/java/org/rhq/enterprise/server/TestServerPluginService.java b/modules/enterprise/server/itests/src/test/java/org/rhq/enterprise/server/TestServerPluginService.java deleted file mode 100644 index be9b752..0000000 --- a/modules/enterprise/server/itests/src/test/java/org/rhq/enterprise/server/TestServerPluginService.java +++ /dev/null @@ -1,148 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2012 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; - -import java.io.File; -import java.net.URL; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.rhq.core.domain.configuration.Configuration; -import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; -import org.rhq.core.domain.plugin.PluginKey; -import org.rhq.core.domain.plugin.PluginStatusType; -import org.rhq.core.domain.plugin.ServerPlugin; -import org.rhq.core.util.MessageDigestGenerator; -import org.rhq.enterprise.server.plugin.pc.AbstractTypeServerPluginContainer; -import org.rhq.enterprise.server.plugin.pc.MasterServerPluginContainer; -import org.rhq.enterprise.server.plugin.pc.MasterServerPluginContainerConfiguration; -import org.rhq.enterprise.server.plugin.pc.ServerPluginEnvironment; -import org.rhq.enterprise.server.plugin.pc.ServerPluginService; -import org.rhq.enterprise.server.plugin.pc.ServerPluginType; -import org.rhq.enterprise.server.xmlschema.ServerPluginDescriptorMetadataParser; -import org.rhq.enterprise.server.xmlschema.ServerPluginDescriptorUtil; -import org.rhq.enterprise.server.xmlschema.generated.serverplugin.ServerPluginDescriptorType; - -/** - * - * - * @author Lukas Krejci - */ -public abstract class TestServerPluginService extends ServerPluginService implements TestServerPluginServiceMBean { - public TestMasterServerPluginContainer master; - public MasterServerPluginContainerConfiguration masterConfig; - - protected TestServerPluginService() { - // build the config at constructor time so tests have it even before the PC is initialized - File dir = new File(System.getProperty("java.io.tmpdir"), "test-server-plugins"); - this.masterConfig = new MasterServerPluginContainerConfiguration(dir, dir, dir, null); - } - - @Override - public MasterServerPluginContainer createMasterPluginContainer() { - this.master = new TestMasterServerPluginContainer(); - this.master.initialize(this.masterConfig); - return this.master; - } - - protected abstract List<AbstractTypeServerPluginContainer> createPluginContainers(MasterServerPluginContainer master); - - public static ServerPlugin getPlugin(ServerPluginEnvironment env) { - return getPlugin(env.getPluginUrl(), env.getPluginDescriptor()); - } - - public static ServerPlugin getPlugin(URL pluginUrl, ServerPluginDescriptorType pluginDescriptor) { - try { - Configuration pluginConfig = null; - Configuration scheduledJobsConfig = null; - ConfigurationDefinition configDef; - - configDef = ServerPluginDescriptorMetadataParser.getPluginConfigurationDefinition(pluginDescriptor); - if (configDef != null) { - pluginConfig = configDef.getDefaultTemplate().createConfiguration(); - } - - configDef = ServerPluginDescriptorMetadataParser.getScheduledJobsDefinition(pluginDescriptor); - if (configDef != null) { - scheduledJobsConfig = configDef.getDefaultTemplate().createConfiguration(); - } - - File pluginFile = new File(pluginUrl.toURI()); - PluginKey pluginKey = PluginKey.createServerPluginKey(new ServerPluginType(pluginDescriptor).stringify(), pluginDescriptor.getName()); - ServerPlugin plugin = - new ServerPlugin(0, pluginKey.getPluginName(), pluginFile.getName(), - pluginDescriptor.getDisplayName(), true, PluginStatusType.INSTALLED, - pluginDescriptor.getDescription(), "", MessageDigestGenerator.getDigestString(pluginFile), - pluginDescriptor.getVersion(), pluginDescriptor.getVersion(), pluginConfig, - scheduledJobsConfig, new ServerPluginType(pluginDescriptor).stringify(), - System.currentTimeMillis(), System.currentTimeMillis()); - return plugin; - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - public static ServerPlugin getPlugin(URL pluginUrl) throws Exception { - ServerPluginDescriptorType type = ServerPluginDescriptorUtil.loadPluginDescriptorFromUrl(pluginUrl); - - return getPlugin(pluginUrl, type); - } - - protected Map<URL, ? extends ServerPluginDescriptorType> preloadAllPlugins() throws Exception { - return null; - } - - private class TestMasterServerPluginContainer extends MasterServerPluginContainer { - - @Override - protected ClassLoader createRootServerPluginClassLoader() { - return getClass().getClassLoader(); - } - - @Override - protected Map<URL, ? extends ServerPluginDescriptorType> preloadAllPlugins() throws Exception { - Map<URL, ? extends ServerPluginDescriptorType> plugins = TestServerPluginService.this.preloadAllPlugins(); - if (plugins != null) { - return plugins; - } - - // if our test never setup any plugins, ignore it and just return an empty map - File pluginDir = getConfiguration().getPluginDirectory(); - if (pluginDir == null || pluginDir.listFiles() == null || pluginDir.listFiles().length == 0) { - return new HashMap<URL, ServerPluginDescriptorType>(); - } else { - return super.preloadAllPlugins(); - } - } - - @Override - protected List<PluginKey> getDisabledPluginKeys() { - // in the real world, the db is checked for enable flag, here we say all plugins are enabled - return new ArrayList<PluginKey>(); - } - - @Override - protected List<AbstractTypeServerPluginContainer> createPluginContainers() { - return TestServerPluginService.this.createPluginContainers(this); - } - } -} diff --git a/modules/enterprise/server/itests/src/test/java/org/rhq/enterprise/server/TestServerPluginServiceMBean.java b/modules/enterprise/server/itests/src/test/java/org/rhq/enterprise/server/TestServerPluginServiceMBean.java deleted file mode 100644 index 5c478a9..0000000 --- a/modules/enterprise/server/itests/src/test/java/org/rhq/enterprise/server/TestServerPluginServiceMBean.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2012 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; - -import org.rhq.enterprise.server.plugin.pc.ServerPluginServiceMBean; - -/** - * - * - * @author Lukas Krejci - */ -public interface TestServerPluginServiceMBean extends ServerPluginServiceMBean { - -} diff --git a/modules/enterprise/server/itests/src/test/java/org/rhq/enterprise/server/alert/AlertDefinitionWithComplexNotificationsTest.java b/modules/enterprise/server/itests/src/test/java/org/rhq/enterprise/server/alert/AlertDefinitionWithComplexNotificationsTest.java deleted file mode 100644 index 9ab2cf9..0000000 --- a/modules/enterprise/server/itests/src/test/java/org/rhq/enterprise/server/alert/AlertDefinitionWithComplexNotificationsTest.java +++ /dev/null @@ -1,712 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2012 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.alert; - -import java.io.File; -import java.util.Collections; -import java.util.HashSet; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Set; - -import javax.persistence.EntityManager; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.testng.annotations.AfterClass; -import org.testng.annotations.AfterMethod; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.Test; - -import org.jboss.shrinkwrap.api.ShrinkWrap; -import org.jboss.shrinkwrap.api.exporter.ZipExporter; -import org.jboss.shrinkwrap.api.spec.JavaArchive; - -import org.rhq.core.domain.alert.AlertDampening; -import org.rhq.core.domain.alert.AlertDefinition; -import org.rhq.core.domain.alert.AlertPriority; -import org.rhq.core.domain.alert.BooleanExpression; -import org.rhq.core.domain.alert.notification.AlertNotification; -import org.rhq.core.domain.auth.Subject; -import org.rhq.core.domain.authz.Permission; -import org.rhq.core.domain.authz.Role; -import org.rhq.core.domain.cloud.Server; -import org.rhq.core.domain.cloud.Server.OperationMode; -import org.rhq.core.domain.configuration.Configuration; -import org.rhq.core.domain.configuration.PropertySimple; -import org.rhq.core.domain.criteria.AlertDefinitionCriteria; -import org.rhq.core.domain.criteria.ResourceCriteria; -import org.rhq.core.domain.plugin.ServerPlugin; -import org.rhq.core.domain.resource.Agent; -import org.rhq.core.domain.resource.InventoryStatus; -import org.rhq.core.domain.resource.Resource; -import org.rhq.core.domain.resource.ResourceType; -import org.rhq.core.domain.resource.group.ResourceGroup; -import org.rhq.core.domain.shared.ResourceBuilder; -import org.rhq.core.domain.shared.ResourceTypeBuilder; -import org.rhq.enterprise.server.TestServerPluginService; -import org.rhq.enterprise.server.auth.SessionManager; -import org.rhq.enterprise.server.test.AbstractEJB3Test; -import org.rhq.enterprise.server.test.TestServerCommunicationsService; -import org.rhq.enterprise.server.test.TransactionCallback; -import org.rhq.enterprise.server.util.LookupUtil; -import org.rhq.enterprise.server.util.ResourceTreeHelper; - -/** - * - * - * @author Lukas Krejci - */ -@Test(groups = "alert") -public class AlertDefinitionWithComplexNotificationsTest extends AbstractEJB3Test { - - private static final Log LOG = LogFactory.getLog(AlertDefinitionWithComplexNotificationsTest.class); - - private enum ParentType { - GROUP, TEMPLATE - } - - private String universalName; - - private Server server; - private Agent agent; - private Subject subject; - private Role role; - private ResourceType resourceType; - private ResourceGroup resourceGroup; - private Set<Resource> resources; - private AlertDefinition templateAlertDefinition; - private AlertDefinition groupAlertDefinition; - private AlertDefinition resourceAlertDefinition; - private ServerPlugin serverPlugin; - private Set<Object> junk = new LinkedHashSet<Object>(); - - private int resourceLevelAlertDefinitionId; - private int groupLevelAlertDefinitionId; - private int templateLevelAlertDefinitionId; - private Resource copyTestsResource; - - private TestAlertSenderPluginService alertSenderService; - private TestServerCommunicationsService agentService; - - @BeforeClass - public void prepareDB() { - executeInTransaction(new TransactionCallback() { - @Override - public void execute() throws Exception { - EntityManager em = getEntityManager(); - - universalName = getClass().getName(); - - agent = new Agent("localhost", "localhost", 0, "foo", "bar"); - - server = new Server(); - server.setAddress("localhost"); - server.setName("localhost"); - server.setOperationMode(OperationMode.NORMAL); - - server.setAgents(Collections.singletonList(agent)); - - role = new Role(universalName); - role.addPermission(Permission.MANAGE_INVENTORY); - role.addPermission(Permission.MANAGE_SETTINGS); - - subject = new Subject(universalName, true, false); - subject.addRole(role); - - resourceType = - new ResourceTypeBuilder().createPlatformResourceType().withId(0).withName(universalName) - .withPlugin(universalName).build(); - - resourceGroup = new ResourceGroup(universalName, resourceType); - - resources = new LinkedHashSet<Resource>(); - for (int i = 0; i < 10; ++i) { - Resource res = createResourceForTest(universalName + i); - - resources.add(res); - - resourceGroup.addExplicitResource(res); - } - - templateAlertDefinition = createDefinitionForTest(universalName + " template", true); - templateAlertDefinition.setResourceType(resourceType); - - groupAlertDefinition = createDefinitionForTest(universalName + " group", true); - groupAlertDefinition.setResourceGroup(resourceGroup); - - resourceAlertDefinition = createDefinitionForTest(universalName + " resource", true); - resourceAlertDefinition.setResource(resources.iterator().next()); - - em.persist(agent); - em.persist(server); - em.persist(role); - em.persist(subject); - em.persist(resourceType); - em.persist(resourceGroup); - for (Resource r : resources) { - em.persist(r); - } - em.persist(templateAlertDefinition); - em.persist(groupAlertDefinition); - em.persist(resourceAlertDefinition); - - //only need this for a short time now, so that we can precreate the plugin structure - alertSenderService = new TestAlertSenderPluginService(); - prepareCustomServerPluginService(alertSenderService); - alertSenderService.masterConfig.getPluginDirectory().mkdirs(); - unprepareServerPluginService(); - - JavaArchive archive = - ShrinkWrap.create(JavaArchive.class).addClass(TestAlertSender.class) - .addAsResource("test-alert-sender-serverplugin.xml", "META-INF/rhq-serverplugin.xml"); - - File pluginFile = - new File(alertSenderService.masterConfig.getPluginDirectory(), "test-aler-plugin.jar"); - - archive.as(ZipExporter.class).exportTo(pluginFile, true); - - //the alert sender plugin manager needs the plugins in the database... - serverPlugin = TestServerPluginService.getPlugin(pluginFile.toURI().toURL()); - em.persist(serverPlugin); - } - }); - } - - @BeforeMethod - public void containerSetup() { - alertSenderService = new TestAlertSenderPluginService(); - prepareCustomServerPluginService(alertSenderService); - alertSenderService.masterConfig.getPluginDirectory().mkdirs(); - - alertSenderService.startMasterPluginContainer(); - - agentService = prepareForTestAgents(); - } - - @AfterMethod - public void containerTearDown() throws Exception { - unprepareServerPluginService(); - unprepareForTestAgents(); - } - - @AfterClass(alwaysRun = true) - public void cleanDB() throws Exception { - for (Object o : junk) { - removeNoExceptions(o); - } - - removeNoExceptions(resourceAlertDefinition); - removeNoExceptions(groupAlertDefinition); - removeNoExceptions(templateAlertDefinition); - removeNoExceptions(resourceGroup); - for (Resource r : resources) { - r.removeExplicitGroup(resourceGroup); - r.getAlertDefinitions().clear(); - removeNoExceptions(r); - } - removeNoExceptions(resourceType); - removeNoExceptions(subject); - removeNoExceptions(role); - removeNoExceptions(server); - removeNoExceptions(agent); - - removeNoExceptions(serverPlugin); - } - - @BeforeMethod - public void login() throws Exception { - //the embedded server cannot do a full-blown login - //so we hack our way in - subject = SessionManager.getInstance().put(subject); - } - - @AfterMethod(alwaysRun = true) - public void logout() throws Exception { - SessionManager.getInstance().invalidate(subject.getSessionId()); - } - - private Resource getCopyTestsResource() throws Exception { - if (copyTestsResource == null) { - final String keyAndName = universalName + "-copyTests"; - - LookupUtil.getResourceManager().createResource(subject, createResourceForTest(keyAndName), Resource.ROOT_ID); - - //ok, now the new resource should contain the alert definition defined by the template - ResourceCriteria crit = new ResourceCriteria(); - crit.addFilterResourceKey(keyAndName); - crit.fetchExplicitGroups(true); //so that cleanup works - crit.fetchAlertDefinitions(true); //so that cleanup works - - List<Resource> foundResources = LookupUtil.getResourceManager().findResourcesByCriteria(subject, crit); - - assertEquals("A new resource should have been created", 1, foundResources.size()); - - Resource res = foundResources.get(0); - resources.add(res); - - copyTestsResource = res; - } - - return copyTestsResource; - } - - public void testNotificationsCopiedOnAlertTemplateApplication() throws Exception { - TestAlertSender.setExpectedSubject(null); - TestAlertSender.resetValidateMethodCallCount(); - - Resource res = getCopyTestsResource(); - - //apply the template manually - this is done in server-agent back-and-forth that we - //don't test here and which is complex to mock out. - //this method has to be called using the overlord subject - LookupUtil.getAlertTemplateManager().updateAlertDefinitionsForResource(LookupUtil.getSubjectManager().getOverlord(), res.getId()); - - assertEquals("No validation should occur on the copied notifications", 0, TestAlertSender.getValidateMethodCallCount()); - - AlertDefinitionManagerLocal adm = LookupUtil.getAlertDefinitionManager(); - AlertDefinitionCriteria adCrit = new AlertDefinitionCriteria(); - adCrit.addFilterResourceIds(res.getId()); - adCrit.fetchAlertNotifications(true); - - List<AlertDefinition> foundAlertDefs = adm.findAlertDefinitionsByCriteria(subject, adCrit); - junk.addAll(foundAlertDefs); - - assertEquals("The new resource should have an alert definition obtained from the template.", 1, foundAlertDefs.size()); - - AlertDefinition defWithNotifications = foundAlertDefs.get(0); - - testSingleDependentAlertDefinition(defWithNotifications, ParentType.TEMPLATE, defWithNotifications.getParentId()); - } - - @Test(dependsOnMethods = "testNotificationsCopiedOnAlertTemplateApplication") - public void testNotificationsCopiedOnGroupMemberAddition() throws Exception { - TestAlertSender.setExpectedSubject(null); - TestAlertSender.resetValidateMethodCallCount(); - - Resource res = getCopyTestsResource(); - - LookupUtil.getResourceGroupManager().addResourcesToGroup(subject, resourceGroup.getId(), new int[] { res.getId() }); - - assertEquals("No validation should occur on the copied notifications", 0, TestAlertSender.getValidateMethodCallCount()); - - AlertDefinitionManagerLocal adm = LookupUtil.getAlertDefinitionManager(); - AlertDefinitionCriteria adCrit = new AlertDefinitionCriteria(); - adCrit.addFilterResourceIds(res.getId()); - adCrit.fetchAlertNotifications(true); - - List<AlertDefinition> foundAlertDefs = adm.findAlertDefinitionsByCriteria(subject, adCrit); - junk.addAll(foundAlertDefs); - - //1 from the group, 1 from the template - assertEquals("The new resource should have an alert definition obtained from the group.", 2, foundAlertDefs.size()); - - AlertDefinition groupOriginatingDef = null; - for(AlertDefinition d : foundAlertDefs) { - if ((universalName + " group").equals(d.getName())) { - groupOriginatingDef = d; - break; - } - } - - assertNotNull("The alert definition originating from the group not present on the resource.", groupOriginatingDef); - - testSingleDependentAlertDefinition(groupOriginatingDef, ParentType.GROUP, groupOriginatingDef.getGroupAlertDefinition().getId()); - } - - public void testCorrectSubjectPassedOnResourceLevelAlertDefinitionCreation() throws Exception { - TestAlertSender.setExpectedSubject(subject); - - AlertDefinitionManagerLocal adm = LookupUtil.getAlertDefinitionManager(); - - Resource res = resources.iterator().next(); - - AlertDefinition def = createDefinitionForTest("testCorrectSubjectPassedOnResourceLevelAlertDefinitionCreation", false); - def.setResource(resources.iterator().next()); - - int id = adm.createAlertDefinition(subject, def, res.getId(), true); - def.setId(id); - - resourceLevelAlertDefinitionId = id; - - junk.add(def); - - testMainAlertDefinition(id); - } - - @Test(dependsOnMethods = { "testNotificationsCopiedOnAlertTemplateApplication", "testNotificationsCopiedOnGroupMemberAddition" }) - public void testCorrectSubjectPassedOnGroupLevelAlertDefinitionCreation() throws Exception { - TestAlertSender.setExpectedSubject(subject); - - GroupAlertDefinitionManagerLocal gadm = LookupUtil.getGroupAlertDefinitionManager(); - - AlertDefinition def = createDefinitionForTest("testCorrectSubjectPassedOnGroupLevelAlertDefinitionCreation", false); - def.setResourceGroup(resourceGroup); - - int id = gadm.createGroupAlertDefinitions(subject, def, resourceGroup.getId()); - def.setId(id); - - groupLevelAlertDefinitionId = id; - - junk.add(def); - - testMainAlertDefinition(id); - List<AlertDefinition> deps = testDependentAlertDefinitions(id, ParentType.GROUP); - - junk.addAll(deps); - } - - @Test(dependsOnMethods = { "testNotificationsCopiedOnAlertTemplateApplication", "testNotificationsCopiedOnGroupMemberAddition" }) - public void testCorrectSubjectPassedOnTemplateLevelAlertDefinitionCreation() throws Exception { - TestAlertSender.setExpectedSubject(subject); - - AlertTemplateManagerLocal atm = LookupUtil.getAlertTemplateManager(); - - AlertDefinition def = createDefinitionForTest("testCorrectSubjectPassedOnTemplateLevelAlertDefinitionCreation", false); - def.setResourceGroup(resourceGroup); - - int id = atm.createAlertTemplate(subject, def, resourceType.getId()); - def.setId(id); - - templateLevelAlertDefinitionId = id; - - junk.add(def); - - testMainAlertDefinition(id); - List<AlertDefinition> deps = testDependentAlertDefinitions(id, ParentType.TEMPLATE); - - junk.addAll(deps); - } - - @Test(dependsOnMethods = "testCorrectSubjectPassedOnResourceLevelAlertDefinitionCreation") - public void testNoValidationWhenNoNotificationUpdateOnResourceLevel() throws Exception { - TestAlertSender.setExpectedSubject(subject); - TestAlertSender.resetValidateMethodCallCount(); - - AlertDefinitionManagerLocal adm = LookupUtil.getAlertDefinitionManager(); - - AlertDefinitionCriteria crit = new AlertDefinitionCriteria(); - crit.addFilterId(resourceLevelAlertDefinitionId); - crit.fetchAlertNotifications(true); - crit.fetchConditions(true); - - List<AlertDefinition> foundDefs = adm.findAlertDefinitionsByCriteria(subject, crit); - - assertEquals("Failed to find the previously created resource level alert definition.", 1, foundDefs.size()); - - AlertDefinition foundDef = foundDefs.get(0); - - foundDef.setEnabled(true); - - adm.updateAlertDefinition(subject, resourceLevelAlertDefinitionId, foundDef, false); - - assertEquals("The notification validation method shouldn't have been called", 0, TestAlertSender.getValidateMethodCallCount()); - } - - @Test(dependsOnMethods = "testCorrectSubjectPassedOnGroupLevelAlertDefinitionCreation") - public void testNoValidationWhenNoNotificationUpdateOnGroupLevel() throws Exception { - TestAlertSender.setExpectedSubject(subject); - TestAlertSender.resetValidateMethodCallCount(); - - AlertDefinitionManagerLocal adm = LookupUtil.getAlertDefinitionManager(); - - AlertDefinitionCriteria crit = new AlertDefinitionCriteria(); - crit.addFilterId(groupLevelAlertDefinitionId); - crit.fetchAlertNotifications(true); - crit.fetchConditions(true); - - List<AlertDefinition> foundDefs = adm.findAlertDefinitionsByCriteria(subject, crit); - - assertEquals("Failed to find the previously created group level alert definition.", 1, foundDefs.size()); - - AlertDefinition foundDef = foundDefs.get(0); - - foundDef.setEnabled(true); - - GroupAlertDefinitionManagerLocal gadm = LookupUtil.getGroupAlertDefinitionManager(); - gadm.updateGroupAlertDefinitions(subject, foundDef, true); - - assertEquals("The notification validation method shouldn't have been called", 0, TestAlertSender.getValidateMethodCallCount()); - } - - @Test(dependsOnMethods = "testCorrectSubjectPassedOnTemplateLevelAlertDefinitionCreation") - public void testNoValidationWhenNoNotificationUpdateOnTemplateLevel() throws Exception { - TestAlertSender.setExpectedSubject(subject); - TestAlertSender.resetValidateMethodCallCount(); - - AlertDefinitionManagerLocal adm = LookupUtil.getAlertDefinitionManager(); - - AlertDefinitionCriteria crit = new AlertDefinitionCriteria(); - crit.addFilterId(templateLevelAlertDefinitionId); - crit.fetchAlertNotifications(true); - crit.fetchConditions(true); - - List<AlertDefinition> foundDefs = adm.findAlertDefinitionsByCriteria(subject, crit); - - assertEquals("Failed to find the previously created resource level alert definition.", 1, foundDefs.size()); - - AlertDefinition foundDef = foundDefs.get(0); - - foundDef.setEnabled(true); - - AlertTemplateManagerLocal atm = LookupUtil.getAlertTemplateManager(); - - atm.updateAlertTemplate(subject, foundDef, true); - - assertEquals("The notification validation method shouldn't have been called", 0, TestAlertSender.getValidateMethodCallCount()); - } - - @Test(dependsOnMethods = "testNoValidationWhenNoNotificationUpdateOnResourceLevel") - public void testCorrectSubjectPassedOnResourceLevelAlertDefinitionUpdate() throws Exception { - TestAlertSender.setExpectedSubject(subject); - TestAlertSender.resetValidateMethodCallCount(); - - AlertDefinitionManagerLocal adm = LookupUtil.getAlertDefinitionManager(); - - AlertDefinitionCriteria crit = new AlertDefinitionCriteria(); - crit.addFilterId(resourceLevelAlertDefinitionId); - crit.fetchAlertNotifications(true); - crit.fetchConditions(true); - - List<AlertDefinition> foundDefs = adm.findAlertDefinitionsByCriteria(subject, crit); - - assertEquals("Failed to find the previously created resource level alert definition.", 1, foundDefs.size()); - - AlertDefinition foundDef = foundDefs.get(0); - - AlertNotification newNotif = createAlertNotificationForTest(foundDef, false); - //just add some dummy config property so that the 2 notifs are distinguishable from each other - //and are saved separately - newNotif.getConfiguration().put(new PropertySimple("foo-resource", "bar")); - - adm.updateAlertDefinition(subject, resourceLevelAlertDefinitionId, foundDef, false); - - assertEquals("Validation should have been called for a new notification during alert def update", 1, TestAlertSender.getValidateMethodCallCount()); - } - - @Test(dependsOnMethods = "testCorrectSubjectPassedOnGroupLevelAlertDefinitionCreation") - public void testCorrectSubjectPassedOnGroupLevelAlertDefinitionUpdate() throws Exception { - TestAlertSender.setExpectedSubject(subject); - TestAlertSender.resetValidateMethodCallCount(); - - AlertDefinitionManagerLocal adm = LookupUtil.getAlertDefinitionManager(); - - AlertDefinitionCriteria crit = new AlertDefinitionCriteria(); - crit.addFilterId(groupLevelAlertDefinitionId); - crit.fetchAlertNotifications(true); - crit.fetchConditions(true); - - List<AlertDefinition> foundDefs = adm.findAlertDefinitionsByCriteria(subject, crit); - - assertEquals("Failed to find the previously created group level alert definition.", 1, foundDefs.size()); - - AlertDefinition foundDef = foundDefs.get(0); - - AlertNotification newNotif = createAlertNotificationForTest(foundDef, false); - //just add some dummy config property so that the 2 notifs are distinguishable from each other - //and are saved separately - newNotif.getConfiguration().put(new PropertySimple("foo-group", "bar")); - - GroupAlertDefinitionManagerLocal gadm = LookupUtil.getGroupAlertDefinitionManager(); - gadm.updateGroupAlertDefinitions(subject, foundDef, true); - - //notice that the validation should be called just once, even though in effect we're creating 11 notifs - //1 for group and 10 for its members. - assertEquals("Validation should have been called for a new notification during alert def update", 1, TestAlertSender.getValidateMethodCallCount()); - } - - @Test(dependsOnMethods = "testCorrectSubjectPassedOnTemplateLevelAlertDefinitionCreation") - public void testCorrectSubjectPassedOnTemplateLevelAlertDefinitionUpdate() throws Exception { - TestAlertSender.setExpectedSubject(subject); - TestAlertSender.resetValidateMethodCallCount(); - - AlertDefinitionManagerLocal adm = LookupUtil.getAlertDefinitionManager(); - - AlertDefinitionCriteria crit = new AlertDefinitionCriteria(); - crit.addFilterId(templateLevelAlertDefinitionId); - crit.fetchAlertNotifications(true); - crit.fetchConditions(true); - - List<AlertDefinition> foundDefs = adm.findAlertDefinitionsByCriteria(subject, crit); - - assertEquals("Failed to find the previously created template level alert definition.", 1, foundDefs.size()); - - AlertDefinition foundDef = foundDefs.get(0); - - AlertNotification newNotif = createAlertNotificationForTest(foundDef, false); - //just add some dummy config property so that the 2 notifs are distinguishable from each other - //and are saved separately - newNotif.getConfiguration().put(new PropertySimple("foo-template", "bar")); - - AlertTemplateManagerLocal atm = LookupUtil.getAlertTemplateManager(); - atm.updateAlertTemplate(subject, foundDef, true); - - //notice that the validation should be called just once, even though in effect we're creating 11 notifs - //1 for template and 10 for its members. - assertEquals("Validation should have been called for a new notification during alert def update", 1, TestAlertSender.getValidateMethodCallCount()); - } - - private void removeNoExceptions(final Object o) { - try { - executeInTransaction(new TransactionCallback() { - public void execute() { - EntityManager em = getEntityManager(); - Object o2 = em.merge(o); - - if (o2 instanceof Resource) { - ResourceTreeHelper.deleteResource(em, (Resource) o2); - } else { - em.remove(o2); - } - } - }); - } catch (Exception e) { - LOG.error("Failed to DELETE an object from database: " + o, e); - } - } - - private AlertDefinition createDefinition(String name) { - AlertDefinition ret = new AlertDefinition(); - ret.setName(name); - ret.setPriority(AlertPriority.MEDIUM); - ret.setAlertDampening(new AlertDampening(AlertDampening.Category.NONE)); - ret.setConditionExpression(BooleanExpression.ANY); - ret.setRecoveryId(0); - - return ret; - } - - private AlertDefinition createDefinitionForTest(String name, boolean precanned) { - AlertDefinition def = createDefinition(name); - createAlertNotificationForTest(def, precanned); - - return def; - } - - private AlertNotification createAlertNotificationForTest(AlertDefinition alertDefinition, boolean precanned) { - AlertNotification notif = new AlertNotification("Test Alert Sender"); - - Configuration alertConfig = new Configuration(); - - if (precanned) { - alertConfig.put(new PropertySimple(TestAlertSender.PERSISTENT_PROPERTY_NAME, TestAlertSender.PERSISTEN_PROPERTY_EXPECTED_VALUE)); - } else { - alertConfig.put(new PropertySimple(TestAlertSender.PERSISTENT_PROPERTY_NAME, "persistent")); - alertConfig.put(new PropertySimple(TestAlertSender.EPHEMERAL_PROPERTY_NAME, "ephemeral")); - } - - Configuration extraConfig = new Configuration(); - - if (precanned) { - extraConfig.put(new PropertySimple(TestAlertSender.PERSISTENT_PROPERTY_NAME, TestAlertSender.PERSISTEN_PROPERTY_EXPECTED_VALUE)); - } else { - extraConfig.put(new PropertySimple(TestAlertSender.PERSISTENT_PROPERTY_NAME, "persistent")); - extraConfig.put(new PropertySimple(TestAlertSender.EPHEMERAL_PROPERTY_NAME, "ephemeral")); - } - - notif.setConfiguration(alertConfig); - notif.setExtraConfiguration(extraConfig); - - alertDefinition.addAlertNotification(notif); - notif.setAlertDefinition(alertDefinition); - - return notif; - } - - private void testMainAlertDefinition(int id) { - AlertDefinitionCriteria crit = new AlertDefinitionCriteria(); - crit.addFilterId(id); - crit.fetchAlertNotifications(true); - - List<AlertDefinition> checkList = - LookupUtil.getAlertDefinitionManager().findAlertDefinitionsByCriteria(subject, crit); - - assertNotNull("Failed to retrieve the save alert definition", checkList); - assertEquals("The alert definition should have been saved.", 1, checkList.size()); - - AlertDefinition check = checkList.get(0); - - assertEquals("There should be exactly 1 notification on the definition", 1, check.getAlertNotifications() - .size()); - - Configuration config = check.getAlertNotifications().get(0).getConfiguration(); - assertEquals("Unexpected persistent value in notif config", TestAlertSender.PERSISTEN_PROPERTY_EXPECTED_VALUE, - config.getSimpleValue(TestAlertSender.PERSISTENT_PROPERTY_NAME, null)); - assertNull("Ephemeral property seems to have been saved", - config.getSimpleValue(TestAlertSender.EPHEMERAL_PROPERTY_NAME, null)); - } - - private List<AlertDefinition> testDependentAlertDefinitions(int expectedParentId, ParentType parentType) { - AlertDefinitionCriteria crit = new AlertDefinitionCriteria(); - - Set<Integer> resourceIds = new HashSet<Integer>(resources.size()); - for (Resource r : resources) { - resourceIds.add(r.getId()); - } - - if (parentType == ParentType.TEMPLATE) { - crit.addFilterAlertTemplateParentId(expectedParentId); - } else if (parentType == ParentType.GROUP) { - crit.addFilterGroupAlertDefinitionId(expectedParentId); - } - - crit.fetchAlertNotifications(true); - - List<AlertDefinition> checkList = - LookupUtil.getAlertDefinitionManager().findAlertDefinitionsByCriteria(subject, crit); - - assertNotNull("Failed to retrieve the save alert definition", checkList); - assertEquals("The dependent alert definitions should have been saved.", resources.size(), checkList.size()); - - for (AlertDefinition check : checkList) { - testSingleDependentAlertDefinition(check, parentType, expectedParentId); - } - - return checkList; - } - - private void testSingleDependentAlertDefinition(AlertDefinition alertDef, ParentType parentType, int expectedParentId) { - assertEquals("There should be exactly 1 notification on the definition " + alertDef, 1, alertDef - .getAlertNotifications().size()); - - Configuration config = alertDef.getAlertNotifications().get(0).getConfiguration(); - assertEquals("Unexpected persistent value in notif config " + alertDef, - TestAlertSender.PERSISTEN_PROPERTY_EXPECTED_VALUE, - config.getSimpleValue(TestAlertSender.PERSISTENT_PROPERTY_NAME, null)); - assertNull("Ephemeral property seems to have been saved " + alertDef, - config.getSimpleValue(TestAlertSender.EPHEMERAL_PROPERTY_NAME, null)); - - if (parentType == ParentType.GROUP) { - assertEquals("The group parent id has unexpected value", expectedParentId, alertDef.getGroupAlertDefinition().getId()); - } else if (parentType == ParentType.TEMPLATE) { - assertEquals("The parent id has unexpected value", Integer.valueOf(expectedParentId), alertDef.getParentId()); - } - } - - private Resource createResourceForTest(String resourceKey) { - Resource res = new ResourceBuilder().createPlatform().withRandomUuid().withResourceKey(resourceKey) - .withResourceType(resourceType).withName(resourceKey) - .withInventoryStatus(InventoryStatus.COMMITTED).build(); - res.setAgent(agent); - - return res; - } -} diff --git a/modules/enterprise/server/itests/src/test/java/org/rhq/enterprise/server/alert/TestAlertSender.java b/modules/enterprise/server/itests/src/test/java/org/rhq/enterprise/server/alert/TestAlertSender.java deleted file mode 100644 index 900d74c..0000000 --- a/modules/enterprise/server/itests/src/test/java/org/rhq/enterprise/server/alert/TestAlertSender.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2012 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.alert; - -import org.testng.Assert; - -import org.rhq.core.domain.alert.Alert; -import org.rhq.core.domain.alert.notification.SenderResult; -import org.rhq.core.domain.auth.Subject; -import org.rhq.core.domain.configuration.Configuration; -import org.rhq.core.domain.configuration.PropertySimple; -import org.rhq.enterprise.server.plugin.pc.ServerPluginComponent; -import org.rhq.enterprise.server.plugin.pc.alert.AlertSender; -import org.rhq.enterprise.server.plugin.pc.alert.AlertSenderValidationResults; - -/** - * - * - * @author Lukas Krejci - */ -public class TestAlertSender extends AlertSender<ServerPluginComponent> { - - public static final String NAME = "Test Alert Sender"; - - public static final String PERSISTENT_PROPERTY_NAME = "persistent"; - public static final String PERSISTEN_PROPERTY_EXPECTED_VALUE = "persistentephemeral"; - public static final String EPHEMERAL_PROPERTY_NAME = "ephemeral"; - - private static Subject EXPECTED_SUBJECT; - private static volatile int VALIDATE_METHOD_CALL_COUNT; - private static Runnable VALIDATION_CHECKER; - - public static void setExpectedSubject(Subject subject) { - EXPECTED_SUBJECT = subject; - } - - public static void setValidationChecker(Runnable validationChecker) { - VALIDATION_CHECKER = validationChecker; - } - - public static int getValidateMethodCallCount() { - return VALIDATE_METHOD_CALL_COUNT; - } - - public static void resetValidateMethodCallCount() { - VALIDATE_METHOD_CALL_COUNT = 0; - } - - @Override - public SenderResult send(Alert alert) { - SenderResult ret = new SenderResult(); - ret.addSuccessMessage("kachny"); - - return ret; - } - - @Override - public AlertSenderValidationResults validateAndFinalizeConfiguration(Subject subject) { - ++VALIDATE_METHOD_CALL_COUNT; - - if (EXPECTED_SUBJECT != null && !subject.equals(EXPECTED_SUBJECT)) { - throw new AssertionError("Unexpected subject. Expected " + EXPECTED_SUBJECT + " but was " + subject); - } - - if (VALIDATION_CHECKER != null) { - VALIDATION_CHECKER.run(); - } - - if (alertParameters.getSimple(EPHEMERAL_PROPERTY_NAME) == null) { - Assert.fail("Ephemeral property not present in alert parameters during validation. This should never happen."); - } - - if (extraParameters.getSimple(EPHEMERAL_PROPERTY_NAME) == null) { - Assert.fail("Ephemeral property not present in extra parameters during validation. This should never happen."); - } - - updateConfig(alertParameters); - updateConfig(extraParameters); - - return new AlertSenderValidationResults(alertParameters, extraParameters); - } - - private void updateConfig(Configuration configuration) { - String persistentValue = configuration.getSimpleValue(PERSISTENT_PROPERTY_NAME, ""); - String ephemeralValue = configuration.getSimpleValue(EPHEMERAL_PROPERTY_NAME, ""); - - configuration.put(new PropertySimple(PERSISTENT_PROPERTY_NAME, persistentValue + ephemeralValue)); - configuration.remove(EPHEMERAL_PROPERTY_NAME); - } -} diff --git a/modules/enterprise/server/itests/src/test/java/org/rhq/enterprise/server/alert/TestAlertSenderPluginService.java b/modules/enterprise/server/itests/src/test/java/org/rhq/enterprise/server/alert/TestAlertSenderPluginService.java deleted file mode 100644 index 9aae985..0000000 --- a/modules/enterprise/server/itests/src/test/java/org/rhq/enterprise/server/alert/TestAlertSenderPluginService.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2012 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.alert; - -import java.util.Collections; -import java.util.List; - -import org.rhq.core.domain.plugin.ServerPlugin; -import org.rhq.enterprise.server.TestServerPluginService; -import org.rhq.enterprise.server.plugin.pc.AbstractTypeServerPluginContainer; -import org.rhq.enterprise.server.plugin.pc.MasterServerPluginContainer; -import org.rhq.enterprise.server.plugin.pc.ServerPluginEnvironment; -import org.rhq.enterprise.server.plugin.pc.ServerPluginManager; -import org.rhq.enterprise.server.plugin.pc.alert.AlertSenderPluginManager; -import org.rhq.enterprise.server.plugin.pc.alert.AlertServerPluginContainer; - -/** - * - * - * @author Lukas Krejci - */ -public class TestAlertSenderPluginService extends TestServerPluginService { - - @Override - protected List<AbstractTypeServerPluginContainer> createPluginContainers(MasterServerPluginContainer master) { - return Collections.<AbstractTypeServerPluginContainer>singletonList(new TestAlertServerPluginContainer(master)); - } - - class TestAlertServerPluginContainer extends AlertServerPluginContainer { - public TestAlertServerPluginContainer(MasterServerPluginContainer master) { - super(master); - } - - @Override - protected ServerPluginManager createPluginManager() { - return new TestAlertServerPluginManager(this); - } - } - - class TestAlertServerPluginManager extends AlertSenderPluginManager { - public TestAlertServerPluginManager(AlertServerPluginContainer pc) { - super(pc); - } - - @Override - protected ServerPlugin getPlugin(ServerPluginEnvironment env) { - return TestServerPluginService.getPlugin(env); - } - } -} diff --git a/modules/enterprise/server/itests/src/test/java/org/rhq/enterprise/server/drift/AbstractDriftServerTest.java b/modules/enterprise/server/itests/src/test/java/org/rhq/enterprise/server/drift/AbstractDriftServerTest.java deleted file mode 100644 index 4f43c5d..0000000 --- a/modules/enterprise/server/itests/src/test/java/org/rhq/enterprise/server/drift/AbstractDriftServerTest.java +++ /dev/null @@ -1,238 +0,0 @@ -/* - * 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 org.rhq.core.domain.resource.ResourceCategory.SERVER; -import static org.rhq.enterprise.server.util.LookupUtil.getSubjectManager; - -import java.io.File; -import java.lang.reflect.Method; -import java.util.List; - -import javax.persistence.EntityManager; -import javax.persistence.NoResultException; -import javax.persistence.NonUniqueResultException; - -import org.apache.commons.io.FileUtils; -import org.testng.annotations.AfterClass; -import org.testng.annotations.AfterMethod; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.Test; - -import org.rhq.core.domain.auth.Subject; -import org.rhq.core.domain.drift.Drift; -import org.rhq.core.domain.drift.DriftDefinition; -import org.rhq.core.domain.drift.DriftDefinitionTemplate; -import org.rhq.core.domain.resource.Agent; -import org.rhq.core.domain.resource.Resource; -import org.rhq.core.domain.resource.ResourceType; -import org.rhq.core.domain.shared.ResourceBuilder; -import org.rhq.core.domain.shared.ResourceTypeBuilder; -import org.rhq.enterprise.server.plugin.ServerPluginsLocal; -import org.rhq.enterprise.server.test.AbstractEJB3Test; -import org.rhq.enterprise.server.test.TestServerCommunicationsService; -import org.rhq.enterprise.server.util.ResourceTreeHelper; -import org.rhq.enterprise.server.test.TransactionCallback; - -@Test(groups = "drift", sequential = true) -public abstract class AbstractDriftServerTest extends AbstractEJB3Test { - - protected final String RESOURCE_TYPE_NAME = getClass().getSimpleName() + "_RESOURCE_TYPE"; - - protected final String AGENT_NAME = getClass().getSimpleName() + "_AGENT"; - - protected final String RESOURCE_NAME = getClass().getSimpleName() + "_RESOURCE"; - - private ServerPluginsLocal serverPluginsMgr; - - protected DriftServerPluginService driftServerPluginService; - - protected TestServerCommunicationsService agentServiceContainer; - - protected ResourceType resourceType; - - protected Agent agent; - - protected Resource resource; - - @BeforeMethod - public void initServices(Method testMethod) throws Exception { - initDriftServer(); - initAgentServices(); - - InitDB annotation = testMethod.getAnnotation(InitDB.class); - if (annotation == null || annotation.value()) { - initDB(); - } - } - - private void initDriftServer() throws Exception { - driftServerPluginService = new DriftServerPluginService(); - prepareCustomServerPluginService(driftServerPluginService); - driftServerPluginService.masterConfig.getPluginDirectory().mkdirs(); - - String projectVersion = System.getProperty("projectVersion"); - - File jpaDriftPlugin = new File("../plugins/drift-rhq/target/rhq-serverplugin-drift-" + projectVersion + ".jar"); - assertTrue("Drift server plugin JAR file not found at" + jpaDriftPlugin.getPath(), jpaDriftPlugin.exists()); - FileUtils.copyFileToDirectory(jpaDriftPlugin, driftServerPluginService.masterConfig.getPluginDirectory()); - - driftServerPluginService.startMasterPluginContainer(); - - //serverPluginsMgr = LookupUtil.getServerPlugins(); - } - - private void initAgentServices() { - agentServiceContainer = prepareForTestAgents(); - agentServiceContainer.driftService = new TestDefService(); - } - - @AfterMethod - public void shutDownServices() throws Exception { - shutDownDriftServer(); - shutDownAgentServices(); - } - - private void shutDownDriftServer() throws Exception { - unprepareServerPluginService(); - //already done by the above call - //driftServerPluginService.stopMasterPluginContainer(); - } - - private void shutDownAgentServices() { - agentServiceContainer = null; - unprepareForTestAgents(); - } - - @AfterClass - public void cleanUpDB() throws Exception { - purgeDB(); - executeInTransaction(new TransactionCallback() { - @Override - public void execute() throws Exception { - purgeDB(getEntityManager()); - } - }); - } - - private void initDB() throws Exception { - purgeDB(); - executeInTransaction(new TransactionCallback() { - @Override - public void execute() throws Exception { - EntityManager em = getEntityManager(); - initResourceType(); - initAgent(); - initResource(); - - em.persist(resourceType); - em.persist(agent); - resource.setAgent(agent); - em.persist(resource); - - initDB(em); - } - }); - } - - private void purgeDB() { - executeInTransaction(new TransactionCallback() { - @Override - public void execute() throws Exception { - EntityManager em = getEntityManager(); - - em.createQuery("delete from JPADrift ").executeUpdate(); - em.createQuery("delete from JPADriftChangeSet").executeUpdate(); - em.createQuery("delete from JPADriftSet").executeUpdate(); - em.createQuery("delete from JPADriftFile").executeUpdate(); - em.createQuery("delete from DriftDefinition").executeUpdate(); - em.createQuery("delete from DriftDefinitionTemplate").executeUpdate(); - - deleteEntity(Resource.class, RESOURCE_NAME, em); - deleteEntity(Agent.class, AGENT_NAME, em); - deleteEntity(ResourceType.class, RESOURCE_TYPE_NAME, em); - - purgeDB(em); - } - }); - } - - protected void purgeDB(EntityManager em) { - } - - protected void initDB(EntityManager em) { - } - - protected void deleteEntity(Class<?> clazz, String name, EntityManager em) { - try { - Object entity = em - .createQuery("select entity from " + clazz.getSimpleName() + " entity where entity.name = :name") - .setParameter("name", name).getSingleResult(); - if (clazz.equals(Resource.class)) { - ResourceTreeHelper.deleteResource(em, (Resource) entity); - } else { - em.remove(entity); - } - } catch (NoResultException e) { - // we can ignore no results because this code will run when the db - // is empty and we expect no results in that case - } catch (NonUniqueResultException e) { - // we will fail here to let the person running the test know that - // the database may not be in a consistent state - fail("Purging " + name + " failed. Expected to find one instance of " + clazz.getSimpleName() - + " but found more than one. The database may not be in a consistent state."); - } - } - - protected void initResourceType() { - resourceType = new ResourceTypeBuilder().createResourceType().withId(0).withName(RESOURCE_TYPE_NAME) - .withCategory(SERVER).withPlugin(RESOURCE_TYPE_NAME.toLowerCase()).build(); - } - - protected void initAgent() { - agent = new Agent(AGENT_NAME, AGENT_NAME, 17080, "", AGENT_NAME + "_TOKEN"); - } - - protected void initResource() { - resource = new ResourceBuilder().createResource().withId(0).withName(RESOURCE_NAME) - .withResourceKey(RESOURCE_NAME).withRandomUuid().withResourceType(resourceType).build(); - } - - protected Subject getOverlord() { - return getSubjectManager().getOverlord(); - } - - protected String toString(DriftDefinition def) { - return "DriftDefinition[id: " + def.getId() + ", name: " + def.getName() + "]"; - } - - protected String toString(DriftDefinitionTemplate template) { - return DriftDefinitionTemplate.class.getSimpleName() + "[id: " + template.getId() + ", name: " - + template.getName() + "]"; - } - - protected Drift findDriftByPath(List<? extends Drift> drifts, String path) { - for (Drift drift : drifts) { - if (drift.getPath().equals(path)) { - return drift; - } - } - return null; - } -} diff --git a/modules/enterprise/server/itests/src/test/java/org/rhq/enterprise/server/drift/DriftServerPluginService.java b/modules/enterprise/server/itests/src/test/java/org/rhq/enterprise/server/drift/DriftServerPluginService.java deleted file mode 100644 index 46d725f..0000000 --- a/modules/enterprise/server/itests/src/test/java/org/rhq/enterprise/server/drift/DriftServerPluginService.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 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 java.util.Collections; -import java.util.List; - -import org.rhq.core.domain.plugin.ServerPlugin; -import org.rhq.enterprise.server.TestServerPluginService; -import org.rhq.enterprise.server.plugin.pc.AbstractTypeServerPluginContainer; -import org.rhq.enterprise.server.plugin.pc.MasterServerPluginContainer; -import org.rhq.enterprise.server.plugin.pc.ServerPluginEnvironment; -import org.rhq.enterprise.server.plugin.pc.ServerPluginManager; -import org.rhq.enterprise.server.plugin.pc.drift.DriftServerPluginContainer; -import org.rhq.enterprise.server.plugin.pc.drift.DriftServerPluginManager; - -public class DriftServerPluginService extends TestServerPluginService { - - @Override - protected List<AbstractTypeServerPluginContainer> createPluginContainers(MasterServerPluginContainer master) { - return Collections.<AbstractTypeServerPluginContainer>singletonList(new TestDriftServerPluginContainer(master)); - } - - - class TestDriftServerPluginContainer extends DriftServerPluginContainer { - public TestDriftServerPluginContainer(MasterServerPluginContainer master) { - super(master); - } - - @Override - protected ServerPluginManager createPluginManager() { - return new TestDriftServerPluginManager(this); - } - } - - class TestDriftServerPluginManager extends DriftServerPluginManager { - public TestDriftServerPluginManager(DriftServerPluginContainer pc) { - super(pc); - } - - @Override - protected ServerPlugin getPlugin(ServerPluginEnvironment env) { - return TestServerPluginService.getPlugin(env); - } - } -} diff --git a/modules/enterprise/server/itests/src/test/java/org/rhq/enterprise/server/drift/DriftTemplateManagerBeanTest.java b/modules/enterprise/server/itests/src/test/java/org/rhq/enterprise/server/drift/DriftTemplateManagerBeanTest.java deleted file mode 100644 index bbd93b1..0000000 --- a/modules/enterprise/server/itests/src/test/java/org/rhq/enterprise/server/drift/DriftTemplateManagerBeanTest.java +++ /dev/null @@ -1,614 +0,0 @@ -/* - * 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.util.ArrayList; -import java.util.LinkedList; -import java.util.List; - -import javax.ejb.EJBException; -import javax.persistence.EntityManager; - -import org.testng.annotations.BeforeClass; -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.test.AssertUtils; -import org.rhq.enterprise.server.test.TransactionCallback; - -public class DriftTemplateManagerBeanTest extends AbstractDriftServerTest { - - private static final String TEST_CREATE_TEMPLATE = "test-createTemplateForNegativeUpdateTests"; - private static final String TEST_PIN_TEMPLATE = "test-pinTemplate"; - - private DriftTemplateManagerLocal templateMgr; - - private DriftManagerLocal driftMgr; - - private JPADrift drift1; - private JPADrift drift2; - private JPADriftFile driftFile1; - private JPADriftFile driftFile2; - - @BeforeClass - public void initClass() { - templateMgr = getDriftTemplateManager(); - driftMgr = getDriftManager(); - } - - @Override - protected void initDB(EntityManager em) { - 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("test-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(new TransactionCallback() { - @Override - public void execute() throws Exception { - EntityManager em = getEntityManager(); - - 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); - } - }); - } - - @Test(groups = "negativeUpdate") - public 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); - getEntityManager().clear(); - System.out.println("Created " + template.toString(false)); - } - - @Test(groups = "negativeUpdate", dependsOnMethods = "createTemplateForNegativeUpdateTests", expectedExceptions = EJBException.class, expectedExceptionsMessageRegExp = ".*base directory.*cannot be modified") - @InitDB(false) - public 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") - @InitDB(false) - public 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") - @InitDB(false) - public void doNotAllowTemplateNameToBeUpdated() { - DriftDefinitionTemplate template = loadTemplate(TEST_CREATE_TEMPLATE); - template.setName("A new name"); - - templateMgr.updateTemplate(getOverlord(), template); - } - - @Test(groups = "negativeUpdate", dependsOnMethods = "createTemplateForNegativeUpdateTests", expectedExceptions = EJBException.class, expectedExceptionsMessageRegExp = ".*template name must be unique.*") - @InitDB(false) - public 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("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, "attachedDef1", true); - final DriftDefinition attachedDef2 = createDefinition(template, "attachedDef2", true); - final DriftDefinition detachedDef1 = createDefinition(template, "detachedDef1", false); - final DriftDefinition detachedDef2 = createDefinition(template, "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 tempalte 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()); - } - } - - @Test(groups = "pinning", dependsOnGroups = "negativeUpdate") - public 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, "attachedDef1", true); - final DriftDefinition attachedDef2 = createDefinition(template, "attachedDef2", true); - final DriftDefinition detachedDef1 = createDefinition(template, "detachedDef1", false); - final DriftDefinition detachedDef2 = createDefinition(template, "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("a1b2c3"); - drift1 = new JPADrift(changeSet0, "drift.1", FILE_ADDED, null, driftFile1); - - final JPADriftSet driftSet = new JPADriftSet(); - driftSet.addDrift(drift1); - - // create change set v1 - driftFile2 = new JPADriftFile("1a2b3c"); - final JPADriftChangeSet changeSet1 = new JPADriftChangeSet(resource, 1, DRIFT, attachedDef1); - drift2 = new JPADrift(changeSet1, "drift.2", FILE_ADDED, null, driftFile2); - - executeInTransaction(new TransactionCallback() { - @Override - public void execute() throws Exception { - EntityManager em = getEntityManager(); - - 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") - @InitDB(false) - public 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, "drift.1", 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, "drift.1").getNewDriftFile(), - "The newDriftFile property was not set correctly for " + drift1); - assertPropertiesMatch(drift2.getNewDriftFile(), findDriftByPath(actualDrifts, "drift.2").getNewDriftFile(), - "The newDriftFile property was not set correctly for " + drift1); - } - - @Test(groups = "pinning", dependsOnMethods = "pinTemplate") - @InitDB(false) - public 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("attachedDef1") || d.getName().equals("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") - @InitDB(false) - public 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("detachedDef1") || d.getName().equals("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, "attachedDef1", true); - final DriftDefinition attachedDef2 = createDefinition(template, "attachedDef2", true); - final DriftDefinition detachedDef1 = createDefinition(template, "detachedDef1", false); - final DriftDefinition detachedDef2 = createDefinition(template, "detachedDef2", false); - - // create some change sets - final JPADriftChangeSet changeSet0 = new JPADriftChangeSet(resource, 0, COVERAGE, attachedDef1); - - driftFile1 = new JPADriftFile("a1b2c3"); - drift1 = new JPADrift(changeSet0, "drift.1", FILE_ADDED, null, driftFile1); - - final JPADriftSet driftSet0 = new JPADriftSet(); - driftSet0.addDrift(drift1); - - final JPADriftChangeSet changeSet1 = new JPADriftChangeSet(resource, 0, DRIFT, detachedDef1); - - driftFile2 = new JPADriftFile("1a2b3c"); - drift2 = new JPADrift(changeSet1, "drift.2", FILE_ADDED, null, driftFile2); - - final JPADriftSet driftSet1 = new JPADriftSet(); - driftSet1.addDrift(drift2); - - executeInTransaction(new TransactionCallback() { - @Override - public void execute() throws Exception { - EntityManager em = getEntityManager(); - - 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); - } - -} diff --git a/modules/enterprise/server/itests/src/test/java/org/rhq/enterprise/server/drift/InitDB.java b/modules/enterprise/server/itests/src/test/java/org/rhq/enterprise/server/drift/InitDB.java deleted file mode 100644 index 65a6523..0000000 --- a/modules/enterprise/server/itests/src/test/java/org/rhq/enterprise/server/drift/InitDB.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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.lang.annotation.RetentionPolicy.RUNTIME; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - -@Retention(RUNTIME) -@Target({ElementType.METHOD }) -public @interface InitDB { - boolean value() default true; -} diff --git a/modules/enterprise/server/itests/src/test/java/org/rhq/enterprise/server/drift/JPADriftServerBeanTest.java b/modules/enterprise/server/itests/src/test/java/org/rhq/enterprise/server/drift/JPADriftServerBeanTest.java deleted file mode 100644 index dee42d9..0000000 --- a/modules/enterprise/server/itests/src/test/java/org/rhq/enterprise/server/drift/JPADriftServerBeanTest.java +++ /dev/null @@ -1,311 +0,0 @@ -/* - * 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.apache.commons.io.IOUtils.toInputStream; -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.DriftConfigurationDefinition.BaseDirValueContext.fileSystem; -import static org.rhq.core.domain.drift.DriftConfigurationDefinition.DriftHandlingMode.normal; -import static org.rhq.core.domain.drift.DriftFileStatus.LOADED; -import static org.rhq.enterprise.server.util.LookupUtil.getJPADriftServer; -import static org.rhq.test.AssertUtils.assertPropertiesMatch; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import javax.persistence.EntityManager; - -import org.testng.annotations.BeforeClass; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.Test; - -import org.rhq.core.domain.configuration.Configuration; -import org.rhq.core.domain.criteria.JPADriftChangeSetCriteria; -import org.rhq.core.domain.drift.Drift; -import org.rhq.core.domain.drift.DriftDefinition; -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.drift.dto.DriftChangeSetDTO; -import org.rhq.core.domain.drift.dto.DriftDTO; -import org.rhq.core.domain.drift.dto.DriftFileDTO; -import org.rhq.core.domain.util.PageList; -import org.rhq.test.AssertUtils; -import org.rhq.enterprise.server.test.TransactionCallback; - -@Test(dependsOnGroups = "pinning") -public class JPADriftServerBeanTest extends AbstractDriftServerTest { - - private JPADriftServerLocal jpaDriftServer; - - private final String DRIFT_FILE_1_ID = "a1b2c3d4"; - - private final String DRIFT_FILE_2_ID = "1ab2b3c4d"; - - private JPADriftFile driftFile1; - - private JPADriftFile driftFile2; - - @BeforeClass - public void initTests() { - jpaDriftServer = getJPADriftServer(); - } - - @BeforeMethod - public void persistDriftFiles() throws Exception { - driftFile1 = jpaDriftServer.persistDriftFile(new JPADriftFile(DRIFT_FILE_1_ID)); - driftFile2 = jpaDriftServer.persistDriftFile(new JPADriftFile(DRIFT_FILE_2_ID)); - - String driftFile1Content = "drift file 1 content..."; - String driftFile2Content = "drift file 2 content..."; - - jpaDriftServer.persistDriftFileData(driftFile1, toInputStream(driftFile1Content), driftFile1Content.length()); - jpaDriftServer.persistDriftFileData(driftFile2, toInputStream(driftFile2Content), driftFile2Content.length()); - - driftFile1 = jpaDriftServer.getDriftFile(getOverlord(), DRIFT_FILE_1_ID); - driftFile2 = jpaDriftServer.getDriftFile(getOverlord(), DRIFT_FILE_2_ID); - - assertDriftFilePersisted(driftFile1, "driftFile1", driftFile1Content); - assertDriftFilePersisted(driftFile2, "driftFile2", driftFile2Content); - } - - public void persistResourceChangeSet() { - // first create and persist the drift definition - final DriftDefinition driftDef = new DriftDefinition(new Configuration()); - driftDef.setName("test::persistResourceChangeSet"); - driftDef.setEnabled(true); - driftDef.setDriftHandlingMode(normal); - driftDef.setInterval(2400L); - driftDef.setBasedir(new DriftDefinition.BaseDirectory(fileSystem, "/foo/bar/test")); - driftDef.setResource(resource); - - executeInTransaction(new TransactionCallback() { - @Override - public void execute() throws Exception { - EntityManager em = getEntityManager(); - em.persist(driftDef); - } - }); - - // create the change set to be persisted - DriftChangeSetDTO changeSet = new DriftChangeSetDTO(); - changeSet.setCategory(COVERAGE); - changeSet.setVersion(1); - changeSet.setDriftDefinitionId(driftDef.getId()); - changeSet.setResourceId(resource.getId()); - changeSet.setDriftHandlingMode(normal); - changeSet.setCtime(System.currentTimeMillis()); - - DriftDTO drift1 = new DriftDTO(); - drift1.setCategory(FILE_ADDED); - drift1.setPath("drift.1"); - drift1.setChangeSet(changeSet); - drift1.setCtime(System.currentTimeMillis()); - drift1.setNewDriftFile(toDTo(driftFile1)); - - DriftDTO drift2 = new DriftDTO(); - drift2.setCategory(FILE_ADDED); - drift2.setPath("drift.2"); - drift2.setChangeSet(changeSet); - drift2.setCtime(System.currentTimeMillis()); - drift2.setNewDriftFile(toDTo(driftFile2)); - - Set<DriftDTO> drifts = new HashSet<DriftDTO>(); - drifts.add(drift1); - drifts.add(drift2); - changeSet.setDrifts(drifts); - - String newChangeSetId = jpaDriftServer.persistChangeSet(getOverlord(), changeSet); - - // verify that the change set was persisted - JPADriftChangeSetCriteria criteria = new JPADriftChangeSetCriteria(); - criteria.addFilterId(newChangeSetId); - criteria.fetchDrifts(true); - - PageList<JPADriftChangeSet> changeSets = jpaDriftServer.findDriftChangeSetsByCriteria(getOverlord(), criteria); - assertEquals("Expected to find one change set", 1, changeSets.size()); - - JPADriftChangeSet jpaChangeSet = changeSets.get(0); - assertEquals("Expected change set to contain two drifts. This could be a result of the change set not being " + - "persisted correctly or the criteria fetch being done incorrectly.", 2, jpaChangeSet.getDrifts().size()); - - AssertUtils - .assertPropertiesMatch("The change set was not persisted correctly", changeSet, jpaChangeSet, "id", "drifts", - "class", "ctime"); - - List<? extends Drift> expectedDrifts = asList(drift1, drift2); - List<? extends Drift> actualDrifts = new ArrayList(jpaChangeSet.getDrifts()); - - // We ignore the id and ctime properties because those are set by JPADriftServerBean - // and are somewhat implmentation specific. We ignore the directory property because - // it is really a calculated property. newDriftFile has to be compared separately - // since it does not implement equals. - AssertUtils.assertCollectionMatchesNoOrder("The change set drifts were not persisted correctly", - (List<Drift>) expectedDrifts, (List<Drift>) actualDrifts, "id", "ctime", "changeSet", "directory", - "newDriftFile", "class"); - - assertPropertiesMatch("The newDriftFile property was not set correctly for " + drift1, drift1.getNewDriftFile(), - findDriftByPath(actualDrifts, "drift.1").getNewDriftFile(), "class", "ctime") ; - assertPropertiesMatch("The newDriftFile property was not set correctly for " + drift2, drift2.getNewDriftFile(), - findDriftByPath(actualDrifts, "drift.2").getNewDriftFile(), "class", "ctime") ; - } - - public void persistTemplateChangeSet() { - // create the change set to be persisted - // - // Note that we do not set the drift definition id or resource id since - // the change set is not owned by a resource. It is owned by the - // resource type. - DriftChangeSetDTO changeSet = new DriftChangeSetDTO(); - changeSet.setCategory(COVERAGE); - changeSet.setVersion(1); - changeSet.setDriftHandlingMode(normal); - changeSet.setCtime(System.currentTimeMillis()); - - DriftDTO drift1 = new DriftDTO(); - drift1.setCategory(FILE_ADDED); - drift1.setPath("drift.1"); - drift1.setChangeSet(changeSet); - drift1.setCtime(System.currentTimeMillis()); - drift1.setNewDriftFile(toDTo(driftFile1)); - - DriftDTO drift2 = new DriftDTO(); - drift2.setCategory(FILE_ADDED); - drift2.setPath("drift.2"); - drift2.setChangeSet(changeSet); - drift2.setCtime(System.currentTimeMillis()); - drift2.setNewDriftFile(toDTo(driftFile2)); - - Set<DriftDTO> drifts = new HashSet<DriftDTO>(); - drifts.add(drift1); - drifts.add(drift2); - changeSet.setDrifts(drifts); - - String newChangeSetId = jpaDriftServer.persistChangeSet(getOverlord(), changeSet); - - // verify that the change set was persisted - JPADriftChangeSetCriteria criteria = new JPADriftChangeSetCriteria(); - criteria.addFilterId(newChangeSetId); - criteria.fetchDrifts(true); - - PageList<JPADriftChangeSet> changeSets = jpaDriftServer.findDriftChangeSetsByCriteria(getOverlord(), criteria); - assertEquals("Expected to find one change set", 1, changeSets.size()); - - JPADriftChangeSet jpaChangeSet = changeSets.get(0); - assertEquals("Expected change set to contain two drifts. This could be a result of the change set not being " + - "persisted correctly or the criteria fetch being done incorrectly.", 2, jpaChangeSet.getDrifts().size()); - - AssertUtils - .assertPropertiesMatch("The change set was not persisted correctly", changeSet, jpaChangeSet, "id", "drifts", - "class", "ctime"); - - List<? extends Drift> expectedDrifts = asList(drift1, drift2); - List<? extends Drift> actualDrifts = new ArrayList(jpaChangeSet.getDrifts()); - - // We ignore the id and ctime properties because those are set by JPADriftServerBean - // and are somewhat implmentation specific. We ignore the directory property because - // it is really a calculated property. newDriftFile has to be compared separately - // since it does not implement equals. - AssertUtils.assertCollectionMatchesNoOrder("The change set drifts were not persisted correctly", - (List<Drift>) expectedDrifts, (List<Drift>) actualDrifts, "id", "ctime", "changeSet", "directory", - "newDriftFile", "class"); - - assertPropertiesMatch("The newDriftFile property was not set correctly for " + drift1, drift1.getNewDriftFile(), - findDriftByPath(actualDrifts, "drift.1").getNewDriftFile(), "class", "ctime") ; - assertPropertiesMatch("The newDriftFile property was not set correctly for " + drift2, drift2.getNewDriftFile(), - findDriftByPath(actualDrifts, "drift.2").getNewDriftFile(), "class", "ctime") ; - } - - public void copyChangeSet() { - // first create the change set that will be copied - final JPADriftChangeSet changeSet = new JPADriftChangeSet(null, 0, COVERAGE, null); - changeSet.setDriftHandlingMode(normal); - - final JPADrift drift1 = new JPADrift(changeSet, "drift.1", FILE_ADDED, null, driftFile1); - final JPADrift drift2 = new JPADrift(changeSet, "drift.2", FILE_ADDED, null, driftFile2); - - final JPADriftSet driftSet = new JPADriftSet(); - driftSet.addDrift(drift1); - driftSet.addDrift(drift2); - - // next create the drift definition - final DriftDefinition driftDef = new DriftDefinition(new Configuration()); - driftDef.setName("test::copyChangeSet"); - driftDef.setEnabled(true); - driftDef.setDriftHandlingMode(normal); - driftDef.setInterval(2400L); - driftDef.setBasedir(new DriftDefinition.BaseDirectory(fileSystem, "/foo/bar/test")); - driftDef.setResource(resource); - - // persist the change set and drift definition - executeInTransaction(new TransactionCallback() { - @Override - public void execute() throws Exception { - EntityManager em = getEntityManager(); - em.persist(changeSet); - em.persist(driftDef); - em.persist(driftSet); - changeSet.setInitialDriftSet(driftSet); - em.merge(changeSet); - } - }); - - jpaDriftServer.copyChangeSet(getOverlord(), changeSet.getId(), driftDef.getId(), resource.getId()); - - // verify that the change set was created for the definition - JPADriftChangeSetCriteria criteria = new JPADriftChangeSetCriteria(); - criteria.addFilterDriftDefinitionId(driftDef.getId()); - criteria.addFilterCategory(COVERAGE); - - PageList<JPADriftChangeSet> changeSets = jpaDriftServer.findDriftChangeSetsByCriteria(getOverlord(), criteria); - - assertEquals("Expected to get back one change set", 1,changeSets.size()); - - JPADriftChangeSet newChangeSet = changeSets.get(0); - Set<JPADrift> expectedDrifts = new HashSet<JPADrift>(asList(drift1, drift2)); - Set<JPADrift> actualDrifts = newChangeSet.getDrifts(); - - AssertUtils.assertCollectionMatchesNoOrder("The change set drifts were not copied correctly", expectedDrifts, - actualDrifts, - "changeSet", "newDriftFile"); - } - - private DriftFileDTO toDTo(JPADriftFile driftFile) { - DriftFileDTO dto = new DriftFileDTO(); - dto.setHashId(driftFile.getHashId()); - dto.setDataSize(driftFile.getDataSize()); - dto.setStatus(driftFile.getStatus()); - return dto; - } - - - private void assertDriftFilePersisted(JPADriftFile driftFile, String name, String content) { - assertNotNull("Failed to get " + name + " Was it persisted?", driftFile); - assertEquals("The content for " + name + " is wrong", content, jpaDriftServer.getDriftFileBits( - driftFile.getHashId())); - assertEquals("The drift file status is wrong", LOADED, driftFile.getStatus()); - } - -} diff --git a/modules/enterprise/server/itests/src/test/java/org/rhq/enterprise/server/drift/ManageDriftDefinitionsTest.java b/modules/enterprise/server/itests/src/test/java/org/rhq/enterprise/server/drift/ManageDriftDefinitionsTest.java deleted file mode 100644 index 564264a..0000000 --- a/modules/enterprise/server/itests/src/test/java/org/rhq/enterprise/server/drift/ManageDriftDefinitionsTest.java +++ /dev/null @@ -1,326 +0,0 @@ -/* - * 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 org.rhq.core.domain.common.EntityContext; -import org.rhq.core.domain.configuration.Configuration; -import org.rhq.core.domain.criteria.DriftDefinitionCriteria; -import org.rhq.core.domain.criteria.JPADriftChangeSetCriteria; -import org.rhq.core.domain.drift.*; -import org.rhq.core.domain.resource.Resource; -import org.rhq.core.domain.resource.ResourceType; -import org.rhq.core.domain.util.PageList; -import org.rhq.enterprise.server.safeinvoker.HibernateDetachUtility; -import org.rhq.test.AssertUtils; -import org.rhq.enterprise.server.test.TransactionCallback; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; - -import javax.persistence.EntityManager; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.atomic.AtomicBoolean; - -import static java.util.Arrays.asList; -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.DriftConfigurationDefinition.BaseDirValueContext.fileSystem; -import static org.rhq.core.domain.drift.DriftConfigurationDefinition.DriftHandlingMode.normal; -import static org.rhq.core.domain.drift.DriftDefinitionComparator.CompareMode.BOTH_BASE_INFO_AND_DIRECTORY_SPECIFICATIONS; -import static org.rhq.enterprise.server.util.LookupUtil.getDriftManager; -import static org.rhq.enterprise.server.util.LookupUtil.getDriftTemplateManager; - -@Test(dependsOnGroups = "pinning") -public class ManageDriftDefinitionsTest extends AbstractDriftServerTest { - - private final String DRIFT_NOT_SUPPORTED_TYPE = getClass().getSimpleName() + "DRIFT_NOT_SUPPORTED_RESOURCE_TYPE"; - - private final String DRIFT_NOT_SUPPORTED_RESOURCE = getClass().getSimpleName() + "DRIFT_NOT_SUPPORTED_RESOURCE"; - - private DriftManagerLocal driftMgr; - - private DriftTemplateManagerLocal templateMgr; - - private ResourceType driftNotSupportedType; - - private Resource driftNotSupportedResource; - - @BeforeClass - public void initClass() throws Exception { - driftMgr = getDriftManager(); - templateMgr = getDriftTemplateManager(); - } - - @Override - protected void purgeDB(EntityManager em) { - deleteEntity(Resource.class, DRIFT_NOT_SUPPORTED_RESOURCE, em); - deleteEntity(ResourceType.class, DRIFT_NOT_SUPPORTED_TYPE, em); - } - - public void createDefinitionFromUnpinnedTemplate() { - // first create a template - final DriftDefinition templateDef = new DriftDefinition(new Configuration()); - templateDef.setName("test_createUnpinnedDefinition"); - templateDef.setEnabled(true); - templateDef.setDriftHandlingMode(normal); - templateDef.setInterval(2400L); - templateDef.setBasedir(new DriftDefinition.BaseDirectory(fileSystem, "/foo/bar/test")); - - // persist the template - DriftDefinitionTemplate template = templateMgr.createTemplate(getOverlord(), resourceType.getId(), false, - templateDef); - - // create and persist the definition - DriftDefinition definition = template.createDefinition(); - definition.setTemplate(template); - driftMgr.updateDriftDefinition(getOverlord(), EntityContext.forResource(resource.getId()), definition); - - // verify that the definition was created - DriftDefinition newDef = loadDefinition(definition.getName()); - DriftDefinitionComparator comparator = new DriftDefinitionComparator( - BOTH_BASE_INFO_AND_DIRECTORY_SPECIFICATIONS); - - assertEquals("The drift definition was not persisted correctly", 0, comparator.compare(definition, newDef)); - assertEquals("The template association was not set on the definition", template, newDef.getTemplate()); - } - - // The following two tests are commented out because when they are enabled - // and all tests in the itests module are run, the @AfterClass method for - // DriftTemplateManagerBeanTest does not run immediately after all of its - // test methods have finished running. Instead, some of the tests in - // ManageDriftDefinitionsTest start running. This leads to some database - // constraint violations because of how agents are created in the parent - // class, DriftServerTest. See http://groups.google.com/group/testng-users/browse_thread/thread/da2790679a430d51?pli=1 - // more info on the order in which TestNG executes tests. - -// public void createEntitiesThatDoNotSupportDrift() { -// // first create the resource type that does not support drift -// driftNotSupportedType = new ResourceTypeBuilder() -// .createResourceType() -// .withId(0) -// .withName(DRIFT_NOT_SUPPORTED_TYPE) -// .withCategory(SERVER) -// .withPlugin(DRIFT_NOT_SUPPORTED_TYPE.toLowerCase()) -// .build(); -// -// // create a resource of the type that does not support drift -// driftNotSupportedResource = new ResourceBuilder() -// .createResource() -// .withId(0) -// .withName(DRIFT_NOT_SUPPORTED_RESOURCE) -// .withResourceKey(DRIFT_NOT_SUPPORTED_RESOURCE) -// .withRandomUuid() -// .withResourceType(driftNotSupportedType) -// .build(); -// -// executeInTransaction(new TransactionCallback() { -// @Override -// public void execute() throws Exception { -// EntityManager em = getEntityManager(); -// em.persist(driftNotSupportedType); -// em.persist(driftNotSupportedResource); -// } -// }); -// } -// -// @Test(dependsOnMethods = "createEntitiesThatDoNotSupportDrift", -// expectedExceptions = EJBException.class, -// expectedExceptionsMessageRegExp = ".*Cannot create drift definition.*type.*does not support drift management") -// @InitDB(false) -// public void doNotAllowDefinitionToBeCreatedForTypeThatDoesNotSupportDrift() { -// DriftDefinition driftDef = new DriftDefinition(new Configuration()); -// driftDef.setName("test_typeDoesNotSupportDrift"); -// driftDef.setEnabled(true); -// driftDef.setInterval(1800L); -// driftDef.setDriftHandlingMode(normal); -// driftDef.setBasedir(new DriftDefinition.BaseDirectory(fileSystem, "/foo/bar/test")); -// -// driftMgr.updateDriftDefinition(getOverlord(), EntityContext.forResource(driftNotSupportedResource.getId()), -// driftDef); -// } - - @SuppressWarnings("unchecked") - public void createDefinitionFromPinnedTemplate() throws Exception { - // We first need to create a pinned template. Users can only create a pinned - // template from a snapshot of an existing resource-level drift definition. - // We are going to take a bit of a short cut though by directly creating - // and persisting the pinned change set. - - // first create the change set - final JPADriftChangeSet changeSet0 = new JPADriftChangeSet(null, 0, COVERAGE, null); - changeSet0.setDriftHandlingMode(DriftConfigurationDefinition.DriftHandlingMode.normal); - - final JPADriftFile driftFile1 = new JPADriftFile("a1b2c3"); - final JPADriftFile driftFile2 = new JPADriftFile("1a2b3c"); - - JPADrift drift1 = new JPADrift(changeSet0, "drift.1", FILE_ADDED, null, driftFile1); - JPADrift drift2 = new JPADrift(changeSet0, "drift.2", FILE_ADDED, null, driftFile2); - - final JPADriftSet driftSet = new JPADriftSet(); - driftSet.addDrift(drift1); - driftSet.addDrift(drift2); - - // create the template - final DriftDefinition templateDef = new DriftDefinition(new Configuration()); - templateDef.setName("test_createUnpinnedDefinition"); - templateDef.setEnabled(true); - templateDef.setDriftHandlingMode(normal); - templateDef.setInterval(2400L); - templateDef.setBasedir(new DriftDefinition.BaseDirectory(fileSystem, "/foo/bar/test")); - templateDef.setPinned(true); - - final DriftDefinitionTemplate template = templateMgr.createTemplate(getOverlord(), resourceType.getId(), true, - templateDef); - - executeInTransaction(new TransactionCallback() { - @Override - public void execute() throws Exception { - EntityManager em = getEntityManager(); - - em.persist(driftFile1); - em.persist(driftFile2); - em.persist(changeSet0); - em.persist(driftSet); - changeSet0.setInitialDriftSet(driftSet); - em.merge(changeSet0); - - // setting the change set id on the template is the last and the - // most important step in making the template pinned - template.setChangeSetId(changeSet0.getId()); - em.merge(template); - } - }); - - // Create and persist a resource-level definition. - final DriftDefinition definition = template.createDefinition(); - definition.setTemplate(template); - - final AtomicBoolean agentInvoked = new AtomicBoolean(false); - - agentServiceContainer.driftService = new TestDefService() { - @Override - public void updateDriftDetection(int resourceId, DriftDefinition driftDef, DriftSnapshot snapshot) { - try { - HibernateDetachUtility.nullOutUninitializedFields(driftDef, - HibernateDetachUtility.SerializationType.SERIALIZATION); - HibernateDetachUtility.nullOutUninitializedFields(snapshot, - HibernateDetachUtility.SerializationType.SERIALIZATION); - agentInvoked.set(true); - assertNotNull("Expected snapshot drift instances collection to be non-null", - snapshot.getDriftInstances()); - assertEquals("Expected snapshot to contain two drift entries", 2, snapshot.getDriftInstances().size()); - } catch (Exception e) { - String msg = "Do not pass attached entites to agent since those entities are outside of " + - "Hibernate's control. The persistence context should be flushed and cleared to ensure that " + - "only detached objects are sent to the agent"; - throw new RuntimeException(msg, e); - } - } - }; - - driftMgr.updateDriftDefinition(getOverlord(), EntityContext.forResource(resource.getId()), definition); - - DriftDefinition newDef = loadDefinition(definition.getName()); - - // verify that the definition is marked as pinned - assertTrue("The drift definition should be marked as pinned", newDef.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"); - - // lastly verify that the agent is called - assertTrue("Failed to send drift definition along with snapshot to agent", agentInvoked.get()); - } - - public void unpinDefinition() { - // First create the template - final DriftDefinition templateDef = new DriftDefinition(new Configuration()); - templateDef.setName("test_unpin_def_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); - - // First create the definition - DriftDefinition definition = template.createDefinition(); - definition.setName("test_unpin"); - definition.setEnabled(true); - definition.setBasedir(new DriftDefinition.BaseDirectory(fileSystem, "/foo/bar/test")); - definition.setComplianceStatus(DriftComplianceStatus.OUT_OF_COMPLIANCE_DRIFT); - definition.setInterval(1800L); - definition.setDriftHandlingMode(normal); - definition.setPinned(true); - - // persist the definition - driftMgr.updateDriftDefinition(getOverlord(), EntityContext.forResource(resource.getId()), definition); - - // now update the definition - DriftDefinition newDef = loadDefinition(definition.getName()); - assertNotNull("Failed to load new definition, " + toString(definition)); - newDef.setPinned(false); - - driftMgr.updateDriftDefinition(getOverlord(), EntityContext.forResource(resource.getId()), newDef); - - // now verify that the definition was updated - DriftDefinition updatedDef = loadDefinition(definition.getName()); - assertNotNull("Failed to load updated definition, " + toString(newDef)); - - assertFalse("The updated definition should be set to unpinned", updatedDef.isPinned()); - assertEquals("The updated definition should be set to in compliance", DriftComplianceStatus.IN_COMPLIANCE, - updatedDef.getComplianceStatus()); - } - - private DriftDefinition loadDefinition(String name) { - DriftDefinitionCriteria criteria = new DriftDefinitionCriteria(); - criteria.addFilterResourceIds(resource.getId()); - criteria.addFilterName(name); - criteria.fetchConfiguration(true); - criteria.fetchResource(true); - criteria.fetchTemplate(true); - - PageList<DriftDefinition> driftDefs = driftMgr.findDriftDefinitionsByCriteria(getOverlord(), criteria); - assertEquals("Expected to find one drift definition", 1, driftDefs.size()); - - return driftDefs.get(0); - } - -} diff --git a/modules/enterprise/server/itests/src/test/java/org/rhq/enterprise/server/drift/ManageSnapshotsTest.java b/modules/enterprise/server/itests/src/test/java/org/rhq/enterprise/server/drift/ManageSnapshotsTest.java deleted file mode 100644 index a214621..0000000 --- a/modules/enterprise/server/itests/src/test/java/org/rhq/enterprise/server/drift/ManageSnapshotsTest.java +++ /dev/null @@ -1,276 +0,0 @@ -/* - * 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.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.enterprise.server.util.LookupUtil.getDriftManager; -import static org.rhq.enterprise.server.util.LookupUtil.getDriftTemplateManager; -import static org.rhq.test.AssertUtils.assertPropertiesMatch; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.ObjectOutputStream; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.atomic.AtomicBoolean; - -import javax.persistence.EntityManager; - -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; - -import org.rhq.core.domain.configuration.Configuration; -import org.rhq.core.domain.criteria.GenericDriftChangeSetCriteria; -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.DriftDefinitionTemplate; -import org.rhq.core.domain.drift.DriftSnapshot; -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.server.EntitySerializer; -import org.rhq.core.domain.util.PageList; -import org.rhq.test.AssertUtils; -import org.rhq.enterprise.server.test.TransactionCallback; - -@Test(dependsOnGroups = "pinning") -public class ManageSnapshotsTest extends AbstractDriftServerTest { - - private DriftManagerLocal driftMgr; - - private DriftTemplateManagerLocal templateMgr; - - @BeforeClass - public void initClass() throws Exception { - driftMgr = getDriftManager(); - templateMgr = getDriftTemplateManager(); - } - - public void pinningSnapshotShouldSetDriftDefAsPinned() { - final DriftDefinition driftDef = createAndPersistDriftDef("test::setPinnedFlag"); - - // create initial change set - final JPADriftChangeSet changeSet = new JPADriftChangeSet(resource, 0, COVERAGE, driftDef); - - final JPADriftFile driftFile1 = new JPADriftFile("a1b2c3"); - JPADrift drift = new JPADrift(changeSet, "drift.1", FILE_ADDED, null, driftFile1); - - final JPADriftSet driftSet = new JPADriftSet(); - driftSet.addDrift(drift); - - executeInTransaction(new TransactionCallback() { - @Override - public void execute() throws Exception { - EntityManager em = getEntityManager(); - em.persist(driftFile1); - em.persist(changeSet); - em.persist(driftSet); - changeSet.setInitialDriftSet(driftSet); - em.merge(changeSet); - } - }); - - driftMgr.pinSnapshot(getOverlord(), driftDef.getId(), 0); - DriftDefinition updatedDriftDef = driftMgr.getDriftDefinition(getOverlord(), driftDef.getId()); - - assertNotNull("Failed to get " + toString(driftDef), updatedDriftDef); - assertTrue("Failed to set pinned flag of " + toString(driftDef), updatedDriftDef.isPinned()); - } - - @SuppressWarnings("unchecked") - public void pinningSnapshotShouldMakeSnapshotTheInitialChangeSet() throws Exception { - final DriftDefinition driftDef = createAndPersistDriftDef("test::makeSnapshotVersionZero"); - - // create initial change set - final JPADriftChangeSet changeSet0 = new JPADriftChangeSet(resource, 0, COVERAGE, driftDef); - - final JPADriftFile driftFile1 = new JPADriftFile("a1b2c3"); - JPADrift drift1 = new JPADrift(changeSet0, "drift.1", FILE_ADDED, null, driftFile1); - - final JPADriftSet driftSet = new JPADriftSet(); - driftSet.addDrift(drift1); - - // create change set v1 - final JPADriftFile driftFile2 = new JPADriftFile("1a2b3c"); - final JPADriftChangeSet changeSet1 = new JPADriftChangeSet(resource, 1, DRIFT, driftDef); - final JPADrift drift2 = new JPADrift(changeSet1, "drift.2", FILE_ADDED, null, driftFile2); - - executeInTransaction(new TransactionCallback() { - @Override - public void execute() throws Exception { - EntityManager em = getEntityManager(); - em.persist(driftFile1); - em.persist(driftFile2); - em.persist(changeSet0); - em.persist(driftSet); - changeSet0.setInitialDriftSet(driftSet); - em.merge(changeSet0); - em.persist(changeSet1); - em.persist(drift2); - } - }); - - driftMgr.pinSnapshot(getOverlord(), driftDef.getId(), 1); - - // Verify that there is now only one change set for the drift def - GenericDriftChangeSetCriteria criteria = new GenericDriftChangeSetCriteria(); - criteria.addFilterDriftDefinitionId(driftDef.getId()); - - PageList<? extends DriftChangeSet<?>> changeSets = driftMgr.findDriftChangeSetsByCriteria(getOverlord(), - criteria); - assertEquals("All change sets except the change set representing the pinned snapshot should be removed", - 1, changeSets.size()); - DriftChangeSet<?> changeSet = changeSets.get(0); - - assertEquals("The pinned snapshot version should be reset to zero", 0, changeSet.getVersion()); - assertEquals("The change set category is wrong", COVERAGE, changeSet.getCategory()); - - JPADriftChangeSet expectedChangeSet = new JPADriftChangeSet(resource, 1, COVERAGE, driftDef); - List<? extends Drift> expectedDrifts = asList( - new JPADrift(expectedChangeSet, drift1.getPath(), FILE_ADDED, null, driftFile1), - new JPADrift(expectedChangeSet, drift2.getPath(), FILE_ADDED, null, driftFile2)); - - List<? extends Drift> actualDrifts = new ArrayList(changeSet.getDrifts()); - - AssertUtils.assertCollectionMatchesNoOrder( - "Expected to find drifts from change sets 1 and 2 in the new initial 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, "drift.1").getNewDriftFile(), - "The newDriftFile property was not set correctly for " + drift1); - assertPropertiesMatch(drift2.getNewDriftFile(), findDriftByPath(actualDrifts, "drift.2").getNewDriftFile(), - "The newDriftFile property was not set correctly for " + drift1); - } - - public void pinningSnapshotShouldSendRequestToAgent() { - final DriftDefinition driftDef = createAndPersistDriftDef("test::setPinnedFlag"); - - // create initial change set - final JPADriftChangeSet changeSet = new JPADriftChangeSet(resource, 0, COVERAGE, driftDef); - - final JPADriftFile driftFile1 = new JPADriftFile("a1b2c3"); - JPADrift drift = new JPADrift(changeSet, "drift.1", FILE_ADDED, null, driftFile1); - - final JPADriftSet driftSet = new JPADriftSet(); - driftSet.addDrift(drift); - - executeInTransaction(new TransactionCallback() { - @Override - public void execute() throws Exception { - EntityManager em = getEntityManager(); - em.persist(driftFile1); - em.persist(changeSet); - em.persist(driftSet); - changeSet.setInitialDriftSet(driftSet); - em.merge(changeSet); - } - }); - - final AtomicBoolean agentInvoked = new AtomicBoolean(false); - agentServiceContainer.driftService = new TestDefService() { - @Override - public void pinSnapshot(int resourceId, String configName, DriftSnapshot snapshot) { - try { - agentInvoked.set(true); - // serialize the method arguments here to more closely simulate what - // happens during the call. We cannot send hibernate-proxied objects - // to the agent. This is an attempt to catch that. - ObjectOutputStream stream = new ObjectOutputStream(new ByteArrayOutputStream()); - EntitySerializer.writeExternalRemote(resourceId, stream); - EntitySerializer.writeExternalRemote(configName, stream); - EntitySerializer.writeExternalRemote(snapshot, stream); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - }; - - driftMgr.pinSnapshot(getOverlord(), driftDef.getId(), 0); - - assertTrue("Failed to send request to agent to pin snapshot", agentInvoked.get()); - } - - @Test(expectedExceptions = IllegalArgumentException.class, - expectedExceptionsMessageRegExp = "Cannot repin.*definition.*") - public void doNotAllowSnapshotToBePinnedWhenDefinitionIsAttachedToPinnedTemplate() { - // First create the template - final DriftDefinition templateDef = new DriftDefinition(new Configuration()); - templateDef.setName("Template-Pinned_Test"); - 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); - - // Now we will pin the template. We are going to take a bit of a short cut - // here. Pinning a template requires a drift definition with at least one - // snapshot. For the purposes of this test we can simply set the - // changeSetId field of the template to indicate that it is pinned. - template.setChangeSetId("1234"); - - // Next create a resource-level definition from the template. - final DriftDefinition driftDef = template.createDefinition(); - driftDef.setResource(resource); - - executeInTransaction(new TransactionCallback() { - @Override - public void execute() throws Exception { - EntityManager em = getEntityManager(); - em.merge(template); - em.persist(driftDef); - } - }); - - // Now try resource-level pinning, i.e., pin a snapshot to the definition - driftMgr.pinSnapshot(getOverlord(), driftDef.getId(), 0); - } - - private DriftDefinition createAndPersistDriftDef(String name) { - final DriftDefinition driftDef = new DriftDefinition(new Configuration()); - driftDef.setName(name); - driftDef.setEnabled(true); - driftDef.setDriftHandlingMode(normal); - driftDef.setInterval(1800L); - driftDef.setBasedir(new DriftDefinition.BaseDirectory(fileSystem, "/foo/bar/test")); - - executeInTransaction(new TransactionCallback() { - @Override - public void execute() throws Exception { - driftDef.setResource(resource); - getEntityManager().persist(driftDef); - } - }); - - return driftDef; - } - -}
commit 1aa4c1f65dfd021b902060e64b82f0ba291691dd Author: Jay Shaughnessy jshaughn@jshaughn.csb Date: Fri Nov 2 14:08:21 2012 -0400
Protect toString() impls from detached entities
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/drift/DriftDefinition.java b/modules/core/domain/src/main/java/org/rhq/core/domain/drift/DriftDefinition.java index f714d9e..a9b0ad3 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/drift/DriftDefinition.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/drift/DriftDefinition.java @@ -284,10 +284,16 @@ public class DriftDefinition implements Serializable { @Override public String toString() { StringBuilder builder = new StringBuilder(); - builder.append("DriftDefinition [id=").append(id).append(", name=").append(name).append(", enabled=").append( - isEnabled).append(", interval=").append(interval).append(", resource=").append(resource).append( - ", basedir=").append(getBasedir()).append(", includes=").append(getIncludes()).append(", excludes=") - .append(getExcludes()).append("]"); + builder.append("DriftDefinition [id=").append(id).append(", name=").append(name).append(", enabled=") + .append(isEnabled).append(", interval=").append(interval).append(", resource=").append(resource); + try { + builder.append(", basedir=").append(getBasedir()).append(", includes=").append(getIncludes()) + .append(", excludes=").append(getExcludes()); + } catch (Exception e) { + // ignore, not attached + } + builder.append("]"); + return builder.toString(); }
@@ -425,8 +431,8 @@ public class DriftDefinition implements Serializable { }
private Long getIntervalProperty() { - return Long.parseLong(configuration.getSimpleValue(DriftConfigurationDefinition.PROP_INTERVAL, String - .valueOf(DriftConfigurationDefinition.DEFAULT_INTERVAL))); + return Long.parseLong(configuration.getSimpleValue(DriftConfigurationDefinition.PROP_INTERVAL, + String.valueOf(DriftConfigurationDefinition.DEFAULT_INTERVAL))); }
private void setIntervalProperty(Long interval) { diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/drift/JPADrift.java b/modules/core/domain/src/main/java/org/rhq/core/domain/drift/JPADrift.java index 5bde9e0..c3d6bb3 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/drift/JPADrift.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/drift/JPADrift.java @@ -198,7 +198,15 @@ public class JPADrift implements Serializable, Drift<JPADriftChangeSet, JPADrift
@Override public String toString() { - return "JPADrift [ id=" + id + ", category=" + category + ", path=" + path + ", changeSet=" + changeSet + "]"; + StringBuilder sb = new StringBuilder("JPADrift ["); + sb.append("id=" + id).append(", category=" + category).append(", path=" + path); + try { + sb.append(", changeSet=" + changeSet); + } catch (Exception e) { + // not attached + } + sb.append("]"); + return sb.toString(); }
}
rhq-commits@lists.fedorahosted.org