Plan synchronization of delivery test fixtures

This commit is contained in:
2026-10-10 23:56:12 +00:00
parent 8f6e72b0b8
commit 6176971307

103
docs/roadmap/race.md Normal file
View File

@@ -0,0 +1,103 @@
# Roadmap: synchronize delivery test fixtures
Status: planned; implementation has not started.
## Objective and evidence
Make the delivery HTTP fixtures safe for concurrent access by test goroutines
and request handlers while preserving their existing behavioral assertions.
The [PromptKit bug report](promptkit-bug-report.md) supplies the original
diagnostics and consumer context.
Upstream investigation reproduced
`TestReleaseKitSourceDeliveryWorkflowFromTaggedCheckout` under the race detector
with Go 1.26.8. The diagnostics identified `commit`, `remoteCommit`, and
`releaseCreates` accesses shared between the workflow test and HTTP handlers.
The workflow test and relevant unsynchronized accesses predate v0.4.0.
Subprocess completion supplies no synchronization for this shared Go state.
The ordinary Woodpecker and multi-module workflow tests passed their focused
race-enabled runs during investigation. Source inspection nevertheless found
the same unsynchronized state pattern in their fixtures. A passing run alone
does not establish safe access under other scheduling.
## Scope
The correction belongs in test infrastructure:
- The `deliveryServerState`, `newDeliveryServer`, and `writeDeliveryRelease`
helpers in [main_test.go](../../cmd/releasekit/main_test.go), including all
tests using that fixture.
- The [source-delivery workflow test](../../cmd/releasekit/releasekit_delivery_workflow_test.go)
and [ordinary Woodpecker workflow tests](../../cmd/releasekit/woodpecker_test.go).
- The `mappedDeliveryFixture`, `newMappedDeliveryFixture`, and their consumers
in [multi_module_woodpecker_test.go](../../cmd/releasekit/multi_module_woodpecker_test.go).
Production behavior, public API contracts, and release requirements retain their
current definitions. Use the standard library and small fixture-local helpers,
following the [agent](../policy/agents.md) and
[testing](../policy/testing.md) policies.
## Implementation
1. **Synchronize the shared delivery fixture.** Give mutable fixture state a
`sync.Mutex`. Protect handler reads and writes, test-side configuration
changes, assertion reads, counters, page state, note content, and asset-map
operations with the same mutex. Initialize immutable configuration before
serving requests where practical; synchronize later initialization such as
the source commit assigned after profile creation. Review captured handler
values and response helpers as part of this boundary.
2. **Update every shared-fixture consumer.** Use simple locked setters and
snapshot accessors for test configuration and assertions. Snapshot plain
values separately from the mutex, copying maps and mutable byte slices when
they will be inspected outside the lock. Include failure diagnostics that
format fixture state. Keep lock ownership clear in handler helpers and
release locks before executing CLI workflows or closing the server.
3. **Apply the same discipline to the mapped fixture.** Protect its commit,
request and creation counters, page fields, uploads, and asset map, together
with all corresponding test accesses. Keep each fixture's synchronization
local and proportionate to its existing responsibilities.
4. **Preserve behavioral coverage.** Retain rejection of mismatched hosted tags
before release creation, exact source-tag preservation, complete note bodies,
idempotent page and asset delivery, expected asset counts, mapped module
identity, retries using tagged configuration, and existing failure outcomes.
Use these workflows as the regression coverage for the reported race. Add
further coverage only for a concrete gap discovered during the correction.
## Verification and completion
With dependencies prepared, run the affected workflows from the repository root
using the local toolchain and offline module settings:
```sh
GOTOOLCHAIN=local GOWORK=off GOPROXY=off GOSUMDB=off \
go test -race -mod=readonly -count=1 ./cmd/releasekit \
-run '^(TestReleaseKitSourceDeliveryWorkflowFromTaggedCheckout|TestWoodpeckerTagDeliveryTemplate|TestMultiModuleWoodpeckerDelivery)$'
```
Then run the full race-enabled suite once to verify the other shared-fixture
users and catch remaining cross-goroutine access:
```sh
GOTOOLCHAIN=local GOWORK=off GOPROXY=off GOSUMDB=off \
go test -race -mod=readonly -count=1 ./...
```
Review the fixture accesses as well as the test results: successful execution
complements the synchronization review. Keep local Git repositories, HTTP
servers, and synthetic module caches isolated as described in
[development](../development.md#testing-synthetic-modules).
Completion means both fixtures and their consumers use synchronized state,
the existing assertions remain effective, and the focused and full race-enabled
suites pass. Record completion and verification here and update the bug report's
status with the remediation outcome. Commit the completed correction under the
repository's ordinary change workflow.
This verification addresses the reported defect. Future release validation
continues to follow the [release procedure](../release.md). The correction is
suitable for a subsequent patch release; preparation and publication are separate
work under that procedure, preserving the published v0.4.0 contents.