Permit safe cross-run output declarations
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
@@ -46,6 +47,75 @@ func TestRemoteCommitDecodersRejectUnknownFields(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseImmutableRunObjectKeyAcceptsSameSessionRuns(t *testing.T) {
|
||||
prefix := testCurrentSessionPrefix()
|
||||
for _, runID := range []string{"20260519T010203Z-a1b2c3d4", "20260401T010203Z-11223344"} {
|
||||
key := S3RunRelativeDestinationKey(S3RunPrefix(prefix, runID), "published/artifacts/recap.md")
|
||||
identity, err := ParseImmutableRunObjectKey(prefix, key)
|
||||
if err != nil {
|
||||
t.Fatalf("ParseImmutableRunObjectKey(%q) error = %v", runID, err)
|
||||
}
|
||||
if identity.RunID != runID || identity.RelativePath != "published/artifacts/recap.md" {
|
||||
t.Fatalf("ParseImmutableRunObjectKey(%q) = %#v", runID, identity)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseImmutableRunObjectKeyRejectsUnsafeOrMutableKeys(t *testing.T) {
|
||||
prefix := testCurrentSessionPrefix()
|
||||
for _, key := range []string{
|
||||
prefix + "current/commit-pointer.json",
|
||||
prefix + "locks/source.lock",
|
||||
prefix + "runs//published/recap.md",
|
||||
prefix + "runs/20260519T010203Z-a1b2c3d4",
|
||||
prefix + "runs/20260519T010203Z-a1b2c3d4/published/../recap.md",
|
||||
"dnd/campaigns/other/sessions/2026-05-03/runs/20260519T010203Z-a1b2c3d4/published/recap.md",
|
||||
} {
|
||||
if _, err := ParseImmutableRunObjectKey(prefix, key); err == nil {
|
||||
t.Fatalf("ParseImmutableRunObjectKey(%q) error = nil, want rejection", key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemoteCommitAllowsPublishedOutputFromEarlierSameSessionRunOnly(t *testing.T) {
|
||||
commit := testRemoteCommit(t, "20260519T010203Z-a1b2c3d4")
|
||||
prefix := testCurrentSessionPrefix()
|
||||
published := RemoteArtifact{
|
||||
Type: RemoteArtifactTypePublishedOutput, Source: "narratio.artifact.recap",
|
||||
DestinationKey: S3RunRelativeDestinationKey(S3RunPrefix(prefix, "20260401T010203Z-11223344"), "published/artifacts/recap.md"),
|
||||
SHA256: strings.Repeat("a", 64), Size: 1, Generation: "older-generation",
|
||||
}
|
||||
commit.Artifacts = append(commit.Artifacts, published)
|
||||
if err := commit.ValidateForSessionPrefix(prefix); err != nil {
|
||||
t.Fatalf("ValidateForSessionPrefix() error = %v", err)
|
||||
}
|
||||
|
||||
commit.Artifacts[1].DestinationKey = "dnd/campaigns/other/sessions/2026-05-03/runs/20260401T010203Z-11223344/published/artifacts/recap.md"
|
||||
if err := commit.ValidateForSessionPrefix(prefix); err == nil {
|
||||
t.Fatal("ValidateForSessionPrefix() cross-session error = nil")
|
||||
}
|
||||
commit.Artifacts[1].DestinationKey = published.DestinationKey
|
||||
commit.Artifacts[1].Type = RemoteArtifactTypeRunFile
|
||||
if err := commit.ValidateForSessionPrefix(prefix); err == nil {
|
||||
t.Fatal("ValidateForSessionPrefix() earlier non-published object error = nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemoteCommitRejectsEffectivePublishedDestinationCollisionAcrossRuns(t *testing.T) {
|
||||
commit := testRemoteCommit(t, "20260519T010203Z-a1b2c3d4")
|
||||
prefix := testCurrentSessionPrefix()
|
||||
for index, runID := range []string{commit.RunID, "20260401T010203Z-11223344"} {
|
||||
commit.Artifacts = append(commit.Artifacts, RemoteArtifact{
|
||||
Type: RemoteArtifactTypePublishedOutput, Source: fmt.Sprintf("narratio.artifact.recap_%d", index),
|
||||
DestinationKey: S3RunRelativeDestinationKey(S3RunPrefix(prefix, runID), "published/artifacts/recap.md"),
|
||||
SHA256: strings.Repeat("a", 64), Size: 1, Generation: fmt.Sprintf("generation-%d", index),
|
||||
})
|
||||
}
|
||||
if err := commit.ValidateForSessionPrefix(prefix); err == nil || !strings.Contains(err.Error(), "duplicate published output destination") {
|
||||
t.Fatalf("ValidateForSessionPrefix() error = %v, want effective destination collision", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemoteCommitDecoderAcceptsHistoricalRunManifestArtifact(t *testing.T) {
|
||||
data := []byte(`{"format_version":1,"campaign":"sample-campaign","session_id":"2026-05-03","run_id":"20260519T010203Z-a1b2c3d4","artifacts":[{"type":"run_manifest","source":"run:manifest.json","destination_key":"sample-campaign/2026-05-03/runs/20260519T010203Z-a1b2c3d4/manifest.json","sha256":"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef","size":1,"generation":"historical"}]}`)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user