Files
MeshCore/test/test_pocket_eink_refresh.py
T

76 lines
3.1 KiB
Python

#!/usr/bin/env python3
"""Exercise the production Pocket e-paper driver against a recording panel."""
import os
from pathlib import Path
import shutil
import subprocess
import tempfile
import unittest
ROOT = Path(__file__).resolve().parents[1]
UI = ROOT / "src/helpers/ui"
FIXTURE = ROOT / "test/fixtures/pocket_eink_refresh"
class PocketEinkRefreshTest(unittest.TestCase):
@classmethod
def setUpClass(cls):
compiler = shutil.which(os.environ.get("CXX", "g++"))
if compiler is None:
raise unittest.SkipTest("host G++ required")
cls.temporary = tempfile.TemporaryDirectory(prefix="pocket-eink-refresh-")
cls.work = Path(cls.temporary.name)
# Copy the actual driver so its quoted hardware includes resolve to the
# fixture. The DisplayDriver base and Pocket feature configuration stay
# production code, while the panel records calls crossing the HW API.
for name in ("GxEPDDisplay.h", "GxEPDDisplay.cpp"):
shutil.copyfile(UI / name, cls.work / name)
cls.binary = cls.work / "refresh-test"
flags = ["-std=c++17", "-Wall", "-Wextra", "-Werror", "-g",
"-Wno-unused-parameter", "-Wno-sign-compare"]
if os.name != "nt":
flags += ["-fsanitize=address,undefined", "-fno-sanitize-recover=all",
"-fno-omit-frame-pointer", "-fno-pie", "-no-pie"]
command = [compiler, *flags, "-DHELTEC_MESH_POCKET=1", "-DCOMPANION_RADIO_FULL=1",
"-DEINK_DISPLAY_MODEL=GxEPD2_213_B74", "-DDISPLAY_ROTATION=3",
"-I" + str(cls.work), "-I" + str(FIXTURE), "-I" + str(UI),
"-I" + str(ROOT / "src"), str(FIXTURE / "main.cpp"),
str(cls.work / "GxEPDDisplay.cpp"), "-o", str(cls.binary)]
result = subprocess.run(command, capture_output=True, text=True, timeout=90)
if result.returncode:
cls.temporary.cleanup()
raise AssertionError(" ".join(command) + "\n" + result.stdout + result.stderr)
@classmethod
def tearDownClass(cls):
cls.temporary.cleanup()
def run_case(self, scenario):
result = subprocess.run([str(self.binary), scenario], capture_output=True,
text=True, timeout=10)
self.assertEqual(result.returncode, 0, result.stdout + result.stderr)
def test_manual_clean_affects_current_frame_even_when_crc_is_unchanged(self):
self.run_case("manual")
def test_first_image_is_clean_even_when_gui_applies_its_refresh_settings(self):
self.run_case("boot")
def test_unchanged_frames_skip_io_and_do_not_use_partial_refresh_budget(self):
self.run_case("periodic")
def test_changing_clean_interval_preserves_a_pending_full_refresh(self):
self.run_case("interval")
def test_waking_from_hibernate_restores_panel_history_before_partial_updates(self):
self.run_case("wake")
def test_rotation_cleans_the_current_frame_and_keeps_native_dimensions(self):
self.run_case("rotation")
if __name__ == "__main__":
unittest.main()