Skip to content

Commit fce1a4b

Browse files
authored
test(launchagent): model BSD stat in Linux smoke fixtures (#5181)
Model BSD byte-count stat inside the existing non-macOS smoke fixture. Preserve production retention behavior and all durable assertions. Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
1 parent 5bdae1b commit fce1a4b

1 file changed

Lines changed: 30 additions & 7 deletions

File tree

‎examples/macos-dashboard-launchagent-status-smoke.py‎

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import plistlib
88
import shutil
99
import subprocess
10+
import sys
1011
import tempfile
1112
from pathlib import Path
1213

@@ -54,7 +55,17 @@ def log_rotation_prelude(plist: Path) -> str:
5455
return prelude
5556

5657

57-
def check_log_rotation(home: Path, plist: Path, basename: str, limit: int) -> None:
58+
def run_rotation_prelude(fake_bin: Path, prelude: str) -> subprocess.CompletedProcess[str]:
59+
return subprocess.run(
60+
["zsh", "-c", prelude],
61+
env={**os.environ, "PATH": f"{fake_bin}:{os.environ.get('PATH', '')}"},
62+
check=True,
63+
capture_output=True,
64+
text=True,
65+
)
66+
67+
68+
def check_log_rotation(fake_bin: Path, home: Path, plist: Path, basename: str, limit: int) -> None:
5869
logs_dir = home / "Library" / "Logs" / "loopx"
5970
prelude = log_rotation_prelude(plist)
6071
for stream in ("out", "err"):
@@ -69,7 +80,7 @@ def check_log_rotation(home: Path, plist: Path, basename: str, limit: int) -> No
6980
live.write_bytes(b"O" * (limit + 1))
7081
descriptor = os.open(live, os.O_WRONLY | os.O_APPEND)
7182
try:
72-
subprocess.run(["zsh", "-c", prelude], check=True)
83+
run_rotation_prelude(fake_bin, prelude)
7384
os.write(descriptor, b"after-rotation\n")
7485
finally:
7586
os.close(descriptor)
@@ -85,12 +96,12 @@ def check_log_rotation(home: Path, plist: Path, basename: str, limit: int) -> No
8596
# reset on every service start.
8697
small = logs_dir / f"{basename}.err.log"
8798
small.write_bytes(b"kept")
88-
subprocess.run(["zsh", "-c", prelude], check=True)
99+
run_rotation_prelude(fake_bin, prelude)
89100
assert not small.with_suffix(".log.1").exists()
90101
assert small.read_bytes() == b"kept"
91102

92103

93-
def check_retention_keeps_the_log_when_the_backup_fails(home: Path, plist: Path, basename: str, limit: int) -> None:
104+
def check_retention_keeps_the_log_when_the_backup_fails(fake_bin: Path, home: Path, plist: Path, basename: str, limit: int) -> None:
94105
"""A failed backup must leave the live log alone.
95106
96107
Truncating on a failed copy would destroy the only record of the failure
@@ -105,7 +116,7 @@ def check_retention_keeps_the_log_when_the_backup_fails(home: Path, plist: Path,
105116
backup = live.with_suffix(".log.1")
106117

107118
def run_prelude() -> subprocess.CompletedProcess[str]:
108-
result = subprocess.run(["zsh", "-c", prelude], capture_output=True, text=True)
119+
result = run_rotation_prelude(fake_bin, prelude)
109120
assert result.returncode == 0, (result.stdout, result.stderr)
110121
assert live.read_bytes() == original, "a failed backup must not truncate the live log"
111122
assert not backup.is_file(), "a failed backup must not leave a partial generation"
@@ -171,6 +182,18 @@ def main() -> int:
171182
fake_bin.mkdir()
172183
home.mkdir()
173184

185+
# This fixture models macOS commands on Linux CI. Keep the real BSD
186+
# stat on macOS; emulate only its byte-count operation elsewhere.
187+
if sys.platform != "darwin":
188+
write_executable(
189+
fake_bin / "stat",
190+
f"#!{sys.executable}\n"
191+
"import os, sys\n"
192+
"if len(sys.argv) != 3 or sys.argv[1] != '-f%z':\n"
193+
" raise SystemExit(2)\n"
194+
"print(os.stat(sys.argv[2]).st_size)\n",
195+
)
196+
174197
write_executable(
175198
fake_bin / "uname",
176199
"#!/usr/bin/env bash\nprintf 'Darwin\\n'\n",
@@ -256,8 +279,8 @@ def main() -> int:
256279
run_script(fake_bin, home, ["install"], schema_version=2,
257280
extra_env={"LOOPX_LOG_MAX_BYTES": str(rotation_limit)})
258281
for plist, basename in ((status_plist, "status"), (chat_plist, "chat")):
259-
check_log_rotation(home, plist, basename, rotation_limit)
260-
check_retention_keeps_the_log_when_the_backup_fails(home, plist, basename, rotation_limit)
282+
check_log_rotation(fake_bin, home, plist, basename, rotation_limit)
283+
check_retention_keeps_the_log_when_the_backup_fails(fake_bin, home, plist, basename, rotation_limit)
261284
check_installed_retention_readback(fake_bin, home, plist, basename, rotation_limit)
262285
check_invalid_retention_is_rejected(fake_bin, home, status_plist, rotation_limit)
263286
assert f"- retention: rotated to .1 at each agent start once a log exceeds {rotation_limit} bytes" in run_script(

0 commit comments

Comments
 (0)