package org.stagemonitor.alerting.annotation; import com.codahale.metrics.annotation.ExceptionMetered; import com.codahale.metrics.annotation.Timed; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.stagemonitor.alerting.AlertingPlugin; import org.stagemonitor.alerting.check.Check; import org.stagemonitor.alerting.check.CheckResult; import org.stagemonitor.alerting.check.MetricValueType; import org.stagemonitor.alerting.check.Threshold; import org.stagemonitor.alerting.incident.Incident; import org.stagemonitor.core.Stagemonitor; import org.stagemonitor.core.metrics.metrics2.MetricName; import org.stagemonitor.tracing.MonitorRequests; import java.util.List; import java.util.Map; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.stagemonitor.core.metrics.metrics2.MetricName.name; public class SlaCheckCreatingClassPathScannerTest { private final AlertingPlugin alertingPlugin = Stagemonitor.getPlugin(AlertingPlugin.class); private Map<String, Check> checks; private static class SlaTestClass { @SLAs({ @SLA(metric = {MetricValueType.P95, MetricValueType.MAX}, threshold = {0, 0}), @SLA(errorRateThreshold = 0) }) @MonitorRequests void monitorSla() { throw null; } @SLA(errorRateThreshold = 0) void monitorRequestsAnnotationMissing() { } @MonitorRequests @SLA(metric = {MetricValueType.P95, MetricValueType.MAX}, threshold = 0) void tooFewThresholds() { } @MonitorRequests(resolveNameAtRuntime = true) @SLA(metric = {MetricValueType.P95, MetricValueType.MAX}, threshold = {0, 0}) void slaMonitorRequestsResolveAtRuntime() { } @MonitorRequests(requestName = "monitor requests custom name") @SLA(metric = {MetricValueType.P95, MetricValueType.MAX}, threshold = {0, 0}) void slaMonitorRequestsCustomName() { } @Timed(name = "timed custom name", absolute = true) @SLA(metric = {MetricValueType.P95, MetricValueType.MAX}, threshold = {0, 0}) void slaTimedCustomName() { } @Timed @SLA(metric = {MetricValueType.P95, MetricValueType.MAX}, threshold = {0, 0}) void slaOnTimed() { } @ExceptionMetered @SLA(errorRateThreshold = 0) void slaOnExceptionMetered() { } @Timed @SLA(errorRateThreshold = 0) void slaMissingExceptionMetered() { } static void makeSureClassIsLoaded() { } } @BeforeClass @AfterClass public static void init() throws Exception { Stagemonitor.init(); SlaTestClass.makeSureClassIsLoaded(); ClassLevelMonitorRequestsTestClass.makeSureClassIsLoaded(); Stagemonitor.startMonitoring(); } @Before public void setUp() throws Exception { checks = alertingPlugin.getChecks(); } @Test public void testSlaMonitorRequests() throws Exception { testErrorRateCheck("void org.stagemonitor.alerting.annotation.SlaCheckCreatingClassPathScannerTest$SlaTestClass.monitorSla().errors", name("error_rate_server").tag("request_name", "Monitor Sla").layer("All").build()); testResponseTimeCheck("void org.stagemonitor.alerting.annotation.SlaCheckCreatingClassPathScannerTest$SlaTestClass.monitorSla().responseTime", name("response_time_server").tag("request_name", "Monitor Sla").layer("All").build()); } private void testErrorRateCheck(String checkId, MetricName checkTarget) { final Check errorRateCheck = checks.get(checkId); assertNotNull(checks.keySet().toString(), errorRateCheck); assertEquals("Alerting-Test", errorRateCheck.getApplication()); assertEquals(checkTarget, errorRateCheck.getTarget()); } private void testResponseTimeCheck(String checkId, MetricName checkTarget) { final Check responseTimeChek = checks.get(checkId); assertNotNull(checks.keySet().toString(), responseTimeChek); assertEquals("Alerting-Test", responseTimeChek.getApplication()); assertEquals(checkTarget, responseTimeChek.getTarget()); final List<Threshold> thresholds = responseTimeChek.getThresholds(CheckResult.Status.ERROR); final Threshold p95 = thresholds.get(0); assertEquals(MetricValueType.P95, p95.getValueType()); assertEquals(Threshold.Operator.LESS, p95.getOperator()); assertEquals(0, p95.getThresholdValue(), 0); final Threshold max = thresholds.get(1); assertEquals(MetricValueType.MAX, max.getValueType()); assertEquals(Threshold.Operator.LESS, max.getOperator()); assertEquals(0, max.getThresholdValue(), 0); } @Test public void testSlaCustomName() throws Exception { testResponseTimeCheck("void org.stagemonitor.alerting.annotation.SlaCheckCreatingClassPathScannerTest$SlaTestClass.slaMonitorRequestsCustomName().responseTime", name("response_time_server").tag("request_name", "monitor requests custom name").layer("All").build()); } @Test public void testTimedCustomName() throws Exception { testResponseTimeCheck("void org.stagemonitor.alerting.annotation.SlaCheckCreatingClassPathScannerTest$SlaTestClass.slaTimedCustomName().responseTime", name("timer").tag("signature", "timed custom name").build()); } @Test public void testSlaTimed() throws Exception { testResponseTimeCheck("void org.stagemonitor.alerting.annotation.SlaCheckCreatingClassPathScannerTest$SlaTestClass.slaOnTimed().responseTime", name("timer").tag("signature", "SlaCheckCreatingClassPathScannerTest$SlaTestClass#slaOnTimed").build()); } @Test public void testSlaExceptionMetered() throws Exception { testErrorRateCheck("void org.stagemonitor.alerting.annotation.SlaCheckCreatingClassPathScannerTest$SlaTestClass.slaOnExceptionMetered().errors", name("exception_rate").tag("signature", "SlaCheckCreatingClassPathScannerTest$SlaTestClass#slaOnExceptionMetered").build()); } @Test public void testSlaMissingExceptionMetered() throws Exception { assertNull(checks.get("void org.stagemonitor.alerting.annotation.SlaCheckCreatingClassPathScannerTest$SlaTestClass.slaMissingExceptionMetered().errors")); } @Test public void testSlaMonitorRequestsResolveAtRuntime() throws Exception { assertNull(checks.get("void org.stagemonitor.alerting.annotation.SlaCheckCreatingClassPathScannerTest$SlaTestClass.slaMonitorRequestsResolveAtRuntime().responseTime")); } @Test public void testSlaMonitorRequestsClassLevel() throws Exception { testResponseTimeCheck("public void org.stagemonitor.alerting.annotation.SlaCheckCreatingClassPathScannerTest$ClassLevelMonitorRequestsTestClass.slaMonitorRequestsClassLevel().responseTime", name("response_time_server").tag("request_name", "Sla Monitor Requests Class Level").layer("All").build()); } @MonitorRequests private static class ClassLevelMonitorRequestsTestClass { static void makeSureClassIsLoaded() { } @SLA(metric = {MetricValueType.P95, MetricValueType.MAX}, threshold = {0, 0}) public void slaMonitorRequestsClassLevel() { } } @Test public void testTriggersResponseTimeIncident() throws Exception { try { new SlaTestClass().monitorSla(); } catch (Exception e) { // ignore } alertingPlugin.getThresholdMonitoringReporter().report(); final Incident incident = alertingPlugin.getIncidentRepository() .getIncidentByCheckId("void org.stagemonitor.alerting.annotation.SlaCheckCreatingClassPathScannerTest$SlaTestClass.monitorSla().responseTime"); assertNotNull(incident); } @Test public void testTriggersErrorRateIncident() throws Exception { try { new SlaTestClass().monitorSla(); } catch (Exception e) { // ignore } alertingPlugin.getThresholdMonitoringReporter().report(); final Incident incident = alertingPlugin.getIncidentRepository() .getIncidentByCheckId("void org.stagemonitor.alerting.annotation.SlaCheckCreatingClassPathScannerTest$SlaTestClass.monitorSla().errors"); assertNotNull(incident); } }