Files
kenn-io--agentsview/internal/sync/opencode_storage_gate_internal_test.go
wehub-resource-sync f99010fae1
Desktop Artifacts / Desktop Build (Linux) (push) Waiting to run
Desktop Artifacts / Desktop Build (Windows) (push) Waiting to run
Desktop Artifacts / Desktop Build (Linux (arm64)) (push) Waiting to run
Desktop Artifacts (macOS) / Desktop Build (macOS (aarch64)) (push) Waiting to run
Desktop Artifacts (macOS) / Desktop Build (macOS (x86_64)) (push) Waiting to run
CI / lint (push) Failing after 1s
CI / frontend (push) Failing after 1s
CI / scripts (push) Failing after 1s
CI / Go Test (ubuntu-latest) (push) Failing after 0s
CI / frontend-node-25 (push) Failing after 1s
CI / docs (push) Failing after 0s
CI / coverage (push) Failing after 0s
CI / e2e (push) Failing after 0s
Docker / build-and-push (push) Failing after 1s
CI / integration (push) Failing after 4m43s
CI / Go Test (windows-latest) (push) Has been cancelled
CI / Desktop Unit Tests (Windows) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:30:36 +08:00

69 lines
2.7 KiB
Go

package sync
import (
"testing"
"github.com/stretchr/testify/assert"
)
// TestOpenCodeStorageInvalidationVetoesStalePromotion pins the gate's
// snapshot invariant: an invalidation landing between a pass's pre-parse
// capture and its post-write promotion must win. Watcher changed-path
// classification runs outside syncMu, so it can invalidate a session while
// a full sync is mid-pass; without the veto the pass's promotion would
// restore the pre-event signature and a same-size, same-mtime rewrite —
// the exact case the event invalidation exists to catch — would be skipped
// on every later pass.
func TestOpenCodeStorageInvalidationVetoesStalePromotion(t *testing.T) {
const path = "/data/storage/session/proj/ses_1.json"
const state = "sig-before-event"
t.Run("invalidation after capture blocks promotion", func(t *testing.T) {
e := &Engine{}
snap := e.storageTrustSnapshotFor(path)
e.invalidateOpenCodeStorageSession(path)
e.promoteOpenCodeStorageSession(path, state, snap)
assert.False(t, e.openCodeStorageSessionFresh(path, state),
"a promotion captured before the invalidation must be discarded")
})
t.Run("clear after capture blocks promotion", func(t *testing.T) {
e := &Engine{}
snap := e.storageTrustSnapshotFor(path)
e.clearTrustedOpenCodeStorageSessions()
e.promoteOpenCodeStorageSession(path, state, snap)
assert.False(t, e.openCodeStorageSessionFresh(path, state),
"a promotion captured before a resync clear must be discarded")
})
t.Run("undisturbed capture promotes", func(t *testing.T) {
e := &Engine{}
snap := e.storageTrustSnapshotFor(path)
e.promoteOpenCodeStorageSession(path, state, snap)
assert.True(t, e.openCodeStorageSessionFresh(path, state),
"a promotion with no intervening invalidation must land")
})
t.Run("own pass's in-flight drop does not veto", func(t *testing.T) {
e := &Engine{}
snap := e.storageTrustSnapshotFor(path)
// stageOpenCodeStorageTrust drops trust while staged results are
// in flight to the write batch; that drop belongs to the same
// pass and must not block the pass's own promotion.
e.dropOpenCodeStorageTrust(path)
e.promoteOpenCodeStorageSession(path, state, snap)
assert.True(t, e.openCodeStorageSessionFresh(path, state),
"the staging drop must not veto the same pass's promotion")
})
t.Run("invalidation bumps only its own session", func(t *testing.T) {
e := &Engine{}
const other = "/data/storage/session/proj/ses_2.json"
snap := e.storageTrustSnapshotFor(path)
e.invalidateOpenCodeStorageSession(other)
e.promoteOpenCodeStorageSession(path, state, snap)
assert.True(t, e.openCodeStorageSessionFresh(path, state),
"an unrelated session's invalidation must not veto this promotion")
})
}