Files
cobol-java-v3/docs/output-directory-structure.md
T
hangshuo652 bdc1584b3c feat: 修复 Java Runner command_line 参数传递 + DB-Java 比对功能
- 修复 orchestrator_db.py: Java Runner 未传递 command_line 参数导致 ABEND
- 新增 DB-Java 文件式运行 + DB 表比对功能
- 优化输出目录结构: output/<PROGRAM_ID>/cobol/
- 新增测试文件: test_java_comparison.py, test_java_e2e.py
- 更新 AI 使用日志
2026-09-09 21:35:21 +08:00

13 KiB
Raw Blame History

V3系统目录结构设计文档

一、目录结构概述

V3系统采用统一的目录结构来组织COBOL和Java的输出结果,确保所有程序的输出文件都位于同一个根目录下,便于管理和比较。

二、目录结构规范

2.1 标准目录结构

output/<PROGRAM_ID>/
├── cobol/                              # COBOL输出(所有组)
│   ├── main/                           # 单轮/默认场景
│   │   ├── input/                      # COBOL输入flat文件
│   │   ├── output/                     # COBOL输出flat文件
│   │   └── json/                       # Java验证用JSON
│   ├── run_skip/                       # 跳过场景
│   │   ├── input/
│   │   ├── output/
│   │   └── json/
│   ├── run_<scenario_id>/              # 多轮场景
│   │   ├── input/
│   │   ├── output/
│   │   └── json/
│   └── pre_src/                        # 预处理源码
├── java/                               # Java输出(所有组)
│   ├── main/                           # 对应cobol/main的Java输出
│   │   └── output/
│   ├── run_skip/                       # 对应cobol/run_skip的Java输出
│   │   └── output/
│   └── run_<scenario_id>/              # 对应cobol/run_*的Java输出
│       └── output/
├── coverage/                           # 覆盖率报告(全局)
├── logs/                               # 日志(全局)
│   ├── main.log
│   ├── run_skip.log
│   └── run_<scenario_id>.log
├── gcov/                               # gcov数据(按场景分离)
│   ├── run_main/
│   ├── run_skip/
│   └── run_<scenario_id>/
├── data/                               # SQLite数据库(按场景分离)
│   ├── kin.db                          # 单轮场景
│   └── kin_<scenario_id>.db            # 多轮场景
└── reports/                            # 测试报告
    └── <timestamp>/
        ├── result.json
        ├── report.html
        └── machine.json

2.2 目录命名规则

