/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 org.apache.hadoop.test;

import java.util.HashSet;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * A utility to easily test threaded/synchronized code.
 * Utility works by letting you add threads that do some work to a
 * test context object, and then lets you kick them all off to stress test
 * your parallel code.
 *
 * Also propagates thread exceptions back to the runner, to let you verify.
 *
 * An example:
 *
 * <code>
 *  final AtomicInteger threadsRun = new AtomicInteger();
 *
 *  TestContext ctx = new TestContext();
 *  // Add 3 threads to test.
 *  for (int i = 0; i < 3; i++) {
 *    ctx.addThread(new TestingThread(ctx) {
 *      @Override
 *      public void doWork() throws Exception {
 *        threadsRun.incrementAndGet();
 *      }
 *    });
 *  }
 *  ctx.startThreads();
 *  // Set a timeout period for threads to complete.
 *  ctx.waitFor(30000);
 *  assertEquals(3, threadsRun.get());
 * </code>
 *
 * For repetitive actions, use the {@link MultithreadedTestUtil.RepeatingThread}
 * instead.
 *
 * (More examples can be found in {@link TestMultithreadedTestUtil})
 */
public abstract class MultithreadedTestUtil {

  public static final Log LOG =
    LogFactory.getLog(MultithreadedTestUtil.class);

  /**
   * TestContext is used to setup the multithreaded test runner.
   * It lets you add threads, run them, wait upon or stop them.
   */
  public static class TestContext {
    private Throwable err = null;
    private boolean stopped = false;
    private Set<TestingThread> testThreads = new HashSet<TestingThread>();
    private Set<TestingThread> finishedThreads = new HashSet<TestingThread>();

    /**
     * Check if the context can run threads.
     * Can't if its been stopped and contains an error.
     * @return true if it can run, false if it can't.
     */
    public synchronized boolean shouldRun()  {
      return !stopped && err == null;
    }

    /**
     * Add a thread to the context for running.
     * Threads can be of type {@link MultithreadedTestUtil.TestingThread}
     * or {@link MultithreadedTestUtil.RepeatingTestThread}
     * or other custom derivatives of the former.
     * @param t the thread to add for running.
     */
    public void addThread(TestingThread t) {
      testThreads.add(t);
    }

    /**
     * Starts all test threads that have been added so far.
     */
    public void startThreads() {
      for (TestingThread t : testThreads) {
        t.start();
      }
    }

    /**
     * Waits for threads to finish or error out.
     * @param millis the number of milliseconds to wait
     * for threads to complete.
     * @throws Exception if one or more of the threads
     * have thrown up an error.
     */
    public synchronized void waitFor(long millis) throws Exception {
      long endTime = System.currentTimeMillis() + millis;
      while (shouldRun() &&
             finishedThreads.size() < testThreads.size()) {
        long left = endTime - System.currentTimeMillis();
        if (left <= 0) break;
        checkException();
        wait(left);
      }
      checkException();
    }

    /**
     * Checks for thread exceptions, and if they've occurred
     * throws them as RuntimeExceptions in a deferred manner.
     */
    private synchronized void checkException() throws Exception {
      if (err != null) {
        throw new RuntimeException("Deferred", err);
      }
    }

    /**
     * Called by {@link MultithreadedTestUtil.TestingThread}s to signal
     * a failed thread.
     * @param t the thread that failed.
     */
    public synchronized void threadFailed(Throwable t) {
      if (err == null) err = t;
      LOG.error("Failed!", err);
      notify();
    }

    /**
     * Called by {@link MultithreadedTestUtil.TestingThread}s to signal
     * a successful completion.
     * @param t the thread that finished.
     */
    public synchronized void threadDone(TestingThread t) {
      finishedThreads.add(t);
      notify();
    }

    /**
     * Returns after stopping all threads by joining them back.
     * @throws Exception in case a thread terminated with a failure.
     */
    public void stop() throws Exception {
      synchronized (this) {
        stopped = true;
      }
      for (TestingThread t : testThreads) {
        t.join();
      }
      checkException();
    }

    public Iterable<? extends Thread> getTestThreads() {
      return testThreads;
    }
  }

  /**
   * A thread that can be added to a test context, and properly
   * passes exceptions through.
   */
  public static abstract class TestingThread extends Thread {
    protected final TestContext ctx;
    protected boolean stopped;

    public TestingThread(TestContext ctx) {
      this.ctx = ctx;
    }

    public void run() {
      try {
        doWork();
      } catch (Throwable t) {
        ctx.threadFailed(t);
      }
      ctx.threadDone(this);
    }

    /**
     * User method to add any code to test thread behavior of.
     * @throws Exception throw an exception if a failure has occurred.
     */
    public abstract void doWork() throws Exception;

    protected void stopTestThread() {
      this.stopped = true;
    }
  }

  /**
   * A test thread that performs a repeating operation.
   */
  public static abstract class RepeatingTestThread extends TestingThread {
    public RepeatingTestThread(TestContext ctx) {
      super(ctx);
    }

    /**
     * Repeats a given user action until the context is asked to stop
     * or meets an error.
     */
    public final void doWork() throws Exception {
      while (ctx.shouldRun() && !stopped) {
        doAnAction();
      }
    }

    /**
     * User method for any code to test repeating behavior of (as threads).
     * @throws Exception throw an exception if a failure has occured.
     */
    public abstract void doAnAction() throws Exception;
  }
}
