docstr: Validates gcp _configure_subnet logic.
  
  Checks that _configure_subnet fills default networkInterfaces data for
  each node type that doesn't specify networkInterfaces.
  
  Checks that _list_subnets is not called if all node types specify
  networkInterfaces.
docstr_tok: ["Validates","gcp","_configure_subnet","logic",".","Checks","that","_configure_subnet","fills","default","networkInterfaces","data","for","each","node","type","that","does","n't","specify","networkInterfaces",".","Checks","that","_list_subnets","is","not","called","if","all","node","types","specify","networkInterfaces","."]
code: def testGCPSubnets(self):
      """Validates gcp _configure_subnet logic.
  
      Checks that _configure_subnet fills default networkInterfaces data for
      each node type that doesn't specify networkInterfaces.
  
      Checks that _list_subnets is not called if all node types specify
      networkInterfaces.
      """
      path = os.path.join(
          RAY_PATH, "autoscaler", "gcp", "example-full.yaml"
      )
      config = yaml.safe_load(open(path).read())
  
      config_subnets_configured = copy.deepcopy(config)
      config_subnets_worker_configured = copy.deepcopy(config)
      config_subnets_head_configured = copy.deepcopy(config)
      config_subnets_no_type_configured = copy.deepcopy(config)
  
      config_subnets_configured["available_node_types"][
          "ray_head_default"
      ]["node_config"]["networkInterfaces"] = "mock_interfaces"
      config_subnets_configured["available_node_types"][
          "ray_worker_small"
      ]["node_config"]["networkInterfaces"] = "mock_interfaces"
  
      config_subnets_worker_configured["available_node_types"][
          "ray_worker_small"
      ]["node_config"]["networkInterfaces"] = "mock_interfaces"
  
      config_subnets_head_configured["available_node_types"][
          "ray_head_default"
      ]["node_config"]["networkInterfaces"] = "mock_interfaces"
  
      assert (
          "networkInterfaces"
          not in config_subnets_no_type_configured[
              "available_node_types"
          ]["ray_head_default"]["node_config"]
      )
      assert (
          "networkInterfaces"
          not in config_subnets_no_type_configured[
              "available_node_types"
          ]["ray_worker_small"]["node_config"]
      )
  
      # Configure subnets modifies configs in place so we need to copy
      # the configs for comparision after passing into the method.
      config_subnets_configured_post = copy.deepcopy(
          config_subnets_configured
      )
      config_subnets_worker_configured_post = copy.deepcopy(
          config_subnets_worker_configured
      )
      config_subnets_head_configured_post = copy.deepcopy(
          config_subnets_head_configured
      )
      config_subnets_no_type_configured_post = copy.deepcopy(
          config_subnets_no_type_configured
      )
  
      # Track number of times list_subnets has been called.
      list_subnets_counter = 0
  
      def mock_list_subnets(*args):
          nonlocal list_subnets_counter
          list_subnets_counter += 1
          return [{"selfLink": "link"}]
  
      # Attempting to patch produces an error in the CI.
      gcp_config._list_subnets = mock_list_subnets
      config_subnets_configured_post = gcp_config._configure_subnet(
          config_subnets_configured, compute="mock_compute"
      )
      # List subnets wasn't called
      assert list_subnets_counter == 0
      config_subnets_worker_configured_post = (
          gcp_config._configure_subnet(
              config_subnets_worker_configured, compute="mock_compute"
          )
      )
      # List subnets was called
      assert list_subnets_counter == 1
      config_subnets_head_configured_post = (
          gcp_config._configure_subnet(
              config_subnets_head_configured, compute="mock_compute"
          )
      )
      # List subnets was called
      assert list_subnets_counter == 2
      config_subnets_no_type_configured_post = (
          gcp_config._configure_subnet(
              config_subnets_no_type_configured, compute="mock_compute"
          )
      )
      # List subnets was called
      assert list_subnets_counter == 3
  
      # networkInterfaces field generated by configure subnets with mocked
      # _list_subnets
      default_interfaces = [
          {
              "subnetwork": "link",
              "accessConfigs": [
                  {
                      "name": "External NAT",
                      "type": "ONE_TO_ONE_NAT",
                  }
              ],
          }
      ]
  
      # Unchanged
      assert config_subnets_configured_post == config_subnets_configured
      assert (
          config_subnets_configured_post["available_node_types"][
              "ray_head_default"
          ]["node_config"]["networkInterfaces"]
          == "mock_interfaces"
      )
      assert (
          config_subnets_configured_post["available_node_types"][
              "ray_worker_small"
          ]["node_config"]["networkInterfaces"]
          == "mock_interfaces"
      )
  
      # Head subnets filled
      assert (
          config_subnets_worker_configured_post["available_node_types"][
              "ray_worker_small"
          ]["node_config"]["networkInterfaces"]
          == "mock_interfaces"
      )
      assert (
          config_subnets_worker_configured_post["available_node_types"][
              "ray_head_default"
          ]["node_config"]["networkInterfaces"]
          == default_interfaces
      )
  
      # Worker subnets filled
      assert (
          config_subnets_head_configured_post["available_node_types"][
              "ray_worker_small"
          ]["node_config"]["networkInterfaces"]
          == default_interfaces
      )
      assert (
          config_subnets_head_configured_post["available_node_types"][
              "ray_head_default"
          ]["node_config"]["networkInterfaces"]
          == "mock_interfaces"
      )
  
      # Head and worker subnets filled
      assert (
          config_subnets_no_type_configured_post[
              "available_node_types"
          ]["ray_worker_small"]["node_config"]["networkInterfaces"]
          == default_interfaces
      )
      assert (
          config_subnets_no_type_configured_post[
              "available_node_types"
          ]["ray_head_default"]["node_config"]["networkInterfaces"]
          == default_interfaces
      )
  
imports: import copy
  import logging
  import os
  import sys
  import tempfile
  from typing import Dict, Any
  import unittest
  import urllib
  from unittest.mock import MagicMock, Mock, patch
  import jsonschema
  import pytest
  import yaml
  from click.exceptions import ClickException
  import mock
  from ray._private.test_utils import load_test_config, recursive_fnmatch
  from ray.autoscaler._private._azure.config import _configure_key_pair
  from ray.autoscaler._private.gcp import config
  from ray.autoscaler._private.providers import _NODE_PROVIDERS
  from ray.autoscaler._private.util import fill_node_type_min_max_workers, merge_setup_commands, prepare_config, validate_config
label_desc: Use image node_id 12 for calling the AutoscalingConfigTest obj's underlying member method code with example usage: obj.testGCPSubnets() and returns: list