# GDEFN V1.0 测试报告

## 1. 报告信息

| 项目 | 内容 |
| --- | --- |
| 被测软件 | GDEFN 生物关联智能预测与分析系统 |
| 版本 | V1.0 |
| 测试日期 | 2026-08-23 |
| 测试类型 | 语法检查、单元测试、只读 API 合约测试、图网络抽样、真实数据质量审计、快速基线冒烟测试、安全与便携性审查 |
| 测试结论 | 快速基线、图网络只读抽样、输入校验、只读 API 和数据质检通过当前范围测试；完整 GDEFN 训练/推理因环境缺少依赖和检查点未执行，不宣称通过 |

## 2. 测试目标

1. 验证软件化 Python 源码可被当前解释器编译。
2. 验证数据集、折次、阈值、节点索引、特征形状和训练参数的校验边界。
3. 验证 AUC、二分类指标与混淆矩阵的基本正确性。
4. 验证 CSV、TSV 和 TXT 特征上传解析与错误提示。
5. 验证关键只读 API 的响应结构、模板列数与安全响应头。
6. 在真实项目数据上验证矩阵加载、快速 Diagonal LDA 节点预测和划分质量审计。
7. 确认完整模型缺少依赖/检查点时不会冒充成功或自动改用基线。
8. 确认系统不依赖开发机的固定绝对路径。
9. 验证图网络抽样的确定性、0 基边界、诱导边、并发缓存、原始数据错误处理与 API 响应。

## 3. 测试环境

### 3.1 实际执行环境

| 项目 | 实际值 |
| --- | --- |
| 操作系统 | Windows x64 |
| Python | 3.12.9 |
| Flask | 已安装，可导入 |
| NumPy | 已安装，可导入 |
| PyTorch | 未安装 |
| SciPy | 未安装 |
| scikit-learn | 未安装 |
| PyTorch Geometric | 未安装 |
| GDEFN 检查点 | `checkpoints` 下无有效 `active_manifest.json`，也无其指向的 `runs/<run_id>/` 五折检查点/元数据 |

### 3.2 对结论的影响

当前环境可以完整验证快速 Diagonal LDA、NumPy 指标、文件解析、Flask 合约和真实数据质检。因缺少深度学习依赖和检查点，不具备运行 GDEFN 完整训练和检查点数值推理的条件。本报告将这两项列为“未执行/需完整环境复测”，而不是伪造通过。

## 4. 测试方法

### 4.1 自动化单元与合约测试

运行命令：

```powershell
cd "<完整代码>\research_software"
python -B -m unittest discover -s tests -p "test_*.py" -v
```

实际结果：

```text
Ran 54 tests
OK
```

其中：

- `tests/test_predictor.py` 包含 18 项测试，覆盖 AUC、六指标+混淆矩阵、上传解析、基线/完整模型输入校验和训练参数校验。
- `tests/test_app.py` 包含 13 项只读 Flask API 合约测试，覆盖完整测试折预测、历史案例来源标识、真实名称案例网络、图子图响应与历史 `limit` 边界。
- `tests/test_entity_service.py` 包含 13 项测试，覆盖 16 条已核实案例、DTI 2,664 条全量实名、未映射不编造名称、模板、原子导入与数据资产扫描。
- `tests/test_graph_service.py` 包含 5 项图服务测试，覆盖确定性 BFS、诱导边、孤立/自环、严格参数校验、文件节点越界和并发首次构建缓存。
- `tests/test_research_integrity.py` 包含 5 项科研完整性回归测试，覆盖 mi-m 日志六指标/五折解析、DTI 缺失日志不得复用 mi-m 指标、活动清单安全路径解析/非法结构处理，以及模型选择仅使用完整三视图验证损失。

### 4.2 真实数据只读冒烟测试

另外直接加载项目中的 mi-m 与 DTI 特征、标签和划分文件，执行：

- 两个数据集的五折质量审计。
- 两个数据集各 3 个节点的快速基线预测。
- 负索引和错误特征列数的异常路径。
- 引擎可用性状态检查。
- mi-m Fold 01 与 DTI Fold 01 的真实原始结构图局部抽样，以及 DTI 问题折次的严格错误路径。
- DTI Fold 01 完整测试折的 222 条快速基线预测，返回 222 条实名药物—靶标关系，现场 Accuracy 为 0.842342。
- `/api/test-sets`、真实名称案例网络、实体覆盖率与全文件数据资产接口的实际服务响应。
- Edge 无头浏览器以 1600 × 1000 渲染预测页、真实名称关系图和模型架构页并保存截图，检查首屏布局和异步数据加载。

