class_docstr: e2e verification of autoscaling following the steps in the Ray documentation.
  kubectl is used throughout, as that reflects the instructions in the docs.
class_docstr_tok: ["e2e","verification","of","autoscaling","following","the","steps","in","the","Ray","documentation",".","kubectl","is","used","throughout",",","as","that","reflects","the","instructions","in","the","docs","."]
docstr: Get Ray CR config yaml.
  
  - Use configurable replica fields for a CPU workerGroup.
  
  - Add a GPU-annotated group for testing GPU upscaling.
  
  - Fill in Ray image, autoscaler image, and image pull policies from env
    variables.
docstr_tok: ["Get","Ray","CR","config","yaml",".","-","Use","configurable","replica","fields","for","a","CPU","workerGroup",".","-","Add","a","GPU-annotated","group","for","testing","GPU","upscaling",".","-","Fill","in","Ray","image",",","autoscaler","image",",","and","image","pull","policies","from","env","variables","."]
code: def _get_ray_cr_config(
      self, min_replicas=0, cpu_replicas=0, gpu_replicas=0
  ) -> Dict[str, Any]:
      """Get Ray CR config yaml.
  
      - Use configurable replica fields for a CPU workerGroup.
  
      - Add a GPU-annotated group for testing GPU upscaling.
  
      - Fill in Ray image, autoscaler image, and image pull policies from env
        variables.
      """
      with open(EXAMPLE_CLUSTER_PATH) as ray_cr_config_file:
          ray_cr_config_str = ray_cr_config_file.read()
  
      for k8s_object in yaml.safe_load_all(ray_cr_config_str):
          if k8s_object["kind"] in [
              "RayCluster",
              "RayJob",
              "RayService",
          ]:
              config = k8s_object
              break
      head_group = config["spec"]["headGroupSpec"]
      head_group["rayStartParams"][
          "resources"
      ] = '"{\\"Custom1\\": 1, \\"Custom2\\": 5}"'
  
      cpu_group = config["spec"]["workerGroupSpecs"][0]
      cpu_group["replicas"] = cpu_replicas
      cpu_group["minReplicas"] = min_replicas
      # Keep maxReplicas big throughout the test.
      cpu_group["maxReplicas"] = 300
      cpu_group["rayStartParams"][
          "resources"
      ] = '"{\\"Custom1\\": 1, \\"Custom2\\": 5}"'
  
      # Add a GPU-annotated group.
      # (We're not using real GPUs, just adding a GPU annotation for the autoscaler
      # and Ray scheduler.)
      gpu_group = copy.deepcopy(cpu_group)
      gpu_group["rayStartParams"]["num-gpus"] = "1"
      gpu_group["replicas"] = gpu_replicas
      gpu_group["minReplicas"] = 0
      gpu_group["maxReplicas"] = 1
      gpu_group["groupName"] = "fake-gpu-group"
      config["spec"]["workerGroupSpecs"].append(gpu_group)
  
      # Substitute images.
      for group_spec in config["spec"]["workerGroupSpecs"] + [
          config["spec"]["headGroupSpec"]
      ]:
          containers = group_spec["template"]["spec"]["containers"]
  
          ray_container = containers[0]
          # Confirm the first container in the example config is the Ray container.
          assert ray_container["name"] in ["ray-head", "ray-worker"]
          # ("machine-learning" is the name of the worker Ray container)
  
          ray_container["image"] = RAY_IMAGE
  
          for container in containers:
              container["imagePullPolicy"] = PULL_POLICY
  
      autoscaler_options = {
          "image": AUTOSCALER_IMAGE,
          "imagePullPolicy": PULL_POLICY,
          # Allow quick scale-down for test purposes.
          "idleTimeoutSeconds": 10,
      }
      config["spec"]["autoscalerOptions"] = autoscaler_options
  
      return config
  
file_path: ray/python/ray/tests/kuberay/test_autoscaling_e2e.py
imports: import base64
  import copy
  import logging
  import os
  import pytest
  import subprocess
  import sys
  import tempfile
  import unittest
  from typing import Any, Dict
  import yaml
  from ray.tests.kuberay.utils import get_pod, get_pod_names, get_raycluster, ray_client_port_forward, ray_job_submit, switch_to_ray_parent_dir, kubectl_exec_python_script, kubectl_logs, kubectl_delete, wait_for_pods, wait_for_pod_to_start, wait_for_ray_health
  from ray.tests.kuberay.scripts import gpu_actor_placement, gpu_actor_validation, non_terminated_nodes_count
label_desc: Use image node_id 1 for calling the KubeRayAutoscalingTest obj's underlying member method code with example usage: obj._get_ray_cr_config(min_replicas, cpu_replicas, gpu_replicas) and returns: config