Files
Agent-System-Backend/internal/store/migrate_compat_test.go
T
weichenandCursor b4a19e784d
governance / governance (pull_request) Successful in 18s
ci / vet-and-test (pull_request) Successful in 1m5s
Merge Backend main into IAM U4 role authority
Why: the U4 branch is 89 commits behind main, which now carries the shared
document renderer, two-trees project work, the SQLite instance guard and
exec env layers (PR #209 merged as c76d8bd); it conflicted in storage
migrations, host capabilities and the extension surface. The user authorized
syncing U4 after the renderer line on 2026-10-18.
Evidence: content is the agent-exec transport 3b64eb5 (cursor worker, unit
backend-iam-u4-onto-main-c76d8bd-r1, run on a checkout whose tree equals main,
receipt /tmp/cleanup-20261018/render/u4-backend-onto-run.json, SELF). Host
check: main migrations 1-48 unchanged (migrate.go has no deleted lines versus
main), U4 migrations moved from 35-36 to 49-50 with identical SQL,
surface.txt is the sorted union, deps stay at main's pins.
Impact: databases that ran unmerged U4 builds with the old numbering must be
recreated. SurfaceVersion becomes 2.25.0-experimental. Main's admin password
account creation now requires the system.users.create action like the other
U4 account writes.
Refs: Backend main c76d8bd, PR #209

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-18 12:50:32 +00:00

74 lines
2.2 KiB
Go

package store
import (
"strings"
"testing"
)
func TestMigrationCompatRegistered(t *testing.T) {
if len(migrationBreaksOldReaders) != len(migrations) {
t.Fatalf("兼容登记 %d 条,迁移 %d 条", len(migrationBreaksOldReaders), len(migrations))
}
for _, m := range migrations {
if _, ok := migrationBreaksOldReaders[m.version]; !ok {
t.Fatalf("迁移 v%d %s 未登记是否破坏旧制品读取", m.version, m.name)
}
}
if SchemaTarget() != latestMigrationVersion() {
t.Fatalf("target=%d latest=%d", SchemaTarget(), latestMigrationVersion())
}
if SchemaCompatFloor() < 0 || SchemaCompatFloor() > SchemaTarget() {
t.Fatalf("compatFloor=%d target=%d", SchemaCompatFloor(), SchemaTarget())
}
}
func TestMigrationTailKeepsAdoptedExecEnvBeforeFeatureHistory(t *testing.T) {
want := []struct {
version int
name string
}{
{35, "exec_env_layers"},
{36, "instance_guard"},
{37, "work_task_bindings"},
{38, "trusted_context_manifests"},
{39, "workflow_step_sources"},
{40, "context_manifest_resolve_scope"},
{41, "scrub_candidate_context_scope_text"},
{42, "command_audit_attribution_snapshot"},
{43, "project_audit_committed_links"},
{44, "project_audit_committed_prefix"},
{45, "project_audit_all_writers_guard"},
{46, "project_work_observation_outbox"},
{47, "human_decision_proofs"},
{48, "document_render_deliveries"},
{49, "role_policy_authority"},
{50, "role_authority_import_stage"},
}
for _, item := range want {
if got, ok := MigrationName(item.version); !ok || got != item.name {
t.Fatalf("migration v%d=%q,%v want %q,true", item.version, got, ok, item.name)
}
}
}
func TestLegacyFeatureMigrationIdentitiesAreNeverAliases(t *testing.T) {
for version, legacyName := range legacyFeatureMigrationNames {
err := ValidateMigrationIdentity(version, legacyName)
if err == nil {
t.Fatalf("legacy v%d %q was accepted", version, legacyName)
}
if got := err.Error(); !containsAll(got, "migration identity mismatch", "legacy feature migration numbering") {
t.Fatalf("legacy v%d %q was not explicitly rejected: %v", version, legacyName, err)
}
}
}
func containsAll(value string, parts ...string) bool {
for _, part := range parts {
if !strings.Contains(value, part) {
return false
}
}
return true
}