1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
import json
import os
import subprocess
import tempfile
import unittest
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
class RecipeTests(unittest.TestCase):
def invoke(self, role, *recipes):
with tempfile.TemporaryDirectory() as directory:
path = Path(directory)
commands = {
"chezmoi": 'if [ "$1" = data ]; then printf \'%s\\n\' "$ROLE_DATA"; else echo "chezmoi $*"; fi',
"sudo": 'echo "UNEXPECTED sudo"; exit 99',
"flatpak": 'echo "UNEXPECTED flatpak"; exit 99',
"pacman": 'echo "UNEXPECTED pacman"; exit 99',
}
for name, body in commands.items():
executable = path / name
executable.write_text("#!/bin/sh\n" + body + "\n")
executable.chmod(0o755)
return subprocess.run(
["just", *recipes],
cwd=ROOT,
env={
**os.environ,
"PATH": f"{path}:{os.environ['PATH']}",
"ROLE_DATA": json.dumps({"machineRole": role}),
},
capture_output=True,
text=True,
check=False,
)
def test_invalid_role_stops_package_commands(self):
for recipe in ["pkg-apply", "pkg-fix", "flatpak-update"]:
with self.subTest(recipe=recipe):
result = self.invoke("invalid", recipe)
self.assertNotEqual(result.returncode, 0)
self.assertNotIn("UNEXPECTED", result.stdout)
def test_non_host_maintenance_only_uses_chezmoi(self):
for role in ["vm", "canonical"]:
for recipe in ["diff", "merge", "re-add"]:
with self.subTest(role=role, recipe=recipe):
result = self.invoke(role, recipe)
self.assertEqual(result.returncode, 0, result.stderr)
self.assertIn("chezmoi", result.stdout)
self.assertNotIn("UNEXPECTED", result.stdout)
def test_non_host_etc_paths_fail_before_home_changes(self):
for recipe in ["diff", "merge", "re-add"]:
result = self.invoke("canonical", recipe, ".config/zsh", "etc/hosts")
self.assertNotEqual(result.returncode, 0)
self.assertNotIn("chezmoi", result.stdout)
def test_vm_migration_initializes_role_before_switch(self):
result = subprocess.check_output(
["just", "--justfile", "nix/justfile", "--dry-run", "migrate-chezmoi"],
cwd=ROOT,
stderr=subprocess.STDOUT,
text=True,
)
self.assertLess(result.index("chezmoi init"), result.index("switch.sh"))
def test_host_home_paths_do_not_select_etc(self):
for recipe in ["diff", "merge", "re-add"]:
result = self.invoke("host", recipe, ".config/zsh")
self.assertEqual(result.returncode, 0, result.stderr)
self.assertEqual(len(result.stdout.splitlines()), 1)
self.assertIn(".config/zsh", result.stdout)
def test_host_mixed_paths_are_split_by_domain(self):
for domain, expected in [("home", ".config/zsh"), ("etc", "etc/hosts")]:
result = subprocess.check_output(
[
"bash",
"-c",
(
"source scripts/maintenance-lib.sh; "
"_machine_role() { echo host; }; "
'_maintenance_select auto "$1" .config/zsh etc/hosts; '
'printf "%s\\n" "$maintenance_run" "${args[@]}"'
),
"test",
domain,
],
cwd=ROOT,
text=True,
)
self.assertEqual(result.splitlines(), ["true", expected])
|