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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
"""Tests for normalize-notify-sounds.sh temp handling and atomic write.
The script re-encodes each .ogg in place. SOUND_DIR is often the stow-symlinked
~/.local copy, so the write must land on the real repo file and preserve the
symlink. Two bugs the fix addresses:
- A failed or empty re-encode used to truncate the target with `cat "$tmp" >
"$f"`, corrupting a repo-tracked sound to zero bytes.
- The mktemp had no EXIT trap, so an interrupted encode leaked a temp file.
ffmpeg/ffprobe are faked via stubs on PATH (this directory) so the encode
result is controllable without real audio work.
Run from repo root:
python3 -m unittest tests.normalize-notify.test_normalize_notify_sounds
"""
import glob
import os
import shutil
import subprocess
import tempfile
import unittest
HERE = os.path.dirname(os.path.abspath(__file__))
REPO_ROOT = os.path.abspath(os.path.join(HERE, "..", ".."))
SCRIPT = os.path.join(REPO_ROOT, "scripts", "normalize-notify-sounds.sh")
class NormalizeNotifySounds(unittest.TestCase):
def setUp(self):
self.tmp = tempfile.mkdtemp(prefix="norm-notify-test-")
self.addCleanup(shutil.rmtree, self.tmp, ignore_errors=True)
self.bindir = os.path.join(self.tmp, "bin")
os.mkdir(self.bindir)
for tool in ("ffmpeg", "ffprobe"):
fake = os.path.join(HERE, "fake-" + tool)
if not os.path.exists(fake):
fake = os.path.join(HERE, "fake-ffmpeg") # ffprobe reuses stub
dst = os.path.join(self.bindir, tool)
shutil.copy(fake, dst)
os.chmod(dst, 0o755)
# sound dir with one .ogg, plus a "repo" the sound symlinks into
self.repo = os.path.join(self.tmp, "repo")
os.mkdir(self.repo)
self.sounddir = os.path.join(self.tmp, "sounds")
os.mkdir(self.sounddir)
def run_script(self, env_extra=None):
env = dict(os.environ)
env["PATH"] = self.bindir + os.pathsep + env["PATH"]
if env_extra:
env.update(env_extra)
return subprocess.run(
["bash", SCRIPT, self.sounddir],
capture_output=True, text=True, timeout=20, env=env,
)
def make_sound(self, name="chime.ogg", body="ORIGINAL\n", symlink=False):
if symlink:
real = os.path.join(self.repo, name)
with open(real, "w") as f:
f.write(body)
link = os.path.join(self.sounddir, name)
os.symlink(real, link)
return link, real
path = os.path.join(self.sounddir, name)
with open(path, "w") as f:
f.write(body)
return path, path
def leftover_temps(self, directory):
return glob.glob(os.path.join(directory, "*.ogg.*")) + \
[p for p in glob.glob(os.path.join(directory, "tmp*")) if p.endswith(".ogg")]
# --- Normal ----------------------------------------------------------
def test_reencodes_regular_file(self):
path, _ = self.make_sound()
r = self.run_script()
self.assertEqual(r.returncode, 0, r.stderr)
with open(path) as f:
self.assertEqual(f.read(), "ENCODED\n")
def test_preserves_symlink_and_updates_target(self):
link, real = self.make_sound(symlink=True)
r = self.run_script()
self.assertEqual(r.returncode, 0, r.stderr)
self.assertTrue(os.path.islink(link), "the stow symlink must survive")
with open(real) as f:
self.assertEqual(f.read(), "ENCODED\n",
"the re-encode must land on the real repo file")
# --- Error / corruption guard ---------------------------------------
def test_empty_reencode_does_not_corrupt_target(self):
path, _ = self.make_sound(body="ORIGINAL\n")
self.run_script(env_extra={"FAKE_FFMPEG_EMPTY": "1"})
with open(path) as f:
self.assertEqual(f.read(), "ORIGINAL\n",
"an empty re-encode must not truncate the tracked file")
def test_failed_encode_leaves_no_temp_in_target_dir(self):
self.make_sound(symlink=True)
self.run_script(env_extra={"FAKE_FFMPEG_FAIL": "1"})
self.assertEqual(self.leftover_temps(self.repo), [],
"a failed encode must not leak a temp file")
def test_failed_encode_does_not_corrupt_target(self):
_, real = self.make_sound(symlink=True, body="ORIGINAL\n")
self.run_script(env_extra={"FAKE_FFMPEG_FAIL": "1"})
with open(real) as f:
self.assertEqual(f.read(), "ORIGINAL\n")
if __name__ == "__main__":
unittest.main()
|