github.com/nginxinc/kubernetes-ingress@v1.12.5/tests/suite/test_rl_policies.py (about) 1 import pytest, requests, time 2 from kubernetes.client.rest import ApiException 3 from suite.resources_utils import wait_before_test, replace_configmap_from_yaml 4 from suite.custom_resources_utils import ( 5 read_custom_resource, 6 delete_virtual_server, 7 create_virtual_server_from_yaml, 8 patch_virtual_server_from_yaml, 9 create_policy_from_yaml, 10 delete_policy, 11 read_policy, 12 ) 13 from settings import TEST_DATA, DEPLOYMENTS 14 15 std_vs_src = f"{TEST_DATA}/rate-limit/standard/virtual-server.yaml" 16 rl_pol_pri_src = f"{TEST_DATA}/rate-limit/policies/rate-limit-primary.yaml" 17 rl_vs_pri_src = f"{TEST_DATA}/rate-limit/spec/virtual-server-primary.yaml" 18 rl_pol_sec_src = f"{TEST_DATA}/rate-limit/policies/rate-limit-secondary.yaml" 19 rl_vs_sec_src = f"{TEST_DATA}/rate-limit/spec/virtual-server-secondary.yaml" 20 rl_pol_invalid = f"{TEST_DATA}/rate-limit/policies/rate-limit-invalid.yaml" 21 rl_vs_invalid = f"{TEST_DATA}/rate-limit/spec/virtual-server-invalid.yaml" 22 rl_vs_override_spec = f"{TEST_DATA}/rate-limit/spec/virtual-server-override.yaml" 23 rl_vs_override_route = f"{TEST_DATA}/rate-limit/route-subroute/virtual-server-override-route.yaml" 24 rl_vs_override_spec_route = ( 25 f"{TEST_DATA}/rate-limit/route-subroute/virtual-server-override-spec-route.yaml" 26 ) 27 28 29 @pytest.mark.policies 30 @pytest.mark.parametrize( 31 "crd_ingress_controller, virtual_server_setup", 32 [ 33 ( 34 { 35 "type": "complete", 36 "extra_args": [ 37 f"-enable-custom-resources", 38 f"-enable-preview-policies", 39 f"-enable-leader-election=false", 40 ], 41 }, 42 {"example": "rate-limit", "app_type": "simple",}, 43 ) 44 ], 45 indirect=True, 46 ) 47 class TestRateLimitingPolicies: 48 def restore_default_vs(self, kube_apis, virtual_server_setup) -> None: 49 """ 50 Restore VirtualServer without policy spec 51 """ 52 delete_virtual_server( 53 kube_apis.custom_objects, virtual_server_setup.vs_name, virtual_server_setup.namespace 54 ) 55 create_virtual_server_from_yaml( 56 kube_apis.custom_objects, std_vs_src, virtual_server_setup.namespace 57 ) 58 wait_before_test() 59 60 @pytest.mark.smoke 61 @pytest.mark.parametrize("src", [rl_vs_pri_src]) 62 def test_rl_policy_1rs( 63 self, kube_apis, crd_ingress_controller, virtual_server_setup, test_namespace, src, 64 ): 65 """ 66 Test if rate-limiting policy is working with 1 rps 67 """ 68 print(f"Create rl policy") 69 pol_name = create_policy_from_yaml(kube_apis.custom_objects, rl_pol_pri_src, test_namespace) 70 print(f"Patch vs with policy: {src}") 71 patch_virtual_server_from_yaml( 72 kube_apis.custom_objects, 73 virtual_server_setup.vs_name, 74 src, 75 virtual_server_setup.namespace, 76 ) 77 78 wait_before_test() 79 policy_info = read_custom_resource(kube_apis.custom_objects, test_namespace, "policies", pol_name) 80 occur = [] 81 t_end = time.perf_counter() + 1 82 resp = requests.get( 83 virtual_server_setup.backend_1_url, headers={"host": virtual_server_setup.vs_host}, 84 ) 85 print(resp.status_code) 86 assert resp.status_code == 200 87 while time.perf_counter() < t_end: 88 resp = requests.get( 89 virtual_server_setup.backend_1_url, headers={"host": virtual_server_setup.vs_host}, 90 ) 91 occur.append(resp.status_code) 92 delete_policy(kube_apis.custom_objects, pol_name, test_namespace) 93 self.restore_default_vs(kube_apis, virtual_server_setup) 94 assert ( 95 policy_info["status"] 96 and policy_info["status"]["reason"] == "AddedOrUpdated" 97 and policy_info["status"]["state"] == "Valid" 98 ) 99 assert occur.count(200) <= 1 100 101 @pytest.mark.parametrize("src", [rl_vs_sec_src]) 102 def test_rl_policy_10rs( 103 self, kube_apis, crd_ingress_controller, virtual_server_setup, test_namespace, src, 104 ): 105 """ 106 Test if rate-limiting policy is working with 10 rps 107 """ 108 rate_sec = 10 109 print(f"Create rl policy") 110 pol_name = create_policy_from_yaml(kube_apis.custom_objects, rl_pol_sec_src, test_namespace) 111 print(f"Patch vs with policy: {src}") 112 patch_virtual_server_from_yaml( 113 kube_apis.custom_objects, 114 virtual_server_setup.vs_name, 115 src, 116 virtual_server_setup.namespace, 117 ) 118 119 wait_before_test() 120 policy_info = read_custom_resource(kube_apis.custom_objects, test_namespace, "policies", pol_name) 121 occur = [] 122 t_end = time.perf_counter() + 1 123 resp = requests.get( 124 virtual_server_setup.backend_1_url, headers={"host": virtual_server_setup.vs_host}, 125 ) 126 assert resp.status_code == 200 127 while time.perf_counter() < t_end: 128 resp = requests.get( 129 virtual_server_setup.backend_1_url, headers={"host": virtual_server_setup.vs_host}, 130 ) 131 occur.append(resp.status_code) 132 delete_policy(kube_apis.custom_objects, pol_name, test_namespace) 133 self.restore_default_vs(kube_apis, virtual_server_setup) 134 assert ( 135 policy_info["status"] 136 and policy_info["status"]["reason"] == "AddedOrUpdated" 137 and policy_info["status"]["state"] == "Valid" 138 ) 139 assert rate_sec >= occur.count(200) >= (rate_sec - 2) 140 141 @pytest.mark.parametrize("src", [rl_vs_invalid]) 142 def test_rl_policy_invalid( 143 self, kube_apis, crd_ingress_controller, virtual_server_setup, test_namespace, src, 144 ): 145 """ 146 Test the status code is 500 if invalid policy is deployed 147 """ 148 print(f"Create rl policy") 149 invalid_pol_name = create_policy_from_yaml( 150 kube_apis.custom_objects, rl_pol_invalid, test_namespace 151 ) 152 print(f"Patch vs with policy: {src}") 153 patch_virtual_server_from_yaml( 154 kube_apis.custom_objects, 155 virtual_server_setup.vs_name, 156 src, 157 virtual_server_setup.namespace, 158 ) 159 160 wait_before_test() 161 policy_info = read_custom_resource( 162 kube_apis.custom_objects, test_namespace, "policies", invalid_pol_name 163 ) 164 resp = requests.get( 165 virtual_server_setup.backend_1_url, headers={"host": virtual_server_setup.vs_host}, 166 ) 167 print(resp.text) 168 delete_policy(kube_apis.custom_objects, invalid_pol_name, test_namespace) 169 self.restore_default_vs(kube_apis, virtual_server_setup) 170 assert ( 171 policy_info["status"] 172 and policy_info["status"]["reason"] == "Rejected" 173 and policy_info["status"]["state"] == "Invalid" 174 ) 175 assert resp.status_code == 500 176 177 @pytest.mark.parametrize("src", [rl_vs_pri_src]) 178 def test_rl_policy_deleted( 179 self, kube_apis, crd_ingress_controller, virtual_server_setup, test_namespace, src, 180 ): 181 """ 182 Test the status code if 500 is valid policy is removed 183 """ 184 print(f"Create rl policy") 185 pol_name = create_policy_from_yaml(kube_apis.custom_objects, rl_pol_pri_src, test_namespace) 186 print(f"Patch vs with policy: {src}") 187 patch_virtual_server_from_yaml( 188 kube_apis.custom_objects, 189 virtual_server_setup.vs_name, 190 src, 191 virtual_server_setup.namespace, 192 ) 193 wait_before_test() 194 resp = requests.get( 195 virtual_server_setup.backend_1_url, headers={"host": virtual_server_setup.vs_host}, 196 ) 197 assert resp.status_code == 200 198 delete_policy(kube_apis.custom_objects, pol_name, test_namespace) 199 wait_before_test() 200 resp = requests.get( 201 virtual_server_setup.backend_1_url, headers={"host": virtual_server_setup.vs_host}, 202 ) 203 self.restore_default_vs(kube_apis, virtual_server_setup) 204 assert resp.status_code == 500 205 206 @pytest.mark.parametrize("src", [rl_vs_override_spec, rl_vs_override_route]) 207 def test_rl_override( 208 self, kube_apis, crd_ingress_controller, virtual_server_setup, test_namespace, src, 209 ): 210 """ 211 List multiple policies in vs and test if the one with less rps is used 212 """ 213 print(f"Create rl policy") 214 pol_name_pri = create_policy_from_yaml( 215 kube_apis.custom_objects, rl_pol_pri_src, test_namespace 216 ) 217 pol_name_sec = create_policy_from_yaml( 218 kube_apis.custom_objects, rl_pol_sec_src, test_namespace 219 ) 220 print(f"Patch vs with policy: {src}") 221 patch_virtual_server_from_yaml( 222 kube_apis.custom_objects, 223 virtual_server_setup.vs_name, 224 src, 225 virtual_server_setup.namespace, 226 ) 227 wait_before_test() 228 occur = [] 229 t_end = time.perf_counter() + 1 230 resp = requests.get( 231 virtual_server_setup.backend_1_url, headers={"host": virtual_server_setup.vs_host}, 232 ) 233 assert resp.status_code == 200 234 while time.perf_counter() < t_end: 235 resp = requests.get( 236 virtual_server_setup.backend_1_url, headers={"host": virtual_server_setup.vs_host}, 237 ) 238 occur.append(resp.status_code) 239 delete_policy(kube_apis.custom_objects, pol_name_pri, test_namespace) 240 delete_policy(kube_apis.custom_objects, pol_name_sec, test_namespace) 241 self.restore_default_vs(kube_apis, virtual_server_setup) 242 assert occur.count(200) <= 1 243 244 @pytest.mark.parametrize("src", [rl_vs_override_spec_route]) 245 def test_rl_override_spec_route( 246 self, kube_apis, crd_ingress_controller, virtual_server_setup, test_namespace, src, 247 ): 248 """ 249 List policies in vs spec and route resp. and test if route overrides spec 250 route:policy = secondary (10 rps) 251 spec:policy = primary (1 rps) 252 """ 253 rate_sec = 10 254 print(f"Create rl policy") 255 pol_name_pri = create_policy_from_yaml( 256 kube_apis.custom_objects, rl_pol_pri_src, test_namespace 257 ) 258 pol_name_sec = create_policy_from_yaml( 259 kube_apis.custom_objects, rl_pol_sec_src, test_namespace 260 ) 261 print(f"Patch vs with policy: {src}") 262 patch_virtual_server_from_yaml( 263 kube_apis.custom_objects, 264 virtual_server_setup.vs_name, 265 src, 266 virtual_server_setup.namespace, 267 ) 268 wait_before_test() 269 occur = [] 270 t_end = time.perf_counter() + 1 271 resp = requests.get( 272 virtual_server_setup.backend_1_url, headers={"host": virtual_server_setup.vs_host}, 273 ) 274 assert resp.status_code == 200 275 while time.perf_counter() < t_end: 276 resp = requests.get( 277 virtual_server_setup.backend_1_url, headers={"host": virtual_server_setup.vs_host}, 278 ) 279 occur.append(resp.status_code) 280 delete_policy(kube_apis.custom_objects, pol_name_pri, test_namespace) 281 delete_policy(kube_apis.custom_objects, pol_name_sec, test_namespace) 282 self.restore_default_vs(kube_apis, virtual_server_setup) 283 assert rate_sec >= occur.count(200) >= (rate_sec - 2)