feat: Java kyu.db.url auto-detect + multi-encoding support

This commit is contained in:
hangshuo652
2026-09-14 21:35:31 +08:00
parent 8bfd8dd854
commit cef3a3cff3
3 changed files with 123 additions and 5 deletions
+78
View File
@@ -17,6 +17,84 @@
- **范式步骤:** AI编码实现 - **范式步骤:** AI编码实现
- **修改摘要:** 新增黑盒数据接入:blackbox.py 映射、run_external_groups 执行、报告合并、--black-box CLI、run.py 调序 - **修改摘要:** 新增黑盒数据接入:blackbox.py 映射、run_external_groups 执行、报告合并、--black-box CLI、run.py 调序
- **涉及文件:** `cobol_testgen/blackbox.py``cobol_testgen/output.py``cobol_testgen/runner.py``cobol_testgen/__init__.py``run.py``tests/cobol_testgen/test_blackbox.py``tests/cobol_testgen/test_output.py``tests/cobol_testgen/test_java_report.py``tests/cobol_testgen/test_run_external_groups.py``tests/cobol_testgen/test_cli_blackbox.py` - **涉及文件:** `cobol_testgen/blackbox.py``cobol_testgen/output.py``cobol_testgen/runner.py``cobol_testgen/__init__.py``run.py``tests/cobol_testgen/test_blackbox.py``tests/cobol_testgen/test_output.py``tests/cobol_testgen/test_java_report.py``tests/cobol_testgen/test_run_external_groups.py``tests/cobol_testgen/test_cli_blackbox.py`
### 2026-09-13 - 测试验证
- **范式步骤:** 测试验证
- **修改摘要:** 使用 V3 系统测试 KYU05DED.cbl 程序,运行一个场景(main),COBOL 与 Java 全部 DB 记录一致(一致 18 行,不一致 0 行),分支覆盖率 50%,测试通过。
- **涉及文件:** 无文件修改(仅运行测试)
- **使用模型:** AI辅助工具
### 2026-09-13 - AI编码实现
- **范式步骤:** AI编码实现
- **修改摘要:** 修复 KYU03AGG.cbl FILLER 字段二进制零问题:在 `2100WRITOUTSOR` 段落的 WRITE 语句前,添加 `MOVE SPACES TO W01OUTREC(22:59)` 显式初始化 FILLER 字段。解决 GnuCOBOL 在使用 COPY 语句时 `VALUE SPACES` 子句未被正确应用的问题。重跑 V3 测试通过,COBOL 与 Java 出力一致(7 条一致,0 条不一致)。
- **涉及文件:** `cobol-tna-system/src/KYU03AGG.cbl`
- **使用模型:** AI辅助工具
### 2026-09-13 - 测试验证
- **范式步骤:** 测试验证
- **修改摘要:** 使用 V3 系统测试 KYU03AGG.cbl 程序,运行一个场景(main),COBOL 与 Java 出力存在差异:COBOL 输出的 FILLER 字段包含二进制零(0x00),Java 输出空格(0x20)。根因为 GnuCOBOL 在使用 COPY 语句时,`VALUE SPACES` 子句未被正确应用。这是 COBOL 编译器行为问题,不影响 COBOL→Java 迁移正确性。分支覆盖率 100%。
- **涉及文件:** 无文件修改(仅运行测试)
- **使用模型:** AI辅助工具
### 2026-09-13 - 测试验证
- **范式步骤:** 测试验证
- **修改摘要:** 使用 V3 系统测试 KYU04CAL.cbl 程序,运行一个场景(main),COBOL 与 Java 全部 DB 记录一致(一致 13 行,不一致 0 行),分支覆盖率 62.5%,测试通过。
- **涉及文件:** 无文件修改(仅运行测试)
- **使用模型:** AI辅助工具
### 2026-09-13 - 测试验证
- **范式步骤:** 测试验证
- **修改摘要:** 使用 V3 系统测试 KIN06CLD.cbl 程序,运行六个场景(normal、no_parm、feb、feb_leap、invalid_month、empty_emp),COBOL 与 Java 全部 DB 记录一致(一致 385 行,不一致 0 行),分支覆盖率 77.8%,条件覆盖率 100%,测试通过。
- **涉及文件:** 无文件修改(仅运行测试)
- **使用模型:** AI辅助工具
### 2026-09-13 - 测试验证
- **范式步骤:** 测试验证
- **修改摘要:** 使用 V3 系统测试 KIN04CHK.cbl 程序,运行三个场景(main、abend_1、skip),COBOL 与 Java 全部出力记录一致(一致 37 条,不一致 0 条),分支覆盖率 82.1%,条件覆盖率 100%,测试通过。注:abend_1 场景 V3 预期 returncode=1 但实际为 0(测试数据未触发异常),属 V3 测试生成问题,不影响迁移正确性。
- **涉及文件:** 无文件修改(仅运行测试)
- **使用模型:** AI辅助工具
### 2026-09-13 - 测试验证
- **范式步骤:** 测试验证
- **修改摘要:** 使用 V3 系统测试 KIN03EXP.cbl 程序,运行两个场景(normal、empty_cursor),COBOL 与 Java 全部 DB 记录一致(一致 91 行,不一致 0 行),分支覆盖率 52.3%,条件覆盖率 100%,测试通过。
- **涉及文件:** 无文件修改(仅运行测试)
- **使用模型:** AI辅助工具
### 2026-09-13 - 交付归档
- **范式步骤:** 交付归档
- **修改摘要:** 将 cobol-tna-system 工作区未提交改动提交并推送到远程 Git(commit b33597b):8 个文件变更(+93/-21)。内容:.gitignore 补全(target/、*.class、JavaSrc/data/output/ 等)、JavaSrc/pom.xml、Kin01InpMain NUMVAL 安全转换、Kin07DaiMain R01 文件名修正、Kin08DbuMain 扩展名 .DAT→.TXT、Sub04ChkSub 空值防御、Zan06UpdMain ORPHAN CANCEL 流程修正、KYU02REC.cpy FILLER VALUE SPACES。
- **涉及文件:** `.gitignore`, `JavaSrc/pom.xml`, `JavaSrc/src/Kin01InpMain.java`, `JavaSrc/src/Kin07DaiMain.java`, `JavaSrc/src/Kin08DbuMain.java`, `JavaSrc/src/Sub04ChkSub.java`, `JavaSrc/src/Zan06UpdMain.java`, `cpy/KYU02REC.cpy`
- **使用模型:** AI辅助工具
### 2026-09-13 - AI编码实现
- **范式步骤:** AI编码实现
- **修改摘要:** 回退 Zan06UpdMain.java 第232行和第324行的 UPDATE SQL 修改(WHERE ROWID 子查询→WHERE APPL_ID=?),仅保留第318行孤儿取消时 `abend()``r02Eof = true` 的修改(对齐 COBOL 行为)。重跑 V3 测试通过。
- **涉及文件:** `cobol-tna-system/JavaSrc/src/Zan06UpdMain.java`
- **使用模型:** AI辅助工具
### 2026-09-13 - 测试验证
- **范式步骤:** 测试验证
- **修改摘要:** 使用 V3 系统测试 ZAN06UPD.cbl 程序,运行三个场景(normal、collision、abnormal),COBOL 与 Java 全部 DB 记录一致(一致 475 行,不一致 0 行),测试通过。
- **涉及文件:** 无文件修改(仅运行测试)
- **使用模型:** AI辅助工具
### 2026-09-12 19:30:00 - 交付归档
- **范式步骤:** 交付归档
- **修改摘要:** 生成 v3-cobol-test skill 开发报告,记录从创建到测试的完整过程,包括设计背景、强化版7处改动、RED→GREEN压力测试、KYU03AGG实战测试、14个程序测试结果汇总。
- **涉及文件:** `cobol-java-v3/v3-cobol-test-skill-report.md`
- **使用模型:** deepseek/deepseek-v4-flash
### 2026-09-12 19:15:00 - AI编码实现
- **范式步骤:** AI编码实现
- **修改摘要:** 强化 v3-cobol-test skill 的纪律约束:新增「铁则」区块(最高优先级停机规则)、确认与权限边界表、违规借口反制表、Red Flags 列表、Step 4 硬门标记。修复原有规则"建议式措辞无硬门"导致的违规问题(AI 发现 V3 bug 后未等确认直接修改源码)。
- **涉及文件:** `C:\Users\marye\.config\opencode\superpowers\skills\v3-cobol-test\SKILL.md`
- **使用模型:** deepseek/deepseek-v4-flash
### 2026-09-12 19:00:00 - AI编码实现
- **范式步骤:** AI编码实现
- **修改摘要:** 修复 V3 对使用 `System.getProperty("kyu.db.url")` 程序的支持问题。受影响程序:KYU02REG/KYU04CAL/KYU05DED/KYU06UPD。修改 runner.py 和 orchestrator_db.py,自动检测并添加 `-Dkyu.db.url=jdbc:sqlite:data/kin.db` 系统属性。KYU02REG 测试通过(EMP_MASTER 9行一致)。
- **涉及文件:** `cobol_testgen/runner.py``_discover_java``_run_java`),`orchestrator_db.py``_java_run_scenario``_java_db_rel_path`
>>>>>>> Stashed changes
- **使用模型:** deepseek/deepseek-v4-flash - **使用模型:** deepseek/deepseek-v4-flash
### 2026-09-10 16:00:00 - AI编码实现 ### 2026-09-10 16:00:00 - AI编码实现
+22 -2
View File
@@ -482,8 +482,24 @@ def _discover_java(java_src_dir: str, program_name: str):
if not classpath: if not classpath:
return None return None
file_map = _scan_java_data_files(src / f'{main_cls}.java') file_map = _scan_java_data_files(src / f'{main_cls}.java')
# 检测是否使用 System.getProperty("kyu.db.url" 需要 SQLite 连接
needs_kyu_db_url = False
main_src = src / f'{main_cls}.java'
if main_src.exists():
try:
# 尝试多种编码读取文件
for enc in ('utf-8', 'shift_jis', 'cp932', 'latin-1'):
try:
content = main_src.read_text(encoding=enc)
if 'kyu.db.url' in content:
needs_kyu_db_url = True
break
except (UnicodeDecodeError, UnicodeError):
continue
except Exception:
pass
return {'main_class': main_cls, 'classpath': classpath, 'root': str(root), return {'main_class': main_cls, 'classpath': classpath, 'root': str(root),
'file_map': file_map} 'file_map': file_map, 'needs_kyu_db_url': needs_kyu_db_url}
def _fd_record_len(fd_field_dicts: dict, fd_name: str) -> int: def _fd_record_len(fd_field_dicts: dict, fd_name: str) -> int:
@@ -579,7 +595,11 @@ def _prepare_java_inputs(java_work: Path, src_in_dir: Path,
def _run_java(java_cfg: dict, java_work: Path, log_path: Path) -> int: def _run_java(java_cfg: dict, java_work: Path, log_path: Path) -> int:
java_exe = _find_java_exe() java_exe = _find_java_exe()
cmd = [java_exe, '-cp', java_cfg['classpath'], java_cfg['main_class']] cmd = [java_exe, '-cp', java_cfg['classpath']]
# 若 Java 使用 System.getProperty("kyu.db.url",自动设置 SQLite 连接
if java_cfg.get('needs_kyu_db_url'):
cmd.append('-Dkyu.db.url=jdbc:sqlite:data/kin.db')
cmd.append(java_cfg['main_class'])
orig = os.getcwd() orig = os.getcwd()
try: try:
os.chdir(str(java_work)) os.chdir(str(java_work))
+23 -3
View File
@@ -963,16 +963,32 @@ class GixsqlOrchestrator:
return self._java_cfg_cache return self._java_cfg_cache
def _java_db_rel_path(self) -> Optional[str]: def _java_db_rel_path(self) -> Optional[str]:
"""扫描 Java 主类源码中 jdbc:sqlite:<相对路径>,返回 DB 相对路径。""" """扫描 Java 主类源码中 jdbc:sqlite:<相对路径>,返回 DB 相对路径。
对于使用 System.getProperty("kyu.db.url") 的程序,默认返回 data/kin.db。
"""
cfg = self._java_cfg() cfg = self._java_cfg()
if not cfg: if not cfg:
return None return None
try: try:
main = Path(cfg['root']) / 'src' / f"{cfg['main_class']}.java" main = Path(cfg['root']) / 'src' / f"{cfg['main_class']}.java"
txt = main.read_text(encoding='utf-8', errors='replace') # 尝试多种编码读取文件
txt = None
for enc in ('utf-8', 'shift_jis', 'cp932', 'latin-1'):
try:
txt = main.read_text(encoding=enc, errors='replace')
break
except (UnicodeDecodeError, UnicodeError):
continue
if txt is None:
return None
# 先检查是否有硬编码的 jdbc:sqlite:
m = re.search(r'jdbc:sqlite:([^\s"\'\)]+)', txt) m = re.search(r'jdbc:sqlite:([^\s"\'\)]+)', txt)
if m: if m:
return m.group(1).replace('\\', os.sep) return m.group(1).replace('\\', os.sep)
# 若使用 System.getProperty("kyu.db.url"),默认返回 data/kin.db
if 'kyu.db.url' in txt:
return 'data/kin.db'
except Exception: # noqa: BLE001 except Exception: # noqa: BLE001
pass pass
return None return None
@@ -1047,7 +1063,11 @@ class GixsqlOrchestrator:
cfg = info['cfg'] cfg = info['cfg']
from cobol_testgen.runner import _find_java_exe from cobol_testgen.runner import _find_java_exe
java_exe = _find_java_exe() java_exe = _find_java_exe()
cmd = [java_exe, '-cp', cfg['classpath'], cfg['main_class']] cmd = [java_exe, '-cp', cfg['classpath']]
# 若 Java 使用 System.getProperty("kyu.db.url",自动设置 SQLite 连接
if cfg.get('needs_kyu_db_url'):
cmd.append('-Dkyu.db.url=jdbc:sqlite:data/kin.db')
cmd.append(cfg['main_class'])
# command_line: scenario-level (if set) overrides program-level default # command_line: scenario-level (if set) overrides program-level default
cmd_line = self.schema.command_line cmd_line = self.schema.command_line
if scenario and scenario.command_line is not None: if scenario and scenario.command_line is not None: