Migrate to IDF 5.5.3 candidate

Pin PlatformIO packages and toolchains, rebase protected SDK
overrides, and add WebSocket receive regression coverage. Document
isolated candidate validation, archive provenance, and remaining gates.
This commit is contained in:
2026-09-18 14:23:13 +02:00
parent cdc4d4a8df
commit 797d2681ac
32 changed files with 1394 additions and 123 deletions
+76
View File
@@ -3,6 +3,7 @@
import contextlib
import importlib.util
import io
import json
import os
from pathlib import Path
import subprocess
@@ -66,6 +67,81 @@ class ValidationTests(unittest.TestCase):
self.assertNotIn('build', [c.name for c in commands])
self.assertEqual([c.name for c in commands if '--interop' in c.argv], ['wolfssh_order_contract'])
def test_explicit_paths_and_web_performance(self):
options = self.options('--build-dir', '/isolated/build', '--idf-path', '/isolated/idf',
'--platformio-core-dir', '/isolated/core', '--web-performance')
commands = {c.name: c for c in runner.plan(options)}
self.assertEqual(len(commands), 24)
for name in ('sdk_security_overrides', 'web_serial_performance'):
self.assertEqual(commands[name].argv[3:],
('--build-dir', '/isolated/build', '--idf-path', '/isolated/idf'))
self.assertEqual(commands['ssh_memory'].argv[3:], ('--idf-path', '/isolated/idf'))
for name in ('wolfssh_auth_contract', 'ssh_protocol_policy', 'wolf_crypto_policy'):
self.assertEqual(commands[name].argv[3:],
('--compile-commands', '/isolated/build/compile_commands.json'))
self.assertEqual(commands['security_build_policy'].argv[3:],
('--sdkconfig-header', '/isolated/build/config/sdkconfig.h'))
def test_explicit_environment_is_narrow_and_not_global(self):
with patch.dict(os.environ, {'IDF_PATH': 'old-idf', 'PLATFORMIO_CORE_DIR': 'old-core'}):
with patch.object(runner, 'run_command', return_value=('PASS', 'fixture')) as run:
self.assertEqual(self.execute([self.command('pass')], idf_path=Path('/sdk'),
platformio_core_dir=Path('/core'))[0], 0)
env = run.call_args.args[2]
self.assertEqual(env['IDF_PATH'], '/sdk')
self.assertEqual(env['PLATFORMIO_CORE_DIR'], '/core')
expected = dict(os.environ, CCACHE_DISABLE='1', IDF_PATH='/sdk', PLATFORMIO_CORE_DIR='/core')
self.assertEqual(env, expected)
self.assertEqual(os.environ['IDF_PATH'], 'old-idf')
self.assertEqual(os.environ['PLATFORMIO_CORE_DIR'], 'old-core')
def test_snapshot_content_sets_and_ambiguity_fail_closed(self):
with tempfile.TemporaryDirectory() as tmp:
root, stage, build = [Path(tmp) / name for name in ('root', 'stage', 'build')]
for base in (root, stage):
for directory in ('src', 'cmake', 'boards', 'managed_components', 'tools/wolfssh_order'):
(base / directory).mkdir(parents=True)
for name in ('src/main.c', 'tools/security_overrides.py', 'CMakeLists.txt',
'extra_script.py', 'sdkconfig.defaults', 'partitions.csv'):
(base / name).write_text('identical fixture')
build.mkdir()
database = build / 'compile_commands.json'
entry = {'directory': str(stage), 'file': 'src/main.c'}
database.write_text(json.dumps([entry]))
with contextlib.redirect_stdout(io.StringIO()):
evidence = runner.verify_snapshot(root, build)
self.assertEqual(evidence[:2], (stage, 6))
self.assertEqual(runner.verify_snapshot(root, build), evidence)
(stage / 'src/main.c').write_text('stale')
with self.assertRaisesRegex(RuntimeError, 'content differs'):
runner.verify_snapshot(root, build)
(stage / 'src/main.c').write_text('identical fixture')
(stage / 'src/extra.c').touch()
with self.assertRaisesRegex(RuntimeError, 'file set differs'):
runner.verify_snapshot(root, build)
(stage / 'src/extra.c').unlink()
for entries in ([], [entry, entry]):
database.write_text(json.dumps(entries))
with self.assertRaisesRegex(RuntimeError, 'exactly one'):
runner.verify_snapshot(root, build)
def test_external_build_cannot_rebuild_default(self):
with contextlib.redirect_stderr(io.StringIO()), self.assertRaises(SystemExit):
runner.main(['--build', '--build-dir', '/isolated/build'])
def test_snapshot_failure_never_runs_suites(self):
with patch.object(runner, 'verify_snapshot', side_effect=RuntimeError('mismatch')):
with patch.object(runner, 'execute', side_effect=AssertionError('executed')):
with contextlib.redirect_stdout(io.StringIO()):
self.assertEqual(runner.main(['--build-dir', '/isolated/build']), 1)
def test_snapshot_checked_after_execution(self):
for final, expected in ((('stage', 1, 'same'), 0), (('stage', 1, 'changed'), 1)):
with patch.object(runner, 'verify_snapshot', side_effect=[('stage', 1, 'same'), final]) as verify:
with patch.object(runner, 'execute', return_value=0), contextlib.redirect_stdout(io.StringIO()):
self.assertEqual(runner.main(['--build-dir', '/isolated/build']), expected)
self.assertEqual(verify.call_count, 2)
def test_bad_timeout(self):
for value in ('0', '-1', 'nan', 'inf', '3601', 'junk'):
with contextlib.redirect_stderr(io.StringIO()), self.assertRaises(SystemExit):