Files
STM32F4-Base/.pre-commit-config.yaml
T
wandering1 029437be89 台架执行《实机测试实施指南》步骤 3~7 并闭环
步骤 3/4(IWDG V2/V4/V5 + 堆低水位 S11):
- V2 任务饿死 stall 后 ≤2.5s IWDG 复位;V4 关中断死循环 ~4.9s 稳定复位;
  V5 30min 120×FTP 全 PASS、零 IWDG 复位。堆告警全程未触发(min_ever=4728B)。
- task_watchdog.c:stall 证据写盘会经 nand_ftl_wd_feed 喂狗 → 增 s_stall_evidenced
  每次 stall 仅取一次证据,避免"取证据"本身阻止复位。
- default_task.c:堆低水位告警(HEAP_LOW_WATER_B=3072)。

步骤 5(GD5F 错误通道 S9):gd5f2gq5ue.c/.h + nand_ftl.c 错误码统一为 int32_t 并
全量检查返回值;套件回归 16/16 PASSED。
- test/run_all_suites.py:--forbidden 改为按套件覆盖(GD5F 用 "HardFault;assert")——
  TC-GD5F-704 故意触发 [ERR] 回落轮询,统一默认值会误判 FAIL。

步骤 6(网络稳定性):7.1 正常路径 ✅(V5 证据);7.2 N-2 丢弃可观测性代码已具备、
49s 静默在 V5 未复现(降级低风险观察项);7.3 N-3 待 PC peer。

步骤 7(工程卫生):
- S5:新增 test-cppcheck 钩子(仅 warning,排除模拟器桩)。
- S4:新增 scripts/check_test_traceability.py(默认仅告警)。
- 待核实项 TEST_SUITE_SELECTED 实机核实 = 死代码(无使用点);RTC 套件实际正常执行,
  真缺口 = 缺套件级汇总行 → sd2506_test_task.c 补 === RTC Tests: N/M PASSED === 并
  修正 Phase 级汇总累计问题;test_config.h 补齐 RTC 并注释"当前无引用"。

验证:产品 @build 0/0;pre-commit --all-files 17/17 Passed;
run_all_suites.py --suites RTC → PASS。
文档:实机测试实施指南 / SD2506_Test_Guide / 待处理内容 / 测试与架构改进建议 同步。
2026-10-04 00:35:06 +08:00

