test(performance): Refactor resource tests, and address PR feedback

This commit is contained in:
sumit_chaturvedi
2025-06-16 19:06:13 +05:30
parent 5050345beb
commit 75da655059
3 changed files with 84 additions and 34 deletions
+50 -22
View File
@@ -1,38 +1,66 @@
from locust import HttpUser, task, events
from utils.helpers import get_api_token, get_auth_headers, get_random_resource_id
from locust import task, events
from utils.helpers import (
APIUserBase,
get_api_token,
get_auth_headers,
get_sort_value,
get_available_resource_filters ,
get_next_resource_filter
)
from utils.config import (
RESOURCES_UI_SORT_VALUES,
RESOURCE_INSERTED_AT,
)
GLOBAL = {"token": None, "resource_ids": []}
GLOBAL = {"token": None, "resource_ids": [], "resource_filters": None}
@events.test_start.add_listener
def on_test_start(environment, **kwargs):
GLOBAL["token"] = get_api_token(environment.host)
GLOBAL["resource_filters"] = get_available_resource_filters(environment.host, GLOBAL["token"])
class ResourceUser(HttpUser):
class ResourceUser(APIUserBase):
def on_start(self):
self.token = GLOBAL["token"]
self.headers = get_auth_headers(self.token)
self.available_resource_filters = GLOBAL["resource_filters"]
with self.client.get(
"/resources", headers=self.headers, name="/resources", catch_response=True
) as response:
if response.status_code == 200:
json_data = response.json()
GLOBAL["resource_ids"] = [
item["id"] for item in json_data.get("data", [])[:10]
]
else:
response.failure("Failed to load /resources")
@task
def resources_default(self):
name = "GET /resources"
page_number = self._next_page(name)
endpoint = (
f"/resources?page[number]={page_number}"
f"&{get_sort_value(RESOURCES_UI_SORT_VALUES)}"
)
self.client.get(endpoint, headers=get_auth_headers(self.token), name=name)
@task(3)
def list_resources(self):
self.client.get("/resources", headers=self.headers, name="/resources")
def resource_with_include(self):
name = "GET /resources (with include)"
page = self._next_page(name)
endpoint = (
f"/resources?page[number]={page}"
f"&{get_sort_value(RESOURCES_UI_SORT_VALUES)}"
f"&include=findings,provider"
)
self.client.get(endpoint, headers=get_auth_headers(self.token), name=name)
@task(2)
def get_single_resource(self):
if GLOBAL["resource_ids"]:
resource_id = get_random_resource_id(GLOBAL["resource_ids"])
self.client.get(
f"/resources/{resource_id}", headers=self.headers, name="/resources/:id"
)
def resource_filter(self):
name = "GET /resources (random filter)"
filter_type, filter_value = get_next_resource_filter(self.available_resource_filters)
endpoint = f"/resources?filter[{filter_type}]={filter_value}"
self.client.get(endpoint, headers=get_auth_headers(self.token), name=name)
@task(2)
def resource_filter_with_include(self):
name = "GET /resources (random filter + include)"
filter_type, filter_value = get_next_resource_filter(self.available_resource_filters)
endpoint = (
f"/resources?filter[{filter_type}]={filter_value}"
f"&include=findings,provider"
)
self.client.get(endpoint, headers=get_auth_headers(self.token), name=name)
+3
View File
@@ -17,3 +17,6 @@ FINDINGS_RESOURCE_METADATA = {
S_PROVIDER_NAME = "provider-50k"
M_PROVIDER_NAME = "provider-250k"
L_PROVIDER_NAME = "provider-500k"
RESOURCES_UI_SORT_VALUES = ["name", "region", "inserted_at"]
RESOURCE_INSERTED_AT = os.environ.get("RESOURCE_INSERTED_AT", "2025-04-14")
+31 -12
View File
@@ -167,23 +167,42 @@ def get_sort_value(sort_values: list) -> str:
"""
return f"sort={','.join(sort_values)}"
def get_random_resource_id(resource_list):
def get_available_resource_filters(host: str, token: str) -> dict:
"""
Selects and returns a random resource ID from the provided list.
Fetches and returns available resource filter values from the API.
Args:
resource_list (list): A list of resource IDs.
host (str): The host URL of the API.
token (str): Bearer token for authentication.
Returns:
Any: A randomly selected resource ID from the list.
dict: A dictionary containing lists of unique values for each resource filter type.
Example:
{
"service": ["ec2", "s3", "rds"],
"type": ["instance", "bucket"],
"region": ["us-east-1", "us-west-2"]
}
Raises:
ValueError: If the provided list is empty.
Example:
resource_id = get_random_resource_id(GLOBAL["resource_ids"])
AssertionError: If the API request fails or does not return a 200 status code.
"""
if not resource_list:
raise ValueError("The resource list is empty.")
return random.choice(resource_list)
url = f"{host}/resources"
params = {
"fields[resources]": "type,region,service"
}
response = requests.get(url, headers=get_auth_headers(token), params=params)
assert response.status_code == 200, f"Failed to fetch filters: {response.text}"
resources = response.json()["data"]
filters = {"service": set(), "type": set(), "region": set()}
for res in resources:
attr = res["attributes"]
filters["service"].add(attr["service"])
filters["type"].add(attr["type"])
filters["region"].add(attr["region"])
return {k: list(v) for k, v in filters.items()}