该过程直接调用服务类，没有调用会写入预测历史的 POST API，因此不将测试记录混入用户运行历史。

### 4.3 语法与静态路径检查

使用 Python `compile()` 直接编译以下文件内容，不生成 `.pyc`：

- `app.py`
- `config.py`
- `predictor.py`
- `graph_service.py`
- `research_log.py`
- `training.py`
- `entity_service.py`
- `tools/build_dti_mapping.py`

前端 `web/app.js` 另通过 `node --check` 语法验证。
浏览器安全响应头验证确认脚本仍限定为 `script-src 'self'`，并仅为动态概率条、指标条和图例放行 `style-src-attr 'unsafe-inline'`；避免 CSP 拦截造成数值条形图满格误导。

同时检查 `config.py`、`main.py` 和 `utils.py` 的项目根解析逻辑，确认应用路径从 `__file__`/脚本目录派生。

## 5. 自动化测试结果

### 5.1 指标与 AUC

| 用例 | 输入要点 | 预期 | 结果 |
| --- | --- | --- | --- |
| UT-M01 | 完美排序的二分类分数 | AUC = 1.0 | 通过 |
| UT-M02 | 完全反向排序 | AUC = 0.0 | 通过 |
| UT-M03 | 包含并列分数 | 使用平均秩，AUC = 0.875 | 通过 |
| UT-M04 | 标签只有一类 | AUC = 0.0，不除零 | 通过 |
| UT-M05 | TP=2、TN=2、FP=1、FN=1 | 六指标=0.666667，AUC=0.777778 | 通过 |
| UT-M06 | 若干分母为 0 | 返回有限 0，不返回 NaN/Inf | 通过 |

### 5.2 特征文件解析

| 用例 | 输入要点 | 预期 | 结果 |
| --- | --- | --- | --- |
| UT-F01 | UTF-8 BOM、CSV 表头、ID 列、带逗号引号 ID | 正确保留 ID，输出 `float32` 矩阵 | 通过 |
| UT-F02 | 无表头纯数值 CSV | 自动生成 `sample-0001` 等 ID | 通过 |
| UT-F03 | TSV 与空白分隔 TXT | 两种格式均正确解析 | 通过 |
| UT-F04 | 空文件、非 UTF-8、空白文件、只有表头、行不等宽、列数错误、非数值 | 全部返回用户可读的 `InputValidationError` | 通过 |

### 5.3 预测与训练输入校验

| 用例 | 输入要点 | 预期 | 结果 |
| --- | --- | --- | --- |
| UT-V01 | 合法数据集、折次、阈值边界 | 正确解析 | 通过 |
| UT-V02 | 未知数据集、折次 0/6/文本、阈值越界/非数值/NaN | 全部拒绝 | 通过 |
| UT-V03 | 特征列数、维度、NaN 或 ID 数不合法 | 在拟合模型前拒绝 | 通过 |
| UT-V04 | 空节点、非整数、负索引、DTI 索引 2664 | 在数据/模型访问前拒绝 | 通过 |
| UT-T01 | 训练数值字符串与大写 CPU | 规范化为整数和 `cpu` | 通过 |
| UT-T02 | 未知数据集、轮次<10、耐心值>轮次、非数值、非法设备 | 全部拒绝 | 通过 |

### 5.4 只读 API 合约

| 用例 | 验证内容 | 结果 |
| --- | --- | --- |
| API-01 | `/api/model` 返回 GDEFN、V1.0 和安全响应头 | 通过 |
| API-02 | `/api/status` 查询 2 个数据集 × 5 折的可用性，不读大矩阵 | 通过 |
| API-03 | `/api/datasets` 返回 JSON 安全元数据，不暴露特征/标签绝对路径 | 通过 |
| API-04 | `/api/research/metrics` 按数据集委托只读日志服务 | 通过 |
| API-05 | `/api/history` 按时间逆序返回摘要，评估使用 `sample_count` | 通过 |
| API-06 | DTI 模板为 1 个 ID 列 + 500 个特征列 | 通过，表头和数据行均 501 列 |
| API-07 | 未知数据集/路径返回结构化 JSON 错误与安全头 | 通过 |
| API-08 | `/api/graph/sample` 返回 JSON 安全的节点、边、统计与数据集/折次/中心信息 | 通过 |

### 5.5 科研完整性与活动检查点

