/* * 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.measurement.test; import java.util.ArrayList; import java.util.List; import java.util.Random; import java.util.Set; import javax.persistence.Query; import junit.framework.Assert; import org.testng.annotations.Test; import org.rhq.core.domain.auth.Subject; import org.rhq.core.domain.measurement.DataType; import org.rhq.core.domain.measurement.DisplayType; import org.rhq.core.domain.measurement.MeasurementCategory; import org.rhq.core.domain.measurement.MeasurementDefinition; import org.rhq.core.domain.measurement.MeasurementSchedule; import org.rhq.core.domain.measurement.MeasurementScheduleRequest; import org.rhq.core.domain.measurement.MeasurementUnits; import org.rhq.core.domain.measurement.ResourceMeasurementScheduleRequest; import org.rhq.core.domain.measurement.calltime.CallTimeDataKey; 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.ResourceCategory; import org.rhq.core.domain.resource.ResourceType; import org.rhq.enterprise.server.measurement.MeasurementConstants; import org.rhq.enterprise.server.measurement.MeasurementScheduleManagerLocal; import org.rhq.enterprise.server.util.LookupUtil; import org.rhq.enterprise.server.util.ResourceTreeHelper; /** * Test some measurement schedule handling * * @author Jay Shaughnessy */ public class MeasurementScheduleManagerTest extends AbstractMeasurementScheduleManagerTest { private MeasurementScheduleManagerLocal measurementScheduleManager; private Subject overlord; private Resource resource1; private MeasurementDefinition definitionCt1; private ResourceType theResourceType; private Agent theAgent; private MeasurementScheduleTestServerCommunicationsService testCommService; @Override protected void beforeMethod() { try { prepareScheduler(); testCommService = (MeasurementScheduleTestServerCommunicationsService) prepareForTestAgents(); this.measurementScheduleManager = LookupUtil.getMeasurementScheduleManager(); this.overlord = LookupUtil.getSubjectManager().getOverlord(); } catch (Throwable t) { // Catch RuntimeExceptions and Errors and dump their stack trace, because Surefire will completely swallow them // and throw a cryptic NPE (see http://jira.codehaus.org/browse/SUREFIRE-157)! t.printStackTrace(); throw new RuntimeException(t); } } @Override protected void afterMethod() { try { // delete values beginTx(); // delete keys List<Integer> resourceIds = new ArrayList<Integer>(); resourceIds.add(resource1.getId()); Query q = em.createNamedQuery(CallTimeDataKey.QUERY_DELETE_BY_RESOURCES); q.setParameter("resourceIds", resourceIds); q.executeUpdate(); resource1 = em.merge(resource1); for (MeasurementSchedule sched : resource1.getSchedules()) { em.remove(sched); } ResourceTreeHelper.deleteResource(em, resource1); definitionCt1 = em.merge(definitionCt1); em.remove(definitionCt1); theResourceType = em.merge(theResourceType); em.remove(theResourceType); theAgent = em.merge(theAgent); em.remove(theAgent); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(e); } finally { try { unprepareScheduler(); unprepareForTestAgents(); } catch (Exception e) { } commitAndClose(); } } @Test public void testIntervals() { try { beginTx(); setupResources(); MeasurementSchedule schedule1 = new MeasurementSchedule(definitionCt1, resource1); em.persist(schedule1); definitionCt1.addSchedule(schedule1); resource1.addSchedule(schedule1); resource1 = em.merge(resource1); commitAndClose(); // 60s is valid schedule1.setInterval(60000L); measurementScheduleManager.updateSchedule(overlord, schedule1); schedule1 = measurementScheduleManager.getScheduleById(overlord, schedule1.getId()); Assert.assertEquals(60000L, schedule1.getInterval()); // 10s is invalid and should be assigned 30s schedule1.setInterval(10000L); measurementScheduleManager.updateSchedule(overlord, schedule1); schedule1 = measurementScheduleManager.getScheduleById(overlord, schedule1.getId()); Assert.assertEquals(MeasurementConstants.MINIMUM_COLLECTION_INTERVAL_MILLIS, schedule1.getInterval()); // 0s is invalid and should be assigned 30s schedule1.setInterval(0L); measurementScheduleManager.updateSchedule(overlord, schedule1); schedule1 = measurementScheduleManager.getScheduleById(overlord, schedule1.getId()); Assert.assertEquals(MeasurementConstants.MINIMUM_COLLECTION_INTERVAL_MILLIS, schedule1.getInterval()); // negative intervals are invalid and should be assigned 30s schedule1.setInterval(-60000L); measurementScheduleManager.updateSchedule(overlord, schedule1); schedule1 = measurementScheduleManager.getScheduleById(overlord, schedule1.getId()); Assert.assertEquals(MeasurementConstants.MINIMUM_COLLECTION_INTERVAL_MILLIS, schedule1.getInterval()); // Try a different mechanism // 60s is valid measurementScheduleManager.updateSchedulesForResource(overlord, resource1.getId(), new int[] { definitionCt1.getId() }, 60000L); Set<ResourceMeasurementScheduleRequest> resScheds = measurementScheduleManager .findSchedulesForResourceAndItsDescendants(new int[] { resource1.getId() }, false); Assert.assertEquals(1, resScheds.size()); Set<MeasurementScheduleRequest> scheds = resScheds.iterator().next().getMeasurementSchedules(); Assert.assertEquals(1, scheds.size()); Assert.assertEquals(60000L, scheds.iterator().next().getInterval()); // 10s is invalid and should be assigned 30s measurementScheduleManager.updateSchedulesForResource(overlord, resource1.getId(), new int[] { definitionCt1.getId() }, 10000L); resScheds = measurementScheduleManager.findSchedulesForResourceAndItsDescendants( new int[] { resource1.getId() }, false); Assert.assertEquals(1, resScheds.size()); scheds = resScheds.iterator().next().getMeasurementSchedules(); Assert.assertEquals(1, scheds.size()); Assert.assertEquals(MeasurementConstants.MINIMUM_COLLECTION_INTERVAL_MILLIS, scheds.iterator().next() .getInterval()); // 0s is invalid and should be assigned 30s measurementScheduleManager.updateSchedulesForResource(overlord, resource1.getId(), new int[] { definitionCt1.getId() }, 0L); resScheds = measurementScheduleManager.findSchedulesForResourceAndItsDescendants( new int[] { resource1.getId() }, false); Assert.assertEquals(1, resScheds.size()); scheds = resScheds.iterator().next().getMeasurementSchedules(); Assert.assertEquals(1, scheds.size()); Assert.assertEquals(MeasurementConstants.MINIMUM_COLLECTION_INTERVAL_MILLIS, scheds.iterator().next() .getInterval()); // negative intervals are invalid and should be assigned 30s measurementScheduleManager.updateSchedulesForResource(overlord, resource1.getId(), new int[] { definitionCt1.getId() }, -60000L); resScheds = measurementScheduleManager.findSchedulesForResourceAndItsDescendants( new int[] { resource1.getId() }, false); Assert.assertEquals(1, resScheds.size()); scheds = resScheds.iterator().next().getMeasurementSchedules(); Assert.assertEquals(1, scheds.size()); Assert.assertEquals(MeasurementConstants.MINIMUM_COLLECTION_INTERVAL_MILLIS, scheds.iterator().next() .getInterval()); } catch (Exception e) { e.printStackTrace(); Assert.fail(); } finally { commitAndClose(); } } @Test public void testBug811696() { try { beginTx(); setupResources(); long defaultInterval = definitionCt1.getDefaultInterval(); long updatedInterval = defaultInterval * 2; // first, establish a schedule for the test resource MeasurementSchedule schedule1 = new MeasurementSchedule(definitionCt1, resource1); schedule1.setInterval(defaultInterval); em.persist(schedule1); definitionCt1.addSchedule(schedule1); resource1.addSchedule(schedule1); resource1 = em.merge(resource1); commitAndClose(); // Test interval update of metrics at the template level testCommService.init(); testCommService.setExpectedInterval(updatedInterval); testCommService.setExpectedIsEnabled(true); measurementScheduleManager.updateSchedulesForResourceType(overlord, new int[] { definitionCt1.getId() }, updatedInterval, true); Assert.assertTrue(testCommService.isTested()); if (testCommService.hasFailures()) { Assert.fail(testCommService.getFailures().get(0)); } Set<ResourceMeasurementScheduleRequest> resScheds = measurementScheduleManager .findSchedulesForResourceAndItsDescendants(new int[] { resource1.getId() }, false); Assert.assertEquals(1, resScheds.size()); ResourceMeasurementScheduleRequest rmsr = resScheds.iterator().next(); Set<MeasurementScheduleRequest> scheds = rmsr.getMeasurementSchedules(); Assert.assertEquals(1, scheds.size()); MeasurementScheduleRequest msr = scheds.iterator().next(); Assert.assertEquals(updatedInterval, msr.getInterval()); Assert.assertEquals(true, msr.isEnabled()); // Test disable of metrics at the template level, this should have no effect on the interval in the client // or in the db testCommService.init(); testCommService.setExpectedInterval(updatedInterval); testCommService.setExpectedIsEnabled(false); measurementScheduleManager.disableSchedulesForResourceType(overlord, new int[] { definitionCt1.getId() }, true); Assert.assertTrue(testCommService.isTested()); resScheds = measurementScheduleManager.findSchedulesForResourceAndItsDescendants( new int[] { resource1.getId() }, false); Assert.assertEquals(1, resScheds.size()); rmsr = resScheds.iterator().next(); scheds = rmsr.getMeasurementSchedules(); Assert.assertEquals(1, scheds.size()); msr = scheds.iterator().next(); Assert.assertEquals(updatedInterval, msr.getInterval()); Assert.assertEquals(false, msr.isEnabled()); // Test enable of metrics at the template level, this should have no effect on the interval in the client // or in the db testCommService.init(); testCommService.setExpectedInterval(updatedInterval); testCommService.setExpectedIsEnabled(false); measurementScheduleManager.enableSchedulesForResourceType(overlord, new int[] { definitionCt1.getId() }, true); Assert.assertTrue(testCommService.isTested()); resScheds = measurementScheduleManager.findSchedulesForResourceAndItsDescendants( new int[] { resource1.getId() }, false); Assert.assertEquals(1, resScheds.size()); rmsr = resScheds.iterator().next(); scheds = rmsr.getMeasurementSchedules(); Assert.assertEquals(1, scheds.size()); msr = scheds.iterator().next(); Assert.assertEquals(updatedInterval, msr.getInterval()); Assert.assertEquals(true, msr.isEnabled()); } catch (Exception e) { Assert.fail(e.getMessage()); } finally { commitAndClose(); } } /** * Just set up two resources plus measurement definitions */ private void setupResources() { theAgent = new Agent("testagent", "localhost", 1234, "", "randomToken"); em.persist(theAgent); theResourceType = new ResourceType("test-plat", "test-plugin", ResourceCategory.PLATFORM, null); em.persist(theResourceType); definitionCt1 = new MeasurementDefinition("CT-Def1", MeasurementCategory.PERFORMANCE, MeasurementUnits.MILLISECONDS, DataType.MEASUREMENT, true, 120000L, DisplayType.SUMMARY); definitionCt1.setResourceType(theResourceType); em.persist(definitionCt1); resource1 = new Resource("test-platform-key1", "test-platform-name", theResourceType); resource1.setUuid("" + new Random().nextInt()); resource1.setAgent(theAgent); resource1.setInventoryStatus(InventoryStatus.COMMITTED); em.persist(resource1); } private void beginTx() throws Exception { getTransactionManager().begin(); } private void commitAndClose() { try { if (null != em) { em.flush(); } } catch (Throwable t) { // best effort } try { getTransactionManager().commit(); } catch (Throwable t) { // best effort } } }