panel public release
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,191 @@
|
||||
package steamvdf
|
||||
|
||||
import "testing"
|
||||
|
||||
// Realistic ACF as steamcmd writes it for a 7DTD dedicated server pinned
|
||||
// to a frozen beta branch.
|
||||
const acf7dtd = `"AppState"
|
||||
{
|
||||
"appid" "294420"
|
||||
"Universe" "1"
|
||||
"name" "7 Days to Die Dedicated Server"
|
||||
"StateFlags" "4"
|
||||
"installdir" "7 Days to Die Dedicated Server"
|
||||
"LastUpdated" "1750912345"
|
||||
"SizeOnDisk" "14680064000"
|
||||
"StagingSize" "0"
|
||||
"buildid" "14503775"
|
||||
"LastOwner" "76561190000000000"
|
||||
"UpdateResult" "0"
|
||||
"BytesToDownload" "0"
|
||||
"BytesDownloaded" "0"
|
||||
"AutoUpdateBehavior" "0"
|
||||
"AllowOtherDownloadsWhileRunning" "0"
|
||||
"ScheduledAutoUpdate" "0"
|
||||
"InstalledDepots"
|
||||
{
|
||||
"294422"
|
||||
{
|
||||
"manifest" "1118115119020227469"
|
||||
"size" "14680064000"
|
||||
}
|
||||
}
|
||||
"UserConfig"
|
||||
{
|
||||
"betakey" "v2.6"
|
||||
}
|
||||
"MountedConfig"
|
||||
{
|
||||
"betakey" "v2.6"
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
const acfPublic = `"AppState"
|
||||
{
|
||||
"appid" "2430930"
|
||||
"name" "Palworld Dedicated Server"
|
||||
"buildid" "20112233"
|
||||
"UserConfig"
|
||||
{
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
func TestParseAppManifestBetaBranch(t *testing.T) {
|
||||
m, err := ParseAppManifest(acf7dtd)
|
||||
if err != nil {
|
||||
t.Fatalf("ParseAppManifest: %v", err)
|
||||
}
|
||||
if m.AppID != "294420" || m.BuildID != "14503775" || m.BetaKey != "v2.6" {
|
||||
t.Fatalf("got %+v", m)
|
||||
}
|
||||
if m.Name != "7 Days to Die Dedicated Server" {
|
||||
t.Fatalf("name: %q", m.Name)
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseAppManifestPublic(t *testing.T) {
|
||||
m, err := ParseAppManifest(acfPublic)
|
||||
if err != nil {
|
||||
t.Fatalf("ParseAppManifest: %v", err)
|
||||
}
|
||||
if m.BuildID != "20112233" || m.BetaKey != "" {
|
||||
t.Fatalf("got %+v", m)
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseAppManifestNoBuildID(t *testing.T) {
|
||||
if _, err := ParseAppManifest(`"AppState" { "appid" "1" }`); err == nil {
|
||||
t.Fatal("expected error for manifest without buildid")
|
||||
}
|
||||
}
|
||||
|
||||
// app_info_print output as steamcmd emits it: banner noise, the numeric
|
||||
// appid root key, escaped quotes, nested branches with pwdrequired etc.
|
||||
const appInfo = `Redirecting stderr to '/root/Steam/logs/stderr.txt'
|
||||
Loading Steam API...OK
|
||||
Connecting anonymously to Steam Public...OK
|
||||
Waiting for client config...OK
|
||||
Waiting for user info...OK
|
||||
AppID : 294420, change number : 27581234/0, last change : Sat Jun 28 12:00:00 2026
|
||||
"294420"
|
||||
{
|
||||
"common"
|
||||
{
|
||||
"name" "7 Days to Die Dedicated Server"
|
||||
"type" "Tool"
|
||||
}
|
||||
"config"
|
||||
{
|
||||
"installdir" "7 Days to Die Dedicated Server"
|
||||
}
|
||||
"depots"
|
||||
{
|
||||
"294422"
|
||||
{
|
||||
"name" "Linux Depot"
|
||||
"config"
|
||||
{
|
||||
"oslist" "linux"
|
||||
}
|
||||
}
|
||||
"branches"
|
||||
{
|
||||
"public"
|
||||
{
|
||||
"buildid" "19216811"
|
||||
"timeupdated" "1751168000"
|
||||
}
|
||||
"latest_experimental"
|
||||
{
|
||||
"buildid" "19333444"
|
||||
"description" "Latest \"experimental\" build"
|
||||
"timeupdated" "1752168000"
|
||||
}
|
||||
"v2.6"
|
||||
{
|
||||
"buildid" "14503775"
|
||||
"description" "2.6 Stable"
|
||||
"timeupdated" "1750168000"
|
||||
}
|
||||
"private_qa"
|
||||
{
|
||||
"buildid" "19999999"
|
||||
"pwdrequired" "1"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
func TestParseAppInfoBranches(t *testing.T) {
|
||||
b, err := ParseAppInfoBranches(appInfo, "294420")
|
||||
if err != nil {
|
||||
t.Fatalf("ParseAppInfoBranches: %v", err)
|
||||
}
|
||||
want := map[string]string{
|
||||
"public": "19216811",
|
||||
"latest_experimental": "19333444",
|
||||
"v2.6": "14503775",
|
||||
"private_qa": "19999999",
|
||||
}
|
||||
for k, v := range want {
|
||||
if b[k] != v {
|
||||
t.Fatalf("branch %s: got %q want %q (all: %v)", k, b[k], v, b)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseAppInfoBranchesUnknownRootKey(t *testing.T) {
|
||||
// Caller passes the wrong appid; fallback finds the object anyway.
|
||||
b, err := ParseAppInfoBranches(appInfo, "999999")
|
||||
if err != nil {
|
||||
t.Fatalf("fallback failed: %v", err)
|
||||
}
|
||||
if b["public"] != "19216811" {
|
||||
t.Fatalf("got %v", b)
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseAppInfoNoBranches(t *testing.T) {
|
||||
if _, err := ParseAppInfoBranches(`"1" { "common" { "name" "x" } }`, "1"); err == nil {
|
||||
t.Fatal("expected error when branches missing")
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseToleratesCommentsAndUnquoted(t *testing.T) {
|
||||
kv, err := Parse("// comment\nAppState { key value // trailing\n nested { a b } }")
|
||||
if err != nil {
|
||||
t.Fatalf("Parse: %v", err)
|
||||
}
|
||||
if kv.Get("AppState", "key") != "value" || kv.Get("appstate", "nested", "a") != "b" {
|
||||
t.Fatalf("got %v", kv)
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseUnterminated(t *testing.T) {
|
||||
if _, err := Parse(`"A" { "k" "v"`); err == nil {
|
||||
t.Fatal("expected unterminated-object error")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user