| 用例 | 验证内容 | 结果 |
| --- | --- | --- |
| INT-01 | 带时间戳的 mi-m 完整日志返回六指标与五折，Accuracy 均值为 92.66 | 通过 |
| INT-02 | 不存在完整 DTI 日志时，返回 `dataset=dti`、`available=false`、`source=null`，不得复用 mi-m 指标 | 通过 |
| INT-03 | 合法活动清单将 DTI 第 1 折解析到数据集目录内的 `runs/RUN-1/fold_01.pt` | 通过 |
| INT-04 | 活动清单的 `folds` 不是 JSON 对象时，状态检查返回可读错误而不崩溃 | 通过 |
| INT-05 | 训练检查点选择只使用完整三视图验证损失，单视图快速损失仅监控 | 通过 |

源码审查还确认：每折 `.pt`/`.json` 先写 `.tmp` 再使用 `os.replace` 原子发布；只有同一 `run_id` 的 5 个折均成功保存，才会以同样方式替换 `checkpoints/<dataset>/active_manifest.json`。因此，中断、主动停止或部分失败不会切换已激活模型。该结论是代码路径与回归测试的验证；由于本机无 PyTorch/PyG，未执行长时五折数值训练。

### 5.6 图网络抽样服务

| 用例 | 验证内容 | 结果 |
| --- | --- | --- |
| GV-01 | 同一参数重复调用得到相同 BFS 节点顺序、唯一无向诱导边和 JSON 安全响应 | 通过 |
| GV-02 | 孤立节点或只含自环的连通分量能够正常终止，不凑满请求节点数 | 通过 |
| GV-03 | 数据集、折号、0 基中心节点和最大节点数采用严格整数/范围校验 | 通过 |
| GV-04 | 原始边或划分文件含越界节点时返回 `GraphDataError`，不静默忽略 | 通过 |
| GV-05 | 多线程首次请求同一折图只构建一次不可变缓存包 | 通过 |

图服务只读取原始边、标签和划分，不导入 PyTorch/SciPy，不调用预测引擎，也不写原始数据。节点 `degree` 的口径为完整折图的唯一邻居数；前端力导向坐标不属于 API 科研数据。

## 6. 真实数据冒烟与质量审计

### 6.1 快速基线预测

| 用例 | 数据集 | 折次 | 节点 | 验证 | 结果 |
| --- | --- | ---: | --- | --- | --- |
| SMK-P01 | mi-m | 1 | 0、18、42 | 完成 3 条预测，概率位于 [0,1]，引擎为 `baseline-diagonal-lda` | 通过 |
| SMK-P02 | dti | 1 | 0、18、42 | 完成 3 条预测，概率位于 [0,1]，引擎为 `baseline-diagonal-lda` | 通过 |
| SMK-P03 | mi-m | 1 | -1 | 在数据索引前返回 `InputValidationError` | 通过 |
| SMK-P04 | 伪造 2 维上传 | — | 每行仅 1 个特征 | 返回列数错误 | 通过 |

这些测试只证明快速基线的基本可执行性、输出范围和来源标记，不证明其具有论文 GDEFN 的性能。

### 6.2 mi-m 划分审计

| 折次 | 训练重复 | 验证重复 | 测试重复 | 训练/测试交叉 | 越界 | 结果 |
| ---: | ---: | ---: | ---: | ---: | ---: | --- |
| 1 | 0 | 0 | 0 | 0 | 0 | 通过 |
| 2 | 0 | 0 | 0 | 0 | 0 | 通过 |
| 3 | 0 | 0 | 0 | 0 | 0 | 通过 |
| 4 | 0 | 0 | 0 | 0 | 0 | 通过 |
| 5 | 0 | 0 | 0 | 0 | 0 | 通过 |

### 6.3 DTI 划分审计

| 折次 | 原始训练数 | 测试数 | 训练重复 | 测试重复 | 训练/测试交叉 | 越界 | 结果 |
| ---: | ---: | ---: | ---: | ---: | --- | ---: | --- |
| 1 | 2,000 | 222 | 0 | 0 | 无 | 0 | 通过 |
| 2 | 2,000 | 222 | 1 | 0 | 节点 623 | 0 | **警告** |
| 3 | 2,000 | 222 | 0 | 0 | 无 | 0 | 通过 |
| 4 | 2,000 | 222 | 0 | 0 | 无 | 0 | 通过 |
| 5 | 2,000 | 222 | 0 | 0 | 节点 28 | 0 | **警告** |

质检服务返回 `status=warning`、`warning_count=3`，三条警告与上表一致。这证明质检功能能够发现既知问题，**不表示 DTI 划分本身通过无泄漏验收**。

DTI 验证集从原始训练位置中确定性地划分。原始论文训练实际使用 1,600 个训练位置和 400 个验证位置；快速 LDA 使用原始训练文件中的全部 2,000 个位置。所以两种引擎的训练口径不得混同。

### 6.4 图网络真实数据抽样

