/* * 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.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 java.util.concurrent.TimeUnit; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNull; public class DynamicTimerTest { private static final Logger LOGGER = LoggerFactory.getLogger(DynamicTimerTest.class); private DynamicTimer getInstance() throws Exception { Field theInstance = DynamicTimer.class.getDeclaredField("INSTANCE"); theInstance.setAccessible(true); return (DynamicTimer) theInstance.get(null); } private List<Monitor<?>> getTimers() throws Exception { return getInstance().getMonitors(); } private final TagList tagList = BasicTagList.of("PLATFORM", "true"); private Timer getByName(String name) throws Exception { List<Monitor<?>> timers = getTimers(); for (Monitor<?> m : timers) { String monitorName = m.getConfig().getName(); if (name.equals(monitorName)) { return (Timer) m; } } return null; } @SuppressWarnings("unchecked") @Test public void testHasUnitTag() throws Exception { DynamicTimer.start("test1", tagList); CompositeMonitor c = (CompositeMonitor<Long>) getByName("test1"); assert c != null; List<Monitor<?>> monitors = c.getMonitors(); for (Monitor<?> m : monitors) { Tag type = m.getConfig().getTags().getTag("unit"); assertEquals(type.getValue(), "MILLISECONDS"); } } final ManualClock clock = new ManualClock(0L); /** * Erase all previous timers by creating a new loading cache with a short expiration time */ @BeforeMethod public void setupInstance() throws Exception { LOGGER.info("Setting up DynamicTimer instance with a new cache"); DynamicTimer theInstance = getInstance(); Field timers = DynamicTimer.class.getDeclaredField("timers"); timers.setAccessible(true); ExpiringCache<DynamicTimer.ConfigUnit, Timer> newShortExpiringCache = new ExpiringCache<>(1000L, configUnit -> new BasicTimer(configUnit.getConfig(), configUnit.getUnit()), 100L, clock); timers.set(theInstance, newShortExpiringCache); } @Test public void testGetValue() throws Exception { Stopwatch s = DynamicTimer.start("test1", tagList); Timer c = getByName("test1"); s.stop(); // we don't call s.stop(), so we only have one recorded value assert c != null; assertEquals(c.getValue().longValue(), s.getDuration(TimeUnit.MILLISECONDS)); c.record(13, TimeUnit.MILLISECONDS); long expected = (13 + s.getDuration(TimeUnit.MILLISECONDS)) / 2; assertEquals(c.getValue().longValue(), expected); } @Test public void testExpiration() throws Exception { clock.set(0L); DynamicTimer.start("test1", tagList); DynamicTimer.start("test2", tagList); clock.set(500L); DynamicTimer.start("test1", tagList); clock.set(1000L); Stopwatch s = DynamicTimer.start("test1", tagList); clock.set(1200L); s.stop(); Timer c1 = getByName("test1"); assert c1 != null; assertEquals(c1.getValue().longValue(), s.getDuration(TimeUnit.MILLISECONDS)); Thread.sleep(200L); Timer c2 = getByName("test2"); assertNull(c2, "Timers not used in a while should expire"); } @Test public void testByStrings() throws Exception { Stopwatch s = DynamicTimer.start("byName"); Stopwatch s2 = DynamicTimer.start("byName2", "key", "value"); Thread.sleep(100L); s.stop(); s2.stop(); Timer c1 = getByName("byName"); assert c1 != null; assertEquals(c1.getValue().longValue(), s.getDuration(TimeUnit.MILLISECONDS)); Timer c2 = getByName("byName2"); assert c2 != null; assertEquals(c2.getValue().longValue(), s2.getDuration(TimeUnit.MILLISECONDS)); } }