API reference¶
adc_locust.env_config
¶
Load, validate, and interactively create the .env file that supplies
Nitro API credentials and NetScaler address information.
Credentials are never hardcoded or logged. Values are read from a
gitignored .env file in the current working directory (or a path given
via --env-file / ADC_LOCUST_ENV_FILE), following the same pattern used
by the reference Nitro SDK scripts this project is built from.
EnvConfigError
¶
Bases: RuntimeError
Raised when required Nitro connection settings are missing.
NitroEnvConfig(nitro_user, nitro_pass, nitro_url, verify_tls=False)
dataclass
¶
Resolved Nitro API connection settings.
default_env_path()
¶
Return the default .env location: ADC_LOCUST_ENV_FILE or CWD/.env.
Source code in src/adc_locust/env_config.py
55 56 57 58 59 | |
load_env(path=None)
¶
Load and validate Nitro connection settings from a .env file.
Raises EnvConfigError with a human-readable explanation (including the contents to add) if the file is missing or incomplete.
Source code in src/adc_locust/env_config.py
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | |
missing_variables(path)
¶
Return the required variable names not present (or empty) in path.
Source code in src/adc_locust/env_config.py
68 69 70 71 72 73 | |
write_env(path, *, nitro_user, nitro_pass, nitro_url, verify_tls=False)
¶
Create or overwrite path with the given Nitro connection settings.
Used by the interactive setup screen so a .env can be produced without
leaving the Textual interface. The file is written with owner-only
permissions since it holds a plaintext credential.
Source code in src/adc_locust/env_config.py
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | |
adc_locust.nitro_client
¶
Read-only Nitro API client used to discover NetScaler load-balancing and content-switching configuration available for load testing.
Built from the patterns in list-vservers-multi-service.py, check-cs-targets.py, and dot_4485/locust/common/distribution_check.py (nitro reference project). All operations here are read-only queries against the ADC — no configuration is created, modified, or deleted.
BoundService(name, weight=None)
dataclass
¶
One service bound to an LB vserver.
CSPolicyBinding(policy_name, priority, rule, target_lbvserver)
dataclass
¶
One Content Switching policy bound to a CS vserver.
CSVServerInfo(name, ip, port, servicetype, state, default_lbvserver, policy_bindings=list())
dataclass
¶
A Content Switching vserver, its default target, and its policies.
target_for(lb_vserver_name)
¶
Return the policy binding routing to lb_vserver_name, if any.
Source code in src/adc_locust/nitro_client.py
101 102 103 104 105 106 | |
NitroClient(env)
¶
A read-only session against a NetScaler's Nitro API.
Use as a context manager so the session is always logged out:
with NitroClient(env) as client:
vservers = client.list_lb_vservers()
Source code in src/adc_locust/nitro_client.py
121 122 123 124 125 | |
connect()
¶
Log in to the Nitro API. Raises NitroConnectionError on failure.
Source code in src/adc_locust/nitro_client.py
127 128 129 130 131 132 133 134 135 136 137 | |
find_cs_target(lb_vserver_name)
¶
Find the CS vserver (and matching policy, if any) that routes to an unroutable LB vserver. Returns None if no CS vserver targets it.
Source code in src/adc_locust/nitro_client.py
233 234 235 236 237 238 239 240 241 242 | |
list_cs_vservers()
¶
Return all Content Switching vservers with their policy bindings.
Source code in src/adc_locust/nitro_client.py
196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 | |
list_lb_vservers(*, multi_service_only=True)
¶
Return LB vservers, optionally limited to those balancing traffic across more than one bound service (real load-balancing scenarios).
Source code in src/adc_locust/nitro_client.py
174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 | |
snapshot_service_hits(service_names)
¶
Return {service_name: totalrequests} for the given bound services.
Used to compare traffic distribution before/after a Locust run. Read-only — queries service_stats for each named service.
Source code in src/adc_locust/nitro_client.py
244 245 246 247 248 249 250 251 252 253 254 255 256 | |
NitroConnectionError
¶
Bases: RuntimeError
Raised when logging in to the NetScaler Nitro API fails.
adc_locust.locust_runner
¶
Build and run Locust load tests against a discovered NetScaler vserver.
Targets are derived from Nitro API discovery (see nitro_client.py) rather
than hardcoded, unlike the reference dot_4485/locust/common/config.py
which lists specific known vservers. Locust itself is invoked headless as
a subprocess, matching the documented usage in the reference project
(locust -f locustfile.py --tags fairness), so Locust's gevent runtime
never shares a process/event loop with the Textual UI.
LoadTestConfig(users=10, spawn_rate=2.0, run_time_seconds=30, mode=FAIRNESS)
dataclass
¶
Locust run parameters for a single test.
LoadTestError
¶
Bases: RuntimeError
Raised when Locust cannot be run or its results cannot be parsed.
LoadTestResult(request_count, failure_count, requests_per_second, median_response_time_ms, service_deltas, warnings)
dataclass
¶
Aggregated Locust stats plus the per-service distribution delta.
ServiceDelta(service_name, before, after)
dataclass
¶
Hit-count change for one bound service across a test run.
TestTarget(lb_vserver_name, target_host, target_port, scheme, host_header, path_prefix, via_content_switching, persistence, bound_services=list())
dataclass
¶
How to reach one vserver for load testing, and what it should show.
build_target(vserver, cs_match, *, port=443, scheme='https')
¶
Derive a reachable test target for a discovered LB vserver.
If the vserver has its own routable IP, target it directly. Otherwise it must be a Content Switching target (see nitro_client.find_cs_target); route through the CS vserver's IP with the Host header / rule path needed to match its policy, mirroring dot_4485/locust/common/config.py.
Source code in src/adc_locust/locust_runner.py
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | |
compare_service_hits(before, after)
¶
Compute per-service deltas and flag services that received far less than their expected even share of new traffic (see dot_4485/locust/common/distribution_check.py).
Source code in src/adc_locust/locust_runner.py
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 | |
generate_locustfile(target)
¶
Render a standalone Locust scenario module for target.
Includes both a fairness User (clears cookies every request, to reveal
the raw LB algorithm distribution) and a persistence User (retains
cookies, to confirm ADC stickiness), tagged as in the reference
scenarios so either can be selected with --tags.
Source code in src/adc_locust/locust_runner.py
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 | |
run_load_test(target, config)
¶
Run Locust headless against target and return aggregated results.
This call blocks for the duration of the run and should be invoked from a worker thread, not the UI thread. It does not itself query Nitro service stats — callers that want a distribution delta should snapshot with NitroClient.snapshot_service_hits() immediately before and after calling this, then pass both to compare_service_hits().
Source code in src/adc_locust/locust_runner.py
218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 | |
adc_locust.app
¶
ADC Locust: a Textual TUI for load-testing Citrix ADC load balancing and content switching using the Nitro API for discovery and Locust for traffic generation.
AdcLocustApp(env_path)
¶
Bases: App[None]
Discover NetScaler vservers via Nitro, then load-test them with Locust.
Source code in src/adc_locust/app.py
23 24 25 | |
main()
¶
Run the application.
Source code in src/adc_locust/app.py
57 58 59 60 | |