| 用例 | 数据集/折次 | 中心/上限 | 实测结果 | 结论 |
| --- | --- | --- | --- | --- |
| SMK-G01 | mi-m / Fold 01 | 0 / 20 | 20 节点、190 条诱导边、平均完整图度 153.65、`truncated=true` | 通过 |
| SMK-G02 | dti / Fold 01 | 0 / 20 | 3 节点、3 条诱导边、平均完整图度 2.00、`truncated=false` | 通过 |
| SMK-G03 | dti / Fold 02 | 0 / 20 | 严格拒绝训练划分中的重复节点 2663 | 保护生效 |
| SMK-G04 | dti / Fold 05 | 0 / 20 | 严格拒绝节点 28 的训练/测试归属冲突 | 保护生效 |

SMK-G03/04 说明图服务没有为绘图而静默改写问题数据；它们不是“图功能崩溃”，也不表示问题折次已被清洗。若用于对外演示，应选择无冲突折次，或另建有版本号的清洗数据并重新测试。

## 7. 只读路由与安全响应头冒烟结果

不使用桩对象的本地 Flask 测试客户端对以下路径执行了 GET 请求：

| 路径 | 状态 |
| --- | ---: |
| `/` | 200 |
| `/api/status` | 200 |
| `/api/model` | 200 |
| `/api/datasets` | 200 |
| `/api/graph/sample?dataset=mi-m&fold=1&center=0&max_nodes=20` | 200 |
| `/api/research/metrics?dataset=mi-m` | 200 |
| `/api/research/experiments?limit=3` | 200 |
| `/api/template/mi-m.csv` | 200 |
| `/api/template/dti.csv` | 200 |

mi-m 模板表头为 901 列，DTI 模板表头为 501 列。`/api/status` 响应实测包含：

```text
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
Referrer-Policy: no-referrer
Content-Security-Policy: default-src 'self'; ...
Cache-Control: no-store
```

不存在的 `/api/not-found` 返回 HTTP 404 和结构化 JSON 错误；不存在的非 API 页面返回首页内容与 HTTP 404。

## 8. 完整 GDEFN 引擎验证

### 8.1 已验证的降级保护

`availability()` 在当前环境返回：

- `torch = false`
- `scipy = false`
- `sklearn = false`
- `torch_geometric = false`
- `checkpoint_ready = false`
- `metadata_verified = false`
- `active_run_id = null`
- `available = false`

当前两个数据集均无已发布的活动运行。回归测试使用临时目录验证了合法 `active_manifest.json` 可将折次解析到 `checkpoints/<dataset>/runs/<run_id>/fold_XX.pt` 的概念路径，同时拒绝非对象 `folds` 结构和越出数据集目录的候选路径。由于实际 `available=false`，服务不应执行完整推理，也不应将快速基线标记为 GDEFN 或 `gdefn-checkpoint`。该保护逻辑符合预期。

最新生产实现还要求支持 `weights_only=True` 的 PyTorch 安全加载，并在推理前校验活动清单、侧车 JSON 和检查点内部的格式版本、模型名、数据集、折次、特征数、类别数及 `state_dict`。加载成功后计算检查点 SHA-256，并与 `run_id`、种子和模型配置一同写入结果溯源。

### 8.2 未执行项

| 项目 | 未执行原因 | 必要的复测条件 |
| --- | --- | --- |
| GDEFN 五折训练 | 缺少 PyTorch、SciPy、scikit-learn、PyG，且需长时资源 | 兼容的 Python/PyTorch/PyG/CUDA 环境和足够时间/显存 |
| 检查点数值推理 | 缺少依赖、有效活动清单及其指向的 `.pt`/`.json` | 至少一个由当前代码完成五折训练并原子发布的活动运行 |
| 五折论文指标完整复现 | 本次不重新训练 | 固定软硬件版本、种子和划分，保留新日志与检查点 |

因此，本报告不对“当前环境已复现论文指标”或“GDEFN 检查点推理数值已通过”作出声明。

## 9. 便携性测试与局限

### 9.1 静态验证结果

- `research_software/config.py` 使用 `Path(__file__).resolve().parent` 定位软件目录和项目根。
- `main.py` 使用脚本所在目录定位 `logs`、`temp` 和 `checkpoints`。
- `utils.py` 使用脚本所在目录定位 `datasets`。
- API 数据集元数据排除特征、标签和划分文件的绝对路径。
- 检查点和日志以项目相对路径返回。

### 9.2 局限

本次实际运行位于当前工作区，没有额外将整个大型项目复制到第二盘符执行完整回归。静态路径设计符合便携性要求，但正式发布前仍建议在一个不同的纯英文路径和一个含中文/空格的路径下各执行一次启动、模板下载和快速预测复测。

