Prune stale plugin metadata
This commit is contained in:
@@ -255,6 +255,62 @@ func TestFileStorePersistsAndReloadsResources(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestFileStoreNormalizesPluginVersionsAndPrunesLegacySCUMSnapshotData(t *testing.T) {
|
||||
path := filepath.Join(t.TempDir(), "metadata.json")
|
||||
stalePlugin := domain.GamePlugin{ID: "game.scum.codex.20260804095301", Name: "SCUM Server", Version: "0.1.4", ServerType: "scum", ServerDisplayName: "SCUM Dedicated Server", ManifestRef: "plugins/examples/scum-server-plugin/game.scum.codex.20260804095301/manifest.json", Status: domain.GamePluginStatusInstalled}
|
||||
latestPlugin := domain.GamePlugin{ID: "game.scum", Name: "SCUM Server", Version: "0.1.15", ServerType: "scum", ServerDisplayName: "SCUM Dedicated Server", ManifestRef: "artifact://manifests/game.scum/0.1.15", Status: domain.GamePluginStatusInstalled}
|
||||
stamp := time.Date(2026, 9, 14, 9, 0, 0, 0, time.UTC)
|
||||
snapshot := StoreSnapshot{
|
||||
GamePlugins: []domain.GamePlugin{stalePlugin, latestPlugin},
|
||||
ServerInstances: []domain.ServerInstance{{ID: "server-scum", PluginID: stalePlugin.ID, PluginVersion: stalePlugin.Version, Name: "SCUM", State: domain.ServerInstanceStateDraft, CreatedAt: stamp, UpdatedAt: stamp}},
|
||||
RuntimeBindings: []domain.RuntimeBinding{{ID: "runtime-binding-server-scum", ServerInstanceID: "server-scum", PluginID: stalePlugin.ID, PluginVersion: stalePlugin.Version, ProfileKey: "local", Mode: "local-process", Status: domain.RuntimeBindingStatusComplete, CreatedAt: stamp, UpdatedAt: stamp}},
|
||||
Jobs: []domain.Job{
|
||||
{ID: "job-scum-sqlite-query", ServerInstanceID: "server-scum", RunEndpointID: "run-local", Capability: domain.JobCapabilityRemoteRunDBSQLiteQuery, IdempotencyKey: "legacy-query", State: domain.JobStateSucceeded, CreatedAt: stamp, UpdatedAt: stamp},
|
||||
{ID: "job-scum-start", ServerInstanceID: "server-scum", RunEndpointID: "run-local", Capability: domain.JobCapabilityRemoteRunProgram, IdempotencyKey: "start", State: domain.JobStateSucceeded, CreatedAt: stamp, UpdatedAt: stamp},
|
||||
},
|
||||
PluginDataRecords: []domain.PluginDataRecord{
|
||||
{ID: snapshotPluginDataID("server-scum", stalePlugin.ID, "scum_gifts", "starter"), PluginID: stalePlugin.ID, ServerInstanceID: "server-scum", Collection: "scum_gifts", Key: "starter", Value: map[string]any{"name": "Starter"}, CreatedAt: stamp, UpdatedAt: stamp},
|
||||
{ID: snapshotPluginDataID("server-scum", stalePlugin.ID, "scum_trajectories", "point-1"), PluginID: stalePlugin.ID, ServerInstanceID: "server-scum", Collection: "scum_trajectories", Key: "point-1", Value: map[string]any{"source": "legacy"}, CreatedAt: stamp, UpdatedAt: stamp},
|
||||
},
|
||||
}
|
||||
payload, err := json.Marshal(snapshot)
|
||||
if err != nil {
|
||||
t.Fatalf("marshal stale snapshot: %v", err)
|
||||
}
|
||||
if err := os.WriteFile(path, payload, 0o600); err != nil {
|
||||
t.Fatalf("write stale snapshot: %v", err)
|
||||
}
|
||||
|
||||
store, err := NewFileStore(path)
|
||||
if err != nil {
|
||||
t.Fatalf("reload stale snapshot: %v", err)
|
||||
}
|
||||
plugins, err := store.GamePlugins().List(domain.GamePluginFilter{ServerType: "scum"})
|
||||
if err != nil || len(plugins) != 1 || plugins[0].ID != latestPlugin.ID || plugins[0].Version != latestPlugin.Version {
|
||||
t.Fatalf("expected only latest plugin, plugins=%+v err=%v", plugins, err)
|
||||
}
|
||||
server, err := store.ServerInstances().Get("server-scum")
|
||||
if err != nil || server.PluginID != latestPlugin.ID || server.PluginVersion != latestPlugin.Version {
|
||||
t.Fatalf("expected server reference migration, server=%+v err=%v", server, err)
|
||||
}
|
||||
binding, err := store.RuntimeBindings().Get("runtime-binding-server-scum")
|
||||
if err != nil || binding.PluginID != latestPlugin.ID || binding.PluginVersion != latestPlugin.Version {
|
||||
t.Fatalf("expected runtime binding migration, binding=%+v err=%v", binding, err)
|
||||
}
|
||||
config, err := store.PluginDataRecords().List(domain.PluginDataFilter{PluginID: latestPlugin.ID, ServerInstanceID: "server-scum", Collection: "scum_gifts"})
|
||||
if err != nil || len(config) != 1 || config[0].Key != "starter" {
|
||||
t.Fatalf("expected plugin-owned config data to migrate, data=%+v err=%v", config, err)
|
||||
}
|
||||
legacy, err := store.PluginDataRecords().List(domain.PluginDataFilter{ServerInstanceID: "server-scum", Collection: "scum_trajectories"})
|
||||
if err != nil || len(legacy) != 0 {
|
||||
t.Fatalf("expected legacy SCUM projection data to be pruned, data=%+v err=%v", legacy, err)
|
||||
}
|
||||
jobs, err := store.Jobs().List(domain.JobFilter{ServerInstanceID: "server-scum"})
|
||||
if err != nil || len(jobs) != 1 || jobs[0].ID != "job-scum-start" {
|
||||
t.Fatalf("expected legacy SCUM sqlite query job to be pruned, jobs=%+v err=%v", jobs, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMySQLSnapshotRoundTripsDurableJobSchedulingMetadata(t *testing.T) {
|
||||
stamp := time.Date(2026, 7, 18, 12, 0, 0, 0, time.UTC)
|
||||
source := &MySQLStore{MemoryStore: NewMemoryStore()}
|
||||
|
||||
Reference in New Issue
Block a user