1 /* 2 * Copyright (C) 2008 The Guava Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.common.testing; 18 19 import com.google.common.annotations.GwtCompatible; 20 import com.google.common.annotations.GwtIncompatible; 21 import java.util.EnumSet; 22 import java.util.concurrent.Callable; 23 import java.util.concurrent.CountDownLatch; 24 import java.util.concurrent.ExecutorService; 25 import java.util.concurrent.Executors; 26 import java.util.concurrent.Future; 27 import java.util.concurrent.TimeUnit; 28 import junit.framework.TestCase; 29 30 /** 31 * Unit test for {@link FakeTicker}. 32 * 33 * @author Jige Yu 34 */ 35 @GwtCompatible(emulated = true) 36 public class FakeTickerTest extends TestCase { 37 38 @GwtIncompatible // NullPointerTester testNullPointerExceptions()39 public void testNullPointerExceptions() { 40 NullPointerTester tester = new NullPointerTester(); 41 tester.testAllPublicInstanceMethods(new FakeTicker()); 42 } 43 44 @GwtIncompatible // java.time.Duration testAdvance()45 public void testAdvance() { 46 FakeTicker ticker = new FakeTicker(); 47 assertEquals(0, ticker.read()); 48 assertSame(ticker, ticker.advance(10)); 49 assertEquals(10, ticker.read()); 50 ticker.advance(1, TimeUnit.MILLISECONDS); 51 assertEquals(1000010L, ticker.read()); 52 ticker.advance(java.time.Duration.ofMillis(1)); 53 assertEquals(2000010L, ticker.read()); 54 } 55 testAutoIncrementStep_returnsSameInstance()56 public void testAutoIncrementStep_returnsSameInstance() { 57 FakeTicker ticker = new FakeTicker(); 58 assertSame(ticker, ticker.setAutoIncrementStep(10, TimeUnit.NANOSECONDS)); 59 } 60 testAutoIncrementStep_nanos()61 public void testAutoIncrementStep_nanos() { 62 FakeTicker ticker = new FakeTicker().setAutoIncrementStep(10, TimeUnit.NANOSECONDS); 63 assertEquals(0, ticker.read()); 64 assertEquals(10, ticker.read()); 65 assertEquals(20, ticker.read()); 66 } 67 testAutoIncrementStep_millis()68 public void testAutoIncrementStep_millis() { 69 FakeTicker ticker = new FakeTicker().setAutoIncrementStep(1, TimeUnit.MILLISECONDS); 70 assertEquals(0, ticker.read()); 71 assertEquals(1000000, ticker.read()); 72 assertEquals(2000000, ticker.read()); 73 } 74 testAutoIncrementStep_seconds()75 public void testAutoIncrementStep_seconds() { 76 FakeTicker ticker = new FakeTicker().setAutoIncrementStep(3, TimeUnit.SECONDS); 77 assertEquals(0, ticker.read()); 78 assertEquals(3000000000L, ticker.read()); 79 assertEquals(6000000000L, ticker.read()); 80 } 81 82 @GwtIncompatible // java.time.Duration testAutoIncrementStep_duration()83 public void testAutoIncrementStep_duration() { 84 FakeTicker ticker = new FakeTicker().setAutoIncrementStep(java.time.Duration.ofMillis(1)); 85 assertEquals(0, ticker.read()); 86 assertEquals(1000000, ticker.read()); 87 assertEquals(2000000, ticker.read()); 88 } 89 testAutoIncrementStep_resetToZero()90 public void testAutoIncrementStep_resetToZero() { 91 FakeTicker ticker = new FakeTicker().setAutoIncrementStep(10, TimeUnit.NANOSECONDS); 92 assertEquals(0, ticker.read()); 93 assertEquals(10, ticker.read()); 94 assertEquals(20, ticker.read()); 95 96 for (TimeUnit timeUnit : EnumSet.allOf(TimeUnit.class)) { 97 ticker.setAutoIncrementStep(0, timeUnit); 98 assertEquals( 99 "Expected no auto-increment when setting autoIncrementStep to 0 " + timeUnit, 100 30, 101 ticker.read()); 102 } 103 } 104 testAutoIncrement_negative()105 public void testAutoIncrement_negative() { 106 FakeTicker ticker = new FakeTicker(); 107 try { 108 ticker.setAutoIncrementStep(-1, TimeUnit.NANOSECONDS); 109 fail("Expected IllegalArgumentException"); 110 } catch (IllegalArgumentException expected) { 111 } 112 } 113 114 @GwtIncompatible // concurrency 115 testConcurrentAdvance()116 public void testConcurrentAdvance() throws Exception { 117 final FakeTicker ticker = new FakeTicker(); 118 119 int numberOfThreads = 64; 120 runConcurrentTest( 121 numberOfThreads, 122 new Callable<Void>() { 123 @Override 124 public Void call() throws Exception { 125 // adds two nanoseconds to the ticker 126 ticker.advance(1L); 127 Thread.sleep(10); 128 ticker.advance(1L); 129 return null; 130 } 131 }); 132 133 assertEquals(numberOfThreads * 2, ticker.read()); 134 } 135 136 @GwtIncompatible // concurrency 137 testConcurrentAutoIncrementStep()138 public void testConcurrentAutoIncrementStep() throws Exception { 139 int incrementByNanos = 3; 140 final FakeTicker ticker = 141 new FakeTicker().setAutoIncrementStep(incrementByNanos, TimeUnit.NANOSECONDS); 142 143 int numberOfThreads = 64; 144 runConcurrentTest( 145 numberOfThreads, 146 new Callable<Void>() { 147 @Override 148 public Void call() throws Exception { 149 ticker.read(); 150 return null; 151 } 152 }); 153 154 assertEquals(incrementByNanos * numberOfThreads, ticker.read()); 155 } 156 157 /** Runs {@code callable} concurrently {@code numberOfThreads} times. */ 158 @GwtIncompatible // concurrency runConcurrentTest(int numberOfThreads, final Callable<Void> callable)159 private void runConcurrentTest(int numberOfThreads, final Callable<Void> callable) 160 throws Exception { 161 ExecutorService executorService = Executors.newFixedThreadPool(numberOfThreads); 162 final CountDownLatch startLatch = new CountDownLatch(numberOfThreads); 163 final CountDownLatch doneLatch = new CountDownLatch(numberOfThreads); 164 for (int i = numberOfThreads; i > 0; i--) { 165 @SuppressWarnings("unused") // https://errorprone.info/bugpattern/FutureReturnValueIgnored 166 Future<?> possiblyIgnoredError = 167 executorService.submit( 168 new Callable<Void>() { 169 @Override 170 public Void call() throws Exception { 171 startLatch.countDown(); 172 startLatch.await(); 173 callable.call(); 174 doneLatch.countDown(); 175 return null; 176 } 177 }); 178 } 179 doneLatch.await(); 180 } 181 } 182