package main import ( "os" "path/filepath" "strings" "testing" ) func TestBootFailureKeepsVerdictAndServerOutput(t *testing.T) { out := "[boot-test] deploying boottest-example (cm2network/steamcmd)\n" + "[boot-test] container started; waiting for ready pattern /Server ready/\n" + "[boot-test] FAILED: container exited before it was ready\n" + "---- last 2 log lines ----\n" + "Unknown argument --save-dir\n" + "Usage: example_server ...\n" got := bootFailure(out) if !strings.Contains(got, "failed: FAILED: container exited before it was ready") { t.Errorf("verdict missing: %s", got) } if !strings.Contains(got, "Unknown argument --save-dir") || strings.Contains(got, "deploying boottest") { t.Errorf("want only the server's last lines, got: %s", got) } if v := bootVerdict("[boot-test] PASSED: READY: Server ready"); v != "PASSED: READY: Server ready" { t.Errorf("verdict = %q", v) } } func TestOutsideDirsSkipsSteamNoise(t *testing.T) { r := &bootReport{ContainerChanges: []string{ "A /home/steam/.config/example-game/worlds/w.db", "A /home/steam/Steam/logs/connection_log.txt", "C /home/steam/Steam/config/config.vdf", "C /home/steam/.steam/registry.vdf", "A /usr/sbin/docker-init", }} got := outsideDirs(r) if len(got) != 1 || got[0] != "/home/steam/.config/example-game/worlds" { t.Errorf("got %v", got) } if outsideDirs(nil) != nil { t.Error("nil report should have no dirs") } } func TestVariantNotes(t *testing.T) { v := variant{Title: "Crossplay", Description: "PC + Xbox", StartupHint: "./example_server -crossplay", Ports: []string{"30000/udp"}} got := variantNotes(v, "needs Xbox") for _, want := range []string{"variant: Crossplay (PC + Xbox)", "documented startup: ./example_server -crossplay", "30000/udp", "the admin asked for: needs Xbox"} { if !strings.Contains(got, want) { t.Errorf("missing %q in %q", want, got) } } } func TestBlankRequiredLookingSettings(t *testing.T) { dir := t.TempDir() game := filepath.Join(dir, "example") os.MkdirAll(game, 0o755) os.WriteFile(filepath.Join(game, "game.yaml"), []byte(`id: example defaultConfig: JoinPassword: "" AdminPassword: "" ServerPassword: set-by-default ServerName: x configSchema: properties: JoinPassword: {type: string} AdminPassword: {type: string, x-generate: {type: password}} ServerPassword: {type: string} ServerName: {type: string} `), 0o644) got := blankRequiredLooking(dir, "example") if len(got) != 1 || got[0] != "JoinPassword" { t.Errorf("got %v, want only JoinPassword (AdminPassword is generated, ServerPassword has a default)", got) } msg := emptySettingsProblem(got, "FAILED: server crashed") if !strings.Contains(msg, "stops when JoinPassword is empty") || !strings.Contains(msg, `"x-generate": {"type": "password"}`) { t.Errorf("message: %s", msg) } } func TestScoreDraftAgainstTheRealTemplate(t *testing.T) { real := map[string]any{"defaultDockerImage": "cm2network/steamcmd", "installMethod": "STEAMCMD", "installConfig": map[string]any{"appId": "1000000"}, "defaultPorts": []any{"30000/udp", "30001/udp"}, "configSchema": map[string]any{"properties": map[string]any{"ServerName": map[string]any{}, "MaxPlayers": map[string]any{}}}} draft := map[string]any{"defaultDockerImage": "cm2network/steamcmd", "installMethod": "STEAMCMD", "installConfig": map[string]any{"appId": "1000000"}, "defaultPorts": []any{"30000/udp", "30002/tcp"}, "readyPattern": `Server is ready`, "configSchema": map[string]any{"properties": map[string]any{"SERVER_NAME": map[string]any{}, "WorldName": map[string]any{}}}} var s evalScore scoreDraft(&s, real, map[string]any{"readyExample": "12:00:01 Server is ready for players"}, draft) if !s.SameRoute || s.PortsSame || !s.ReadyMatch || s.SettingsHit != 1 || s.RealSetting != 2 || s.Settings != 2 { t.Errorf("score %+v", s) } if strings.Join(s.PortsDiff, ",") != "extra 30002/tcp,missing 30001/udp" { t.Errorf("ports diff %v", s.PortsDiff) } } func TestPRTextForBuildsAndRepairs(t *testing.T) { _, title := prText("Example", "job1", &buildResult{Passed: true}) if title != "feat(games): add Example" { t.Errorf("build title %q", title) } commit, title := prText("Example", "job1", &buildResult{Repair: true}) if title != "WIP: fix(games): repair Example (did not boot yet)" || !strings.HasPrefix(commit, "fix(games): repair Example") { t.Errorf("repair %q / %q", title, commit) } }