Files
gbr-games/cmd/gbrgames/import_test.go
T
gregandClaude Opus 5.5 e9ff989246
Validate game templates / validate (push) Successful in 9m32s
Validate game templates / publish (push) Canceled after 0s
Validate game templates / boot-test (push) Canceled after 5m15s
ci: boot-test changed games before publishing
Only games whose folder changed are boot-tested (against the previous
main commit, or against main on branches; manual runs pick games). Each
one is deployed by the node-agent's real deploy code on a dedicated
game-test runner, in a network that can reach the internet but not the
LAN. Publishing to the panel runs only if they all booted.

- boottest-payload builds the DEPLOY_SERVER message the panel would send
- readyPattern/failPatterns in game.yaml; readyExample in test.yaml is
  checked against the pattern during validation
- secrets in test.yaml come from CI; a game missing one is skipped
- Minecraft gets a ready pattern; Dragonwilds needs DRAGONWILDS_OWNER_ID
- RUNNER.md + scripts/runner: runner, isolated network, systemd unit

Also fixes newline values ("\n" separators/footers) that yaml.v3 wrote
as "" on import, which would have broken ARK and Dragonwilds config
files once synced, and adds a round-trip test for the importer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 17:49:19 -04:00

49 lines
1.4 KiB
Go

package main
import (
"encoding/json"
"os"
"path/filepath"
"reflect"
"testing"
)
// Whatever the panel exports must come back unchanged after import and export.
func TestImportRoundTrip(t *testing.T) {
game := map[string]any{
"id": "round-trip", "name": "Round Trip", "defaultDockerImage": "debian:12", "installMethod": "NONE",
"defaultStartupCommand": "./start.sh -log",
"requiredMemoryMb": float64(4096),
"configFormatOptions": map[string]any{
"separator": "\n", "footer": "\n", "header": "[Section]\n", "assignment": "=", "space": " ",
"multi": "[A]\nOptionSettings=(", "quoteStrings": true,
},
"installConfig": map[string]any{"script": "#!/bin/bash\nset -e\necho hi\n"},
"defaultConfig": map[string]any{"Rate": "1.000000", "Port": float64(7777), "Empty": "", "Ratio": 0.5},
}
dir := t.TempDir()
path := filepath.Join(dir, "game.yaml")
if err := writeGame(path, game); err != nil {
t.Fatal(err)
}
raw, err := os.ReadFile(path)
if err != nil {
t.Fatal(err)
}
loaded, err := loadYAML(raw)
if err != nil {
t.Fatal(err)
}
// Compare as JSON, the way the panel receives it
var got, want any
gotJSON, _ := json.Marshal(loaded)
wantJSON, _ := json.Marshal(game)
json.Unmarshal(gotJSON, &got)
json.Unmarshal(wantJSON, &want)
if !reflect.DeepEqual(got, want) {
t.Fatalf("round trip changed the template\n got: %s\nwant: %s\nyaml:\n%s", gotJSON, wantJSON, raw)
}
}