package platform import ( "os" "path/filepath" "testing" ) func TestGetDistroFamily(t *testing.T) { tests := []struct { name string id string idLike string want string }{ {"fedora", "fedora", "", "rhel"}, {"rocky via ID_LIKE", "rocky", "rhel centos fedora", "rhel"}, {"arch", "arch", "", "arch"}, {"manjaro via ID_LIKE", "manjaro", "arch", "arch"}, {"unknown derivative via ID_LIKE arch", "myarchdistro", "arch", "arch"}, {"elementary", "elementary", "ubuntu debian", "debian"}, {"opensuse tumbleweed", "opensuse-tumbleweed", "opensuse suse", "suse"}, {"opensuse leap", "opensuse-leap", "suse opensuse", "suse"}, {"debian", "debian", "", "debian"}, {"ubuntu", "ubuntu", "debian", "debian"}, {"unknown id returned unchanged", "void", "", "void"}, {"empty input", "", "", ""}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if got := GetDistroFamily(tt.id, tt.idLike); got != tt.want { t.Errorf("GetDistroFamily(%q, %q) = %q, want %q", tt.id, tt.idLike, got, tt.want) } }) } } // withOSRelease writes content to a temp file and points osReleasePaths at it // for the duration of the test. func withOSRelease(t *testing.T, content string) { t.Helper() path := filepath.Join(t.TempDir(), "os-release") if err := os.WriteFile(path, []byte(content), 0644); err != nil { t.Fatalf("failed to write temp os-release: %v", err) } orig := osReleasePaths osReleasePaths = []string{path} t.Cleanup(func() { osReleasePaths = orig }) } func TestIsImmutableDistro(t *testing.T) { tests := []struct { name string distro string osRelease string want bool }{ { name: "fedora silverblue via VARIANT_ID", distro: "fedora", osRelease: "ID=fedora\nVARIANT_ID=silverblue\n", want: true, }, { name: "fedora kinoite via VARIANT_ID", distro: "fedora", osRelease: "ID=fedora\nVARIANT_ID=kinoite\n", want: true, }, { name: "plain fedora workstation", distro: "fedora", osRelease: "ID=fedora\nVARIANT_ID=workstation\n", want: false, }, { name: "bluefin via distro name", distro: "bluefin", osRelease: "ID=bluefin\nID_LIKE=\"fedora\"\n", want: true, }, { name: "plain arch", distro: "arch", osRelease: "ID=arch\n", want: false, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { withOSRelease(t, tt.osRelease) p := &Platform{OSType: Linux, Distro: tt.distro} if got := p.IsImmutableDistro(); got != tt.want { t.Errorf("IsImmutableDistro() = %v, want %v", got, tt.want) } }) } t.Run("non-linux is never immutable", func(t *testing.T) { p := &Platform{OSType: Windows, Distro: "fedora"} if p.IsImmutableDistro() { t.Errorf("IsImmutableDistro() on Windows = true, want false") } }) } func TestReadOSReleaseFallback(t *testing.T) { dir := t.TempDir() fallback := filepath.Join(dir, "usr-lib-os-release") content := "ID=opensuse-tumbleweed\nID_LIKE=\"opensuse suse\"\nVARIANT_ID=tumbleweed\n" if err := os.WriteFile(fallback, []byte(content), 0644); err != nil { t.Fatalf("failed to write temp os-release: %v", err) } orig := osReleasePaths osReleasePaths = []string{filepath.Join(dir, "missing"), fallback} t.Cleanup(func() { osReleasePaths = orig }) id, idLike, variantID := readOSRelease() if id != "opensuse-tumbleweed" { t.Errorf("readOSRelease() id = %q, want %q", id, "opensuse-tumbleweed") } if idLike != "opensuse suse" { t.Errorf("readOSRelease() idLike = %q, want %q", idLike, "opensuse suse") } if variantID != "tumbleweed" { t.Errorf("readOSRelease() variantID = %q, want %q", variantID, "tumbleweed") } if family := GetDistroFamily(id, idLike); family != "suse" { t.Errorf("GetDistroFamily(%q, %q) = %q, want %q", id, idLike, family, "suse") } } func TestReadOSReleaseMissing(t *testing.T) { orig := osReleasePaths osReleasePaths = []string{filepath.Join(t.TempDir(), "missing")} t.Cleanup(func() { osReleasePaths = orig }) id, idLike, variantID := readOSRelease() if id != "" || idLike != "" || variantID != "" { t.Errorf("readOSRelease() = (%q, %q, %q), want all empty", id, idLike, variantID) } }