class_docstr: .. note:: tested on etcd server v3.4.3.
  
  Starts and stops a local standalone etcd server on a random free
  port. Useful for single node, multi-worker launches or testing,
  where a sidecar etcd server is more convenient than having to
  separately setup an etcd server.
  
  This class registers a termination handler to shutdown the etcd
  subprocess on exit. This termination handler is NOT a substitute for
  calling the ``stop()`` method.
  
  The following fallback mechanism is used to find the etcd binary:
  
  1. Uses env var TORCHELASTIC_ETCD_BINARY_PATH
  2. Uses ``<this file root>/bin/etcd`` if one exists
  3. Uses ``etcd`` from ``PATH``
  
  Usage
  ::
  
   server = EtcdServer("/usr/bin/etcd", 2379, "/tmp/default.etcd")
   server.start()
   client = server.get_client()
   # use client
   server.stop()
  
  Args:
      etcd_binary_path: path of etcd server binary (see above for fallback path)
code: def _start(
      self,
      data_dir: str,
      timeout: int = 60,
      stderr: Union[int, TextIO, None] = None,
  ) -> None:
      sock = find_free_port()
      sock_peer = find_free_port()
      self._port = sock.getsockname()[1]
      peer_port = sock_peer.getsockname()[1]
  
      etcd_cmd = shlex.split(
          " ".join(
              [
                  self._etcd_binary_path,
                  "--enable-v2",
                  "--data-dir",
                  data_dir,
                  "--listen-client-urls",
                  f"http://{self._host}:{self._port}",
                  "--advertise-client-urls",
                  f"http://{self._host}:{self._port}",
                  "--listen-peer-urls",
                  f"http://{self._host}:{peer_port}",
              ]
          )
      )
  
      log.info("Starting etcd server: [%s]", etcd_cmd)
  
      sock.close()
      sock_peer.close()
      self._etcd_proc = subprocess.Popen(
          etcd_cmd, close_fds=True, stderr=stderr
      )
      self._wait_for_ready(timeout)
  
imports: import atexit
  import logging
  import os
  import shlex
  import shutil
  import socket
  import subprocess
  import tempfile
  import time
  from typing import Optional, TextIO, Union
label_desc: Use image node_id 7 for calling the EtcdServer obj's underlying member method code with example usage: obj._start(data_dir, timeout, stderr) without return types