class_docstr: Controls a stand-alone Spark cluster for integration tests.
  Tests can run forked, but not in parallel.
  Multiple controller instances would restart each other's masters.
class_docstr_tok: ["Controls","a","stand-alone","Spark","cluster","for","integration","tests",".","Tests","can","run","forked",",","but","not","in","parallel",".","Multiple","controller","instances","would","restart","each","other","'s","masters","."]
code: def __init__(
      self, logfile, discovery_schedule, hosts, master_instance
  ):
      if (
          hosts
          and discovery_schedule
          or (not hosts and not discovery_schedule)
      ):
          raise ValueError(
              "either discovery schedule or hosts must be given, not both"
          )
  
      if "SPARK_HOME" not in os.environ:
          raise RuntimeError(
              "SPARK_HOME not set, it has to point to your Spark installation"
          )
  
      self._spark_home = os.environ["SPARK_HOME"]
      self._logfile = logfile
      self._discovery_schedule = (
          dict(discovery_schedule) if discovery_schedule else {}
      )
      self._hosts = hosts.split(",") if hosts else None
      self._next_worker_instance = master_instance
      self._host_worker = {}
      self._worker_logs = {}
      self._workers = []
      self._shutdown = threading.Event()
      self._logfile_monitor = None
  
      self._master_instance = master_instance
      self._master_host = "localhost"
      self._master_log = None
      self._master_url = None
      self._log_re = re.compile(
          r"^starting org\.apache\.spark\.deploy\..+, logging to (.+)$"
      )
      self._url_re = re.compile(
          "^.+ Starting Spark master at (.+)[\r\n]+"
      )
      self._executor_re = re.compile(
          "^.+ Launching executor ([^ ]+) on worker .+$"
      )
  
imports: from __future__ import absolute_import
  import contextlib
  import json
  import logging
  import os
  import re
  import sys
  import threading
  import time
  import warnings
  import mock
  from parameterized import parameterized
  import pytest
  import unittest
  from horovod.runner.util.threads import in_thread
  from horovod.runner.common.util import safe_shell_exec, tiny_shell_exec
  from horovod.spark import conf, run_elastic
  from common import temppath
label_desc: Use image node_id 1 to create a new SparkClusterController object from inherited base classes: object with example: obj = SparkClusterController(logfile, discovery_schedule, hosts, master_instance)