bc1d56d1a4
P0.6: gcov infrastructure P1: extract_structure output expansion (11 new feature fields) P2: Confusion group rule engine (8 pairs + contradiction + backtrack) P3: 4-factor confidence calculation + quality gate update P4: 33+2 COBOL program type test samples (22 files, 7 categories) P5: parametrized/ test data generation engine P6: japanese_data.py lookup tables P7-10: Type-specific test suites (~159 parametrized tests) P11: Full classification pipeline (classify_program) + orchestrator integration P12: Documentation (module-interfaces, test-plan v3.0, coverage-matrix) Architecture decisions: - classification_pipeline/ merged to hina/pipeline/ - parametrized/ as independent module - japanese_data.py as root-level file - hina/__all__ only exports classify_program() Co-Authored-By: Claude <noreply@anthropic.com>
1240 lines
43 KiB
Markdown
1240 lines
43 KiB
Markdown
# COBOL 迁移验证平台 第二阶段设计书
|
||
|
||
> 版本: v2.0 | 日期: 2026-06-19
|
||
> 基于: cobol-test-benchmark.md 的 33+2 程序类型分类体系
|
||
> 范围: 12 个 Phase,从类型判定引擎完善到完整测试基准实现
|
||
|
||
---
|
||
|
||
## 目录
|
||
|
||
1. [设计总则](#1-设计总则)
|
||
2. [Phase 1: extract_structure 输出扩展](#2-phase-1-extract_structure-输出扩展)
|
||
3. [Phase 2: 混淆组判定规则引擎](#3-phase-2-混淆组判定规则引擎)
|
||
4. [Phase 3: 确信度 4 因子计算](#4-phase-3-确信度-4-因子计算)
|
||
5. [Phase 4: 33+2 种程序类型 COBOL 测试样本](#5-phase-4-332-种程序类型-cobol-测试样本)
|
||
6. [Phase 5: 参数化测试数据生成引擎](#6-phase-5-参数化测试数据生成引擎)
|
||
7. [Phase 6: 日文测试数据生成查找表](#7-phase-6-日文测试数据生成查找表)
|
||
8. [Phase 7-10: 类型别测试套件](#8-phase-7-10-类型别测试套件)
|
||
9. [Phase 11: 完整类型判定管道](#9-phase-11-完整类型判定管道)
|
||
10. [Phase 12: 文档更新](#10-phase-12-文档更新)
|
||
11. [依赖关系与分工矩阵](#11-依赖关系与分工矩阵)
|
||
12. [接口变更一览](#12-接口变更一览)
|
||
13. [COBOL 覆盖率测试体系](#13-cobol-覆盖率测试体系)
|
||
14. [架构审核决议汇总](#14-架构审核决议汇总)
|
||
|
||
---
|
||
|
||
## 1. 设计总则
|
||
|
||
### 1.1 新增 Phase 0.6: gcov 基础设施
|
||
|
||
> 在 Phase 1 之前完成,为所有类型测试提供 gcov 能力。
|
||
> 负责: F | 工作量: 3h
|
||
|
||
为覆盖率测试体系提供可自动化运行的基础设施。Phase 7-10 中所有 gcov 测试的前置条件。
|
||
|
||
| 步骤 | 内容 | 工作量 |
|
||
|:-----|:-----|:------|
|
||
| 1 | `cobc --coverage` 环境验证自动化 | 0.5h |
|
||
| 2 | `collect_gcov()` 路径修复(含中文目录兼容)| 1h |
|
||
| 3 | `Config` 追加 gcov_enabled / gcov_work_dir / gcov_threshold | 0.5h |
|
||
| 4 | `test_gcov_basic.py` — gcov 全链路验证测试 | 1h |
|
||
|
||
**验收**: cobc --coverage 编译 → 运行 → .gcda 生成 → collect_gcov() line_rate > 0
|
||
|
||
```python
|
||
# config/__init__.py — Config 新增字段
|
||
gcov_enabled: bool = False
|
||
gcov_work_dir: str = ".gcov_output"
|
||
gcov_threshold: float = 0.5
|
||
```
|
||
|
||
### 1.3 分层原则
|
||
|
||
```
|
||
Layer 1: data/ — 所有模块共享的数据契约
|
||
Layer 2: 核心引擎 — cobol_testgen/ config/ jcl/ quality/ report/ preprocessor/
|
||
Layer 3: 业务引擎 — hina/ agents/ comparator/ runners/
|
||
Layer 4: 管道集成 — orchestrator/ web/
|
||
|
||
依赖方向: Layer 1 ← Layer 2 ← Layer 3 ← Layer 4
|
||
禁止逆向依赖。
|
||
```
|
||
|
||
### 1.4 模块通信规则
|
||
|
||
- 所有模块间通信通过 `data/` 层的数据类进行
|
||
- 每个模块的公开 API 由 `__init__.py` 的 `__all__` 定义
|
||
- 禁止钻入模块内部(如 `from cobol_testgen.coverage import ...`)
|
||
- 详见 `CONTRIBUTING.md`
|
||
|
||
### 1.5 最终模块布局(经架构审核确认)
|
||
|
||
```
|
||
项目根目录/
|
||
├── cobol_testgen/ ← COBOL 解析引擎 (P1扩展)
|
||
│
|
||
├── hina/
|
||
│ ├── rule_engine/ ← 混淆组规则引擎 (P2)
|
||
│ ├── confidence.py ← 确信度 4 因子计算 (P3)
|
||
│ └── pipeline/ ← 完整类型判定管道 (P11)
|
||
│
|
||
├── parametrized/ ← 独立模块!参数化测试数据生成引擎 (P5)
|
||
│ ├── __init__.py
|
||
│ ├── matching.py
|
||
│ ├── division.py
|
||
│ └── common.py
|
||
│
|
||
├── japanese_data.py ← 独立文件!日文测试数据查找表 (P6)
|
||
│
|
||
├── test-data/cobol/ ← 新增 33+2 种 COBOL 样本 (P4)
|
||
│
|
||
├── tests/
|
||
│ └── parametrized/ ← 类型别测试套件 (P7-10)
|
||
│
|
||
└── docs/ ← 文档更新 (P12)
|
||
|
||
重要决策:
|
||
✅ classification_pipeline/ → 合并到 hina/pipeline/
|
||
✅ parametrized/ → 独立模块(项目根目录)
|
||
✅ japanese_data.py → 独立文件(项目根目录)
|
||
```
|
||
|
||
---
|
||
|
||
## 2. Phase 1: extract_structure 输出扩展
|
||
|
||
### 2.1 目的
|
||
|
||
当前 `extract_structure()` 输出的结构特征不足以判定 33+2 种程序类型。需要增加以下字段。
|
||
|
||
### 2.2 新增输出字段
|
||
|
||
在 `cobol_testgen/__init__.py` 的 `extract_structure()` 返回字典中追加:
|
||
|
||
```python
|
||
# 新增字段(原有字段不变)
|
||
{
|
||
# ── 文件相关 ──
|
||
"select_files": { # SELECT 语句列表
|
||
"INFILE": {"assign_to": "INPUT.DAT", "organization": "SEQUENTIAL"},
|
||
"OUTFILE": {"assign_to": "OUTPUT.DAT", "organization": "SEQUENTIAL"},
|
||
},
|
||
"open_directions_detail": { # OPEN 方向详情
|
||
"INFILE": "INPUT",
|
||
"OUTFILE": "OUTPUT",
|
||
"WORKFILE": "I-O",
|
||
},
|
||
|
||
# ── DIVIDE 语句检测 ──
|
||
"has_divide": False, # 是否有 DIVIDE 语句
|
||
"divide_constants": [], # DIVIDE 的被除数列表: [50, 25, 100]
|
||
|
||
# ── INSPECT/STRING 语句检测 ──
|
||
"has_inspect": False, # 是否有 INSPECT 语句
|
||
"has_string": False, # 是否有 STRING 语句
|
||
|
||
# ── PERFORM 模式分类 ──
|
||
"perform_patterns": [ # 每个 PERFORM 的模式
|
||
{"type": "inline", "target": None, "condition": None}, # inline / paragraph / thru / varying / times
|
||
{"type": "varying", "target": "WS-I", "condition": "WS-I > 100"},
|
||
{"type": "times", "times": 50},
|
||
{"type": "until", "condition": "WS-A > 5"},
|
||
{"type": "thru", "target": "PARA-A", "thru": "PARA-C"},
|
||
],
|
||
|
||
# ── 主循环定位(含 READ 语句的 PERFORM 块)──
|
||
"main_loop": { # 主循环信息(None=无循环)
|
||
"type": "perform_until", # perform_until / perform_varying / read_loop
|
||
"read_file": "INFILE", # 在该循环中 READ 的文件
|
||
"has_at_end": True, # 是否有 AT END 处理
|
||
"at_end_action": "MOVE 'Y' TO WS-EOF", # AT END 处理内容
|
||
},
|
||
|
||
# ── IF 分支类型统计 ──
|
||
"if_types": {
|
||
"total": 3, # IF 总数
|
||
"comparison": 2, # 比较型 (>, <, >=, <=)
|
||
"equality": 1, # 等值型 (=)
|
||
"compound": 1, # 复合型 (AND/OR)
|
||
"nested_depth": 2, # 最大嵌套深度
|
||
},
|
||
|
||
# ── 变量命名模式检测 ──
|
||
"variable_patterns": {
|
||
"has_prev_key": True, # WS-PREV-* 模式变量
|
||
"has_accumulator": True, # WS-*CNT / WS-*SUM 模式变量
|
||
"has_error_field": False, # WS-ERR* / WS-MSG* 模式变量
|
||
"has_key_field": True, # WS-*KEY 模式变量
|
||
"prev_key_fields": ["WS-PREV-KEY"], # 具体的前键值字段名
|
||
"accumulator_fields": ["WS-REC-CNT"], # 具体的累加器字段名
|
||
},
|
||
|
||
# ── OPEN 模式 ──
|
||
"open_pattern": "sequential", # sequential / reopen(OPEN→CLOSE→再OPEN)
|
||
}
|
||
```
|
||
|
||
### 2.3 实现位置
|
||
|
||
| 新增特征 | 实现文件 | 实现方法 |
|
||
|:---------|:---------|:---------|
|
||
| SELECT 文件详情 | `read.py` 的 `parse_file_control()` 扩展 | 追加 organization 字段 |
|
||
| DIVIDE/INSPECT/STRING | `core.py` `_BrParser` | 添加 IF 语句解析 |
|
||
| PERFORM 模式分类 | `core.py` `_BrParser` | BrPerform 属性已存在 |
|
||
| 主循环定位 | `core.py` 新函数 `locate_main_loop()` | 搜索含 READ 的 PERFORM 块 |
|
||
| IF 类型统计 | `core.py` 新函数 `stat_if_types()` | 遍历 BrIf 的 condition |
|
||
| 变量命名模式 | `core.py` 新函数 `detect_variable_patterns()` | 正则匹配字段名 |
|
||
| OPEN 模式 | `read.py` 新函数 `detect_open_pattern()` | 检查 OPEN→CLOSE→OPEN |
|
||
|
||
### 2.4 接口变更
|
||
|
||
```python
|
||
# cobol_testgen/__init__.py — __all__ 不变
|
||
# extract_structure() 签名不变,返回字典追加新字段
|
||
# 现有调用者不受影响(dict.get() 返回 None 获得默认值)
|
||
```
|
||
|
||
---
|
||
|
||
## 3. Phase 2: 混淆组判定规则引擎
|
||
|
||
### 3.1 新模块 `hina/rule_engine/`
|
||
|
||
创建独立子模块,与现有的 `classifier.py` 互补:
|
||
|
||
```
|
||
hina/
|
||
├── __init__.py # 导出 rule_engine 的 API
|
||
├── classifier.py # 现有(不变)
|
||
├── rule_engine/ # 新增
|
||
│ ├── __init__.py
|
||
│ ├── confusion_groups.py # 8 混淆组的规则实现
|
||
│ ├── contradiction.py # 矛盾检测
|
||
│ └── backtrack.py # 回溯机制
|
||
```
|
||
|
||
### 3.2 8 混淆组规则
|
||
|
||
```python
|
||
# hina/rule_engine/confusion_groups.py
|
||
|
||
def resolve_confusion_pair(features: dict, pair_name: str) -> dict:
|
||
"""解决一对混淆组,返回判定结果。
|
||
|
||
参数:
|
||
features — extract_structure() 输出的结构特征
|
||
pair_name — 混淆对名称:
|
||
"matching_vs_keybreak"
|
||
"dedup_vs_nodedup"
|
||
"validation_vs_keybreak"
|
||
"csv_merge_vs_split"
|
||
"simple_vs_two_stage"
|
||
"pure_vs_mixed"
|
||
"division_50_25_100"
|
||
"mn_output_mode"
|
||
|
||
返回:
|
||
{"resolved_type": str, "confidence": float, "evidence": list}
|
||
"""
|
||
|
||
# 规则实现示例 ── "matching_vs_keybreak"
|
||
def _matching_vs_keybreak(features: dict) -> dict:
|
||
"""匹配 vs key切
|
||
|
||
判定逻辑:
|
||
1. SELECT 文件数 < 2 → 排除匹配 → key切
|
||
2. IF 类型统计中 3 路 IF(comparison) 占比 > 50% → 匹配
|
||
3. 2 路 IF(equality) 为主 + WS-PREV-KEY 存在 → key切
|
||
4. 有累加器(WS-*CNT) + WS-PREV-KEY + 2 路 IF → key切
|
||
5. 输入文件 ≥ 2 + 3 路 IF → 匹配
|
||
6. 无法确定 → 回退到 conflict_score
|
||
"""
|
||
file_count = len(features.get("select_files", {}))
|
||
if_types = features.get("if_types", {})
|
||
var_patterns = features.get("variable_patterns", {})
|
||
|
||
evidence = []
|
||
if file_count >= 2:
|
||
evidence.append("file_count>=2 → possible matching")
|
||
|
||
comp_ratio = if_types.get("comparison", 0) / max(if_types.get("total", 1), 1)
|
||
if comp_ratio > 0.5:
|
||
evidence.append("comparison IF ratio > 50% → matching signature")
|
||
|
||
if var_patterns.get("has_prev_key") and var_patterns.get("has_accumulator"):
|
||
evidence.append("WS-PREV-KEY + accumulator → keybreak signature")
|
||
|
||
# 综合判断
|
||
matching_score = sum(1 for e in evidence if "matching" in e)
|
||
keybreak_score = sum(1 for e in evidence if "keybreak" in e)
|
||
|
||
if matching_score > keybreak_score:
|
||
return {"resolved_type": "マッチング", "confidence": 0.7 + matching_score * 0.1,
|
||
"evidence": evidence}
|
||
elif keybreak_score > matching_score:
|
||
return {"resolved_type": "キーブレイク", "confidence": 0.7 + keybreak_score * 0.1,
|
||
"evidence": evidence}
|
||
else:
|
||
return {"resolved_type": "unknown", "confidence": 0.5, "evidence": evidence}
|
||
```
|
||
|
||
### 3.3 矛盾检测
|
||
|
||
```python
|
||
# hina/rule_engine/contradiction.py
|
||
|
||
# 7 个矛盾对
|
||
CONTRADICTION_PAIRS = [
|
||
("matching_vs_keybreak", {
|
||
"type_a": "マッチング",
|
||
"type_b": "キーブレイク",
|
||
"rule": lambda f: f.get("variable_patterns", {}).get("has_prev_key"),
|
||
"tiebreaker": "file_count", # file_count ≥ 2 → matching wins
|
||
}),
|
||
("dedup_vs_nodedup", {
|
||
"type_a": "項目チェック(重複含む)",
|
||
"type_b": "項目チェック(重複含まず)",
|
||
"rule": lambda f: f.get("variable_patterns", {}).get("has_prev_key"),
|
||
"tiebreaker": "prev_key_exists", # WS-PREV-KEY → 含重复 wins
|
||
}),
|
||
("validation_vs_keybreak", {
|
||
"type_a": "項目チェック",
|
||
"type_b": "キーブレイク",
|
||
"rule": lambda f: f.get("variable_patterns", {}).get("has_error_field"),
|
||
"tiebreaker": "has_error_field", # WS-ERR* → 校验 wins; WS-*CNT → key切 wins
|
||
}),
|
||
# ... 其余 4 个
|
||
]
|
||
|
||
def detect_contradictions(features: dict, candidates: list[str]) -> list[dict]:
|
||
"""检测候选类型中的矛盾对,返回矛盾列表。"""
|
||
|
||
def resolve_contradiction(features: dict, contradiction: dict) -> str:
|
||
"""使用 tiebreaker 规则解决单个矛盾。"""
|
||
```
|
||
|
||
### 3.4 回溯机制
|
||
|
||
```python
|
||
# hina/rule_engine/backtrack.py
|
||
|
||
class BacktrackResolver:
|
||
"""当混淆组判定进入死胡同时,回溯到 extract_structure 重新提取特征。"""
|
||
|
||
def __init__(self, structure_extractor: callable):
|
||
self.extract = structure_extractor
|
||
self.max_rounds = 3
|
||
|
||
def resolve(self, cobol_source: str, initial_features: dict) -> dict:
|
||
"""多轮判定。每轮检测矛盾→回溯→重新提取→重新判定。"""
|
||
features = initial_features
|
||
for round_num in range(self.max_rounds):
|
||
# Step 1: 检测矛盾
|
||
contradictions = detect_contradictions(features, candidates)
|
||
|
||
if not contradictions:
|
||
# 无矛盾,返回最终结果
|
||
return self._finalize(features)
|
||
|
||
# Step 2: 解析矛盾
|
||
for c in contradictions:
|
||
resolution = resolve_contradiction(features, c)
|
||
|
||
# Step 3: 如果需要更多信息,回溯重新提取
|
||
if self._needs_backtrack(contradictions):
|
||
refined_source = self._refine_extraction(cobol_source, contradictions)
|
||
features = self.extract(refined_source)
|
||
|
||
return self._finalize_with_warning(features)
|
||
```
|
||
|
||
### 3.5 接口变更
|
||
|
||
```python
|
||
# hina/__init__.py — __all__ 追加
|
||
"resolve_confusion_pair", # (features, pair_name) → dict
|
||
"detect_contradictions", # (features, candidates) → list[dict]
|
||
"BacktrackResolver", # class — 多轮判定
|
||
```
|
||
|
||
---
|
||
|
||
## 4. Phase 3: 确信度 4 因子计算
|
||
|
||
### 4.1 新函数
|
||
|
||
在 `hina/classifier.py` 中新增确信度计算函数,或者创建 `hina/confidence.py`:
|
||
|
||
```python
|
||
# hina/confidence.py — 新增文件
|
||
|
||
def compute_confidence_v2(
|
||
keyword_result: dict, # detect_keyword() 的输出
|
||
structure_features: dict, # extract_structure() 的输出
|
||
contradictions: list[dict], # contradiction.detect_contradictions() 的输出
|
||
resolution: dict # confusion_groups 的输出
|
||
) -> dict:
|
||
"""四因子确信度计算。
|
||
|
||
公式:
|
||
confidence = base × context_factor × consistency_factor × structure_factor
|
||
|
||
参数:
|
||
keyword_result — {matches: [(category, confidence, keyword)], ...}
|
||
structure_features — extract_structure 输出的完整字典
|
||
contradictions — 矛盾列表
|
||
resolution — 混淆组解决结果
|
||
|
||
返回:
|
||
{
|
||
"confidence": float, # 最终确信度 (0~1)
|
||
"base": float, # 基础确信度
|
||
"context_factor": float, # 上下文因子
|
||
"consistency_factor": float, # 一致性因子
|
||
"structure_factor": float, # 结构一致性因子
|
||
"judgment": str, # "auto" / "review" / "manual" / "impossible"
|
||
"needs_review": bool,
|
||
}
|
||
"""
|
||
```
|
||
|
||
### 4.2 因子定义
|
||
|
||
```
|
||
基础确信度:
|
||
L1 关键字规则对应的基准确信度 (0.70~0.99)
|
||
DB操作=0.95, SORT=0.95, CALL=0.90, 编辑输出=0.80, ...
|
||
|
||
上下文因子:
|
||
关键字匹配数 ≥ 3 → 1.0
|
||
关键字匹配数 = 2 → 0.95
|
||
关键字匹配数 = 1 → 0.90
|
||
需要上下文确认 → 0.50
|
||
|
||
一致性因子:
|
||
无矛盾 → 1.0
|
||
有矛盾已解决 → 0.90
|
||
有矛盾未解决 → 0.80
|
||
多重矛盾 (≥3) → 0.50
|
||
|
||
结构一致性因子:
|
||
结构完全匹配 (5/5 特征一致) → 1.0
|
||
部分一致 (3-4/5) → 0.7
|
||
少量一致 (1-2/5) → 0.5
|
||
无法确定 → 0.3
|
||
|
||
综合判定:
|
||
≥ 90% → 自动判定 ("auto")
|
||
70-89% → 自动判定 + 建议 Review ("review")
|
||
50-69% → Agent 提案 + 人工确认 ("manual")
|
||
< 50% → 判定不可,全部人工 ("impossible")
|
||
```
|
||
|
||
### 4.3 接口变更
|
||
|
||
```python
|
||
# hina/__init__.py — __all__ 追加
|
||
"compute_confidence_v2", # 四因子确信度计算
|
||
"compute_confidence", # 已有函数保持不动(旧版调用者不受影响)
|
||
```
|
||
|
||
### 4.4 质量门禁公式更新(gcov 集成)
|
||
|
||
Phase 0.6 完成后,`hina/gate.py` 的评分公式改为双模式:
|
||
|
||
```
|
||
当前(gcov 未启用):
|
||
quality_score = branch_rate×0.5 + paragraph_rate×0.5 + confidence×0.4
|
||
|
||
新增 quality_score_v2(gcov 启用时):
|
||
quality_score_v2 = static_cov×0.3 + gcov_cov×0.4 + confidence×0.3
|
||
```
|
||
|
||
- 静态覆盖率 30% — 快速参考,验证数据生成完整性
|
||
- gcov 动态覆盖率 **40%** — 权重最高,代表真实执行结果
|
||
- HINA 确信度 30%
|
||
|
||
**新增文件**: `coverage/compare_coverage.py` — 对比静态与 gcov 覆盖率,定位虚假覆盖
|
||
|
||
```python
|
||
def compare_coverage(program_name: str) -> dict:
|
||
"""返回 {static, dynamic, gap, misleading_branches}"""
|
||
```
|
||
|
||
---
|
||
|
||
## 5. Phase 4: 33+2 种程序类型 COBOL 测试样本
|
||
|
||
### 5.1 目录结构
|
||
|
||
```
|
||
test-data/cobol/ # 已有 HINA001~101 保留
|
||
├── HINA001.cbl # 已有
|
||
├── ...
|
||
├── HINA101.cbl # 已有
|
||
│
|
||
├── category_matching/ # 匹配系 (10种)
|
||
│ ├── MT01_1TO1.cbl
|
||
│ ├── MT02_1TON.cbl
|
||
│ ├── MT03_NTO1.cbl
|
||
│ ├── MT16_TWO_STAGE_1TO1.cbl
|
||
│ ├── MT17_TWO_STAGE_NTO1.cbl
|
||
│ ├── MT18_MN_TO_M.cbl
|
||
│ ├── MT19_MN_TO_N.cbl
|
||
│ ├── MT20_MN_TO_MXN.cbl
|
||
│ ├── MT32_MIXED_SAME_KEY.cbl
|
||
│ └── MT33_MIXED_DIFF_KEY.cbl
|
||
│
|
||
├── category_sort/ # SORT/ MERGE (2种)
|
||
│ ├── ST01_SORT.cbl
|
||
│ └── ST02_MERGE.cbl
|
||
│
|
||
├── category_division/ # 分割系 (3种)
|
||
│ ├── DV01_DIVIDE_50.cbl
|
||
│ ├── DV02_DIVIDE_25.cbl
|
||
│ └── DV03_DIVIDE_100.cbl
|
||
│
|
||
├── category_validation/ # 校验 (1种,补充)
|
||
│ ├── VL01_CHECK_WITH_DUP.cbl
|
||
│ └── VL02_CHECK_NO_DUP.cbl
|
||
│
|
||
├── category_csv/ # 文件转换 (3种)
|
||
│ ├── CV01_CSV_NO_NEWLINE.cbl
|
||
│ ├── CV02_CSV_WITH_NEWLINE.cbl
|
||
│ └── CV03_ASCII_EBCDIC.cbl
|
||
│
|
||
├── category_cics/ # online (1种)
|
||
│ └── CI01_CICS.cbl
|
||
│
|
||
└── category_db/ # DB操作 (1种,补充)
|
||
└── DB01_SELECT_UPDATE.cbl
|
||
```
|
||
|
||
### 5.2 样本规范
|
||
|
||
每个 COBOL 测试样本必须:
|
||
|
||
1. **可编译** — 用 `cobc -x -std=ibm-strict` 编译通过
|
||
2. **10-50 行** — 足够表达类型特征,不要过大
|
||
3. **包含关键特征** — 每种类型独有的关键字和结构模式
|
||
4. **有注释** — 开头的星号注释说明类型编号和名称
|
||
5. **HEADER 注释**:
|
||
|
||
```cobol
|
||
* ==== TYPE: MT01 マッチング(1:1) ====
|
||
* 特征: 2 输入文件 SELECT, IF KEY = 比较, 3路 IF, 无累加器
|
||
* BRANCHES: 4 (2 IFs), DECISIONS: 2
|
||
* SELECT COUNT: 2, OPEN COUNT: 2
|
||
```
|
||
|
||
### 5.3 实现顺序
|
||
|
||
按依赖关系分 3 批创建:
|
||
|
||
```
|
||
第一批 (Phase 4a): 匹配系 10 种 + SORT/MERGE 2 种
|
||
依赖: 这 12 个样本是 Phase 7-8 测试的基础
|
||
|
||
第二批 (Phase 4b): 分割系 3 种 + 校验 2 种 + 文件转换 3 种
|
||
依赖: 这 8 个样本是 Phase 7 测试的基础
|
||
|
||
第三批 (Phase 4c): CICS 1 种 + DB 1 种
|
||
依赖: 需要模拟器环境,可先做代码样本,延迟测试
|
||
```
|
||
|
||
---
|
||
|
||
## 6. Phase 5: 参数化测试数据生成引擎
|
||
|
||
### 6.1 独立模块 `parametrized/`(项目根目录)
|
||
|
||
```
|
||
项目根目录/
|
||
├── parametrized/ ← 独立!不是 cobol_testgen 的子模块
|
||
│ ├── __init__.py
|
||
│ ├── matching.py # 匹配系数据生成
|
||
│ ├── sort.py # SORT 数据生成
|
||
│ ├── division.py # 分割系数据生成
|
||
│ ├── validation.py # 校验系数据生成
|
||
│ ├── csv_conversion.py # CSV→FB 数据生成
|
||
│ └── common.py # 通用工具
|
||
|
||
依赖方向:
|
||
parametrized/ → cobol_testgen (需要 PIC 解析算边界值)
|
||
parametrized/ → data/ (构造 Field/TestCase 对象)
|
||
cobol_testgen → parametrized ❌ 禁止
|
||
```
|
||
|
||
**理由**:parametrized/ 的输入是数值参数(记录数、匹配率、不平衡比),不是 COBOL 源码。放在 cobol_testgen/ 下会使 COBOL 解析引擎依赖测试工具。独立模块保持分层干净。
|
||
|
||
### 6.2 类型专属参数化
|
||
|
||
```python
|
||
# cobol_testgen/parametrized/matching.py
|
||
|
||
def generate_matching_data(
|
||
matching_type: str, # "1:1" / "1:N" / "N:1"
|
||
record_count_r01: int,
|
||
record_count_r02: int,
|
||
key_match_ratio: float = 1.0, # 匹配率(用于剩余件测试)
|
||
imbalance_ratio: float = 1.0, # 不平衡比
|
||
) -> tuple[list[dict], list[dict]]:
|
||
"""生成匹配系测试数据。
|
||
|
||
返回:
|
||
(主文件记录列表, 从件记录列表)
|
||
文件间通过 KEY 字段关联。
|
||
"""
|
||
|
||
def generate_keybreak_data(
|
||
group_count: int, # key 组数
|
||
records_per_group: int, # 每组件数
|
||
sum_type: str = "accumulate", # "accumulate" / "aggregate" / "mark"
|
||
) -> list[dict]:
|
||
"""生成 key 切测试数据。
|
||
|
||
返回:
|
||
按 KEY 分组的数据,组间 KEY 值变化触发中断。
|
||
"""
|
||
|
||
# cobol_testgen/parametrized/division.py
|
||
|
||
def generate_division_data(
|
||
division_type: int, # 50 / 25 / 100
|
||
record_count: int, # 总件数(整数倍/余数/不足)
|
||
) -> list[list[dict]]:
|
||
"""生成分割系测试数据。
|
||
|
||
返回:
|
||
按分割文件分组的记录列表:
|
||
[[文件1的记录], [文件2的记录], ...]
|
||
文件数 = ceil(record_count / division_type)
|
||
"""
|
||
```
|
||
|
||
### 6.3 通用数据生成工具
|
||
|
||
```python
|
||
# cobol_testgen/parametrized/common.py
|
||
|
||
def generate_zero_byte_file(path: str):
|
||
"""生成 0 字节空文件(VSAM 空 cluster 或顺序 0 字节)。"""
|
||
|
||
def generate_status_35_scenario(path: str):
|
||
"""STATUS 35 场景:不生成文件,让 OPEN 找不到 DD。"""
|
||
|
||
def generate_minimal_records(fields: list[Field]) -> list[dict]:
|
||
"""各文件生成 1 条正常记录。"""
|
||
|
||
def generate_boundary_values(field: Field) -> dict:
|
||
"""从 PIC 解析 S9(7)V99 → 生成 max/min/溢出值。"""
|
||
|
||
def generate_sorted_records(fields: list[Field], record_count: int) -> list[dict]:
|
||
"""按 ASCENDING/DESCENDING KEY 生成已排序序列。"""
|
||
|
||
def generate_duplicate_keys(records: list[dict], key_field: str) -> list[dict]:
|
||
"""同键值追加 ≥2 件。"""
|
||
```
|
||
|
||
### 6.4 接口变更
|
||
|
||
```python
|
||
# cobol_testgen/__init__.py — __all__ 追加(parametrized 是独立模块,非子包)
|
||
from parametrized import (
|
||
generate_matching_data, # 匹配系数据
|
||
generate_keybreak_data, # key切数据
|
||
generate_division_data, # 分割系数据
|
||
generate_zero_byte_file, # 空文件
|
||
generate_boundary_values, # 边界值
|
||
)
|
||
```
|
||
|
||
---
|
||
|
||
## 7. Phase 6: 日文测试数据生成查找表
|
||
|
||
### 7.1 新文件 `japanese_data.py`(项目根目录,独立文件)
|
||
|
||
```python
|
||
# japanese_data.py
|
||
|
||
# ── 查找表 ──
|
||
|
||
FULLWIDTH_KATAKANA = "アイウエオカキクケコサシスセソタチツテト..."
|
||
FULLWIDTH_HIRAGANA = "あいうえおかきくけこさしすせそたちつてと..."
|
||
FULLWIDTH_DIGITS = "0123456789"
|
||
FULLWIDTH_ALPHA = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||
|
||
HALFWIDTH_KATAKANA = "アイウエオカキクケコサシスセソタチツテト..."
|
||
|
||
SJIS_5C_PROBLEM = ["ソ", "噂", "能"] # Shift-JIS 第2字节 0x5C
|
||
SJIS_7C_PROBLEM = ["本", "問"] # Shift-JIS 第2字节 0x7C
|
||
|
||
WAREKI_BOUNDARIES = [
|
||
# (元号, 西历开始年, 和历开始, 西历最后日, 和历最后日)
|
||
("令和", 2019, "R010501", None, None),
|
||
("平成", 1989, "H010108", "2019/04/30", "H310430"),
|
||
("昭和", 1926, "S611231", "1989/01/07", "S640107"),
|
||
("大正", 1912, "T011231", "1926/12/25", "T151225"),
|
||
("明治", 1868, "M451229", "1912/01/29", "M450129"),
|
||
]
|
||
|
||
# ── 生成函数 ──
|
||
|
||
def generate_fullwidth_text(field: Field) -> str:
|
||
"""PIC N 字段 → 全角文字填充。"""
|
||
|
||
def generate_halfwidth_katakana(field: Field) -> str:
|
||
"""PIC X 字段 → 半角假名填充。"""
|
||
|
||
def generate_sjis_5c_problem(field: Field) -> str:
|
||
"""生成含 5C 问题文字的字符串。"""
|
||
|
||
def generate_sjis_7c_problem(field: Field) -> str:
|
||
"""生成含 7C 问题文字的字符串。"""
|
||
|
||
def generate_wareki_date(wareki_type: str) -> str:
|
||
"""生成和历日期字符串。"""
|
||
|
||
def generate_wareki_boundary(era: str) -> tuple[str, str]:
|
||
"""生成指定元号的边界日期对(末日 → 初日)。"""
|
||
|
||
def generate_encoding_test_data(
|
||
from_encoding: str,
|
||
to_encoding: str,
|
||
) -> tuple[bytes, bytes]:
|
||
"""生成编码转换测试数据(EBCDIC→SJIS→UTF-8 三段)。"""
|
||
|
||
def select_data_type(field: Field) -> str:
|
||
"""选择数据类型: PIC N → 日文 / PIC 9 → 数值 / PIC X → 半角"""
|
||
```
|
||
|
||
### 7.2 接口变更
|
||
|
||
```python
|
||
# cobol_testgen/__init__.py — __all__ 追加
|
||
"generate_fullwidth_text",
|
||
"generate_halfwidth_katakana",
|
||
"generate_wareki_date",
|
||
```
|
||
|
||
---
|
||
|
||
## 8. Phase 7-10: 类型别测试套件
|
||
|
||
### 8.1 测试文件清单
|
||
|
||
```
|
||
tests/
|
||
├── parametrized/
|
||
│ ├── test_matching.py # 匹配系 ~15 测试 (Phase 7)
|
||
│ ├── test_division.py # 分割系 ~9 测试 (Phase 7)
|
||
│ ├── test_csv_conversion.py # 文件转换 ~8 测试 (Phase 7)
|
||
│ ├── test_sort_merge.py # SORT/MERGE ~16 测试 (Phase 8)
|
||
│ ├── test_call_search.py # CALL/SEARCH ~20 测试 (Phase 8)
|
||
│ ├── test_crosscutting.py # 横跨功能 ~70 测试 (Phase 9)
|
||
│ └── test_japanese.py # 日文处理 ~31 测试 (Phase 10)
|
||
```
|
||
|
||
### 8.2 测试模板
|
||
|
||
```python
|
||
# tests/parametrized/test_matching.py
|
||
"""匹配系深度测试 — 基于 cobol-test-benchmark.md Type 01-03, 16-20, 32-33"""
|
||
|
||
import pytest
|
||
from cobol_testgen.parametrized import generate_matching_data
|
||
|
||
@pytest.mark.parametrize("r01,r02,match_ratio", [
|
||
(10, 10, 1.0), # MT-N001: 1:1 完全匹配
|
||
(1, 100, 0.0), # MT-N009: 1:N 极端不平衡
|
||
(100, 1, 0.0), # MT-N010: N:1 极端不平衡
|
||
])
|
||
def test_matching_basic(r01, r02, match_ratio):
|
||
"""MT-N001~003: 1:1 / 1:N / N:1 基本匹配"""
|
||
main_recs, sub_recs = generate_matching_data(
|
||
matching_type="1:1",
|
||
record_count_r01=r01,
|
||
record_count_r02=r02,
|
||
key_match_ratio=match_ratio,
|
||
)
|
||
assert len(main_recs) == r01
|
||
assert len(sub_recs) == r02
|
||
```
|
||
|
||
### 8.3 Phase 7 测试矩阵
|
||
|
||
| 测试文件 | 覆盖内容 | 测试项数 | 对应文档 |
|
||
|:---------|:---------|:--------:|:---------|
|
||
| `test_matching.py` | 1:1/1:N/N:1 + 不平衡 + 键重复 + 未排序 + 高级匹配 | 20 | MT-N001~012, AM-N001~008 |
|
||
| `test_division.py` | 50/25/100 分割 + 余数 + 不足 + OPEN失败 + 命名 | 9 | S-N001~007, S-A001~002 |
|
||
| `test_csv_conversion.py` | 无换行/有换行/引用符/空項目/超长 | 8 | CF-N001~006, CF-A001~002 |
|
||
|
||
### 8.4 Phase 8 测试矩阵
|
||
|
||
| 测试文件 | 覆盖内容 | 测试项数 | 对应文档 |
|
||
|:---------|:---------|:--------:|:---------|
|
||
| `test_sort_merge.py` | SORT升/降/多键/稳定/INPUT/OUTPUT PROCESS + MERGE | 16 | SR-N001~010, MR-N001~003 |
|
||
| `test_call_search.py` | CALL字面量/动态/USING/IS INITIAL/嵌套 + SEARCH ALL | 20 | C-N001~009, T-N001~007 |
|
||
|
||
### 8.5 Phase 9 测试矩阵 (横跨功能)
|
||
|
||
| 测试文件 | 覆盖内容 | 测试项数 | 对应文档 |
|
||
|:---------|:---------|:--------:|:---------|
|
||
| `test_crosscutting.py` | 可变长入出力(11) + 循环处理(10) + 数值精度(12) + 日期(18) + 排他(4) + RERUN(4) + 性能(4) | 63 | VL/LP/NP/D/EX/RR/PV |
|
||
|
||
### 8.6 Phase 10 测试矩阵 (日文)
|
||
|
||
| 测试文件 | 覆盖内容 | 测试项数 | 对应文档 |
|
||
|:---------|:---------|:--------:|:---------|
|
||
| `test_japanese.py` | PIC N全角(5) + 半角假名(5) + 外字(6) + 5C/7C(4) + 编码转换(8) + 全角空格(3) | 31 | J-N/K/G/D/X/S |
|
||
|
||
---
|
||
|
||
## 9. Phase 11: 完整类型判定管道
|
||
|
||
### 9.1 新模块 `hina/pipeline/`
|
||
|
||
```
|
||
hina/
|
||
├── rule_engine/ # 混淆组规则 (P2)
|
||
├── confidence.py # 确信度计算 (P3)
|
||
├── pipeline/ # 完整类型判定管道 (合并自 classification_pipeline/)
|
||
│ ├── __init__.py
|
||
│ └── pipeline.py # 管道编排
|
||
```
|
||
|
||
### 9.2 管道流程
|
||
|
||
```python
|
||
# hina/pipeline/pipeline.py
|
||
|
||
def classify_program(cobol_source: str) -> dict:
|
||
"""完整程序类型判定管道。
|
||
|
||
流程:
|
||
1. 并行执行:
|
||
a. 关键字识别 (detect_keyword) — 11 类 L1 关键字
|
||
b. 结构提取 (extract_structure) — 全部特征
|
||
|
||
2. 关键字确信度 ≥ 90% → 直接输出类型
|
||
(DB操作/SORT/MERGE/online 等高确信度独占类型)
|
||
|
||
3. 关键字 50-89% → 进入混淆组判定
|
||
a. 结构解析 (PERFORM模式/主循环/IF分支)
|
||
b. 8 混淆组规则引擎
|
||
c. 4 因子确信度计算
|
||
d. 矛盾检测 → 有矛盾则回溯
|
||
|
||
4. 关键字 < 50% → Agent 辅助判定
|
||
a. classify_with_llm() 调用
|
||
b. LLM 返回建议类型
|
||
c. 规则引擎验证 LLM 结果
|
||
|
||
5. 输出最终判定 JSON
|
||
"""
|
||
```
|
||
|
||
### 9.3 输出格式
|
||
|
||
```python
|
||
{
|
||
"program_name": "HINA005",
|
||
"category": "condition_heavy", # 混淆组
|
||
"subtype": "simple_if", # 具体类型
|
||
"type_code": "05", # 33+2 中的编号
|
||
"method": "keyword", # keyword / rule_engine / agent
|
||
|
||
# ── 确信度详情 ──
|
||
"confidence": 0.92,
|
||
"confidence_detail": {
|
||
"base": 0.95,
|
||
"context_factor": 1.0,
|
||
"consistency_factor": 0.9,
|
||
"structure_factor": 1.0,
|
||
},
|
||
|
||
# ── 判定依据 ──
|
||
"evidence": [
|
||
"EXEC SQL → DB操作 (keyword, 95%)",
|
||
"SELECT count=1, OPEN count=1",
|
||
"IF branches=2, decisions=1",
|
||
"No contradictions detected",
|
||
],
|
||
|
||
# ── 是否需要 Review ──
|
||
"needs_review": False,
|
||
|
||
# ── 测试策略建议 ──
|
||
"testing_strategy": {
|
||
"required_tests": 5,
|
||
"coverage_target": "branch",
|
||
"supplement_strategy": "incremental",
|
||
},
|
||
}
|
||
```
|
||
|
||
### 9.4 集成到 orchestrator
|
||
|
||
```python
|
||
# orchestrator.py — 替换现有的 HINA 分类步骤
|
||
|
||
def run_pipeline(cfg: Config, ...) -> VerificationRun:
|
||
# ... 现有代码 ...
|
||
|
||
# ── 类型判定(替换现有 HINA 步骤) ──
|
||
from hina/pipeline import classify_program
|
||
classification = classify_program(cobol_src_text)
|
||
|
||
vr.hina_type = classification["category"]
|
||
vr.hina_confidence = classification["confidence"]
|
||
vr.debug["classification"] = classification
|
||
|
||
# 如果确信度 < 50%,标记为人工处理
|
||
if classification["confidence"] < 0.5 and classification["needs_review"]:
|
||
vr.quality_warn = f"类型判定确信度过低({classification['confidence']:.0%}),建议人工确认"
|
||
|
||
# ... 后续代码不变 ...
|
||
```
|
||
|
||
---
|
||
|
||
## 10. Phase 12: 文档更新
|
||
|
||
### 10.1 更新文件
|
||
|
||
| 文件 | 更新内容 |
|
||
|:-----|:---------|
|
||
| `docs/module-interfaces.md` | 追加 hina/pipeline 模块接口;追加 parametrized 子模块接口;更新 hina 模块接口(rule_engine, confidence_v2) |
|
||
| `docs/test-plan.md` → v3.0 | 追加 33+2 程序类型覆盖行;追加类型别测试矩阵;追加横跨功能测试行;追加日文测试行;更新总测试数预期(412 → 600+) |
|
||
| `docs/cobol-coverage-matrix.md` | 追加程序类型覆盖行;追加测试基准覆盖行;更新覆盖率目标 |
|
||
|
||
### 10.2 测试计划 v3.0 更新内容
|
||
|
||
```markdown
|
||
## 测试预期(更新版)
|
||
|
||
| 维度 | v2.0 | v3.0 追加 | v3.0 总计 |
|
||
|:-----|:----:|:---------:|:---------:|
|
||
| L0 单元测试 | 280 | +50 (参数化引擎) | 330 |
|
||
| L1 类型测试 | 0 | +80 (Phase 7-8) | 80 |
|
||
| 横跨功能测试 | 0 | +70 (Phase 9) | 70 |
|
||
| 日文测试 | 0 | +31 (Phase 10) | 31 |
|
||
| 非功能测试 | 6 | +10 | 16 |
|
||
| 已有回归 | 112 | — | 112 |
|
||
| **总计** | **412** | **+241** | **~653** |
|
||
```
|
||
|
||
---
|
||
|
||
## 11. 依赖关系与分工矩阵
|
||
|
||
### 11.1 Phase 依赖图
|
||
|
||
```
|
||
Phase 1 (特征提取) ──→ Phase 2 (规则引擎) ──→ Phase 3 (确信度)
|
||
│ │ │
|
||
│ └────────┬───────────────┘
|
||
│ │
|
||
│ ▼
|
||
│ Phase 11 (hina/pipeline)
|
||
│ │
|
||
▼ ▼
|
||
Phase 5 (parametrized/) Phase 4 (COBOL样本)
|
||
│ │
|
||
└────────┬──────────────────┘
|
||
│
|
||
▼
|
||
Phase 7-10 (测试套件)
|
||
│
|
||
▼
|
||
Phase 12 (文档)
|
||
```
|
||
|
||
### 11.2 并行执行阶段
|
||
|
||
```
|
||
可以完全并行:
|
||
Phase 1 (A) + Phase 4 (C) + Phase 5 (A) + Phase 6 (B)
|
||
Phase 2 (D) + Phase 4b (C)
|
||
Phase 7-8 (F/G) + Phase 9 (F/G) + Phase 10 (B)
|
||
测试执行阶段 (所有人可并行写自己的测试)
|
||
|
||
需要串行:
|
||
Phase 1 → Phase 2 → Phase 3 → Phase 11 (D 负责全链路)
|
||
Phase 4 → Phase 7-8 (需要样本才能测试)
|
||
Phase 5 → Phase 7-10 (需要参数化引擎才能生成测试数据)
|
||
```
|
||
|
||
### 11.3 分工矩阵
|
||
|
||
| 开发者 | Phase | 模块 | 工作量 |
|
||
|:-------|:------|:-----|:-------|
|
||
| **A** | 1, 5 | cobol_testgen 扩展 + parametrized | 3 天 |
|
||
| **B** | 6, 10, 12 | japanese_data + 日文测试 + 文档 | 2 天 |
|
||
| **C** | 4, 7 | 33+2 COBOL 样本 + 匹配/分割测试 | 3 天 |
|
||
| **D** | 2, 3, 11 | rule_engine + confidence + pipeline | 4 天 |
|
||
| **E** | 6, 10 | japanese_data + 日文测试、LLM 提示词优化 | 2 天 |
|
||
| **F** | 8, 9 | SORT/MERGE/CALL/SEARCH + 横跨功能 | 3 天 |
|
||
| **G** | 0.6, 8 | gcov 基础设施 + SORT/MERGE/SEARCH 测试 | 3 天 |
|
||
| **H** | 4c, 11 集成 | CICS/DB 样本 + orchestrator 集成 | 2 天 |
|
||
|
||
### 11.4 总工时估算
|
||
|
||
| Phase | 内容 | 人日 |
|
||
|:------|:-----|:----:|
|
||
| P1 | extract_structure 扩展 | 1.5 |
|
||
| P2 | 混淆组规则引擎 | 2.0 |
|
||
| P3 | 确信度 4 因子 | 1.0 |
|
||
| P4 | 33+2 COBOL 样本 | 2.0 |
|
||
| P5 | 参数化数据生成 | 2.0 |
|
||
| P6 | 日文数据生成 | 1.0 |
|
||
| P7 | 匹配/分割/CSV 测试 | 1.5 |
|
||
| P8 | SORT/MERGE/CALL/SEARCH 测试 | 1.5 |
|
||
| P9 | 横跨功能测试 | 2.5 |
|
||
| P10 | 日文测试 | 1.5 |
|
||
| P11 | 类型判定管道 | 2.0 |
|
||
| P12 | 文档 | 1.0 |
|
||
| | **总计** | **~19.5 人日** |
|
||
|
||
---
|
||
|
||
## 12. 接口变更一览
|
||
|
||
### 12.1 向后兼容(现有代码不受影响)
|
||
|
||
| 变更 | 类型 | 说明 |
|
||
|:-----|:-----|:------|
|
||
| `extract_structure()` 返回追加字段 | ✅ 兼容 | 现有调用用 `dict.get()`,新字段不出现时返回 None |
|
||
| `compute_confidence()` 保留 | ✅ 兼容 | 新增 `compute_confidence_v2()` 并行存在 |
|
||
| `orchestrator.py` 导入路径修改 | ✅ 兼容 | 已改为模块顶层导入 |
|
||
| `__init__.py` 加 `__all__` | ✅ 兼容 | 只是显式声明已有接口 |
|
||
|
||
### 12.2 非兼容(需同步更新调用者)
|
||
|
||
| 变更 | 类型 | 如何处理 |
|
||
|:-----|:-----|:---------|
|
||
| `hina/__init__.py` 新增 `__all__` | ⚠️ 通知 | 仅影响 `from hina import *` 用户(无此类代码)|
|
||
| `cobol_testgen/__init__.py` 新增 `__all__` | ⚠️ 通知 | 仅影响 `from cobol_testgen import *` 用户(无此类代码)|
|
||
| `orchestrator.py` 导入从 `from x.y import z` 改为 `from x import z` | ⚠️ 通知 | 已在本次修改中同步更新 |
|
||
|
||
### 12.3 新增公开 API 汇总
|
||
|
||
```python
|
||
# parametrized/ __all__(新增独立模块):
|
||
"generate_matching_data" # Phase 5
|
||
"generate_keybreak_data" # Phase 5
|
||
"generate_division_data" # Phase 5
|
||
"generate_boundary_values" # Phase 5
|
||
|
||
# japanese_data.py(新增独立文件):
|
||
from japanese_data import generate_fullwidth_text, generate_halfwidth_katakana, generate_wareki_date
|
||
|
||
# hina __all__ 追加:
|
||
"resolve_confusion_pair" # Phase 2
|
||
"detect_contradictions" # Phase 2
|
||
"BacktrackResolver" # Phase 2
|
||
"compute_confidence_v2" # Phase 3
|
||
"classify_program" # Phase 11 — hina.pipeline.pipeline.classify_program
|
||
```
|
||
|
||
---
|
||
|
||
## 附录:快速开始指南
|
||
|
||
### 对于 A(cobol_testgen 扩展)
|
||
|
||
```bash
|
||
# 1. 扩展 read.py — 添加 SELECT organization 和 OPEN 模式检测
|
||
# 2. 扩展 core.py — 添加 DIVIDE/INSPECT/STRING 检测、PERFORM 分类、IF 统计、变量模式、主循环
|
||
# 3. 更新 __init__.py __all__
|
||
```
|
||
|
||
### 对于 D(规则引擎 + 确信度 + 管道)
|
||
|
||
```bash
|
||
# 1. 创建 hina/rule_engine/ — 8 混淆组规则(独立命名函数)
|
||
# 2. 创建 hina/confidence.py — 四因子计算
|
||
# 3. 创建 hina/pipeline/ — 完整管道编排
|
||
# 4. 修改 orchestrator.py — 替换 HINA 分类步骤
|
||
```
|
||
|
||
### 对于 C(COBOL 样本 + 测试)
|
||
|
||
```bash
|
||
# 1. 创建 test-data/cobol/category_matching/ — 10 个匹配系样本
|
||
# 2. 创建 test-data/cobol/category_sort/ — SORT/MERGE 样本
|
||
# 3. 创建 tests/parametrized/test_matching.py
|
||
# 4. 驱动测试: python -m pytest tests/parametrized/test_matching.py
|
||
```
|
||
|
||
### 对于 B(日文处理 + 文档)
|
||
|
||
```bash
|
||
# 1. 创建 japanese_data.py(项目根目录)— 查找表 + 生成函数
|
||
# 2. 创建 tests/parametrized/test_japanese.py
|
||
# 3. 更新 docs/module-interfaces.md
|
||
# 4. 更新 docs/test-plan.md → v3.0
|
||
```
|
||
|
||
---
|
||
|
||
## 13. COBOL 覆盖率测试体系 — 与各 Phase 的集成
|
||
|
||
> 覆盖率测试不是独立章节,而是贯穿多个 Phase 的基础设施。
|
||
> 已在 Phase 1.1(Phase 0.6)中新增 gcov 基础设施。
|
||
> 以下列出覆盖率的其他部分的分布位置:
|
||
|
||
| 覆盖率内容 | 所在 Phase | 说明 |
|
||
|:-----------|:----------|:------|
|
||
| gcov 基础设施(环境验证 + collect_gcov 修复 + Config 字段 + 全链路测试)| **Phase 0.6** (1.1节) | F 负责,3h |
|
||
| 质量门禁公式更新(quality_score_v2)+ 静态 vs 动态对比报告 | **Phase 3** (4.4节) | 新增 gcov 权重 40% |
|
||
| 各类型 gcov 验证测试(约 15 个) | **Phase 7-10** | 每个类型群至少 1 条 gcov 测试 |
|
||
| orchestrator gcov_enabled 集成 | **Phase 11** (9.5节) | 连接 Config → orchestrator → gate.py |
|
||
|
||
### 13.1 覆盖率目标
|
||
|
||
**模块覆盖率(pytest --cov):**
|
||
|
||
| 模块 | 目标 |
|
||
|:-----|:----:|
|
||
| cobol_testgen/* | ≥ 90% |
|
||
| hina/* | ≥ 85% |
|
||
| comparator/* | ≥ 85% |
|
||
| runners/* | ≥ 70% |
|
||
| orchestrator.py | ≥ 85% |
|
||
|
||
**程序覆盖率(gcov 验证,各类型群最低 line_rate):**
|
||
|
||
| 类型群 | 门槛 | 理由 |
|
||
|:-------|:----:|:------|
|
||
| 条件分支(IF/EVALUATE) | ≥ 70% | 分支密集,应高覆盖 |
|
||
| 匹配系 | ≥ 60% | 至少覆盖关键 IF 分支 |
|
||
| SEARCH ALL | ≥ 60% | 命中/未命中均需覆盖 |
|
||
| CALL | ≥ 60% | 主程序 + 子程序 |
|
||
| SORT | ≥ 50% | 大量 I/O,代码行不多 |
|
||
| 分割系 | ≥ 50% | 文件操作密集 |
|
||
| 编辑输出 | ≥ 50% | WRITE 语句需要实际输出 |
|
||
|
||
**静态 vs 动态差距**: 同类差距 ≤ 30%(超过说明静态分析不可靠)
|
||
|
||
> 门槛说明:基于 HINA 现有 10 个程序的 gcov 预测数据。
|
||
> 纯逻辑程序(IF/EVALUATE)可达 70%+,I/O 密集程序(SORT/分割)约 50%。
|
||
> 上线后根据实测数据调整。
|
||
|
||
---
|
||
|
||
|
||
## 14. 架构审核决议汇总
|
||
|
||
> 来源: `/plan-eng-review` | 日期: 2026-06-19
|
||
|
||
|
||
### 14.1 审核决策
|
||
|
||
| 分类 | 决策 | 方案 | 结果 |
|
||
|:-----|:-----|:-----|:-----|
|
||
| 架构 | classification_pipeline/ 归属 | 合并到 hina/pipeline/ | ✅ 采纳 |
|
||
| 架构 | parametrized/ 归属 | 独立模块(项目根目录) | ✅ 采纳 |
|
||
| 架构 | japanese_data.py 归属 | 独立文件(项目根目录) | ✅ 采纳 |
|
||
| 架构 | orchestrator 过渡 | 并行开发,一次性替换 | ✅ 采纳 |
|
||
| 架构 | COBOL 样本兼容 | 不可编译类型用注释模拟关键字 | ✅ 采纳 |
|
||
| 代码质量 | 矛盾判定规则 | 独立命名函数取代 lambda | ✅ 采纳 |
|
||
| 测试 | 新模块单元测试 | 每个 Phase 包含自身测试 | ✅ 采纳 |
|
||
| 性能 | 回溯机制 | 加 30s 超时降级 | ✅ 采纳 |
|
||
|
||
### 14.2 NOT in Scope
|
||
|
||
| 项目 | 理由 |
|
||
|:-----|:------|
|
||
| CICS/DB 真实环境集成测试 | 需要大型机模拟器 |
|
||
| PySpark 完整管道验证 | Java 兼容性问题 |
|
||
| 多语言国际化(除日文外) | 33+2 类型未要求 |
|
||
| CI/CD 性能基准自动化 | 不属于 12 个 Phase |
|
||
|
||
### 14.3 实现任务
|
||
|
||
- [ ] **T1 (P1, human: ~2h)** — 扩展 extract_structure 新增 8 类特征
|
||
- [ ] **T2 (P2, human: ~3h)** — hina/rule_engine/ 8 混淆组(独立函数)
|
||
- [ ] **T3 (P3, human: ~1.5h)** — hina/confidence.py 4 因子确信度
|
||
- [ ] **T4 (P4, human: ~2.5h)** — test-data/cobol/ 33+2 样本
|
||
- [ ] **T5 (P5, human: ~2.5h)** — parametrized/ 数据生成引擎
|
||
- [ ] **T6 (P6, human: ~1h)** — japanese_data.py 日文查找表
|
||
- [ ] **T7 (P7-10, human: ~6h)** — 类型别测试套件 (~241 测试)
|
||
- [ ] **T8 (P11, human: ~2.5h)** — hina/pipeline/ 完整管道 + orchestrator 集成
|
||
- [ ] **T9 (P12, human: ~1h)** — 文档更新
|
||
|
||
### 14.4 总测试预期
|
||
|
||
```
|
||
现有: 428 测试
|
||
新增: ~60 (新模块自身单元测试)
|
||
新增: ~241 (类型别测试套件 P7-10)
|
||
总计: ~729 测试
|
||
```
|
||
|
||
### 14.5 并行策略
|
||
|
||
```
|
||
Lane A: P1 (cobol_testgen 扩展) → 独立
|
||
Lane B: P4 (COBOL 样本) → 独立,需先完成
|
||
Lane C: P5 (parametrized/) → 需要 cobol_testgen 的 PIC 解析
|
||
Lane D: P6 (japanese_data) → 独立
|
||
Lane E: P2 (rule_engine) → 需要 P1 的特征
|
||
└── P3 (confidence) → 需要 P2
|
||
└── P11 (pipeline) → 需要 P2+P3
|
||
Lane F: P7-10 (测试套件) → 需要 P4+P5+P6
|
||
└── P12 (文档) → 最后
|
||
|
||
启动顺序:
|
||
第 1 批 (并行): Lane A + Lane B + Lane D
|
||
第 2 批: Lane C (P1 完成 + 已有 data/) + Lane E (P1 完成)
|
||
第 3 批: Lane F (P4+P5+P6 完成)
|
||
最后: P12
|
||
```
|
||
|
||
---
|
||
|
||
## 15. 验收标准
|
||
|
||
> 所有 Phase 完成后,用以下标准验证是否达标。
|
||
|
||
|
||
| 编号 | 验收项 | 验证方法 | 关联 Phase |
|
||
|:-----|:-------|:---------|:-----------|
|
||
|
||
### 15.1 功能验收
|
||
|
||
| A01 | extract_structure() 返回包含全部 8 个新增字段 | pytest tests/cobol_testgen/ 全部通过 | P1 |
|
||
| A02 | 8 个混淆组规则各有 ≥ 2 个测试 | pytest tests/hina/ 覆盖 | P2 |
|
||
| A03 | 4 因子确信度的 4 个判定阈值各 ≥ 1 个测试 | pytest tests/hina/ 覆盖 | P3 |
|
||
| A04 | 33+2 个 COBOL 样本全部在 test-data/cobol/ 下 | ls test-data/cobol/category_*/ 共 35+ 文件 | P4 |
|
||
| A05 | parametrized/ 各生成函数有测试覆盖主要参数组合 | pytest tests/parametrized/ 全部通过 | P5 |
|
||
| A06 | japanese_data.py 生成函数返回正确格式 | pytest tests/parametrized/test_japanese.py | P6 |
|
||
| A07 | 类型测试套件 ≥ 200 个测试 | pytest --collect-only | P7-10 |
|
||
| A08 | hina/pipeline/ 的 3 条判定路径各有测试覆盖 | pytest tests/hina/ 模拟三种路径 | P11 |
|
||
| A09 | gcov 全链路验证测试通过 | pytest tests/test_gcov_basic.py | P0.6 |
|
||
| A10 | 质量门禁 gcov 模式下 quality_score_v2 工作 | pytest tests/hina/test_gate.py 覆盖 | P3 |
|
||
|
||
### 15.2 覆盖率验收
|
||
|
||
| 验收项 | 目标 | 验证方法 |
|
||
|:-------|:----:|:---------|
|
||
| 模块覆盖率(pytest --cov)| ≥ 68% | pytest --cov=. |
|
||
| 核心管道覆盖率 | ≥ 85% | pytest --cov=cobol_testgen --cov=hina --cov=orchestrator |
|
||
| Python 测试总数 | ≥ 650 | pytest --collect-only -q |
|
||
| gcov 动态验证(可编译类型)| line_rate ≥ 50% | pytest tests/test_gcov_basic.py |
|
||
|
||
### 15.3 回归验收
|
||
|
||
- [ ] 所有现有测试通过: pytest tests/ --ignore=e2e/ -q → 0 failed
|
||
- [ ] 新增测试不降低现有覆盖率
|
||
- [ ] 所有 __all__ 中列出的公开函数有类型注解
|
||
|
||
---
|
||
|
||
---
|
||
|