github.com/nginxinc/kubernetes-ingress@v1.12.5/tests/suite/test_v_s_route_regexp_location.py (about)

     1  import requests
     2  import pytest
     3  
     4  from settings import TEST_DATA
     5  from suite.custom_assertions import assert_event, assert_vs_conf_not_exists
     6  from suite.custom_resources_utils import patch_v_s_route_from_yaml, patch_virtual_server_from_yaml, \
     7      get_vs_nginx_template_conf, create_virtual_server_from_yaml, create_v_s_route_from_yaml
     8  from suite.resources_utils import wait_before_test, get_events, get_first_pod_name, \
     9      create_example_app, wait_until_all_pods_are_ready, ensure_response_from_backend
    10  from suite.yaml_utils import get_first_host_from_yaml
    11  
    12  
    13  @pytest.mark.vsr
    14  @pytest.mark.parametrize('crd_ingress_controller, v_s_route_setup',
    15                           [({"type": "complete", "extra_args": [f"-enable-custom-resources"]},
    16                             {"example": "virtual-server-route-regexp-location"})],
    17                           indirect=True)
    18  class TestRegexpLocation:
    19      @pytest.mark.parametrize('test_data', [
    20          pytest.param({"regex_type": "exact",
    21                        "expected_results": {"/exact-match$request": 200,
    22                                             "/exact-match$request/": 404,
    23                                             "/exact-match$request?var1=value": 200}}, id="exact"),
    24          pytest.param({"regex_type": "case-sensitive",
    25                        "expected_results": {"/case-SENsitiVe/match": 200,
    26                                             "/case-sensitive/match/": 404,
    27                                             "/case-SENsitiVe/match/": 200}}, id="case-sensitive"),
    28          pytest.param({"regex_type": "case-insensitive",
    29                        "expected_results": {"/case-inSENsitiVe/match": 200,
    30                                             "/case-insensitive/match/": 200,
    31                                             "/case-inSENsitiVe/match/": 200}}, id="case-insensitive")
    32      ])
    33      def test_response_for_regex_location(self, kube_apis,
    34                                           ingress_controller_prerequisites, crd_ingress_controller,
    35                                           v_s_route_setup, v_s_route_app_setup, test_data):
    36          req_url = f"http://{v_s_route_setup.public_endpoint.public_ip}:{v_s_route_setup.public_endpoint.port}"
    37          vs_src_yaml = f"{TEST_DATA}" \
    38                        f"/virtual-server-route-regexp-location/standard/virtual-server-{test_data['regex_type']}.yaml"
    39          vsr_src_yaml = f"{TEST_DATA}/virtual-server-route-regexp-location/route-single-{test_data['regex_type']}.yaml"
    40          patch_virtual_server_from_yaml(kube_apis.custom_objects, v_s_route_setup.vs_name,
    41                                         vs_src_yaml,
    42                                         v_s_route_setup.namespace)
    43          patch_v_s_route_from_yaml(kube_apis.custom_objects,
    44                                    v_s_route_setup.route_s.name,
    45                                    vsr_src_yaml,
    46                                    v_s_route_setup.route_s.namespace)
    47          wait_before_test(1)
    48  
    49          for item in test_data['expected_results']:
    50              uri = item
    51              expected_code = test_data['expected_results'][uri]
    52              ensure_response_from_backend(f"{req_url}{uri}", v_s_route_setup.vs_host)
    53              resp = requests.get(f"{req_url}{uri}", headers={"host": v_s_route_setup.vs_host})
    54              if expected_code == 200:
    55                  assert resp.status_code == expected_code and "Server name: backend2-" in resp.text
    56              else:
    57                  assert resp.status_code == expected_code, "Expected 404 for URI that doesn't match"
    58  
    59      def test_flow_for_invalid_vs(self, kube_apis,
    60                                   ingress_controller_prerequisites, crd_ingress_controller,
    61                                   v_s_route_setup, v_s_route_app_setup):
    62          ic_pod_name = get_first_pod_name(kube_apis.v1, ingress_controller_prerequisites.namespace)
    63          text_vs = f"{v_s_route_setup.namespace}/{v_s_route_setup.vs_name}"
    64          vs_event_text = f'VirtualServer {text_vs} was rejected with error: ' \
    65                          f'spec.routes[1].path: Duplicate value: "=/exact-match$request"'
    66          vs_src_yaml = f"{TEST_DATA}" \
    67                        f"/virtual-server-route-regexp-location/standard/virtual-server-invalid-duplicate-routes.yaml"
    68          patch_virtual_server_from_yaml(kube_apis.custom_objects, v_s_route_setup.vs_name,
    69                                         vs_src_yaml,
    70                                         v_s_route_setup.namespace)
    71          wait_before_test(2)
    72  
    73          vs_events = get_events(kube_apis.v1, v_s_route_setup.namespace)
    74          assert_vs_conf_not_exists(kube_apis, ic_pod_name, ingress_controller_prerequisites.namespace, v_s_route_setup)
    75          assert_event(vs_event_text, vs_events)
    76  
    77      def test_flow_for_invalid_vsr(self, kube_apis,
    78                                    ingress_controller_prerequisites, crd_ingress_controller,
    79                                    v_s_route_setup, v_s_route_app_setup):
    80          ic_pod_name = get_first_pod_name(kube_apis.v1, ingress_controller_prerequisites.namespace)
    81          text_vs = f"{v_s_route_setup.namespace}/{v_s_route_setup.vs_name}"
    82          text_vsr_s = f"{v_s_route_setup.route_m.namespace}/{v_s_route_setup.route_m.name}"
    83          vs_event_text = f'Configuration for {text_vs} was added or updated with warning(s)'
    84          vsr_event_text = f'VirtualServerRoute {text_vsr_s} was rejected with error: ' \
    85                           f'spec.subroutes[1].path: Duplicate value: "=/backends/exact-match$request"'
    86          vs_src_yaml = f"{TEST_DATA}" \
    87                        f"/virtual-server-route-regexp-location/standard/virtual-server-exact.yaml"
    88          patch_virtual_server_from_yaml(kube_apis.custom_objects, v_s_route_setup.vs_name,
    89                                         vs_src_yaml,
    90                                         v_s_route_setup.namespace)
    91          vsr_src_yaml = f"{TEST_DATA}" \
    92                         f"/virtual-server-route-regexp-location/route-multiple-invalid-multiple-regexp-subroutes.yaml"
    93          patch_v_s_route_from_yaml(kube_apis.custom_objects,
    94                                    v_s_route_setup.route_m.name,
    95                                    vsr_src_yaml,
    96                                    v_s_route_setup.route_m.namespace)
    97          wait_before_test(2)
    98  
    99          config = get_vs_nginx_template_conf(kube_apis.v1,
   100                                              v_s_route_setup.namespace,
   101                                              v_s_route_setup.vs_name,
   102                                              ic_pod_name,
   103                                              ingress_controller_prerequisites.namespace)
   104          ns_events = get_events(kube_apis.v1, v_s_route_setup.route_m.namespace)
   105          assert_event(vsr_event_text, ns_events) and assert_event(vs_event_text, ns_events)
   106          assert "location =/backends/exact-match$request {" not in config
   107  
   108  
   109  class VSRRegexpSetup:
   110      """
   111      Encapsulate advanced routing VSR example details.
   112  
   113      Attributes:
   114          namespace (str):
   115          vs_host (str):
   116          vs_name (str):
   117      """
   118  
   119      def __init__(self, namespace, vs_host, vs_name):
   120          self.namespace = namespace
   121          self.vs_host = vs_host
   122          self.vs_name = vs_name
   123  
   124  
   125  @pytest.fixture(scope="class")
   126  def vsr_regexp_setup(request, kube_apis,
   127                       ingress_controller_prerequisites, ingress_controller_endpoint, test_namespace) -> VSRRegexpSetup:
   128      """
   129      Prepare an example app for advanced routing VSR.
   130  
   131      Single namespace with VS+VSR and simple app.
   132  
   133      :param request: internal pytest fixture
   134      :param kube_apis: client apis
   135      :param ingress_controller_endpoint:
   136      :param ingress_controller_prerequisites:
   137      :param test_namespace:
   138      :return:
   139      """
   140      print("------------------------- Deploy Virtual Server -----------------------------------")
   141      vs_src_yaml = f"{TEST_DATA}/{request.param['example']}/additional-case/virtual-server-exact-over-all.yaml"
   142      vs_name = create_virtual_server_from_yaml(kube_apis.custom_objects, vs_src_yaml, test_namespace)
   143      vs_host = get_first_host_from_yaml(vs_src_yaml)
   144  
   145      print("------------------------- Deploy VSRs -----------------------------------")
   146      for item in ['prefix', 'exact', 'regexp']:
   147          create_v_s_route_from_yaml(kube_apis.custom_objects,
   148                                     f"{TEST_DATA}/{request.param['example']}/additional-case/route-{item}.yaml",
   149                                     test_namespace)
   150  
   151      print("---------------------- Deploy simple app ----------------------------")
   152      create_example_app(kube_apis, "extended", test_namespace)
   153      wait_until_all_pods_are_ready(kube_apis.v1, test_namespace)
   154  
   155      return VSRRegexpSetup(test_namespace, vs_host, vs_name)
   156  
   157  
   158  @pytest.mark.vsr
   159  @pytest.mark.parametrize('crd_ingress_controller, vsr_regexp_setup',
   160                           [({"type": "complete", "extra_args": [f"-enable-custom-resources"]},
   161                             {"example": "virtual-server-route-regexp-location"})],
   162                           indirect=True)
   163  class TestVSRRegexpMultipleMatches:
   164      def test_exact_match_overrides_all(self, kube_apis,
   165                                         ingress_controller_prerequisites, ingress_controller_endpoint,
   166                                         crd_ingress_controller, vsr_regexp_setup):
   167          req_url = f"http://{ingress_controller_endpoint.public_ip}:{ingress_controller_endpoint.port}"
   168          ensure_response_from_backend(f"{req_url}/backends/match", vsr_regexp_setup.vs_host)
   169          resp = requests.get(f"{req_url}/backends/match", headers={"host": vsr_regexp_setup.vs_host})
   170          assert resp.status_code == 200 and "Server name: backend2-" in resp.text
   171  
   172      def test_regexp_overrides_prefix(self, kube_apis,
   173                                       ingress_controller_prerequisites, ingress_controller_endpoint,
   174                                       crd_ingress_controller, vsr_regexp_setup):
   175          req_url = f"http://{ingress_controller_endpoint.public_ip}:{ingress_controller_endpoint.port}"
   176          vs_src_yaml = f"{TEST_DATA}" \
   177                        f"/virtual-server-route-regexp-location/additional-case/virtual-server-regexp-over-prefix.yaml"
   178          patch_virtual_server_from_yaml(kube_apis.custom_objects, vsr_regexp_setup.vs_name,
   179                                         vs_src_yaml,
   180                                         vsr_regexp_setup.namespace)
   181          wait_before_test(1)
   182          ensure_response_from_backend(f"{req_url}/backends/match", vsr_regexp_setup.vs_host)
   183          resp = requests.get(f"{req_url}/backends/match", headers={"host": vsr_regexp_setup.vs_host})
   184          assert resp.status_code == 200 and "Server name: backend3-" in resp.text