Files
cobol-java-v3/ANALYSIS_REPORT.md
T

469 lines
20 KiB
Markdown
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.
# 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/ # 文档
```