/* * Copyright 2014 Netflix, Inc. * * 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.netflix.servo.monitor; import com.netflix.servo.annotations.DataSourceType; import com.netflix.servo.tag.BasicTagList; import com.netflix.servo.tag.Tag; import com.netflix.servo.tag.TagList; import com.netflix.servo.util.ExpiringCache; import com.netflix.servo.util.ManualClock; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import java.lang.reflect.Field; import java.util.List; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNull; public class DynamicCounterTest { private static final Logger LOGGER = LoggerFactory.getLogger(DynamicCounterTest.class); private DynamicCounter getInstance() throws Exception { Field theInstance = DynamicCounter.class.getDeclaredField("INSTANCE"); theInstance.setAccessible(true); return (DynamicCounter) theInstance.get(null); } private List<Monitor<?>> getCounters() throws Exception { return getInstance().getMonitors(); } private final TagList tagList = BasicTagList.of("PLATFORM", "true"); private StepCounter getByName(String name) throws Exception { List<Monitor<?>> counters = getCounters(); for (Monitor<?> m : counters) { String monitorName = m.getConfig().getName(); if (name.equals(monitorName)) { return (StepCounter) m; } } return null; } @Test public void testHasRightType() throws Exception { DynamicCounter.increment("test1", tagList); StepCounter c = getByName("test1"); assert c != null; Tag type = c.getConfig().getTags().getTag(DataSourceType.KEY); assertEquals(type.getValue(), "NORMALIZED"); } final ManualClock clock = new ManualClock(0L); /** * Erase all previous counters by creating a new loading cache with a short expiration time. */ @BeforeMethod public void setupInstance() throws Exception { LOGGER.info("Setting up DynamicCounter instance with a new cache"); DynamicCounter theInstance = getInstance(); Field counters = DynamicCounter.class.getDeclaredField("counters"); counters.setAccessible(true); ExpiringCache<MonitorConfig, Counter> newShortExpiringCache = new ExpiringCache<>(60000L, config -> new StepCounter(config, clock), 100L, clock); counters.set(theInstance, newShortExpiringCache); } @Test public void testGetValue() throws Exception { clock.set(0L); DynamicCounter.increment("test1", tagList); StepCounter c = getByName("test1"); clock.set(60000L); assert c != null; assertEquals(c.getCount(0), 1L); c.increment(13); clock.set(120000L); assertEquals(c.getCount(0), 13L); } @Test public void testExpiration() throws Exception { clock.set(0L); DynamicCounter.increment("test1", tagList); DynamicCounter.increment("test2", tagList); clock.set(500L); DynamicCounter.increment("test1", tagList); clock.set(1000L); DynamicCounter.increment("test1", tagList); clock.set(60200L); StepCounter c1 = getByName("test1"); assert c1 != null; assertEquals(c1.getCount(0), 3L); // the expiration task is not using Clock Thread.sleep(200); StepCounter c2 = getByName("test2"); assertNull(c2, "Counters not used in a while should expire"); } @Test public void testByStrings() throws Exception { clock.set(1L); DynamicCounter.increment("byName"); DynamicCounter.increment("byName"); StepCounter c = getByName("byName"); clock.set(60001L); assert c != null; assertEquals(c.getCount(0), 2L); DynamicCounter.increment("byName2", "key", "value", "key2", "value2"); DynamicCounter.increment("byName2", "key", "value", "key2", "value2"); StepCounter c2 = getByName("byName2"); clock.set(120001L); assert c2 != null; assertEquals(c2.getCount(0), 2L); } @Test public void testShouldNotThrow() throws Exception { DynamicCounter.increment("name", "", ""); } }