237 lines
12 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# pre-commit 自动化代码审查配置
# 详见 docs/代码规范/pre-commit使用说明.md
default_install_hook_types: [pre-commit, commit-msg]
exclude: |
(?x)^(
\.opencode/node_modules/|
Lib/lvgl/|
simulator/|
MDK-ARM/RTE/
)
repos:
# 1) 通用钩子(官方)
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
hooks:
- id: trailing-whitespace
# 排除第三方库(CubeMX 重生成会带回行尾空白,避免每次重生成产生提交抖动);
# 自研代码(Drivers/BSP、Src、Inc、App 等)不受影响
exclude: |
(?x)^(
Drivers/CMSIS/|
Drivers/STM32F4xx_HAL_Driver/|
Middlewares/
)
- id: end-of-file-fixer
- id: check-added-large-files
- id: check-merge-conflict
- id: check-yaml
# 2) C 代码格式:只检查,绝不改写(编码铁律)
# Route A:暂不启用,待全库格式化基线后再放开
# - repo: https://github.com/pre-commit/mirrors-clang-format
# rev: v19.1.4
# hooks:
# - id: clang-format
# args: [--dry-run, --Werror]
# 3) commit message 格式(宽松规则,兼容中文标题)
- repo: https://github.com/jorisroovers/gitlint
rev: v0.19.1
hooks:
- id: gitlint
# 4) 本地自定义钩子(仓库级)
- repo: local
hooks:
- id: cppcheck
name: cppcheck
entry: cppcheck
# 注意:YAML 流序列中逗号是元素分隔符,含逗号/空格的参数必须加引号
args: ['--enable=warning,performance,portability,style', '--error-exitcode=1',
'--inline-suppr',
'--std=c99', '--quiet',
'--suppress=missingIncludeSystem', '--suppress=missingInclude',
'--suppress=invalidPrintfArgType_sint', '--suppress=invalidPrintfArgType_uint',
'--suppress=unusedFunction', '--suppress=unusedStructMember',
'--suppress=noExplicitConstructor', '--suppress=useStlAlgorithm',
'--suppress=constParameterPointer', '--suppress=constParameterCallback',
'--suppress=redundantAssignment',
'--suppress=normalCheckLevelMaxBranches',
'-I', 'Inc', '-I', 'App', '-I', 'Drivers/BSP',
'-I', 'Drivers/STM32F4xx_HAL_Driver/Inc', '-I', 'Drivers/CMSIS/Include',
'-I', 'Middlewares/Third_Party/FreeRTOS/Source/include']
language: system
types: [c]
# 仅扫描项目自有代码;排除第三方库与 LVGL 依赖文件
# (UI 生成文件 ui_font_cn_12/ui_menu_tab 由生成器按工程约定产出,纳入受检)
exclude: |
(?x)^(
Drivers/CMSIS/|
Drivers/STM32F4xx_HAL_Driver/|
Drivers/BSP/NET/lftpd/|
Drivers/BSP/dhara/|
Lib/|
Middlewares/|
MDK-ARM/|
test/
)
# 4b) test/ 代码宽松静态检查(S5,2026-10-03 加)
# 背景:`test/` 此前完全豁免 pre-commit(靠"自律"),而 `test/board/` 下
# 6300+ 行 C 代码**且编入固件**(曾出现 `s_rx_buf` 使用先于声明)。
# 本钩子**只开 warning**(不引入存量 style 噪音),排除模拟器桩
# (`test/host/*/stub/`,第三方/桩头形态不受控)。
# 基线:2026-10-03 全量实测 **0 条 warning**(存量可控,故直接挂钩子)。
# 依据:docs/审查记录/测试与架构改进建议.md §3.4;实机测试实施指南.md §8.1
- id: test-cppcheck
name: cppcheck (test/, warning only)
entry: cppcheck
args: ['--enable=warning', '--error-exitcode=1',
'--inline-suppr', '--std=c99', '--quiet',
'--suppress=missingIncludeSystem', '--suppress=missingInclude',
'--suppress=invalidPrintfArgType_sint', '--suppress=invalidPrintfArgType_uint',
'--suppress=unusedFunction', '--suppress=unusedStructMember',
'--suppress=constParameterPointer', '--suppress=constParameterCallback',
'--suppress=redundantAssignment',
'--suppress=normalCheckLevelMaxBranches',
'-i', 'test/host/watchdog/stub',
'-i', 'test/host/cfg_file/stub',
'-i', 'test/host/sys_clock/stub',
'-I', 'Inc', '-I', 'App', '-I', 'Drivers/BSP',
'-I', 'Drivers/STM32F4xx_HAL_Driver/Inc', '-I', 'Drivers/CMSIS/Include',
'-I', 'Middlewares/Third_Party/FreeRTOS/Source/include',
'test/']
language: system
# 触发条件:test/ 下 C/头文件变动;扫描范围恒为整个 test/(pass_filenames=false)
files: ^test/.*\.(c|h)$
pass_filenames: false
- id: no-mojibake
name: Forbid U+FFFD mojibake
entry: python scripts/check_mojibake.py
language: system
types: [c]
- id: coding-standard
name: C coding standard (规范V1.0)
entry: python scripts/check_coding_standard.py
language: system
types: [c]
# 范围与 cppcheck 钩子一致;另排除 CubeMX 生成文件(Src/、Inc/,重新生成即覆盖)、
# dhara/FatFS 接口适配层(nand_ftl,函数名由外部 API 固定)
exclude: |
(?x)^(
Drivers/CMSIS/|
Drivers/STM32F4xx_HAL_Driver/|
Drivers/BSP/NET/lftpd/|
Drivers/BSP/GD5F2GQ5UE/nand_ftl\.|
Drivers/BSP/dhara/|
Lib/|
Middlewares/|
MDK-ARM/|
test/|
Src/|
Inc/
)
# 5) 文档一致性门禁(D-7)
# 存在性:md 互链 / 反引号路径是否指向真实文件(防迁移/删除后残留死链)
- id: doc-links
name: 文档链接存在性 (D-3/D-7)
entry: python scripts/check_doc_links.py
language: system
files: \.md$
# 外部资料(芯片手册转录)链接形态不受控;第三方目录整体排除
exclude: |
(?x)^(
\.opencode/node_modules/|
Lib/lvgl/|
simulator/|
MDK-ARM/RTE/|
docs/芯片手册/
)
# 数值:README/AGENTS 任务表须与 Src/freertos.c 一致(D-2/D-7)
- id: task-table
name: FreeRTOS 任务表一致性 (D-2/D-7)
entry: python scripts/gen_task_table.py --check
language: system
files: ^(README\.md|AGENTS\.md|Src/freertos\.c)$
pass_filenames: false
# 体积:内存/Flash 数字须与最新 .map 一致(D-7 第三档)
# 只在内存文档或代码变动时触发;.map 未生成时脚本自身给出明确提示
- id: mem-numbers
name: 内存/Flash 数字一致性 (D-7 体积档)
entry: python scripts/check_mem_numbers.py --scan
language: system
files: ^(docs/内存管理/.*\.md|scripts/check_mem_numbers\.py|App/.*\.c|App/.*\.h|Src/.*\.c|Inc/.*\.h)$
pass_filenames: false
# 6) CubeMX 重生成存活审计(2026-09-29 加)
# 背景:.ioc 的 KeepUserCode 只保护 USER CODE 标记区;标记之外的手工改动
# 重生成即被覆盖,且多数不报编译错(崩溃采集被打回空 while(1)、加固宏被删)。
# 本钩子验证"重生成易失清单"各项是否仍在预期位置,并对关键区做哈希漂移检测。
# 范围:仅在这些易失文件变动时触发(改动 .ioc 或生成文件本身就值得复核)。
- id: cubemx-survival
name: CubeMX 重生成存活审计
entry: python scripts/check_cubemx_survival.py --check
language: system
files: ^(STM32F407-Demo\.ioc|Src/.*\.(c|h)|Inc/.*\.h|App/util/task_watchdog\.(c|h)|MDK-ARM/.*\.uvprojx|scripts/check_cubemx_survival\.py)$
pass_filenames: false
# 7) 看门狗判定状态机主机侧单元测试(2026-10-01 加)
# 背景:task_watchdog.c 的判定逻辑(位图取走清零 / 掩码 / miss_streak
# 累计 / 100ms 节流 / tick 回绕)是纯逻辑,板端套件无法穷举边界;本钩子
# 用 MSVC 离线编译真实源文件(#include 纳入)并用可观测桩驱动,秒级、零
# 硬件、不占 MCU RAM。仅在被测文件或其平台层 / 测试变动时触发。
# 详见 docs/测试说明/看门狗单元测试说明.md
- id: watchdog-unit-test
name: 看门狗判定状态机单测(主机侧)
entry: python test/host/watchdog/run_unit_test.py
language: system
files: ^(App/util/task_watchdog\.(c|h)|test/host/watchdog/.*|test/host/common/unit_test_harness\.py)$
pass_filenames: false
# 7b) 系统时钟时间换算主机侧单元测试(2026-10-02 加)
# 背景:sys_clock.c 的 Unix↔日历换算(闰年 / 月末 / 世纪 / 2038 上限)、
# 星期(Zeller)、"30 天惰性再基准化"(防 49.7 天 tick 回绕)、RTC 故障
# 降级路径均为纯逻辑;本钩子用 MSVC 离线编译真实源文件(#include 纳入)
# 并以可注入桩驱动(可控时钟 + 阴影 RTC)。首次落地即抓出 Zeller 公式
# 缺陷(1970~2099 全部日期星期皆错,详见测试说明文档)。
# files 含 sys_clock.c 依赖的 sd2506.h(时间结构/返回值定义)。
- id: sys-clock-unit-test
name: 系统时钟换算单测(主机侧)
entry: python test/host/sys_clock/run_unit_test.py
language: system
files: ^(App/util/sys_clock\.(c|h)|Drivers/BSP/SD2506/sd2506\.h|test/host/sys_clock/.*|test/host/common/unit_test_harness\.py)$
pass_filenames: false
# 7c) 配置引擎主机侧单元测试(2026-10-02 加,S1-b)
# 背景:cfg_file.c 的核心是"文本 <-> 结构"纯变换(INI 段/键解析、四种值
# 类型编解码、外科手术式保存、超长守卫、load/save/poll 契约);板端套件只
# 保存到缺失/新文件(走 s_gen_document 路径),**从不触发对已存在文件的外科
# 手术改写**,故掩盖了该路径的缺陷。本钩子用 MSVC 离线编译真实源文件
# (#include 纳入)+ 内存虚拟文件系统后端驱动,首次落地即抓出 P0:
# `s_encode(...) == 0` 恒假(其成功返回文本长度而非 0)使**外科手术保存的
# 受管值改写路径沦为死码**——对已存在 /config.ini 保存时受管键从不改写(静默
# 不落盘,且 net_cfg_save 仍报 OK)。详见测试说明文档。
- id: cfg-file-unit-test
name: 配置引擎单测(主机侧)
entry: python test/host/cfg_file/run_unit_test.py
language: system
files: ^(App/cfg/cfg_file\.(c|h)|App/cfg/cfg_file_store\.h|App/log/sys_log\.h|test/host/cfg_file/.*|test/host/common/unit_test_harness\.py)$
pass_filenames: false
# 8) 测试套件开关门禁(2026-10-01 加)
# 背景:test_config.h 的 TEST_SUITE_* 决定固件里编入哪个测试套件,
# 全部注释 = 产品构建。但此前**无任何门禁检查**——实测已提交的 HEAD 里
# TEST_SUITE_CH395F 就是开启状态(.map 含 34 处 test 代码),即仓库里
# 躺着的是测试固件。本钩子抓这个静默漏网:默认要求产品构建,跑套件回归
# 确需提交测试构建时用 `--allow-test-build` / ALLOW_TEST_BUILD=1 显式放行。
# 详见 docs/待处理内容.md T-1
- id: test-suite-switch
name: 测试套件开关=产品构建
entry: python scripts/check_test_suite.py
language: system
files: ^test/board/test_config\.h$
pass_filenames: false