mirror of
https://github.com/lrnselfreliance/wrolpi.git
synced 2026-10-25 18:40:06 -04:00
Some checks are pending
Backend Tests / api-tests (core) (push) Waiting to run
Backend Tests / api-tests (files) (push) Waiting to run
Backend Tests / api-tests (media) (push) Waiting to run
Backend Tests / api-tests (rest) (push) Waiting to run
Backend Tests / api-contract-tests (push) Waiting to run
Backend Tests / api-migrations-and-start (push) Waiting to run
CodeQL / Analyze (push) Waiting to run
Controller Tests / controller-tests (push) Waiting to run
Cypress Tests / cypress-component-tests (push) Waiting to run
Cypress Tests / cypress-e2e-tests (push) Waiting to run
Jest Tests / jest-tests (push) Waiting to run
* Tests fail when a request writes outside request.ctx.db.write()
A request's transaction begins deferred. A write in it after a read fails
instantly ("database is locked") when another connection wrote in between,
and a write left for the response middleware's commit can be lost after the
response was sent. #846-#853 and #863 moved handlers' writes into
request.ctx.db.write(); this keeps it that way.
Under pytest, a listener records every INSERT/UPDATE/DELETE/REPLACE made
while a request runs (or in a task it started) outside RequestDB.write()
or get_db_session(commit=True), and the autouse no_deferred_request_writes
fixture fails the test. allow_deferred_request_writes opts a test out.
The test-only response listener now runs switches outside the request,
as production's perpetual process does.
It found three more:
- DELETE /api/zim/<ids> deleted the .zim file, returned 204, then lost the
row's delete when the middleware's commit failed under contention. It
now writes in request.ctx.db.write().
- Viewing a file recorded the view in a background task on the request's
Session, after the request ended. set_file_viewed opens its own write.
- tags.import_config (startup and config import) read, then wrote, in a
deferred get_db_session(). It now begins as a writer.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Tasks don't inherit a declared write; tags import change backed out
From review of #864:
- background_task's task copied its creator's Context, including
_write_intent when started inside get_db_session(commit=True) or
RequestDB.write(), so the guard ignored the task's own writes for its
lifetime. The task now starts with no declared write. That exposes
fetch_channel_source_id (started by the channels config import): it read
the Channel, asked the remote site for its source_id, then committed in
the same deferred transaction. It now reads, fetches with no
transaction open, then writes in a short get_db_session(commit=True).
- tags.import_config: commit=True held the write lock through its directory
walk, and its exit commit saved changes the need_commit gate used to
drop. Reverted to master; splitting its reads from a short write is its
own change. The two tests that run it through a request are marked
allow_deferred_request_writes until then.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
25 lines
1.3 KiB
INI
25 lines
1.3 KiB
INI
[pytest]
|
|
asyncio_mode = auto
|
|
testpaths =
|
|
wrolpi
|
|
modules
|
|
asyncio_default_fixture_loop_scope = function
|
|
markers =
|
|
allow_unexpected_queries: the test trips the serializer query guard on purpose (see wrolpi.db.no_db_access)
|
|
allow_deferred_request_writes: a request writes outside request.ctx.db.write() on purpose (see wrolpi.db.RequestDB)
|
|
# Do not remove timeout - tests should not run forever.
|
|
#
|
|
# This is a hang detector, not a performance budget. It was 30s, but the plugin was never
|
|
# declared in requirements.txt, so CI installed without it and the limit had never actually been
|
|
# applied there. The first run that enforced it failed sixteen tests, every one of them at
|
|
# 30.0s and none of them hung: a 4 vCPU CI runner runs this suite in roughly twice the
|
|
# wall-clock of a dev machine, and a cluster of refresh/worker tests sits at 28-30s there --
|
|
# test_get_refresh_progress passed at 29.9s and test_create_playlist at 29.8s, which is luck
|
|
# rather than headroom.
|
|
#
|
|
# 120s is about four times the slowest legitimate test observed on CI, so it still catches a
|
|
# genuine hang long before the CI job times out, while leaving slow-but-working tests alone.
|
|
# Raise it if CI grows slower; a named timeout failure is the point, and a limit tight enough to
|
|
# fire on healthy tests just trades one unreliable signal for another.
|
|
timeout = 120
|
|
timeout_method = signal
|