def setUp(self):
    # When setting up a test simply make a best effort to start from a clean
    # state.
    self._starting_remnants = data_utils.terminate_keras_multiprocessing_pools(
        use_sigkill=False)

    self._sleep_at_end = False
    super(ForkRobustTestCase, self).setUp()
  def tearDown(self):
    # Give multiprocessing pools some time to finish on their own before
    # cleanup_all_keras_forkpools yanks the rug out from under them. This is
    # particularly important because calling .close() on a pool that is already
    # in the process of spinning down can cause an uncatchable segmentation
    # fault at which point the tearDown will hang.
    if self._sleep_at_end:
      time.sleep(1)

    # If a test finishes and leaves behind uncleanable artifacts then that is a
    # failure condition. However, if the state was not clean to begin with the
    # test should not fail on that account.
    new_remnants = set(data_utils.terminate_keras_multiprocessing_pools(
        use_sigkill=True)).difference(self._starting_remnants)

    if new_remnants:
      raise ValueError('Test left behind stubborn orphans:\n  {}'.format(
          '\n  '.join(new_remnants)))
    super(ForkRobustTestCase, self).tearDown()