Add campaign-aware workspace path foundation

This commit is contained in:
2026-05-17 20:57:27 +00:00
parent e58e545686
commit 550288e008
34 changed files with 448 additions and 146 deletions

View File

@@ -10,9 +10,9 @@ import (
func TestEnsureLayoutCreatesExpectedDirectories(t *testing.T) {
store := NewLocalStore(t.TempDir())
paths, err := store.EnsureLayout("session-1")
paths, err := store.EnsureLayoutFor("sample-campaign", "session-1")
if err != nil {
t.Fatalf("EnsureLayout() error = %v", err)
t.Fatalf("EnsureLayoutFor() error = %v", err)
}
checkDirExists(t, paths.Root)
@@ -22,8 +22,11 @@ func TestEnsureLayoutCreatesExpectedDirectories(t *testing.T) {
checkDirExists(t, paths.TranscriptsRawDir)
checkDirExists(t, paths.TranscriptsTrimmedDir)
checkDirExists(t, paths.ArtifactsDir)
checkDirExists(t, paths.ReportsDir)
checkDirExists(t, paths.ConfigDir)
checkDirExists(t, paths.LogsDir)
checkDirExists(t, paths.CurrentDir)
checkDirExists(t, paths.RunsDir)
if filepath.Base(paths.ManifestPath) != "manifest.json" {
t.Fatalf("ManifestPath = %q, want basename manifest.json", paths.ManifestPath)
@@ -33,6 +36,43 @@ func TestEnsureLayoutCreatesExpectedDirectories(t *testing.T) {
}
}
func TestResolveSessionPathsForLegacyFallback(t *testing.T) {
root := t.TempDir()
store := NewLocalStore(root)
legacyRoot := SessionWorkDir(root, "session-1")
if err := os.MkdirAll(legacyRoot, 0o755); err != nil {
t.Fatalf("MkdirAll() error = %v", err)
}
paths, err := store.ResolveSessionPathsFor("sample-campaign", "session-1")
if err != nil {
t.Fatalf("ResolveSessionPathsFor() error = %v", err)
}
if paths.Root != legacyRoot {
t.Fatalf("paths.Root = %q, want legacy root %q", paths.Root, legacyRoot)
}
}
func TestResolveSessionPathsForAmbiguousRoots(t *testing.T) {
root := t.TempDir()
store := NewLocalStore(root)
legacyRoot := SessionWorkDir(root, "session-1")
canonicalRoot := SessionWorkDirForCampaign(root, "sample-campaign", "session-1")
for _, dir := range []string{legacyRoot, canonicalRoot} {
if err := os.MkdirAll(dir, 0o755); err != nil {
t.Fatalf("MkdirAll(%q) error = %v", dir, err)
}
}
_, err := store.ResolveSessionPathsFor("sample-campaign", "session-1")
if err == nil {
t.Fatal("expected ambiguity error, got nil")
}
if !strings.Contains(err.Error(), "ambiguous session workspace roots") {
t.Fatalf("error = %v, want ambiguity message", err)
}
}
func TestChecksumCalculation(t *testing.T) {
store := NewLocalStore(t.TempDir())
path := filepath.Join(t.TempDir(), "sample.txt")
@@ -53,9 +93,9 @@ func TestChecksumCalculation(t *testing.T) {
func TestLockAcquireRelease(t *testing.T) {
store := NewLocalStore(t.TempDir())
lock, err := store.AcquireSessionLock("session-1")
lock, err := store.AcquireSessionLockFor("sample-campaign", "session-1")
if err != nil {
t.Fatalf("AcquireSessionLock() error = %v", err)
t.Fatalf("AcquireSessionLockFor() error = %v", err)
}
exists, err := store.Exists(lock.path)
@@ -81,15 +121,15 @@ func TestLockAcquireRelease(t *testing.T) {
func TestLockConflict(t *testing.T) {
store := NewLocalStore(t.TempDir())
lock1, err := store.AcquireSessionLock("session-1")
lock1, err := store.AcquireSessionLockFor("sample-campaign", "session-1")
if err != nil {
t.Fatalf("first AcquireSessionLock() error = %v", err)
t.Fatalf("first AcquireSessionLockFor() error = %v", err)
}
defer func() {
_ = store.ReleaseSessionLock(lock1)
}()
_, err = store.AcquireSessionLock("session-1")
_, err = store.AcquireSessionLockFor("sample-campaign", "session-1")
if err == nil {
t.Fatal("expected lock conflict error, got nil")
}
@@ -138,9 +178,9 @@ func TestCopyInput(t *testing.T) {
t.Fatalf("WriteFile() error = %v", err)
}
ref, err := store.CopyInput("session-1", srcPath, "inputs/speakers.yml")
ref, err := store.CopyInputFor("sample-campaign", "session-1", srcPath, "inputs/speakers.yml")
if err != nil {
t.Fatalf("CopyInput() error = %v", err)
t.Fatalf("CopyInputFor() error = %v", err)
}
if ref.Kind != "input" {