Home | History | Annotate | Download | only in testing
      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 
     22 import junit.framework.TestCase;
     23 
     24 import java.util.EnumSet;
     25 import java.util.concurrent.Callable;
     26 import java.util.concurrent.CountDownLatch;
     27 import java.util.concurrent.ExecutorService;
     28 import java.util.concurrent.Executors;
     29 import java.util.concurrent.TimeUnit;
     30 
     31 /**
     32  * Unit test for {@link FakeTicker}.
     33  *
     34  * @author Jige Yu
     35  */
     36 @GwtCompatible(emulated = true)
     37 public class FakeTickerTest extends TestCase {
     38 
     39   @GwtIncompatible("NullPointerTester")
     40   public void testNullPointerExceptions() {
     41     NullPointerTester tester = new NullPointerTester();
     42     tester.testAllPublicInstanceMethods(new FakeTicker());
     43   }
     44 
     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   }
     53 
     54   public void testAutoIncrementStep_returnsSameInstance() {
     55     FakeTicker ticker = new FakeTicker();
     56     assertSame(ticker, ticker.setAutoIncrementStep(10, TimeUnit.NANOSECONDS));
     57   }
     58 
     59   public void testAutoIncrementStep_nanos() {
     60     FakeTicker ticker = new FakeTicker().setAutoIncrementStep(10, TimeUnit.NANOSECONDS);
     61     assertEquals(0, ticker.read());
     62     assertEquals(10, ticker.read());
     63     assertEquals(20, ticker.read());
     64   }
     65 
     66   public void testAutoIncrementStep_millis() {
     67     FakeTicker ticker = new FakeTicker().setAutoIncrementStep(1, TimeUnit.MILLISECONDS);
     68     assertEquals(0, ticker.read());
     69     assertEquals(1000000, ticker.read());
     70     assertEquals(2000000, ticker.read());
     71   }
     72 
     73   public void testAutoIncrementStep_seconds() {
     74     FakeTicker ticker = new FakeTicker().setAutoIncrementStep(3, TimeUnit.SECONDS);
     75     assertEquals(0, ticker.read());
     76     assertEquals(3000000000L, ticker.read());
     77     assertEquals(6000000000L, ticker.read());
     78   }
     79 
     80   public void testAutoIncrementStep_resetToZero() {
     81     FakeTicker ticker = new FakeTicker().setAutoIncrementStep(10, TimeUnit.NANOSECONDS);
     82     assertEquals(0, ticker.read());
     83     assertEquals(10, ticker.read());
     84     assertEquals(20, ticker.read());
     85 
     86     for (TimeUnit timeUnit : EnumSet.allOf(TimeUnit.class)) {
     87       ticker.setAutoIncrementStep(0, timeUnit);
     88       assertEquals(
     89           "Expected no auto-increment when setting autoIncrementStep to 0 " + timeUnit,
     90           30, ticker.read());
     91     }
     92   }
     93 
     94   public void testAutoIncrement_negative() {
     95     FakeTicker ticker = new FakeTicker();
     96     try {
     97       ticker.setAutoIncrementStep(-1, TimeUnit.NANOSECONDS);
     98       fail("Expected IllegalArgumentException");
     99     } catch (IllegalArgumentException expected) {
    100     }
    101   }
    102 
    103   @GwtIncompatible("concurrency")
    104 
    105   public void testConcurrentAdvance() throws Exception {
    106     final FakeTicker ticker = new FakeTicker();
    107 
    108     int numberOfThreads = 64;
    109     runConcurrentTest(numberOfThreads,
    110         new Callable<Void>() {
    111           @Override
    112           public Void call() throws Exception {
    113             // adds two nanoseconds to the ticker
    114             ticker.advance(1L);
    115             Thread.sleep(10);
    116             ticker.advance(1L);
    117             return null;
    118           }
    119         });
    120 
    121     assertEquals(numberOfThreads * 2, ticker.read());
    122   }
    123 
    124   @GwtIncompatible("concurrency")
    125 
    126   public void testConcurrentAutoIncrementStep() throws Exception {
    127     int incrementByNanos = 3;
    128     final FakeTicker ticker =
    129         new FakeTicker().setAutoIncrementStep(incrementByNanos, TimeUnit.NANOSECONDS);
    130 
    131     int numberOfThreads = 64;
    132     runConcurrentTest(numberOfThreads,
    133         new Callable<Void>() {
    134           @Override
    135           public Void call() throws Exception {
    136             ticker.read();
    137             return null;
    138           }
    139         });
    140 
    141     assertEquals(incrementByNanos * numberOfThreads, ticker.read());
    142   }
    143 
    144   /**
    145    * Runs {@code callable} concurrently {@code numberOfThreads} times.
    146    */
    147   @GwtIncompatible("concurrency")
    148   private void runConcurrentTest(int numberOfThreads, final Callable<Void> callable)
    149       throws Exception {
    150     ExecutorService executorService = Executors.newFixedThreadPool(numberOfThreads);
    151     final CountDownLatch startLatch = new CountDownLatch(numberOfThreads);
    152     final CountDownLatch doneLatch = new CountDownLatch(numberOfThreads);
    153     for (int i = numberOfThreads; i > 0; i--) {
    154       executorService.submit(new Callable<Void>() {
    155         @Override
    156         public Void call() throws Exception {
    157           startLatch.countDown();
    158           startLatch.await();
    159           callable.call();
    160           doneLatch.countDown();
    161           return null;
    162         }
    163       });
    164     }
    165     doneLatch.await();
    166   }
    167 }
    168