Integrate shared C transport with desktop and Android frontends, add radio probes and detailed Windows diagnostics, and fix GUI build dependencies and early configuration startup errors.
70 lines
3.7 KiB
Python
70 lines
3.7 KiB
Python
#!/usr/bin/env python3
|
|
"""Одновременный запуск Binder/GATT probe на двух телефонах, с полными раздельными логами."""
|
|
|
|
import argparse
|
|
from pathlib import Path
|
|
import subprocess
|
|
import sys
|
|
import time
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(description=__doc__)
|
|
parser.add_argument("--receiver", required=True, help="ADB serial принимающей стороны")
|
|
parser.add_argument("--initiator", required=True, help="ADB serial инициатора")
|
|
parser.add_argument("--receiver-id", required=True, help="64-bit ID принимающей стороны, hex")
|
|
parser.add_argument("--initiator-id", required=True, help="64-bit ID инициатора, hex")
|
|
parser.add_argument("--reject", action="store_true", help="Проверить отказ callback вместо duplex")
|
|
parser.add_argument("--install", action="store_true", help="Установить готовые app и androidTest APK перед тестом")
|
|
parser.add_argument("--output", type=Path, required=True)
|
|
args = parser.parse_args()
|
|
if args.receiver == args.initiator:
|
|
parser.error("Нужны два разных устройства")
|
|
for value in (args.receiver_id, args.initiator_id):
|
|
if not 0 < int(value, 16) <= 0xffffffffffffffff:
|
|
parser.error("ID должен быть ненулевым unsigned 64-bit числом")
|
|
args.output.mkdir(parents=True, exist_ok=True)
|
|
project = Path(__file__).resolve().parents[1]
|
|
roles = [("receiver", args.receiver, args.initiator_id, "false"),
|
|
("initiator", args.initiator, args.receiver_id, "true")]
|
|
if args.install:
|
|
for _, serial, _, _ in roles:
|
|
for apk in ("app/build/outputs/apk/debug/app-debug.apk",
|
|
"app/build/outputs/apk/androidTest/debug/app-debug-androidTest.apk"):
|
|
subprocess.run(["adb", "-s", serial, "install", "-r", str(project / apk)], check=True)
|
|
processes = []
|
|
files = []
|
|
try:
|
|
# Оба процесса создаются до ожидания: согласование запуска не зависит от задержек отдельных tool approvals.
|
|
for role, serial, peer, initiate in roles:
|
|
logfile = args.output / f"{role}.log"
|
|
output = logfile.open("w")
|
|
files.append(output)
|
|
command = ["adb", "-s", serial, "shell", "am", "instrument", "-w", "-e", "peer", peer,
|
|
"-e", "initiator", initiate, "-e", "reject", str(args.reject).lower(),
|
|
"com.utun.bletest.test/com.utun.bletest.BleApiProbe"]
|
|
processes.append((role, subprocess.Popen(command, stdout=output, stderr=subprocess.STDOUT), logfile))
|
|
print(f"Started {role}: {serial}, peer={peer}", flush=True)
|
|
deadline = time.monotonic() + 210
|
|
while any(process.poll() is None for _, process, _ in processes):
|
|
if time.monotonic() >= deadline:
|
|
raise TimeoutError("Timed out waiting for two-device probe")
|
|
time.sleep(0.25)
|
|
success = True
|
|
for role, process, logfile in processes:
|
|
content = logfile.read_text()
|
|
print(f"{role}:\n{content}", flush=True)
|
|
success &= process.returncode == 0 and "result=PASS " in content and "INSTRUMENTATION_CODE: -1" in content
|
|
return 0 if success else 1
|
|
finally:
|
|
for _, process, _ in processes:
|
|
if process.poll() is None:
|
|
process.terminate()
|
|
process.wait(timeout=10)
|
|
for output in files:
|
|
output.close()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|