When is it safe to act on WireMock's DELETE /__admin/mappings/unmatched for a museum ticketing catalogue?
answer
- the census describes the run, not the catalogue
- sharding and tag filters fake dead stubs
- unserved can mean shadowed, not obsolete
- in-memory only; disk keeps the definitions
- two consecutive full runs before deleting
basics
~20 sIn WireMock, DELETE /__admin/mappings/unmatched removes the stubs an instance never served, so it is only safe after a run that exercised the whole catalogue. A sharded, tagged or aborted run makes live stubs look dead. The delete is in-memory only.
solid answer
~40 sIn WireMock, `DELETE /__admin/mappings/unmatched` removes precisely the stubs the running instance has never served, so the delete is only as trustworthy as the run that produced the census. A sharded suite, a tag filter, an aborted run or a nightly-only error-path test all leave live stubs looking dead, and a long-lived instance serving several suites reports a union you have to reason about deliberately. Two more caveats bite in practice: a stub can go unserved because an overlapping mapping answered instead, which is a catalogue problem rather than a dead stub; and the delete touches only the running WireMock instance, leaving the JSON under `mappings/` and every body under `__files/` exactly where they were. In MockServer the equivalent catalogue reloads from `mockserver.initializationJsonPath` unless `persistExpectations` writes the pruned set back.
go deeper
Know that this WireMock call deletes stubs the instance never used, and that it changes only the running server. Nothing on disk moves, so a restart brings the whole catalogue back.
Be able to explain why the census depends on the run: sharding, tag filters and aborted suites all shrink the traffic, and the endpoint reports on traffic rather than on intent.
Demonstrate the protocol — full unfiltered runs, two consecutive censuses, an owner claim window, deletions landing through review — and name the overlap case where an unserved stub is a design problem, not dead weight.
Decide where automatic pruning is allowed at all. Argue that a tidy-up on a pull-request pipeline rewrites the catalogue by whichever shard ran last, and set the policy that keeps deletions reviewable.
## What the delete actually does In WireMock, `DELETE /__admin/mappings/unmatched` tells a running instance to drop every stub mapping it has not served a request from. It is the census endpoint's destructive twin: `GET` on the same path lists that set, `DELETE` removes it. There is no dry run, no confirmation and no undo inside the server — the next call to WireMock's `GET /__admin/mappings` simply returns a smaller catalogue. So the interesting question is never whether the call is correct. It is whether the run that produced the census was representative. The delete is exactly as trustworthy as the traffic the instance saw, and no more. ## The census is a property of the run, not of the catalogue A stub is reported as never served because *this instance* served nothing from it. Everything that narrows the traffic narrows the census in the same breath: - **Sharding.** One worker of six exercises roughly one sixth of the museum ticketing endpoints; the other five sixths look dead to it. - **Tag or group filters.** A smoke run that touches only `/exhibitions` and `/tickets` reports every membership and refund stub as unused. - **An aborted or failed run.** A suite that died on its third test leaves almost the whole catalogue unserved. - **Nightly-only paths.** The stub returning `409` for a sold-out session may be exercised once a day by one job and never by the pull-request pipeline. - **A long-lived instance serving several suites.** Here the census is a union over everything that has run since start-up, which is more useful — but only if you know what actually ran. Any of these turns a live stub into a deletion candidate, and the endpoint gives you no signal that it happened. The instance cannot tell you what it was *not* asked. ## The overlap case, which is not a dead stub A stub can be never served because another mapping in the same catalogue answered the request instead. That is real information — two definitions in your set claim overlapping traffic — but the conclusion is not *delete the unserved one*. A narrow museum ticketing stub for `GET /memberships/{card}` returning a lapsed card may be exactly the behaviour you wanted, with a broader mapping quietly taking every request to that path. Deleting the loser cements the behaviour you did not intend. Resolve the overlap first, then decide about deletion. ## In-memory versus on disk The delete changes the running instance and nothing else. | after `DELETE /__admin/mappings/unmatched` in WireMock | state | |---|---| | the never-served stubs in the running instance | removed | | the JSON definitions under `mappings/` | untouched | | the response bodies under `__files/` | untouched | | the next start-up from the same directory | loads the full, unpruned set again | To make a prune durable you have to write it down. WireMock's `POST /__admin/mappings/save` persists the instance's current set back to `mappings/`, or you delete the definition files in the repository so the change arrives through review like any other. The second is usually what you want, because a catalogue that changes only through an admin call has no history and no reviewer. Note that neither path touches WireMock's `__files/`: body files orphaned by a prune stay in the repository until somebody scans for them deliberately. ## A prune protocol that survives contact with a real suite 1. Run the **whole** suite against one instance — no shard, no tag filter — and confirm it finished cleanly. 2. Fetch WireMock's `GET /__admin/mappings/unmatched` and keep it as an artefact of that build. 3. Repeat on the next build. A stub never served twice in a row from full runs is a far stronger candidate than one seen once. 4. Circulate the list by owner and give a claim window, rather than deleting on the spot. 5. Remove the definition files in the repository, open it as a normal change, and let the following full run prove nothing broke. 6. Sweep WireMock's `__files/` separately for bodies that no remaining definition names. ## Where the call earns its keep anyway None of this makes the endpoint useless — it makes it a tool with a precondition. Two settings where it is straightforwardly good: - **A throwaway instance in a full nightly run**, where the delete is a report you diff rather than a change you keep. - **A curated demo or exploratory instance**, where you deliberately load a large set, drive it by hand, and want everything you did not touch gone before you save the result. The failure mode to avoid is the tidy-up that runs on a pull-request pipeline, deletes what that pipeline did not exercise, and persists the result. That is not maintenance; it is a slow rewrite of the catalogue by whichever shard happened to run last.
- How would you make a WireMock prune durable without hand-editing the running instance?Delete the JSON definitions under `mappings/` in the repository and let the change go through review, so the smaller catalogue has an author and a history. `POST /__admin/mappings/save` will persist the instance's current set back to `mappings/`, but a catalogue that only ever changes through an admin call leaves no reviewable trail, and it still will not remove the orphaned bodies under `__files/`.
- A long-lived WireMock instance serves three suites. How does that change the never-served census?It becomes a union over everything that has run since start-up, which is closer to a real statement about the catalogue than any single suite could give you. The catch is that it is only as complete as the set of suites that actually ran, so you need to know which ones did before you read the result — and a restart silently resets the whole count.
saying these in an interview costs you the question
- Pruning from a census taken on one shard
- Assuming the delete also removes files from mappings/
- Treating a shadowed stub as obviously dead weight
- Running the tidy-up automatically on every pull request
- Forgetting that a restart reloads the unpruned catalogue
- Expecting __files/ bodies to disappear with their definitions