blob: 9ba5e5723530beda43e45c3ef55d3029f19e0e2b [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.ratis.util;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Timeout;
import org.slf4j.event.Level;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import static org.apache.ratis.util.TimeDuration.Abbreviation;
import static org.apache.ratis.util.TimeDuration.parse;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class TestTimeDuration {
{
Slf4jUtils.setLogLevel(TimeDuration.LOG, Level.DEBUG);
}
@Test
@Timeout(value = 1)
public void testAbbreviation() {
Arrays.asList(TimeUnit.values())
.forEach(a -> assertNotNull(Abbreviation.valueOf(a.name())));
assertEquals(TimeUnit.values().length, Abbreviation.values().length);
final List<String> allSymbols = Arrays.stream(Abbreviation.values())
.map(Abbreviation::getSymbols)
.flatMap(List::stream)
.collect(Collectors.toList());
Arrays.asList(TimeUnit.values()).forEach(unit ->
allSymbols.stream()
.map(s -> "0" + s)
.forEach(s -> assertEquals(0L, parse(s, unit), s)));
}
@Test
@Timeout(value = 1)
public void testParse() {
assertEquals(1L, parse("1_000_000 ns", TimeUnit.MILLISECONDS));
assertEquals(10L, parse("10_000_000 nanos", TimeUnit.MILLISECONDS));
assertEquals(100L, parse("100_000_000 nanosecond", TimeUnit.MILLISECONDS));
assertEquals(1000L, parse("1_000_000_000 nanoseconds", TimeUnit.MILLISECONDS));
assertEquals(1L, parse("1000 us", TimeUnit.MILLISECONDS));
assertEquals(10L, parse("10000 μs", TimeUnit.MILLISECONDS));
assertEquals(100L, parse("100000 micros", TimeUnit.MILLISECONDS));
assertEquals(1000L, parse("1000000 microsecond", TimeUnit.MILLISECONDS));
assertEquals(10000L, parse("10000000 microseconds", TimeUnit.MILLISECONDS));
assertEquals(1L, parse("1 ms", TimeUnit.MILLISECONDS));
assertEquals(10L, parse("10 msec", TimeUnit.MILLISECONDS));
assertEquals(100L, parse("100 millis", TimeUnit.MILLISECONDS));
assertEquals(1000L, parse("1000 millisecond", TimeUnit.MILLISECONDS));
assertEquals(10000L, parse("10000 milliseconds", TimeUnit.MILLISECONDS));
assertEquals(1000L, parse("1 s", TimeUnit.MILLISECONDS));
assertEquals(10000L, parse("10 sec", TimeUnit.MILLISECONDS));
assertEquals(100000L, parse("100 second", TimeUnit.MILLISECONDS));
assertEquals(1000000L, parse("1000 seconds", TimeUnit.MILLISECONDS));
assertEquals(60, parse("1 m", TimeUnit.SECONDS));
assertEquals(600, parse("10 min", TimeUnit.SECONDS));
assertEquals(6000, parse("100 minutes", TimeUnit.SECONDS));
assertEquals(60000, parse("1000 minutes", TimeUnit.SECONDS));
assertEquals(60, parse("1 h", TimeUnit.MINUTES));
assertEquals(600, parse("10 hr", TimeUnit.MINUTES));
assertEquals(6000, parse("100 hour", TimeUnit.MINUTES));
assertEquals(60000, parse("1000 hours", TimeUnit.MINUTES));
assertEquals(24, parse("1 d", TimeUnit.HOURS));
assertEquals(240, parse("10 day", TimeUnit.HOURS));
assertEquals(2400, parse("100 days", TimeUnit.HOURS));
}
@Test
@Timeout(value = 1)
public void testRoundUp() {
final long nanosPerSecond = 1_000_000_000L;
final TimeDuration oneSecond = TimeDuration.valueOf(1, TimeUnit.SECONDS);
assertEquals(-nanosPerSecond, oneSecond.roundUpNanos(-nanosPerSecond - 1));
assertEquals(-nanosPerSecond, oneSecond.roundUpNanos(-nanosPerSecond));
assertEquals(0, oneSecond.roundUpNanos(-nanosPerSecond + 1));
assertEquals(0, oneSecond.roundUpNanos(-1));
assertEquals(0, oneSecond.roundUpNanos(0));
assertEquals(nanosPerSecond, oneSecond.roundUpNanos(1));
assertEquals(nanosPerSecond, oneSecond.roundUpNanos(nanosPerSecond - 1));
assertEquals(nanosPerSecond, oneSecond.roundUpNanos(nanosPerSecond));
assertEquals(2*nanosPerSecond, oneSecond.roundUpNanos(nanosPerSecond + 1));
}
@Test
@Timeout(value = 1)
public void testTo() {
final TimeDuration oneSecond = TimeDuration.valueOf(1, TimeUnit.SECONDS);
assertTo(1000, "1000ms", oneSecond, TimeUnit.MILLISECONDS);
final TimeDuration nanos = assertTo(1_000_000_000, "1000000000ns", oneSecond, TimeUnit.NANOSECONDS);
assertTo(1000, "1000ms", nanos, TimeUnit.MILLISECONDS);
assertTo(0, "0.0167min", oneSecond, TimeUnit.MINUTES);
assertTo(0, "0.0167min", nanos, TimeUnit.MINUTES);
final TimeDuration millis = TimeDuration.valueOf(1_999, TimeUnit.MILLISECONDS);
assertTo(1, "1.9990s", millis, TimeUnit.SECONDS);
assertTo(0, "0.0333min", millis, TimeUnit.MINUTES);
}
static TimeDuration assertTo(long expected, String expectedString, TimeDuration timeDuration, TimeUnit toUnit) {
final TimeDuration computed = timeDuration.to(toUnit);
assertEquals(expected, computed.getDuration());
assertEquals(toUnit, computed.getUnit());
assertEquals(expectedString, timeDuration.toString(toUnit, 4));
return computed;
}
@Test
@Timeout(value = 1)
public void testAddAndSubtract() {
final TimeDuration oneSecond = TimeDuration.valueOf(1, TimeUnit.SECONDS);
final TimeDuration tenSecond = TimeDuration.valueOf(10, TimeUnit.SECONDS);
{
final TimeDuration d = oneSecond.subtract(oneSecond);
assertEquals(0, d.getDuration());
assertEquals(TimeUnit.SECONDS, d.getUnit());
final TimeDuration sum = d.add(oneSecond);
assertEquals(1, sum.getDuration());
assertEquals(TimeUnit.SECONDS, sum.getUnit());
}
{
final TimeDuration d = tenSecond.subtract(oneSecond);
assertEquals(9, d.getDuration());
assertEquals(TimeUnit.SECONDS, d.getUnit());
final TimeDuration sum = d.add(oneSecond);
assertEquals(10, sum.getDuration());
assertEquals(TimeUnit.SECONDS, sum.getUnit());
}
{
final TimeDuration d = oneSecond.subtract(tenSecond);
assertEquals(-9, d.getDuration());
assertEquals(TimeUnit.SECONDS, d.getUnit());
final TimeDuration sum = d.add(tenSecond);
assertEquals(1, sum.getDuration());
assertEquals(TimeUnit.SECONDS, sum.getUnit());
}
final TimeDuration oneMS = TimeDuration.valueOf(1, TimeUnit.MILLISECONDS);
{
final TimeDuration d = oneSecond.subtract(oneMS);
assertEquals(999, d.getDuration());
assertEquals(TimeUnit.MILLISECONDS, d.getUnit());
final TimeDuration sum = d.add(oneSecond);
assertEquals(1999, sum.getDuration());
assertEquals(TimeUnit.MILLISECONDS, sum.getUnit());
}
{
final TimeDuration d = oneMS.subtract(oneSecond);
assertEquals(-999, d.getDuration());
assertEquals(TimeUnit.MILLISECONDS, d.getUnit());
final TimeDuration sum = d.add(oneSecond);
assertEquals(1, sum.getDuration());
assertEquals(TimeUnit.MILLISECONDS, sum.getUnit());
}
}
@Test
@Timeout(value = 1)
public void testNegate() {
assertNegate(0);
assertNegate(1);
assertNegate(-1);
assertNegate(Long.MAX_VALUE);
Assertions.assertEquals(
TimeDuration.valueOf(Long.MAX_VALUE, TimeUnit.SECONDS),
TimeDuration.valueOf(Long.MIN_VALUE, TimeUnit.SECONDS).negate());
}
private static void assertNegate(long n) {
Assertions.assertEquals(
TimeDuration.valueOf(-n, TimeUnit.SECONDS),
TimeDuration.valueOf(n, TimeUnit.SECONDS).negate());
Assertions.assertEquals(
TimeDuration.valueOf(n, TimeUnit.SECONDS),
TimeDuration.valueOf(-n, TimeUnit.SECONDS).negate());
}
@Test
@Timeout(value = 1)
public void testMultiply() {
assertMultiply(0, TimeDuration.ONE_SECOND, TimeDuration.valueOf(0, TimeUnit.SECONDS));
assertMultiply(0.001, TimeDuration.ONE_SECOND, TimeDuration.ONE_MILLISECOND);
assertMultiply(0.001/60, TimeDuration.ONE_MINUTE, TimeDuration.ONE_MILLISECOND);
assertMultiply(100,
TimeDuration.valueOf(Long.MAX_VALUE / 10, TimeUnit.NANOSECONDS),
TimeDuration.valueOf(Long.MAX_VALUE / 100, TimeUnit.MICROSECONDS)
);
assertMultiply(1E-30,
TimeDuration.valueOf(1_000_000_000_000_000_000L, TimeUnit.DAYS),
TimeDuration.valueOf(86, TimeUnit.NANOSECONDS)
);
}
private static void assertMultiply(double multiplier, TimeDuration t, TimeDuration expected) {
assertMultiply(t , multiplier, expected);
assertMultiply(t.negate(), -multiplier, expected);
assertMultiply(t.negate(), multiplier, expected.negate());
assertMultiply(t , -multiplier, expected.negate());
}
private static void assertMultiply(TimeDuration t, double multiplier, TimeDuration expected) {
final TimeDuration computed = t.multiply(multiplier);
TimeDuration.LOG.info("assertMultiply: {} x {} = {} ?= {}\n\n", t, multiplier, computed, expected);
Assertions.assertEquals(expected.getUnit(), computed.getUnit());
final long d = Math.abs(computed.getDuration() - expected.getDuration());
Assertions.assertTrue(d <= Math.abs(expected.getDuration()) * TimeDuration.ERROR_THRESHOLD);
}
@Test
@Timeout(value = 1)
public void testHigherLower() {
final TimeUnit[] units = {TimeUnit.NANOSECONDS, TimeUnit.MICROSECONDS, TimeUnit.MILLISECONDS,
TimeUnit.SECONDS, TimeUnit.MINUTES, TimeUnit.HOURS, TimeUnit.DAYS};
for(int i = 1; i < units.length; i++) {
assertHigherLower(units[i-1], units[i]);
}
Assertions.assertSame(TimeUnit.NANOSECONDS, TimeDuration.lowerUnit(TimeUnit.NANOSECONDS));
Assertions.assertSame(TimeUnit.DAYS, TimeDuration.higherUnit(TimeUnit.DAYS));
}
@Test
@Timeout(value = 1)
public void testCompareTo() {
assertTimeDurationCompareTo(TimeDuration.ONE_MINUTE, TimeDuration.ONE_SECOND);
final TimeDuration fifteenSecond = TimeDuration.valueOf(15, TimeUnit.SECONDS);
assertTimeDurationCompareTo(TimeDuration.ONE_DAY, fifteenSecond);
assertTimeDurationEquals(TimeDuration.ONE_MINUTE, fifteenSecond.multiply(4));
assertTimeDurationEquals(TimeDuration.ONE_DAY, TimeDuration.ONE_MINUTE.multiply(60).multiply(24));
}
static void assertTimeDurationEquals(TimeDuration left, TimeDuration right) {
assertEquals(0, left.compareTo(right));
assertEquals(0, right.compareTo(left));
assertEquals(left, right);
assertEquals(right, left);
}
static void assertTimeDurationCompareTo(TimeDuration larger, TimeDuration smaller) {
assertTrue(smaller.compareTo(larger) < 0);
assertTrue(larger.compareTo(smaller) > 0);
assertEquals(smaller, TimeDuration.min(smaller, larger));
assertEquals(smaller, TimeDuration.min(larger, smaller));
assertEquals(larger, TimeDuration.max(smaller, larger));
assertEquals(larger, TimeDuration.max(larger, smaller));
final TimeDuration diff = larger.add(smaller.negate());
assertTrue(diff.isPositive());
assertTrue(diff.isNonNegative());
assertFalse(diff.isNegative());
assertFalse(diff.isNonPositive());
}
private static void assertHigherLower(TimeUnit lower, TimeUnit higher) {
Assertions.assertSame(lower, TimeDuration.lowerUnit(higher));
Assertions.assertSame(higher, TimeDuration.higherUnit(lower));
}
}