Repository: django/django
File: django/test/runner.py (Python)

Code before:
        setup_test_environment(debug=debug_mode)

    db_aliases = used_aliases if used_aliases is not None else connections
    for alias in db_aliases:
        connection = connections[alias]
        if is_spawn_or_forkserver:
            # Restore initial settings in spawned processes.
            connection.settings_dict.update(initial_settings[alias])
            if value := serialized_contents.get(alias):
                connection._test_serialized_contents = value
        connection.creation.setup_worker_connection(_worker_id)

    if is_spawn_or_forkserver:
        call_command(
            "check", stdout=io.StringIO(), stderr=io.StringIO(), databases=used_aliases
        )


def _safe_init_worker(init_worker, counter, *args, **kwargs):
    try:
        init_worker(counter, *args, **kwargs)
    except Exception:
        with counter.get_lock():
            counter.value = -1
        raise


def _run_subsuite(args):
    """
    Run a suite of tests with a RemoteTestRunner and return a RemoteTestResult.

    This helper lives at module-level and its arguments are wrapped in a tuple
    because of the multiprocessing module's requirements.
    """
    runner_class, subsuite_index, subsuite, failfast, buffer = args
    runner = runner_class(failfast=failfast, buffer=buffer)
    result = runner.run(subsuite)
    return subsuite_index, result.events


def _process_setup_stub(*args):
    """Stub method to simplify run() implementation."""
    pass


class ParallelTestSuite(unittest.TestSuite):
    """
    Run a series of tests in parallel in several processes.

    While the unittest module's documentation implies that orchestrating the
    execution of tests is the responsibility of the test runner, in practice,

Review comment (bug):
Is the goal of this new method to avoid indenting the original `_init_worker` one level in to add the try-except there?

Also, question: what happens if we create a `multiprocessing.Pool` of `N` threads: `t1`, `t2`, ..., `tN`, and (for example) `t2` executes super fast and crashes inside `_init_worker` before `t3` even starts initializing?

Since `_safe_init_worker` sets `counter.value = -1` on failure, any thread still initializing could then read that shared value and end up with `_worker_id = 0`. That seems unintended and could lead to duplicate or invalid worker IDs. Furthermore, it could still raise but the code handling the exception does not see the counter in `-1`.

Code after:
        setup_test_environment(debug=debug_mode)

    db_aliases = used_aliases if used_aliases is not None else connections
    for alias in db_aliases:
        connection = connections[alias]
        if is_spawn_or_forkserver:
            # Restore initial settings in spawned processes.
            connection.settings_dict.update(initial_settings[alias])
            if value := serialized_contents.get(alias):
                connection._test_serialized_contents = value
        connection.creation.setup_worker_connection(_worker_id)

    if is_spawn_or_forkserver:
        call_command(
            "check", stdout=io.StringIO(), stderr=io.StringIO(), databases=used_aliases
        )


def _safe_init_worker(init_worker, counter, *args, **kwargs):
    try:
        init_worker(counter, *args, **kwargs)
    except Exception:
        with counter.get_lock():
            # Set a value that will not increment above zero any time soon.
            counter.value = -1000
        raise


def _run_subsuite(args):
    """
    Run a suite of tests with a RemoteTestRunner and return a RemoteTestResult.

    This helper lives at module-level and its arguments are wrapped in a tuple
    because of the multiprocessing module's requirements.
    """
    runner_class, subsuite_index, subsuite, failfast, buffer = args
    runner = runner_class(failfast=failfast, buffer=buffer)
    result = runner.run(subsuite)
    return subsuite_index, result.events


def _process_setup_stub(*args):
    """Stub method to simplify run() implementation."""
    pass


class ParallelTestSuite(unittest.TestSuite):
    """
    Run a series of tests in parallel in several processes.

    While the unittest module's documentation implies that orchestrating the