code: def tearDown(self):
      print("start tearDown")
      assert len(self.sub_process) == len(self.sub_process_type)
      for i, proc in enumerate(self.sub_process):
          if self.sub_process_type[i] == "master":
              if proc.is_alive():
                  proc.terminate()
                  proc.join()
          elif self.sub_process_type[i] == "worker":
              os.killpg(os.getpgid(proc.pid), signal.SIGTERM)
          else:
              raise NotImplementedError
      disconnect()
  
imports: import unittest
  from parl.utils import get_free_tcp_port
  from parl.utils import is_port_available
  from parl.utils import logger
  import multiprocessing
  from parl.remote.master import Master
  from parl.remote.worker import Worker
  from parl.remote.client import disconnect
  from parl.remote import remote_constants
  import time
  import os
  import signal
  import psutil
  import subprocess
label_desc: Use image node_id 2 for calling the XparlTestCase obj's underlying member method code with example usage: obj.tearDown() without return types