code: def test_get_avail_mem_per_ray_worker_node(monkeypatch):
      monkeypatch.setenv("RAY_ON_SPARK_WORKER_CPU_CORES", "4")
      monkeypatch.setenv("RAY_ON_SPARK_WORKER_GPU_NUM", "8")
      monkeypatch.setenv(
          "RAY_ON_SPARK_WORKER_PHYSICAL_MEMORY_BYTES", "1000000"
      )
      monkeypatch.setenv(
          "RAY_ON_SPARK_WORKER_SHARED_MEMORY_BYTES", "500000"
      )
  
      assert _get_avail_mem_per_ray_worker_node(
          num_cpus_per_node=1,
          num_gpus_per_node=2,
          object_store_memory_per_node=None,
      ) == (140000, 60000, None, None)
  
      assert _get_avail_mem_per_ray_worker_node(
          num_cpus_per_node=1,
          num_gpus_per_node=2,
          object_store_memory_per_node=80000,
      ) == (120000, 80000, None, None)
  
      assert _get_avail_mem_per_ray_worker_node(
          num_cpus_per_node=1,
          num_gpus_per_node=2,
          object_store_memory_per_node=120000,
      ) == (100000, 100000, None, None)
  
      assert _get_avail_mem_per_ray_worker_node(
          num_cpus_per_node=2,
          num_gpus_per_node=2,
          object_store_memory_per_node=None,
      ) == (280000, 120000, None, None)
  
      assert _get_avail_mem_per_ray_worker_node(
          num_cpus_per_node=1,
          num_gpus_per_node=4,
          object_store_memory_per_node=None,
      ) == (280000, 120000, None, None)
  
file_path: ray/python/ray/tests/spark/test_utils.py
imports: from unittest.mock import patch
  import os
  import re
  import sys
  import pytest
  from ray.util.spark.utils import get_spark_task_assigned_physical_gpus, _calc_mem_per_ray_worker_node, _get_avail_mem_per_ray_worker_node
  from ray.util.spark.cluster_init import _convert_ray_node_options, _verify_node_options, _append_default_spilling_dir_config
label_desc: Use image node_id 3 for calling a global function with example usage: test_get_avail_mem_per_ray_worker_node(monkeypatch) without return types