17dd252788645e940eada959bdde927426e2531c9Paul Duffin/* 27dd252788645e940eada959bdde927426e2531c9Paul Duffin * Copyright (C) 2008 The Guava Authors 37dd252788645e940eada959bdde927426e2531c9Paul Duffin * 47dd252788645e940eada959bdde927426e2531c9Paul Duffin * Licensed under the Apache License, Version 2.0 (the "License"); 57dd252788645e940eada959bdde927426e2531c9Paul Duffin * you may not use this file except in compliance with the License. 67dd252788645e940eada959bdde927426e2531c9Paul Duffin * You may obtain a copy of the License at 77dd252788645e940eada959bdde927426e2531c9Paul Duffin * 87dd252788645e940eada959bdde927426e2531c9Paul Duffin * http://www.apache.org/licenses/LICENSE-2.0 97dd252788645e940eada959bdde927426e2531c9Paul Duffin * 107dd252788645e940eada959bdde927426e2531c9Paul Duffin * Unless required by applicable law or agreed to in writing, software 117dd252788645e940eada959bdde927426e2531c9Paul Duffin * distributed under the License is distributed on an "AS IS" BASIS, 127dd252788645e940eada959bdde927426e2531c9Paul Duffin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 137dd252788645e940eada959bdde927426e2531c9Paul Duffin * See the License for the specific language governing permissions and 147dd252788645e940eada959bdde927426e2531c9Paul Duffin * limitations under the License. 157dd252788645e940eada959bdde927426e2531c9Paul Duffin */ 167dd252788645e940eada959bdde927426e2531c9Paul Duffin 177dd252788645e940eada959bdde927426e2531c9Paul Duffinpackage com.google.common.testing; 187dd252788645e940eada959bdde927426e2531c9Paul Duffin 197dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.annotations.GwtCompatible; 207dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.annotations.GwtIncompatible; 217dd252788645e940eada959bdde927426e2531c9Paul Duffin 227dd252788645e940eada959bdde927426e2531c9Paul Duffinimport junit.framework.TestCase; 237dd252788645e940eada959bdde927426e2531c9Paul Duffin 247dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.util.EnumSet; 257dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.util.concurrent.Callable; 267dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.util.concurrent.CountDownLatch; 277dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.util.concurrent.ExecutorService; 287dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.util.concurrent.Executors; 297dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.util.concurrent.TimeUnit; 307dd252788645e940eada959bdde927426e2531c9Paul Duffin 317dd252788645e940eada959bdde927426e2531c9Paul Duffin/** 327dd252788645e940eada959bdde927426e2531c9Paul Duffin * Unit test for {@link FakeTicker}. 337dd252788645e940eada959bdde927426e2531c9Paul Duffin * 347dd252788645e940eada959bdde927426e2531c9Paul Duffin * @author Jige Yu 357dd252788645e940eada959bdde927426e2531c9Paul Duffin */ 367dd252788645e940eada959bdde927426e2531c9Paul Duffin@GwtCompatible(emulated = true) 377dd252788645e940eada959bdde927426e2531c9Paul Duffinpublic class FakeTickerTest extends TestCase { 387dd252788645e940eada959bdde927426e2531c9Paul Duffin 397dd252788645e940eada959bdde927426e2531c9Paul Duffin @GwtIncompatible("NullPointerTester") 407dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testNullPointerExceptions() { 417dd252788645e940eada959bdde927426e2531c9Paul Duffin NullPointerTester tester = new NullPointerTester(); 427dd252788645e940eada959bdde927426e2531c9Paul Duffin tester.testAllPublicInstanceMethods(new FakeTicker()); 437dd252788645e940eada959bdde927426e2531c9Paul Duffin } 447dd252788645e940eada959bdde927426e2531c9Paul Duffin 457dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testAdvance() { 467dd252788645e940eada959bdde927426e2531c9Paul Duffin FakeTicker ticker = new FakeTicker(); 477dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals(0, ticker.read()); 487dd252788645e940eada959bdde927426e2531c9Paul Duffin assertSame(ticker, ticker.advance(10)); 497dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals(10, ticker.read()); 507dd252788645e940eada959bdde927426e2531c9Paul Duffin ticker.advance(1, TimeUnit.MILLISECONDS); 517dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals(1000010L, ticker.read()); 527dd252788645e940eada959bdde927426e2531c9Paul Duffin } 537dd252788645e940eada959bdde927426e2531c9Paul Duffin 547dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testAutoIncrementStep_returnsSameInstance() { 557dd252788645e940eada959bdde927426e2531c9Paul Duffin FakeTicker ticker = new FakeTicker(); 567dd252788645e940eada959bdde927426e2531c9Paul Duffin assertSame(ticker, ticker.setAutoIncrementStep(10, TimeUnit.NANOSECONDS)); 577dd252788645e940eada959bdde927426e2531c9Paul Duffin } 587dd252788645e940eada959bdde927426e2531c9Paul Duffin 597dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testAutoIncrementStep_nanos() { 607dd252788645e940eada959bdde927426e2531c9Paul Duffin FakeTicker ticker = new FakeTicker().setAutoIncrementStep(10, TimeUnit.NANOSECONDS); 617dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals(0, ticker.read()); 627dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals(10, ticker.read()); 637dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals(20, ticker.read()); 647dd252788645e940eada959bdde927426e2531c9Paul Duffin } 657dd252788645e940eada959bdde927426e2531c9Paul Duffin 667dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testAutoIncrementStep_millis() { 677dd252788645e940eada959bdde927426e2531c9Paul Duffin FakeTicker ticker = new FakeTicker().setAutoIncrementStep(1, TimeUnit.MILLISECONDS); 687dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals(0, ticker.read()); 697dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals(1000000, ticker.read()); 707dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals(2000000, ticker.read()); 717dd252788645e940eada959bdde927426e2531c9Paul Duffin } 727dd252788645e940eada959bdde927426e2531c9Paul Duffin 737dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testAutoIncrementStep_seconds() { 747dd252788645e940eada959bdde927426e2531c9Paul Duffin FakeTicker ticker = new FakeTicker().setAutoIncrementStep(3, TimeUnit.SECONDS); 757dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals(0, ticker.read()); 767dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals(3000000000L, ticker.read()); 777dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals(6000000000L, ticker.read()); 787dd252788645e940eada959bdde927426e2531c9Paul Duffin } 797dd252788645e940eada959bdde927426e2531c9Paul Duffin 807dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testAutoIncrementStep_resetToZero() { 817dd252788645e940eada959bdde927426e2531c9Paul Duffin FakeTicker ticker = new FakeTicker().setAutoIncrementStep(10, TimeUnit.NANOSECONDS); 827dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals(0, ticker.read()); 837dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals(10, ticker.read()); 847dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals(20, ticker.read()); 857dd252788645e940eada959bdde927426e2531c9Paul Duffin 867dd252788645e940eada959bdde927426e2531c9Paul Duffin for (TimeUnit timeUnit : EnumSet.allOf(TimeUnit.class)) { 877dd252788645e940eada959bdde927426e2531c9Paul Duffin ticker.setAutoIncrementStep(0, timeUnit); 887dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals( 897dd252788645e940eada959bdde927426e2531c9Paul Duffin "Expected no auto-increment when setting autoIncrementStep to 0 " + timeUnit, 907dd252788645e940eada959bdde927426e2531c9Paul Duffin 30, ticker.read()); 917dd252788645e940eada959bdde927426e2531c9Paul Duffin } 927dd252788645e940eada959bdde927426e2531c9Paul Duffin } 937dd252788645e940eada959bdde927426e2531c9Paul Duffin 947dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testAutoIncrement_negative() { 957dd252788645e940eada959bdde927426e2531c9Paul Duffin FakeTicker ticker = new FakeTicker(); 967dd252788645e940eada959bdde927426e2531c9Paul Duffin try { 977dd252788645e940eada959bdde927426e2531c9Paul Duffin ticker.setAutoIncrementStep(-1, TimeUnit.NANOSECONDS); 987dd252788645e940eada959bdde927426e2531c9Paul Duffin fail("Expected IllegalArgumentException"); 997dd252788645e940eada959bdde927426e2531c9Paul Duffin } catch (IllegalArgumentException expected) { 1007dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1017dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1027dd252788645e940eada959bdde927426e2531c9Paul Duffin 1037dd252788645e940eada959bdde927426e2531c9Paul Duffin @GwtIncompatible("concurrency") 1047dd252788645e940eada959bdde927426e2531c9Paul Duffin 1057dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testConcurrentAdvance() throws Exception { 1067dd252788645e940eada959bdde927426e2531c9Paul Duffin final FakeTicker ticker = new FakeTicker(); 1077dd252788645e940eada959bdde927426e2531c9Paul Duffin 1087dd252788645e940eada959bdde927426e2531c9Paul Duffin int numberOfThreads = 64; 1097dd252788645e940eada959bdde927426e2531c9Paul Duffin runConcurrentTest(numberOfThreads, 1107dd252788645e940eada959bdde927426e2531c9Paul Duffin new Callable<Void>() { 1117dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 1127dd252788645e940eada959bdde927426e2531c9Paul Duffin public Void call() throws Exception { 1137dd252788645e940eada959bdde927426e2531c9Paul Duffin // adds two nanoseconds to the ticker 1147dd252788645e940eada959bdde927426e2531c9Paul Duffin ticker.advance(1L); 1157dd252788645e940eada959bdde927426e2531c9Paul Duffin Thread.sleep(10); 1167dd252788645e940eada959bdde927426e2531c9Paul Duffin ticker.advance(1L); 1177dd252788645e940eada959bdde927426e2531c9Paul Duffin return null; 1187dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1197dd252788645e940eada959bdde927426e2531c9Paul Duffin }); 1207dd252788645e940eada959bdde927426e2531c9Paul Duffin 1217dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals(numberOfThreads * 2, ticker.read()); 1227dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1237dd252788645e940eada959bdde927426e2531c9Paul Duffin 1247dd252788645e940eada959bdde927426e2531c9Paul Duffin @GwtIncompatible("concurrency") 1257dd252788645e940eada959bdde927426e2531c9Paul Duffin 1267dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testConcurrentAutoIncrementStep() throws Exception { 1277dd252788645e940eada959bdde927426e2531c9Paul Duffin int incrementByNanos = 3; 1287dd252788645e940eada959bdde927426e2531c9Paul Duffin final FakeTicker ticker = 1297dd252788645e940eada959bdde927426e2531c9Paul Duffin new FakeTicker().setAutoIncrementStep(incrementByNanos, TimeUnit.NANOSECONDS); 1307dd252788645e940eada959bdde927426e2531c9Paul Duffin 1317dd252788645e940eada959bdde927426e2531c9Paul Duffin int numberOfThreads = 64; 1327dd252788645e940eada959bdde927426e2531c9Paul Duffin runConcurrentTest(numberOfThreads, 1337dd252788645e940eada959bdde927426e2531c9Paul Duffin new Callable<Void>() { 1347dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 1357dd252788645e940eada959bdde927426e2531c9Paul Duffin public Void call() throws Exception { 1367dd252788645e940eada959bdde927426e2531c9Paul Duffin ticker.read(); 1377dd252788645e940eada959bdde927426e2531c9Paul Duffin return null; 1387dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1397dd252788645e940eada959bdde927426e2531c9Paul Duffin }); 1407dd252788645e940eada959bdde927426e2531c9Paul Duffin 1417dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals(incrementByNanos * numberOfThreads, ticker.read()); 1427dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1437dd252788645e940eada959bdde927426e2531c9Paul Duffin 1447dd252788645e940eada959bdde927426e2531c9Paul Duffin /** 1457dd252788645e940eada959bdde927426e2531c9Paul Duffin * Runs {@code callable} concurrently {@code numberOfThreads} times. 1467dd252788645e940eada959bdde927426e2531c9Paul Duffin */ 1477dd252788645e940eada959bdde927426e2531c9Paul Duffin @GwtIncompatible("concurrency") 1487dd252788645e940eada959bdde927426e2531c9Paul Duffin private void runConcurrentTest(int numberOfThreads, final Callable<Void> callable) 1497dd252788645e940eada959bdde927426e2531c9Paul Duffin throws Exception { 1507dd252788645e940eada959bdde927426e2531c9Paul Duffin ExecutorService executorService = Executors.newFixedThreadPool(numberOfThreads); 1517dd252788645e940eada959bdde927426e2531c9Paul Duffin final CountDownLatch startLatch = new CountDownLatch(numberOfThreads); 1527dd252788645e940eada959bdde927426e2531c9Paul Duffin final CountDownLatch doneLatch = new CountDownLatch(numberOfThreads); 1537dd252788645e940eada959bdde927426e2531c9Paul Duffin for (int i = numberOfThreads; i > 0; i--) { 1547dd252788645e940eada959bdde927426e2531c9Paul Duffin executorService.submit(new Callable<Void>() { 1557dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 1567dd252788645e940eada959bdde927426e2531c9Paul Duffin public Void call() throws Exception { 1577dd252788645e940eada959bdde927426e2531c9Paul Duffin startLatch.countDown(); 1587dd252788645e940eada959bdde927426e2531c9Paul Duffin startLatch.await(); 1597dd252788645e940eada959bdde927426e2531c9Paul Duffin callable.call(); 1607dd252788645e940eada959bdde927426e2531c9Paul Duffin doneLatch.countDown(); 1617dd252788645e940eada959bdde927426e2531c9Paul Duffin return null; 1627dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1637dd252788645e940eada959bdde927426e2531c9Paul Duffin }); 1647dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1657dd252788645e940eada959bdde927426e2531c9Paul Duffin doneLatch.await(); 1667dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1677dd252788645e940eada959bdde927426e2531c9Paul Duffin} 168