k6 load tests for MIT Open Learning
properties. Each property lives in its own directory; today that is
learn/, covering MIT Learn's API and frontend.
With k6 installed locally:
k6 run learn/learn.smoke.ts -e BACKEND_BASE_URL=#### -e FRONTEND_BASE_URL=####Or in Docker, which needs no local k6 and brings its own browser. The repo root
is mounted at /app, so scripts are addressed by their path within it:
./scripts/k6.sh /app/learn/learn.smoke.ts -e BACKEND_BASE_URL=#### -e FRONTEND_BASE_URL=####To check that a script compiles and all its imports resolve without sending any traffic:
k6 archive learn/learn.smoke.tsThe numbers for average-load and stress should be revisited over time.
| Script | Purpose |
|---|---|
learn/learn.smoke.ts |
Lightweight smoke testing of deployments (4 users) |
learn/learn.average-load.ts |
An average amount of user load (100 users) |
learn/learn.stress.ts |
A stressful amount of user load (200 users) |
learn/channels.compare.ts |
Per-endpoint timings for the channels API, for comparing two runs |
Each of the first three splits its virtual users evenly between a backend API scenario and a browser scenario driving the frontend.
For base URLs, include the port number if you reach the service through one.
| Name | Description | Example |
|---|---|---|
BACKEND_BASE_URL |
Base URL of the backend API service. | https://api.learn.odl.local |
FRONTEND_BASE_URL |
Base URL of the frontend service. | https://learn.odl.local |
SSO_BASE_URL |
Base URL of the Keycloak service. | https://keycloak.odl.local |
IGNORE_HTTPS_ERRORS |
Ignore HTTPS certificate errors. Only for local test certificates. | true |
USERS_JSON_FILE |
Credentials for the browser login journey, as [{"email": "<EMAIL>", "password": "<PASSWORD>"}, ...]. Resolved relative to the script, so put it under learn/data/, which is gitignored. |
data/users.json |
AUTH_ACCESS_TOKEN |
Bearer token for the backend API scenario. Without it, authenticated API checks are skipped. |
channels.compare.ts additionally takes VUS (default 15), DURATION
(default 3m), RUN_LABEL (default run, names the output file) and
CHANNEL_NAME_PREFIX, which narrows the test to channels whose names start with
the given prefix.
Credentials are secrets and this repository is public. learn/data/ is
gitignored for that reason — keep credential files there and nowhere else.
learn/backend/client/v0/api.ts and v1/api.ts are generated by
k6 x openapi from MIT
Learn's published OpenAPI schema. Do not edit them by hand:
./scripts/generate-from-openapi.shSet LEARN_API_BASE_URL to generate against a deployment other than production.
k6 x openapi is a k6 subcommand extension, so the script downloads a k6 built
with it into .cache/, pinned by version and checksum. That binary is needed
only to generate: the clients it writes are plain TypeScript and the tests run
on a stock k6.
Read the generator's stderr. It logs a warning for every descriptor construct it
skips or approximates, and exits 0 anyway. Against production it currently warns
twice about /api/v1/contentfiles/, whose path parameters the schema declares
incompletely; no operation the tests call is affected.
Every generated method is async, so each call site awaits it and tags both
its request and its check with endpoint rather than nesting them in a k6
group(), which rejects an async callback unless k6 runs with
--features async-metric-context.
yarn install
yarn lint # biome
yarn typecheck # see the note belowyarn typecheck currently reports 8 pre-existing errors, all in
learn/backend/test.ts, which treats JSONValue as an array. CI does not gate
on it yet.