Support declared graceful stop and steam.update probe
- LifecycleActionTemplate 新增 gracefulStop:stop 动作可声明插件自有的优雅关闭命令、 参数、环境、超时与 fallback;超时且 fallback=report 时任务失败,避免默认杀进程。 - 依赖探针新增 steam.update:通过 steamcmd +app_info_print 读取公开分支 buildid, 与本地 appmanifest_<appid>.acf 比较,输出 installed/latest/update=yes|no|unknown。 - 依赖执行输入新增 ServerRoot,供探针定位插件声明的服务器安装目录。
This commit is contained in:
@@ -92,7 +92,7 @@ func TestDependencyInstallExecutesTypedPlanAndResumesCompletedSteps(t *testing.T
|
||||
|
||||
first := worker.executeDependencyJob(context.Background(), assignment)
|
||||
if first.State != lifecycleResultStateSucceeded || first.ExecutionResult.Kind != "dependency.install" || first.ExecutionResult.Checksum != dependencyTestDigest {
|
||||
state, evidence, probeErr := worker.executor.runDependencyProbe(context.Background(), client.dependencyInput.Probe, client.dependencyInput.Bindings)
|
||||
state, evidence, probeErr := worker.executor.runDependencyProbe(context.Background(), client.dependencyInput.Probe, client.dependencyInput.Bindings, client.dependencyInput.ServerRoot)
|
||||
t.Fatalf("expected real typed dependency install, got %+v calls=%+v present=%v probe=%s evidence=%s err=%v", first, runner.calls, runner.present, state, evidence, probeErr)
|
||||
}
|
||||
second := worker.executeDependencyJob(context.Background(), assignment)
|
||||
@@ -165,6 +165,77 @@ func TestDependencyInstallRejectsLegacySteamCMDAppAdapter(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
type steamProbeSupervisor struct {
|
||||
output string
|
||||
exit int
|
||||
calls [][]string
|
||||
}
|
||||
|
||||
func (supervisor *steamProbeSupervisor) Run(_ context.Context, command ProcessCommand) (ProcessResult, error) {
|
||||
supervisor.calls = append(supervisor.calls, append([]string(nil), command.Args...))
|
||||
return ProcessResult{ExitCode: supervisor.exit, Stdout: supervisor.output}, nil
|
||||
}
|
||||
|
||||
func TestSteamUpdateProbeReportsInstalledAndPublishedBuilds(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
steamcmdDir := filepath.Join(dir, "steamcmd")
|
||||
if err := os.MkdirAll(steamcmdDir, 0o700); err != nil {
|
||||
t.Fatalf("create steamcmd fixture dir: %v", err)
|
||||
}
|
||||
steamcmd := filepath.Join(steamcmdDir, "steamcmd.exe")
|
||||
if err := os.WriteFile(steamcmd, []byte("steamcmd fixture"), 0o700); err != nil {
|
||||
t.Fatalf("write steamcmd fixture: %v", err)
|
||||
}
|
||||
installRoot := filepath.Join(dir, "scumserver")
|
||||
if err := os.MkdirAll(filepath.Join(installRoot, "steamapps"), 0o700); err != nil {
|
||||
t.Fatalf("create install root fixture: %v", err)
|
||||
}
|
||||
manifest := "\"AppState\"\n{\n\t\"appid\"\t\t\"3792580\"\n\t\"buildid\"\t\t\"16912763\"\n}\n"
|
||||
if err := os.WriteFile(filepath.Join(installRoot, "steamapps", "appmanifest_3792580.acf"), []byte(manifest), 0o600); err != nil {
|
||||
t.Fatalf("write appmanifest fixture: %v", err)
|
||||
}
|
||||
published := "AppID : 3792580, change number : 1\n\"depots\"\n{\n\t\"buildid\"\t\t\"99999999\"\n}\n\"branches\"\n{\n\t\"public\"\n\t{\n\t\t\"buildid\"\t\t\"16919999\"\n\t}\n}\n"
|
||||
runner := &steamProbeSupervisor{output: published}
|
||||
executor := NewLifecycleExecutor(WithLifecycleWorkspaceRoot(t.TempDir()), WithDependencyCommandRunner(runner))
|
||||
probe := protocol.DependencyProbe{Key: "scum-server-build", Kind: "steam.update", TargetKey: "steamcmd", SteamAppID: "3792580"}
|
||||
|
||||
state, evidence, err := executor.runDependencyProbe(context.Background(), probe, map[string]string{"steamcmd": steamcmd}, installRoot)
|
||||
if err != nil {
|
||||
t.Fatalf("steam update probe failed: %v", err)
|
||||
}
|
||||
if state != "present" || evidence != "installed=16912763 latest=16919999 update=yes" {
|
||||
t.Fatalf("unexpected steam update evidence: state=%s evidence=%s", state, evidence)
|
||||
}
|
||||
if len(runner.calls) != 1 || !strings.Contains(strings.Join(runner.calls[0], " "), "+app_info_print 3792580") {
|
||||
t.Fatalf("unexpected steamcmd invocation: %+v", runner.calls)
|
||||
}
|
||||
|
||||
runner.output = strings.Replace(published, "16919999", "16912763", 1)
|
||||
state, evidence, err = executor.runDependencyProbe(context.Background(), probe, map[string]string{"steamcmd": steamcmd}, installRoot)
|
||||
if err != nil {
|
||||
t.Fatalf("steam update probe failed: %v", err)
|
||||
}
|
||||
if state != "present" || evidence != "installed=16912763 latest=16912763 update=no" {
|
||||
t.Fatalf("unexpected up-to-date evidence: state=%s evidence=%s", state, evidence)
|
||||
}
|
||||
|
||||
if err := os.RemoveAll(filepath.Join(installRoot, "steamapps")); err != nil {
|
||||
t.Fatalf("remove install root manifest: %v", err)
|
||||
}
|
||||
state, evidence, err = executor.runDependencyProbe(context.Background(), probe, map[string]string{"steamcmd": steamcmd}, "")
|
||||
if err != nil {
|
||||
t.Fatalf("steam update probe without install root failed: %v", err)
|
||||
}
|
||||
if state != "unknown" || evidence != "installed=none latest=16912763 update=yes" {
|
||||
t.Fatalf("unexpected unknown installed build evidence: state=%s evidence=%s", state, evidence)
|
||||
}
|
||||
|
||||
probe.SteamAppID = "3792580;rm"
|
||||
if _, _, err := executor.runDependencyProbe(context.Background(), probe, map[string]string{"steamcmd": steamcmd}, installRoot); err == nil {
|
||||
t.Fatal("expected invalid steam app id rejection")
|
||||
}
|
||||
}
|
||||
|
||||
func dependencyAssignment(capability string) protocol.RunJobAssignment {
|
||||
assignment := workerJobAssignment(capability)
|
||||
assignment.LeaseToken = "lease-dependency"
|
||||
|
||||
Reference in New Issue
Block a user