code: def test_child_process_observer(sleep_mock, os_kill_mock):
      # Case 1: All processes are running and did not exit yet
      processes = [Mock(returncode=None), Mock(returncode=None)]
      observer = _ChildProcessObserver(
          main_pid=1234, child_processes=processes
      )
      finished = (
          observer._run()
      )  # call _run() directly to simulate while loop
      assert not finished
  
      # Case 2: All processes have finished with exit code 0 (success)
      processes = [Mock(returncode=0), Mock(returncode=0)]
      observer = _ChildProcessObserver(
          main_pid=1234, child_processes=processes
      )
      finished = (
          observer._run()
      )  # call _run() directly to simulate while loop
      assert finished
  
      # Case 3: One process has finished with exit code 1 (failure)
      processes = [Mock(returncode=0), Mock(returncode=1)]
      observer = _ChildProcessObserver(
          main_pid=1234, child_processes=processes
      )
      finished = (
          observer._run()
      )  # call _run() directly to simulate while loop
      assert finished
      expected_signal = (
          signal.SIGTERM if sys.platform == "win32" else signal.SIGKILL
      )
      processes[0].send_signal.assert_called_once_with(expected_signal)
      processes[1].send_signal.assert_called_once_with(expected_signal)
      os_kill_mock.assert_called_once_with(1234, expected_signal)
  
      # The main routine stops
      observer = _ChildProcessObserver(
          main_pid=1234, child_processes=[Mock(), Mock()]
      )
      observer._run = Mock()
      assert not observer._finished
      observer.run()
      assert observer._finished
      sleep_mock.assert_called_once_with(5)
  
file_path: pytorch-lightning/tests/tests_fabric/strategies/launchers/test_subprocess_script.py
imports: import os
  import signal
  import sys
  from unittest import mock
  from unittest.mock import ANY, Mock
  import lightning.fabric
  import pytest
  from lightning.fabric.strategies.launchers.subprocess_script import _HYDRA_AVAILABLE, _ChildProcessObserver, _SubprocessScriptLauncher
label_desc: Use image node_id 6 for calling a global function with example usage: test_child_process_observer(sleep_mock, os_kill_mock) without return types