Restore durable log ingest and typed plugin projections

This commit is contained in:
npc0-hue
2026-09-02 10:20:30 +08:00
parent 40ac46ba17
commit 6018d8f0fc
61 changed files with 809 additions and 3157 deletions
@@ -101,9 +101,24 @@ func TestCoreServiceKeepsPlatformBuildKeyOffMachineJobChannel(t *testing.T) {
domain.RuntimeLogSource{Key: "console", Kind: "process.stdout", TargetKey: "server/process", StreamKey: "console", CursorKind: "sequence", RetentionDays: 14},
domain.RuntimeLogSource{Key: "server-events", Kind: "file.tail", TargetKey: "logs/server", StreamKey: "scum.server", CursorKind: "fingerprint", RetentionDays: 90},
)
plugin.RuntimeProfiles.DataTargets = []domain.RuntimeDataTarget{{
Key: "scum-database",
Kind: "sqlite.snapshot",
TransportKey: "scum-database",
SourceRootKey: "server-root",
SourcePath: "SCUM/Saved/SaveFiles/SCUM.db",
WorkspaceKey: "databases/scum-database",
RefreshPolicy: "on-demand-snapshot",
MaxBytes: 1024 * 1024,
Platforms: []string{"linux"},
}}
if err := svc.store.GamePlugins().Update(plugin); err != nil {
t.Fatalf("seed plugin lifecycle assets: %v", err)
}
instance.Deployment.ServerRoot = "/srv/scum"
if err := svc.store.ServerInstances().Update(instance); err != nil {
t.Fatalf("seed instance deployment root: %v", err)
}
inputs := make(chan domain.DistributionBuildInput, 1)
release := make(chan struct{})
var releaseOnce sync.Once
@@ -149,6 +164,9 @@ func TestCoreServiceKeepsPlatformBuildKeyOffMachineJobChannel(t *testing.T) {
if len(plan.DependencyProbes) != 1 || plan.DependencyProbes[0].Key != "java-runtime" || len(plan.InstallPlans) != 1 || plan.InstallPlans[0].Key != "java-install" || len(plan.LogSources) != 1 || !hasAutonomousLogSource(plan.LogSources, "process.stdout", "console") || plan.RuntimeBindings["logs/latest"] != "runtime.logs.latest" {
t.Fatalf("autonomous lifecycle plan lost plugin runtime declarations: %+v", plan)
}
if len(plan.DataTargets) != 1 || plan.DataTargets[0].Key != "scum-database" || plan.DataTargets[0].Kind != "sqlite.snapshot" || plan.DataTargets[0].SourcePath != "SCUM/Saved/SaveFiles/SCUM.db" || plan.RuntimeBindings["server-root"] != instance.Deployment.ServerRoot {
t.Fatalf("autonomous lifecycle plan lost private database target bindings: %+v", plan)
}
if hasAutonomousLogSource(plan.LogSources, "file.tail", "latest-log") || hasAutonomousLogSource(plan.LogSources, "file.tail", "scum.server") {
t.Fatalf("autonomous lifecycle plan must not carry file-tail sources into process.start: %+v", plan.LogSources)
}
@@ -214,55 +232,6 @@ func hasAutonomousLogSource(sources []domain.RunAutonomousLogSource, kind string
return false
}
func TestCoreServiceRunDistributionDefaultsEmptyDeploymentProfileToPluginLifecycleProfile(t *testing.T) {
svc := newTestCoreService()
plugin := scumDeploymentTestPlugin()
plugin.Name = "SCUM"
plugin.Version = "0.1.1"
plugin.ServerType = "scum"
plugin.Status = domain.GamePluginStatusInstalled
plugin.SupportedOS = []string{"windows"}
plugin.DeclaredPermissions = []string{"server.run.distribution"}
plugin.LifecycleActions = domain.PluginLifecycleActions{Install: "actions/install.json", Start: "actions/start.json", Stop: "actions/stop.json", Status: "actions/status.json"}
plugin.RuntimeProfiles.LifecycleProfiles = []domain.RuntimeLifecycleProfile{{Key: "run-local", Mode: "local-process", Capabilities: []string{domain.LifecycleCapabilityInstall, domain.LifecycleCapabilityStart, domain.LifecycleCapabilityStop, domain.LifecycleCapabilityStatus}, ActionRefs: domain.PluginLifecycleActions{Install: "actions/install.json", Start: "actions/start.json", Stop: "actions/stop.json", Status: "actions/status.json"}, Platforms: []string{"windows"}}}
requireManualSCUMRuntimeBindings(&plugin, "run-local")
if err := svc.store.GamePlugins().Create(plugin); err != nil {
t.Fatalf("create SCUM plugin: %v", err)
}
session := createServiceUserAndLogin(t, svc, domain.User{ID: "scum-default-profile-owner", DisplayName: "SCUM Default Profile Owner", Email: "scum-default-profile@example.test", Roles: []string{"server-owner"}, PasswordHash: "secret-password"})
created, err := svc.CreateServerInstanceWorkflowForSession(session, domain.ServerLifecycleCreate{
ID: "scum-default-profile-package", PluginID: plugin.ID, Name: "SCUM Default Profile Package", IdempotencyKey: "scum-default-profile-package-create",
Deployment: domain.ServerDeploymentDefinition{Mode: domain.ServerDeploymentModeGuided, ServerRoot: `D:\scum-default-profile`, CreateInputs: map[string]string{"serverName": "Moon", "gamePort": "27000", "queryPort": "27015", "maxPlayers": "128"}},
})
if err != nil {
t.Fatalf("create SCUM guided draft without explicit profile: %v", err)
}
if created.Instance.Deployment.ProfileKey != "run-local" {
t.Fatalf("expected create defaults to persist plugin lifecycle profile, got %+v", created.Instance.Deployment)
}
legacy := created.Instance
legacy.Deployment.ProfileKey = ""
if err := svc.store.ServerInstances().Update(legacy); err != nil {
t.Fatalf("simulate legacy empty deployment profile: %v", err)
}
inputs := make(chan domain.DistributionBuildInput, 1)
svc.ConfigureDistributionBuilder(captureDistributionBuilder{inputs: inputs, payload: []byte("profile-default-build")})
if _, err := svc.GenerateRunDistributionForSession(session, domain.RunDistributionGenerateRequest{ServerInstanceID: legacy.ID, TargetOS: "windows", TargetArch: "amd64", IdempotencyKey: "scum-default-profile-package"}); err != nil {
t.Fatalf("generate Run distribution with empty deployment profile: %v", err)
}
var platformInput domain.DistributionBuildInput
select {
case platformInput = <-inputs:
case <-time.After(time.Second):
t.Fatal("platform builder did not receive profile-defaulted input")
}
plan := platformInput.AutonomousLifecycle
if platformInput.ProfileKey != "run-local" || plan == nil || plan.ProfileKey != "run-local" || plan.Deployment == nil || plan.Deployment.ProfileKey != "run-local" {
t.Fatalf("expected package context to default empty deployment profile to run-local, input=%+v plan=%+v", platformInput, plan)
}
}
func TestCoreServiceBuildsWithoutRegisteredDistributionWorker(t *testing.T) {
svc, session, instance := newDistributionTestFixture(t)
bootstrapEndpoint, err := svc.store.RunEndpoints().Get(instance.RunEndpointID)