from multiprocessing import Pool
from typing import Callable
from typing import Tuple
from typing import Any


def _run_tests_parallel(num_processes: int,
                        parameter_combinations: Callable[[], Tuple[Any, ...]],
                        run_test: Callable[..., bool]) -> bool:
  """Tests all combinations in parallel with the given number of processes."""

  # Python multiprocessing doesn't work within Google. Import the Pool module
  # only when multiprocessing is enable for this reason.
  with Pool(num_processes) as pool:
    # For each combination, assign a job to the worker pool and return a
    # placeholder object for getting the test result. We use `c` not `*c` here
    # as apply_async unpacks the tuple.
    result_objs = [
        pool.apply_async(run_test, c) for c in parameter_combinations()
    ]

    # Get the results of the tests using the placeholder objects.
    return all(result.get() for result in result_objs)