67 lines
3.0 KiB
Python
67 lines
3.0 KiB
Python
#!/usr/bin/env python3
|
|
"""A previously passing RAM/capability manifest cannot bypass a new contract."""
|
|
|
|
import hashlib
|
|
import json
|
|
from pathlib import Path
|
|
import subprocess
|
|
import tempfile
|
|
import unittest
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
|
|
|
|
class FullLoggingResumeTest(unittest.TestCase):
|
|
def check_cached(self, source, *, packet_present=True, logging_required=True):
|
|
with tempfile.TemporaryDirectory() as temp:
|
|
directory = Path(temp)
|
|
stem = "Station_G2_repeater_observer_mqtt-full-usb-wifi-ota-vtest"
|
|
checks = [{"capability": "logging.usb.control", "evidence": "USB control", "present": True},
|
|
{"capability": "logging.usb.packets", "evidence": "packet logger", "present": packet_present}]
|
|
if source is not None:
|
|
for check in checks:
|
|
check["source"] = source
|
|
manifest = {"schema_version": 2, "verified": True, "verification": checks}
|
|
(directory / (stem + ".capabilities.json")).write_text(json.dumps(manifest))
|
|
(directory / (stem + ".bin")).write_bytes(b"firmware")
|
|
(directory / (stem + "-merged.bin")).write_bytes(b"merged firmware")
|
|
proof = dict(schema_version=1, passed=True, available_internal_bytes=80000,
|
|
required_heap_bytes=50000, largest_internal_region_bytes=80000,
|
|
required_contiguous_bytes=5120, elf_sha256="a" * 64,
|
|
files={p.name: hashlib.sha256(p.read_bytes()).hexdigest() for p in directory.iterdir()})
|
|
(directory / (stem + ".memory.json")).write_text(json.dumps(proof))
|
|
command = '''
|
|
source build.sh
|
|
OUTPUT_DIR="$1"
|
|
BUILD_APPLICATION_EXPECTATIONS=()
|
|
if [ "$3" = yes ]; then
|
|
BUILD_APPLICATION_EXPECTATIONS=('logging.usb.control=USB control' 'logging.usb.packets=packet logger')
|
|
fi
|
|
build_artifacts_exist ESP32_PLATFORM "$2"
|
|
'''
|
|
return subprocess.run(["bash", "-c", command, "resume-test", str(directory), stem,
|
|
"yes" if logging_required else "no"], cwd=ROOT,
|
|
text=True, capture_output=True)
|
|
|
|
def test_old_and_elf_only_manifests_force_a_rebuild(self):
|
|
for source in (None, "linked image"):
|
|
with self.subTest(source=source):
|
|
result = self.check_cached(source)
|
|
self.assertNotEqual(result.returncode, 0, result.stdout)
|
|
|
|
def test_verified_packaged_logger_can_resume(self):
|
|
result = self.check_cached("packaged application")
|
|
self.assertEqual(result.returncode, 0, result.stderr)
|
|
|
|
def test_missing_packet_logger_cannot_resume(self):
|
|
result = self.check_cached("packaged application", packet_present=False)
|
|
self.assertNotEqual(result.returncode, 0)
|
|
|
|
def test_other_profiles_keep_their_existing_resume_policy(self):
|
|
result = self.check_cached(None, logging_required=False)
|
|
self.assertEqual(result.returncode, 0, result.stderr)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|