text: import pytest
  
  from settings import TEST_DATA
  from suite.custom_assertions import assert_event_and_count, assert_event_and_get_count, wait_and_assert_status_code, \
      wait_for_event_count_increases, assert_event_with_full_equality_and_count
  from suite.custom_resources_utils import get_vs_nginx_template_conf
  from suite.resources_utils import replace_configmap_from_yaml, \
      ensure_connection_to_public_endpoint, replace_configmap, create_service_from_yaml, get_first_pod_name, get_events, \
      read_service, replace_service, wait_before_test, delete_namespace, create_service_with_name, \
      create_deployment_with_name, create_namespace_with_name_from_yaml, ensure_response_from_backend
  
  
  class ExternalNameSetup:
      """Encapsulate ExternalName example details.
  
      Attributes:
          ic_pod_name:
          external_host: external service host
      """
      def __init__(self, ic_pod_name, external_svc, external_host):
          self.ic_pod_name = ic_pod_name
          self.external_svc = external_svc
          self.external_host = external_host
  
  
  @pytest.fixture(scope="class")
  def vs_externalname_setup(request,
                            kube_apis,
                            ingress_controller_prerequisites,
                            virtual_server_setup) -> ExternalNameSetup:
      print("------------------------- Deploy External-Backend -----------------------------------")
      external_ns = create_namespace_with_name_from_yaml(kube_apis.v1, "external-ns", f"{TEST_DATA}/common/ns.yaml")
      external_svc_name = create_service_with_name(kube_apis.v1, external_ns, "external-backend-svc")
      create_deployment_with_name(kube_apis.apps_v1_api, external_ns, "external-backend")
      print("------------------------- Prepare ExternalName Setup -----------------------------------")
      external_svc_src = f"{TEST_DATA}/virtual-server-externalname/externalname-svc.yaml"
      external_svc_host = f"{external_svc_name}.{external_ns}.svc.cluster.local"
      config_map_name = ingress_controller_prerequisites.config_map["metadata"]["name"]
      replace_configmap_from_yaml(kube_apis.v1, config_map_name,
                                  ingress_controller_prerequisites.namespace,
                                  f"{TEST_DATA}/virtual-server-externalname/nginx-config.yaml")
      external_svc = create_service_from_yaml(kube_apis.v1, virtual_server_setup.namespace, external_svc_src)
      wait_before_test(2)
      ensure_connection_to_public_endpoint(virtual_server_setup.public_endpoint.public_ip,
                                           virtual_server_setup.public_endpoint.port,
                                           virtual_server_setup.public_endpoint.port_ssl)
      ic_pod_name = get_first_pod_name(kube_apis.v1, ingress_controller_prerequisites.namespace)
      ensure_response_from_backend(virtual_server_setup.backend_1_url, virtual_server_setup.vs_host)
  
      def fin():
          print("Clean up ExternalName Setup:")
          delete_namespace(kube_apis.v1, external_ns)
          replace_configmap(kube_apis.v1, config_map_name,
                            ingress_controller_prerequisites.namespace,
                            ingress_controller_prerequisites.config_map)
  
      request.addfinalizer(fin)
  
      return ExternalNameSetup(ic_pod_name, external_svc, external_svc_host)
  
  
  @pytest.mark.vs
  @pytest.mark.skip_for_nginx_oss
  @pytest.mark.parametrize('crd_ingress_controller, virtual_server_setup',
                           [({"type": "complete", "extra_args": [f"-enable-custom-resources", "-v=3"]},
                             {"example": "virtual-server-externalname", "app_type": "simple"})],
                           indirect=True)
  class TestVSWithExternalNameService:
      def test_response(self, kube_apis, crd_ingress_controller, virtual_server_setup, vs_externalname_setup):
          wait_and_assert_status_code(200, virtual_server_setup.backend_1_url,
                                      virtual_server_setup.vs_host)
  
      def test_template_config(self, kube_apis, ingress_controller_prerequisites,
                               crd_ingress_controller,
                               virtual_server_setup, vs_externalname_setup):
          result_conf = get_vs_nginx_template_conf(kube_apis.v1,
                                                   virtual_server_setup.namespace,
                                                   virtual_server_setup.vs_name,
                                                   vs_externalname_setup.ic_pod_name,
                                                   ingress_controller_prerequisites.namespace)
          line = f"zone vs_{virtual_server_setup.namespace}_{virtual_server_setup.vs_name}_backend1 256k;"
          assert line in result_conf
          assert "random two least_conn;" in result_conf
          assert f"server {vs_externalname_setup.external_host}:80 max_fails=1 fail_timeout=10s max_conns=0 resolve;"\
                 in result_conf
  
      def test_events_flows(self, kube_apis, ingress_controller_prerequisites,
                            crd_ingress_controller, virtual_server_setup, vs_externalname_setup):
          text = f"{virtual_server_setup.namespace}/{virtual_server_setup.vs_name}"
          vs_event_text = f"Configuration for {text} was added or updated"
          wait_before_test(10)
          events_vs = get_events(kube_apis.v1, virtual_server_setup.namespace)
          initial_count = assert_event_and_get_count(vs_event_text, events_vs)
  
          print("Step 1: Update external host in externalName service")
          external_svc = read_service(kube_apis.v1, vs_externalname_setup.external_svc, virtual_server_setup.namespace)
          external_svc.spec.external_name = "demo.nginx.com"
          replace_service(kube_apis.v1, vs_externalname_setup.external_svc, virtual_server_setup.namespace, external_svc)
          wait_before_test(10)
  
          wait_for_event_count_increases(kube_apis, vs_event_text, initial_count, virtual_server_setup.namespace)
          events_step_1 = get_events(kube_apis.v1, virtual_server_setup.namespace)
          assert_event_and_count(vs_event_text, initial_count + 1, events_step_1)
  
          print("Step 2: Remove resolver from ConfigMap to trigger an error")
          config_map_name = ingress_controller_prerequisites.config_map["metadata"]["name"]
          vs_event_warning_text = f"Configuration for {text} was added or updated ; with warning(s):"
          replace_configmap(kube_apis.v1, config_map_name,
                            ingress_controller_prerequisites.namespace,
                            ingress_controller_prerequisites.config_map)
          wait_before_test(10)
  
          events_step_2 = get_events(kube_apis.v1, virtual_server_setup.namespace)
          assert_event_and_count(vs_event_warning_text, 1, events_step_2)
          assert_event_with_full_equality_and_count(vs_event_text, initial_count + 1, events_step_2)
  