Files
LinkPort/docs/testing.md
T
曾志威 59ed5ca0ef feat(windows): discover local and AppData databases automatically
Unify database path selection, preserve explicit overrides, and remove launcher-imposed data paths. Back up the selected directory with locking and recursive-copy protection. Include regression tests and migration documentation.

Prior focused path and desktop checks, Go vet, and the frontend build passed. Full regression failures in cluster discovery and three UI cases are recorded in docs/testing.md.
2026-09-20 18:20:20 +08:00

18 KiB
Raw Blame History

测试与版本矩阵

2026-09-20 Windows 多路径启动验证

  • Go 1.25.0:go test ./internal/desktop ./cmd/serviceport -count=1 -timeout=120s 通过,覆盖当前目录新库、AppData 已有库、双库优先级、相对/绝对显式路径、不依赖 AppData 环境、手动主密钥模式不遍历、目录占位错误、已有库缺密钥,以及 data-path 命令无初始化副作用与参数校验。
  • powershell.exe -NoProfile -ExecutionPolicy Bypass -File scripts/start-dev.test.ps1 通过:临时含空格项目、异目录调用、调用者目录恢复、构建锁、BuildOnly/FullCheck/RebuildWeb、构建/路径解析失败隔离;源码/发布入口不强制数据路径且保留显式设置;完整备份实际选中目录,并拒绝递归备份和被其他实例占用的数据。该脚本使用只记录环境变量的可执行 fixture,不启动真实服务。
  • go vet ./...、npm.cmd --prefix web run build、git diff --check 通过。Vite 报告主包体积警告,未作为失败处理;构建后保留 web/dist/.gitkeep,待 Vite 完成后再构建嵌入前端的新 EXE。
  • node scripts/verify-desktop.mjs artifacts/path-validation/serviceport.exe 使用此次新构建程序及 Edge 无头浏览器,通过当前目录创建、首次账号设置、自动 TLS、DPAPI 密钥保持、认证重启,以及将测试库移至隔离 AppData 后复用旧账号且不另建本地库。原桌面脚本的管理员字段定位已更新为实际表单标签“登录账号/登录密码”。
  • 全量 go test ./... -count=1 -timeout=120s 未全绿:未改动的 internal/cluster 中 TestMySQLReplicationAndGroupDiscovery 出现“无可用主节点”,单包复跑还出现拓扑不符;其余包通过。协议覆盖全部为本地 fixture,未连接真实 MySQL/MongoDB/SSH 服务。
  • Playwright 使用新 EXE、独立数据和 19091/19092 端口,执行 npm.cmd test -- --max-failures=3:77 通过、3 失败、8 未运行,达到失败上限后停止。失败为 account-editor.spec.ts 的 320×568 权限页多出 14px 滚动,以及 workspace-features.spec.ts 的 URL 参数、搜索/树导航两项超时;未修改这些前端功能或把此轮报告为全套通过。
  • 未运行实际项目的启动入口、未替换现用 EXE、未读写真实项目数据或用户 AppData 数据;路径变更无需数据库表结构迁移。

本地生成文件与 Git 忽略规则

.gitignore 排除本地 data、bin、artifacts、tmp、依赖目录和环境凭据;前端构建输出保留 web/dist/.gitkeep。Playwright 可从项目根目录或 web 运行,两处的 test-results、playwright-report、blob-report、缓存和隔离临时目录均不进入版本控制。

SQLite 的 .sqlite、.sqlite3 及其 journal/WAL/SHM 文件忽略;根目录临时 .db 及其侧文件也忽略。数据目录中的审计、DPAPI 主密钥与 TLS 文件保持本地,另外排除根目录可选的 tls 目录。规则不全局忽略所有 .db、证书、归档或配置文件,避免隐藏协议 fixture 和源码资产;.env.example、依赖锁文件、测试代码和文档应继续可提交。

修改规则后使用 git check-ignore --no-index 验证正反例,并检查 git ls-files 确认生成目录未被跟踪(dist 仅保留占位文件)。忽略规则不会删除文件,也不会让已经跟踪的文件自动退出版本控制。

