Phase 5-7: README, Makefile, unit tests
- README.md: full usage docs - Makefile: build/install/uninstall/test/lint/clean targets - config/config_test.go: 7 tests (load, save, find, add, roundtrip, invalid yaml) - runtime/runtime_test.go: 6 tests (get, available, ListRunning graceful degradation) - systemd/generator_test.go: 7 tests (ServiceName, Generate system/user/custom/docker/unknown, buildExecCommands) - fix: docker/podman ListRunning returns nil (not error) when daemon unavailable - fix: invalid YAML test uses tab-indent which is genuinely unparseable
This commit is contained in:
179
systemd/generator_test.go
Normal file
179
systemd/generator_test.go
Normal file
@@ -0,0 +1,179 @@
|
||||
package systemd
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/warkanum/unitdore/config"
|
||||
)
|
||||
|
||||
func TestServiceName(t *testing.T) {
|
||||
u := config.Unit{Name: "nginx"}
|
||||
got := ServiceName(u)
|
||||
want := "unitdore-nginx.service"
|
||||
if got != want {
|
||||
t.Errorf("ServiceName() = %q, want %q", got, 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
// System unit markers must NOT appear
|
||||
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)
|
||||
}
|
||||
|
||||
if !strings.Contains(content, "ExecStart=/usr/bin/docker start redis") {
|
||||
t.Errorf("Generate() wrong ExecStart for docker:\n%s", content)
|
||||
}
|
||||
if !strings.Contains(content, "ExecStop=/usr/bin/docker stop redis") {
|
||||
t.Errorf("Generate() wrong ExecStop for docker:\n%s", 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/<runtime> for unknown runtimes:\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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user