blob: 776875d9a96b090561e8a57cbc1e1857005bcf5f [file] [log] [blame]
/**
* 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 org.apache.aurora.common.stats;
import java.util.concurrent.atomic.AtomicLong;
import com.google.common.base.Supplier;
import org.apache.aurora.common.util.testing.FakeTicker;
import org.easymock.IMocksControl;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import static org.easymock.EasyMock.createControl;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.expectLastCall;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
/**
* @author William Farner
*/
public class RateTest {
private static final int ONE_SEC = 1000000000;
private static final double EPSILON = 1E-6;
private IMocksControl control;
private FakeTicker ticker;
private Stat<Integer> input;
@Before
@SuppressWarnings("unchecked")
public void setUp() {
control = createControl();
ticker = new FakeTicker();
input = control.createMock(Stat.class);
}
@After
public void verify() {
Stats.flush();
control.verify();
}
@Test
public void testInputsRegistered() {
expect(input.getName()).andReturn("test");
expectLastCall().atLeastOnce();
control.replay();
Rate.of(input);
assertNotNull(Stats.getVariable("test"));
}
@Test
public void testNoHistory() throws Exception {
expectCalls(0);
control.replay();
assertResults();
}
@Test
public void testFlat() throws Exception {
expectCalls(10, 10);
control.replay();
assertResults(0);
}
@Test
public void testFixedRate() throws Exception {
expectCalls(10, 20, 30, 40);
control.replay();
assertResults(10, 10, 10);
}
@Test
public void testVariableRate() throws Exception {
expectCalls(10, 20, 50, 150);
control.replay();
assertResults(10, 30, 100);
}
@Test
public void testVariableRateAtomicLong() throws Exception {
AtomicLong value = new AtomicLong();
Rate<AtomicLong> rate = Rate.of("test", value).withTicker(ticker).build();
ticker.waitNanos(ONE_SEC);
value.set(10);
assertEquals(0d, rate.sample(), EPSILON);
ticker.waitNanos(ONE_SEC);
value.set(20);
assertEquals(10d, rate.sample(), EPSILON);
ticker.waitNanos(ONE_SEC);
value.set(50);
assertEquals(30d, rate.sample(), EPSILON);
ticker.waitNanos(ONE_SEC);
value.set(100);
assertEquals(50d, rate.sample(), EPSILON);
control.replay();
}
@Test
public void testNegativeRate() throws Exception {
expectCalls(40, 30, 20, 10);
control.replay();
assertResults(-10, -10, -10);
}
@Test
public void testZeroDelta() throws Exception {
expectCalls(10, 10, 10);
control.replay();
assertResults(0, 0);
}
@Test
public void testLongWindow() throws Exception {
expectCalls(10, 10, 0, 10, 10);
control.replay();
assertResults(Rate.of(input).withWindowSize(3).withTicker(ticker).build(), 0, -5, 0, 0);
}
@Test
public void testRateOfRate() throws Exception {
expectCalls(10, 20, 30, 40, 50, 60);
control.replay();
Rate<Integer> rate = Rate.of(input).withTicker(ticker).build();
Rate<Double> rateOfRate = Rate.of(rate).withTicker(ticker).build();
assertThat(rate.sample(), is(0d));
assertThat(rateOfRate.sample(), is(0d));
ticker.waitNanos(ONE_SEC);
assertThat(rate.sample(), is(10d));
assertThat(rateOfRate.sample(), is(10d));
ticker.waitNanos(ONE_SEC);
assertThat(rate.sample(), is(10d));
assertThat(rateOfRate.sample(), is(0d));
ticker.waitNanos(ONE_SEC);
assertThat(rate.sample(), is(10d));
assertThat(rateOfRate.sample(), is(0d));
ticker.waitNanos(ONE_SEC);
assertThat(rate.sample(), is(10d));
assertThat(rateOfRate.sample(), is(0d));
ticker.waitNanos(ONE_SEC);
assertThat(rate.sample(), is(10d));
assertThat(rateOfRate.sample(), is(0d));
}
@Test
public void testScaleFactor() throws Exception {
expectCalls(10, 20, 30, 40);
control.replay();
assertResults(Rate.of(input).withTicker(ticker).withScaleFactor(10).build(), 100, 100, 100);
}
@Test
public void testFractionalScaleFactor() throws Exception {
expectCalls(10, 20, 30, 40);
control.replay();
assertResults(Rate.of(input).withTicker(ticker).withScaleFactor(0.1).build(), 1, 1, 1);
}
@Test
public void testSupplier() throws Exception {
Supplier<Long> supplier = new Supplier<Long>() {
long value = 0;
@Override public Long get() {
value += 10;
return value;
}
};
control.replay();
assertResults(Rate.of("test", supplier).withTicker(ticker).build(), 10, 10, 10);
}
private void expectCalls(int... samples) {
expect(input.getName()).andReturn("test");
expectLastCall().atLeastOnce();
for (int sample : samples) {
expect(input.read()).andReturn(sample);
}
}
private void assertResults(double... results) throws Exception {
assertResults(Rate.of(input).withTicker(ticker).build(), results);
}
private void assertResults(Rate rate, double... results) throws Exception {
// First result is always zero.
assertEquals(0d, rate.sample().doubleValue(), EPSILON);
ticker.waitNanos(ONE_SEC);
for (double result : results) {
assertEquals(result, rate.sample().doubleValue(), EPSILON);
ticker.waitNanos(ONE_SEC);
}
}
}