2026-09-18 未保存目标连接测试

  • 新接口覆盖全部 10 种协议的草稿分派、未完成的非选中账号、按账号 ID 保留或临时覆盖密码、配置与历史不变、网关引用不变、CSRF 与字段校验、错误脱敏、私钥和 Kubeconfig 资产解析。
  • SSH 使用隔离的本机协议 fixture,验证未确认/错误指纹时不进行认证、确认后连接成功、后续测试不会继承临时信任。其他协议的新增接口测试使用记录型 handler;浏览器测试模拟远端结果。未连接生产服务或进行真实数据库版本验收。
  • go test ./... -count=1 -timeout=120s 中 API、存储、模型及协议包通过;Windows 桌面 TestLocalKeyPersistenceAndLock 仍报 The system cannot find the file specified.。网关 TestShutdownClosesAfterGracePeriod 首次报 handler not started,随后单独重跑整个 internal/gateway 包通过,因此不宣称首次全量通过。
  • go vet ./...、Vue 类型检查与 Vite 构建通过。Vite 保留大包体积提示;前端构建完成后用 Go 1.25.0 生成新的嵌入式测试程序,恢复 web/dist/.gitkeep。
  • 默认 18081/18082 被另一轮测试占用,本轮设置 SERVICEPORT_E2E_PORT=19081、SERVICEPORT_E2E_AUTH_PORT=19082 并通过 SERVICEPORT_E2E_BINARY 指定新程序;使用独立临时数据和结果目录,未停止其他服务、未部署实际数据目录。
  • target-editor-test.spec.ts 的 13 项用例全部通过:修改后按指定账号测试且不保存、10 种协议新建草稿测试、390px 手机下 MongoDB URI 副本集草稿测试、SSH 临时指纹取消与确认。其他协议的远端连接结果由浏览器路由模拟,后端 SSH 认证由上面的本地 fixture 验证。
  • 整套浏览器运行先通过 35 项,随后并行工作新增的 rabbit-version.spec.ts 在创建测试目标时失败:fixture 账号缺少保存接口必需的名称,尚未进入连接测试。未修改该并行文件,余下用例另起隔离服务继续运行;不能把这一轮称为首次全套通过。
  • 余下 32 项先通过 31 项,最后的主题用例在创建浏览器上下文时遇到 Edge 退出;用新浏览器单独重跑通过。最终本轮范围内的 67 项浏览器用例分批通过,另有上述并行 RabbitMQ 用例失败记录。Windows 测试服务退出等待期间仅停止本轮指定路径的测试程序,未停止用户服务或另一轮测试程序。

改动原因和行为边界见 未保存配置的连接测试 与 变更原因与设计记录。

2026-09-18 账号路由与免滚动编辑验证

以下是本轮实际执行记录;下方早期版本的“全量通过”不代表本轮 Windows 环境所有测试通过。

  • 前端:npm.cmd --prefix web run build(Vue 类型检查及 Vite 生产构建)通过。使用 Go 1.25.0 在前端构建结束后生成新的嵌入式测试程序,并通过 SERVICEPORT_E2E_BINARY 运行 Playwright;恢复了受版本控制的 web/dist/.gitkeep。
  • 最终 55 项浏览器用例分批验证通过。全量运行先通过 48 项;旧工作区测试仍假设白名单位于登录表单,按新分组入口修正后,该文件的 6 项业务用例通过。最后的主题用例在创建浏览器上下文时遇到 Edge 退出,使用新浏览器单独重跑通过。因此不是一次完整运行零失败。
  • 新增免滚动用例使用 12 个已有账号,检查 1440×900、375×812、320×568 的登录、目标、权限、更多分组内容高度;验证新增第 13 个账号立即聚焦、切换保留草稿、跨账号错误定位及保存后凭据保留。小屏溢出修正后该用例通过。
  • 账号路由后端改动执行 go test ./... -count=1 -timeout=120s。相关模型、存储、API、网关及协议包通过;internal/desktop 的 TestLocalKeyPersistenceAndLock 仍报 The system cannot find the file specified.,因此完整命令返回失败。go vet ./... 通过。
  • 随后补充的双目标 SSH 账号切换/重连测试单独运行通过,覆盖同一监听端口按账号访问不同目标、只切换一个账号、新连接更新路由以及已有会话保持原目标。SSH、HTTP TLS、MongoDB 和 RabbitMQ 路由测试使用隔离 fixture,没有对实际生产服务做验收。
  • 最新免滚动编辑调整只涉及前端及文档,重新执行前端构建和浏览器验证,未把此前后端结果表述为重新运行后的结果。测试使用独立数据库和端口,未部署或迁移实际使用的数据目录。

