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