| 1 | package main |
| 2 | |
| 3 | // `lchat install` (versions.go): staged builds land on sibling-service binary |
| 4 | // paths with a .prev- backup, and the guardrails hold (unknown sibling, |
| 5 | // unstaged version). |
| 6 | |
| 7 | import ( |
| 8 | "os" |
| 9 | "path/filepath" |
| 10 | "strings" |
| 11 | "testing" |
| 12 | ) |
| 13 | |
| 14 | func TestInstallSibling(t *testing.T) { |
| 15 | old := optDir |
| 16 | optDir = t.TempDir() |
| 17 | defer func() { optDir = old }() |
| 18 | |
| 19 | // Stage a fake build the way stage would lay it out. |
| 20 | ver := "abc1234" |
| 21 | if err := os.MkdirAll(filepath.Dir(versionBinPath(ver)), 0o755); err != nil { |
| 22 | t.Fatal(err) |
| 23 | } |
| 24 | if err := os.WriteFile(versionBinPath(ver), []byte("new-build"), 0o755); err != nil { |
| 25 | t.Fatal(err) |
| 26 | } |
| 27 | // An existing home binary to be replaced. |
| 28 | target := filepath.Join(optDir, "home") |
| 29 | if err := os.WriteFile(target, []byte("old-build"), 0o755); err != nil { |
| 30 | t.Fatal(err) |
| 31 | } |
| 32 | |
| 33 | msg, err := installSibling("home", ver) |
| 34 | if err != nil { |
| 35 | t.Fatal(err) |
| 36 | } |
| 37 | if got, _ := os.ReadFile(target); string(got) != "new-build" { |
| 38 | t.Fatalf("target = %q, want the staged build", got) |
| 39 | } |
| 40 | // The previous binary survives as a dated .prev- sibling. |
| 41 | prevs, _ := filepath.Glob(target + ".prev-*") |
| 42 | if len(prevs) != 1 { |
| 43 | t.Fatalf("prev backups = %v, want exactly one", prevs) |
| 44 | } |
| 45 | if got, _ := os.ReadFile(prevs[0]); string(got) != "old-build" { |
| 46 | t.Fatalf("backup = %q, want the old build", got) |
| 47 | } |
| 48 | if !strings.Contains(msg, "lchat-svc restart lchat-home") { |
| 49 | t.Fatalf("summary should name the restart: %q", msg) |
| 50 | } |
| 51 | |
| 52 | // First install (no existing binary): no backup, no error. |
| 53 | if _, err := installSibling("push", ver); err != nil { |
| 54 | t.Fatal(err) |
| 55 | } |
| 56 | if prevs, _ := filepath.Glob(filepath.Join(optDir, "push.prev-*")); len(prevs) != 0 { |
| 57 | t.Fatalf("fresh install made a backup: %v", prevs) |
| 58 | } |
| 59 | |
| 60 | // Guardrails. |
| 61 | if _, err := installSibling("router", ver); err == nil { |
| 62 | t.Fatal("unknown sibling must refuse") |
| 63 | } |
| 64 | if _, err := installSibling("home", "def5678"); err == nil { |
| 65 | t.Fatal("unstaged version must refuse") |
| 66 | } |
| 67 | } |
| 68 | |