blob: a92cd4926f06b092bee3f3d1942859b42a902c6c [file] [log] [blame]
/*
* Copyright 2016 The gRPC Authors
*
* 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 io.grpc.internal;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import com.google.common.base.Stopwatch;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
/** Unit tests for {@link FakeClock}. */
@RunWith(JUnit4.class)
public class FakeClockTest {
@Test
public void testScheduledExecutorService_sameInstance() {
FakeClock fakeClock = new FakeClock();
ScheduledExecutorService scheduledExecutorService1 = fakeClock.getScheduledExecutorService();
ScheduledExecutorService scheduledExecutorService2 = fakeClock.getScheduledExecutorService();
assertTrue(scheduledExecutorService1 == scheduledExecutorService2);
}
@Test
public void testScheduledExecutorService_isDone() {
FakeClock fakeClock = new FakeClock();
ScheduledFuture<?> future = fakeClock.getScheduledExecutorService()
.schedule(newRunnable(), 100L, TimeUnit.NANOSECONDS);
fakeClock.forwardNanos(99L);
assertFalse(future.isDone());
fakeClock.forwardNanos(2L);
assertTrue(future.isDone());
}
@Test
public void testScheduledExecutorService_cancel() {
FakeClock fakeClock = new FakeClock();
ScheduledFuture<?> future = fakeClock.getScheduledExecutorService()
.schedule(newRunnable(), 100L, TimeUnit.NANOSECONDS);
fakeClock.forwardNanos(99L);
future.cancel(false);
fakeClock.forwardNanos(2);
assertTrue(future.isCancelled());
}
@Test
public void testScheduledExecutorService_getDelay() {
FakeClock fakeClock = new FakeClock();
ScheduledFuture<?> future = fakeClock.getScheduledExecutorService()
.schedule(newRunnable(), 100L, TimeUnit.NANOSECONDS);
fakeClock.forwardNanos(90L);
assertEquals(10L, future.getDelay(TimeUnit.NANOSECONDS));
}
@Test
public void testScheduledExecutorService_result() {
FakeClock fakeClock = new FakeClock();
final boolean[] result = new boolean[]{false};
ScheduledFuture<?> unused = fakeClock.getScheduledExecutorService().schedule(
new Runnable() {
@Override
public void run() {
result[0] = true;
}
},
100L,
TimeUnit.NANOSECONDS);
fakeClock.forwardNanos(100L);
assertTrue(result[0]);
}
@Test
public void testStopWatch() {
FakeClock fakeClock = new FakeClock();
Stopwatch stopwatch = fakeClock.getStopwatchSupplier().get();
long expectedElapsedNanos = 0L;
stopwatch.start();
fakeClock.forwardNanos(100L);
expectedElapsedNanos += 100L;
assertEquals(expectedElapsedNanos, stopwatch.elapsed(TimeUnit.NANOSECONDS));
fakeClock.forwardTime(10L, TimeUnit.MINUTES);
expectedElapsedNanos += TimeUnit.MINUTES.toNanos(10L);
assertEquals(expectedElapsedNanos, stopwatch.elapsed(TimeUnit.NANOSECONDS));
stopwatch.stop();
fakeClock.forwardNanos(1000L);
assertEquals(expectedElapsedNanos, stopwatch.elapsed(TimeUnit.NANOSECONDS));
stopwatch.reset();
expectedElapsedNanos = 0L;
assertEquals(expectedElapsedNanos, stopwatch.elapsed(TimeUnit.NANOSECONDS));
}
@Test
@SuppressWarnings("FutureReturnValueIgnored")
public void testPendingAndDueTasks() {
FakeClock fakeClock = new FakeClock();
ScheduledExecutorService scheduledExecutorService = fakeClock.getScheduledExecutorService();
scheduledExecutorService.schedule(newRunnable(), 200L, TimeUnit.NANOSECONDS);
scheduledExecutorService.execute(newRunnable());
scheduledExecutorService.schedule(newRunnable(), 0L, TimeUnit.NANOSECONDS);
scheduledExecutorService.schedule(newRunnable(), 80L, TimeUnit.NANOSECONDS);
scheduledExecutorService.schedule(newRunnable(), 90L, TimeUnit.NANOSECONDS);
scheduledExecutorService.schedule(newRunnable(), 100L, TimeUnit.NANOSECONDS);
scheduledExecutorService.schedule(newRunnable(), 110L, TimeUnit.NANOSECONDS);
scheduledExecutorService.schedule(newRunnable(), 120L, TimeUnit.NANOSECONDS);
assertEquals(8, fakeClock.numPendingTasks());
assertEquals(2, fakeClock.getDueTasks().size());
fakeClock.runDueTasks();
assertEquals(6, fakeClock.numPendingTasks());
assertEquals(0, fakeClock.getDueTasks().size());
fakeClock.forwardNanos(90L);
assertEquals(4, fakeClock.numPendingTasks());
assertEquals(0, fakeClock.getDueTasks().size());
fakeClock.forwardNanos(20L);
assertEquals(2, fakeClock.numPendingTasks());
assertEquals(0, fakeClock.getDueTasks().size());
}
@Test
public void testTaskFilter() {
FakeClock fakeClock = new FakeClock();
ScheduledExecutorService scheduledExecutorService = fakeClock.getScheduledExecutorService();
final AtomicBoolean selectedDone = new AtomicBoolean();
final AtomicBoolean ignoredDone = new AtomicBoolean();
final Runnable selectedRunnable = new Runnable() {
@Override
public void run() {
selectedDone.set(true);
}
};
Runnable ignoredRunnable = new Runnable() {
@Override
public void run() {
ignoredDone.set(true);
}
};
FakeClock.TaskFilter filter = new FakeClock.TaskFilter() {
@Override
public boolean shouldAccept(Runnable runnable) {
return runnable == selectedRunnable;
}
};
scheduledExecutorService.execute(selectedRunnable);
scheduledExecutorService.execute(ignoredRunnable);
assertEquals(2, fakeClock.numPendingTasks());
assertEquals(1, fakeClock.numPendingTasks(filter));
assertEquals(2, fakeClock.getPendingTasks().size());
assertEquals(1, fakeClock.getPendingTasks(filter).size());
assertSame(selectedRunnable, fakeClock.getPendingTasks(filter).iterator().next().command);
assertEquals(2, fakeClock.runDueTasks());
assertTrue(selectedDone.get());
assertTrue(ignoredDone.get());
}
private Runnable newRunnable() {
return new Runnable() {
@Override
public void run() {
}
};
}
}