48 lines
2.3 KiB
Python
48 lines
2.3 KiB
Python
#!/usr/bin/env python3
|
|
"""Compile the entire production diagnostic module with deterministic public-API fakes.
|
|
|
|
No TLS, network, scheduler, hardware or real heap/stack measurement is simulated.
|
|
Lock assertions and injected interleavings test the bounded publication contract.
|
|
"""
|
|
import os
|
|
from pathlib import Path
|
|
import re
|
|
import subprocess
|
|
import tempfile
|
|
|
|
ROOT = Path(__file__).resolve().parents[2]
|
|
HERE = Path(__file__).resolve().parent
|
|
|
|
def without_includes(path):
|
|
return '\n'.join(line for line in path.read_text().splitlines()
|
|
if not line.startswith(('#include', '#pragma once')))
|
|
|
|
server = (ROOT / 'src/web_server.c').read_text()
|
|
wrappers = []
|
|
for name in ('traced_ticket_handler', 'traced_websocket_handler',
|
|
'traced_admin_ticket_handler', 'traced_admin_upgrade_handler'):
|
|
match = re.search(r'static esp_err_t ' + name + r'\(httpd_req_t \*request\)\n\{.*?\n\}', server, re.S)
|
|
assert match, name
|
|
wrappers.append(match.group())
|
|
# This slice must not take over cleanup, add async probes, or enable SDK logging.
|
|
assert 'config.user_cb = web_diagnostics_tls;' in server
|
|
assert 'config.httpd.close_fn' not in server and 'config.httpd.open_fn' not in server
|
|
source = (ROOT / 'src/web_diagnostics.c').read_text()
|
|
for forbidden in ('httpd_queue_work', 'httpd_get_client_list', 'esp_event_handler_register',
|
|
'httpd_req_get_', 'request->uri', 'request->user_ctx', 'request->sess_ctx',
|
|
'malloc(', 'calloc(', 'xTaskCreate', 'ESP_LOG', 'esp_log_level_set'):
|
|
assert forbidden not in source, forbidden
|
|
|
|
with tempfile.TemporaryDirectory(prefix='web-diagnostics-') as directory:
|
|
directory = Path(directory)
|
|
unit = directory / 'test.c'
|
|
unit.write_text((HERE / 'fakes.h').read_text() + '\n' +
|
|
without_includes(ROOT / 'src/web_diagnostics.h') + '\n' +
|
|
without_includes(ROOT / 'src/web_diagnostics.c') + '\n' +
|
|
'\n'.join(wrappers) + '\n' + (HERE / 'test.c').read_text())
|
|
executable = directory / 'test'
|
|
subprocess.run([os.environ.get('CC', 'cc'), '-std=c11', '-Wall', '-Wextra', '-Werror',
|
|
str(unit), '-o', str(executable)], check=True)
|
|
subprocess.run([str(executable)], check=True)
|
|
print('PASS: production integration/secrecy source guards (1 group)')
|