package catalog import ( "strings" "testing" "git.unkin.net/unkin/bootapi/internal/model" ) const almaYAML = ` name: almalinux9 match: platforms: [almalinux9] family: almalinux kickstart: almalinux9 version_default: "9" kernel_url: "{{.ArtifactBase}}/almalinux/{{.Version}}/BaseOS/{{.Arch}}/os/images/pxeboot/vmlinuz" initrd_url: "{{.ArtifactBase}}/almalinux/{{.Version}}/BaseOS/{{.Arch}}/os/images/pxeboot/initrd.img" kernel_args: [inst.text] vars: mirror: "{{.ArtifactBase}}/almalinux/{{.Version}}" ` const fedoraYAML = ` name: fedora match: family: fedora kickstart: fedora version_default: "41" kernel_url: "{{.ArtifactBase}}/fedora/releases/{{.Version}}/Everything/{{.Arch}}/os/images/pxeboot/vmlinuz" initrd_url: "{{.ArtifactBase}}/fedora/releases/{{.Version}}/Everything/{{.Arch}}/os/images/pxeboot/initrd.img" ` func testCatalog(t *testing.T) *Catalog { t.Helper() c, err := Parse(map[string][]byte{ "almalinux9.yaml": []byte(almaYAML), "fedora.yaml": []byte(fedoraYAML), }) if err != nil { t.Fatalf("Parse: %v", err) } return c } func TestSelect(t *testing.T) { c := testCatalog(t) cases := []struct { host *model.Host want string ok bool }{ {&model.Host{Platform: "almalinux9", OSFamily: "almalinux"}, "almalinux9", true}, // exact platform {&model.Host{Platform: "fedora42", OSFamily: "fedora"}, "fedora", true}, // family {&model.Host{Platform: "almalinux9", TemplateOverride: "fedora"}, "fedora", true}, // override wins {&model.Host{Platform: "debian12", OSFamily: "debian"}, "", false}, // no match } for _, tc := range cases { d, ok := c.Select(tc.host) if ok != tc.ok { t.Errorf("Select(%+v) ok=%v, want %v", tc.host, ok, tc.ok) continue } if ok && d.Name != tc.want { t.Errorf("Select(%+v) = %q, want %q", tc.host, d.Name, tc.want) } } } func TestResolve(t *testing.T) { c := testCatalog(t) h := &model.Host{Platform: "almalinux9", OSFamily: "almalinux", OSVersion: "9", Arch: "x86_64"} d, ok := c.Select(h) if !ok { t.Fatal("expected a match") } r, err := d.Resolve(h, "https://af/api/v1/remote") if err != nil { t.Fatal(err) } if r.KernelURL != "https://af/api/v1/remote/almalinux/9/BaseOS/x86_64/os/images/pxeboot/vmlinuz" { t.Errorf("kernel = %q", r.KernelURL) } if r.Vars["mirror"] != "https://af/api/v1/remote/almalinux/9" { t.Errorf("mirror = %q", r.Vars["mirror"]) } if len(r.KernelArgs) != 1 || r.KernelArgs[0] != "inst.text" { t.Errorf("kernel_args = %v", r.KernelArgs) } } func TestResolveVersionDefault(t *testing.T) { c := testCatalog(t) // Host with no OSVersion falls back to the catalog's version_default. h := &model.Host{Platform: "fedora", OSFamily: "fedora", Arch: "x86_64"} d, _ := c.Select(h) r, err := d.Resolve(h, "https://af") if err != nil { t.Fatal(err) } if !strings.Contains(r.KernelURL, "/releases/41/") { t.Errorf("expected version_default 41 in %q", r.KernelURL) } } func TestParseValidation(t *testing.T) { bad := map[string]string{ "no-kernel": "name: x\nmatch: {platforms: [x]}\nkickstart: x\ninitrd_url: y", "no-match": "name: x\nkickstart: x\nkernel_url: k\ninitrd_url: i", "no-name": "kickstart: x\nmatch: {family: x}\nkernel_url: k\ninitrd_url: i", "bad-template": "name: x\nmatch: {family: x}\nkickstart: x\nkernel_url: \"{{ .Nope\"\ninitrd_url: i", } for name, y := range bad { if _, err := Parse(map[string][]byte{name + ".yaml": []byte(y)}); err == nil { t.Errorf("%s: expected a validation error, got nil", name) } } } func TestNames(t *testing.T) { c := testCatalog(t) got := strings.Join(c.Names(), ",") if got != "almalinux9,fedora" { t.Errorf("Names() = %q", got) } }