/* * RHQ Management Platform * Copyright (C) 2005-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.sync.test; import static org.testng.Assert.assertNull; import static org.testng.Assert.assertSame; import static org.testng.Assert.assertEquals; import java.util.Arrays; import java.util.Collections; import java.util.List; import javax.persistence.EntityManager; import javax.persistence.Query; import org.hamcrest.Description; import org.jmock.Expectations; import org.jmock.Mockery; import org.jmock.api.Action; import org.jmock.api.Invocation; import org.testng.annotations.Test; import org.rhq.core.domain.auth.Subject; import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.configuration.PropertyList; import org.rhq.core.domain.configuration.PropertyMap; import org.rhq.core.domain.configuration.PropertySimple; import org.rhq.core.domain.measurement.MeasurementDefinition; import org.rhq.core.domain.measurement.NumericType; import org.rhq.core.domain.resource.ResourceCategory; import org.rhq.core.domain.resource.ResourceType; import org.rhq.core.domain.sync.entity.MetricTemplate; import org.rhq.enterprise.server.measurement.MeasurementScheduleManagerLocal; import org.rhq.enterprise.server.sync.importers.ExportedEntityMatcher; import org.rhq.enterprise.server.sync.importers.MetricTemplateImporter; import org.rhq.test.JMockTest; /** * @author Lukas Krejci */ @Test public class MetricTemplateImporterTest extends JMockTest { private static class TestPrerequisities { private EntityManager em; private Query q; private MeasurementScheduleManagerLocal msm; private List<MeasurementDefinition> defs; public TestPrerequisities(Mockery context) { em = context.mock(EntityManager.class); msm = context.mock(MeasurementScheduleManagerLocal.class); q = context.mock(Query.class); } public Query getQuery() { return q; } public EntityManager getEntityManager() { return em; } public MeasurementScheduleManagerLocal getMeasurementScheduleManager() { return msm; } public void setMeasurementDefinitions(List<MeasurementDefinition> defs) { this.defs = defs; } @SuppressWarnings("static-access") public void addExpectations(Expectations expectations) { expectations.allowing(em).createQuery(expectations.with(expectations.any(String.class))); expectations.will(Expectations.returnValue(q)); expectations.allowing(q).getResultList(); expectations.will(Expectations.returnValue(defs)); } }; private static final ResourceType FAKE_RESOURCE_TYPE = new ResourceType("fake", "fake", ResourceCategory.PLATFORM, null); public void testNonMatchingMeasurementDefinitionsAreIgnored() { final TestPrerequisities prereqs = new TestPrerequisities(context); //some data to supply MeasurementDefinition def = new MeasurementDefinition(FAKE_RESOURCE_TYPE, "fake"); def.setId(1); def.setDefaultOn(true); def.setDefaultInterval(1000); //now we setup the prerequisites to return the faked results from the database //for the non-matching template, we want the "database" to return no results //while for the matching template, we want the "database" to return our own def. prereqs.setMeasurementDefinitions(Collections.singletonList(def)); //setup the expected behavior context.checking(new Expectations() { { prereqs.addExpectations(this); MeasurementScheduleManagerLocal msm = prereqs.getMeasurementScheduleManager(); //this is what we expect the measurement schedule manager msm to be //called with when the importer finishes its work. one(msm).updateDefaultCollectionIntervalAndEnablementForMeasurementDefinitions(with(any(Subject.class)), with(new int[] { 1 }), with(1000L), with(true), with(false)); } }); MetricTemplateImporter importer = new MetricTemplateImporter(null, prereqs.getEntityManager(), prereqs.getMeasurementScheduleManager()); MetricTemplate nonMatching = new MetricTemplate(); nonMatching.setResourceTypeName("asf"); nonMatching.setResourceTypePlugin("asfd"); nonMatching.setMetricName("asf"); MetricTemplate matching = new MetricTemplate(def); importer.configure(null); ExportedEntityMatcher<MeasurementDefinition, MetricTemplate> matcher = importer.getExportedEntityMatcher(); assertNull(matcher.findMatch(nonMatching), "The non-matching metric template shouldn't have been matched."); assertSame(matcher.findMatch(matching), def, "The matching metric template should have found the defined measurement definition"); //this is the "meat" of the test.. //we call update() twice but only get 1 actual change pour down to database //and the importer not choking on this. importer.update(null, nonMatching); importer.update(def, matching); //this should invoke the mocked measurement schedule manager and the expectations should check it gets called //correctly by the importer. importer.finishImport(); } public void testCanUpdateEnablements() { MeasurementDefinition defToEnable = new MeasurementDefinition(FAKE_RESOURCE_TYPE, "enabled"); MeasurementDefinition defToDisable = new MeasurementDefinition(FAKE_RESOURCE_TYPE, "disable"); defToEnable.setId(1); defToEnable.setDefaultOn(true); defToEnable.setDefaultInterval(1000); defToDisable.setId(2); defToDisable.setDefaultOn(false); defToDisable.setDefaultInterval(2000); final TestPrerequisities prereqs = new TestPrerequisities(context); prereqs.setMeasurementDefinitions(Arrays.asList(defToEnable, defToDisable)); context.checking(new Expectations() { { prereqs.addExpectations(this); MeasurementScheduleManagerLocal msm = prereqs.getMeasurementScheduleManager(); //this is what we expect the measurement schedule manager msm to be //called with when the importer finishes its work. one(msm).updateDefaultCollectionIntervalAndEnablementForMeasurementDefinitions(with(any(Subject.class)), with(new int[] { 1 }), with(1000L), with(true), with(false)); one(msm).updateDefaultCollectionIntervalAndEnablementForMeasurementDefinitions(with(any(Subject.class)), with(new int[] { 2 }), with(2000L), with(false), with(false)); } }); MetricTemplateImporter importer = new MetricTemplateImporter(null, prereqs.getEntityManager(), prereqs.getMeasurementScheduleManager()); importer.configure(null); ExportedEntityMatcher<MeasurementDefinition, MetricTemplate> matcher = importer.getExportedEntityMatcher(); MetricTemplate match1 = new MetricTemplate(defToEnable); MetricTemplate match2 = new MetricTemplate(defToDisable); assertSame(matcher.findMatch(match1), defToEnable, "The matching metric template should have found the defined measurement definition"); assertSame(matcher.findMatch(match2), defToDisable, "The matching metric template should have found the defined measurement definition"); importer.update(defToEnable, match1); importer.update(defToDisable, match2); //this should invoke the mocked measurement schedule manager and the expectations should check it gets called //correctly by the importer. importer.finishImport(); } public void testCanUpdateSchedules() { MeasurementDefinition def = new MeasurementDefinition(FAKE_RESOURCE_TYPE, "def"); def.setId(1); def.setDefaultOn(true); def.setDefaultInterval(1000); final TestPrerequisities prereqs = new TestPrerequisities(context); prereqs.setMeasurementDefinitions(Collections.singletonList(def)); context.checking(new Expectations() { { prereqs.addExpectations(this); MeasurementScheduleManagerLocal msm = prereqs.getMeasurementScheduleManager(); one(msm).updateDefaultCollectionIntervalAndEnablementForMeasurementDefinitions(with(any(Subject.class)), with(new int[] { 1 }), with(1000L), with(true), with(true)); } }); MetricTemplateImporter importer = new MetricTemplateImporter(null, prereqs.getEntityManager(), prereqs.getMeasurementScheduleManager()); Configuration importConfig = new Configuration(); importConfig.put(new PropertySimple(MetricTemplateImporter.UPDATE_ALL_SCHEDULES_PROPERTY, true)); importer.configure(importConfig); ExportedEntityMatcher<MeasurementDefinition, MetricTemplate> matcher = importer.getExportedEntityMatcher(); MetricTemplate template = new MetricTemplate(def); assertSame(matcher.findMatch(template), def, "The matching metric template should have found the defined measurement definition"); importer.update(def, template); //this should invoke the mocked measurement schedule manager and the expectations should check it gets called //correctly by the importer. importer.finishImport(); } public void testPerMetricUpdateScheduleOverrides() { MeasurementDefinition updatedDef = new MeasurementDefinition(FAKE_RESOURCE_TYPE, "def"); updatedDef.setId(1); updatedDef.setDefaultOn(true); updatedDef.setDefaultInterval(1000); MeasurementDefinition notUpdatedDef = new MeasurementDefinition(FAKE_RESOURCE_TYPE, "ndef"); notUpdatedDef.setId(2); notUpdatedDef.setDefaultOn(true); notUpdatedDef.setDefaultInterval(2000); final TestPrerequisities prereqs = new TestPrerequisities(context); prereqs.setMeasurementDefinitions(Arrays.asList(updatedDef, notUpdatedDef)); context.checking(new Expectations() { { prereqs.addExpectations(this); MeasurementScheduleManagerLocal msm = prereqs.getMeasurementScheduleManager(); one(msm).updateDefaultCollectionIntervalAndEnablementForMeasurementDefinitions(with(any(Subject.class)), with(new int[] { 1 }), with(1000L), with(true), with(true)); one(msm).updateDefaultCollectionIntervalAndEnablementForMeasurementDefinitions(with(any(Subject.class)), with(new int[] { 2 }), with(2000L), with(true), with(false)); } }); MetricTemplateImporter importer = new MetricTemplateImporter(null, prereqs.getEntityManager(), prereqs.getMeasurementScheduleManager()); Configuration importConfig = new Configuration(); //this is the default, but let's be specific here so that this doesn't start failing if we change the //default in the future. importConfig.put(new PropertySimple(MetricTemplateImporter.UPDATE_ALL_SCHEDULES_PROPERTY, false)); //set the def to update the schedules anyway PropertyList list = new PropertyList(MetricTemplateImporter.METRIC_UPDATE_OVERRIDES_PROPERTY); importConfig.put(list); PropertyMap map = new PropertyMap(MetricTemplateImporter.METRIC_UPDATE_OVERRIDE_PROPERTY); list.add(map); map.put(new PropertySimple(MetricTemplateImporter.METRIC_NAME_PROPERTY, "def")); map.put(new PropertySimple(MetricTemplateImporter.RESOURCE_TYPE_NAME_PROPERTY, FAKE_RESOURCE_TYPE.getName())); map.put(new PropertySimple(MetricTemplateImporter.RESOURCE_TYPE_PLUGIN_PROPERTY, FAKE_RESOURCE_TYPE.getPlugin())); map.put(new PropertySimple(MetricTemplateImporter.UPDATE_SCHEDULES_PROPERTY, true)); importer.configure(importConfig); ExportedEntityMatcher<MeasurementDefinition, MetricTemplate> matcher = importer.getExportedEntityMatcher(); MetricTemplate template1 = new MetricTemplate(updatedDef); MetricTemplate template2 = new MetricTemplate(notUpdatedDef); assertSame(matcher.findMatch(template1), updatedDef, "The matching metric template should have found the defined measurement definition"); assertSame(matcher.findMatch(template2), notUpdatedDef, "The matching metric template should have found the defined measurement definition"); importer.update(updatedDef, template1); importer.update(notUpdatedDef, template2); //this should invoke the mocked measurement schedule manager and the expectations should check it gets called //correctly by the importer. importer.finishImport(); } public void testNullConfigurationInterpretedAsDefault() { //this doesn't need to be implemented as long as at least one of the other //test methods passes null to the importer.configure() and succeeds. testNonMatchingMeasurementDefinitionsAreIgnored(); } public void testDistinguishingBetweenNormalAndPerMinuteTemplates() { MeasurementDefinition normalDef = new MeasurementDefinition(FAKE_RESOURCE_TYPE, "def"); MeasurementDefinition perMinuteDef = new MeasurementDefinition(FAKE_RESOURCE_TYPE, "def"); normalDef.setId(1); normalDef.setDefaultOn(true); normalDef.setDefaultInterval(1000); perMinuteDef.setId(2); perMinuteDef.setDefaultOn(false); perMinuteDef.setDefaultInterval(2000); perMinuteDef.setRawNumericType(NumericType.TRENDSUP); final TestPrerequisities prereqs = new TestPrerequisities(context); prereqs.setMeasurementDefinitions(Arrays.asList(normalDef, perMinuteDef)); context.checking(new Expectations() { { prereqs.addExpectations(this); MeasurementScheduleManagerLocal msm = prereqs.getMeasurementScheduleManager(); one(msm).updateDefaultCollectionIntervalAndEnablementForMeasurementDefinitions(with(any(Subject.class)), with(new int[] { 1 }), with(1000L), with(true), with(false)); one(msm).updateDefaultCollectionIntervalAndEnablementForMeasurementDefinitions(with(any(Subject.class)), with(new int[] { 2 }), with(2000L), with(false), with(false)); } }); MetricTemplateImporter importer = new MetricTemplateImporter(null, prereqs.getEntityManager(), prereqs.getMeasurementScheduleManager()); importer.configure(null); ExportedEntityMatcher<MeasurementDefinition, MetricTemplate> matcher = importer.getExportedEntityMatcher(); MetricTemplate template1 = new MetricTemplate(normalDef); MetricTemplate template2 = new MetricTemplate(perMinuteDef); assertSame(matcher.findMatch(template1), normalDef, "The matching metric template should have found the defined measurement definition"); assertSame(matcher.findMatch(template2), perMinuteDef, "The matching metric template should have found the defined measurement definition"); importer.update(normalDef, template1); importer.update(perMinuteDef, template2); //this should invoke the mocked measurement schedule manager and the expectations should check it gets called //correctly by the importer. importer.finishImport(); } public void testNotifiesAboutIgnoredMetricTemplates() throws Exception { final TestPrerequisities prereqs = new TestPrerequisities(context); prereqs.setMeasurementDefinitions(Collections.<MeasurementDefinition>emptyList()); context.checking(new Expectations() { { prereqs.addExpectations(this); } }); MetricTemplateImporter importer = new MetricTemplateImporter(null, prereqs.getEntityManager(), prereqs.getMeasurementScheduleManager()); importer.configure(null); importer.configure(null); MetricTemplate unmatched = new MetricTemplate(); unmatched.setMetricName("made-up"); unmatched.setResourceTypeName("made-up"); unmatched.setResourceTypePlugin("made-up"); ExportedEntityMatcher<MeasurementDefinition, MetricTemplate> matcher = importer.getExportedEntityMatcher(); assertNull(matcher.findMatch(unmatched)); importer.update(null, unmatched); String notes = importer.finishImport(); String expectedNotes = MetricTemplateImporter.getUnmatchedMetricTemplatesReport(Collections.singleton(unmatched)); assertEquals(notes, expectedNotes); } }