改动原因见 变更原因与设计记录,使用方式见 易用性 与 账号说明。

0.3.0 验证

  • 共享代理出口:Go 全套测试与静态检查通过,覆盖旧出口原子迁移/幂等性、凭据不重复保存、目标引用解析、共享更新、运行中修改阻止、引用删除阻止和密码查看权限。八项浏览器流程验证代理独立菜单、目标下拉、多目标共享、解绑删除及既有服务功能;主题测试遇到 Edge 进程退出后独立重跑通过。桌面/390px 手机截图无页面溢出或抽屉裁切。

  • Go 全量测试和 go vet 通过;Vue 类型检查和生产构建通过。

  • 内置 Kubernetes 测试使用模拟 API 与真实 SPDY 流,覆盖 TLS/Token、双向数据、建连取消、成功连接不受拨号 context 取消影响、关闭清理,以及 Service selector 和命名 targetPort。未连接真实 Kubernetes 集群。

  • 七项浏览器流程覆盖既有功能、K8s 配置保存/编辑、缺失 kubeconfig 错误和版本信息;手机抽屉位置、宽度及截图验证通过。主题测试在整套运行时遇到 Edge 进程退出,独立重跑通过。

  • 版本 CLI/API、无数据初始化的版本查询及 Windows 元数据注入构建通过。Linux/Docker 构建尚未运行。

本次验证记录

2026-09-09,Windows / Go 1.25.0 / Node.js 24 / Microsoft Edge:

  • go test ./... 通过,真实服务测试在未提供环境变量时明确跳过。
  • go vet ./... 通过。
  • Vue 类型检查与生产构建通过,生成并嵌入 Go 可执行文件。
  • Playwright 两条完整流程通过:MySQL 默认读写/可选只读/密码查看,MongoDB 与 SSH 的 SOCKS5 配置及编辑后凭据保留。
  • 已检查桌面与移动端截图,移动端使用独立卡片布局且无页面横向溢出。
  • PowerShell、Bash、MongoDB 初始化脚本语法检查及主密钥生成检查通过。
  • MySQL AST 和 MongoDB wire/BSON 只读检查器完成短时模糊测试。

Docker 真实服务矩阵尚未在本机执行,不能据此宣称全部目标版本已完成兼容认证。

本地测试

统一使用 Go 1.25.0。Windows 已安装更高版本 Go 时设置 GOTOOLCHAIN=go1.25.0;首次使用需下载兼容工具链。

$env:GOTOOLCHAIN = 'go1.25.0'
go test ./...
go vet ./...
npm.cmd --prefix web run build
go build -o bin/serviceport.exe ./cmd/serviceport
npm.cmd --prefix web test

浏览器测试使用隔离的临时 SQLite、随机主密钥和仅供测试的登录密码,监听 127.0.0.1:18081,结束后清理。不连接用户的数据库。默认使用已安装的 Edge;其他平台可安装 Playwright Chromium 并设置 SERVICEPORT_BROWSER_CHANNEL=chromium。截图输出到忽略版本控制的 web/test-results。

已有自动化覆盖

