code: def add_engines(n=1, profile="iptest", total=False):
      """add a number of engines to a given profile.
  
      If total is True, then already running engines are counted, and only
      the additional engines necessary (if any) are started.
      """
      rc = Client(profile=profile)
      base = len(rc)
  
      if total:
          n = max(n - base, 0)
  
      eps = []
      for i in range(n):
          ep = TestProcessLauncher()
          ep.cmd_and_args = ipengine_cmd_argv + [
              "--profile=%s" % profile,
              "--InteractiveShell.colors=nocolor",
              "--log-level=10",
          ]
          ep.start()
          launchers.append(ep)
          eps.append(ep)
      tic = time.time()
      while len(rc) < base + n:
          if any([ep.poll() is not None for ep in eps]):
              raise RuntimeError("A test engine failed to start.")
          elif time.time() - tic > 15:
              raise RuntimeError(
                  "Timeout waiting for engines to connect."
              )
          time.sleep(0.1)
      rc.close()
      return eps
  
file_path: ipyparallel/ipyparallel/tests/__init__.py
imports: import asyncio
  import os
  import time
  from subprocess import Popen
  from IPython.paths import get_ipython_dir
  from ipyparallel import Client, error
  from ipyparallel.cluster.launcher import SIGKILL, LocalProcessLauncher, ProcessStateError, ipcontroller_cmd_argv, ipengine_cmd_argv
label_desc: Use image node_id 2 for calling a global function with example usage: add_engines(n, profile, total) and returns: eps