目录 命名规则 说明
cobol/main/ 固定名称 单轮/默认场景
cobol/run_skip/ 固定名称 跳过场景(原 skip/
cobol/run_<id>/ run_ + 场景ID 多轮场景
java/<对应cobol目录>/ 与cobol目录对应 Java输出
coverage/ 固定名称 覆盖率报告
logs/ 固定名称 日志文件
gcov/run_<id>/ run_ + 场景ID gcov数据
data/ 固定名称 SQLite数据库

2.3 文件命名规则

文件类型 命名规则 示例
COBOL输入文件 <PROGRAM_ID>R<NN> KIN01R01, ZAN01R01
COBOL输出文件 <PREFIX>W<NN> KIN01W01, ZAN01W01
JSON中介文件 <PROGRAM_ID>.json KIN01INP.json
覆盖率报告 <PROGRAM_ID>_coverage.html KIN01INP_coverage.html
运行日志 <场景ID>.log main.log, run_normal.log
gcov数据 按场景ID分目录 gcov/run_main/, gcov/run_skip/
SQLite数据库 kin_<场景ID>.db kin.db, kin_normal.db

三、场景映射规则

3.1 单轮场景

定义:程序只有一次执行,无多场景配置。

目录结构

output/<PROGRAM_ID>/
├── cobol/
│   └── main/
│       ├── input/
│       ├── output/
│       └── json/
├── java/
│   └── main/
│       └── output/
├── coverage/
├── logs/
│   └── main.log
├── gcov/
│   └── run_main/
└── data/
    └── kin.db

3.2 多轮场景

定义:程序有多次执行,通过YAML配置文件定义场景。

目录结构

output/<PROGRAM_ID>/
├── cobol/
│   ├── run_normal/
│   │   ├── input/
│   │   ├── output/
│   │   └── json/
│   ├── run_insert_error/
│   │   ├── input/
│   │   ├── output/
│   │   └── json/
│   └── run_sql_delete_error/
│       ├── input/
│       ├── output/
│       └── json/
├── java/
│   ├── run_normal/
│   │   └── output/
│   ├── run_insert_error/
│   │   └── output/
│   └── run_sql_delete_error/
│       └── output/
├── coverage/
├── logs/
│   ├── run_normal.log
│   ├── run_insert_error.log
│   └── run_sql_delete_error.log
├── gcov/
│   ├── run_normal/
│   ├── run_insert_error/
│   └── run_sql_delete_error/
└── data/
    ├── kin_normal.db
    ├── kin_insert_error.db
    └── kin_sql_delete_error.db

3.3 跳过场景

定义:程序有跳过主FD输入的场景(旧版 skip/ 目录)。

目录结构

output/<PROGRAM_ID>/
├── cobol/
│   ├── main/
│   │   ├── input/
│   │   ├── output/
│   │   └── json/
│   └── run_skip/
│       ├── input/
│       ├── output/
│       └── json/
├── java/
│   ├── main/
│   │   └── output/
│   └── run_skip/
│       └── output/
├── coverage/
├── logs/
│   ├── main.log
│   └── run_skip.log
├── gcov/
│   ├── run_main/
│   └── run_skip/
└── data/
    ├── kin.db
    └── kin_skip.db

四、路径依赖说明

4.1 env_overrides 路径

COBOL运行时通过环境变量映射文件路径:

# 输入文件
env_overrides[fname] = os.path.join("input", fname)

# 输出文件
env_overrides[fname] = os.path.join("output", fname)

注意:这些是相对于CWD的路径,CWD为 cobol/main/cobol/run_<id>/

4.2 SQLite数据库路径

# 单轮场景
db_path = data/kin.db

# 多轮场景
db_path = data/kin_<scenario_id>.db

4.3 gcov数据路径

# 单轮场景
gcov_dir = gcov/run_main/

# 多轮场景
gcov_dir = gcov/run_<scenario_id>/

五、向后兼容性

5.1 旧版目录迁移

旧版目录 新版目录 迁移方式
main/input/ cobol/main/input/ 移动文件
main/output/ cobol/main/output/ 移动文件
main/json/ cobol/main/json/ 移动文件
skip/input/ cobol/run_skip/input/ 重命名+移动
skip/output/ cobol/run_skip/output/ 重命名+移动
skip/json/ cobol/run_skip/json/ 重命名+移动
pre_src/ cobol/pre_src/ 移动文件
coverage/ coverage/ 保持不变
logs/ logs/ 保持不变
gcov/ gcov/ 保持不变
data/ data/ 保持不变

5.2 兼容性处理

def _ensure_cobol_dir_structure(runtime_dir):
    """确保cobol目录结构存在,兼容旧版"""
    cobol_dir = runtime_dir / "cobol"
    if not cobol_dir.exists():
        # 检查是否是旧版结构(main/直接在runtime_dir下)
        old_main = runtime_dir / "main"
        if old_main.exists():
            # 迁移到新结构
            shutil.move(str(old_main), str(cobol_dir / "main"))

六、黑盒测试映射

6.1 YAML配置示例

# config/programs/KIN08DBU.yaml
runs:
  - id: normal
    sysin:
      - { dd: KIN08S01, content: "..." }
  - id: no_period
    sysin:
      - { dd: KIN08S01, content: "..." }
  - id: insert_error
    inject_duplicate_pk: true
    sysin:
      - { dd: KIN08S01, content: "..." }
  - id: sql_delete_error
    sysin:
      - { dd: KIN08S01, content: "..." }
  - id: sql_select_error
    sysin:
      - { dd: KIN08S01, content: "..." }

6.2 目录映射

场景ID COBOL目录 Java目录 日志文件 gcov目录 数据库文件
normal cobol/run_normal/ java/run_normal/output/ logs/run_normal.log gcov/run_normal/ data/kin_normal.db
no_period cobol/run_no_period/ java/run_no_period/output/ logs/run_no_period.log gcov/run_no_period/ data/kin_no_period.db
insert_error cobol/run_insert_error/ java/run_insert_error/output/ logs/run_insert_error.log gcov/run_insert_error/ data/kin_insert_error.db
sql_delete_error cobol/run_sql_delete_error/ java/run_sql_delete_error/output/ logs/run_sql_delete_error.log gcov/run_sql_delete_error/ data/kin_sql_delete_error.db
sql_select_error cobol/run_sql_select_error/ java/run_sql_select_error/output/ logs/run_sql_select_error.log gcov/run_sql_select_error/ data/kin_sql_select_error.db

6.3 黑盒测试执行流程

  1. 编译阶段:编译一次,全场景共享 .exe.gcno
  2. 场景执行:对每个场景独立执行
    • 生成场景特定输入数据
    • 初始化场景特定DB
    • 运行COBOL程序
    • 收集场景特定gcov数据
  3. Java执行:使用最后一个场景的DB结果
  4. 验证比对:比较COBOL和Java输出
  5. 覆盖率合并:合并多轮gcov数据,生成覆盖率报告

6.4 测试报告生成

报告类型 生成方式 输出位置
覆盖率HTML报告 orchestrator_db.generate_coverage_report() coverage/<PROGRAM_ID>_coverage.html
测试结果JSON orchestrator.run_all() reports/<timestamp>/result.json
测试报告HTML ReportGenerator.generate_html() reports/<timestamp>/report.html
机器可读JSON ReportGenerator.generate_machine_json() reports/<timestamp>/machine.json

七、代码修改清单

7.1 orchestrator_db.py

行号 修改内容 说明
103 runtime_dir = v3_root / "output" / program_id / "cobol" 添加cobol子目录
594-596 run_label = "main" if not scenario else f"run_{scenario.id}" 统一场景目录命名
626-628 env_overrides 路径改为 "input""output" 移除main/层级
686 log_dir = self.runtime_dir.parent / "logs" 日志目录移到根目录
700 gcda_dst_dir = gcov_dir / run_label 统一gcov目录命名
769 output_dir = v3_root / "output" / self.program_id / "coverage" 覆盖率报告移到根目录
779 gcov_dir = self.runtime_dir.parent / "gcov" gcov目录移到根目录
975 java_out = self.runtime_dir.parent / "java" / run_label / "output" Java输出目录
1016 self.java_output_path = self.runtime_dir.parent / "java" / run_label / "output" Java输出路径

7.2 cobol_testgen/__init__.py

行号 修改内容 说明
1759 outpath = prog_outdir / 'cobol' / 'main' / 'json' JSON输出路径
1769 prog_outdir / 'cobol' / 'main' / 'input' 输入文件路径
1776 prog_outdir / 'cobol' / 'main' / 'input' 子程序输入路径
1796 prog_outdir / 'cobol' / 'run_skip' / 'json' Skip JSON路径
1802 prog_outdir / 'cobol' / 'run_skip' / 'input' Skip输入路径

7.3 cobol_testgen/runner.py

行号 修改内容 说明
425-426 Path(outdir) / 'cobol' / 'main' / 'input' 主场景输入路径
425-426 Path(outdir) / 'cobol' / 'main' / 'output' 主场景输出路径
430-431 Path(outdir) / 'cobol' / 'run_skip' / 'input' Skip场景输入路径
430-431 Path(outdir) / 'cobol' / 'run_skip' / 'output' Skip场景输出路径

7.4 runners/gixsql_runner.py

行号 修改内容 说明
308 debug_dir = ... / "cobol" / "pre_src" 预处理源码路径

7.5 orchestrator.py

行号 修改内容 说明
142 co = Path(f"output/{cfg.program}/cobol/main/output/cobol_out.bin") COBOL输出路径
159 java_out_dir = Path("output") / cfg.program / "java" / "main" / "output" Java输出路径
200 rd = Path(f"output/{vr.program}/reports") / vr.timestamp 报告输出路径

八、测试验证

8.1 单元测试

运行现有单元测试确保向后兼容:

python -m pytest tests/ -v

8.2 集成测试

运行黑盒测试验证目录结构:

cd test-data
python s15_coverage_verification.py
python s30_db_e2e.py

8.3 手动验证

检查目录结构是否正确:

# 检查单轮程序
ls -la output/KIN01INP/
ls -la output/KIN01INP/cobol/main/
ls -la output/KIN01INP/java/main/output/

# 检查多轮程序
ls -la output/KIN08DBU/
ls -la output/KIN08DBU/cobol/run_normal/
ls -la output/KIN08DBU/java/run_normal/output/

九、注意事项

  1. env_overrides 路径:修改后需要确保COBOL运行时能找到正确的文件
  2. SQLite数据库路径:多轮场景的DB文件需要按场景命名
  3. gcov数据合并:多轮场景的gcov数据需要正确合并
  4. 向后兼容:需要处理旧版目录结构的迁移
  5. 测试覆盖:修改后需要运行所有测试确保功能正常

文档版本v1.0 创建日期2026-09-05 最后更新2026-09-05