模块 覆盖范围
API 登录、会话/CSRF、默认读写、CRUD 脱敏、密码保留和重新认证查看、限流、停止前禁止修改、主机指纹字段防绕过
存储 AES-GCM 随机 nonce、篡改/用途/错误密钥拒绝、SQLite 加密持久化、登录密码重置及会话版本
运行管理 CIDR、来源限制、并发上限、端口冲突、可选 TLS、启停和连接清理
SOCKS5 无认证/密码认证、禁止降级、远端 DNS、IPv4/IPv6、失败不直连、超时和取消
MySQL TLS 网关、raw packet 转发、二进制预编译、重置、可选只读、LOCAL INFILE 拒绝、AST 模糊测试
MongoDB 官方 Go 驱动连接、双端 SCRAM、推测认证、上下游 TLS、BSON/OP_MSG、批量写入/游标、只读递归检查与模糊测试
SSH 进程内真实 SSH 协议、密码/公钥、带口令私钥、固定指纹、PTY/window、exec/退出码、SFTP channel、限制转发及取消
管理界面 登录、新建三类代理、默认读写、切换只读、SOCKS5 配置、凭据保留、密码查看、桌面及移动端布局

进程内协议测试使用可控服务端,不等同于真实数据库版本或 OpenSSH 的完整兼容认证。

Docker 真实版本测试

需要安装并运行 Docker Engine/Compose。所有服务为独立测试实例,端口只绑定到本机;脚本使用独立 Compose 项目,测试会创建并删除临时数据库,结束后删除该项目的测试卷。不要将这些测试指向生产服务。

.\scripts\test-matrix.ps1
bash scripts/test-matrix.sh

固定镜像和端口以 Compose 文件 为准:

服务 版本 本机端口
MySQL 5.7.44 / 8.0.43 / 8.4.6 13357 / 13380 / 13384
MongoDB 6.0.26 / 7.0.24 / 8.0.13 27060 / 27070 / 27080
OpenSSH 测试 Dockerfile 固定基础镜像 12222
SOCKS5 仓库内测试实现,无认证 / 密码 11080 / 11081

生成的测试 CA 用于目标 TLS 验证。MongoDB 8.0 测试实例配置单节点副本集,脚本负责初始化以验证事务。脚本对全部数据库版本及 SSH/SFTP 分别执行直连、无认证 SOCKS5、密码 SOCKS5 三条路径;SOCKS5 路径使用仅 Docker 内可解析的服务名,检查远端 DNS。服务凭据仅供这些一次性测试实例使用,详见 Compose。

手动启动测试实例:

docker compose -f deploy/compose.test.yml up -d --build --wait
docker compose -f deploy/compose.test.yml run --rm --no-deps mongo80-init

独立连接已准备好的目标测试实例:

  • MySQL:SERVICEPORT_MYSQL_TEST_ADDR、SERVICEPORT_MYSQL_TEST_USER、SERVICEPORT_MYSQL_TEST_PASSWORD、可选 SERVICEPORT_MYSQL_TEST_CA(CA 文件路径),执行 go test ./internal/protocol/mysqlproxy -run TestRealMySQL -count=1 -v。
  • MongoDB:SERVICEPORT_MONGO_TEST_ADDR、SERVICEPORT_MONGO_TEST_USER、SERVICEPORT_MONGO_TEST_PASSWORD、可选 SERVICEPORT_MONGO_TEST_CA(PEM 内容),执行 go test ./internal/protocol/mongoproxy -run TestRealMongo -count=1 -v。
  • SSH:SERVICEPORT_SSH_TEST_ADDR、SERVICEPORT_SSH_TEST_USER、SERVICEPORT_SSH_TEST_PASSWORD,执行 go test ./internal/protocol/sshproxy -run TestRealSSH -count=1 -v。验证远程输出和退出码、SFTP 上传下载及清理、禁止 TCP 转发。

三类测试可额外设置 SERVICEPORT_TEST_SOCKS_ADDR 和可选 SERVICEPORT_TEST_SOCKS_USER/PASSWORD,使用真实生产出站层经 SOCKS5 连接上述目标。测试中的首次 SSH 指纹探测仅适用于已明确指定的一次性测试服务,不替代生产环境的管理员独立核对流程。

测试账号须允许创建和删除独立测试库;未设置地址时真实版本测试明确跳过。省略上游 CA 时测试按明文上游运行,但网关客户端仍执行 TLS。

