feat: DB管线补全 + 新增orchestrator_db/program_schema/to_sql + 清理临时脚本

This commit is contained in:
hangshuo652
2026-07-11 14:55:52 +08:00
parent 40e8a50ab4
commit af37e33b98
32 changed files with 3232 additions and 255 deletions
+468
View File
@@ -0,0 +1,468 @@
# COBOL→Java/Spark 迁移验证平台 V3 — 系统认知分析报告
> 生成日期: 2026-07-11
> 范围: `cobol-java-v3/` 全仓库
---
## 一、核心架构
**项目职责**:解析 COBOL 程序语义结构 → 自动生成覆盖全部路径的测试数据 → 分别在 COBOL 和 Java/Spark 上执行 → 对比两者输出以验证迁移正确性。
两条独立管线:
| 管线 | 入口 | 目标程序类型 |
|------|------|-------------|
| **Native 管线** | `orchestrator.py:run_pipeline()` | 非 DB 批处理 COBOL |
| **DB 管线** | `orchestrator_db.py:GixsqlOrchestrator.run_all()` | 含 EXEC SQL 的 DB COBOL |
---
## 二、Native 管线 (`orchestrator.py:run_pipeline`)
### 职责概述
接收 copybook/COBOL 源码/Java 源码/字段映射,走完整对比流程:LLM 解析结构 → cobol_testgen 生成数据 → COBOL 编译运行 → Java 编译运行 → 二进制输出对齐 → 字段级对比 → 生成 HTML/JSON 报告。
### 内部结构
```
run_pipeline()
├── Agent1Parser(llm).parse(copybook) → FieldTreeCOPYBOOK结构)
├── extract_structure(cobol_src) → 控制流树
├── generate_data() → 基础测试数据 (list[dict])
├── classify_program(cobol_src, llm) → HINA 类型判定
├── strategy_supplement() → 策略 Agent 追加测试
├── gate_check() + incremental_supplement() → 质量门禁循环(最多4次)
├── Agent2Data(llm).design(tree) → 数据设计
├── DataWriter → CobolRunner → NativeJavaRunner / SparkJavaRunner
├── CobolBinaryReader → align_records → compare_field
├── Agent3Diagnostic(llm) → 差异诊断
└── ReportGenerator → JSON + HTML + machine JSON
```
### 数据流
```
输入: copybook.cpy + program.cbl + java/ + mapping.yaml
↓ Agent1Parser (LLM)
FieldTree
↓ cobol_testgen.extract_structure + generate_data
测试记录 list[dict]
↓ HINA 类型判定 + 策略补充 + 质量门禁循环
增强测试数据
↓ DataWriter → CobolRunner (cobc) → COBOL二进制输出
↓ DataWriter → NativeJavaRunner (java -jar) / SparkJavaRunner → Java输出
↓ CobolBinaryReader + align_records + compare_field
字段级对比结果 FieldResult[]
↓ ReportGenerator
输出: reports/{program}/{timestamp}/result.json + report.html + machine.json
```
### 依赖关系
- `agents/`: LLMClient, Agent1Parser, Agent2Data, Agent3Diagnostic
- `cobol_testgen/`: extract_structure, generate_data, incremental_supplement, check_coverage
- `runners/`: CobolRunner, NativeJavaRunner, SparkJavaRunner, DataWriter
- `comparator/`: align_records, compare_field, CobolBinaryReader
- `data/`: FieldTree, TestSuite, TestCase, VerificationRun, FieldResult
- `config/`: Config, MappingConfig
- `storage/`: TestDataBundle
- `report/`: ReportGenerator
- `hina/`: classify_program, gate_check, supplement
- 外部:httpx (LLM), cobc (COBOL编译), Java/Maven, Spark (可选)
### 关键注意事项
- `LLM 成本上限`: max_llm_cost=0.50,超限直接返回 BLOCKED (exit_code=3)
- `质量门禁`: quality_gate_mode=warn 时只记录警告,不阻塞管线
- `DRY-RUN 模式`: 只检查输入文件存在性,不执行实际管线(sys.exit(0/2)
- `Agent1Parser 返回空字段时直接 BLOCKED`
- `complete_tests 替换`: `orchestrator.py:112` 用 cobol_testgen 生成的 complete_tests 整体替换 suite.test_cases,覆盖了 Agent2Data 的设计结果
---
## 三、DB 管线 (`orchestrator_db.py:GixsqlOrchestrator`)
### 职责概述
6 步执行含 SQL 的 DB COBOL 程序:gixpp 预处理 + cobc 编译 → 测试数据生成(含 DB 初始化 + 扁平文件)→ COBOL 执行 → SQLite 中介数据提取 → Java 执行 → 验证。
### 内部结构
```
GixsqlOrchestrator
├── step1_setup_environment()
│ ├── _copy_sources_to_workdir() → 源码拷贝到ASCII-only路径
│ ├── runner.preprocess() → gixpp
│ └── runner.compile() → cobc
├── step2_generate_inputs()
│ ├── extract_structure() + generate_data()
│ ├── _init_database() + _create_tables()
│ ├── _populate_database() → SQL meta + branch paths → DB初始行
│ ├── write_all_files() → 扁平文件
│ └── write_sysin_file() → SYSIN卡片
├── step3_run_cobol()
├── step4_extract_intermediate() → SQLite → JSON中介数据
├── step5_run_java() → java -jar
├── step6_verify() → VerificationRun
├── generate_coverage_report() → gcov + 静态分支 → HTML
└── run_all(skip_steps) → Step 1→4 (skip_jvm) / 1→6
```
### 数据流
```
输入: cobol-tna-system/src/{program}.cbl + .cpy copybooks
↓ Step 1: _copy_sources_to_workdir → gixpp → cobc
可执行文件 + 预处理后源码
↓ Step 2: cobol_testgen → pipeline_bridge → to_sql
扁平文件 + DB 初始行 (SQLite)
↓ Step 3: COBOL 运行
更新后 DB + 扁平文件输出
↓ Step 4: DB → JSON 中介数据
W01 JSON
↓ Step 5: Java 运行
Java 输出文件
↓ Step 6: 验证
VerificationRun
```
### 依赖关系
- `config/program_schema.py`: 每个程序的 DB 表定义 YAMLconfig/programs/{pid}.yaml
- `cobol_testgen/`: extract_structure, generate_data, flatfile, file_io, read, gcov, coverage, design_mcdc, to_sql, core, pipeline_bridge
- `runners/gixsql_runner.py`: GixsqlCobolRunner
- `data/diff_result.py`: VerificationRun, FieldResult
- 外部:gixsql/bin/gixpp.exe(预处理),cobc(编译),Java, SQLite3
- cobol-tna-system/bin/: SUB 程序 DLL
### 关键注意事项
- `gixpp 无法处理中文路径`:所有源码拷贝到 ASCII-only %TEMP%/gixsql_build/{pid}/
- `DB 路径约定`: C:/Temp/gix/{program_id}.db,需要跟 COBOL CONNECT TO 语句的路径一致
- `R02 关联 POST-PROCESS`: Step2 中 R02APPL-ID 被强制同步为 R01APPL-ID
- `Step 5/6 默认跳过`: skip_jvm=True,只有显式设置才会执行 Java 对比
- `gcov 文件清理`: coverage 报告后删除 CWD 中的 .gcno/.gcda,但可能因 PermissionError 失败
- `性能隐患`: _populate_database 中重复解析了 DATA DIVISION 和 PROCEDURE DIVISION
---
## 四、核心引擎 (`cobol_testgen/`)
### 职责概述
COBOL 程序的全静态分析 + 测试数据生成 + 覆盖率报告。4 层架构(INPUT → CORE → CONDITION → DESIGN+ OUTPUT + COVERAGE。
### 内部结构
```
cobol_testgen/
├── __init__.py 对外API (extract_structure/generate_data/incremental_supplement) + CLI入口 main()
├── read.py INPUT层: 预处理/COPYBOOK展开/EXEC SQL剥离/DATA DIVISION解析(Lark语法 grammar.lark
├── core.py CORE层: PROCEDURE DIVISION解析 → 分支树 + 数据流追踪
├── cond.py CONDITION层: 条件表达式解析 → MC/DC枚举 → 约束合并 → satisfying_value
├── design.py DESIGN层: enum_paths + generate_records + 约束应用
├── design_mcdc.py MC/DC路径枚举(独立路径集)
├── models.py 共享数据模型(BrSeq/BrIf/BrEval/BrPerform/Assign/CondLeaf等)
├── output.py OUTPUT层: JSON输出 + 输入文件输出
├── coverage.py COVERAGE层: 决策点收集 + mark_coverage + HTML中文覆盖率报告
├── flatfile.py 扁平文件写入(FD布局分析)
├── file_io.py 输出文件读取
├── to_sql.py SQL元数据收集 + DB输入构建
├── gcov.py gcov 解析
├── pipeline_bridge.py build_branch_tree_fallbackLark解析失败时的回退)
├── grammar.lark DATA DIVISION Lark语法
├── procedure_grammar.lark PROCEDURE DIVISION Lark语法
├── procedure_parser.py Lark解析器
├── runner.py 编译+运行+对比(--run模式)
└── __main__.py CLI入口 python -m cobol_testgen
```
### 数据流
```
COBOL源码
↓ read.preprocess → resolve_copybooks → strip_exec_sql
预处理后文本
↓ read.parse_data_divisionLark grammar
FieldDef[]
↓ expand_occurs
展开下标后的字段字典
↓ core.build_branch_tree / pipeline_bridge.build_branch_tree_fallback
分支树 (BrSeq + BrIf + BrEval + BrPerform + ...) + assignments
↓ design.enum_paths / design_mcdc.enum_paths
路径约束 (path_cons, path_assign)[]
↓ cond.parse_compound_condition + mcdc_sets + satisfying_value
MC/DC 约束集
↓ design.generate_records
测试记录 list[dict]
↓ coverage.run_coverage + mark_coverage
HTML 覆盖率报告
```
### 依赖关系
- `lark>=1.1.0`: DATA DIVISION + PROCEDURE DIVISION 解析(Earley parser
- `japanese_data.py`: 日文测试数据生成函数
- 内部无额外外部依赖
### 关键注意事项
- `MC/DC compound IF 已知 BUG`: cond.py:mcdc_sets 合并同字段约束时会改变操作符/值,导致 coverage.py:_match_leaf 匹配失败
- `_MAX_PATHS=10000`: 路径截断导致 F-branch 约束丢失,靠 implied_branch 标记补偿
- `Lark grammar 限制`: grammar.lark 要求命名终端(不能内联字符串),且 Earley+dynamic lexer
- `88-level 假设`: AGENTS.md 明确要求目标程序不含 88-level VALUE 子句,88-level 解析仅为测试程序保留
- `COPYBOOK 搜索路径`: 默认 filepath.parent/../cpy,不灵活
- `OCCURS DEPENDING ON`: 被捕获但未用于实际记录生成
---
## 五、各子模块速览
### `config/` — 配置层
| 文件 | 职责 |
|------|------|
| `__init__.py` | Config dataclass,支持 aurak.toml 加载 |
| `mapping.py` | MappingConfig, FieldMapping(字段映射) |
| `program_schema.py` | ProgramSchema, TableDef, ColumnDef → 从 YAML 加载每个 DB 程序的表定义 |
| `programs/` | 6 个 KIN/ZAN 程序的 DB schema YAML |
### `agents/` — LLM 智能体
| 文件 | 职责 |
|------|------|
| `llm.py` | LLMClienthttpx + 缓存 + 重试) |
| `agent1_parser.py` | COPYBOOK → FieldTreeLLM |
| `agent2_data.py` | FieldTree → TestSuiteLLM 数据设计) |
| `agent3_diagnostic.py` | MISMATCH → 诊断建议(LLM |
### `runners/` — 编译运行
| 文件 | 职责 |
|------|------|
| `runner.py` | Runner ABC + BuildResult/RunResult |
| `cobol_runner.py` | CobolRunnercobc 编译执行) |
| `native_java_runner.py` | NativeJavaRunnermvn package + java -jar |
| `spark_java_runner.py` | SparkJavaRunnerspark-submit |
| `data_writer.py` | DataWriter(二进制/JSON 数据写入) |
| `gixsql_runner.py` | GixsqlCobolRunnergixpp + cobc |
### `comparator/` — 对比引擎
| 文件 | 职责 |
|------|------|
| `aligner.py` | align_recordsCOBOL ↔ Java 记录对齐,按 CUST-ID 匹配) |
| `field_compare.py` | compare_fielddecimal/string 容忍比较) |
| `cobol_binary_reader.py` | CobolBinaryReader(二进制输出解析) |
| `normalizer.py` | NormalizerCOMP-3/EBCDIC 解码) |
| `rounding_detect.py` | detect_rounding(舍入检测) |
### `data/` — 数据模型
| 文件 | 职责 |
|------|------|
| `field_tree.py` | Field + FieldTreeCOPYBOOK 解析结果) |
| `test_case.py` | TestCase + TestSuite + SparkConfig |
| `diff_result.py` | FieldResult + VerificationRun(管道运行结果) |
### `storage/` — 存储
| 文件 | 职责 |
|------|------|
| `store.py` | DiskCacheSHA256 key → JSON+ ReportStoreJSONL |
| `bundle.py` | TestDataBundle(测试数据目录路径管理) |
### `hina/` — 程序类型分类
| 文件 | 职责 |
|------|------|
| `classifier.py` | classify_program(关键词/规则/LLM 三路径判定) |
| `gate.py` | gate_check(质量门禁检查) |
| `strategy.py` | supplement(策略补充) |
| `confidence.py` | 置信度计算 |
| `gcov_collector.py` | gcov 数据收集 |
| `retry.py` | 重试逻辑 |
| `rule_engine/` | 规则引擎定义 |
| `pipeline/` | 子管线定义 |
### `jcl/` — JCL 处理
| 文件 | 职责 |
|------|------|
| `parser.py` | JCL 解析 |
| `executor.py` | JCL 执行 |
### `web/` — Web 界面
| 文件 | 职责 |
|------|------|
| `api.py` | FastAPI202+ polling 异步管线) |
| `worker.py` | 后台任务执行 |
### `report/`
| 文件 | 职责 |
|------|------|
| `generator.py` | ReportGeneratorJSON/HTML/机器JSON |
---
## 六、与管道无关的测试/调试脚本
以下脚本位于根目录,非生产管线代码,用于开发调试/临时验证:
### 调试 KIN08DBU 特定
| 脚本 | 用途 |
|------|------|
| `_analyze.py` | 打印 KIN08DBU 第185-260行 |
| `_analyze2.py` | 查找 KIN08DBU 的 FILE CONTROL 段落 |
| `_check_db.py` | 检查 KIN08DBU DB 运行后状态 |
| `_check_db_full.py` | 完整 DB 状态 + SQL 直接插入测试 |
| `_check_flats.py` | 检查 KIN08DBU 扁平文件生成 |
| `_check_schema.py` | 查看 SQLite 表结构 |
| `_check_sysin.py` | 检查 SYSINFILE 布局检测 |
| `_debug_sql.py` | SQL INSERT 问题调试 |
| `_debug_step1.py` | Step 1 编译问题调试 |
| `_find_exit.py` | 查找 MSG/STOP RUN/GOBACK |
| `_find_exit2.py` | 查找 EXIT/GOBACK 和段落结构 |
| `_investigate_exit.py` | 完整 3 步骤 + DB 前后状态分析 |
| `_run_k08.py` | KIN08DBU 3 步骤运行 + SYSIN |
| `_run_k08_v2.py` | KIN08DBU 全 4 步骤 + 覆盖率 |
| `_test_insert.py` | 直接 SQLite INSERT 测试 |
### 通用调试
| 脚本 | 用途 |
|------|------|
| `debug_cons.py` | ZAN01CHK 约束调试(RRC 字段 <> 约束) |
| `debug_cons2.py` | ZAN01CHK 路径约束枚举调试 |
| `test_llm.py` | LLM 客户端直连测试 |
| `test_pipeline.py` | 全管线端到端测试 |
| `write_result.py` | 任务结果写入 uploads/tasks |
| `reset_task.py` | JSON 任务状态重置为 queued |
| `preprocessor.py` | 独立 COPYBOOK 展开器(非 cobol_testgen/read.py |
| `test_hello.cbl` | 最小 COBOL "HELLO WORLD" 测试程序 |
### 工具库(可被生产代码引用)
| 脚本 | 用途 |
|------|------|
| `japanese_data.py` | 日文测试数据生成工具(被 cobol_testgen 正式 import,属于半生产代码) |
---
## 七、跨文件关键依赖关系图
```
main.py
└─→ orchestrator.py:run_pipeline()
├─→ agents/ (LLMClient, Agent1-3)
├─→ cobol_testgen/ (extract_structure, generate_data)
│ ├─→ read.py → grammar.lark (Lark)
│ ├─→ models.py
│ ├─→ core.py
│ ├─→ cond.py
│ ├─→ design.py + design_mcdc.py
│ ├─→ coverage.py
│ └─→ japanese_data.py
├─→ hina/ (classify, gate, strategy)
├─→ runners/ (CobolRunner, NativeJavaRunner)
├─→ comparator/ (align_records, compare_field, CobolBinaryReader)
├─→ data/ (VerificationRun, FieldResult, TestSuite)
├─→ storage/ (TestDataBundle)
└─→ report/ (ReportGenerator)
orchestrator_db.py:GixsqlOrchestrator
├─→ config/program_schema.py (ProgramSchema)
├─→ cobol_testgen/ (extract_structure, generate_data, flatfile, to_sql, coverage, gcov, pipeline_bridge)
├─→ runners/gixsql_runner.py
└─→ data/diff_result.py
web/api.py
└─→ orchestrator.py:run_pipeline()
```
---
## 八、关键注意事项总览
### 架构层
1. **两条管线分裂**: orchestrator.py (Native) 和 orchestrator_db.py (DB) 各自独立,共用 cobol_testgen 核心但互不调用
2. **管线替换设计缺陷**: orchestrator.py:112 用 complete_tests 整体替换 suite.test_cases,覆盖了 Agent2Data 的设计
3. **DB 管线硬编码路径**: C:/Temp/gix/{pid}.db,不灵活
### 稳定性层
4. **`_MAX_PATHS=10000` 截断**: 导致 F-branch 约束丢失,implied_branch 只是标记补偿,不生成真实测试数据
5. **MC/DC 合并 BUG**: cond.py 同字段约束合并改变语义,导致覆盖率匹配失败
6. **PermissionError 静默忽略**: coverage 清理 .gcda 文件时,可能积累
### 数据层
7. **OCCURS DEPENDING ON 未使用**: 虽被解析但 generate_records 未利用
8. **88-level VALUE 假设**: 系统假设目标程序无 88-level VALUE,但解析器仍保留该能力
9. **R02 APPL-ID 强制覆盖**: orchestrator_db.py:177-179 无条件同步 R02→R01 的 APPL-ID
### 安全/错误处理层
10. **NPE 静默忽略**: orchestrator.py:178 的 except: pass 吞掉 Agent3Diagnostic 的所有异常
11. **hina 分类失败不阻塞**: orchestrator.py:63-65 仅记录警告,不影响流程
12. **LLM API KEY 硬编码**: test_llm.py:4 和 test_pipeline.py:3 包含明文 API key
---
## 九、目录结构与功能总览
```
cobol-java-v3/ # 根工程
├── main.py # CLI 入口(非 DB 管线)
├── orchestrator.py # Native 管线编排(核心)
├── orchestrator_db.py # DB 管线编排(6步)
├── pyproject.toml # 包定义 verify-cli
├── requirements.txt # httpx, pyyaml, pytest, fastapi, uvicorn
├── cobol_testgen/ # 核心引擎(4层架构)
│ ├── __init__.py # 对外API + main() CLI
│ ├── read.py # INPUT层:预处理/DATA DIVISION解析
│ ├── core.py # CORE层:PROCEDURE DIVISION解析
│ ├── cond.py # CONDITION层:条件/MCDC/约束
│ ├── design.py # DESIGN层:路径枚举/值生成
│ ├── design_mcdc.py # MC/DC路径枚举
│ ├── coverage.py # 覆盖率统计/HTML报告
│ ├── output.py # JSON/文件输出
│ ├── flatfile.py # 扁平文件写入
│ ├── file_io.py # 输出文件读取
│ ├── to_sql.py # DB输入构建
│ ├── gcov.py # gcov解析
│ ├── pipeline_bridge.py # Lark回退解析桥接
│ ├── models.py # 共享数据模型
│ ├── grammar.lark # DATA DIVISION Lark语法
│ ├── procedure_grammar.lark # PROCEDURE DIVISION Lark语法
│ ├── procedure_parser.py # PROCEDURE DIVISION Lark解析器
│ ├── runner.py # 编译运行+验证
│ └── __main__.py # CLI入口
├── agents/ # LLM智能体
├── hina/ # 程序类型分类/质量门禁
├── runners/ # 编译运行引擎
├── comparator/ # 对比引擎
├── config/ # 配置/DB schema YAML
├── data/ # 数据模型
├── storage/ # 存储/缓存
├── report/ # 报告生成
├── jcl/ # JCL处理
├── web/ # FastAPI Web界面
├── _*.py (14个) # 调试脚本(非生产代码)
├── debug_cons*.py (2个) # 约束调试
├── test_*.py (3个) # LLM/管线测试
├── write_result.py # 任务结果写入
├── reset_task.py # 任务重置
├── preprocessor.py # 独立COPYBOOK展开器
├── japanese_data.py # 日文数据生成库
├── test_hello.cbl # 最小COBOL程序
├── tests/ # pytest测试套件
├── benchmark-programs/ # 36个基准COBOL程序
├── test-data/ # 测试套件
├── cobol-tna-system/ # KIN telecom COBOL系统
├── gixsql/ # gixsql预处理工具
├── tasks/ # Web任务JSON
├── uploads/ # Web上传目录
├── reports/ # 报告输出
├── output_20260701/ # 历史输出
├── coverage/ # 覆盖率报告
├── config/programs/ # 6个DB程序schema YAML
├── logs/ # 日志
└── docs/ # 文档
```