@@ -18,7 +18,7 @@ It covers Admin, Free, and Premium and shows how to generate HTML/JUnit reports.
1818Create a venv and install deps:
1919
2020``` bash
21- cd maas_billing_tests_independent_v5_full
21+ cd maas_billing_tests_independent
2222python3 -m venv .venv
2323source .venv/bin/activate
2424pip install -r requirements.txt
@@ -38,32 +38,25 @@ oc login https://api.<cluster>:6443 --token '<your-user-token>'
3838oc whoami
3939```
4040
41- Maas API base URLs:
42-
43- # Preferred: apps-domain host (TLS + correct Host header)
44- APPS=$(oc get ingresses.config/cluster -o jsonpath='{.spec.domain}')
45- export MAAS_API_BASE_URL="https://maas-api.${APPS} "
46- export USAGE_API_BASE="${MAAS_API_BASE_URL}" # used by usage tests
47-
48- # Fallback (commented): ELB endpoint + explicit Host header
49- # HOST=$(oc -n openshift-ingress get gateway openshift-ai-inference -o jsonpath='{.status.addresses[ 0] .value}')
50- # curl -H "Host: maas-api.${APPS}" "http://${HOST}/v1/models"
51-
41+ Get Gateway Endpoint and set base URLs:
5242
43+ ``` bash
44+ HOST=$( oc -n openshift-ingress get gateway openshift-ai-inference -o jsonpath=' {.status.addresses[0].value}' )
45+ export MAAS_API_BASE_URL=" http://${HOST} /maas-api"
46+ export USAGE_API_BASE=" ${MAAS_API_BASE_URL} " # used by usage tests
47+ ```
5348Export the ** current user’s** OpenShift token into ` FREE_OC_TOKEN `
5449(the tests use this name for “who you are right now”):
5550
5651``` bash
5752export FREE_OC_TOKEN=" $( oc whoami -t) "
5853```
59-
6054Pick a ** MODEL_NAME** from the catalog (` id ` field):
6155
6256``` bash
6357curl -s -H " Authorization: Bearer ${FREE_OC_TOKEN} " " ${MAAS_API_BASE_URL} /v1/models" | jq -r ' .data[] | [.id,.name,.url] | @tsv'
6458export MODEL_NAME=" <paste-id-from-output>" # e.g., facebook-opt-125m-simulated
6559```
66-
6760---
6861
6962## 2) Configure limits the tests will use
@@ -74,16 +67,16 @@ Read your gateway **RateLimitPolicy** values and export them so the tests know
7467what to expect:
7568
7669``` bash
77- # Free (update the jsonpath if your CR layout differs )
70+ # FREE request-rate burst (per window )
7871export RATE_LIMIT_BURST_FREE=$(
79- oc -n openshift-ingress get ratelimitpolicies.gateway.networking.k8s .io gateway-rate-limits \
72+ oc -n openshift-ingress get ratelimitpolicies.kuadrant .io gateway-rate-limits \
8073 -o jsonpath=' {.spec.limits.free.rates[0].limit}'
8174)
8275
8376# Premium (optional; only needed for the Free-vs-Premium test)
8477export RATE_LIMIT_BURST_PREMIUM=$(
85- oc -n openshift-ingress get ratelimitpolicies.gateway.networking.k8s .io gateway-rate-limits \
86- -o jsonpath=' {.spec.limits.premium .rates[0].limit}'
78+ oc -n openshift-ingress get ratelimitpolicies.kuadrant .io gateway-rate-limits \
79+ -o jsonpath=' {.spec.limits.enterprise .rates[0].limit}'
8780)
8881```
8982
@@ -108,9 +101,11 @@ The suite assumes **`FREE_OC_TOKEN`** holds the *current* user’s token.
108101### A) Admin (sanity / wiring)
109102
110103``` bash
111- pytest -q tests/test_tokens.py::test_minted_token_is_jwt
112- pytest -q tests/test_models_user.py
113- pytest -q tests/test_gateway_endpoints.py::test_chat_completion_works
104+
105+ pytest -q testing/maas_billing_tests_independent/tests/test_tokens.py::test_minted_token_is_jwt
106+ pytest -q testing/maas_billing_tests_independent/tests/test_models_user.py
107+ pytest -q testing/maas_billing_tests_independent/tests/test_gateway_endpoints.py::test_chat_completion_works
108+
114109```
115110
116111### B) Free user (authz + request-rate burst + usage)
@@ -120,35 +115,35 @@ pytest -q tests/test_gateway_endpoints.py::test_chat_completion_works
120115export FREE_OC_TOKEN=" $( oc whoami -t) "
121116
122117# basics
123- pytest -q tests/test_tokens.py::test_minted_token_is_jwt
124- pytest -q tests/test_models_user.py
125- pytest -q tests/test_gateway_endpoints.py::test_chat_completion_works
118+ pytest -q testing/maas_billing_tests_independent/ tests/test_tokens.py::test_minted_token_is_jwt
119+ pytest -q testing/maas_billing_tests_independent/ tests/test_models_user.py
120+ pytest -q testing/maas_billing_tests_independent/ tests/test_gateway_endpoints.py::test_chat_completion_works
126121
127122# request-rate burst (expects some 429s after RATE_LIMIT_BURST_FREE)
128- pytest -q tests/test_quota_global.py::test_rate_limit_burst
123+ pytest -q testing/maas_billing_tests_independent/ tests/test_quota_global.py::test_rate_limit_burst
129124
130125# usage (optional; requires USAGE_API_BASE)
131- pytest -q tests/test_usage_logs.py
126+ pytest -q testing/maas_billing_tests_independent/ tests/test_usage_logs.py
132127```
133128
134129#### Token‑rate for Free
135130Trigger token-based limiting by making each call expensive in tokens:
136131``` bash
137132export TOKENS_PER_CALL_LARGE=1200
138- pytest -q tests/test_token_ratelimit.py
133+ pytest -q testing/maas_billing_tests_independent/ tests/test_token_ratelimit.py
139134```
140135
141136#### Interplay for Free — which limiter fires first?
142137** Request‑rate first:** many * cheap* calls
143138``` bash
144139export TOKENS_PER_CALL_SMALL=16
145140export BURST_SLEEP=0.05
146- pytest -q tests/test_quota_global.py::test_rate_limit_burst
141+ pytest -q testing/maas_billing_tests_independent/ tests/test_quota_global.py::test_rate_limit_burst
147142```
148143** Token‑rate first:** few * expensive* calls
149144``` bash
150145export TOKENS_PER_CALL_LARGE=1200
151- pytest -q tests/test_token_ratelimit.py
146+ pytest -q testing/maas_billing_tests_independent/ tests/test_token_ratelimit.py
152147```
153148
154149### C) Premium user (same flow + Free-vs-Premium comparison)
@@ -158,31 +153,31 @@ pytest -q tests/test_token_ratelimit.py
158153export FREE_OC_TOKEN=" $( oc whoami -t) " # current user’s token again
159154export PREMIUM_OC_TOKEN=" $FREE_OC_TOKEN " # used by the test to mint for premium
160155
161- pytest -q tests/test_gateway_endpoints.py::test_chat_completion_works
156+ pytest -q testing/maas_billing_tests_independent/ tests/test_gateway_endpoints.py::test_chat_completion_works
162157
163158# Compare Free vs Premium burst; Premium must not be worse than Free
164159# (uses RATE_LIMIT_BURST_FREE / RATE_LIMIT_BURST_PREMIUM)
165- pytest -q tests/test_quota_per_user.py::test_free_vs_premium_quota
160+ pytest -q testing/maas_billing_tests_independent/ tests/test_quota_per_user.py::test_free_vs_premium_quota
166161```
167162
168163#### Token‑rate for Premium
169164Run the token limiter test while logged in as your Premium user:
170165``` bash
171166export TOKENS_PER_CALL_LARGE=1200
172- pytest -q tests/test_token_ratelimit.py
167+ pytest -q testing/maas_billing_tests_independent/ tests/test_token_ratelimit.py
173168```
174169
175170#### Interplay for Premium — which limiter fires first?
176171** Request‑rate first:** many * cheap* calls (uses ` RATE_LIMIT_BURST_PREMIUM ` if you exported it)
177172``` bash
178173export TOKENS_PER_CALL_SMALL=16
179174export BURST_SLEEP=0.05
180- pytest -q tests/test_quota_global.py::test_rate_limit_burst
175+ pytest -q testing/maas_billing_tests_independent/ tests/test_quota_global.py::test_rate_limit_burst
181176```
182177** Token‑rate first:** few * expensive* calls
183178``` bash
184179export TOKENS_PER_CALL_LARGE=1200
185- pytest -q tests/test_token_ratelimit.py
180+ pytest -q testing/maas_billing_tests_independent/ tests/test_token_ratelimit.py
186181```
187182
188183### D) Token-rate (current user – Free ** or** Premium)
@@ -191,7 +186,7 @@ If you want to *exercise* token-rate limiting, increase tokens per call to make
191186
192187``` bash
193188export TOKENS_PER_CALL_LARGE=1200 # example value to drive token usage
194- pytest -q tests/test_token_ratelimit.py
189+ pytest -q testing/maas_billing_tests_independent/ tests/test_token_ratelimit.py
195190```
196191
197192---
@@ -206,12 +201,12 @@ By shaping traffic as above (many *cheap* calls vs few *expensive* calls), you c
206201## 4) Reports (HTML & JUnit)
207202
208203``` bash
209- mkdir -p reports
204+ mkdir -p testing/maas_billing_tests_independent/ reports
210205
211206# Example: run everything for the current user and produce reports
212- pytest -q \
213- --html=reports/current.html --self-contained-html \
214- --junitxml=reports/current.xml
207+ pytest -q testing/maas_billing_tests_independent/tests \
208+ --html=testing/maas_billing_tests_independent/ reports/current.html --self-contained-html \
209+ --junitxml=testing/maas_billing_tests_independent/ reports/current.xml
215210```
216211
217212Open ` reports/current.html ` in your browser.
@@ -235,21 +230,7 @@ Open `reports/current.html` in your browser.
235230
236231---
237232
238- ## 6) Troubleshooting
239-
240- - ** 401 Unauthorized** – ensure you exported ` FREE_OC_TOKEN="$(oc whoami -t)" ` in this shell.
241- - ** 404 on chat** – the test already posts to ** ` <model-url>/v1/chat/completions ` ** .
242- If you edited anything, make sure you didn’t send to ` /maas-api/v1/chat/completions ` .
243- - ** Burst test returns 429 too early** – your exported ` RATE_LIMIT_BURST_FREE ` is higher than
244- the actual policy. Re-read the CR and export the real value (or lower ` N_BURST ` if you set it).
245- - ** Never see 429** – increase ` N_BURST ` or verify the RateLimitPolicy is ** Accepted/Enforced**
246- in the ` openshift-ingress ` project.
247- - ** WSL vs PowerShell** – they’re separate shells; log in and re-export vars in whichever one
248- you use to run ` pytest ` .
249-
250- ---
251-
252- ## 7) PowerShell equivalents (Windows)
233+ ## 6) PowerShell equivalents (Windows)
253234
254235``` powershell
255236# venv
@@ -319,10 +300,10 @@ export TOKENS_PER_CALL_SMALL=16
319300export BURST_SLEEP=0.05
320301
321302# run a few
322- pytest -q tests/test_tokens.py::test_minted_token_is_jwt
323- pytest -q tests/test_models_user.py
324- pytest -q tests/test_gateway_endpoints.py::test_chat_completion_works
325- pytest -q tests/test_quota_global.py::test_rate_limit_burst
303+ pytest -q testing/maas_billing_tests_independent/ tests/test_tokens.py::test_minted_token_is_jwt
304+ pytest -q testing/maas_billing_tests_independent/ tests/test_models_user.py
305+ pytest -q testing/maas_billing_tests_independent/ tests/test_gateway_endpoints.py::test_chat_completion_works
306+ pytest -q testing/maas_billing_tests_independent/ tests/test_quota_global.py::test_rate_limit_burst
326307
327308# report
328309mkdir -p reports && pytest -q --html=reports/current.html --self-contained-html --junitxml=reports/current.xml
0 commit comments