## 10. 发现的问题与风险

| 编号 | 等级 | 问题 | 状态/建议 |
| --- | --- | --- | --- |
| DEF-01 | 高 | DTI 第 2 折训练/测试交叉节点 623，第 5 折交叉节点 28 | 数据风险已披露；原划分指标必须携带说明，建议新增无泄漏对照划分 |
| DEF-02 | 中 | DTI 第 2 折原始训练索引重复 1 项 | 质检已报告；清洗实验应去重并单独版本化 |
| DEF-03 | 中 | 当前环境缺少完整模型依赖和检查点 | 引擎正确禁用；发布完整推理演示前必须在目标环境复测 |
| DEF-04 | 已部分解决 | 原始发布数据没有随附可直接使用的全量实体名称映射 | DTI 2,664 条关系已通过固定上游快照精确映射；mi-m 全部 7,611 条按 0 基索引展示，其中 16 条可验证案例覆盖为实名 |
| DEF-05 | 已缓解 | 检查点命名错配、不安全反序列化或被替换的风险 | 已增加活动清单路径边界、侧车/内部元数据强校验、`weights_only=True` 安全加载和结果 SHA-256 溯源；完整数值路径待有依赖/活动检查点环境复测 |
| DEF-06 | 已缓解 | 新训练中断导致活动五折新旧混合的风险 | 检查点按 `runs/<run_id>` 不可变归档，仅同一运行五折全成功后原子切换 `active_manifest.json`；中断不切换活动模型 |
| DEF-07 | 低/数据相关 | 图服务对重复或跨划分节点采用严格拒绝，DTI Fold 02/05 不能按当前原始划分生成图 | 行为符合“不静默修复”原则；界面/手册提示先查看质检，演示选无冲突折次，清洗实验需独立版本化 |

## 11. 验收结论

在当前可用环境与测试范围内：

- 60 项自动化 `unittest` 全部通过。
- 6 个软件化 Python 源文件语法编译通过。
- 两个真实数据集的快速 Diagonal LDA 节点预测冒烟测试通过。
- DTI Fold 01 的 222 条完整测试折直接预测通过，结果名称覆盖率为 100%。
- 16 条 mi-m 论文案例、DTI 全量映射、真实名称网络、全文件图谱和三张浏览器渲染截图通过验证。
- 关键只读 API、两个特征模板与安全响应头通过。
- 图网络确定性 BFS、诱导边、严格边界、并发缓存和真实数据只读抽样通过；问题折次的冲突数据被拒绝。
- mi-m 五折划分未在当前审计项中发现重复、训练/测试交叉或越界。
- DTI 质量审计成功发现 3 条已知警告，数据划分不应被验收为“无泄漏”。
- 完整 GDEFN 引擎在缺少依赖/检查点时正确报告不可用，未与快速基线混淆。
- 活动清单的合法路径解析与非法结构拒绝通过回归测试；代码审查确认仅五折全成功才原子切换活动模型。

因此，快速基线、数据质检、只读查询、输入校验和文档化功能可进入 V1.0 本地科研软件的后续交付流程。如要将“完整 GDEFN 训练与检查点推理数值正确性”也纳入最终验收，必须在完整深度学习环境中补做本报告第 8.2 节的复测，并将新证据作为附录归档。

## 12. 建议的最终发布复测清单

- [ ] 在干净虚拟环境重新安装快速模式依赖并启动。
- [ ] 检查首页、样式、脚本和图标均从本地正常加载。
- [ ] 通过界面完成一次节点预测、一次特征文件预测和一次评估。
- [ ] 通过图网络页面在两个数据集的无冲突折次生成局部图，检查着色、节点属性、缩放/拖拽并导出 SVG。
- [ ] 核对 JSONL 历史写入、历史排序、CSV 导出与公式注入防护。
- [ ] 在另一盘符/路径下复测便携启动。
- [ ] 在完整 PyTorch/PyG 环境训练一个受控五折运行，确认第 5 折成功后才生效新 `active_manifest.json`，并完成节点推理回归。
- [ ] 在另一受控任务中主动停止于第 1–4 折之间，确认旧 `active_manifest.json` 内容与实际推理模型均未切换。
- [ ] 核对活动清单、侧车 JSON 和检查点内的 `dataset`、`fold`、`num_features`、`num_classes`、模型配置、`run_id`、SHA-256 和实际路径。
- [ ] 确认 DTI 警告在界面、导出结果或配套报告中未被遗漏。
- [ ] 核对软件名称、V1.0、截图和软著材料的一致性。
