From 7249a9572c90e64d9b70ba22d372a34d1fd3b6a7 Mon Sep 17 00:00:00 2001 From: Benjamin Pelletier Date: Sun, 23 Aug 2026 18:34:15 +0000 Subject: [PATCH] Add multiple user types --- .../benchmarker/configurations/loads.py | 7 ++++-- .../engine/loads/user_ramp/user_ramp.py | 24 ++++++++++++++----- .../configurations/loads/UserRampLoad.json | 20 ++++++++++++---- 3 files changed, 39 insertions(+), 12 deletions(-) diff --git a/monitoring/benchmarker/configurations/loads.py b/monitoring/benchmarker/configurations/loads.py index a66446ece5..797c35bd59 100644 --- a/monitoring/benchmarker/configurations/loads.py +++ b/monitoring/benchmarker/configurations/loads.py @@ -156,11 +156,14 @@ class LoadCompletionCriteria(ImplicitDict): class UserRampLoad(ImplicitDict): - """Ramps up users of a specified type, observing resulting throughput.""" + """Ramps up users of specified type(s), observing resulting throughput.""" - user_type: BenchmarkUserName + user_type: Optional[BenchmarkUserName] """Type of user to instantiate.""" + user_types: Optional[list[BenchmarkUserName]] + """Types of users to instantiate, cycling through them in order as load increases.""" + initial_users: int = 1 """Number of users to start with.""" diff --git a/monitoring/benchmarker/engine/loads/user_ramp/user_ramp.py b/monitoring/benchmarker/engine/loads/user_ramp/user_ramp.py index ac4e302131..f30f7290ae 100644 --- a/monitoring/benchmarker/engine/loads/user_ramp/user_ramp.py +++ b/monitoring/benchmarker/engine/loads/user_ramp/user_ramp.py @@ -45,12 +45,21 @@ async def run_user_ramp_load( scenario_name: BenchmarkScenarioName, ) -> tuple[list[ExecutedOperation], list[BenchmarkScenarioStepReport]]: """Apply a load by driving virtual user workflows and monitoring step criteria.""" - ramp_user_type = ramp.user_type - if ramp_user_type not in user_specs_map: - raise ValueError( - f"User type '{ramp_user_type}' for UserRampLoad.user_type not found in configuration.user_types" - ) - user_spec = user_specs_map[ramp_user_type] + if "user_types" in ramp and ramp.user_types: + user_types_list = ramp.user_types + for ut in user_types_list: + if ut not in user_specs_map: + raise ValueError( + f"User type '{ut}' for UserRampLoad.user_types not found in configuration.user_types" + ) + elif "user_type" in ramp and ramp.user_type: + if ramp.user_type not in user_specs_map: + raise ValueError( + f"User type '{ramp.user_type}' for UserRampLoad.user_type not found in configuration.user_types" + ) + user_types_list = [ramp.user_type] + else: + raise ValueError("Neither user_type nor user_types specified for UserRampLoad") random = ( Random(ramp.random_seed) @@ -113,6 +122,9 @@ async def _periodic_summary_logger() -> None: first_user_spawned = None last_user_spawned = None while len(virtual_users) < current_load_factor: + user_spec = user_specs_map[ + user_types_list[len(virtual_users) % len(user_types_list)] + ] user_id = f"{user_spec.name}_{len(virtual_users) + 1}" if first_user_spawned is None: first_user_spawned = user_id diff --git a/schemas/monitoring/benchmarker/configurations/loads/UserRampLoad.json b/schemas/monitoring/benchmarker/configurations/loads/UserRampLoad.json index e95a4a71eb..605a1f799f 100644 --- a/schemas/monitoring/benchmarker/configurations/loads/UserRampLoad.json +++ b/schemas/monitoring/benchmarker/configurations/loads/UserRampLoad.json @@ -1,7 +1,7 @@ { "$id": "https://github.com/interuss/monitoring/blob/main/schemas/monitoring/benchmarker/configurations/loads/UserRampLoad.json", "$schema": "https://json-schema.org/draft/2020-12/schema", - "description": "Ramps up users of a specified type, observing resulting throughput.\n\nmonitoring.benchmarker.configurations.loads.UserRampLoad, as defined in monitoring/benchmarker/configurations/loads.py", + "description": "Ramps up users of specified type(s), observing resulting throughput.\n\nmonitoring.benchmarker.configurations.loads.UserRampLoad, as defined in monitoring/benchmarker/configurations/loads.py", "properties": { "$ref": { "description": "Path to content that replaces the $ref", @@ -47,14 +47,26 @@ }, "user_type": { "description": "Type of user to instantiate.", - "type": "string" + "type": [ + "string", + "null" + ] + }, + "user_types": { + "description": "Types of users to instantiate, cycling through them in order as load increases.", + "items": { + "type": "string" + }, + "type": [ + "array", + "null" + ] } }, "required": [ "load_completion_criteria", "step_completion_criteria", - "throughput_stability_criteria", - "user_type" + "throughput_stability_criteria" ], "type": "object" } \ No newline at end of file