/**
* Copyright 2013 Netflix, Inc.
* <p/>
* 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
* <p/>
* http://www.apache.org/licenses/LICENSE-2.0
* <p/>
* 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.util.UnmodifiableSet;
import org.testng.annotations.Test;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotEquals;
public class BucketTimerTest extends AbstractMonitorTest<BucketTimer> {
@Override
public BucketTimer newInstance(String name) {
return new BucketTimer(
MonitorConfig.builder(name).build(),
new BucketConfig.Builder().withBuckets(new long[]{10L, 20L}).build()
);
}
@Test
public void testRecord() throws Exception {
BucketTimer c = newInstance("foo");
Map<String, Number> expectedValues;
expectedValues = new HashMap<>();
expectedValues.put("totalTime", 0L);
expectedValues.put("min", 0L);
expectedValues.put("max", 0L);
expectedValues.put("bucket=10ms", 0L);
expectedValues.put("bucket=20ms", 0L);
expectedValues.put("bucket=overflow", 0L);
assertMonitors(c.getMonitors(), expectedValues);
assertEquals(c.getCount(0).longValue(), 0L);
c.record(40);
expectedValues = new HashMap<>();
expectedValues.put("totalTime", 40L);
expectedValues.put("min", 40L);
expectedValues.put("max", 40L);
expectedValues.put("bucket=10ms", 0L);
expectedValues.put("bucket=20ms", 0L);
expectedValues.put("bucket=overflow", 1L);
assertMonitors(c.getMonitors(), expectedValues);
assertEquals(c.getCount(0).longValue(), 1L);
c.record(10);
expectedValues = new HashMap<>();
expectedValues.put("totalTime", 50L);
expectedValues.put("min", 10L);
expectedValues.put("max", 40L);
expectedValues.put("bucket=10ms", 1L);
expectedValues.put("bucket=20ms", 0L);
expectedValues.put("bucket=overflow", 1L);
assertMonitors(c.getMonitors(), expectedValues);
assertEquals(c.getCount(0).longValue(), 2L);
c.record(5);
expectedValues = new HashMap<>();
expectedValues.put("totalTime", 55L);
expectedValues.put("min", 5L);
expectedValues.put("max", 40L);
expectedValues.put("bucket=10ms", 2L);
expectedValues.put("bucket=20ms", 0L);
expectedValues.put("bucket=overflow", 1L);
assertMonitors(c.getMonitors(), expectedValues);
assertEquals(c.getCount(0).longValue(), 3L);
c.record(20);
expectedValues = new HashMap<>();
expectedValues.put("totalTime", 75L);
expectedValues.put("min", 5L);
expectedValues.put("max", 40L);
expectedValues.put("bucket=10ms", 2L);
expectedValues.put("bucket=20ms", 1L);
expectedValues.put("bucket=overflow", 1L);
assertMonitors(c.getMonitors(), expectedValues);
assertEquals(c.getCount(0).longValue(), 4L);
c.record(125);
expectedValues = new HashMap<>();
expectedValues.put("totalTime", 200L);
expectedValues.put("min", 5L);
expectedValues.put("max", 125L);
expectedValues.put("bucket=10ms", 2L);
expectedValues.put("bucket=20ms", 1L);
expectedValues.put("bucket=overflow", 2L);
assertMonitors(c.getMonitors(), expectedValues);
assertEquals(c.getCount(0).longValue(), 5L);
}
@Test
public void testRecordDifferentUnits() throws Exception {
BucketTimer c = new BucketTimer(
MonitorConfig.builder("foo").build(),
new BucketConfig.Builder().withBuckets(new long[]{10000L, 20000L}).withTimeUnit(TimeUnit.NANOSECONDS).build(),
TimeUnit.MICROSECONDS
);;
Map<String, Number> expectedValues;
expectedValues = new HashMap<>();
expectedValues.put("totalTime", 0L);
expectedValues.put("min", 0L);
expectedValues.put("max", 0L);
expectedValues.put("bucket=10000ns", 0L);
expectedValues.put("bucket=20000ns", 0L);
expectedValues.put("bucket=overflow", 0L);
assertMonitors(c.getMonitors(), expectedValues);
assertEquals(c.getCount(0).longValue(), 0L);
c.record(40);
expectedValues = new HashMap<>();
expectedValues.put("totalTime", 40L);
expectedValues.put("min", 40L);
expectedValues.put("max", 40L);
expectedValues.put("bucket=10000ns", 0L);
expectedValues.put("bucket=20000ns", 0L);
expectedValues.put("bucket=overflow", 1L);
assertMonitors(c.getMonitors(), expectedValues);
assertEquals(c.getCount(0).longValue(), 1L);
c.record(10);
expectedValues = new HashMap<>();
expectedValues.put("totalTime", 50L);
expectedValues.put("min", 10L);
expectedValues.put("max", 40L);
expectedValues.put("bucket=10000ns", 1L);
expectedValues.put("bucket=20000ns", 0L);
expectedValues.put("bucket=overflow", 1L);
assertMonitors(c.getMonitors(), expectedValues);
assertEquals(c.getCount(0).longValue(), 2L);
c.record(5);
expectedValues = new HashMap<>();
expectedValues.put("totalTime", 55L);
expectedValues.put("min", 5L);
expectedValues.put("max", 40L);
expectedValues.put("bucket=10000ns", 2L);
expectedValues.put("bucket=20000ns", 0L);
expectedValues.put("bucket=overflow", 1L);
assertMonitors(c.getMonitors(), expectedValues);
assertEquals(c.getCount(0).longValue(), 3L);
c.record(20);
expectedValues = new HashMap<>();
expectedValues.put("totalTime", 75L);
expectedValues.put("min", 5L);
expectedValues.put("max", 40L);
expectedValues.put("bucket=10000ns", 2L);
expectedValues.put("bucket=20000ns", 1L);
expectedValues.put("bucket=overflow", 1L);
assertMonitors(c.getMonitors(), expectedValues);
assertEquals(c.getCount(0).longValue(), 4L);
c.record(125);
expectedValues = new HashMap<>();
expectedValues.put("totalTime", 200L);
expectedValues.put("min", 5L);
expectedValues.put("max", 125L);
expectedValues.put("bucket=10000ns", 2L);
expectedValues.put("bucket=20000ns", 1L);
expectedValues.put("bucket=overflow", 2L);
assertMonitors(c.getMonitors(), expectedValues);
assertEquals(c.getCount(0).longValue(), 5L);
}
private void assertMonitors(List<Monitor<?>> monitors, Map<String, Number> expectedValues) {
Set<String> exclude = UnmodifiableSet.of("count", "min", "max");
String[] namespaces = new String[]{"statistic", "servo.bucket"};
for (Monitor<?> monitor : monitors) {
for (String namespace : namespaces) {
final String tag = monitor.getConfig().getTags().getValue(namespace);
if (tag != null && !exclude.contains(tag)) {
final Number actual = (Number) monitor.getValue();
final Number expected = expectedValues.get(tag);
assertEquals(actual, expected, namespace + "." + tag);
}
}
}
}
@Test
public void testEqualsCount() throws Exception {
BucketTimer c1 = newInstance("foo");
BucketTimer c2 = newInstance("foo");
assertEquals(c1, c2);
c1.record(42);
assertNotEquals(c1, c2);
c2.record(42);
assertEquals(c1, c2);
c1.record(11);
assertNotEquals(c1, c2);
c2.record(11);
assertEquals(c1, c2);
}
@Test
public void testHashCode() throws Exception {
BucketTimer c1 = newInstance("foo");
BucketTimer c2 = newInstance("foo");
assertEquals(c1.hashCode(), c2.hashCode());
c1.record(42);
assertNotEquals(c1.hashCode(), c2.hashCode());
c2.record(42);
assertEquals(c1.hashCode(), c2.hashCode());
c1.record(11);
assertNotEquals(c1.hashCode(), c2.hashCode());
c2.record(11);
assertEquals(c1.hashCode(), c2.hashCode());
}
}