diff --git a/src/org/hyperic/hq/hqapi1/test/AlertDefinitionTestBase.java b/src/org/hyperic/hq/hqapi1/test/AlertDefinitionTestBase.java index c0abe9f6..88580aab 100644 --- a/src/org/hyperic/hq/hqapi1/test/AlertDefinitionTestBase.java +++ b/src/org/hyperic/hq/hqapi1/test/AlertDefinitionTestBase.java @@ -94,17 +94,19 @@ protected List syncAlertDefinitions(List defin return response.getAlertDefinition(); } - protected AlertDefinition createProblemAlertDefinition(Resource resource, - Escalation e, - boolean isResourceType, - boolean willRecover) + protected AlertDefinition createAvailabilityAlertDefinition(Resource resource, + Escalation e, + boolean isResourceType, + boolean willRecover, + double availability) throws IOException { // Find availability metric for the passed in resource Metric availMetric = findAvailabilityMetric(resource); // Create alert definition - String name = "Test" + (isResourceType ? " Resource Type " : " ") + "Problem Alert"; + String name = "Test" + (isResourceType ? " Resource Type " : " ") + + "Availability=" + availability + " Alert"; AlertDefinition d = generateTestDefinition(name); d.setWillRecover(willRecover); if (isResourceType) { @@ -118,7 +120,8 @@ protected AlertDefinition createProblemAlertDefinition(Resource resource, AlertCondition threshold = AlertDefinitionBuilder.createThresholdCondition( true, availMetric.getName(), - AlertDefinitionBuilder.AlertComparator.EQUALS, 0); + AlertDefinitionBuilder.AlertComparator.EQUALS, + availability); d.getAlertCondition().add(threshold); AlertDefinition newDef = syncAlertDefinition(d); @@ -126,9 +129,9 @@ protected AlertDefinition createProblemAlertDefinition(Resource resource, validateTypeDefinition(newDef); } - validateProblemAlertDefinition(newDef, willRecover, true); + validateAvailabilityAlertDefinition(newDef, willRecover, true); - assertTrue("The problem alert definition should have " + assertTrue("The alert definition should have " + ((e == null) ? "no" : "an") + " escalation", (e == null) ? newDef.getEscalation() == null : newDef.getEscalation() != null); @@ -171,9 +174,9 @@ protected void validateTypeDefinition(AlertDefinition d) { d.getResourcePrototype() != null); } - protected void validateProblemAlertDefinition(AlertDefinition def, - boolean willRecover, - boolean enabled) { + protected void validateAvailabilityAlertDefinition(AlertDefinition def, + boolean willRecover, + boolean enabled) { assertTrue("The problem alert definition should be active", def.isActive()); assertTrue("The problem alert definition's willRecover flag should be " + willRecover, diff --git a/src/org/hyperic/hq/hqapi1/test/AlertFireRecovery_test.java b/src/org/hyperic/hq/hqapi1/test/AlertFireRecovery_test.java index fca44bcb..08d45dd2 100644 --- a/src/org/hyperic/hq/hqapi1/test/AlertFireRecovery_test.java +++ b/src/org/hyperic/hq/hqapi1/test/AlertFireRecovery_test.java @@ -115,10 +115,12 @@ public void testFireProblemAlertAndThenCreateAndFireRecoveryAlert() Resource platform = getLocalPlatformResource(false, false); boolean willRecover = false; - AlertDefinition problemDef = createProblemAlertDefinition(platform, null, false, willRecover); - Alert problemAlert = fireProblemAlert(problemDef, willRecover); + AlertDefinition problemDef = + createAvailabilityAlertDefinition(platform, null, false, willRecover, 0); + Alert problemAlert = fireAvailabilityAlert(problemDef, willRecover, 0); - AlertDefinition recoveryDef = createRecoveryAlertDefinition(platform, problemDef, false); + AlertDefinition recoveryDef = + createRecoveryAlertDefinition(platform, problemDef, false); fireRecoveryAlert(recoveryDef, problemAlert, willRecover); // Cleanup @@ -138,7 +140,7 @@ private void createAndFireAlerts(Escalation escalation, Resource platform = getLocalPlatformResource(false, false); AlertDefinition problemDef = - createProblemAlertDefinition(platform, escalation, isResourceType, willRecover); + createAvailabilityAlertDefinition(platform, escalation, isResourceType, willRecover, 0); AlertDefinition recoveryDef = createRecoveryAlertDefinition(platform, problemDef, addRecoveryPostCreate); @@ -149,7 +151,7 @@ private void createAndFireAlerts(Escalation escalation, problemDefToFire = problemDef; } - Alert problemAlert = fireProblemAlert(problemDefToFire, willRecover); + Alert problemAlert = fireAvailabilityAlert(problemDefToFire, willRecover, 0); AlertDefinition recoveryDefToFire = null; if (isResourceType) { @@ -167,29 +169,6 @@ private void createAndFireAlerts(Escalation escalation, cleanup(definitions); } - private Alert fireProblemAlert(AlertDefinition problemDef, - boolean willRecover) - throws Exception { - - long start = System.currentTimeMillis(); - - // Insert a fake 'down' measurement so that - // the problem alert definition will fire. - sendAvailabilityDataPoint(problemDef.getResource(), 0.0); - - Alert problemAlert = findAlert(problemDef, start); - assertFalse("The problem alert should not be fixed", - problemAlert.isFixed()); - - // Get the updated problem alert definition - AlertDefinition updatedDef = getAlertDefinition(problemAlert.getAlertDefinitionId()); - validateProblemAlertDefinition(updatedDef, - willRecover, - willRecover ? false : true); - - return problemAlert; - } - private Alert fireRecoveryAlert(AlertDefinition recoveryDef, Alert problemAlert, boolean willRecover) @@ -204,7 +183,11 @@ private Alert fireRecoveryAlert(AlertDefinition recoveryDef, Alert recoveryAlert = findAlert(recoveryDef, start); assertTrue("The recovery alert should be fixed", recoveryAlert.isFixed()); - + + // Get the updated recovery alert definition + AlertDefinition updatedRecoveryDef = getAlertDefinition(recoveryDef.getId()); + validateAvailabilityAlertDefinition(updatedRecoveryDef, false, true); + // Get the updated problem alert problemAlert = getAlert(problemAlert.getId()); assertTrue("The problem alert should be fixed", @@ -212,7 +195,7 @@ private Alert fireRecoveryAlert(AlertDefinition recoveryDef, // Get the updated problem alert definition AlertDefinition problemDef = getAlertDefinition(problemAlert.getAlertDefinitionId()); - validateProblemAlertDefinition(problemDef, willRecover, true); + validateAvailabilityAlertDefinition(problemDef, willRecover, true); return recoveryAlert; } diff --git a/src/org/hyperic/hq/hqapi1/test/AlertTestBase.java b/src/org/hyperic/hq/hqapi1/test/AlertTestBase.java index ad72536c..d2bffa8c 100644 --- a/src/org/hyperic/hq/hqapi1/test/AlertTestBase.java +++ b/src/org/hyperic/hq/hqapi1/test/AlertTestBase.java @@ -117,6 +117,30 @@ protected Alert generateAlerts(Resource resource, return findAlert(def, start); } + protected Alert fireAvailabilityAlert(AlertDefinition def, + boolean willRecover, + double availability) + throws Exception { + + long start = System.currentTimeMillis(); + + // Insert a fake availability data point so that + // the alert definition will fire. + sendAvailabilityDataPoint(def.getResource(), availability); + + Alert alert = findAlert(def, start); + assertFalse("The alert should not be fixed", + alert.isFixed()); + + // Get the updated alert definition + AlertDefinition updatedDef = getAlertDefinition(alert.getAlertDefinitionId()); + validateAvailabilityAlertDefinition(updatedDef, + willRecover, + willRecover ? false : true); + + return alert; + } + protected void sendAvailabilityDataPoint(Resource resource, double availability) throws IOException { diff --git a/src/org/hyperic/hq/hqapi1/test/HierarchicalAlertingTestBase.java b/src/org/hyperic/hq/hqapi1/test/HierarchicalAlertingTestBase.java index fa64f54f..52b26cbe 100644 --- a/src/org/hyperic/hq/hqapi1/test/HierarchicalAlertingTestBase.java +++ b/src/org/hyperic/hq/hqapi1/test/HierarchicalAlertingTestBase.java @@ -27,7 +27,7 @@ protected void simulatePlatformDownServersDown(boolean enabled) Resource platform = getLocalPlatformResource(false, true); AlertDefinition platformAlertDef = - createProblemAlertDefinition(platform, null, false, true); + createAvailabilityAlertDefinition(platform, null, false, true, 0); List problemAlertDefs = new ArrayList(); for (Resource server : platform.getResource()) { @@ -39,7 +39,8 @@ protected void simulatePlatformDownServersDown(boolean enabled) // set alert definition to willRecover=true // so that it will fire only once - problemAlertDefs.add(createProblemAlertDefinition(server, null, false, true)); + problemAlertDefs.add( + createAvailabilityAlertDefinition(server, null, false, true, 0)); } } diff --git a/src/org/hyperic/hq/hqapi1/test/MaintenanceGet_test.java b/src/org/hyperic/hq/hqapi1/test/MaintenanceGet_test.java index fdd5fe03..7a4a42fc 100644 --- a/src/org/hyperic/hq/hqapi1/test/MaintenanceGet_test.java +++ b/src/org/hyperic/hq/hqapi1/test/MaintenanceGet_test.java @@ -72,15 +72,10 @@ public void testGet() throws Exception { Group g = getFileServerMountCompatibleGroup(); long start = System.currentTimeMillis() + HOUR; long end = start + HOUR; - MaintenanceResponse scheduleResponse = mApi.schedule(g.getId(), - start, end); - hqAssertSuccess(scheduleResponse); - - MaintenanceResponse getResponse = mApi.get(g.getId()); - hqAssertSuccess(getResponse); - - MaintenanceEvent e = getResponse.getMaintenanceEvent(); - assertNotNull("MaintenanceEvent not found for valid group " + g.getName()); + + MaintenanceEvent e = schedule(g, start, end); + e = get(g); + assertNotNull("Maintenance event not found for valid group " + g.getName(), e); valididateMaintenanceEvent(e, g, start, end); StatusResponse unscheduleResponse = mApi.unschedule(g.getId()); diff --git a/src/org/hyperic/hq/hqapi1/test/MaintenanceSchedule_test.java b/src/org/hyperic/hq/hqapi1/test/MaintenanceSchedule_test.java index 1220c79e..cc057a45 100644 --- a/src/org/hyperic/hq/hqapi1/test/MaintenanceSchedule_test.java +++ b/src/org/hyperic/hq/hqapi1/test/MaintenanceSchedule_test.java @@ -27,22 +27,32 @@ package org.hyperic.hq.hqapi1.test; +import org.hyperic.hq.hqapi1.GroupApi; import org.hyperic.hq.hqapi1.HQApi; import org.hyperic.hq.hqapi1.MaintenanceApi; +import org.hyperic.hq.hqapi1.types.Alert; +import org.hyperic.hq.hqapi1.types.AlertDefinition; +import org.hyperic.hq.hqapi1.types.MaintenanceEvent; import org.hyperic.hq.hqapi1.types.MaintenanceResponse; +import org.hyperic.hq.hqapi1.types.MaintenanceState; import org.hyperic.hq.hqapi1.types.Group; import org.hyperic.hq.hqapi1.types.GroupResponse; import org.hyperic.hq.hqapi1.types.Operation; +import org.hyperic.hq.hqapi1.types.Resource; import org.hyperic.hq.hqapi1.types.Role; import org.hyperic.hq.hqapi1.types.RoleResponse; import org.hyperic.hq.hqapi1.types.StatusResponse; import org.hyperic.hq.hqapi1.types.User; +import java.util.Collections; import java.util.List; +import java.util.Random; public class MaintenanceSchedule_test extends MaintenanceTestBase { - private static final long HOUR = 60 * 60 * 1000; + private static final long SECOND = 1000; + private static final long MINUTE = 60 * SECOND; + private static final long HOUR = 60 * MINUTE; public MaintenanceSchedule_test(String name) { super(name); @@ -92,12 +102,8 @@ public void testSchedule() throws Exception { Group g = getFileServerMountCompatibleGroup(); long start = System.currentTimeMillis() + HOUR; long end = start + HOUR; - MaintenanceResponse response = mApi.schedule(g.getId(), - start, end); - hqAssertSuccess(response); - - assertNotNull(response.getMaintenanceEvent()); - valididateMaintenanceEvent(response.getMaintenanceEvent(), g, start, end); + + MaintenanceEvent event = schedule(g, start, end); StatusResponse unscheduleResponse = mApi.unschedule(g.getId()); hqAssertSuccess(unscheduleResponse); @@ -105,6 +111,70 @@ public void testSchedule() throws Exception { cleanupGroup(g); } + public void testFireAlertsBeforeSchedulingCompatibleGroup() + throws Exception { + + HQApi api = getApi(); + + // create resource + Resource resource = createControllableResource(api); + + // create group + Group maintGroup = createGroup(Collections.singletonList(resource)); + + // create alert definitions + AlertDefinition alertDefFireOnce = + createAvailabilityAlertDefinition(resource, null, false, true, 1); + AlertDefinition alertDefFireEveryTime = + createAvailabilityAlertDefinition(resource, null, false, false, 1); + + // insert a fake 'up' measurement so that + // the alert definitions will fire. + long alertStart = System.currentTimeMillis(); + Alert alertFireOnce = fireAvailabilityAlert(alertDefFireOnce, true, 1); + Alert alertFireEveryTime = fireAvailabilityAlert(alertDefFireEveryTime, false, 1); + + // TODO check measurement enabled status + + // schedule maintenance + MaintenanceApi mApi = api.getMaintenanceApi(); + long maintStart = System.currentTimeMillis() + 5*SECOND; + long maintEnd = maintStart + MINUTE; + + MaintenanceEvent event = schedule(maintGroup, maintStart, maintEnd); + + // wait for maintenance to start + waitForMaintenanceStateChange(maintGroup, MaintenanceState.RUNNING); + + // validate alert definitions during the maintenance + // the internal enabled flag should be false for all alert definitions + alertDefFireOnce = getAlertDefinition(alertDefFireOnce.getId()); + validateAvailabilityAlertDefinition(alertDefFireOnce, true, false); + + alertDefFireEveryTime = getAlertDefinition(alertDefFireEveryTime.getId()); + validateAvailabilityAlertDefinition(alertDefFireEveryTime, false, false); + + // TODO check measurement enabled status + + // wait for maintenance to end + waitForMaintenanceStateChange(maintGroup, MaintenanceState.COMPLETE); + + // validate alert definitions after the maintenance + // the internal enabled flag should still be false for the willRecover + // alert definition that fired before the maintenance + alertDefFireOnce = getAlertDefinition(alertDefFireOnce.getId()); + validateAvailabilityAlertDefinition(alertDefFireOnce, true, false); + + // the internal enabled flag should be true after the maintenance for + // the alert definition that is configured to fire every time + alertDefFireEveryTime = getAlertDefinition(alertDefFireEveryTime.getId()); + validateAvailabilityAlertDefinition(alertDefFireEveryTime, false, true); + + // TODO check measurement enabled status + + cleanupGroup(maintGroup, true); + } + public void testScheduleNoGroupPermission() throws Exception { List users = createTestUsers(1); @@ -173,4 +243,40 @@ public void testScheduleNoMaintenancePermission() throws Exception { cleanupRole(viewRole); cleanupGroup(groupWithRole); } + + private void waitForMaintenanceStateChange(Group g, MaintenanceState newState) + throws Exception{ + + MaintenanceEvent event = get(g); + assertNotNull("The group must have a scheduled maintenance event", + event); + MaintenanceState initialState = event.getState(); + MaintenanceState currentState = event.getState(); + + long timeout = 0; + if (newState.value().equals(MaintenanceState.RUNNING.value())) { + timeout = event.getStartTime() + 30*SECOND; + } else if (newState.value().equals(MaintenanceState.COMPLETE.value())) { + timeout = event.getEndTime() + 30*SECOND; + } + + while (!currentState.value().equals(newState.value())) { + if (System.currentTimeMillis() >= timeout) { + String message = "The maintenance event did not change state from " + + initialState.value() + " to " + + newState.value() + " in time."; + throw new Exception(message); + } + + pauseTest(5*SECOND); + + event = get(g); + + if (event == null) { + currentState = MaintenanceState.COMPLETE; + } else { + currentState = get(g).getState(); + } + } + } } diff --git a/src/org/hyperic/hq/hqapi1/test/MaintenanceTestBase.java b/src/org/hyperic/hq/hqapi1/test/MaintenanceTestBase.java index b6230c6b..89545847 100644 --- a/src/org/hyperic/hq/hqapi1/test/MaintenanceTestBase.java +++ b/src/org/hyperic/hq/hqapi1/test/MaintenanceTestBase.java @@ -29,25 +29,68 @@ import org.hyperic.hq.hqapi1.types.Group; import org.hyperic.hq.hqapi1.types.GroupResponse; +import org.hyperic.hq.hqapi1.types.MaintenanceEvent; +import org.hyperic.hq.hqapi1.types.MaintenanceResponse; +import org.hyperic.hq.hqapi1.types.Resource; +import org.hyperic.hq.hqapi1.types.ResourcePrototype; import org.hyperic.hq.hqapi1.types.ResourcePrototypeResponse; import org.hyperic.hq.hqapi1.types.ResourcesResponse; import org.hyperic.hq.hqapi1.types.Role; import org.hyperic.hq.hqapi1.types.StatusResponse; -import org.hyperic.hq.hqapi1.types.MaintenanceEvent; import org.hyperic.hq.hqapi1.HQApi; import org.hyperic.hq.hqapi1.GroupApi; import org.hyperic.hq.hqapi1.ResourceApi; import org.hyperic.hq.hqapi1.RoleApi; +import java.util.List; import java.util.Random; -public abstract class MaintenanceTestBase extends HQApiTestBase { +public abstract class MaintenanceTestBase extends AlertTestBase { public MaintenanceTestBase(String name) { super(name); } + MaintenanceEvent get(Group g) throws Exception { + + MaintenanceResponse getResponse = + getApi().getMaintenanceApi().get(g.getId()); + + hqAssertSuccess(getResponse); + + return getResponse.getMaintenanceEvent(); + } + + MaintenanceEvent schedule(Group g, long start, long end) + throws Exception { + + MaintenanceResponse response = + getApi().getMaintenanceApi().schedule(g.getId(), start, end); + + hqAssertSuccess(response); + + MaintenanceEvent event = response.getMaintenanceEvent(); + assertNotNull("The scheduled maintenance event should not be null", + event); + valididateMaintenanceEvent(event, g, start, end); + + return event; + } + void cleanupGroup(Group g) throws Exception { + cleanupGroup(g, false); + } + + void cleanupGroup(Group g, boolean deleteMembers) throws Exception { + + if (deleteMembers) { + ResourceApi api = getApi().getResourceApi(); + for (Resource r : g.getResource()) { + StatusResponse response = api.deleteResource(r.getId()); + hqAssertSuccess(response); + } + } + GroupApi api = getApi().getGroupApi(); StatusResponse response = api.deleteGroup(g.getId()); hqAssertSuccess(response); @@ -61,9 +104,7 @@ void cleanupRole(Role r) throws Exception { Group getFileServerMountCompatibleGroup() throws Exception { - HQApi api = getApi(); - ResourceApi resourceApi = api.getResourceApi(); - GroupApi groupApi = api.getGroupApi(); + ResourceApi resourceApi = getApi().getResourceApi(); ResourcePrototypeResponse protoResponse = resourceApi.getResourcePrototype("FileServer Mount"); @@ -76,16 +117,49 @@ Group getFileServerMountCompatibleGroup() throws Exception { protoResponse.getResourcePrototype().getName(), resources.getResource().size() > 0); + return createGroup(resources.getResource()); + } + + Group createGroup(List resources) throws Exception { + + // determine whether to create a mixed or compatible group + ResourcePrototype prototype = null; + for (Resource r : resources) { + if (prototype == null) { + prototype = r.getResourcePrototype(); + } else { + if (!prototype.getName().equals(r.getResourcePrototype().getName())) { + prototype = null; + break; + } + } + } + + // create group Random r = new Random(); Group g = new Group(); - g.setName("Compatible Group for Maintenance Tests" + r.nextInt()); - g.setResourcePrototype(protoResponse.getResourcePrototype()); - g.getResource().addAll(resources.getResource()); - - GroupResponse groupResponse = groupApi.createGroup(g); + String name = (prototype == null ? "Mixed" : "Compatible") + + " Group for Maintenance Tests" + r.nextInt(); + g.setName(name); + if (prototype != null) { + g.setResourcePrototype(prototype); + } + g.getResource().addAll(resources); + GroupResponse groupResponse = getApi().getGroupApi().createGroup(g); hqAssertSuccess(groupResponse); - - return groupResponse.getGroup(); + Group createdGroup = groupResponse.getGroup(); + assertEquals(resources.size(), createdGroup.getResource().size()); + if (prototype == null) { + assertNull("This should be a mixed group", + createdGroup.getResourcePrototype()); + } else { + assertNotNull("This should be a compatible group", + createdGroup.getResourcePrototype()); + assertEquals(prototype.getName(), + createdGroup.getResourcePrototype().getName()); + } + + return createdGroup; } void valididateMaintenanceEvent(MaintenanceEvent e, Group g, long start, long end) {