/** * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.seyren.core.service.checker; import static org.hamcrest.MatcherAssert.*; import static org.hamcrest.Matchers.*; import static org.mockito.Mockito.*; import java.math.BigDecimal; import java.util.Map; import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.github.restdriver.clientdriver.ClientDriverRule; import com.google.common.base.Optional; import com.seyren.core.domain.Check; import com.seyren.core.util.graphite.GraphiteHttpClient; import com.seyren.core.util.graphite.GraphiteReadException; public class GraphiteTargetCheckerTest { private static final ObjectMapper MAPPER = new ObjectMapper(); @Rule public ClientDriverRule clientDriver = new ClientDriverRule(); private GraphiteHttpClient mockGraphiteHttpClient; private GraphiteTargetChecker checker; @Before public void before() { mockGraphiteHttpClient = mock(GraphiteHttpClient.class); checker = new GraphiteTargetChecker(mockGraphiteHttpClient); } @After public void after() { System.clearProperty("GRAPHITE_URL"); } @Test public void singleValidTargetIsPresent() throws Exception { JsonNode node = MAPPER.readTree("[{\"target\": \"service.error.1MinuteRate\", \"datapoints\": [[0.06, 1337453460]]}]"); when(mockGraphiteHttpClient.getTargetJson("service.error.1MinuteRate", null, null)).thenReturn(node); Map<String, Optional<BigDecimal>> values = checker.check(check()); assertThat(values, hasKey("service.error.1MinuteRate")); } @Test public void singleValidTargetHasCorrectValue() throws Exception { JsonNode node = MAPPER.readTree("[{\"target\": \"service.error.1MinuteRate\", \"datapoints\": [[0.06, 1337453460]]}]"); when(mockGraphiteHttpClient.getTargetJson("service.error.1MinuteRate", null, null)).thenReturn(node); Map<String, Optional<BigDecimal>> values = checker.check(check()); assertThat(values.get("service.error.1MinuteRate").isPresent(), is(true)); assertThat(values.get("service.error.1MinuteRate").get(), is(new BigDecimal("0.06"))); } @Test public void valueIsDeterminedByGoingThroughDatapointsInReverserOrder() throws Exception { JsonNode node = MAPPER.readTree("[{\"target\": \"service.error.1MinuteRate\", \"datapoints\": [[0.20, 1337453460],[0.01, 1337453463]]}]"); when(mockGraphiteHttpClient.getTargetJson("service.error.1MinuteRate", null, null)).thenReturn(node); Map<String, Optional<BigDecimal>> values = checker.check(check()); assertThat(values.get("service.error.1MinuteRate").get(), is(new BigDecimal("0.01"))); } @Test public void valueIsDeterminedBySkippingNullValues() throws Exception { JsonNode node = MAPPER.readTree("[{\"target\": \"service.error.1MinuteRate\", \"datapoints\": [[0.17, 1337453460],[null, 1337453463]]}]"); when(mockGraphiteHttpClient.getTargetJson("service.error.1MinuteRate", null, null)).thenReturn(node); Map<String, Optional<BigDecimal>> values = checker.check(check()); assertThat(values.get("service.error.1MinuteRate").get(), is(new BigDecimal("0.17"))); } @Test public void targetWhichOnlyHasNullValuesIsAbsent() throws Exception { JsonNode node = MAPPER.readTree("[{\"target\": \"service.error.1MinuteRate\", \"datapoints\": [[null, 1337453460],[null, 1337453463]]}]"); when(mockGraphiteHttpClient.getTargetJson("service.error.1MinuteRate", null, null)).thenReturn(node); Map<String, Optional<BigDecimal>> values = checker.check(check()); assertThat(values.get("service.error.1MinuteRate").isPresent(), is(false)); } @Test public void multipleTargetsAreHandledCorrectly() throws Exception { JsonNode node = MAPPER.readTree("[" + "{\"target\": \"service.error.1MinuteRate\", \"datapoints\": [[0.20, 1337453460],[0.01, 1337453463]]}," + "{\"target\": \"service.warn.1MinuteRate\", \"datapoints\": [[0.56, 1337453460],[0.78, 1337453463]]}" + "]"); when(mockGraphiteHttpClient.getTargetJson("service.*.1MinuteRate", null, null)).thenReturn(node); Map<String, Optional<BigDecimal>> values = checker.check(checkWithTarget("service.*.1MinuteRate")); assertThat(values.entrySet(), hasSize(2)); assertThat(values.get("service.error.1MinuteRate").get(), is(new BigDecimal("0.01"))); assertThat(values.get("service.warn.1MinuteRate").get(), is(new BigDecimal("0.78"))); } @Test public void exceptionGettingDataFromGraphiteIsHandled() throws Exception { when(mockGraphiteHttpClient.getTargetJson("service.*.1MinuteRate", null, null)).thenThrow(new GraphiteReadException("Graphite bad times", new RuntimeException("Bad times"))); Map<String, Optional<BigDecimal>> values = checker.check(checkWithTarget("service.*.1MinuteRate")); assertThat(values.size(), is(0)); } private Check check() { return checkWithTarget("service.error.1MinuteRate"); } private Check checkWithTarget(String target) { return new Check() .withId("id") .withTarget(target) .withWarn(new BigDecimal("0.15")) .withError(new BigDecimal("0.20")); } }