fix: 清除硬编码API Key与机器特定路径,改用环境变量+混合式路径解析
This commit is contained in:
@@ -0,0 +1,26 @@
|
|||||||
|
# COBOL → Java/Spark 迁移验证平台 v3 — 环境变量模板
|
||||||
|
# 复制本文件并按需设置: copy .env.example .env (或用 setx 持久化)
|
||||||
|
|
||||||
|
# ── DeepSeek API ─────────────────────────────────────────────
|
||||||
|
# 黑盒数据生成 / LLM 路径生成所需。也可写入
|
||||||
|
# black-box-data-create/config.json(该文件已被 gitignore,不会入库)
|
||||||
|
DEEPSEEK_API_KEY=
|
||||||
|
# DEEPSEEK_MODEL=deepseek-v4-flash
|
||||||
|
# DEEPSEEK_BASE_URL=https://api.deepseek.com/chat/completions
|
||||||
|
# DEEPSEEK_TIMEOUT=120
|
||||||
|
# DEEPSEEK_MAX_RETRIES=3
|
||||||
|
# DEEPSEEK_MAX_TOKENS=32768
|
||||||
|
|
||||||
|
# ── 外部测试数据目录(test-data/ 回归脚本、诊断脚本)──────────
|
||||||
|
# 未设置时自动推导为 %USERPROFILE%\Desktop\2026技术大赛\ 下同名目录
|
||||||
|
# COBOL_TNA_ROOT=D:\cobol-tna-system
|
||||||
|
# COBOL_BENCH_ROOT=D:\cobol-test-programs
|
||||||
|
|
||||||
|
# ── GnuCOBOL / gixsql 运行时 ────────────────────────────────
|
||||||
|
# 编译失败自愈回退用的库路径(hina/retry.py)
|
||||||
|
# COB_GNUCOBOL_LIB=D:\GnuCOBOL\lib\gnucobol
|
||||||
|
# DB 管道 SQLite 存放目录(须为短 ASCII 路径,COBOL CONNECT TO 受72列限制)
|
||||||
|
# GIXSQL_DB_DIR=C:/Temp/gix
|
||||||
|
|
||||||
|
# ── jcl-cobol-data-create(agent 模式联调用)─────────────────
|
||||||
|
# JCL_ROOT=D:\jcl-cobol-data-create
|
||||||
@@ -4,6 +4,12 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
### 2026-08-24 04:00:00 - 修复
|
||||||
|
- **范式步骤:** 硬编码清除(P0+P1)
|
||||||
|
- **修改摘要:** 清除2个硬编码API Key及文档明文(config.json取消跟踪改gitignore管理);orchestrator_db.py DB路径抽GIXSQL_DB_DIR常量;hina/retry.py移除浏览器下载路径回退;新增test-data/_paths.py集中路径解析(环境变量→目录推导兜底);13个test-data脚本、tests下5文件、3个diagnose脚本全部去机器特定路径;创建.env.example。回归:260通过/6既有失败,零新增失败
|
||||||
|
- **涉及文件:** `scripts/test_agent_mode.py`, `tests/e2e/test_pipeline.py`, `black-box-data-create/config.json`, `black-box-data-create/.gitignore`, `black-box-data-create/AGENTS.md`, `black-box-data-create/docs/superpowers/*`, `.env.example`, `orchestrator_db.py`, `hina/retry.py`, `diagnose_*.py`(本地), `test-data/_paths.py`, `test-data/s*.py`(13个), `tests/test_golden.py`, `tests/test_biz_e2e.py`, `tests/prepare_test_data.py`, `tests/cobol_testgen/test_merge_pipeline.py`, `tests/runners/test_sqlcode_normalize.py`, `docs/detailed-design/append_doc.py`
|
||||||
|
- **使用模型:** deepseek
|
||||||
|
|
||||||
### 2026-08-24 03:00:00 - 文档
|
### 2026-08-24 03:00:00 - 文档
|
||||||
- **范式步骤:** V3总体设计文档更新
|
- **范式步骤:** V3总体设计文档更新
|
||||||
- **修改摘要:** 更新00-overview.md,添加黑盒模块设计(2B章节)、PGMパターン、多KEY测试、黑盒数据流、双管道架构图
|
- **修改摘要:** 更新00-overview.md,添加黑盒模块设计(2B章节)、PGMパターン、多KEY测试、黑盒数据流、双管道架构图
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
__pycache__/
|
__pycache__/
|
||||||
*.pyc
|
*.pyc
|
||||||
output/
|
output/
|
||||||
|
config.json
|
||||||
@@ -52,7 +52,7 @@ python main.py --design "D:\cobol-tna-system\詳細設計書\詳細設計書_XXX
|
|||||||
- **同一COPYBOOKの複数REPLACING**: `ZAN01REC` が `R01`/`R02` 両方で使われる場合、`_extract_copy_replacing()` はリスト `[(copy_name, prefix), ...]` を返し、`_parse_copybooks()` が識別子でマッチする。
|
- **同一COPYBOOKの複数REPLACING**: `ZAN01REC` が `R01`/`R02` 両方で使われる場合、`_extract_copy_replacing()` はリスト `[(copy_name, prefix), ...]` を返し、`_parse_copybooks()` が識別子でマッチする。
|
||||||
- **PGMタイプ = サブ はスキップ**: `generate()` 関数で `meta.pgm_type == 'サブ'` の場合 `ValueError`。
|
- **PGMタイプ = サブ はスキップ**: `generate()` 関数で `meta.pgm_type == 'サブ'` の場合 `ValueError`。
|
||||||
- **入力タイプ判定**: `使用ファイル一覧` の `I/O` 列に `'I'` を含む行の `媒体` 列を見る。`PS`=ファイル、`DB`=DB、両方=混合。
|
- **入力タイプ判定**: `使用ファイル一覧` の `I/O` 列に `'I'` を含む行の `媒体` 列を見る。`PS`=ファイル、`DB`=DB、両方=混合。
|
||||||
- **APIキー**: コード内にハードコード (`sk-6156cccdc9c14d949cf5bfc5afc67a03`)。モデルは `deepseek-v4-flash`。
|
- **APIキー**: コードにハードコードしない。`config.json` または環境変数 `DEEPSEEK_API_KEY` から読み込む(`agent/config.py` 参照)。モデルは `DEEPSEEK_MODEL`(既定: `deepseek-v4-flash`)。
|
||||||
|
|
||||||
## 多keyテスト
|
## 多keyテスト
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
{
|
|
||||||
"api": {
|
|
||||||
"api_key": "sk-6156cccdc9c14d949cf5bfc5afc67a03",
|
|
||||||
"model": "deepseek-v4-flash",
|
|
||||||
"base_url": "https://api.deepseek.com/chat/completions",
|
|
||||||
"timeout": 120,
|
|
||||||
"max_retries": 3,
|
|
||||||
"max_tokens": 32768
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
# 测试数据生成 Agent 实现计划
|
# 测试数据生成 Agent 实现计划
|
||||||
|
|
||||||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||||
|
|
||||||
@@ -2042,7 +2042,7 @@ from agent.models import ProgramMeta, FileInfo, CopyField, KeyInfo, TableColumn,
|
|||||||
|
|
||||||
def generate(design_md: str, source_cbl: str, file_db_md: str,
|
def generate(design_md: str, source_cbl: str, file_db_md: str,
|
||||||
cpy_dir: str, db_md: str, output_dir: str = "output",
|
cpy_dir: str, db_md: str, output_dir: str = "output",
|
||||||
api_key: str = "sk-6156cccdc9c14d949cf5bfc5afc67a03",
|
api_key: str = "<API_KEY>",
|
||||||
api_model: str = "deepseek-v4-flash",
|
api_model: str = "deepseek-v4-flash",
|
||||||
rules_dir: str = "rules") -> dict:
|
rules_dir: str = "rules") -> dict:
|
||||||
"""生成测试数据的主入口函数。
|
"""生成测试数据的主入口函数。
|
||||||
@@ -2151,7 +2151,7 @@ def main():
|
|||||||
help='DB 定義書 .md のパス')
|
help='DB 定義書 .md のパス')
|
||||||
parser.add_argument('--output', default='output',
|
parser.add_argument('--output', default='output',
|
||||||
help='出力ディレクトリ (デフォルト: output)')
|
help='出力ディレクトリ (デフォルト: output)')
|
||||||
parser.add_argument('--api-key', default='sk-6156cccdc9c14d949cf5bfc5afc67a03',
|
parser.add_argument('--api-key', default='<API_KEY>',
|
||||||
help='DeepSeek API Key')
|
help='DeepSeek API Key')
|
||||||
parser.add_argument('--model', default='deepseek-v4-flash',
|
parser.add_argument('--model', default='deepseek-v4-flash',
|
||||||
help='API モデル名')
|
help='API モデル名')
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# COBOL 测试数据生成 Agent 设计文档
|
# COBOL 测试数据生成 Agent 设计文档
|
||||||
|
|
||||||
## 背景
|
## 背景
|
||||||
|
|
||||||
@@ -203,7 +203,7 @@ PGMパターン 值到规则文件名的映射:
|
|||||||
**API 配置**:
|
**API 配置**:
|
||||||
- 地址:https://api.deepseek.com/chat/completions
|
- 地址:https://api.deepseek.com/chat/completions
|
||||||
- 模型:`deepseek-v4-flash`
|
- 模型:`deepseek-v4-flash`
|
||||||
- API Key:`sk-6156cccdc9c14d949cf5bfc5afc67a03`
|
- API Key:`<API_KEY>`
|
||||||
- timeout:120 秒
|
- timeout:120 秒
|
||||||
|
|
||||||
**请求结构**:
|
**请求结构**:
|
||||||
|
|||||||
@@ -2,24 +2,25 @@
|
|||||||
"""Append the remaining sections to the design document."""
|
"""Append the remaining sections to the design document."""
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
OUT = Path(r"C:\Users\marye\Desktop\2026技术大赛\cobol-java-v3\docs\detailed-design\01-cobol-testgen-core.md")
|
_HERE = Path(__file__).resolve().parent
|
||||||
|
OUT = _HERE / "01-cobol-testgen-core.md"
|
||||||
content = OUT.read_text(encoding="utf-8")
|
content = OUT.read_text(encoding="utf-8")
|
||||||
content = content.replace("PLACEHOLDER", "")
|
content = content.replace("PLACEHOLDER", "")
|
||||||
|
|
||||||
# Read part2 content
|
# Read part2 content
|
||||||
part2 = Path(r"C:\Users\marye\Desktop\2026技术大赛\cobol-java-v3\docs\detailed-design\part2.md")
|
part2 = _HERE / "part2.md"
|
||||||
content += part2.read_text(encoding="utf-8")
|
content += part2.read_text(encoding="utf-8")
|
||||||
|
|
||||||
# Read part3 content
|
# Read part3 content
|
||||||
part3 = Path(r"C:\Users\marye\Desktop\2026技术大赛\cobol-java-v3\docs\detailed-design\part3.md")
|
part3 = _HERE / "part3.md"
|
||||||
content += part3.read_text(encoding="utf-8")
|
content += part3.read_text(encoding="utf-8")
|
||||||
|
|
||||||
# Read part4 content
|
# Read part4 content
|
||||||
part4 = Path(r"C:\Users\marye\Desktop\2026技术大赛\cobol-java-v3\docs\detailed-design\part4.md")
|
part4 = _HERE / "part4.md"
|
||||||
content += part4.read_text(encoding="utf-8")
|
content += part4.read_text(encoding="utf-8")
|
||||||
|
|
||||||
# Read part5 content
|
# Read part5 content
|
||||||
part5 = Path(r"C:\Users\marye\Desktop\2026技术大赛\cobol-java-v3\docs\detailed-design\part5.md")
|
part5 = _HERE / "part5.md"
|
||||||
content += part5.read_text(encoding="utf-8")
|
content += part5.read_text(encoding="utf-8")
|
||||||
|
|
||||||
OUT.write_text(content, encoding="utf-8")
|
OUT.write_text(content, encoding="utf-8")
|
||||||
|
|||||||
+8
-3
@@ -11,9 +11,14 @@ logger = logging.getLogger(__name__)
|
|||||||
HEALING_FIXES = {
|
HEALING_FIXES = {
|
||||||
"compile_error": {
|
"compile_error": {
|
||||||
"detect": lambda log: "not found" in (log or "").lower(),
|
"detect": lambda log: "not found" in (log or "").lower(),
|
||||||
"fix": lambda: _try_set_env(
|
# GnuCOBOL 库路径自愈:仅当环境变量 COB_GNUCOBOL_LIB 已设置时生效
|
||||||
"COB_LIBRARY_PATH",
|
# (见 .env.example)。不再内置任何机器特定回退路径。
|
||||||
"D:\\360安全浏览器下载\\GC32-BDB-SP1-rename-7z-to-exe\\lib\\gnucobol",
|
"fix": lambda: (
|
||||||
|
_try_set_env("COB_LIBRARY_PATH", os.environ["COB_GNUCOBOL_LIB"])
|
||||||
|
if os.environ.get("COB_GNUCOBOL_LIB")
|
||||||
|
else logger.warning(
|
||||||
|
"[Retry] COB_GNUCOBOL_LIB 未设置,无法自动修复库路径"
|
||||||
|
)
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
"s0c7": {
|
"s0c7": {
|
||||||
|
|||||||
+8
-3
@@ -33,6 +33,11 @@ from runners.gixsql_runner import GixsqlCobolRunner, GixsqlTableData
|
|||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
# DB 管道 SQLite 存放目录。默认保持短 ASCII 路径:
|
||||||
|
# COBOL CONNECT TO 字符串受固定格式第 72 列限制,且 gixpp 无法处理中文路径。
|
||||||
|
# 可用环境变量 GIXSQL_DB_DIR 覆盖(见 .env.example)。
|
||||||
|
GIXSQL_DB_DIR = Path(os.environ.get("GIXSQL_DB_DIR", "C:/Temp/gix"))
|
||||||
|
|
||||||
|
|
||||||
def _calc_birth_date(age: int, as_of: str = '20260802') -> str:
|
def _calc_birth_date(age: int, as_of: str = '20260802') -> str:
|
||||||
"""年龄 → 出生日期 YYYYMMDD(通用)。as_of 为运行时运用日。"""
|
"""年龄 → 出生日期 YYYYMMDD(通用)。as_of 为运行时运用日。"""
|
||||||
@@ -103,8 +108,8 @@ class GixsqlOrchestrator:
|
|||||||
compile_flags=config.gixsql_compile_flags,
|
compile_flags=config.gixsql_compile_flags,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Derive DB path: C:\Temp\gix\<program_id>.db (matches COBOL CONNECT TO, short enough for col 72)
|
# Derive DB path: <GIXSQL_DB_DIR>\<program_id>.db (matches COBOL CONNECT TO, short enough for col 72)
|
||||||
self.db_path = Path("C:/Temp/gix") / f"{self.program_id}.db"
|
self.db_path = GIXSQL_DB_DIR / f"{self.program_id}.db"
|
||||||
|
|
||||||
# Pipeline state
|
# Pipeline state
|
||||||
self.src_path: Optional[Path] = None
|
self.src_path: Optional[Path] = None
|
||||||
@@ -263,7 +268,7 @@ class GixsqlOrchestrator:
|
|||||||
|
|
||||||
# シナリオに応じた DB パス
|
# シナリオに応じた DB パス
|
||||||
if scenario:
|
if scenario:
|
||||||
db_path = Path("C:/Temp/gix") / f"{self.program_id}_{scenario.id}.db"
|
db_path = GIXSQL_DB_DIR / f"{self.program_id}_{scenario.id}.db"
|
||||||
self._current_db_path = db_path
|
self._current_db_path = db_path
|
||||||
else:
|
else:
|
||||||
db_path = self.db_path
|
db_path = self.db_path
|
||||||
|
|||||||
@@ -33,11 +33,20 @@ from pathlib import Path
|
|||||||
# ============================================================================
|
# ============================================================================
|
||||||
|
|
||||||
PROJECT_ROOT = Path(__file__).resolve().parent.parent
|
PROJECT_ROOT = Path(__file__).resolve().parent.parent
|
||||||
|
_DESKTOP = Path(os.environ.get("USERPROFILE", "")) / "Desktop"
|
||||||
|
_CONTEST_ROOT = _DESKTOP / "2026技术大赛"
|
||||||
|
|
||||||
|
# COBOL test data project: env var -> contest sibling dir fallback
|
||||||
|
COBOL_PROJECT = Path(
|
||||||
|
os.environ["COBOL_TNA_ROOT"]
|
||||||
|
) if "COBOL_TNA_ROOT" in os.environ else _CONTEST_ROOT / "cobol-tna-system"
|
||||||
|
|
||||||
|
# jcl-cobol-data-create candidates: env var first, then common locations
|
||||||
JCL_ROOT_CANDIDATES = [
|
JCL_ROOT_CANDIDATES = [
|
||||||
Path(r"C:\Users\marye\Desktop\2026技术大赛\jcl-cobol-data-create"),
|
*( [Path(os.environ["JCL_ROOT"])] if "JCL_ROOT" in os.environ else [] ),
|
||||||
|
_CONTEST_ROOT / "jcl-cobol-data-create",
|
||||||
Path(r"D:\jcl-cobol-data-create"),
|
Path(r"D:\jcl-cobol-data-create"),
|
||||||
]
|
]
|
||||||
COBOL_PROJECT = Path(r"C:\Users\marye\Desktop\2026技术大赛\cobol-tna-system")
|
|
||||||
PROGRAM = "ZAN04MAT"
|
PROGRAM = "ZAN04MAT"
|
||||||
|
|
||||||
TEST_INPUTS = {
|
TEST_INPUTS = {
|
||||||
@@ -48,8 +57,9 @@ TEST_INPUTS = {
|
|||||||
"db-md": COBOL_PROJECT / "詳細設計書" / "DB定義書.md",
|
"db-md": COBOL_PROJECT / "詳細設計書" / "DB定義書.md",
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFAULT_API_KEY = "sk-6156cccdc9c14d949cf5bfc5afc67a03"
|
# API key/model come from env or black-box-data-create/config.json (never hardcoded)
|
||||||
DEFAULT_API_MODEL = "deepseek-v4-flash"
|
DEFAULT_API_KEY = os.environ.get("DEEPSEEK_API_KEY", "")
|
||||||
|
DEFAULT_API_MODEL = os.environ.get("DEEPSEEK_MODEL", "deepseek-v4-flash")
|
||||||
|
|
||||||
ORCHESTRATOR_JCL = PROJECT_ROOT / "orchestrator_jcl.py"
|
ORCHESTRATOR_JCL = PROJECT_ROOT / "orchestrator_jcl.py"
|
||||||
|
|
||||||
@@ -414,10 +424,14 @@ def run_full_pipeline():
|
|||||||
"--cpy", str(TEST_INPUTS["cpy"]),
|
"--cpy", str(TEST_INPUTS["cpy"]),
|
||||||
"--db-md", str(TEST_INPUTS["db-md"]),
|
"--db-md", str(TEST_INPUTS["db-md"]),
|
||||||
"--output", str(output_dir),
|
"--output", str(output_dir),
|
||||||
"--api-key", DEFAULT_API_KEY,
|
|
||||||
"--api-model", DEFAULT_API_MODEL,
|
"--api-model", DEFAULT_API_MODEL,
|
||||||
"--verbose",
|
"--verbose",
|
||||||
]
|
]
|
||||||
|
if DEFAULT_API_KEY:
|
||||||
|
# Only pass explicitly when provided; otherwise main.py falls back
|
||||||
|
# to black-box-data-create/config.json or DEEPSEEK_API_KEY env.
|
||||||
|
idx = cmd.index("--api-model")
|
||||||
|
cmd[idx:idx] = ["--api-key", DEFAULT_API_KEY]
|
||||||
|
|
||||||
step("Executing pipeline (this may take several minutes)...")
|
step("Executing pipeline (this may take several minutes)...")
|
||||||
info(f"Command: {' '.join(cmd)}")
|
info(f"Command: {' '.join(cmd)}")
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
# ============================================================================
|
||||||
|
# _paths.py — test-data 回归脚本统一路径解析(混合式)
|
||||||
|
#
|
||||||
|
# 优先级: 环境变量 → %USERPROFILE%\Desktop\2026技术大赛\ 兜底推导
|
||||||
|
# 缺失时在使用方通过 require() 得到清晰的设置指引。
|
||||||
|
# 环境变量说明见项目根 .env.example。
|
||||||
|
# ============================================================================
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
V3_ROOT = Path(__file__).resolve().parent.parent
|
||||||
|
_DESKTOP = Path(os.environ.get("USERPROFILE", "")) / "Desktop"
|
||||||
|
_CONTEST_ROOT = _DESKTOP / "2026技术大赛"
|
||||||
|
|
||||||
|
|
||||||
|
def _resolve(env_name: str, fallback: Path) -> Path:
|
||||||
|
if env_name in os.environ:
|
||||||
|
return Path(os.environ[env_name])
|
||||||
|
return fallback
|
||||||
|
|
||||||
|
|
||||||
|
def require(path, label: str, env_name: str) -> Path:
|
||||||
|
"""存在性检查,失败时给出环境变量设置指引。"""
|
||||||
|
p = Path(path)
|
||||||
|
if not p.exists():
|
||||||
|
sys.exit(
|
||||||
|
f"[错误] {label} 目录不存在: {p}\n"
|
||||||
|
f"请设置环境变量 {env_name} 指向实际目录"
|
||||||
|
f"(例: setx {env_name} \"D:\\...\"),或参见 .env.example"
|
||||||
|
)
|
||||||
|
return p
|
||||||
|
|
||||||
|
|
||||||
|
# 基准程序集(cobol-test-programs)— 本机当前布局中不存在,需 COBOL_BENCH_ROOT
|
||||||
|
BENCH_ROOT = _resolve("COBOL_BENCH_ROOT", _CONTEST_ROOT / "cobol-test-programs")
|
||||||
|
COPYBOOKS_BENCH = BENCH_ROOT / "common" / "copybooks"
|
||||||
|
|
||||||
|
# TNA 电信测试系统 — 当前布局位于大赛目录下
|
||||||
|
TNA_ROOT = _resolve("COBOL_TNA_ROOT", _CONTEST_ROOT / "cobol-tna-system")
|
||||||
|
COPYBOOKS_TNA = TNA_ROOT / "cpy"
|
||||||
|
|
||||||
|
# jcl-cobol-git(HINA 分类验证用旧仓库)
|
||||||
|
COBOL_GIT_ROOT = _resolve("COBOL_GIT_ROOT", _CONTEST_ROOT / "jcl-cobol-git")
|
||||||
|
|
||||||
|
# 散置样本源码
|
||||||
|
SAMPLE_SRC_DIR = _resolve("SAMPLE_SRC_DIR", _CONTEST_ROOT)
|
||||||
@@ -5,7 +5,7 @@ P=0;F=0;BUGS=[]
|
|||||||
def ck(v,m=""): global P,F; (P:=P+1) if v else (F:=F+1,BUGS.append(m))
|
def ck(v,m=""): global P,F; (P:=P+1) if v else (F:=F+1,BUGS.append(m))
|
||||||
def sec(n): print(f"\n--- {n} ---")
|
def sec(n): print(f"\n--- {n} ---")
|
||||||
|
|
||||||
ROOT = "D:/cobol-java/cobol-test-programs/"
|
from _paths import BENCH_ROOT as ROOT
|
||||||
from cobol_testgen import extract_structure, generate_data
|
from cobol_testgen import extract_structure, generate_data
|
||||||
from hina.pipeline.pipeline import classify_program
|
from hina.pipeline.pipeline import classify_program
|
||||||
from hina.classifier import detect_keyword
|
from hina.classifier import detect_keyword
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ P=0;F=0
|
|||||||
def ck(v,m=""): global P,F; (P:=P+1) if v else (F:=F+1, print(f" FAIL {m}"))
|
def ck(v,m=""): global P,F; (P:=P+1) if v else (F:=F+1, print(f" FAIL {m}"))
|
||||||
def sec(n): print(f"\n{'='*60}\n{n}\n{'='*60}")
|
def sec(n): print(f"\n{'='*60}\n{n}\n{'='*60}")
|
||||||
|
|
||||||
ROOT = "D:/cobol-java/cobol-test-programs/"
|
from _paths import BENCH_ROOT as ROOT
|
||||||
COPYBOOKS = os.path.join(ROOT, "common", "copybooks")
|
COPYBOOKS = os.path.join(ROOT, "common", "copybooks")
|
||||||
COBC = "cobc"
|
COBC = "cobc"
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ P=0;F=0
|
|||||||
def ck(v,m=""): global P,F; (P:=P+1) if v else (F:=F+1, print(f" FAIL {m}"))
|
def ck(v,m=""): global P,F; (P:=P+1) if v else (F:=F+1, print(f" FAIL {m}"))
|
||||||
def sec(n): print(f"\n--- {n} ---")
|
def sec(n): print(f"\n--- {n} ---")
|
||||||
|
|
||||||
ROOT = "D:/cobol-java/cobol-test-programs/"
|
from _paths import BENCH_ROOT as ROOT
|
||||||
COPYBOOKS = os.path.join(ROOT, "common", "copybooks")
|
COPYBOOKS = os.path.join(ROOT, "common", "copybooks")
|
||||||
|
|
||||||
from cobol_testgen import extract_structure, generate_data
|
from cobol_testgen import extract_structure, generate_data
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
"""S18: ALL benchmark programs — full E2E: parse → generate → flatfile → compile → run → verify
|
"""S18: ALL benchmark programs — full E2E: parse → generate → flatfile → compile → run → verify
|
||||||
|
|
||||||
Run: cd D:/cobol-java/cobol-java-v3 && python test-data/s18_all_benchmark_e2e.py
|
Run: cd <project-root> && python test-data/s18_all_benchmark_e2e.py
|
||||||
"""
|
"""
|
||||||
import sys, os, subprocess, re, json
|
import sys, os, subprocess, re, json
|
||||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
|
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
|
||||||
@@ -8,7 +8,7 @@ P=0;F=0
|
|||||||
def ck(v,m=""): global P,F; (P:=P+1) if v else (F:=F+1, print(f" FAIL {m}"))
|
def ck(v,m=""): global P,F; (P:=P+1) if v else (F:=F+1, print(f" FAIL {m}"))
|
||||||
def sec(n): print(f"\n{'='*60}\n{n}\n{'='*60}")
|
def sec(n): print(f"\n{'='*60}\n{n}\n{'='*60}")
|
||||||
|
|
||||||
ROOT = "D:/cobol-java/cobol-test-programs/"
|
from _paths import BENCH_ROOT as ROOT
|
||||||
COPYBOOKS = os.path.join(ROOT, "common", "copybooks")
|
COPYBOOKS = os.path.join(ROOT, "common", "copybooks")
|
||||||
COBC = "cobc"
|
COBC = "cobc"
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
import sys, os, re, time
|
import sys, os, re, time
|
||||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
|
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
|
||||||
|
|
||||||
ROOT = "D:/cobol-java/cobol-test-programs/"
|
from _paths import BENCH_ROOT as ROOT
|
||||||
COPYBOOKS = os.path.join(ROOT, "common", "copybooks")
|
COPYBOOKS = os.path.join(ROOT, "common", "copybooks")
|
||||||
from cobol_testgen import extract_structure, generate_data
|
from cobol_testgen import extract_structure, generate_data
|
||||||
from cobol_testgen.read import preprocess, resolve_copybooks
|
from cobol_testgen.read import preprocess, resolve_copybooks
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ P=0;F=0
|
|||||||
def ck(v,m=""): global P,F; (P:=P+1) if v else (F:=F+1, print(f" FAIL {m}"))
|
def ck(v,m=""): global P,F; (P:=P+1) if v else (F:=F+1, print(f" FAIL {m}"))
|
||||||
def sec(n): print(f"\n{'='*60}\n{n}\n{'='*60}")
|
def sec(n): print(f"\n{'='*60}\n{n}\n{'='*60}")
|
||||||
|
|
||||||
ROOT = "D:/cobol-java/cobol-test-programs/"
|
from _paths import BENCH_ROOT as ROOT
|
||||||
COPYBOOKS = os.path.join(ROOT, "common", "copybooks")
|
COPYBOOKS = os.path.join(ROOT, "common", "copybooks")
|
||||||
COBC = "cobc"
|
COBC = "cobc"
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ P=0;F=0
|
|||||||
def ck(v,m=""): global P,F; (P:=P+1) if v else (F:=F+1, print(f" FAIL {m}"))
|
def ck(v,m=""): global P,F; (P:=P+1) if v else (F:=F+1, print(f" FAIL {m}"))
|
||||||
def sec(n): print(f"\n{'='*60}\n{n}\n{'='*60}")
|
def sec(n): print(f"\n{'='*60}\n{n}\n{'='*60}")
|
||||||
|
|
||||||
ROOT = "D:/cobol-java/cobol-test-programs/"
|
from _paths import BENCH_ROOT as ROOT
|
||||||
COPYBOOKS = os.path.join(ROOT, "common", "copybooks")
|
COPYBOOKS = os.path.join(ROOT, "common", "copybooks")
|
||||||
|
|
||||||
from cobol_testgen import extract_structure, generate_data
|
from cobol_testgen import extract_structure, generate_data
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ P=0;F=0
|
|||||||
def ck(v,m=""): global P,F; (P:=P+1) if v else (F:=F+1, print(f" FAIL {m}"))
|
def ck(v,m=""): global P,F; (P:=P+1) if v else (F:=F+1, print(f" FAIL {m}"))
|
||||||
def sec(n): print(f"\n{'='*60}\n{n}\n{'='*60}")
|
def sec(n): print(f"\n{'='*60}\n{n}\n{'='*60}")
|
||||||
|
|
||||||
ROOT = "D:/cobol-java/cobol-tna-system/"
|
from _paths import TNA_ROOT as ROOT
|
||||||
COPYBOOKS = os.path.join(ROOT, "cpy")
|
COPYBOOKS = os.path.join(ROOT, "cpy")
|
||||||
BINDIR = os.path.join(ROOT, "bin")
|
BINDIR = os.path.join(ROOT, "bin")
|
||||||
COBC = "cobc"
|
COBC = "cobc"
|
||||||
|
|||||||
@@ -2,9 +2,9 @@
|
|||||||
import sys, os, re, subprocess, time
|
import sys, os, re, subprocess, time
|
||||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
|
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
|
||||||
|
|
||||||
ROOT_BENCH = "D:/cobol-java/cobol-test-programs/"
|
from _paths import BENCH_ROOT as ROOT_BENCH, COPYBOOKS_BENCH
|
||||||
COPYBOOKS_BENCH = os.path.join(ROOT_BENCH, "common", "copybooks")
|
COPYBOOKS_BENCH = os.path.join(ROOT_BENCH, "common", "copybooks")
|
||||||
ROOT_TNA = "D:/cobol-java/cobol-tna-system/"
|
from _paths import TNA_ROOT as ROOT_TNA
|
||||||
COPYBOOKS_TNA = os.path.join(ROOT_TNA, "cpy")
|
COPYBOOKS_TNA = os.path.join(ROOT_TNA, "cpy")
|
||||||
|
|
||||||
from cobol_testgen import extract_structure, generate_data
|
from cobol_testgen import extract_structure, generate_data
|
||||||
|
|||||||
@@ -2,9 +2,9 @@
|
|||||||
import sys, os, re, time
|
import sys, os, re, time
|
||||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
|
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
|
||||||
|
|
||||||
ROOT_BENCH = "D:/cobol-java/cobol-test-programs/"
|
from _paths import BENCH_ROOT as ROOT_BENCH, COPYBOOKS_BENCH
|
||||||
COPYBOOKS_BENCH = os.path.join(ROOT_BENCH, "common", "copybooks")
|
COPYBOOKS_BENCH = os.path.join(ROOT_BENCH, "common", "copybooks")
|
||||||
ROOT_TNA = "D:/cobol-java/cobol-tna-system/"
|
from _paths import TNA_ROOT as ROOT_TNA
|
||||||
COPYBOOKS_TNA = os.path.join(ROOT_TNA, "cpy")
|
COPYBOOKS_TNA = os.path.join(ROOT_TNA, "cpy")
|
||||||
|
|
||||||
from cobol_testgen import extract_structure, generate_data
|
from cobol_testgen import extract_structure, generate_data
|
||||||
|
|||||||
@@ -2,10 +2,8 @@
|
|||||||
import sys, os, re, time, json
|
import sys, os, re, time, json
|
||||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
|
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
|
||||||
|
|
||||||
ROOT_BENCH = "D:/cobol-java/cobol-test-programs/"
|
from _paths import BENCH_ROOT as ROOT_BENCH, COPYBOOKS_BENCH
|
||||||
COPYBOOKS_BENCH = os.path.join(ROOT_BENCH, "common", "copybooks")
|
from _paths import TNA_ROOT as ROOT_TNA, COPYBOOKS_TNA
|
||||||
ROOT_TNA = "D:/cobol-java/cobol-tna-system/"
|
|
||||||
COPYBOOKS_TNA = os.path.join(ROOT_TNA, "cpy")
|
|
||||||
|
|
||||||
from cobol_testgen import extract_structure, generate_data
|
from cobol_testgen import extract_structure, generate_data
|
||||||
from cobol_testgen.read import preprocess, resolve_copybooks, \
|
from cobol_testgen.read import preprocess, resolve_copybooks, \
|
||||||
|
|||||||
@@ -2,9 +2,9 @@
|
|||||||
import sys, os, re
|
import sys, os, re
|
||||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
|
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
|
||||||
|
|
||||||
ROOT = "D:/cobol-java/cobol-test-programs/"
|
from _paths import BENCH_ROOT as ROOT
|
||||||
COPYBOOKS = os.path.join(ROOT, "common/copybooks")
|
COPYBOOKS = os.path.join(ROOT, "common/copybooks")
|
||||||
TNA = "D:/cobol-java/cobol-tna-system/"
|
from _paths import TNA_ROOT as TNA
|
||||||
from cobol_testgen import extract_structure, generate_data
|
from cobol_testgen import extract_structure, generate_data
|
||||||
|
|
||||||
total_br = 0; total_cov = 0; errors = []; below = []
|
total_br = 0; total_cov = 0; errors = []; below = []
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ P=0;F=0
|
|||||||
def ck(v,m=""): global P,F; (P:=P+1) if v else (F:=F+1, print(f" FAIL {m}"))
|
def ck(v,m=""): global P,F; (P:=P+1) if v else (F:=F+1, print(f" FAIL {m}"))
|
||||||
def sec(n): print(f"\n{'='*60}\n{n}\n{'='*60}")
|
def sec(n): print(f"\n{'='*60}\n{n}\n{'='*60}")
|
||||||
|
|
||||||
DESKTOP = os.path.join(os.environ['USERPROFILE'], "Desktop")
|
from _paths import TNA_ROOT, require
|
||||||
ROOT = os.path.join(DESKTOP, "2026技术大赛", "cobol-tna-system") + "/"
|
ROOT = str(require(TNA_ROOT, "TNA 测试数据", "COBOL_TNA_ROOT")) + "/"
|
||||||
COPYBOOKS = [os.path.join(ROOT, "cpy"), os.path.join(ROOT, "src")]
|
COPYBOOKS = [os.path.join(ROOT, "cpy"), os.path.join(ROOT, "src")]
|
||||||
|
|
||||||
from config import Config
|
from config import Config
|
||||||
|
|||||||
@@ -47,7 +47,8 @@ from cobol_testgen.read import resolve_copybooks, preprocess, extract_procedure_
|
|||||||
from cobol_testgen.core import build_branch_tree
|
from cobol_testgen.core import build_branch_tree
|
||||||
|
|
||||||
try:
|
try:
|
||||||
src_path = Path("D:/cobol-java/sample_ソース_SAN01MAT.cbl")
|
from _paths import SAMPLE_SRC_DIR
|
||||||
|
src_path = SAMPLE_SRC_DIR / "sample_ソース_SAN01MAT.cbl"
|
||||||
src = src_path.read_text(encoding="utf-8")
|
src = src_path.read_text(encoding="utf-8")
|
||||||
sdir = str(src_path.parent)
|
sdir = str(src_path.parent)
|
||||||
|
|
||||||
@@ -89,7 +90,8 @@ section("2. HINA分類: 実プログラム判定精度")
|
|||||||
from hina.classifier import compute_confidence
|
from hina.classifier import compute_confidence
|
||||||
|
|
||||||
# jcl-cobol-git の4プログラム
|
# jcl-cobol-git の4プログラム
|
||||||
cobol_git = Path("D:/cobol-java/jcl-cobol-git/cobol")
|
from _paths import COBOL_GIT_ROOT
|
||||||
|
cobol_git = COBOL_GIT_ROOT / "cobol"
|
||||||
if cobol_git.exists():
|
if cobol_git.exists():
|
||||||
for f in ['CRDVAL', 'CRDCALC', 'CRDRPT', 'GENDATA']:
|
for f in ['CRDVAL', 'CRDCALC', 'CRDRPT', 'GENDATA']:
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -7,6 +7,8 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import sys, os
|
import sys, os
|
||||||
|
from pathlib import Path
|
||||||
|
import pytest
|
||||||
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..")))
|
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..")))
|
||||||
|
|
||||||
from cobol_testgen.read import (
|
from cobol_testgen.read import (
|
||||||
@@ -17,8 +19,17 @@ from cobol_testgen.read import (
|
|||||||
from cobol_testgen.core import build_branch_tree
|
from cobol_testgen.core import build_branch_tree
|
||||||
from cobol_testgen.coverage import collect_decision_points
|
from cobol_testgen.coverage import collect_decision_points
|
||||||
|
|
||||||
_SRC = r'C:\Users\marye\Desktop\2026技术大赛\cobol-tna-system\src'
|
# TNA 测试数据目录: 环境变量优先 → 大赛兄弟目录兜底(见 .env.example)
|
||||||
_CPY = r'C:\Users\marye\Desktop\2026技术大赛\cobol-tna-system\cpy'
|
_TNA = Path(os.environ.get(
|
||||||
|
"COBOL_TNA_ROOT",
|
||||||
|
Path(__file__).resolve().parent.parent.parent.parent / "cobol-tna-system",
|
||||||
|
))
|
||||||
|
_SRC = str(_TNA / "src")
|
||||||
|
_CPY = str(_TNA / "cpy")
|
||||||
|
|
||||||
|
pytestmark = pytest.mark.skipif(
|
||||||
|
not _TNA.exists(), reason=f"TNA test data not found: {_TNA} (set COBOL_TNA_ROOT)"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def _load(pid):
|
def _load(pid):
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
"""E2E Tests for COBOL->Java Verification Platform
|
"""E2E Tests for COBOL->Java Verification Platform
|
||||||
|
|
||||||
Run: cd D:/cobol-java/v3-gstack-code-gen && python -m pytest tests/e2e/ -v
|
Run: cd <project-root> && python -m pytest tests/e2e/ -v
|
||||||
Requires: web server on http://127.0.0.1:8000, WSL available
|
Requires: web server on http://127.0.0.1:8000, WSL available,
|
||||||
|
DEEPSEEK_API_KEY set in the environment.
|
||||||
"""
|
"""
|
||||||
import json, os, sys, time, uuid, shutil
|
import json, os, sys, time, uuid, shutil
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
@@ -50,10 +51,19 @@ def create_task(copybook: str, cobol: str, java_dir: str, mapping: str, runner="
|
|||||||
return tid
|
return tid
|
||||||
|
|
||||||
|
|
||||||
|
def _wsl_path(p: Path) -> str:
|
||||||
|
"""Convert a Windows path to its WSL /mnt/<drive> equivalent."""
|
||||||
|
s = str(p).replace("\\", "/")
|
||||||
|
if len(s) > 1 and s[1] == ":":
|
||||||
|
return f"/mnt/{s[0].lower()}{s[2:]}"
|
||||||
|
return s
|
||||||
|
|
||||||
|
|
||||||
def run_worker_for_task(tid: str):
|
def run_worker_for_task(tid: str):
|
||||||
|
api_key = os.environ.get("DEEPSEEK_API_KEY", "")
|
||||||
script = (
|
script = (
|
||||||
"cd /mnt/d/cobol-java/v3-gstack-code-gen && "
|
f"cd {_wsl_path(PROJECT)} && "
|
||||||
"export LLM_API_KEY=sk-ca4961087c7f4aefa8ed0fc6f3d02329 && "
|
f"export LLM_API_KEY='{api_key}' && "
|
||||||
"export LLM_API_BASE=https://api.deepseek.com/v1 && "
|
"export LLM_API_BASE=https://api.deepseek.com/v1 && "
|
||||||
"export LLM_MODEL=deepseek-chat && "
|
"export LLM_MODEL=deepseek-chat && "
|
||||||
f"python3 -c \"exec(open('write_result.py').read().replace('ec17bf32','{tid}'))\""
|
f"python3 -c \"exec(open('write_result.py').read().replace('ec17bf32','{tid}'))\""
|
||||||
|
|||||||
@@ -1,8 +1,12 @@
|
|||||||
"""Prepare test data for Playwright E2E tests."""
|
"""Prepare test data for Playwright E2E tests."""
|
||||||
|
import os
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
FIXTURES = Path(__file__).parent / "fixtures"
|
FIXTURES = Path(__file__).parent / "fixtures"
|
||||||
COBOL_GIT = Path(r"D:\cobol-java\jcl-cobol-git")
|
COBOL_GIT = Path(
|
||||||
|
os.environ.get("COBOL_GIT_ROOT",
|
||||||
|
Path(__file__).resolve().parent.parent.parent / "jcl-cobol-git")
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def prepare():
|
def prepare():
|
||||||
|
|||||||
@@ -40,10 +40,10 @@ def test_normalize_injects_mapping_after_endsql(tmp_path):
|
|||||||
assert "SQLCODE = -2067" in out
|
assert "SQLCODE = -2067" in out
|
||||||
|
|
||||||
|
|
||||||
def test_normalize_mapping_before_if_sqlcode():
|
def test_normalize_mapping_before_if_sqlcode(tmp_path):
|
||||||
"""映射代码注入在 IF SQLCODE = -803 判断之前"""
|
"""映射代码注入在 IF SQLCODE = -803 判断之前"""
|
||||||
r = _make_runner()
|
r = _make_runner()
|
||||||
pp = Path(r'C:\Users\marye\AppData\Local\Temp\opencode\t3_pp.cbl')
|
pp = tmp_path / "t3_pp.cbl"
|
||||||
pp.parent.mkdir(parents=True, exist_ok=True)
|
pp.parent.mkdir(parents=True, exist_ok=True)
|
||||||
pp.write_text(_pp_text_with_if(), encoding="utf-8")
|
pp.write_text(_pp_text_with_if(), encoding="utf-8")
|
||||||
r._patch_sqlcode_normalize(pp)
|
r._patch_sqlcode_normalize(pp)
|
||||||
@@ -56,10 +56,10 @@ def test_normalize_mapping_before_if_sqlcode():
|
|||||||
assert mapping_idx < if_idx
|
assert mapping_idx < if_idx
|
||||||
|
|
||||||
|
|
||||||
def test_normalize_does_not_change_ok_path():
|
def test_normalize_does_not_change_ok_path(tmp_path):
|
||||||
"""归一化不影响 SQLCODE=0 成功路径"""
|
"""归一化不影响 SQLCODE=0 成功路径"""
|
||||||
r = _make_runner()
|
r = _make_runner()
|
||||||
pp = Path(r'C:\Users\marye\AppData\Local\Temp\opencode\t3b_pp.cbl')
|
pp = tmp_path / "t3b_pp.cbl"
|
||||||
pp.write_text(_pp_text_with_if(), encoding="utf-8")
|
pp.write_text(_pp_text_with_if(), encoding="utf-8")
|
||||||
r._patch_sqlcode_normalize(pp)
|
r._patch_sqlcode_normalize(pp)
|
||||||
out = pp.read_text(encoding="utf-8")
|
out = pp.read_text(encoding="utf-8")
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ from pathlib import Path
|
|||||||
from playwright.sync_api import Page, expect, sync_playwright
|
from playwright.sync_api import Page, expect, sync_playwright
|
||||||
|
|
||||||
BASE_URL = "http://127.0.0.1:8000"
|
BASE_URL = "http://127.0.0.1:8000"
|
||||||
|
COBOL_GIT = Path(os.environ.get("COBOL_GIT_ROOT", Path(__file__).resolve().parent.parent.parent / "jcl-cobol-git"))
|
||||||
FIXTURES = Path(__file__).parent / "fixtures"
|
FIXTURES = Path(__file__).parent / "fixtures"
|
||||||
TESTS_DIR = Path(__file__).parent
|
TESTS_DIR = Path(__file__).parent
|
||||||
|
|
||||||
@@ -172,7 +173,7 @@ def test_file_size_limit(page: Page):
|
|||||||
@pytest.mark.skipif(not _cobol_available(), reason="WSL not available")
|
@pytest.mark.skipif(not _cobol_available(), reason="WSL not available")
|
||||||
def test_cobol_system_pipeline_exists(page: Page):
|
def test_cobol_system_pipeline_exists(page: Page):
|
||||||
"""TC-E2E-02 prep: Verify COBOL system data files exist."""
|
"""TC-E2E-02 prep: Verify COBOL system data files exist."""
|
||||||
data_dir = Path(r"D:\cobol-java\jcl-cobol-git\data")
|
data_dir = COBOL_GIT / "data"
|
||||||
assert (data_dir / "input/member.dat").exists(), "member.dat missing"
|
assert (data_dir / "input/member.dat").exists(), "member.dat missing"
|
||||||
assert (data_dir / "input/rate.dat").exists(), "rate.dat missing"
|
assert (data_dir / "input/rate.dat").exists(), "rate.dat missing"
|
||||||
assert (data_dir / "output/summary_report.dat").exists(), "summary_report missing"
|
assert (data_dir / "output/summary_report.dat").exists(), "summary_report missing"
|
||||||
@@ -181,7 +182,7 @@ def test_cobol_system_pipeline_exists(page: Page):
|
|||||||
@pytest.mark.skipif(not _cobol_available(), reason="WSL not available")
|
@pytest.mark.skipif(not _cobol_available(), reason="WSL not available")
|
||||||
def test_cobol_output_consistent(page: Page):
|
def test_cobol_output_consistent(page: Page):
|
||||||
"""TC-E2E-02: CRDVAL output matches known golden data."""
|
"""TC-E2E-02: CRDVAL output matches known golden data."""
|
||||||
output = Path(r"D:\cobol-java\jcl-cobol-git\data\output")
|
output = COBOL_GIT / "data" / "output"
|
||||||
|
|
||||||
# Verify error report has 7+ error types
|
# Verify error report has 7+ error types
|
||||||
errors = (output / "error_report.dat").read_text()
|
errors = (output / "error_report.dat").read_text()
|
||||||
@@ -200,8 +201,8 @@ def test_cobol_output_consistent(page: Page):
|
|||||||
@pytest.mark.skipif(not _cobol_available(), reason="WSL not available")
|
@pytest.mark.skipif(not _cobol_available(), reason="WSL not available")
|
||||||
def test_java_output_equals_cobol(page: Page):
|
def test_java_output_equals_cobol(page: Page):
|
||||||
"""TC-E2E-02: Java CRDVAL output matches COBOL."""
|
"""TC-E2E-02: Java CRDVAL output matches COBOL."""
|
||||||
cobol_dir = Path(r"D:\cobol-java\jcl-cobol-git\data\output")
|
cobol_dir = COBOL_GIT / "data" / "output"
|
||||||
java_dir = Path(r"D:\cobol-java\jcl-cobol-git\data\output")
|
java_dir = COBOL_GIT / "data" / "output"
|
||||||
|
|
||||||
cobol_report = cobol_dir / "error_report.dat"
|
cobol_report = cobol_dir / "error_report.dat"
|
||||||
assert cobol_report.exists(), "COBOL error report missing"
|
assert cobol_report.exists(), "COBOL error report missing"
|
||||||
@@ -218,7 +219,7 @@ def test_java_output_equals_cobol(page: Page):
|
|||||||
@pytest.mark.skipif(not _cobol_available(), reason="WSL not available")
|
@pytest.mark.skipif(not _cobol_available(), reason="WSL not available")
|
||||||
def test_file_format_consistency(page: Page):
|
def test_file_format_consistency(page: Page):
|
||||||
"""TC-E2E-03: COBOL LINE SEQUENTIAL → JSON → Java roundtrip works."""
|
"""TC-E2E-03: COBOL LINE SEQUENTIAL → JSON → Java roundtrip works."""
|
||||||
cobol_dir = Path(r"D:\cobol-java\jcl-cobol-git")
|
cobol_dir = COBOL_GIT
|
||||||
|
|
||||||
# Check JSON conversion output exists
|
# Check JSON conversion output exists
|
||||||
json_file = cobol_dir / "data/work/validated_tx.json"
|
json_file = cobol_dir / "data/work/validated_tx.json"
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
"""
|
"""
|
||||||
Golden tests — 对接真实 COBOL 信用卡月结系统
|
Golden tests — 对接真实 COBOL 信用卡月结系统
|
||||||
数据源: D:\cobol-java\jcl-cobol-git\
|
数据源: COBOL_GIT_ROOT 环境变量指定的 jcl-cobol-git 目录
|
||||||
验证目标: 28 transactions → 20 valid + 8 rejected → 6 cards → ¥48,250.20 total
|
验证目标: 28 transactions → 20 valid + 8 rejected → 6 cards → ¥48,250.20 total
|
||||||
"""
|
"""
|
||||||
import sys, os
|
import sys, os
|
||||||
sys.path.insert(0, r"D:\cobol-java\v3-gstack-code-gen")
|
|
||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
|
||||||
|
|
||||||
from data.field_tree import Field, FieldTree
|
from data.field_tree import Field, FieldTree
|
||||||
from comparator.cobol_binary_reader import CobolBinaryReader
|
from comparator.cobol_binary_reader import CobolBinaryReader
|
||||||
from comparator.normalizer import Normalizer
|
from comparator.normalizer import Normalizer
|
||||||
@@ -14,7 +14,10 @@ from comparator.field_compare import compare_field
|
|||||||
from comparator.aligner import align_records
|
from comparator.aligner import align_records
|
||||||
from preprocessor import CopybookPreprocessor
|
from preprocessor import CopybookPreprocessor
|
||||||
|
|
||||||
GOLDEN = Path(r"D:\cobol-java\jcl-cobol-git")
|
GOLDEN = Path(
|
||||||
|
os.environ.get("COBOL_GIT_ROOT",
|
||||||
|
Path(__file__).resolve().parent.parent.parent / "jcl-cobol-git")
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# ── Test 1: TXCPY COPYBOOK 结构验证 ──
|
# ── Test 1: TXCPY COPYBOOK 结构验证 ──
|
||||||
|
|||||||
Reference in New Issue
Block a user