Skip to content

REST malformed and concurrent request matrix

Summary

Expand REST robustness coverage from representative smoke tests into a release matrix for malformed and concurrent requests.

Beta 0.7.3 Classification

Release Gate. This validates BUG-075, BUG-076, and BUG-077 through selectable smoke and soak budgets. Smoke mode should be suitable for the release gate; soak mode can be longer operator validation.

Execution Plan

Historical release context: Beta 0.7.3 REST and Arr execution plan.

Acceptance Criteria

  • [x] malformed JSON, non-object JSON, truncated body, wrong method, missing auth, wrong auth, bad route ids, and unsupported content types are covered
  • [x] failures use the stable JSON error envelope
  • [x] concurrent read and safe-mutation traffic does not hang, crash, or corrupt legacy WebServer session state
  • [x] stress summaries include request counts, status counts, latency bounds, and sampled failures
  • [x] the lane can run in short smoke mode and longer operator soak mode

Completion Evidence

  • Test commits: f6cc0f9, 75b4ce7, 331f70d, fe6ee8c.
  • Commands: python -m emule_workspace validate; python -m pytest tests\python\test_rest_api_smoke.py -q; python -m emule_workspace test live-e2e --config Release --platform x64 --suite rest-api; python -m emule_workspace test live-e2e --config Release --platform x64 --suite rest-api --rest-coverage-budget contract-stress.
  • Contract-stress artifact: repos\emulebb-build-tests\reports\rest-api-smoke\20260506-185112-eMule-main-release. The run covered 81 routes and completed 11188 mixed stress requests with 0 failures, 0 timeouts, and 0 non-JSON native REST responses.
  • Soak artifact: repos\emulebb-build-tests\reports\rest-api-smoke\20260506-184530-eMule-main-release. The run completed 10997 mixed native REST, qBit, Torznab, and legacy HTML requests with 0 failures, 0 timeouts, and 0 non-JSON native REST responses.
  • Follow-up hardening: the OpenAPI-derived contract completeness lane now treats 4xx responses as passing only when the operation has an explicit negative-probe status. Undeclared 4xx results fail the route summary, so contract coverage cannot silently turn regressions into expected errors.
  • Follow-up live revalidation found that category creation's empty-body contract probe intentionally returns 400; that expected negative status is now declared in the contract runner.
  • Debug contract-stress revalidation artifact: repos\emulebb-build-tests\reports\rest-api-smoke\20260507-203902-eMule-main-debug. The run covered all 82 OpenAPI routes, exercised 81 safe routes with 0 failed routes, and completed 302 mixed stress requests with 0 failures, 0 timeouts, and 0 non-JSON native REST responses.
  • Follow-up hardening: live REST smoke now proves a qBittorrent-compatible add materializes through /api/v2/torrents/info, preserves category/name fields, exposes valid-transfer properties and files, and deletes the temporary transfer through the qBit adapter. Test commits: 6fd252f, ec962c7.
  • Debug live REST artifact after the qBit valid-transfer coverage: repos\emulebb-build-tests\reports\rest-api-smoke\20260508-000353-eMule-main-debug. The run passed with BindInterface=hide.me, empty P2P BindAddr, EnableUPnP=1, and qBit add/info/properties/files/delete evidence for the temporary hash 11223344556677889900aabbccddeeff.
  • Follow-up report hardening: aMuTorrent, Prowlarr, and Radarr/Sonarr live reports now include a standard launch_inputs block for the P2P bind interface and UPnP decision, with regression tests guarding against the invalid BindAddr=hide.me pattern. Test commits: fa55046, efc52a7.
  • Follow-up destructive-operation hardening: live REST smoke now verifies qBit delete removes the temporary transfer from /api/v2/torrents/info and turns qBit properties/files for that hash into 404; live aMuTorrent browser smoke now verifies /api/v1/downloads/delete removes the synthetic eD2K row from the next UI snapshot. Test commits: d1ac2e3, 5a7565d; aMuTorrent fix commit: 3c23c1b.
  • Follow-up shared-file destructive-operation hardening: the shared-directory live suite now deletes the final replacement shared file through /api/v1/shared-files/{hash} with deleteFiles=true, verifies the REST response reports deletedFiles=true, verifies the disk file is gone, and waits for /api/v1/shared-files to become empty while the shared-directory model remains intact. Test commit: dceeb92.
  • Debug shared-directory live artifact after the shared-file delete coverage: repos\emulebb-build-tests\reports\shared-directories-rest\20260508-005116-eMule-main-debug. The run passed with P2P BindInterface=hide.me, empty P2P BindAddr, WebServer BindAddr=127.0.0.1, and EnableUPnP=1.
  • Follow-up search destructive-operation hardening: live REST smoke now runs repeated server/Kad searches, deletes all resulting search tabs through DELETE /api/v1/searches with confirmDeleteAllSearches=true, and verifies every collected search id returns 404 afterward. Test commit: d73a2d8.
  • Debug live REST artifact after delete-all search coverage: repos\emulebb-build-tests\reports\rest-api-smoke\20260508-005531-eMule-main-debug. The run deleted 12 live search ids, every post-delete probe returned 404, one paused live download trigger completed, and the profile used P2P BindInterface=hide.me, empty P2P BindAddr, WebServer BindAddr=127.0.0.1, and EnableUPnP=1.
  • Follow-up clear-completed destructive-operation hardening: live REST smoke now triggers a paused live download, runs POST /api/v1/transfers/operations/clear-completed with confirmClearCompleted=true, and verifies the incomplete triggered transfer remains readable afterward. Test commit: 8f80a42.
  • Debug live REST artifact after clear-completed coverage: repos\emulebb-build-tests\reports\rest-api-smoke\20260508-010209-eMule-main-debug. The run completed one paused live download trigger, cleared completed transfers with status 200, verified the triggered transfer still returned 200, deleted 12 live search ids with all post-delete probes returning 404, and used P2P BindInterface=hide.me, empty P2P BindAddr, WebServer BindAddr=127.0.0.1, and EnableUPnP=1.
  • Follow-up shared-directory replacement safety hardening: the shared-directory live suite now verifies replacing shared roots does not delete old flat, recursive, long Unicode, or exact trailing-name files while REST exposes only the replacement shared file afterward. Test commit: af7aa80.
  • Debug shared-directory live artifact after replacement safety coverage: repos\emulebb-build-tests\reports\shared-directories-rest\20260508-010807-eMule-main-debug. The run preserved all old fixture files, exposed only replacement_file.txt after root replacement, then deleted that replacement shared file through /api/v1/shared-files/{hash} and observed an empty shared-file list. The profile used P2P BindInterface=hide.me, empty P2P BindAddr, WebServer BindAddr=127.0.0.1, and EnableUPnP=1.
  • Follow-up shutdown exclusion hardening: live REST smoke now emits a shutdown exclusion audit proving /api/v1/app/shutdown is absent from the smoke and soak stress operation lists while the OpenAPI-derived route remains marked safe=false / unsafe. Test commit: 033fa3c.
  • Debug live REST artifact after shutdown exclusion coverage: repos\emulebb-build-tests\reports\rest-api-smoke\20260508-011208-eMule-main-debug. The run reported zero shutdown-route matches across both stress budgets, kept the route marked unsafe in contract metadata, retained the clear-completed and delete-all search proofs, and used P2P BindInterface=hide.me, empty P2P BindAddr, WebServer BindAddr=127.0.0.1, and EnableUPnP=1.
  • Mixed stress evidence from the same debug live REST artifact: the smoke stress pass completed 383 mixed native REST, qBit-compatible, Torznab, and legacy HTML requests with 0 failures, 0 timeouts, and 0 non-JSON native REST responses.
  • Beta 0.7.3 contract-drift revalidation through CI-025: repos\emulebb-build-tests\reports\rest-api-smoke\20260509-144340-eMule-main-release\result.json. The Release x64 live REST run passed with 45 expected native REST errors, 0 undeclared failed routes, qBit wrong-cookie/bad-login/bad-boolean/bad-hash adapter probes, Torznab wrong-key/bad-category/malformed-search probes, and adapter-local error shapes.

Pending Revalidation Focus

This gate is passed, but the next Release 1 hardening pass should refresh the robustness and safety evidence with:

  • [x] malformed JSON, non-object JSON, truncated body, unknown fields, malformed query parameters, bad hashes, wrong methods, unsupported content types, missing auth, and wrong auth
  • [x] missing-resource and invalid-state failures for native /api/v1 routes using the stable JSON error envelope
  • [x] destructive-operation safety checks for shared-file delete
  • [x] destructive-operation safety checks for delete-all searches
  • [x] destructive-operation safety checks for clear-completed transfers
  • [x] destructive-operation safety checks for shared-directory replacement
  • [x] destructive-operation safety checks for shutdown exclusion from broad mutation loops
  • [x] mixed native REST, qBit-compatible, Torznab, and legacy HTML stress with zero hangs, crashes, timeouts, or non-JSON native REST failures

Relationship To Other Items

  • backs CI-011
  • validates BUG-075, BUG-076, and BUG-077