mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-10-28 05:57:47 -04:00
- detect ostree/bootc/transactional hosts - official dms doctor & dms command support - updated installation instructions on dux labs docs Port 2.0
219 lines
8.3 KiB
Go
219 lines
8.3 KiB
Go
package distros
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/duxlabs-dev/dux-shell/core/internal/deps"
|
|
"github.com/spf13/afero"
|
|
)
|
|
|
|
func writeOSRelease(t *testing.T, fs afero.Fs, body string) {
|
|
t.Helper()
|
|
if err := afero.WriteFile(fs, "/etc/os-release", []byte(body), 0o644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func TestDetectImmutable(t *testing.T) {
|
|
cases := []struct {
|
|
name string
|
|
files []string
|
|
osRelease map[string]string
|
|
want bool
|
|
}{
|
|
{"ostree marker beats plain fedora id", []string{"/run/ostree-booted"}, map[string]string{"ID": "fedora"}, true},
|
|
{"silverblue variant without marker", nil, map[string]string{"ID": "fedora", "VARIANT_ID": "silverblue"}, true},
|
|
{"sway atomic variant", nil, map[string]string{"ID": "fedora", "VARIANT_ID": "sway-atomic"}, true},
|
|
{"workstation fedora", nil, map[string]string{"ID": "fedora", "VARIANT_ID": "workstation"}, false},
|
|
{"bazzite id", nil, map[string]string{"ID": "bazzite", "ID_LIKE": "fedora"}, true},
|
|
{"microos", []string{"/usr/sbin/transactional-update"}, map[string]string{"ID": "opensuse-microos"}, true},
|
|
{"aeon by id_like", nil, map[string]string{"ID": "opensuse-aeon-rc", "ID_LIKE": "suse opensuse microos"}, true},
|
|
{"tumbleweed", nil, map[string]string{"ID": "opensuse-tumbleweed", "ID_LIKE": "suse opensuse"}, false},
|
|
{"vanilla by abroot", []string{"/usr/bin/abroot"}, map[string]string{"ID": "ubuntu", "ID_LIKE": "debian"}, true},
|
|
{"steamos", nil, map[string]string{"ID": "steamos", "ID_LIKE": "arch"}, true},
|
|
{"arch", nil, map[string]string{"ID": "arch"}, false},
|
|
}
|
|
for _, c := range cases {
|
|
t.Run(c.name, func(t *testing.T) {
|
|
fs := afero.NewMemMapFs()
|
|
for _, f := range c.files {
|
|
if err := afero.WriteFile(fs, f, nil, 0o644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
got, reason := detectImmutable(fs, c.osRelease)
|
|
if got != c.want {
|
|
t.Fatalf("detectImmutable = %v (%q), want %v", got, reason, c.want)
|
|
}
|
|
if got && reason == "" {
|
|
t.Fatal("immutable without a reason")
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGetOSInfoImmutable(t *testing.T) {
|
|
t.Run("unregistered image id is accepted when immutable", func(t *testing.T) {
|
|
fs := afero.NewMemMapFs()
|
|
writeOSRelease(t, fs, "ID=\"zirconium\"\nID_LIKE=\"zirconium\"\nPRETTY_NAME=\"Zirconium\"\nVERSION_ID=44\n")
|
|
if err := afero.WriteFile(fs, "/run/ostree-booted", nil, 0o644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
info, err := getOSInfo(fs, "amd64")
|
|
if err != nil {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
if !info.Immutable || info.Distribution.ID != "zirconium" || info.VersionID != "44" {
|
|
t.Fatalf("got %+v", info)
|
|
}
|
|
})
|
|
|
|
t.Run("fedora derivative resolves through id_like", func(t *testing.T) {
|
|
fs := afero.NewMemMapFs()
|
|
writeOSRelease(t, fs, "ID=bazzite\nID_LIKE=fedora\nPRETTY_NAME=Bazzite\nVERSION_ID=44\n")
|
|
info, err := getOSInfo(fs, "amd64")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !info.Immutable || info.ID != "bazzite" || info.Distribution.ID != "fedora" {
|
|
t.Fatalf("got %+v", info)
|
|
}
|
|
})
|
|
|
|
t.Run("unregistered mutable id still errors", func(t *testing.T) {
|
|
fs := afero.NewMemMapFs()
|
|
writeOSRelease(t, fs, "ID=slackware\nPRETTY_NAME=Slackware\n")
|
|
if _, err := getOSInfo(fs, "amd64"); err == nil {
|
|
t.Fatal("expected unsupported distribution error")
|
|
}
|
|
})
|
|
|
|
t.Run("silverblue resolves to fedora but is flagged", func(t *testing.T) {
|
|
fs := afero.NewMemMapFs()
|
|
writeOSRelease(t, fs, "ID=fedora\nVARIANT_ID=silverblue\nPRETTY_NAME=\"Fedora Linux 44 (Silverblue)\"\nVERSION_ID=44\n")
|
|
info, err := getOSInfo(fs, "amd64")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !info.Immutable || info.Distribution.ID != "fedora" || info.VariantID != "silverblue" {
|
|
t.Fatalf("got %+v", info)
|
|
}
|
|
})
|
|
|
|
t.Run("bluefin is no longer a mutable fedora", func(t *testing.T) {
|
|
if IsDistroSupported("bluefin") {
|
|
t.Fatal("bluefin must not be registered as an installable distribution")
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestPendingDependencies(t *testing.T) {
|
|
all := []deps.Dependency{
|
|
{Name: "dms (Dux Shell)", Status: deps.StatusMissing},
|
|
{Name: "niri", Status: deps.StatusInstalled},
|
|
{Name: "quickshell", Status: deps.StatusInstalled},
|
|
{Name: "danksearch", Status: deps.StatusMissing},
|
|
}
|
|
got := PendingDependencies(all, map[string]bool{"quickshell": true}, map[string]bool{"danksearch": true})
|
|
if len(got) != 2 || got[0].Name != "dms (Dux Shell)" || got[1].Name != "quickshell" {
|
|
t.Fatalf("got %+v", got)
|
|
}
|
|
}
|
|
|
|
func TestApplyImmutableDetection(t *testing.T) {
|
|
dir := t.TempDir()
|
|
if err := os.WriteFile(filepath.Join(dir, "dms"), []byte("#!/bin/sh\n"), 0o755); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
t.Setenv("PATH", dir)
|
|
got := ApplyImmutableDetection([]deps.Dependency{{Name: "dms (Dux Shell)", Status: deps.StatusMissing}, {Name: "niri", Status: deps.StatusMissing}})
|
|
if got[0].Status != deps.StatusInstalled || got[1].Status != deps.StatusMissing {
|
|
t.Fatalf("got %+v", got)
|
|
}
|
|
}
|
|
|
|
func TestFedoraLayerCommands(t *testing.T) {
|
|
f := NewFedoraDistribution(Registry["fedora"], nil)
|
|
dependencies := []deps.Dependency{
|
|
{Name: "dms (Dux Shell)", Status: deps.StatusMissing},
|
|
{Name: "niri", Status: deps.StatusMissing, Variant: deps.VariantGit},
|
|
{Name: "ghostty", Status: deps.StatusInstalled},
|
|
{Name: "matugen", Status: deps.StatusMissing},
|
|
{Name: "danksearch", Status: deps.StatusMissing},
|
|
{Name: "xwayland-satellite", Status: deps.StatusMissing},
|
|
}
|
|
got := strings.Join(f.LayerCommands(dependencies, deps.WindowManagerNiri, nil, map[string]bool{"danksearch": true}), "\n")
|
|
|
|
for _, want := range []string{
|
|
"_copr:copr.fedorainfracloud.org:avengemedia:dms.repo https://copr.fedorainfracloud.org/coprs/avengemedia/dms/repo/fedora-$(rpm -E %fedora)/avengemedia-dms-fedora-$(rpm -E %fedora).repo",
|
|
"_copr:copr.fedorainfracloud.org:yalter:niri-git.repo",
|
|
"echo priority=1 | sudo tee -a",
|
|
"sudo rpm-ostree install xwayland-satellite dms niri matugen",
|
|
"systemctl reboot",
|
|
} {
|
|
if !strings.Contains(got, want) {
|
|
t.Fatalf("missing %q in:\n%s", want, got)
|
|
}
|
|
}
|
|
for _, unwanted := range []string{"ghostty", "danksearch", "rpm-ostree upgrade", "dnf "} {
|
|
if strings.Contains(got, unwanted) {
|
|
t.Fatalf("unexpected %q in:\n%s", unwanted, got)
|
|
}
|
|
}
|
|
if strings.Count(got, "avengemedia:danklinux.repo https") != 1 {
|
|
t.Fatalf("danklinux repo must be fetched exactly once:\n%s", got)
|
|
}
|
|
}
|
|
|
|
func TestImmutableGuidance(t *testing.T) {
|
|
steam := &OSInfo{PrettyName: "SteamOS", Distribution: DistroInfo{ID: "steamos"}, ImmutableReason: "os-release ID=steamos"}
|
|
got := ImmutableGuidance(steam)
|
|
if !strings.Contains(got, "SteamOS is an image-based system") || !strings.Contains(got, "Nothing was changed") {
|
|
t.Fatalf("got %q", got)
|
|
}
|
|
}
|
|
|
|
func TestFedoraLayerCommandsSwapVariants(t *testing.T) {
|
|
f := NewFedoraDistribution(Registry["fedora"], nil)
|
|
installed := map[string]bool{"dms-greeter": true, "dms": true}
|
|
f.rpmInstalled = func(pkg string) bool { return installed[pkg] }
|
|
orig := installedFromCOPR
|
|
installedFromCOPR = func(pkg, repo string) bool { return pkg == "dms" && repo == "avengemedia/dms-git" }
|
|
t.Cleanup(func() { installedFromCOPR = orig })
|
|
|
|
dependencies := []deps.Dependency{
|
|
{Name: "dms (Dux Shell)", Status: deps.StatusInstalled, Variant: deps.VariantStable, CanToggle: true},
|
|
{Name: "dms-greeter", Status: deps.StatusInstalled, Variant: deps.VariantGit, CanToggle: true},
|
|
{Name: "danksearch", Status: deps.StatusInstalled},
|
|
}
|
|
reinstall := map[string]bool{"dms (Dux Shell)": true, "dms-greeter": true, "danksearch": true}
|
|
got := strings.Join(f.LayerCommands(dependencies, deps.WindowManagerNiri, reinstall, nil), "\n")
|
|
|
|
for _, want := range []string{
|
|
"sudo rm -f /etc/yum.repos.d/_copr:copr.fedorainfracloud.org:avengemedia:dms-git.repo",
|
|
"sudo rpm-ostree install dms dms-greeter-git --uninstall dms dms-greeter",
|
|
} {
|
|
if !strings.Contains(got, want) {
|
|
t.Fatalf("missing %q in:\n%s", want, got)
|
|
}
|
|
}
|
|
if strings.Contains(got, "danksearch") {
|
|
t.Fatalf("reinstall mark without a variant change must not be layered:\n%s", got)
|
|
}
|
|
}
|
|
|
|
func TestApplyImmutableDetectionReadsVariant(t *testing.T) {
|
|
dir := t.TempDir()
|
|
if err := os.WriteFile(filepath.Join(dir, "dms"), []byte("#!/bin/sh\necho 'dms (git) v2.0.0-5333'\n"), 0o755); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
t.Setenv("PATH", dir)
|
|
got := ApplyImmutableDetection([]deps.Dependency{{Name: "dms (Dux Shell)", Status: deps.StatusMissing}})
|
|
if got[0].Variant != deps.VariantGit || got[0].Version != "v2.0.0-5333" {
|
|
t.Fatalf("got %+v", got[0])
|
|
}
|
|
}
|