alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (AbstractListenableFutureTest.java)

This example Java source code file (AbstractListenableFutureTest.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

abstractlistenablefuturetest, beta, cancellationexception, countdownlatch, exception, executionexception, executorservice, interruptedexception, listenablefuture, override, runnable, should, testcase, threading, threads, throwable

The AbstractListenableFutureTest.java Java example source code

/*
 * Copyright (C) 2007 The Guava 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 com.google.common.util.concurrent.testing;

import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.util.concurrent.ListenableFuture;

import junit.framework.TestCase;

import java.util.concurrent.CancellationException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

/**
 * Abstract test case parent for anything implementing {@link ListenableFuture}.
 * Tests the two get methods and the addListener method.
 *
 * @author Sven Mawson
 * @since 10.0
 */
@Beta
@GwtIncompatible
public abstract class AbstractListenableFutureTest extends TestCase {

  protected CountDownLatch latch;
  protected ListenableFuture<Boolean> future;

  @Override
  protected void setUp() throws Exception {

    // Create a latch and a future that waits on the latch.
    latch = new CountDownLatch(1);
    future = createListenableFuture(Boolean.TRUE, null, latch);
  }

  @Override
  protected void tearDown() throws Exception {

    // Make sure we have no waiting threads.
    latch.countDown();
  }

  /**
   * Constructs a listenable future with a value available after the latch
   * has counted down.
   */
  protected abstract <V> ListenableFuture createListenableFuture(
      V value, Exception except, CountDownLatch waitOn);

  /**
   * Tests that the {@link Future#get()} method blocks until a value is
   * available.
   */
  public void testGetBlocksUntilValueAvailable() throws Throwable {

    assertFalse(future.isDone());
    assertFalse(future.isCancelled());

    final CountDownLatch successLatch = new CountDownLatch(1);
    final Throwable[] badness = new Throwable[1];

    // Wait on the future in a separate thread.
    new Thread(new Runnable() {
      @Override
      public void run() {
        try {
          assertSame(Boolean.TRUE, future.get());
          successLatch.countDown();
        } catch (Throwable t) {
          t.printStackTrace();
          badness[0] = t;
        }
      }}).start();

    // Release the future value.
    latch.countDown();

    assertTrue(successLatch.await(10, TimeUnit.SECONDS));

    if (badness[0] != null) {
      throw badness[0];
    }

    assertTrue(future.isDone());
    assertFalse(future.isCancelled());
  }

  /**
   * Tests that the {@link Future#get(long, TimeUnit)} method times out
   * correctly.
   */
  public void testTimeoutOnGetWorksCorrectly() throws InterruptedException,
      ExecutionException {

    // The task thread waits for the latch, so we expect a timeout here.
    try {
      future.get(20, TimeUnit.MILLISECONDS);
      fail("Should have timed out trying to get the value.");
    } catch (TimeoutException expected) {
      // Expected.
    } finally {
      latch.countDown();
    }
  }

  /**
   * Tests that a canceled future throws a cancellation exception.
   *
   * This method checks the cancel, isCancelled, and isDone methods.
   */
  public void testCanceledFutureThrowsCancellation() throws Exception {

    assertFalse(future.isDone());
    assertFalse(future.isCancelled());

    final CountDownLatch successLatch = new CountDownLatch(1);

    // Run cancellation in a separate thread as an extra thread-safety test.
    new Thread(new Runnable() {
      @Override
      public void run() {
        try {
          future.get();
        } catch (CancellationException expected) {
          successLatch.countDown();
        } catch (Exception ignored) {
          // All other errors are ignored, we expect a cancellation.
        }
      }
    }).start();

    assertFalse(future.isDone());
    assertFalse(future.isCancelled());

    future.cancel(true);

    assertTrue(future.isDone());
    assertTrue(future.isCancelled());

    assertTrue(successLatch.await(200, TimeUnit.MILLISECONDS));

    latch.countDown();
  }

  public void testListenersNotifiedOnError() throws Exception {
    final CountDownLatch successLatch = new CountDownLatch(1);
    final CountDownLatch listenerLatch = new CountDownLatch(1);

    ExecutorService exec = Executors.newCachedThreadPool();

    future.addListener(new Runnable() {
      @Override
      public void run() {
        listenerLatch.countDown();
      }
    }, exec);

    new Thread(new Runnable() {
      @Override
      public void run() {
        try {
          future.get();
        } catch (CancellationException expected) {
          successLatch.countDown();
        } catch (Exception ignored) {
          // No success latch count down.
        }
      }
    }).start();

    future.cancel(true);

    assertTrue(future.isCancelled());
    assertTrue(future.isDone());

    assertTrue(successLatch.await(200, TimeUnit.MILLISECONDS));
    assertTrue(listenerLatch.await(200, TimeUnit.MILLISECONDS));

    latch.countDown();

    exec.shutdown();
    exec.awaitTermination(100, TimeUnit.MILLISECONDS);
  }

  /**
   * Tests that all listeners complete, even if they were added before or after
   * the future was finishing.  Also acts as a concurrency test to make sure the
   * locking is done correctly when a future is finishing so that no listeners
   * can be lost.
   */
  public void testAllListenersCompleteSuccessfully()
      throws InterruptedException, ExecutionException {

    ExecutorService exec = Executors.newCachedThreadPool();

    int listenerCount = 20;
    final CountDownLatch listenerLatch = new CountDownLatch(listenerCount);

    // Test that listeners added both before and after the value is available
    // get called correctly.
    for (int i = 0; i < 20; i++) {

      // Right in the middle start up a thread to close the latch.
      if (i == 10) {
        new Thread(new Runnable() {
          @Override
          public void run() {
            latch.countDown();
          }
        }).start();
      }

      future.addListener(new Runnable() {
        @Override
        public void run() {
          listenerLatch.countDown();
        }
      }, exec);
    }

    assertSame(Boolean.TRUE, future.get());
    // Wait for the listener latch to complete.
    listenerLatch.await(500, TimeUnit.MILLISECONDS);

    exec.shutdown();
    exec.awaitTermination(500, TimeUnit.MILLISECONDS);
  }
}

Other Java examples (source code examples)

Here is a short list of links related to this Java AbstractListenableFutureTest.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.