mirror of
https://github.com/mikecarper/MeshCore.git
synced 2026-09-25 15:03:45 +00:00
85 lines
3.5 KiB
Python
85 lines
3.5 KiB
Python
#!/usr/bin/env python3
|
|
"""Exercise real PlatformIO flag ordering through a host compiler (no board).
|
|
|
|
Requires PlatformIO and its tool-scons package, installed by the native tests
|
|
in CI. This deliberately uses ProcessFlags, not a reimplementation of it.
|
|
"""
|
|
|
|
import contextlib
|
|
import io
|
|
import os
|
|
from pathlib import Path
|
|
import runpy
|
|
import shutil
|
|
import subprocess
|
|
import sys
|
|
import tempfile
|
|
import unittest
|
|
from unittest import mock
|
|
|
|
try:
|
|
import SCons.Script
|
|
except ImportError:
|
|
core = Path(os.environ.get("PLATFORMIO_CORE_DIR", Path.home() / ".platformio"))
|
|
for path in sorted((core / "packages" / "tool-scons").glob("scons-local-*"), reverse=True):
|
|
sys.path.insert(0, str(path))
|
|
import SCons.Script
|
|
|
|
from platformio.builder.tools.piobuild import ParseFlagsExtended, ProcessFlags
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
SCRIPT = ROOT / "scripts" / "deduplicate_full_build_flags.py"
|
|
SOURCE = """
|
|
#if !defined(MESH_PACKET_LOGGING) || MESH_PACKET_LOGGING != 1
|
|
#error Full image lost USB packet logging
|
|
#endif
|
|
#if defined(MESH_DEBUG)
|
|
#error Packet logging must not reenable disabled debug logging
|
|
#endif
|
|
int logging_contract(void) { return MESH_PACKET_LOGGING; }
|
|
"""
|
|
|
|
|
|
class FullLoggingCompilerTest(unittest.TestCase):
|
|
def compile(self, flags, *, required):
|
|
self.assertIsNotNone(shutil.which("gcc"), "Install gcc to run the compiler regression")
|
|
env = SCons.Script.Environment(tools=["gcc"], BUILD_FLAGS=flags)
|
|
env.AddMethod(ParseFlagsExtended)
|
|
env.AddMethod(ProcessFlags)
|
|
with mock.patch.dict(os.environ, {
|
|
"MESHCORE_ESP32_FULL_BUILD": "1",
|
|
"MESHCORE_COMPANION_RADIO_FULL": "0",
|
|
"MESHCORE_REQUIRE_PACKET_LOGGING": "1" if required else "0",
|
|
"PLATFORMIO_BUILD_FLAGS": "-DMESH_PACKET_LOGGING=1",
|
|
}), contextlib.redirect_stdout(io.StringIO()):
|
|
runpy.run_path(str(SCRIPT), init_globals={"Import": lambda _: None, "env": env})
|
|
env.ProcessFlags(env["BUILD_FLAGS"])
|
|
with tempfile.TemporaryDirectory() as directory:
|
|
source, target = Path(directory) / "probe.c", Path(directory) / "probe.o"
|
|
source.write_text(SOURCE)
|
|
command = env.subst_list("$CCCOM", source=env.File(str(source)), target=env.File(str(target)))[0]
|
|
result = subprocess.run([str(item) for item in command], text=True, capture_output=True)
|
|
return result, [str(item) for item in command]
|
|
|
|
def test_reproduces_the_published_station_g2_failure(self):
|
|
result, command = self.compile(
|
|
["-UMESH_DEBUG -UMESH_PACKET_LOGGING", "-DMESH_PACKET_LOGGING=1"], required=False)
|
|
self.assertGreater(command.index("-UMESH_PACKET_LOGGING"), command.index("-DMESH_PACKET_LOGGING=1"))
|
|
self.assertNotEqual(result.returncode, 0)
|
|
self.assertIn("Full image lost USB packet logging", result.stderr)
|
|
|
|
def test_full_contract_survives_real_platformio_preprocessing(self):
|
|
for disable in ("-UMESH_PACKET_LOGGING", "-U MESH_PACKET_LOGGING",
|
|
"-DMESH_PACKET_LOGGING=0", "-D MESH_PACKET_LOGGING=0"):
|
|
for before in (True, False):
|
|
with self.subTest(disable=disable, before=before):
|
|
flags = ["-DMESH_PACKET_LOGGING=1", "-UMESH_DEBUG", disable]
|
|
if before:
|
|
flags.reverse()
|
|
result, _ = self.compile(flags, required=True)
|
|
self.assertEqual(result.returncode, 0, result.stderr)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|