Skip to content
Français
Cloud medium

Measure what the emulator serves and how faithful it is

2 min de lecture

Read this page in French

feint does more than answer: it reports what it served, what a client actually drove, and what a real cloud would return in its place. These three mechanisms serve one goal, knowing whether a test proves anything: an introspection page served by the binary, a recording proxy that measures instead of guessing, and snapshots to replay a dataset as often as needed.

What you will get

By the end of this page, you will be able to say what your test actually went through: which routes a real client drove, what a real cloud would return instead, and how to come back to a known dataset.

  • Read the page the emulator serves about itself, and its three counters.
  • Tell apart a mounted route, a probed route and a driven route.
  • Record what an official client sends, without leaking a credential.
  • Return to a known test state, as often as you need.

How to see what the emulator really served

feint ui opens a page the binary serves about itself, at http://127.0.0.1:4599/_feint/ui. No second port, no second process, no build step: three files embedded in the binary. It answers the question neither the logs nor status fully cover: what was mounted, exercised, and by what.

Fenêtre de terminal
feint ui

The feint 0.13.0 page: 395 operations mounted, those a real client drove, and the inventory of resources created per provider

The top of the page is a counter that does not add up, and that is deliberate. The three numbers stay separate because they are not worth the same: a mounted route exists, a probed route answers the protocol correctly, a route driven by a real client is the only one whose behaviour is demonstrated. The bar shows the probed share hatched rather than solid, for the same reason.

The rest of the page shows the session's inventory, read from the internal store rather than from a provider API, with full attributes and a search; the gap with the upstream surface, product by product, where each declined operation carries its written reason; and a call log that reports two things no other tool surfaces: fields a client sent that no handler read, and fields a response carried that the provider's API description does not define.

The page is read-only and served on the loopback interface only. Off loopback it is not hidden, it does not exist. There is no authentication, and that is a reasoned choice rather than an oversight: a password would protect the wrong boundary, since the risk is a malicious page open in the operator's browser, which would inherit whatever secrets that same browser holds.

The same event ring is readable by a script, which makes it a mechanism rather than merely a screen:

Fenêtre de terminal
curl -s localhost:4599/_feint/trace \
| jq -r '.exchanges[] | "\(.method) \(.path) \(.status) \(.operation // "no route")"'
GET /v2/instance-type 200 exoscale/v2.list-instance-types
GET /v2/zone 200 exoscale/v2.list-zones
GET /v2/quota 200 exoscale/v2.list-quotas

Three more endpoints complete the set for tooling: /_feint/conformance carries the per-operation detail, /_feint/resources publishes the inventory, and /_feint/health answers the state and the capabilities of the current mode.

How to return to a known state

feint snapshot names a running emulator's state and lets you come back to it. That is the mechanism which makes a test dataset reachable once and then replayable as often as needed.

Fenêtre de terminal
feint snapshot save reference-state
feint snapshot list
saved 21 resources to /home/bob/.local/state/feint/snapshots/reference-state.json
NAME RESOURCES BYTES SAVED
reference-state 21 26472 2026-07-30T09:43:40Z

After deleting every resource, feint snapshot load reference-state answers loaded reference-state: the emulator now holds 21 resources and the inventory is rebuilt. Loading replaces the state, it does not merge: a test dataset must not depend on what the session did before it.

How to know what a real client expects

feint proxy sits between an official client and a cloud and writes every exchange to a file; feint transcript reads that file back as verbs. The pair answers a question a provider's documentation does not settle: what the client really calls, and the exact shape of the responses it receives.

The intended use is a real account, in read-only mode. The demonstration below points the proxy at the emulator itself, which shows the mechanics with no bill; only the upstream address changes in the real case.

Fenêtre de terminal
feint proxy --upstream http://127.0.0.1:4599 --record recording.jsonl --provider scaleway
eval "$(feint env scaleway --endpoint http://127.0.0.1:4600)"
scw instance server create name=via-proxy type=DEV1-S image=ubuntu_jammy zone=fr-par-1

feint transcript turns it into a work queue ranked by call count, which is to say the operations a client asks for and nobody has served yet:

Fenêtre de terminal
feint transcript recording.jsonl
already served, and exercised here (6):
2 1888 200,201 instance/v1/API.CreateServer
1 4734 200 instance/v1/API.ListServersTypes
1 506 200 instance/v1/API.GetImage
1 303 201 instance/v1/API.CreateIP

The --shape flag prints the field tree actually returned, which is not what the SDK declares it can return, and --against compares that tree with the emulator's to list missing or mistyped fields.

response shape of instance/v1/API.ListServersTypes, as the real cloud returned it:
object servers
object servers.DEV1-L
string servers.DEV1-L.arch
bool servers.DEV1-L.capabilities.block_storage

No credential reaches the file: redaction is a property of the recorded type, not a step a caller could forget. Headers follow an allow list, bodies a deny list, because a body is the measurement you are after where a header is not. The proxy listens on the loopback interface only, unless --expose-to-network: every request going through it carries a valid credential.

feint shapes extends the same logic on the verification side: it records a real cloud's field tree, with no values and no identifiers, which makes the file publishable where a transcript is not, and then feint shapes --check compares the emulator with that recording offline and with no credentials.

Key takeaways

  • The page is served by the binary, on loopback, read-only and without authentication by reasoned choice.
  • Served, probed and driven do not add up: only the last category demonstrates a behaviour.
  • feint proxy measures instead of guessing what a client sends, and redacts credentials by construction.
  • feint transcript answers in verbs: what to serve next, what shape the response must have, which fields are missing.
  • A snapshot replaces the state, it does not merge it: a test dataset does not depend on what preceded it.

Next steps

Is this site useful to you?

Fewer than 1% of readers support this site.

I maintain more than 700 free guides, with no ads and no tracking. Any support, even a symbolic one, helps cover hosting and keeps these resources free. Thank you for the help.

The form does not show? Open Ko-fi in a new tab.

Subscribe and follow my DevSecOps work on LinkedIn