Skip to content

Serve the external payload storage diagnostic natively - #561

Merged
rmcdaniel merged 6 commits into
mainfrom
rust-325-storage-test
Oct 21, 2026
Merged

rmcdaniel merged 6 commits into
mainfrom
rust-325-storage-test

Conversation

@rmcdaniel

Copy link
Copy Markdown
Member

Part of #325.

Native now serves POST /api/storage/test, the external payload storage diagnostic, as published PHP's StorageController::test does.

Behavior.

  • Validation. Laravel's rules and messages for driver (nullable|string|in:local,s3,gcs,azure,custom) and the two payload sizes (required|integer|min:1|max:…), with the 422 validation_failed body and its error count. The request normalization and failure body moved into laravel_validation, which the search attribute registry now shares.

  • Refusals. PHP's 422 bodies for:

    • no policy (external_storage_not_configured, null driver);
    • a disabled policy (external_storage_disabled);
    • a requested driver other than the configured one (storage_driver_unavailable with supported_diagnostic_drivers: ["local"]).

    Drivers native cannot run are refused as unavailable in this runtime, as PHP is without their SDKs.

  • Round trip. A generated small and large payload is written to the local driver, read back with its size and digest verified, and removed. The response reports each payload's size, SHA-256 and the digest of its object URI.

  • Shared objects. Local objects are content-addressed, so a diagnostic payload can have the same bytes as a registered external payload. Native holds the payload object lock for the round trip and removes the object only when no registered payload refers to it. PHP removes it unconditionally.

  • Access. Admin only, in the default or a named namespace.

Fixture. storage-test drives a fresh namespace through:

  • no policy;
  • a disabled policy;
  • another driver;
  • three invalid bodies;
  • two passing round trips.

Published PHP 2.5.14 and native returned identical bodies, including the reference identities. Embedded PHP declares the fixture inapplicable. The contract has 21 unit tests (ServerParityStorageTestContractTest.mjs).

Local checks.

  • A local copy of the SQLite parity step passed storage-test, search-attributes and worker-listing on all three targets, and the comparison passed.
  • The native lib suite (125) and the SQLite execution suite (296) pass.
  • The storage and search attribute tests pass on PostgreSQL and MySQL.

🤖 Generated with Claude Code

durable-workflow-ops and others added 3 commits October 20, 2026 22:01
POST /api/storage/test validates its request with Laravel's messages,
refuses an unconfigured, disabled or mismatched driver with published
PHP's bodies, and round-trips a generated small and large payload through
the local driver. The object is removed only when no registered payload
shares its content-addressed URI. A storage-test parity fixture records
identical bodies from PHP 2.5.14 and native.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… rust-325-storage-test

# Conflicts:
#	rust/src/runtime/http.rs
# Conflicts:
#	.github/workflows/server-parity.yml
#	scripts/conformance/server-parity/contract.mjs
#	scripts/conformance/server-parity/probe.php
durable-workflow-ops and others added 3 commits October 21, 2026 01:24
# Conflicts:
#	.github/workflows/server-parity.yml
#	docs/rust-server-port.md
PHP and native wrote the diagnostic's objects under the same
/state/<namespace> root. CI runs PHP as uid 1000 and native as the runner's
uid, so native could not write into the directory PHP created and answered
503. Each target now writes under file:///state/storage-test-<host>/<namespace>,
which the probe records and the contract checks and hashes. Reproduced and
fixed locally with native running as another uid.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@rmcdaniel

Copy link
Copy Markdown
Member Author

Updated with main after #559 (bb88265), then fixed the fixtures failure in 8b346e9.

Cause. Run 39528081280 failed the storage diagnostic's round trip on every database job: native answered 503 external_payload_unavailable. PHP and native wrote the diagnostic's objects under the same /state/<namespace> root. CI runs PHP as uid 1000 and native as the runner's uid, so native could not write into the directory PHP had already created. My local runs used one uid for every container, which hid this.

Fix. Each target now writes under file:///state/storage-test-<host>/<namespace>. The probe records that root, and the contract checks its form and hashes the reference identity with it. Three new unit cases cover a shared root, a root outside the namespace and a missing root, for 24 in total.

Checks.

  • With native running as uid 1001 locally, the old probe reproduced CI's 503.
  • The new probe passes for all three targets with mixed uids and with a single uid.

I cancelled the superseded runs on bb88265.

@sonarqubecloud

Copy link
Copy Markdown

@rmcdaniel
rmcdaniel merged commit 8ad23a9 into main Oct 21, 2026
17 of 22 checks passed
@rmcdaniel
rmcdaniel deleted the rust-325-storage-test branch October 21, 2026 04:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants