tools: bench.py leaves the TV's address and port to tools/tv.py

--port is passed on as text, so TV_PORT=abc or an empty TV_PORT gets tv.py's own
'not a port number' instead of a ValueError traceback from argparse, and TV._connect
keeps the HOST/PORT tv.py made of the environment bench.py set for it - the split of
a host:port and the 1..65535 check live there, and already reached the arguments.
This commit is contained in:
xbsheng committed 2026-10-26 15:47:57 +08:00
1 parent 83304645ec
commit 7184cc4e7b
2 files changed
+32 -7

No files matched your search

+20 -3
View File
@@ -5,12 +5,13 @@ ADB handshake, several times per key, plus the whole main log pulled back for ev
100 MB on a TCL C755, 41 s a read). Through a
relay one full run took over 45 minutes. Now the TV class connects once with tools/tv.py's client
and reuses it, reopening it once if it drops; only the log's newest lines are read, filtered on the
TV, and not at all once the first keys show the TV doesn't log them; and the key loop looks up Home once. --host also has to reach the client: the old subprocesses only read TV_HOST.
TV, and not at all once the first keys show the TV doesn't log them; and the key loop looks up Home once. --host also has to reach the client: the old subprocesses only read TV_HOST. It reaches it as TV_HOST/TV_PORT, and the target the run keeps is the one tools/tv.py made of those two (it splits `host:port` and checks the range), not the arguments again.
The TV and tools/tv.py are faked, so these run without either.
Run from the repository root: python3 -m unittest discover -s tests -v
"""
import os
import sys
import types
import unittest
@@ -38,7 +39,11 @@ class FakeDevice:
def fake_client(devices):
"""A stand-in for tools/tv.py: connect() hands out the given devices in turn."""
"""A stand-in for tools/tv.py: connect() hands out the given devices in turn.
HOST and PORT stand for the target the real client resolves from TV_HOST/TV_PORT when bench.py
imports it; this one has no parser, so the environment bench.py sets for it is what a test reads.
"""
module = types.ModuleType("tv")
module.HOST, module.PORT = None, None
module.connects = 0
@@ -67,7 +72,19 @@ class OneConnectionTest(unittest.TestCase):
def test_host_and_port_from_the_command_line_reach_the_client(self):
tv, client = self.tv_with(FakeDevice())
tv.shell("true")
self.assertEqual((client.HOST, client.PORT), ("192.0.2.7", 15555))
# bench.py hands the command line to the client through TV_HOST/TV_PORT, the two the real
# tools/tv.py reads when it is imported. The fake client resolves neither, so the pair is
# what this can check; the read-back is the test below.
self.assertEqual((os.environ["TV_HOST"], os.environ["TV_PORT"]), ("192.0.2.7", "15555"))
def test_the_target_the_client_resolved_is_the_one_the_run_keeps(self):
# tools/tv.py splits `host:port` out of the address and refuses a port outside 1..65535.
# bench.py used to put the arguments back over that (tv_client.HOST, PORT = self.host,
# int(self.port)), so `--host <ip>:<port>` reached the client as a machine of that name.
tv, client = self.tv_with(FakeDevice())
client.HOST, client.PORT = "192.0.2.20", 5877
tv.shell("true")
self.assertEqual((tv.host, tv.port, tv.serial), ("192.0.2.20", 5877, "192.0.2.20:5877"))
def test_a_dropped_connection_is_reopened_once(self):
first, second = FakeDevice(fail_first=True), FakeDevice({"echo": b"ok"})
+12 -4
View File
@@ -74,13 +74,17 @@ class TV:
if here not in sys.path:
sys.path.insert(0, here)
# tv.py reads its target from the environment when imported, including CLI overrides here.
os.environ["TV_HOST"], os.environ["TV_PORT"] = self.host, str(self.port)
os.environ["TV_HOST"], os.environ["TV_PORT"] = str(self.host), str(self.port)
try:
import tv as tv_client # noqa: E402
except ModuleNotFoundError as e:
raise SystemExit(f"bench.py needs {e.name}: python3 -m venv tools/venv && "
"tools/venv/bin/pip install -r tools/requirements.txt") from e
tv_client.HOST, tv_client.PORT = self.host, int(self.port)
# Read back the target tv.py made of that environment: it splits `host:port` and refuses a
# port outside 1..65535 there. Overriding these from the arguments (as this did) put the
# `:port` back into the host, so `--host 192.0.2.20:5877` asked for a machine of that name.
self.host, self.port = tv_client.HOST, tv_client.PORT
self.serial = f"{self.host}:{self.port}"
self.client = tv_client.connect()
return self.client
@@ -505,8 +509,12 @@ def main():
parser = argparse.ArgumentParser(description=__doc__,
formatter_class=argparse.RawDescriptionHelpFormatter)
parser.add_argument("--host", default=os.environ.get("TV_HOST"),
help="TV address (or set TV_HOST)")
parser.add_argument("--port", type=int, default=int(os.environ.get("TV_PORT", "5555")))
help="TV address, IP or IP:port (or set TV_HOST)")
# Left as typed: tools/tv.py parses TV_HOST/TV_PORT when TV._connect imports it, refuses a port that
# is not 1..65535 there, and splits the port out of the address. int() here ran before any of that,
# so TV_PORT=abc (or an empty TV_PORT, which tools/tv.py reads as 5555) was a ValueError traceback.
parser.add_argument("--port", default=os.environ.get("TV_PORT") or "5555",
help="the TV's ADB port (or set TV_PORT); default 5555")
parser.add_argument("--keys", type=int, default=36, help="keys per series")
parser.add_argument("--series", type=int, default=3, help="how many series")
parser.add_argument("--cold", type=int, default=5, help="cold starts")