Files
MeshCore/test/test_ssd1306_power.py
T

67 lines
3.1 KiB
Python

#!/usr/bin/env python3
"""Execute the full OLED driver and actual shared-rail reference counting."""
from pathlib import Path
import os
import shutil
import subprocess
import sys
import tempfile
import unittest
from test_replay_reset_integration import extract_braced
ROOT = Path(__file__).resolve().parents[1]
FIXTURE = ROOT / "test/fixtures/ssd1306_power"
DRIVER = ROOT / "src/helpers/ui/SSD1306Display.cpp"
class Ssd1306PowerTests(unittest.TestCase):
def compile_run(self, reset_pin, source=None, expect_failure=False):
compiler = os.environ.get("CXX") or shutil.which("g++") or shutil.which("clang++")
if compiler is None:
self.skipTest("a host C++17 compiler is required")
with tempfile.TemporaryDirectory(prefix="meshcore-ssd1306-power-") as directory:
work = Path(directory)
driver = DRIVER
if source is not None:
driver = work / "SSD1306Display.cpp"
driver.write_text(source, encoding="ascii")
binary = work / "power"
compiled = subprocess.run([
compiler, "-std=c++17", "-Wall", "-Wextra", "-Werror",
"-Wno-unused-parameter", f"-DPIN_OLED_RESET={reset_pin}",
*(["-fsanitize=address,undefined", "-fno-sanitize-recover=all",
"-fno-pie", "-no-pie"] if sys.platform.startswith("linux") else []),
"-I", str(FIXTURE / "mocks"), "-I", str(ROOT / "src"),
"-I", str(ROOT / "src/helpers/ui"),
str(FIXTURE / "test.cpp"), str(driver),
str(ROOT / "src/helpers/ui/DisplayDriver.cpp"), "-o", str(binary),
], text=True, capture_output=True, timeout=60)
self.assertEqual(compiled.returncode, 0, compiled.stdout + compiled.stderr)
checked = subprocess.run([str(binary)], text=True, capture_output=True, timeout=10)
if expect_failure:
self.assertNotEqual(checked.returncode, 0, "negative control escaped the regression")
self.assertIn("Assertion", checked.stderr)
else:
self.assertEqual(checked.returncode, 0, checked.stdout + checked.stderr)
self.assertIn("PASS: actual SSD1306 power ownership (26 scenarios)", checked.stdout)
def test_actual_failure_retry_wake_and_shared_owner_lifecycle(self):
for reset_pin in (21, -1):
with self.subTest(reset_pin=reset_pin):
self.compile_run(reset_pin)
def test_missing_rollback_and_failed_wake_negative_controls(self):
source = DRIVER.read_text()
begin = extract_braced(source, "bool SSD1306Display::begin(")
old_begin = begin[:begin.index(" } else {\n _panel_ready = false;")] + " }\n return started;\n}"
self.compile_run(21, source.replace(begin, old_begin), expect_failure=True)
stopped_wake = "if (!begin()) return; // begin owns and rolls back its claim on failure"
self.assertEqual(source.count(stopped_wake), 1)
self.compile_run(21, source.replace(stopped_wake, "begin();"), expect_failure=True)
if __name__ == "__main__":
unittest.main()