code: def test_monitor_query_log_server(self):
      master_port = self.port
      monitor_port = get_free_tcp_port()
      # start the master
      master = Master(port=master_port, monitor_port=monitor_port)
      th = threading.Thread(target=master.run)
      th.start()
      time.sleep(1)
      # start the cluster monitor
      monitor_file = __file__.replace(
          "log_server_test.pyc", "../monitor.py"
      )
      monitor_file = monitor_file.replace(
          "log_server_test.py", "../monitor.py"
      )
      command = [
          sys.executable,
          monitor_file,
          "--monitor_port",
          str(monitor_port),
          "--address",
          "localhost:" + str(master_port),
      ]
      if _IS_WINDOWS:
          FNULL = tempfile.TemporaryFile()
      else:
          FNULL = open(os.devnull, "w")
      monitor_proc = subprocess.Popen(
          command,
          stdout=FNULL,
          stderr=subprocess.STDOUT,
          close_fds=True,
      )
  
      # Start worker
      cluster_addr = "localhost:{}".format(master_port)
      self.add_worker(n_cpu=4)
  
      # Test monitor API
      outputs = self._connect_and_create_actor(cluster_addr)
      time.sleep(5)  # Wait for the status update
      client = get_global_client()
      jobs_url = "{}/get-jobs?client_id={}".format(
          master.monitor_url, client.client_id
      )
      r = requests.get(jobs_url)
      self.assertEqual(r.status_code, 200)
      data = json.loads(r.text)
      for job in data:
          log_url = job.get("log_url")
          self.assertIsNotNone(log_url)
          r = requests.get(log_url)
          self.assertEqual(r.status_code, 200)
          log_content = json.loads(r.text).get("log")
          self.assertIsNotNone(log_content)
          log_content = log_content.replace("\r\n", "\n")
          self.assertIn(log_content, outputs)
  
          # Test download
          download_url = job.get("download_url")
          r = requests.get(download_url)
          self.assertEqual(r.status_code, 200)
          log_content = r.text.replace("\r\n", "\n")
          self.assertIn(log_content, outputs)
  
      # Clean context
      monitor_proc.kill()
      monitor_proc.wait()
      master.exit()
  
imports: import json
  import multiprocessing
  import os
  import pickle
  import subprocess
  import sys
  import tempfile
  import threading
  import time
  import unittest
  import requests
  import parl
  from parl.remote.client import disconnect, get_global_client
  from parl.utils import _IS_WINDOWS
  from parl.utils.test_utils import XparlTestCase
  from parl.utils import get_free_tcp_port
  from parl.remote.master import Master
label_desc: Use image node_id 3 for calling the TestLogServer obj's underlying member method code with example usage: obj.test_monitor_query_log_server() without return types