Merge "dx: Throttle run-all-tests script" am: dd452a4244
am: 89941e09c6

Change-Id: Ib82f454646766f5f7a9a6a561f73d76e5fc809c0
diff --git a/dx/tests/run-all-tests b/dx/tests/run-all-tests
index d24ef7a..3734a98 100755
--- a/dx/tests/run-all-tests
+++ b/dx/tests/run-all-tests
@@ -105,9 +105,10 @@
 }
 
 function update_result {
-  test_name=$1
-  output=$2
-  result=$3
+  local -r test_name=$1
+  local -r output=$2
+  local -r result=$3
+  local expectFail
 
   if [[ "$known_bad" == *"$test_name"* ]]; then
     expectFail=1
@@ -134,33 +135,46 @@
   fi
 }
 
+function run_one_test_with_flock {
+  local -r output_dir=$1
+  local -r test_name=$2
+  local -r lock_file=$3
+
+  # Wait for the lock and run the test when acquired
+  flock "${lock_file}" ./run-test --output_dir "${output_dir}" "${test_name}"
+}
+
 function run_tests {
+  readonly test_root=$(mktemp -d)
+  trap "rm -rf ${test_root}" EXIT
   if [[ "$sequential" = "yes" ]]; then
     for test_name in *; do
       if [[ "$skip_tests" = *"$test_name"* ]]; then
-          skipped+=(${test_name})
-          continue
+        skipped+=(${test_name})
+        continue
       fi
       if [ -d "$test_name" -a -r "$test_name" ]; then
-        output=/tmp/$$/$test_name
-        ./run-test --output_dir "$output" "$test_name"
-        update_result $test_name $output $?
+        output="${test_root}/${test_name}"
+        ./run-test --output_dir "${output}" "${test_name}"
+        update_result "${test_name}" "${output}" $?
       fi
     done
   else
-    i=0
+    readonly num_workers=4
+    local i=0
     for test_name in *; do
       if [[ "$skip_tests" = *"$test_name"* ]]; then
-          skipped+=(${test_name})
-          continue
+        skipped+=(${test_name})
+        continue
       fi
-      if [ -d "$test_name" -a -r "$test_name" ]; then
-          output=/tmp/$$/$test_name
-          ./run-test --output_dir "$output" "$test_name" &
-          test_pids[i]=$!
-          test_names[test_pids[i]]="$test_name"
-          test_outputs[test_pids[i]]="output"
-          let i+=1
+      local lock_file=${test_root}/lock.$((i % num_workers))
+      if [ -d "${test_name}" -a -r "${test_name}" ]; then
+        output="${test_root}/${test_name}"
+        run_one_test_with_flock "$output" "$test_name" "$lock_file" &
+        test_pids[i]=$!
+        test_names[test_pids[i]]="$test_name"
+        test_outputs[test_pids[i]]="output"
+        let i+=1
       fi
     done
 
@@ -174,6 +188,9 @@
 function handle_interrupt {
   trap INT
   display_results
+  if [ ! -z "${test_pids}" ]; then
+    killall ${test_pids}
+  fi
 }
 
 trap handle_interrupt INT