/*
 * The Alluxio Open Foundation licenses this work under the Apache License, version 2.0
 * (the "License"). You may not use this work except in compliance with the License, which is
 * available at www.apache.org/licenses/LICENSE-2.0
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 * either express or implied, as more fully set forth in the License.
 *
 * See the NOTICE file distributed with this work for information regarding copyright ownership.
 */

package alluxio.test.util;

import org.junit.Assert;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * A set of utility methods for testing concurrency.
 */
public final class ConcurrencyUtils {
  private ConcurrencyUtils() {} // prevent instantiation

  /**
   * Tests the current operations of a list of runnables. Run all the operations at the same time to
   * maximize the chances of triggering a multithreading code error. Suggested by junit team at
   * https://github.com/junit-team/junit/wiki/Multithreaded-code-and-concurrency.
   *
   * @param runnables the list of runnables
   * @param maxTimeoutSeconds the maximal timeout in seconds
   * @throws InterruptedException if awaiting one of the threads fails
   */
  public static void assertConcurrent(final List<? extends Runnable> runnables,
      final int maxTimeoutSeconds) throws InterruptedException {
    final int numThreads = runnables.size();
    final List<Throwable> exceptions = Collections.synchronizedList(new ArrayList<Throwable>());
    final ExecutorService threadPool = Executors.newFixedThreadPool(numThreads);
    try {
      final CountDownLatch allExecutorThreadsReady = new CountDownLatch(numThreads);
      final CountDownLatch afterInitBlocker = new CountDownLatch(1);
      final CountDownLatch allDone = new CountDownLatch(numThreads);
      for (final Runnable submittedTestRunnable : runnables) {
        threadPool.submit(new Runnable() {
          @Override
          public void run() {
            allExecutorThreadsReady.countDown();
            try {
              afterInitBlocker.await();
              submittedTestRunnable.run();
            } catch (final Throwable e) {
              exceptions.add(e);
            } finally {
              allDone.countDown();
            }
          }
        });
      }
      // wait until all threads are ready
      Assert.assertTrue("Timeout initializing threads!",
          allExecutorThreadsReady.await(runnables.size() * 10, TimeUnit.MILLISECONDS));

      // start all test runners
      afterInitBlocker.countDown();
      Assert.assertTrue("Timeout! More than " + maxTimeoutSeconds + " seconds",
          allDone.await(maxTimeoutSeconds, TimeUnit.SECONDS));
    } finally {
      threadPool.shutdownNow();
    }
    Assert.assertTrue("Failed with exception(s) " + exceptions, exceptions.isEmpty());
  }
}

@@ -2132,77 +2132,16 @@
 mit(
-new Runnable() %7B%0A          @Override%0A          public void run()
+() -%3E
  %7B%0A
-  
     
@@ -2193,26 +2193,22 @@
         
-  
 try %7B%0A
-  
         
@@ -2249,18 +2249,16 @@
         
- 
- 
 submitte
@@ -2274,26 +2274,24 @@
 able.run();%0A
-  
           %7D 
@@ -2330,18 +2330,16 @@
         
-  
 exceptio
@@ -2359,18 +2359,16 @@
         
- 
- 
 %7D finall
@@ -2367,26 +2367,24 @@
 %7D finally %7B%0A
-  
             
@@ -2408,22 +2408,8 @@
 ();%0A
-            %7D%0A
     

change alluxio.test.util.ConcurrencyUtils__threadPool (#7934)