package systemd import ( "strings" "testing" "github.com/warkanum/unitdore/config" ) func TestServiceName(t *testing.T) { u := config.Unit{Name: "nginx"} tests := []struct { prefix, suffix, want string }{ {"", "", "unitdore-nginx.service"}, {"prod-", "", "unitdore-prod-nginx.service"}, {"", "-web", "unitdore-nginx-web.service"}, {"prod-", "-web", "unitdore-prod-nginx-web.service"}, } for _, tt := range tests { got := ServiceName(u, tt.prefix, tt.suffix) if got != tt.want { t.Errorf("ServiceName(%q, %q) = %q, want %q", tt.prefix, tt.suffix, got, tt.want) } } } func TestGenerate_SystemUnit(t *testing.T) { u := config.Unit{ Name: "nginx", Runtime: "podman", Order: 1, Enabled: true, } content, err := Generate(u, "", "") if err != nil { t.Fatalf("Generate() error: %v", err) } checks := []string{ "[Unit]", "[Service]", "[Install]", "unitdore-nginx.service", "Description=Unitdore: nginx (podman)", "After=network.target", "WantedBy=multi-user.target", "ExecStart=/usr/bin/podman start -a nginx", "ExecStop=/usr/bin/podman stop nginx", "Restart=on-failure", "Generated by unitdore", } for _, check := range checks { if !strings.Contains(content, check) { t.Errorf("Generate() missing %q in output:\n%s", check, content) } } if strings.Contains(content, "User=") { t.Errorf("Generate() system unit should not contain User= directive:\n%s", content) } if strings.Contains(content, "Requires=") { t.Errorf("Generate() podman system unit should not contain Requires= (podman is daemonless):\n%s", content) } } func TestGenerate_UserUnit(t *testing.T) { u := config.Unit{ Name: "myapp", Runtime: "docker", User: "hein", Order: 2, Enabled: true, } content, err := Generate(u, "", "") if err != nil { t.Fatalf("Generate() error: %v", err) } checks := []string{ "After=default.target", "WantedBy=default.target", "ExecStart=/usr/bin/docker start myapp", "ExecStop=/usr/bin/docker stop myapp", } for _, check := range checks { if !strings.Contains(content, check) { t.Errorf("Generate() user unit missing %q in output:\n%s", check, content) } } if strings.Contains(content, "WantedBy=multi-user.target") { t.Error("Generate() user unit should not contain multi-user.target") } } func TestGenerate_CustomCommand(t *testing.T) { u := config.Unit{ Name: "custom", Runtime: "podman", Command: "/usr/local/bin/mystart.sh", Enabled: true, } content, err := Generate(u, "", "") if err != nil { t.Fatalf("Generate() error: %v", err) } if !strings.Contains(content, "ExecStart=/usr/local/bin/mystart.sh") { t.Errorf("Generate() should use custom command, got:\n%s", content) } } func TestGenerate_DockerRuntime(t *testing.T) { u := config.Unit{ Name: "redis", Runtime: "docker", Enabled: true, } content, err := Generate(u, "", "") if err != nil { t.Fatalf("Generate() error: %v", err) } checks := []string{ "ExecStart=/usr/bin/docker start redis", "ExecStop=/usr/bin/docker stop redis", "After=network.target docker.service", "Requires=docker.service", } for _, check := range checks { if !strings.Contains(content, check) { t.Errorf("Generate() docker runtime missing %q in output:\n%s", check, content) } } } func TestGenerate_UnknownRuntime(t *testing.T) { u := config.Unit{ Name: "weird", Runtime: "containerd", Enabled: true, } content, err := Generate(u, "", "") if err != nil { t.Fatalf("Generate() should not error on unknown runtime: %v", err) } if !strings.Contains(content, "/usr/bin/containerd start weird") { t.Errorf("Generate() should fall back to /usr/bin/ for unknown runtimes:\n%s", content) } } func TestGenerate_WithPrefixSuffix(t *testing.T) { u := config.Unit{ Name: "nginx", Runtime: "podman", Enabled: true, } content, err := Generate(u, "prod-", "-web") if err != nil { t.Fatalf("Generate() error: %v", err) } if !strings.Contains(content, "unitdore-prod-nginx-web.service") { t.Errorf("Generate() prefix+suffix not reflected in service name:\n%s", content) } } func TestBuildExecCommands(t *testing.T) { tests := []struct { name string unit config.Unit wantStart string wantStop string }{ { name: "podman", unit: config.Unit{Name: "app", Runtime: "podman"}, wantStart: "/usr/bin/podman start -a app", wantStop: "/usr/bin/podman stop app", }, { name: "docker", unit: config.Unit{Name: "app", Runtime: "docker"}, wantStart: "/usr/bin/docker start app", wantStop: "/usr/bin/docker stop app", }, { name: "custom command", unit: config.Unit{Name: "app", Runtime: "podman", Command: "/bin/custom"}, wantStart: "/bin/custom", wantStop: "", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { start, stop := buildExecCommands(tt.unit) if start != tt.wantStart { t.Errorf("start = %q, want %q", start, tt.wantStart) } if stop != tt.wantStop { t.Errorf("stop = %q, want %q", stop, tt.wantStop) } }) } }