mirror of
https://github.com/Gathin23/cleanyourtv.git
synced 2026-11-07 10:46:07 -10:00
tools: keep tools/bench.py's results out of the checkout
tools/bench.py writes bench-results/result.json into the folder it was run from when no --out-dir is passed, and its first usage line is exactly that run. That file carries "host": args.host, the address the run was given, beside the TV's fingerprint read with getprop ro.build.fingerprint. .gitignore already keeps every other folder a run leaves the owner's own TV in - backup/, shots/, work/, traces/ - with the reason in its own comment; bench-results/ was the one the tools write into by default that it did not, so a git add -A after the documented run put the TV's address in a pull request. The new test reads the default folder out of bench.py and trace.py instead of copying it, so a tool that changes its default fails there rather than passing on a stale string.
This commit is contained in:
1 parent
f592b6d2db
commit
b1aa8ce233
2 files changed
+110
No files matched your search
@@ -12,6 +12,8 @@ shots/
|
||||
work/
|
||||
# Perfetto traces from tools/trace.py: large, and they hold the TV's process list
|
||||
traces/
|
||||
# Results from tools/bench.py: result.json carries the address the run was given and the TV's fingerprint.
|
||||
bench-results/
|
||||
.DS_Store
|
||||
|
||||
# Generated install bundles and JVM crash reports stay out of contributions.
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
"""The folders a run leaves the owner's own TV in are the ones .gitignore keeps out of a checkout.
|
||||
|
||||
`tools/bench.py` writes `bench-results/result.json` into the folder it was run from - its docstring's
|
||||
first usage line is `python tools/bench.py --keys 36 --series 3`, with no `--out-dir`, so the default is
|
||||
what a reader copies - and that file carries `"host": args.host`, the address the run was given, next to
|
||||
the TV's fingerprint, which the script reads with `getprop ro.build.fingerprint` into `environment`.
|
||||
CONTRIBUTING.md and AGENTS.md both forbid an IP address in the tree, and .gitignore already keeps every
|
||||
other place a run leaves the set: `backup/` (package dumps), `shots/` (session screenshots), `work/`
|
||||
(notes) and `traces/` (Perfetto traces, "they hold the TV's process list"), each with the reason in its
|
||||
own comment. `bench-results/` was the one folder the tools write into by default that it did not, so a
|
||||
`git add -A` after the documented bench run put the TV's address in a pull request.
|
||||
|
||||
The folder names are read out of the tools rather than copied in, and the matcher below has its own
|
||||
reader tests, so a tool that changes its default fails here instead of passing on a stale string.
|
||||
|
||||
Run from the repository root: python3 -m unittest discover -s tests -v
|
||||
"""
|
||||
from fnmatch import fnmatch
|
||||
from pathlib import Path
|
||||
import re
|
||||
import unittest
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
GITIGNORE = ROOT / ".gitignore"
|
||||
TOOLS = ROOT / "tools"
|
||||
PATTERNS = [line.strip() for line in GITIGNORE.read_text(encoding="utf-8").splitlines()
|
||||
if line.strip() and not line.strip().startswith("#")]
|
||||
|
||||
|
||||
def pattern_matches(pattern, path):
|
||||
"""Whether one .gitignore line matches a path inside the checkout."""
|
||||
body = pattern[:-1] if pattern.endswith("/") else pattern
|
||||
if "/" in body:
|
||||
# A pattern with a slash in it is anchored at the checkout root, and a folder takes what is under it.
|
||||
return path == body or path.startswith(body + "/")
|
||||
# Otherwise it names a file or folder anywhere: *.apk, .DS_Store, backup/.
|
||||
return any(fnmatch(part, body) for part in path.split("/"))
|
||||
|
||||
|
||||
def ignored(path):
|
||||
path = path.strip("/")
|
||||
return any(pattern_matches(pattern, path) for pattern in PATTERNS)
|
||||
|
||||
|
||||
def default_of(tool, flag):
|
||||
"""The default of one argument, out of the tool's own parser."""
|
||||
text = (TOOLS / tool).read_text(encoding="utf-8")
|
||||
found = re.search(r'"%s",\s*default="([^"]+)"' % re.escape(flag), text)
|
||||
return found[1] if found else ""
|
||||
|
||||
|
||||
class ToolResultsAreIgnored(unittest.TestCase):
|
||||
def test_bench_default_results_folder_is_ignored(self):
|
||||
folder = default_of("bench.py", "--out-dir")
|
||||
self.assertNotEqual(folder, "", "tools/bench.py has no --out-dir default; update this test")
|
||||
self.assertTrue(ignored(f"{folder}/result.json"),
|
||||
f"tools/bench.py writes {folder}/result.json by default and .gitignore "
|
||||
f"does not keep it out of a checkout: {PATTERNS}")
|
||||
self.assertTrue(ignored(folder), "the folder itself has to be ignored, not only the file name")
|
||||
|
||||
def test_trace_default_traces_folder_is_ignored(self):
|
||||
folder = default_of("trace.py", "--out")
|
||||
self.assertNotEqual(folder, "", "tools/trace.py has no --out default; update this test")
|
||||
self.assertTrue(ignored(f"{folder}/home-1.pftrace"),
|
||||
f"tools/trace.py writes {folder}/ by default and .gitignore does not keep it out")
|
||||
|
||||
def test_the_documented_bench_run_uses_the_default(self):
|
||||
"""The reason the default matters: the usage line a reader copies passes no --out-dir."""
|
||||
text = (TOOLS / "bench.py").read_text(encoding="utf-8")
|
||||
usage = [line.strip() for line in text.splitlines() if line.strip().startswith("TV_HOST=")]
|
||||
self.assertTrue(usage, "tools/bench.py's docstring names no usage line")
|
||||
self.assertTrue(any("bench.py" in line and "--out-dir" not in line for line in usage),
|
||||
f"no usage line relies on the default: {usage}")
|
||||
|
||||
def test_the_result_carries_the_address_and_the_fingerprint(self):
|
||||
"""Why the folder has to be ignored at all: what bench.py puts in result.json."""
|
||||
text = (TOOLS / "bench.py").read_text(encoding="utf-8")
|
||||
for claim in ('"host": args.host', "ro.build.fingerprint", 'os.path.join(args.out_dir, "result.json")'):
|
||||
self.assertIn(claim, text,
|
||||
f"{claim!r} is what makes {default_of('bench.py', '--out-dir')} an identifier leak")
|
||||
|
||||
def test_the_folders_the_checkout_already_kept(self):
|
||||
"""The convention this line joins; if one of these loses its entry, the list is being emptied."""
|
||||
for path in ("backup/getprop.txt", "shots/01-after.png", "work/bench-before/result.json",
|
||||
"traces/home-1.pftrace"):
|
||||
self.assertTrue(ignored(path), f"{path} has to stay out of the checkout: {PATTERNS}")
|
||||
|
||||
def test_what_must_stay_tracked(self):
|
||||
for path in ("docs/TROUBLESHOOTING.md", "tools/bench.py", "themes/aurora/config.json",
|
||||
"examples/tcl-43s5k/debloat.txt", "README.md"):
|
||||
self.assertFalse(ignored(path), f"{path} is part of the repository and must not be ignored")
|
||||
|
||||
def test_a_folder_entry_is_not_a_prefix_match(self):
|
||||
"""`bench-results/` keeps that folder, not every folder whose name starts the same way."""
|
||||
for path in ("bench-results-2026/result.json", "workbench/result.json", "traces-notes/home.pftrace"):
|
||||
self.assertFalse(ignored(path), f"{path} is not one of the ignored folders")
|
||||
|
||||
def test_the_patterns_the_file_already_has(self):
|
||||
"""The matcher's own readers: a path into a folder, a type, a name with no folder in it."""
|
||||
self.assertTrue(ignored("tools/venv/bin/python"))
|
||||
self.assertTrue(ignored("launcher/app/build/outputs/apk/release/app-release.apk"))
|
||||
self.assertTrue(ignored("tools/adbkey/adbkey"))
|
||||
self.assertFalse(ignored("adbkey/adbkey"))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in new issue
Block a user