验证边界

当前开发机器没有 Docker、MySQL 或 MongoDB 服务,真实版本矩阵和 OpenSSH/mongosh 客户端组合尚未在此机器执行。Docker 镜像启动、数据库各版本 TLS/认证差异、真实副本集事务以及所有服务经 SOCKS5 的端到端组合,需要运行测试环境后再确认。

只读是严格请求白名单,不等同数据库权限保证;MongoDB 只读游标按客户端连接限制,多文档事务不在只读兼容范围。完整边界见 只读说明 和 开发计划。

Windows 双击启动验证

已通过 go test ./...、go vet ./...,以及 Edge 无头浏览器的桌面启动回归。验证包括无管理员/主密钥环境变量启动、从其他工作目录启动、首次页面创建管理员、自动本机 TLS、DPAPI 密钥持久化、重启后原账号登录。初始化单元测试覆盖错误 token、跨来源请求和重复初始化;Windows 测试覆盖独占锁和数据库存在时禁止替换丢失密钥。

对解压后的发行包运行:

node scripts/verify-package.mjs <解压后的目录>
node scripts/verify-desktop.mjs <解压后的目录>/serviceport.exe

脚本只在独立临时工作目录中测试:无已有库时创建 data 且不创建隔离的 AppData;随后将测试数据移至隔离的 AppData,验证旧库复用、原账号登录、密钥不变且不另建本地库。整个过程不读取实际用户配置。桌面脚本用 Edge 自动操作首次设置页面,禁用系统浏览器弹窗并使用随机本机端口;系统默认浏览器关联及资源管理器双击交互未由此脚本覆盖。

0.2.0 新增验证范围

  • 独立目标 CRUD、多网关复用、目标修改/删除约束、旧版事务迁移、密码/SSH 身份/启用状态保留、网关存储不重复保存上游秘密。
  • 本机免登录开发会话、Host/来源/CSRF 限制;认证启用时的既有登录与重新认证测试。
  • MySQL 模拟服务压缩协商/回退、流量缩减、结果集和预编译;MongoDB 压缩协商/回退、压缩报文边界、凭据命令不压缩、只读网关转发。真实目标压缩仍需实际版本矩阵验证。
  • SQL/MongoDB 放行与拦截审计、预编译模板、日志故障阻止转发;SSH exec/输入/SFTP 解析;日志内容加密、分页、筛选和 7 天保留。
  • Edge 验证默认免登录、独立目标与网关表单、共享目标/只读策略、MongoDB/SSH/SOCKS5、压缩配置、三种主题及系统跟随/持久化、移动布局和命令审计入口。

2026-09-09 扩展验收

  • Go 1.25.0 全量单元、协议、API、迁移测试与 go vet 通过;Vue 类型检查与生产构建通过。
  • 隔离的真实 MySQL 5.7.44 实例通过 TLS + zlib、读写/只读、SHOW TABLE STATUS、SHOW FULL PROCESSLIST 和指定三语句批次测试;结果见 artifacts/mysql-verification/show-batches-mysql57.log。测试库自动清理,实例验证后关闭。
  • Redis 使用可控 RESP 服务验证认证、HELLO、流水线、订阅、取消及审计;RabbitMQ 使用 amqp091-go 客户端连接模拟 broker;PostgreSQL 使用 pgconn 客户端连接模拟后端,验证简单/扩展查询、参数化、认证及审计。尚未对真实 Redis、RabbitMQ、PostgreSQL 部署做版本兼容验收。
  • 审计测试覆盖跨三日 411 条记录分页、跨日关键词和完整导出、密文迁移、失败重试/冲突保护、7 天清理、取消和并发。连接事件覆盖旧记录迁移、跨日筛选/分页及 CSV 导出。未执行 Go race 检查(当前未配置所需 C 工具链)。
  • Edge 六项流程通过,覆盖拖拽连接、审计筛选/导出、共享目标、可选只读、SSH/SOCKS5 出口、三种新增服务配置、主题及移动布局。最后一项首次因 Edge 进程退出失败,单独重跑通过。