# 测试与版本矩阵 ## 2026-10-07 SSH 自动指纹确认保存 TypeScript/Vite 和 Go 1.27.1 新嵌入程序构建通过。LINKPORT_E2E_BINARY 指向 bin/dev-build/cleanup/linkport.exe,临时 SQLite 与 18761/18762 隔离端口的六个当前 spec 共 22 项通过(28.4 秒)。新增 HTTP fixture 验证保存自动获取并显示完整指纹,探测只提交 host/port,确认前不保存,修改地址移除旧确认、过期结果重新探测,最终“确认新指纹并保存”提交 probeId/fingerprint 和 skipHostKeyVerify=false。保留页面、表单、CSRF 与凭据省略回归。 本轮仅前端变化,复用原后端主机确认绑定,没有重复后端测试;先前全量 Go 的已知 MySQL 集群 fixture 失败仍未解决。该验证不代表真实 SSH 服务验收,未部署或修改真实配置。git diff --check 通过。日志:bin/dev-build/cleanup/ssh-fingerprint-{build,browser}.log。 ## 2026-10-07 业务页面与代理表单 TypeScript/Vite 构建及 Go 1.27.1 重新嵌入 bin/dev-build/cleanup/linkport.exe 通过,保留 web/dist/.gitkeep。最终 LINKPORT_E2E_BINARY 指向该程序,使用临时 SQLite 和 18761/18762 运行当前六个 spec,共 21 项通过(25.0 秒)。验证内容包括:目标/网关/代理/资产页面保存与敏感值留空保留、目标详情返回、未保存确认、代理认证下拉与按模式字段显示、错误紧邻保存按钮且位于视口、服务端 400 错误只显示在当前页、返回不残留错误、菜单切换取消后保留草稿及确认后进入目标页面、320/390px 无横向溢出、全导航与主题回归。 资源保存使用隔离本机 API;代理测试状态和服务端保存错误使用 HTTP fixture,不代表真实代理连通验证。无后端修改,未重复上一轮已执行的全量 Go/vet;既有 MySQL 集群 fixture 失败仍保留,旧 Vue 全套也未因此视为通过,发现规则未收窄。git diff --check 通过。日志:bin/dev-build/cleanup/detail-pages-{build,browser}.log。未替换运行服务或修改真实数据。 ## 2026-10-06 未知会话失败分类 Go 1.27.1 gateway/API 专项通过;全量 go test 除既有 internal/cluster/TestMySQLReplicationAndGroupDiscovery 的 go-mysql 认证空指针外均通过,go vet 通过。前端 TypeScript/Vite 与新嵌入程序构建通过;临时 SQLite、隔离 18761/18762 的当前六个 Playwright spec 共 20 项通过(33.7 秒),其中 422 HTTP fixture 验证 target_session 提示且不显示无证据的目标协议异常。git diff --check 通过,web/dist/.gitkeep 保留。 日志:bin/dev-build/cleanup/session-diagnostics-{tests,go-test,vet,build,browser}.log。另对用户现有目标接口复现一次:SOCKS5 及目标 TCP 成功,MySQL 会话失败且原因类型未知;没有修改配置或替换运行服务,实际 MySQL 连接失败尚未解决。此观察与隔离回归测试分开记录。 ## 2026-10-06 代理测试颜色标识 前端构建及重新嵌入 bin/dev-build/cleanup/linkport.exe 通过。隔离 18761/18762 和临时 SQLite 的 outbound-fields/current-pages 共 4 项通过(13.7 秒);既有类型测试新增 Ant Design 成功/失败语义颜色、状态文字、错误原因以及成功转失败后旧状态消失断言。使用 HTTP fixture 模拟测试响应,不代表真实上游验证。无后端修改,沿用上一轮 Go 检查。日志:bin/dev-build/cleanup/test-colors-{build,browser}.log。 ## 2026-10-06 SOCKS5 / Kubernetes 代理测试 Go 1.27.1 的 outbound/API 专项通过。新测试使用本地 SOCKS5 TCP fixture,覆盖无认证/密码认证、认证拒绝、非 SOCKS5 响应、取消后断开且不发起目标 CONNECT;API 验证 CSRF 和空参数约束。Kubernetes HTTPS fixture 验证凭据资产解析、权限允许/拒绝、API 503 和敏感响应不泄露。没有真实集群或外部代理验证。 最终 `go test ./... -count=1 -timeout=120s`:API、outbound 及其余包通过,仅既有 internal/cluster/TestMySQLReplicationAndGroupDiscovery 的 go-mysql 认证空指针失败。`go vet ./...` 通过。TypeScript/Vite 和新嵌入 bin/dev-build/cleanup/linkport.exe 构建通过,保留 web/dist/.gitkeep;临时库和 18761/18762 上当前六个 Playwright spec 共 20 项通过(31.2 秒),验证四种类型均有测试入口,保留全页面及字段隔离回归。UI 类型操作使用 HTTP fixture,协议实现由 Go TCP/HTTPS fixture 验证。完整旧 Vue 套件仍未通过,本轮未改发现范围。 `git diff --check` 通过。日志:bin/dev-build/cleanup/proxy-probe-{tests,go-test,vet,build,browser}.log。未更新运行中的服务或真实数据。 ## 2026-10-06 代理测试入口类型回归 TypeScript/Vite 与重新嵌入程序构建通过。使用 bin/dev-build/cleanup/linkport.exe、临时 SQLite、隔离 18761/18762,outbound-fields/current-pages 共 4 项通过(12.8 秒)。新增 HTTP fixture 断言 SOCKS5/Kubernetes 不显示不支持的测试按钮,SSH/sing-box 各自发起正确测试请求;原字段隔离与 SOCKS5 凭据保留使用本机 API 验证。无后端改动,沿用本轮已执行的 Go 检查结果;没有真实上游连接验证。日志为 bin/dev-build/cleanup/outbound-action-{build,browser}.log。 ## 2026-10-06 保留数据库迁移 使用 Go 1.27.1:store/desktop/cmd/linkport 专项全部通过;新版本 2 数据库 fixture 验证网关密码与 readonly 权限保留、SOCKS5 目标和 Kubernetes TCP 共享引用迁移,以及二次重开不重复生成代理。原旧密钥、错误密钥、TLS、账号/备注/作用域迁移测试保留并通过。仅操作临时库。 `go test ./... -count=1 -timeout=120s` 的 internal/cluster/TestMySQLReplicationAndGroupDiscovery 因既有 go-mysql WritePublicKeyAuthPacket 空指针失败;其他包通过。`go vet ./...` 通过。没有验证真实 MySQL/Kubernetes/SSH/WebDAV 上游。 前端 TypeScript/Vite 与新嵌入程序构建通过,保留 web/dist/.gitkeep。临时 SQLite、端口 18761/18762、LINKPORT_E2E_BINARY 指向 bin/dev-build/cleanup/linkport.exe;当前六个 spec 在最终主题映射删除后的构建上共 19 项通过(33.0 秒),包含全导航、协议字段、SOCKS5 保存、CSRF 刷新、主题和 domain。最终日志:bin/dev-build/cleanup/final-{build,browser,go-test,vet}.log。git diff --check 通过。Node 22.10.0 仍低于 Vite 推荐版本,构建有大 chunk 提示。 完整旧 Vue 套件未通过:此前 150 项中 account-editor 旧选择器失败、149 项未运行。本轮未重复执行同一旧套件,也未删除被审批拦截的测试或修改发现范围。待删除清单及覆盖影响见 [前端清理剩余项](frontend-cleanup-pending.md)。 ## 2026-10-04 React / MUI 默认主题 本轮将 React 界面从 HeroUI 替换为原生 MUI 9 / Emotion,主题使用 `ThemeProvider`、`CssBaseline` 和默认浅深 palette.mode。辅助页及 Operations 独立严格 TypeScript 检查通过。`react-migration.spec.ts` 已将主题、目标和资产选择器改为 MUI combobox / option,并补充资产编辑空 content 不提交、secretStatus 保留和保存后不意外打开影响范围对话框的回归检查。 生产构建通过。构建结束后使用 Go 1.27.1 重新嵌入 `bin/dev-build/mui/linkport.exe`(2026-10-04 17:40),通过 `LINKPORT_E2E_BINARY` 指定该程序,在隔离端口 18241/18242 和临时 SQLite 上完整执行 `react-migration.spec.ts` / `ui-domain.spec.ts`:13 项通过(11.5 秒)。另执行 `node --test tests/connection-draft.test.mjs tests/account-mapping.test.mjs tests/access-mode.test.mjs`:16 项通过;`git diff --check` 通过。 首次 13 项运行 10 项通过、3 项因 MUI DialogTitle 自动 id 与自定义标题关联重复,可访问名称包含取消按钮文字失败。修正关联后重新构建并完整复测,上述 13 项通过来自最终程序,保留首次失败记录,不称首次零失败。额外浏览器检查 1440、1024、390、320px 均无横向溢出和 pageerror;亮暗、移动及编辑器截图位于 `bin/dev-build/mui`。前轮 HeroUI 程序、截图及通过记录不作为 MUI 验收。 ```powershell $env:LINKPORT_E2E_BINARY='C:/work/github/LinkPort/bin/dev-build/mui/linkport.exe' $env:LINKPORT_E2E_PORT='18241' $env:LINKPORT_E2E_AUTH_PORT='18242' Push-Location web npx.cmd playwright test react-migration.spec.ts ui-domain.spec.ts node --test tests/connection-draft.test.mjs tests/account-mapping.test.mjs tests/access-mode.test.mjs Pop-Location ``` 本轮未修改 Go、HTTP API 或 SQLite schema,也无真实 data 迁移或部署,未重复未修改的后端包测试。旧 Vue DOM 用例和已记录的后端失败保持原记录,不宣称全部旧 suite 或全仓回归通过;没有真实协议或 WebDAV 远端服务器验证。实现与兼容边界见 [React / MUI 前端](react-migration.md)。 下文保留此前 HeroUI 和 Vue 阶段的历史验证记录。 ## 2026-10-04 React / HeroUI 默认样式迁移 生产构建 `npm.cmd --prefix web run build`、Go 1.27.1 嵌入构建与 `go vet ./...` 通过。最终浏览器程序为 `bin/dev-build/react-final/linkport.exe`,使用独立临时数据库。 ```powershell $env:LINKPORT_E2E_BINARY='C:/work/github/LinkPort/bin/dev-build/react-final/linkport.exe' $env:LINKPORT_E2E_PORT='18191' $env:LINKPORT_E2E_AUTH_PORT='18192' Push-Location web npx.cmd playwright test react-migration.spec.ts ui-domain.spec.ts Pop-Location ``` 实际在 `web` 中执行 `npx.cmd playwright test react-migration.spec.ts ui-domain.spec.ts`,13 项通过,耗时 12.5 秒。覆盖免登录、真实 API 保存目标/网关、空密码保留、认证退出、未保存保护、浅深/系统主题及 ocean 兼容、资产/审计/配置页、320/390px 布局。另执行 `node --test tests/connection-draft.test.mjs tests/account-mapping.test.mjs tests/access-mode.test.mjs`,16 项通过。辅助隔离浏览器和 HTTP 检查覆盖秘密保留、Token、WebDAV 设置、备份版本冲突、历史恢复、告警和 AES fixture 解密。 全量 Playwright 发现 146 项;保留的旧 Vue 用例在旧 DOM/文案定位处失败,按 `--max-failures=5` 上限停止,不记为全套通过,也未禁用旧用例。重跑最终程序时使用独立 18211/18212 端口及 `--timeout=10000 --output=test-results/legacy-react`。旧 Node 源文件结构断言也需随 Vue 文件删除进行迁移,不能将其视为当前 React 验收。 后端 `go test ./... -count=1 -timeout=120s` 仍存在之前已记录的 API WebDAV 口令、cluster MySQL RSA fixture、desktop Windows 数据路径与 syncjob 加密旧断言失败。没有修改后端实现。所有 protocol 包通过,但没有真实远端协议服务器验收。 桌面、编辑器、浅深移动截图位于 `bin/dev-build/react-final`。旧主题、Vue 控件和全宽页面截图不代表当前 HeroUI 默认样式。迁移说明见 [React 前端](react-migration.md),原因与兼容影响见 [变更记录](change-rationale.md)。 ## 2026-09-27 独立网络代理与服务关联 - 前端管理入口改为代理;Kubeconfig、SSH、SOCKS5、sing-box 独立创建,目标和 TCP 网关按类型引用。新增 `network-proxies.test.mjs` 11/11,覆盖切换清空、不完整/失效引用阻止保存、只提交 ID、Kubeconfig 无 host、测试可用性、旧内联兼容和新 API 错误的中文/英文/日文映射。 - 逐文件执行全部 15 个 `web/tests/*.test.mjs`。首轮仅 `tcp-kube-forward` 和 `sing-box` 中两个旧“资产”文案断言失败,更新为当前代理/配置称呼后分别 7/7、10/10 通过,其余 13 个文件通过。 - `npm.cmd --prefix web run build` 的 Vue 类型检查通过;Vite 启动 esbuild 报 `spawn EPERM`。收尾文案修改后单独 `vue-tsc --noEmit` 也通过。`web/dist/.gitkeep` 保留,没有生成包含当前界面的新 executable,未用旧程序代替要求 `LINKPORT_E2E_BINARY` 的浏览器验收。相关 Playwright 用例已适配代理创建、上传、目标/TCP 关联及旧文件搜索编辑;使用工作区 TEMP/TMP/PWTEST_CACHE_DIR 执行全量 `--list` 发现 59 文件、134 项,仅是解析/发现检查,不代表浏览器通过。 - 使用 `GOTOOLCHAIN=go1.25.0`,TEMP/TMP/GOTMPDIR 指向 `.tmp/refactor-full-test`、GOCACHE 指向 `.tmp/kube-test/gocache`,执行 `go test -p=1 ./... -count=1 -timeout=120s`。只有六项已知环境失败:`cmd/linkport/TestRestoreCommandRejectsRunningService`、`internal/api/TestDatabaseSnapshotSessionAndPreview`、`internal/desktop/TestLocalSingleFileAndLock`、`internal/security/TestPrivateFileNeverOverwrites`、`internal/store/TestDatabaseSnapshotAndOfflineRestore`、`internal/store/TestSnapshotRejectsIncompleteAndSidecars`。错误分别是 Windows Access is denied 或不能创建完整便携 SQLite 快照;其余包/用例通过,全量不记为通过。 - `go vet -p=1 ./...` 通过。新增 model/store/API 覆盖全部四种代理、普通网关继承、持久化重开、备份恢复、缺失引用、代理改型校验、Kubeconfig 间接影响与运行拦截、API 脱敏。原 SOCKS5 本地两路字节转发 fixture 同时覆盖 legacy 与 proxy 模式。 - 源码交叉检查确认保存/Get/List/Test/导入均解析共享 Kubeconfig,持久化只留引用,管理 API 清除秘密。没有连接真实 Kubernetes 集群、SSH/sing-box 服务或真实目标,也没有部署、迁移或修改真实 data。 当前操作说明见 [网络代理管理](network-proxies.md)。 ## 2026-09-27 新建资产类型直选 - `AssetsManager.vue` 的类型下拉改为表单顶部可换行的六个单选项,沿用既有类型数据、切换清理和编辑锁定逻辑。 - `npm.cmd --prefix web run build` 的 Vue 类型检查通过;Vite 加载配置时启动 esbuild 报 `spawn EPERM`,没有新生产资源和 executable。`web/dist/.gitkeep` 保留,未用旧程序执行要求 `LINKPORT_E2E_BINARY` 的浏览器验收。 - 更新 `asset-remarks.spec.ts`、`file-assets.spec.ts`、`project-scope.spec.ts`、`scope-catalog.spec.ts` 的既有选择方式及编辑类型禁用断言。Playwright `--list` 发现 4 项,仅表示用例可发现,不代表执行通过。 - `git diff --check` 通过。纯前端控件调整,没有后端代码、数据库或真实 data 变更,未重复执行上一节已记录的 Go 全仓测试。 ## 2026-09-27 全模块重构 范围:启动命令与组合根、协议工厂、模型运行契约与账号职责、API 身份/路由管线、网关会话与停止生命周期、集群策略、告警/同步端口与适配器、备份编解码、前端草稿/凭据/游标/画板职责。包含前一轮出口、网关命令、资源目录重构。各模块的实际拆分与保留依据见 [架构覆盖清单](architecture-patterns.md)。 实际验证: - `GOTOOLCHAIN=go1.25.0`,Go 的 `TEMP`、`TMP`、`GOTMPDIR` 指向工作区 `.tmp/refactor-full-test`,`GOCACHE` 使用 `.tmp/kube-test/gocache`。包级检查后执行 `go test -p=1 ./... -count=1 -timeout=120s`。仅复现原有 6 项环境失败:`cmd/linkport/TestRestoreCommandRejectsRunningService`、`internal/api/TestDatabaseSnapshotSessionAndPreview`、`internal/desktop/TestLocalSingleFileAndLock`、`internal/security/TestPrivateFileNeverOverwrites`、`internal/store/TestDatabaseSnapshotAndOfflineRestore`、`internal/store/TestSnapshotRejectsIncompleteAndSidecars`;分别为 Windows 权限拒绝或无法生成完整便携快照。其余用例/包通过,全量结果不记为通过。 - `go vet -p=1 ./...` 通过。Go telemetry 尝试写入用户目录的 `Access is denied` 提示未影响 vet 和通过包的退出码。 - 新增运行回归覆盖协议工厂映射/注册表隔离、panic 后释放名额、重复认证计数、TCP 不计认证、Sentinel 账号切换、拓扑拒绝、64 节点上限、取消与未知协议。全部协议子包 fixture 通过;没有配置真实协议服务器环境变量。 - 新增后台回归覆盖手动告警检查不投递、拒绝 HTTP 重定向、成功后不重复投递;同步取消在途请求、拒绝并发运行、关闭后释放租约和记录失败原因。alerts、backup、syncjob 全包通过;store 除上述既有快照项外通过。 - 启动搬移后,已有 version JSON/无数据初始化、data-path 参数与无初始化、startup banner 边界测试通过。API 的会话/Token/CSRF/网关操作及确认绑定回归通过;后续全仓执行仅 API 快照项失败。 - 逐文件使用 `node web/tests/.test.mjs` 执行全部 14 个逻辑测试文件。首轮 13 个文件通过,`persistent-target.test.mjs` 中旧重启提示断言失败;将测试对齐此前已实现的保存配置后重试指引后,该文件 6/6 通过。没有改产品行为。新增 `connection-draft.test.mjs` 5、`secret-reveal.test.mjs` 5、`audit-pages.test.mjs` 4 项全部通过;通过直接加载实际 TypeScript/Vue 模块验证载荷和延迟响应。 - `npm.cmd --prefix web run build` 的 `vue-tsc --noEmit` 阶段通过,Vite 加载配置时 esbuild 子进程仍报 `spawn EPERM`。`web/dist/.gitkeep` 保留。没有生成包含本轮前端的新 executable,因此未运行要求 `LINKPORT_E2E_BINARY` 指向新程序的 Playwright,未用旧产物代替验收。原生全屏/ResizeObserver 和真实页面生命周期仍需浏览器验收。 - 启动/API/model、runtime、后台、前端分别进行独立源码交叉审查,未发现本轮具体回归;`git diff --check` 通过。源码审查不等于 race 或浏览器执行。 所有自动化使用隔离数据库、本机协议/HTTP fixture 或注入请求,没有连接真实目标、部署或执行数据迁移。 ## 2026-09-27 设计模式重构 范围:出口策略/工厂和拨号选项装饰器、网关命令分发、前端资源目录门面。仅调整内部职责,保持 API、配置和运行行为。 实际验证: - 使用 Go 1.25.0,SOCKS5 搬移后先执行已有聚焦回归;策略完成后 `go test -p=1 ./internal/outbound -count=1 -timeout=120s` 与该包 vet 通过。新增用例检查每次拨号校验、未知模式不触达目标、配置和调用者期限下握手关闭、5 秒/30 秒默认及子 context 释放。 - 网关业务搬离 server.go 后,API 原有会话、CSRF、凭据脱敏、启停保存失败和账号映射聚焦回归通过;完成命令表后新增 `TestGatewayActionRoutingBoundaries` 与 `TestGatewayActionConfirmationRetainsSessionBinding` 通过。后者注入隔离 probe,验证其他会话拒绝、本会话确认成功及一次性消费,不会连接真实 SSH 服务。 - `go test -p=1 ./... -count=1 -timeout=120s` 已执行。仍只有 6 项既有 Windows ACL/SQLite 快照失败:`cmd/linkport/TestRestoreCommandRejectsRunningService`、`internal/api/TestDatabaseSnapshotSessionAndPreview`、`internal/desktop/TestLocalSingleFileAndLock`、`internal/security/TestPrivateFileNeverOverwrites`、`internal/store/TestDatabaseSnapshotAndOfflineRestore` 与 `TestSnapshotRejectsIncompleteAndSidecars`。其余包/用例通过,不记为全量通过。 - `go vet -p=1 ./...` 通过。Go 的 TEMP/TMP/GOTMPDIR 与缓存位于工作区隔离目录;telemetry 写用户目录被拒绝的提示不影响聚焦测试和 vet 的退出码。 - `node web/tests/resource-catalog.test.mjs` 10/10,通过真实 Vue refs 和可控 Promise 覆盖整体发布、交错刷新、旧失败、新失败、保存优先、非资源写入不影响缓存、退出失效和页面协调。`workspace-pages.test.mjs` 1/1、`page-dialogs.test.mjs` 2/2 通过。`node --test` 多文件执行受沙箱子进程 EPERM 阻止,实际通过记录来自逐文件单进程运行。 - Vue 类型检查通过;`npm.cmd --prefix web run build` 在 Vite 启动 esbuild 时仍报 `spawn EPERM`。`web/dist/.gitkeep` 保留,没有生成包含本次改动的新 executable,因此未执行要求 `LINKPORT_E2E_BINARY` 的浏览器回归。Playwright `--list` 成功发现 `workspace.spec.ts`、`running-edit.spec.ts`、`global-assets-proxy-project.spec.ts`、`csrf.spec.ts` 共 11 项,仅表示发现成功。 - `git diff --check` 通过。测试使用隔离数据库、本机协议 fixture 和注入 API,没有连接真实目标,也未部署、操作真实 data 或执行迁移。 设计与扩展入口见 [核心设计模式](architecture-patterns.md)。 ## 2026-09-27 sing-box 连接资产 原因与范围:验证新增的单 outbound JSON、完整配置/JSON 文件自动提取、安全过滤、外部进程适配、SOCKS5 本地桥接、秘密脱敏和三语界面逻辑。linkport 不捆绑 sing-box;当前测试机执行 `Get-Command sing-box` 无结果,因此本轮没有运行真实 `sing-box check/run`,也没有连接真实代理或目标服务器。 实际通过: - `GOTOOLCHAIN=go1.25.0 go test -p=1 ./internal/model ./internal/outbound ./internal/store ./internal/api -run 'SingBox|GatewayDraftConnection|Redis.*NoAccount|NoAccount' -count=1 -timeout=120s`。四个包均通过。受管沙箱把 `GOCACHE`、`GOTMPDIR`、`TEMP`、`GOMODCACHE` 指向工作区后测试退出码为 0;Go telemetry 仍尝试访问用户目录并输出权限警告,但不影响测试结果。首次未隔离系统临时目录时的拒绝访问不是代码失败。 - `GOTOOLCHAIN=go1.25.0 go vet -p=1 ./...` 通过。`go test -p=1 ./... -count=1 -timeout=120s` 使用本机已有模块缓存离线执行,所有包完成编译;`cmd/linkport`、`internal/api`、`internal/desktop`、`internal/security` 各 1 项及 `internal/store` 2 项在 Windows 文件权限或便携 SQLite 快照操作处返回 `Access is denied`,其余包通过。上述 6 项不位于 sing-box 实现;sing-box 的 model/outbound 全包及 store/api 专项均通过。 - `node web/tests/sing-box.test.mjs`:10 项通过,覆盖协议非硬编码 allowlist、单 outbound/完整配置提取、无远程 outbound 和 URI/本地能力拒绝、64 KiB 与复杂度限制、安全摘要、三语文本、闭合错误映射、编辑时不回填秘密和“检查配置”文案边界。文件导入使用同一 JSON 解析/校验路径;未运行真实 sing-box binary。`node --test` 在当前沙箱因 runner 创建子进程时报 `spawn EPERM`,使用同一测试文件的单进程入口通过。 - `node web/tests/connection-stages.test.mjs` 6 项通过;逐个直接执行 `web/tests/*.test.mjs` 的 10 个单进程逻辑文件时 9 个文件通过,`persistent-target.test.mjs` 的既有重试指引断言 1 项失败,该文件不经过 sing-box 路径。`vue-tsc --noEmit -p web/tsconfig.json` 与 `git diff --check` 通过。 - GitHub Releases API 于 2026-09-27 返回最新非预发布版本 `v1.14.2`(发布时间 2026-09-24);对应官方 `go.mod` 为 `go 1.25.5`,官方 `LICENSE` 为 GPL v3 或更高版本正文并附名称/关联限制。这里只用于文档兼容判断,没有下载或执行该发布 binary。 前端生产构建执行到 Vue 类型检查后,Vite 启动 esbuild 子进程被当前沙箱以 `spawn EPERM` 拒绝。没有生成包含本次界面的新 `web/dist` 或新 executable,因此未运行要求 `LINKPORT_E2E_BINARY` 的 Playwright,也没有用旧程序代替验收。Windows 当前 `CGO_ENABLED=0` 且无 GCC/Clang,未执行 race detector。 fixture 覆盖包括生成仅监听 `127.0.0.1` 且带随机认证的 SOCKS5 入站、强制 route final、目标域名透传、进程共享/退出重启、API 不回显、配置包和历史差异脱敏。伪造 binary/本地协议 fixture 只能证明 linkport 自身编排,不证明某个 sing-box 协议、远端代理、DNS、TLS 或目标账号可用。资产“检查配置”只应解释为 installed binary 接受配置;其失败响应只有固定安全错误类别和耗时,不携带 `sing_box_start` 阶段。目标连接测试才覆盖 `run`、四个 sing-box 运行时阶段和目标协议链路。完整边界见 [sing-box 连接资产](sing-box.md)。 ## 2026-09-27 Kubernetes 端口候选与权限预检 - Go 1.25.0 聚焦测试通过:`go test -p=1 ./internal/model ./internal/outbound ./internal/api -run 'TestUploadedKubeconfig|TestKubernetesPermissionPreflight|TestKubernetesPreflightEndpoint|TestKubernetesDiscovery|TestKubeconfigAssetLifecycleAndReferences|TestAssetMetadataAndKubernetesReadPermissions' -count=1 -timeout=120s`;改动包执行 `go vet -p=1 ./internal/model ./internal/outbound ./internal/api` 通过,完整仓库执行的 `go vet -p=1 ./...` 也通过。测试使用工作区 `TEMP/TMP/GOTMPDIR/GOCACHE`,Go telemetry 写入用户目录被拒绝的警告不影响测试结果。 - `go test -p=1 ./... -count=1 -timeout=120s` 未全绿:`cmd/linkport`、`internal/api`、`internal/desktop`、`internal/security` 各 1 项及 `internal/store` 2 项因既有 Windows ACL/便携 SQLite 快照环境失败;其余包通过,`internal/outbound` 全包通过。 - 后端 fixture 使用本机 TLS HTTP Server 模拟 Kubernetes `SelfSubjectAccessReview`,验证允许、拒绝、未知、评估错误、API 禁止审查、Pod 名称限定、资产类型/端口校验、认证保护及不回显 Token/上游原因。模型、发现、预检、资产 API 和正式启动入口回归另覆盖 `certificate-authority`、`client-certificate`、`client-key`、`tokenFile`、`exec` 与 `auth-provider` 在客户端构造或网络请求前被拒绝,并检查资产 API 的稳定错误码。没有连接真实集群,不证明现场 RBAC 或 SPDY port-forward 成功。 - `vue-tsc --noEmit -p web/tsconfig.json` 和单进程 `node web/tests/tcp-kube-forward.test.mjs` 7/7 通过;Playwright `--list` 发现 `tcp-kube-forward.spec.ts` 2 项,其中新断言覆盖自动端口建议、候选切换、预检查询参数与逐项结果。 - `npm.cmd --prefix web run build` 完成 Vue 类型阶段后,Vite 默认配置加载和 `--configLoader native` 都因当前沙箱禁止 Node 创建子进程而报 `spawn EPERM`;`web/dist/.gitkeep` 保留。未生成包含本次界面的新程序,因此未执行需要 `LINKPORT_E2E_BINARY` 的 Playwright,不把用例发现或旧程序结果记为浏览器通过。 ## 2026-09-26 运行中编辑目标与网关配置 - 行为覆盖:运行中的目标与网关编辑入口保持可用;目标更新为所有引用网关批量发布新快照,监听变更先预绑定再提交;旧连接继续使用旧快照,新连接使用新快照。启动/停止状态与配置在同一生命周期锁内持久化,保存失败保持原运行状态。CAS 冲突返回 409;SSH/SFTP 候选主机先匿名探测并二次核对指纹。 - Go 1.25.0 定向回归通过:`go test -p=1 ./internal/gateway ./internal/api -run 'Test(UpdateConfig|StartFrom|StopAndPersist|StoppedUpdate|GatewayLifecyclePersistence|RunningConfiguration|LiveConfigCAS|RunningSSHTarget|RunningSFTPTarget)' -count=1 -timeout=120s`。随后 gateway 全包和跳过既有 portable snapshot 环境项的 API 全包通过;新增 API 生命周期测试确认 enabled 保存失败释放候选端口、disabled 保存失败保持监听。 - `go vet ./...` 在 Go 1.25.0 下通过。规定的 `go test ./... -count=1 -timeout=120s` 未全绿:`cmd/linkport`、`internal/api`、`internal/desktop`、`internal/security` 各 1 项及 `internal/store` 2 项因既有 Windows ACL/便携 SQLite 快照环境失败;未修改的 PostgreSQL prepared-session identity fixture 另有间歇失败,单次复跑通过,20 轮复跑仍可间歇复现。`internal/gateway` 全包通过,`internal/api` 除上述既有快照项外通过。 - `web/node_modules/.bin/vue-tsc.cmd --noEmit -p web/tsconfig.json` 通过。Playwright `--list` 发现 3 个相关文件共 19 项,包括运行中目标/网关编辑、SSH 候选确认取消后重试,以及关闭结果页后“连接成功”和“实测连接阶段”均消失。 - `npm.cmd --prefix web run build` 的类型检查完成,Vite 加载配置时因当前 Windows 沙箱禁止 Node 启动 esbuild 而报 `spawn EPERM`;`web/dist/.gitkeep` 保持存在。未生成包含本次改动的新前端或可执行程序,故没有运行要求 `LINKPORT_E2E_BINARY` 的 Playwright,也不把用例发现或旧程序结果记作通过。 - 所有后端新增测试使用隔离 SQLite、本机 TCP 或 SSH fixture;`running-edit.spec.ts` 只启动隔离本地 listener,目标为不会实际连接的占位地址,不是真实 MySQL 服务。本轮未读取或修改真实 `data/linkport.sqlite`、审计、TLS 或主密钥文件。 ## 2026-09-26 连接测试结果关闭清理 - 目标草稿连接测试关闭结果页后会清空全局详情、编辑器内联成功/失败摘要及“实测连接阶段”,但保留草稿、测试账号选择和未保存状态。`workspace-features.spec.ts` 已改为回归结果页和两类残留状态均消失。 - `web/node_modules/.bin/vue-tsc.cmd --noEmit -p web/tsconfig.json` 通过。把 `TEMP`/`TMP` 指向工作区隔离目录后,Playwright `--list` 成功发现 `workspace-features.spec.ts` 的 3 项用例,包括本次回归。 - `npm.cmd --prefix web run build` 的 Vue 类型检查通过,Vite 启动 esbuild 时因当前 Windows 沙箱禁止 Node 创建子进程而报 `spawn EPERM`;直接执行同一 esbuild 程序成功、由 Node `spawnSync` 执行则稳定返回 `EPERM`。因此本轮没有新的前端产物或嵌入式程序,未运行要求新程序的 Playwright,也不把测试发现记为浏览器通过。`web/dist/.gitkeep` 仍保留。 - Go 1.25.0 使用工作区隔离的 `TEMP`、`GOTMPDIR` 和 `GOCACHE`。`go test ./... -count=1 -timeout=120s` 中除 6 项既有 Windows ACL/SQLite 快照环境失败外其余包通过:`cmd/linkport`、`internal/api`、`internal/desktop`、`internal/security` 各 1 项,`internal/store` 2 项;整套不记为通过。`go vet ./...` 首次因并发 vet 子进程 `exit status 9` 中止,串行 `go vet -p=1 ./...` 通过。 - 浏览器回归中的远端连接响应为路由 fixture,但本轮未实际执行该用例;完整 Go 测试中的协议包使用仓库本地 fixture,不是真实服务器验收。未停止本地服务,未读取或修改真实 `data`。 ## 2026-09-26 网关 TCP Kubeconfig 独立端口转发 ### 主代理最终复验 - `GOTOOLCHAIN=go1.25.0 go test ./... -count=1 -timeout=120s` 已实际执行;本功能涉及的 `model`、`gateway`、`outbound`、`tcpproxy` 及新增 API/存储用例通过。全量仍有 6 个既有 Windows ACL/SQLite 快照环境失败:`cmd/linkport` 1 个、`internal/api` 1 个、`internal/desktop` 1 个、`internal/security` 1 个、`internal/store` 2 个,因此不记为全量通过。 - `go vet ./...` 首次因环境并行启动 `vet.exe` 被拒绝;使用同一 Go 1.25.0 工具链执行 `go vet -p=1 ./...` 通过。原有 SOCKS5 边界回归 `go test -p=1 ./internal/api -run '^TestTCPIndependentBoundary' -count=1 -timeout=120s -v` 的 5 项测试及全部子测试通过。 - 前端最终复跑:`node tests/tcp-kube-forward.test.mjs` 6/6、`node tests/account-mapping.test.mjs` 5/5,生产构建命令的 Vue 类型检查阶段通过;Vite 启动 esbuild 时被当前 Windows 环境以 `spawn EPERM` 拒绝,未生成新前端产物。 - 工作区 `TEMP`/`TMP` 下的 Playwright `--list` 成功发现 `tcp-kube-forward.spec.ts` 与 `tcp-independent.spec.ts` 共 3 项。由于无法构建包含本次界面的新可执行程序,未执行这些浏览器用例,也未用旧程序替代验收。`web/dist/.gitkeep` 保持完好。 - Go 1.25.0 模型专项通过:`go test -p=1 ./internal/model -run 'TestIndependent(TCP|Kubernetes)' -count=1`。覆盖 K8s 资产解析与运行时出口构造、持久化裁剪、缺失正文、无效模式/Context/命名空间/资源/端口、两种模式字段互斥和旧 SOCKS5 空 `mode` 兼容。 - Go 1.25.0 存储专项通过:`go test -p=1 ./internal/store -run 'TestIndependent(TCP|Kubernetes)' -count=1`。覆盖网关原始密文解封后只含资产引用、不含测试 Token,Get/List 注入当前资产正文,直接引用的删除保护,无效 Kubeconfig 更新在写入前拒绝且旧内容不变,完整加密备份/恢复,以及缺失或错误类型资产拒绝。 - Go 1.25.0 API 专项通过:`go test -p=1 ./internal/api -run 'TestIndependentKubernetesTCPForward' -count=1 -timeout=120s`。覆盖创建/读取响应不包含测试 Token 或运行时正文,直接引用出现在资产响应并阻止删除,缺失/错误类型资产返回 400,运行中资产更新返回 409,以及 K8s 与 SOCKS5 双向更新不遗留异类字段。 - 既有出口专项通过:`go test -p=1 ./internal/outbound -run 'Test(Kubernetes|UploadedKubeconfig)' -count=1 -timeout=120s`,覆盖模拟 API/SPDY 双向流、取消、Service 端口解析、上传正文替换和持久隧道生命周期。模型全包通过;Store 全包仅 2 项既有 Windows 快照权限用例失败,API 全包仅既有 portable SQLite snapshot 用例失败,因此不记为三包全量通过。`go vet -p=1 ./internal/model ./internal/store ./internal/api` 通过。 - 在 `web` 目录执行 `node tests/tcp-kube-forward.test.mjs` 6/6、`node tests/account-mapping.test.mjs` 5/5、`npm.cmd exec vue-tsc -- --noEmit -p tsconfig.json` 通过。领域测试验证 K8s payload 只含资产 ID/Context/命名空间/资源/端口,模式双向切换不会遗留异类字段,空命名空间摘要使用当前 Context,连接测试视图不含 Kubeconfig 正文。 - 第一次列举 Playwright 用例时,系统临时目录被拒绝并显示 0 项;把 `TEMP`/`TMP` 指向工作区后,`npm.cmd test -- --list tests/tcp-kube-forward.spec.ts` 成功发现 2 项,分别覆盖 Kubeconfig 新建/回读和旧无 `mode` SOCKS5 回读、原样保存后切换 K8s。这里只完成用例发现,尚未使用本轮新构建程序执行浏览器用例。 - 首次 Go 专项尚未进入测试:系统临时目录创建被环境拒绝;改设 `GOTMPDIR`/`GOCACHE` 后并行首次编译又因资源限制出现 `compile.exe: exit status 9`。最终把 `TEMP`、`TMP`、`GOTMPDIR` 和 `GOCACHE` 指向工作区隔离目录,并设置 `GOMAXPROCS=2`、`-p=1` 后,上述模型和存储专项分别通过。这里记录的是环境失败及成功复跑,不把未执行测试的命令算作业务失败。 - 存储拨号验证使用本机 `httptest` TLS Kubernetes API fixture,确认运行时读取引用资产中的 Bearer Token,并请求所选命名空间和 Deployment;fixture 主动返回 403,因此没有建立 SPDY 数据流。仓库既有 Kubernetes 传输测试使用模拟 API 与 SPDY fixture 验证 port-forward;这些均不是实际 Kubernetes 集群验收,不覆盖现场证书、RBAC、网络策略、代理或具体工作负载。 - 所有新增存储和 API 测试使用隔离 SQLite、临时端口与测试资产;未读取、修改、迁移或部署真实 `data/linkport.sqlite`、审计、TLS 或主密钥。最终全量 Go、前端生产构建和 Playwright 结果在完成后继续补充到本节。 ## 2026-09-26 Redis 上游零账号(2026-09-28 扩展) - Redis 和 MongoDB 目标及网关均可保存空账号列表;草稿/已保存测试、集群识别、手动与周期健康检查、启动、切换和画板关联把空字符串账号 ID 作为明确的无认证端点。TCP 使用相同空 ID 表示空账号。任一服务配置真实账号后继续强制选择有效账号,不把空端点与缺失映射混淆。 - Go 1.25.0 下 model、cluster、gateway、redisproxy 全包及 Redis API 定向回归通过,`go vet -p=1 ./...` 通过。最终 `go test -p=1 ./... -count=1 -timeout=120s` 中功能相关包均通过,但全量仍有 6 项既有 Windows 权限/SQLite 快照失败:`cmd/linkport` 的运行服务恢复保护、`internal/api` 的 portable SQLite snapshot、`internal/desktop` 的单文件/锁、`internal/security` 的私有文件覆盖保护,以及 `internal/store` 的两个 snapshot 用例。首次未限制并发的全量运行另遇编译子进程 Access denied,最终以串行结果为准,不宣称 Go 全量通过。 - 全部 16 个 `web/tests/*.test.mjs` 单进程领域测试文件通过,其中 Redis/MongoDB/TCP 空账号 13 项、持续连接组件 6 项、连接草稿 8 项、连接画板 8 项;`vue-tsc --noEmit -p web/tsconfig.json` 与串行 `go vet -p=1 ./...` 通过。草稿和编辑器夹具逐一覆盖全部 11 种协议,并验证旧目标不继承新建默认值。Playwright `--list` 在工作区 TEMP 下成功发现 60 个文件中的 138 项用例。Vite/esbuild 被当前 Windows 沙箱的 `spawn EPERM` 阻止,无法生成新的 `dist` 和嵌入式可执行程序,因此按必须使用新构建程序的规则未运行 E2E,不宣称前端生产构建或 E2E 通过。 - 普通 Redis、Cluster、Sentinel 和 `HELLO AUTH` 覆盖使用本机 RESP/net.Pipe fixture,确认零账号路径不发送上游 `AUTH`;没有连接真实 Redis/Sentinel,也没有停止本地服务、部署迁移或修改真实 `data`。 ## 2026-09-22 目标后台持续连接 本节记录 2026-09-22 引入 `connectionOptions.persistent` 时的验证;当时默认关闭。2026-09-28 起,管理界面的 11 种新建目标草稿默认开启,旧配置不自动改写;仍仅在引用网关运行时维持后台资源。当前使用入口、兼容边界与原因见 `persistent-targets.md` 和 `change-rationale.md`。 2026-09-28 默认值调整的实际验证为连接草稿 8/8、持续连接组件 6/6、Vue 类型检查、串行 `go vet -p=1 ./...` 和 `git diff --check` 通过;Playwright 已发现逐一切换 11 种类型的用例,但因 Vite/esbuild `spawn EPERM` 未运行浏览器。以下结果保留为 2026-09-22 首次实现时的历史验收记录。 - Go 1.25.0:`go test ./... -count=1 -timeout=120s` 全量通过,日志 `artifacts/persistent-final-go-test.log`;`go vet ./...` 通过。 - Node 22.22.3:`npm.cmd --prefix web run build` 通过,仅有 Vite chunk 大小警告。构建完成后恢复 `web/dist/.gitkeep`,再编译嵌入前端的最终程序 `artifacts/linkport-persistent-final.exe`。 - 最终程序 SHA256:`D52C30CCF34A4FB785B0F0433299B12139342E97CDBC315729A047E83A9B69AC`。 - `node --test web/tests/persistent-target.test.mjs`:**6/6 通过**。针对持续连接和工作区列设置的 Playwright:**6/6 通过(16.1 秒)**,日志 `artifacts/persistent-verified-focused.log`。 - 全量 Playwright 通过 `LINKPORT_E2E_BINARY` 指向上述最终程序,使用隔离 SQLite 和端口 19481/19482:**124/124 通过(6.6 分钟)**。日志 `artifacts/persistent-full.log`,辅助日志 `artifacts/persistent-full.err.log`,产物目录 `artifacts/persistent-full-results`。完成后两个测试监听端口均已释放。 - 初步定向浏览器运行暴露不完整 runtime mock 及表格 expand 结构列被过滤的问题;已改用真实 API 基础配置构造 mock,并修复表格保留结构列。以上成功结果来自修复后的最终程序。状态展示测试模拟 runtime,不等同于真实远端可用性验收。 - 四种数据库协议和 SSH/K8s 使用本地受控 fixture;Redis 网关集成验证无客户端预认证、首次借用、补充新备用会话及停止释放,重复 5 次通过;隧道生命周期相关用例重复 20 次通过。未连接用户真实 MongoDB/K8s,不修改真实目标数据。 - Linux/amd64、Darwin/amd64 的 gateway/outbound 测试程序交叉编译通过,未在对应系统执行。当前 CGO 禁用,未运行 race detector,不宣称 race 检查通过。 - 本轮未部署、未提交,未修改真实 `data` 目录。 ## 2026-09-22 独立 TCP 端口转发 本节记录独立网关 `type: "tcp"` + `tcpForward: {host, port, outboundId}` 的本轮验证,不替代下方其他工作批次的历史结果。功能不要求创建目标服务,也不自动生成目标;使用已有 SOCKS5 代理透传 TCP,不处理业务账号、协议或 TLS。使用说明与兼容边界见 `tcp-port-mapping.md`,设计原因见 `change-rationale.md`。 - 使用 `GOTOOLCHAIN=go1.25.0` 执行 `go test ./... -count=1 -timeout=120s`:通过。 - 使用 Go 1.25.0 执行 `go vet ./...`:通过。 - 新增 `internal/api/tcp_independent_validation_test.go`,执行 `go test ./internal/api -run '^TestTCPIndependentBoundary' -count=1 -timeout=120s -v`:**5 项测试、21 项子测试通过**。覆盖无效代理/字段、账号冲突、部分更新、模式切换、引用重绑定、代理改类型及 impact 影响范围响应脱敏。 - 首次执行 `scripts/build.ps1 -SkipTests`:成功完成前端 npm build 和 Go 1.25.0 编译;当时 Node 22.10 触发 Vite 版本要求警告,不将成功构建等同于该版本符合 Vite 支持要求。 - 补充图视图调整后,使用机器已有 Node 22.22.3 再次执行 `scripts/build.ps1 -SkipTests`:成功完成 npm build 和 Go 1.25.0 编译,生成同一路径的最终程序 `artifacts/tcp-independent/linkport.exe`。此次没有 Node 版本警告,仅保留 chunk 大小警告。`-SkipTests` 不表示构建脚本执行了测试,Go 测试结果来自独立执行。 - 最终重建前,Playwright 通过 `LINKPORT_E2E_BINARY` 指定当时的新构建程序,`tcp-independent.spec.ts` 与 `tcp-forwarding.spec.ts` 共 **2 项通过**;最终程序的全量回归结果另列如下。 - 新增 API 测试 `TestIndependentTCPForwardTwoRoutes` 使用本地带密码 SOCKS5 fixture,把两条独立网关映射转发到本地 TCP fixtures,并校验二进制字节。该结果证明受控环境中的 SOCKS5 认证与两条 TCP 数据转发链路,不是对真实用户 `192.168.11.16:8080/8082`、生产代理、业务认证或 TLS 的验收。 - 全量 Playwright 首次使用默认 Node 22.10,因 `node:sqlite` 不可用而在测试发现阶段失败。随后执行 `fnm use 22.22.3`,仅对当前 shell 切换至机器已有版本,成功发现并启动 121 项测试;未安装新版本或修改持久系统环境。 - 上述一次全量运行执行到 59 项时,被执行工具的 **200 秒时限中断**,未获得完整结果;这是执行时限中断,不是测试用例失败结论。随后已延长时限完成最终重跑。 - **最终完整 Playwright:121/121 通过(6.6 分钟)。** 使用 Node 22.22.3,设置 `LINKPORT_E2E_BINARY=artifacts/tcp-independent/linkport.exe`,在隔离端口 `19281/19282` 运行;日志 `artifacts/tcp-independent-playwright-final.log`。该程序包含最终图视图修复,本条为本轮最终全量结果,不借用其他批次的成功记录。 本次图视图还调整为纯端口转发不显示“未关联目标”提示、禁止拖到目标绑定并保留手动测试按钮;这些调整已纳入最终构建,并随上述 121 项完整浏览器回归通过。 验证边界:独立模式没有目标周期健康检查,只有手动连接测试和运行指标;原目标关联模式的周期检查覆盖不能推广为独立模式覆盖。批量创建只递增监听端口,不递增目的端口。本轮没有以示例中的私网地址进行真实远端验证。 ## 2026-09-22 连接诊断、资产影响、监听指标与完整 SQLite 备份 - Go 固定 `GOTOOLCHAIN=go1.25.0`,最终源码执行 `go test ./... -count=1 -timeout=120s` 全部通过,包括此前失败的 API 与 cluster;日志 `artifacts/optimizations-verified-go-test.log`,错误日志为空。`go vet ./...` 通过。 - MySQL 集群发现修复后,主节点发现与结果字符串生命周期测试重复 1,000 次、cluster 包重复 20 次通过;不增加重试或放宽断言,详见 `internal/cluster/README.md`。 - `node --test web/tests/account-mapping.test.mjs web/tests/connection-stages.test.mjs`:8/8 通过,覆盖账号选择、协议匹配、authSource、闭集诊断清理与中英日阶段说明。Node 22.10 的直接 `.ts` 导入失败已通过与既有测试一致的内存转译加载修复。 - 前端 `npm.cmd --prefix web run build` 通过,最终使用已有 Node 22.22.3,仅保留 Vite 大 chunk 警告;恢复 `web/dist/.gitkeep` 后构建内嵌资源的 Windows executable。曾因默认 PATH 的 Node 22.10 缺少无标志 `node:sqlite` 导致全量用例发现失败,切换已有兼容运行时后重跑,未修改系统 PATH 或安装工具。 - 首轮 Playwright 为 113 通过、6 失败;修复窄屏布局、草稿类别取消、旧 K8s 出口残留,以及过时的确认流程/Element Plus 定位断言。随后在隔离端口 19181/19182 使用 `LINKPORT_E2E_BINARY=artifacts/linkport-optimizations-final.exe` 完整回归:**120/120 通过(6.6 分钟)**,日志 `artifacts/optimizations-final-playwright.log`。该二进制包含界面与诊断修复,但早于最后的 MySQL 结果生命周期修复,因此另行构建最终 verified 程序复验。 - 最终程序 `artifacts/linkport-optimizations-verified.exe` 包含 MySQL 修复,在隔离端口 19281/19282 再跑完整 Playwright:**120/120 通过(6.4 分钟)**,日志 `artifacts/optimizations-verified-playwright.log`,截图目录 `artifacts/optimizations-verified-results`。程序 SHA256 为 `a51cc6a5e05070c663da0e3f385a02b0c6646a2a7c44d0f7ae2d7f91307e6012`。最终 `git diff --check` 与变更 Go 文件的 gofmt 检查通过。 - `internal/security` 和 `internal/gateway` 在 Linux/amd64、Darwin/amd64 的 `go test -c` 交叉编译均通过;没有在这些系统运行测试,不能等同于平台实机验收。 - 协议验证使用隔离 SQLite、本机 TCP/SSH/Kubernetes/数据库 fixture;完整备份测试覆盖已提交 WAL、库内密钥、管理员、目标、审计、自动 TLS、摘要确认、保底快照、停服锁和拒绝 API token。浏览器覆盖完整库下载、检查与风险确认后显示离线恢复指令;没有恢复真实 data 或修改真实目标数据。阶段 UI 与 SSH 探测 UI 的部分响应为模拟,不声称真实远程服务认证成功。 - 未部署、未提交或推送;真实 `data`、审计及 TLS/旧 DPAPI 材料保留。恢复为显式停服命令,不提供运行中覆盖数据库。服务端含密钥的暂存文件写入前应用 Windows 当前用户/SYSTEM DACL 或 Unix 0600;浏览器下载目录权限仍由用户管理。 ## 2026-09-22 脚本相对路径与跨机器调用 - 从系统临时目录而非项目目录调用 Windows PowerShell 测试:go-toolchain.test.ps1 的 12 项断言、node-toolchain.test.ps1 的 8 项断言通过。覆盖项目便携工具优先于 PATH、项目相对覆盖、错误覆盖不降级、配套 npm、带空格目录与缺失提示。使用临时伪文件,不执行或安装工具,不修改持久环境变量。 - Node 内置测试 `node --test scripts/project-paths.test.mjs` 三项通过:验证脚本复制到带空格/方括号的新目录后,路径仍以新项目为基准,并从无关目录启动子进程验证;同时检查三个验证脚本与浏览器启动器使用统一解析,以及维护脚本没有固定盘符/机器安装目录扫描。 - 所有 scripts/*.ps1 的 PowerShell 语法解析通过;Git Bash 分别对 build.sh、test-matrix.sh 和容器 start-replica.sh 执行 `bash -n` 通过。未在实际 Linux/macOS 上构建,也未启动 Docker 协议矩阵。`git diff --check` 通过。 - 从项目外调用 scripts/start-dev.test.ps1 既有隔离回归通过,覆盖相对入口、调用目录、构建锁、参数/失败隔离、数据路径、备份及错误保护;使用临时程序 fixture,不接触真实服务和数据库。 - 实际从项目外调用 `start-dev.ps1 -BuildOnly`:正确定位项目、Go 与 Node,前端构建通过(仅现有大 chunk 警告);随后 Go 编译被工作区并行新增的 internal/outbound/kubernetes.go:184 中 done 重名/类型冲突阻断。本轮没有修改该业务文件,也没有用上次候选程序假装完成新构建。打包和 Playwright 后续步骤因新程序未生成而未执行。 - 上一版工具发现实现的 BuildOnly 成功日志保留在 artifacts/go-discovery,但不能替代最终相对路径版本的完整构建验证。本轮日志位于 artifacts/relative-scripts;未重跑全量 Go/go vet/UI,不宣称全量通过。未部署、提交或修改真实数据,其他并行工作区改动保持原样。 ## 2026-09-22 WebDAV 同步备份替代 S3 - 使用 Go 1.25.0 运行 `go test ./... -count=1 -timeout=120s`:本次变更涉及的 backup、syncjob、store、api、model、MongoDB/HTTP 协议包均通过;全量仅 internal/cluster 的 TestMySQLReplicationAndGroupDiscovery/mysql-group-replication 失败,报 `cluster has no available primary or router`,与本文件此前记录的既有间歇失败一致。本轮未修改该逻辑,不将全量 Go 标记通过。日志 artifacts/webdav-sync/go-test.log。 - `go vet ./...`、`npm.cmd --prefix web run build` 通过,前端只有现有大 chunk 警告。Vite 完成后恢复 web/dist/.gitkeep,再构建 artifacts/webdav-sync/linkport.exe,未覆盖正式程序。 - 设置 LINKPORT_E2E_BINARY 指向新程序,使用隔离 SQLite 与 19491/19492 端口:全量 Playwright **113 通过、4 失败(6.4 分钟)**。四项仍为 global-assets-proxy-project:98、kubeconfig-selection:23、target-outbound-selection:3、workspace:98,分别涉及资产草稿、目标字段显示及连接错误文本;与之前合并及空密码版本相同,不宣称全量浏览器通过。日志 artifacts/webdav-sync/full-web.log;最终退出状态见 results.json。 - 新 WebDAV 两项、目标认证七项均在完整浏览器运行中通过;此前 WebDAV/menu-search/target-auth 专项组合 11 项通过(26.3 秒,focused.log)。覆盖响应式布局、保存和秘密清空、冲突确认、独立备份以及实际隔离 API 到本机 WebDAV 上传的链路。 - Go HTTP fixture 覆盖目录和路径编码、Basic/匿名、强 ETag、条件创建/覆盖、拒绝重定向与错误正文泄漏、大小限制、两设备同步与冲突、租约、旧 S3 设置隔离。独立备份测试验证加密可解密、凭据可恢复、文件名唯一、共享文件不被访问且基线/冲突不变;API 测试覆盖跨地址/用户名不继承旧密码、显式清除及会话/CSRF/API Token 边界。 - 协议测试是 Go fixture,端到端 WebDAV 服务是 Node fixture,未连接外部真实 WebDAV 服务,不能据此保证任意服务商的条件写入兼容。智能体只读复核未发现阻断问题;同步和备份共用最近执行状态的边界已写入 docs/webdav-sync.md。 - 测试进程退出后隔离端口已释放;`git diff --check` 通过。没有部署、提交、修改真实数据库或目标数据。升级说明要求停服备份完整 data 后再运行新版;当前仍保留工作区原有 SSH 指纹改动。 ## 2026-09-22 目标空密码与无认证连接 - Go 1.25.0 `go test ./... -count=1 -timeout=120s` 和 `go vet ./...` 均通过,结果记录 artifacts/target-auth/go-result.json。新增模型/API 用例覆盖仅允许指定协议无认证、具名空密码、显式清除、草稿不落库及网关认证保留。 - MongoDB 和 HTTP 使用本机上游 fixture,验证无认证请求、网关错误密码拒绝及 Authorization 不泄漏;Redis 无凭据时跳过 AUTH 由现有 fixture 覆盖,没有连接实际生产服务器。 - 前端构建和新程序构建通过。使用隔离 SQLite/端口运行无认证版本全量 Playwright:112 通过、4 失败(6.4 分钟),日志 artifacts/target-auth/full-web.log。失败为 global-assets-proxy-project:98、kubeconfig-selection:23、target-outbound-selection:3、workspace:98,与此前合并验证相同,涉及资产草稿断言、目标字段显示和连接错误文本,不宣称全量通过。 - 随后与 WebDAV 专项一起运行 target-auth.spec.ts 全部 7 项通过(组合共 11 项,artifacts/webdav-sync/focused.log),包括新建空密码、无认证表单/草稿、旧账号默认模式、显式清除、协议限制及手机布局。浏览器部分远程结果使用模拟,不代表真实目标兼容验证。 - 未部署或修改实际目标数据,保留工作区已有 SSH 跳过指纹改动;本项无需数据库迁移。 ## 2026-09-22 SSH 转发可选跳过指纹 - Go 1.25.0 `go test ./... -count=1 -timeout=120s` 全部通过(本轮 cluster 亦通过),日志 artifacts/ssh-skip-go-test.log;`go vet ./...` 通过。 - `npm.cmd --prefix web run build` 通过,仅大 chunk 提示;恢复 web/dist/.gitkeep 后构建新程序 artifacts/linkport-ssh-skip.exe。未替换正式程序或访问真实数据库。 - 使用 LINKPORT_E2E_BINARY 指定新程序,在隔离端口/SQLite 运行 ssh-forward-skip.spec.ts、host-identity.spec.ts:3 项通过(13.5 秒)。新增用例首次因 Element Plus 隐藏 checkbox 的操作方式及校验文本定位失败,修正测试定位后重跑通过。本次未重跑全量浏览器套件。 - 新增模型测试验证仅显式开关允许空指纹、仍要求密码。SSH fixture 验证空/错误指纹跳过、实际转发字节回显、返回实际服务器指纹、错误密码拒绝及关闭跳过后的严格校验;不声称真实 SSH 跳板机验证。 ## 2026-09-22 合并 origin/main 943ea75 - 前端 `npm.cmd --prefix web run build` 通过(仅大 chunk 提示);Windows Go 1.25.0 新程序构建通过,恢复并保留 web/dist/.gitkeep。 - `go test ./... -count=1 -timeout=120s`:除 internal/cluster 的 TestMySQLReplicationAndGroupDiscovery/mysql-group-replication 返回 `cluster has no available primary or router` 外全部包通过。该失败在合并前已有记录;本次未改集群发现代码。`go vet ./...` 通过。 - Linux/amd64、Darwin/amd64 的 `go test -c ./internal/desktop` 通过;仅交叉编译,未在对应系统实际启动。 - `node scripts/verify-package.mjs artifacts/merge-verification-20260922/package`、`node scripts/verify-desktop.mjs artifacts/merge-verification-20260922/package/linkport.exe` 均通过,覆盖单 EXE、内嵌资源、隔离登录、库内主密钥、自动 TLS、重启与目录迁移。桌面脚本首次在清理阶段重复等待已退出进程,修复后完整重跑通过。 - 启动脚本隔离回归使用 Windows PowerShell 运行 `scripts/start-dev.test.ps1` 通过。PowerShell 7 的 Add-Type 不支持测试 fixture 所需 ConsoleApplication;Windows PowerShell 首次又发现 fixture 未创建旧 desktop.lock,改为在隔离目录 OpenOrCreate 后通过。不修改真实数据库或服务。 - Playwright 使用 LINKPORT_E2E_BINARY 指定本次新编译程序、隔离 SQLite 和 18681/18682 端口:**104 通过、4 失败(6.1 分钟)**。失败位于 global-assets-proxy-project、kubeconfig-selection、target-outbound-selection、workspace 各一项,涉及资产草稿断言、目标字段显示及连接错误文本;不将全量浏览器回归标记为通过。TCP 映射、请求诊断元数据、范围维护、保存/标签页和响应式专项均在本轮通过。 - 日志、截图和测试程序位于忽略目录 artifacts/merge-verification-20260922;协议测试使用本机 fixture,并非真实 MongoDB/K8s 生产连接验证。没有部署、推送或真实数据迁移。 以下为历史分支验证记录,不替代本节合并结果。 ## 2026-09-21 TCP 端口映射 - Go 1.25.0 全量命令 `go test ./... -count=1 -timeout=120s` 已运行两次;除 `internal/cluster` 的 `TestMySQLReplicationAndGroupDiscovery` 外其他包通过。该未改动测试在 mysql-replication / mysql-group-replication 子用例间歇返回 `cluster has no available primary or router`,单独 `-count=20` 也出现五次失败。本轮没有修改集群发现逻辑,不将全量 Go 测试标记为通过。日志:artifacts/tcp-go-test.log、artifacts/tcp-go-test-final.log。 - 本次相关 API、model、gateway、outbound、tcpproxy 包测试通过;最后补充断连必须非超时、认证计数不伪造以及出口包装半关闭测试后,model/gateway/outbound/tcpproxy 四包复跑通过。`go vet ./...` 通过。 - 新测试覆盖 TCP 无账号创建/保存/测试/断开、默认 0.0.0.0、拒绝只读及 TLS 终止、普通协议约束保留、直连/SOCKS5/SSH/K8s 配置、真实 loopback 字节透传与半关闭、取消清理、来源白名单与连接数限制、运行中切换断开旧连接并让重连使用新目标、停服断连及无账号定时健康检查。上游和 SSH/K8s 测试均为本地 fixture,并非生产目标验证。 - `npm.cmd --prefix web run build` 通过(仅 chunk 大小警告),Vite 完成后生成 artifacts/linkport-tcp-forwarding.exe;恢复 web/dist/.gitkeep。使用该新程序和隔离端口/SQLite,TCP、账号级连线、网关路径、断开重连、多对一六项回归通过(20.9s)。检查了 TCP 连线图截图。 - 全量浏览器运行中,新增 TCP 用例受到其他测试遗留资源影响,长画布拖拽定位失败;为用例的目标和网关增加独立项目筛选后,与 gateway-management、target-accounts 连续复跑六项通过(17.1s),含本机二进制字节回显。产品源码未因此变化。完整 UI 结果记录见下方补充;不能用专项通过替代全量通过。 - 完整 Playwright:97 通过、10 失败(10.0m,日志 artifacts/tcp-playwright.log)。除上述随后修正并复跑通过的 TCP 测试外,其余九项为此前相同失败集合:account-editor 一项、global-assets-proxy-project 两项、kubeconfig-selection 一项、target-outbound-selection 一项、workspace-features 三项、workspace 一项。修正测试隔离后未再次运行全量,只复跑上述相关组合;不将完整 suite 标记通过。 - 未替换 bin/linkport.exe,未操作正式数据,也未提交本次改动。新程序需单独部署后功能才生效。 ## 2026-09-21 MongoDB 网关非 admin 认证库 - Go 1.25.0:`go test ./... -count=1 -timeout=120s`、`go vet ./...` 通过。 - `TestGatewayAuthenticationDatabase` 覆盖 admin、ttx-xwms-test、speculative SCRAM;拒绝错误密码、未知用户名、空认证库和会话中切换认证库。`TestOfficialDriver` 扩展为两种认证库与读写/只读的四组合,均通过。使用官方 Go 驱动和本地上游 fixture,未连接真实目标,未测试 Java 驱动。 - `npm.cmd --prefix web run build` 通过(仅 chunk 大小警告);Vite 完成后构建 `artifacts/linkport-mongo-authsource.exe`,恢复 dist/.gitkeep。 - 设置 `LINKPORT_E2E_BINARY` 指向该新程序,隔离端口 18381/18382 和临时 SQLite;gateway-connection-path、account-targets、connection-diagnostics 六项 Playwright 通过(12.3s)。本次仅复跑相关浏览器用例,未重跑全量 UI;此前全量失败记录仍保留,不宣称全量 UI 通过。 - 未替换运行中的 bin/linkport.exe,未修改实际数据库或目标数据。 ## 2026-09-21 网关账号到目标账号的路径测试 - 最终目标多账号常驻展开版本:前端构建后生成 linkport-multi-account.exe;gateway-connection-path、account-targets、many-to-one、disconnect 五项专项回归通过(18.3s)。account-targets 另行截图复跑一项通过(4.5s),已检查 desktop/mobile 截图;覆盖未选择源时账号可见、选择前后位置稳定、账号级连线及独立映射。 - 前一个 linkport-account-path.exe 的完整 Playwright 结果为 97 通过、9 失败(9.9m)。失败为 account-editor 一项、global-assets-proxy-project 两项、kubeconfig-selection 一项、target-outbound-selection 一项、workspace-features 三项、workspace 一项,与此前记录的失败集合一致。该全量运行不包含最后的目标账号常驻展开改动,不能代替最终版本的全量验证;最终版本仅运行上述专项回归。两份程序均未部署覆盖正在运行的服务。 - `TestGatewayConnectionUsesAccountMapping` 与原有 `TestConnectionErrorsExposeStageWithoutDiagnostic` 通过,使用隔离 SQLite 和 recording handler;覆盖无默认目标的账号选路、目标凭据/地址/SOCKS5 出口、拒绝未知和禁用账号、测试不改映射。 - `go test ./... -count=1 -timeout=120s`(Go 1.25.0)、`go vet ./...`、前端生产构建通过。构建仅有 chunk 大小警告。 - account-targets、connection-diagnostics、gateway-connection-path 共六项 Playwright 通过。补充多账号显式选择后,gateway-connection-path 两项复跑通过,验证请求 query、实际目标账号、K8s 资源路径及不泄露凭据/原始错误;单账号拖拽不改其他映射。新增 fixture 最初漏填 TargetTLS=false 被正常拒绝,修正测试配置后通过;多账号选择测试改为点击 Element Plus select 容器后通过。 - 使用新嵌入式 linkport-account-path.exe、隔离端口/SQLite;完整日志位于 artifacts/mongo-live-check-20260921-160801/account-path-playwright.log。本轮没有真实 MongoDB 连接测试或正式数据变更,不将模拟响应当作真实连接成功。 ## 2026-09-21 资产统一居中弹框 - `npm.cmd --prefix web run build` 通过,仅有 chunk 大小警告;恢复 `.gitkeep` 后构建 linkport-asset-dialog.exe。 - Go 1.25.0 的 `go test ./... -count=1 -timeout=120s` 与 `go vet ./...` 均通过。 - 新增 asset-editor-dialog.spec.ts 两项通过:文件/连接资产与目标弹框尺寸一致、居中、无抽屉、无空页签、底部按钮可见;覆盖 1440/390/320px;取消保留草稿、Escape 放弃、再次打开清空。截图禁用过渡动画后已检查。 - 既有 asset-remarks.spec.ts 一项、usability-assets.spec.ts 两项通过,覆盖上传保存、编辑/清空备注、内联创建回填与父草稿保护。 - 共享弹框复用后,responsive.spec.ts 原先假定全部 connection-editor 都有连接页签和“保存配置”按钮;更新为保留尺寸/滚动/固定操作区断言,仅对存在的页签验证键盘导航,并识别各表单保存按钮。单独重跑 responsive.spec.ts 两项通过,覆盖 320/390/768/1920px。一次组合回归命令被终端 60 秒时限截断并报 EPIPE,不作为通过记录。 - 测试使用 LINKPORT_E2E_BINARY 指向新嵌入式程序、隔离 SQLite 和端口。全量执行日志为 artifacts/mongo-live-check-20260921-160801/asset-dialog-playwright.log。未修改真实资产作测试,未停止/覆盖用户运行服务。 - 全量首跑结果为 94 通过、10 失败(9.6 分钟):包括上一轮已失败的 9 项,以及本次共享容器导致 responsive 用例旧假定失效的 1 项。后者更新断言后所在 responsive.spec.ts 两项已单独通过,其余 9 项未在本任务中修复。不将单独复跑结果合并成一次全量通过;git diff --check 通过。 ## 2026-09-21 菜单与资源侧栏切换 - `npm.cmd --prefix web run build` 通过(只有既有 chunk 大小警告),构建后恢复 `.gitkeep` 并生成 linkport-sidebar.exe。 - `LINKPORT_E2E_BINARY` 指向该新程序,使用独立 SQLite 和 18181/18182 端口。`sidebar-panels.spec.ts` 两项通过,覆盖桌面/手机、键盘及本地偏好;桌面菜单和资源截图已检查。 - 更新既有 DBX 宽度期望,以及 workspace-features/global-assets 用例中的资源视图切换入口。未更改真实业务数据来运行 UI 测试。 - 最新全量 Playwright:93 项通过、9 项失败(9.6 分钟)。侧栏新增两项、DBX 三项、菜单搜索及响应式用例通过。失败为 account-editor、global-assets-proxy-project 两项、kubeconfig-selection、target-outbound-selection、workspace-features 三项和 workspace 的旧诊断断言;涉及小屏表单高度、重复未保存确认、超时和旧显示期望,本轮未扩大范围修复。全量执行日志位于 artifacts/mongo-live-check-20260921-160801/sidebar-playwright.log。不能声明全量浏览器回归通过。 - 嵌入新前端后的全量 Go 测试与 vet 再次通过,git diff --check 通过。新版程序已生成,但未停止或替换用户当前运行的 bin/linkport.exe。 ## 2026-09-21 MongoDB 兼容握手与真实连接 - `TestLegacyAndModernHandshake`:初次 isMaster/helloOk 协商,连续两次刷新选择正确命令,使用本地 net.Pipe fixture。 - `TestUpstreamSCRAMNegotiationAndEmptyFinish`:认证库机制探测、SHA-256 优先、SHA-1 默认、额外空结束交换及异常结束载荷拒绝,使用本地 SCRAM fixture。 - `TestMongoHelloUnsupported`:只允许 CommandNotFound 回退,认证、权限和网络错误不能触发回退。 - 最新 `GOTOOLCHAIN=go1.25.0 go test ./... -count=1 -timeout=120s` 和 `go vet ./...` 均通过。中间一次 cluster MySQL fixture 间歇失败,最新全量通过;不代表间歇性根因已修复。 - `npm.cmd --prefix web run build` 已通过(有 chunk 大小警告),不再是此前的 esbuild EPERM 阻塞。构建后恢复 web/dist/.gitkeep,再构建嵌入新前端的隔离测试程序。 - 实际使用已保存 Kubeconfig,经 K8s port-forward 对 wall-e-test/statefulset/mongo-shopee:27017 进行握手、SCRAM、buildInfo 查询。用户提供认证库/凭据后成功返回版本 4.1.13、standalone、TLS=false、zlib。保存配置并重新读取后再次成功。未执行业务数据写入。 - Playwright 首轮使用 LINKPORT_E2E_BINARY 指向 artifacts/mongo-live-check-20260921-160801/linkport.exe,独立临时 SQLite 和端口,91 项通过、9 项失败;其中部分工作区用例执行期间又加入了后续侧栏变更,因此以后续 linkport-sidebar.exe 全量运行结果为准,不将首轮当作干净的对照基线。 ## 2026-09-21 连接路径与分阶段诊断 - 新增 `TestMongoFailureStages`:本地 net.Pipe fixture 区分 TCP、TLS、hello 拒绝/断连、SCRAM 认证拒绝/交换断连、buildInfo 权限拒绝/断连,不依赖真实服务器。 - 新增 gateway 和 API 白名单阶段测试:保留结构化阶段及内部 cause,未知阶段安全回退,管理响应与错误字符串不泄露凭据和服务器任意诊断文本。 - 新增 `connection-diagnostics.spec.ts`:阶段中文映射、网络/认证区别、K8s 资产名与资源路径、无敏感内容及未知阶段回退;浏览器用例使用模拟失败响应,不连接真实集群。 - 加入诊断后的全量 Go 测试:除既有 MySQL group-replication fixture 再次间歇失败外,API、gateway、Mongo、model、store 等包均通过;该 fixture 单独重跑通过。`go vet ./...` 通过。此前资产合并阶段的一轮全量通过,不能据此宣称间歇性测试已修复。 - Vue 类型检查、Node 中执行的阶段区别/安全回退/K8s 路径纯函数断言、`git diff --check` 通过。Playwright `--list` 成功发现 100 项用例、43 个文件,仅验证用例可发现,不代表执行通过。 - 最后一次 `npm.cmd --prefix web run build` 仍在 Vite/esbuild 启动时报 `spawn EPERM`。没有新前端包、没有部署、没有浏览器 E2E 结果;不能把类型/纯函数检查当作浏览器验证已通过。 ## 2026-09-21 资产合并与目标内联 Kubernetes(当前源码) - Go 1.25.0:最后一轮 `go test ./... -count=1 -timeout=120s` 和 `go vet ./...` 全部通过。期间既有 MySQL group-replication fixture 曾间歇失败;单独重跑和最终全量通过,未修改该集群实现。 - 新增 API/model 回归覆盖:目标不填写 IP 即可保存/草稿测试 StatefulSet、不生成中间代理、内联 Kubeconfig 解析、TLS/直连仍要求地址。存储 fixture 验证资产更新及版本恢复后使用最新内容、清除旧主机指纹、禁止删除被引用资产且不把 Kubeconfig 正文复制到目标记录。 - Vue 类型检查通过;Node 执行 TypeScript 转译后的纯函数断言通过,覆盖目标 payload、不泄漏资产内容、连接引用/直连切换及 K8s 单节点和保活校验。 - `npm.cmd --prefix web run build` 的类型检查阶段通过,但 Vite/esbuild 启动被当前环境以 `spawn EPERM` 阻止。没有新前端包,未构建/部署含新界面的运行程序,未执行浏览器端到端验证。下方旧版本的成功浏览器记录不代表此合并功能已通过 E2E。 - 前端用例按新资产类别、连接字段、StatefulSet 目标直接配置、旧引用兼容和文件更新导航调整。使用隔离 API/模拟响应,不宣称真实 Kubernetes、MongoDB、SSH/SOCKS5 连通性;未操作真实 `data` 或重启服务。 ## 2026-09-21 新建目标选择代理验证 - 新增 `target-outbound-selection.spec.ts`,先对上一轮构建的程序执行首个用例,确认默认「连接信息」页没有可见的代理选择器;修改后新增 3 项用例通过。 - `npm.cmd --prefix web run build` 通过,包含 Vue 类型检查与 Vite 构建,仅有原有主包体积警告。待构建完成后使用 Go 1.25.0 生成 `artifacts/target-outbound-selection/linkport.exe`,保留 `web/dist/.gitkeep`。 - 使用上述新程序、独立数据及 19291/19292 端口执行 `target-outbound-selection.spec.ts`、`kubeconfig-selection.spec.ts`、`kubernetes.spec.ts`、`project-scope.spec.ts`、`target-editor-test.spec.ts`,21 项全部通过。覆盖首屏直连/SSH/SOCKS5/K8s 选择、服务类型和页签切换保留引用、Mongo 草稿测试参数、实际 API 保存与重新编辑回读、改回直连、跨项目选择、空列表、不可用引用及 390px 小屏。 - Go 1.25.0:`go test ./... -count=1 -timeout=120s` 和 `go vet ./...` 全部通过,先完成后端检查再执行全量浏览器测试,避免目录清理竞争。 - 全量 Playwright 使用新程序执行 `npm.cmd --prefix web test -- --max-failures=3`:82 通过、3 失败、8 未运行。失败仍是已记录的 `account-editor.spec.ts` 320×568 权限页多出 14px 滚动,以及 `workspace-features.spec.ts` 的 URL 参数和搜索/树导航两项超时。 - 对上述未运行的 8 项补跑:`workspace.spec.ts` 7 项全部通过,覆盖 SSH/SOCKS5 目标配置、共享代理引用、凭据保留与删除保护等;`workspace-features.spec.ts` 的表格列设置用例在对隐藏 checkbox 执行 `uncheck` 时超时。再用本次修改前的 `artifacts/kubeconfig-selection/linkport.exe` 单独复跑该列设置用例,同样失败,确认不是本次代理入口引入。两轮合计 89 项通过、4 项既有失败,未扩展修复这些无关功能。 - Mongo 草稿连接结果、跨范围列表和不可用引用场景使用浏览器模拟;三类代理创建、Kubeconfig 资产保存、Mongo 目标保存与切回直连通过隔离 API。未连接真实 MongoDB、SSH/SOCKS5 代理或 Kubernetes 集群;Go 协议测试使用本地 fixture。未替换现用程序或操作真实数据。 - `git diff --check` 通过,构建占位文件恢复原样;所有测试结束后确认隔离端口 19291/19292 不再监听。 - 验证边界:本轮程序于 2026-09-21 13:21 构建,Go 检查于 13:25 完成。收尾发现 `internal/store/audit_shards.go`、`commands.go`、`event_shards.go`、`store.go` 在 13:34 出现其他修改;本任务未触碰或回退它们,上述构建及测试结果不覆盖这些后续修改。 ## 2026-09-21 Kubeconfig 资产选择验证 - 修改前,在新构建 EXE 上创建“数据库平台 · 正式”的 Kubeconfig,再以“默认项目 · 测试”新建代理,复现资产被范围过滤且无提示/展开入口;回归用例明确失败。 - `npm.cmd --prefix web run build` 通过,包含 `vue-tsc` 与 Vite 生产构建;仅有原有主包体积警告。构建后保留 `web/dist/.gitkeep`,再使用 Go 1.25.0 构建 `artifacts/kubeconfig-selection/linkport.exe`,未并发替换嵌入资产。 - 使用该新 EXE、独立数据及 19191/19192 端口,`kubeconfig-selection.spec.ts`、`kubernetes.spec.ts`、`usability-assets.spec.ts`、`project-scope.spec.ts` 共 7 项通过。新增 2 项覆盖跨范围 Kubeconfig 显式选择、排除普通文件、隐藏范围后保留引用、保存代理与 Mongo 目标并回读、空态类型提示、刷新失败重试和 390px 小屏。 - Kubernetes 命名空间/资源查询使用浏览器模拟响应;资产、代理和 Mongo 目标保存经过真实隔离 API。没有调用真实 Kubernetes API 或连接真实 MongoDB,不将 UI/引用验证表述为实时 port-forward 成功。 - Go 1.25.0:`go test ./... -count=1 -timeout=120s` 和 `go vet ./...` 串行复跑全部通过,包括 `internal/cluster`。首次与 Playwright 并发运行时,Go 枚举目录遇到正在清理的 `web/test-results`,报 `pattern ./...: open web\test-results: The system cannot find the file specified.`;待浏览器结束后重跑消除该竞争。协议测试使用本地 fixture,未连接真实数据库或 SSH 服务。 - 全量 Playwright 使用同一新 EXE,执行 `npm.cmd test -- --max-failures=3`:79 通过、3 失败、8 未运行,达到失败上限后停止。失败与 2026-09-20 已记录情况一致:`account-editor.spec.ts` 的 320×568 权限页多出 14px 滚动,以及 `workspace-features.spec.ts` 的 URL 参数、搜索/树导航两项超时;新增 2 项均通过,未修改上述无关功能。 - 未改动用户真实数据、未替换现用程序;测试结束后确认隔离端口 19191/19192 不再监听,`git diff --check` 通过。 ## 2026-09-21 库内密钥、历史整合与工作区回归 - Go 1.25.0:`go test ./... -count=1 -timeout=120s` 和 `go vet ./...` 全部通过,包含新增库内密钥与离线整合测试。协议测试仍为隔离 fixture。 - 密钥验证覆盖首次入库、无外置密钥文件、重启、只复制主 SQLite 后仍能解密原密码/私钥、缺失/损坏记录不重建、显式环境密钥不匹配拒绝,以及外置文件不自动导入或覆盖。 - 离线工具 fixture 覆盖当前配置优先、独有资源合并、新增网关停止、旧管理员不覆盖、使用不同源密钥时正确重加密、完整备份、准备模式不改源库、应用模式替换主库、旧库与旧密钥保持。流程测试通过注入测试密钥执行,不依赖真实 DPAPI。真实密钥最初在代理环境解密失败,随后用户在原 Windows 会话执行整合成功,详见 [历史数据说明](historical-data.md)。 - 真实整合结果复核:`consolidate-20260920T171719.754430900Z/report.json` 为 `applied:true`;16 个备份文件及 10 个保留原文件哈希通过。`ready/` 的主库复制件完整性、库内密钥和全部资源解密通过,8 个目标、4 个网关、1 个资产,2 个导入网关停止。实际安装主库在代理环境读取返回 `EPERM`,未直接核对其内容或启动真实服务。 - 前端 vue-tsc/Vite 构建通过并保留 `.gitkeep`,存在已知 bundle 体积警告。账号编辑器 320×568 全页签以及 URL、搜索导航、列设置专项通过;测试未放宽滚动阈值,使用可见 checkbox 标签并保留状态断言。 - `node scripts/package.mjs --all` 完成六目标构建,发布目录 `artifacts/releases/2026-09-20T16-40-11-688Z-701d60e4/` 的六份 SHA256 均与清单一致。Windows x64 原生包与本地启动(无外置密钥、可选认证、TLS、重启与搬移)验收通过。Linux/macOS × amd64/arm64 的桌面测试二进制也编译通过,未实机执行;远程 CI 未执行。 - 全量 Playwright 使用此次新程序 `artifacts/db-key-verification/linkport.exe`,通过 `LINKPORT_E2E_BINARY` 指定,隔离数据库和端口 18485/24687。首轮 91 通过、4 失败:工作区 helper 仍匹配精简前的白名单说明文字,重试又遇到前次创建的重复 fixture。已同步文案断言并重建两套隔离测试库重跑;首轮目录为 `artifacts/db-key-verification/full`,最终目录为 `artifacts/db-key-verification/full-final`。 - 最终完整运行设置 `--retries=0`,95 项全部通过(7.0 分钟),包含此前失败的四项工作区/小屏用例及主题切换。测试结束后停止本轮两套隔离服务;未部署到真实数据目录。 ## 2026-09-20 三平台与明文主密钥验证 - Go 1.25.0:`go test ./... -count=1 -timeout=120s`、`go vet ./...` 全部通过,包含 Windows 本地密钥、运行锁、缺失密钥保护,以及旧 DPAPI 文件不转换且保留的回归。协议测试使用本地 fixture,未连接真实上游服务器。 - `node scripts/build-web.mjs --force` 完成前端类型检查及 Vite 生产构建,保留 `web/dist/.gitkeep`;仅有 bundle 体积警告。之后执行 `node scripts/package.mjs --all`,生成 Windows/Linux/macOS × amd64/arm64 六个平台的独立程序,文件校验和均与清单一致。 - Windows x64 使用此次实际程序通过单文件发布验收(版本信息、内嵌网页、隔离启动和登录)及 `verify-desktop.mjs`(免登录、可选管理员设置、自动 TLS、未加密密钥持久化、认证重启和搬移数据)。其他五个目标为编译验证。另对 Linux/macOS × amd64/arm64 的 `internal/desktop` 测试代码执行 `go test -c`,全部编译成功,未在异系统执行。 - Node 脚本语法、三个 Unix shell 入口的 Git Bash `bash -n`、CI YAML 解析及矩阵检查、`git diff --check` 通过。Windows 启动脚本 fixture 回归在 `Get-CimInstance Win32_Process` 遇到当前环境权限拒绝,未完成源码启动和备份验收;不计为通过。远程三系统 CI 已配置但未执行。 - 产物:`artifacts/releases/2026-09-20T13-38-02-849Z-dc352132/`;浏览器验证使用复制出的新程序 `artifacts/platform-verification/linkport.exe`,通过 `LINKPORT_E2E_BINARY` 指定,测试服务使用隔离数据及 8485/14687 端口。未部署到真实数据目录,未转换或删除实际 `master-key.dpapi`。 - 全量 Playwright 95 项、不重试:90 通过、5 失败。最后的主题用例在 `browser.newContext` 阶段因浏览器关闭失败,用新浏览器单独复跑后通过;剩余 4 项为此前已在旧程序复现的账号权限页 320×568 多出 14px 滚动,以及 `workspace-features.spec.ts` 的 URL 参数、搜索/树导航、表格列设置三项超时。整套结果不计为通过。本轮环境保存、请求报错信息、SQLite、RabbitMQ 版本、Sentinel 认证用例均通过。报告目录为 `artifacts/platform-verification/playwright` 和 `artifacts/platform-verification/theme`。 ## 2026-09-20 Windows 多路径启动验证 - Go 1.25.0:`go test ./internal/desktop ./cmd/linkport -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/linkport.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 被另一轮测试占用,本轮设置 `LINKPORT_E2E_PORT=19081`、`LINKPORT_E2E_AUTH_PORT=19082` 并通过 `LINKPORT_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 测试服务退出等待期间仅停止本轮指定路径的测试程序,未停止用户服务或另一轮测试程序。 改动原因和行为边界见 [未保存配置的连接测试](target-connection-test.md) 与 [变更原因与设计记录](change-rationale.md)。 ## 2026-09-18 账号路由与免滚动编辑验证 以下是本轮实际执行记录;下方早期版本的“全量通过”不代表本轮 Windows 环境所有测试通过。 - 前端:`npm.cmd --prefix web run build`(Vue 类型检查及 Vite 生产构建)通过。使用 Go 1.25.0 在前端构建结束后生成新的嵌入式测试程序,并通过 `LINKPORT_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,没有对实际生产服务做验收。 - 最新免滚动编辑调整只涉及前端及文档,重新执行前端构建和浏览器验证,未把此前后端结果表述为重新运行后的结果。测试使用独立数据库和端口,未部署或迁移实际使用的数据目录。 改动原因见 [变更原因与设计记录](change-rationale.md),使用方式见 [易用性](usability.md) 与 [账号说明](target-accounts.md)。 ## 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.27.1,与当前依赖和构建脚本一致。设置 `GOTOOLCHAIN=go1.27.1`;首次使用可能需要下载工具链。 ```powershell $env:GOTOOLCHAIN = 'go1.27.1' go test ./... go vet ./... npm.cmd --prefix web run build go build -o bin/linkport.exe ./cmd/linkport $env:LINKPORT_E2E_BINARY = Join-Path (Get-Location) 'bin/linkport.exe' npm.cmd --prefix web test ``` 浏览器测试使用隔离的临时 SQLite、随机主密钥和仅供测试的登录密码,监听 `127.0.0.1:18081`,结束后清理。不连接用户的数据库。默认使用已安装的 Edge;其他平台可安装 Playwright Chromium 并设置 `LINKPORT_BROWSER_CHANNEL=chromium`。截图输出到忽略版本控制的 `web/test-results`。 ## 已有自动化覆盖 | 模块 | 覆盖范围 | | --- | --- | | API | 登录、会话/CSRF、默认读写、CRUD 脱敏、密码保留和重新认证查看、限流、运行中目标/网关原子更新、CAS 与失败回滚、主机指纹字段防绕过 | | 存储 | 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 项目,测试会创建并删除临时数据库,结束后删除该项目的测试卷。不要将这些测试指向生产服务。 ```powershell .\scripts\test-matrix.ps1 ``` ```sh bash scripts/test-matrix.sh ``` 固定镜像和端口以 [Compose 文件](../deploy/compose.test.yml) 为准: | 服务 | 版本 | 本机端口 | | --- | --- | --- | | 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。 手动启动测试实例: ```sh 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:`LINKPORT_MYSQL_TEST_ADDR`、`LINKPORT_MYSQL_TEST_USER`、`LINKPORT_MYSQL_TEST_PASSWORD`、可选 `LINKPORT_MYSQL_TEST_CA`(CA 文件路径),执行 `go test ./internal/protocol/mysqlproxy -run TestRealMySQL -count=1 -v`。 - MongoDB:`LINKPORT_MONGO_TEST_ADDR`、`LINKPORT_MONGO_TEST_USER`、`LINKPORT_MONGO_TEST_PASSWORD`、可选 `LINKPORT_MONGO_TEST_CA`(PEM 内容),执行 `go test ./internal/protocol/mongoproxy -run TestRealMongo -count=1 -v`。 - SSH:`LINKPORT_SSH_TEST_ADDR`、`LINKPORT_SSH_TEST_USER`、`LINKPORT_SSH_TEST_PASSWORD`,执行 `go test ./internal/protocol/sshproxy -run TestRealSSH -count=1 -v`。验证远程输出和退出码、SFTP 上传下载及清理、禁止 TCP 转发。 三类测试可额外设置 `LINKPORT_TEST_SOCKS_ADDR` 和可选 `LINKPORT_TEST_SOCKS_USER/PASSWORD`,使用真实生产出站层经 SOCKS5 连接上述目标。测试中的首次 SSH 指纹探测仅适用于已明确指定的一次性测试服务,不替代生产环境的管理员独立核对流程。 测试账号须允许创建和删除独立测试库;未设置地址时真实版本测试明确跳过。省略上游 CA 时测试按明文上游运行,但网关客户端仍执行 TLS。 ## 验证边界 当前开发机器没有 Docker、MySQL 或 MongoDB 服务,真实版本矩阵和 OpenSSH/mongosh 客户端组合尚未在此机器执行。Docker 镜像启动、数据库各版本 TLS/认证差异、真实副本集事务以及所有服务经 SOCKS5 的端到端组合,需要运行测试环境后再确认。 只读是严格请求白名单,不等同数据库权限保证;MongoDB 只读游标按客户端连接限制,多文档事务不在只读兼容范围。完整边界见 [只读说明](readonly.md) 和 [开发计划](development-plan.md)。 ## Windows 双击启动验证 已通过 `go test ./...`、`go vet ./...`,以及 Edge 无头浏览器的桌面启动回归。验证包括无管理员/主密钥环境变量启动、从其他工作目录启动、首次页面创建管理员、自动本机 TLS、DPAPI 密钥持久化、重启后原账号登录。初始化单元测试覆盖错误 token、跨来源请求和重复初始化;Windows 测试覆盖独占锁和数据库存在时禁止替换丢失密钥。 对解压后的发行包运行: ```powershell node scripts/verify-package.mjs <单EXE交付目录或linkport.exe路径> node scripts/verify-desktop.mjs <解压后的目录>/linkport.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 进程退出失败,单独重跑通过。 ## Account-free protocol coverage Model, API, readiness and protocol fixture tests cover anonymous Redis and MongoDB targets and gateways. MongoDB gateway tests use `net.Pipe` fixtures; they do not claim validation against a live MongoDB server. ## Redis password-only authentication (2026-09-28) Using Go 1.25.0 with serial package compilation and workspace-local temporary, build-cache and module-cache directories: - `go test ./internal/model -count=1 -timeout=120s` passed. - Focused API and Redis protocol tests for password-only Redis and the MongoDB rejection boundary passed. - `internal/cluster`, `internal/gateway`, `internal/protocol/redisproxy` and `internal/protocol/mongoproxy` package tests passed in the related-package run. - `go vet ./...` passed. `vue-tsc --noEmit`, the 13-case frontend authentication matrix, the three connection-example cases and the legacy draft regression passed. All non-browser `web/tests/*.test.mjs` domain suites also passed. - `npm.cmd --prefix web run build` completed type checking, then Vite could not start esbuild in this Windows sandbox (`spawn EPERM`). No fresh executable or Playwright run is claimed. - The full `go test ./... -count=1 -timeout=120s` run completed with unrelated environment failures in `cmd/linkport`, `internal/desktop`, `internal/security` and `internal/store` due denied local-file permissions, plus `internal/api` failures for a portable SQLite snapshot and an OS-denied loopback listener. All protocol packages passed, and the focused authentication API tests passed. Coverage includes target creation/redaction/persistence, draft and saved gateway tests, Redis-only model validation across every supported service type, direct and Cluster target AUTH command forms, and direct/Cluster gateway acceptance of `AUTH password` with rejection before upstream dialing for a wrong password. Cluster fixtures also verify that both authenticated and account-free gateways rewrite password-only target credentials to `HELLO ... AUTH default password`. Protocol coverage uses local RESP/`net.Pipe` fixtures, not live Redis or Sentinel. ## Live target switch disconnect behavior (2026-09-28) - Go 1.25.0 targeted `internal/gateway` tests passed for the generic relay, TCP, SSH and multi-account SSH paths. They verify that a failed persistence callback preserves old clients, a successful switch closes all current clients without replacing the listener, and reconnecting clients use the new target. - The focused `internal/api/TestLiveTargetSwitchDisconnectsClientsOnlyAfterSave` test passed against isolated SQLite and loopback TCP fixtures. It covers the existing `POST /api/v1/proxies/{id}/target` endpoint, including failed save, successful disconnect, stable bound address and reconnect routing. - The complete `internal/gateway` package passed. In the broader API package run, unrelated existing SSH host-key and independent TCP/SOCKS5 fixture tests failed because their local test connections returned 422 in the Windows sandbox; the target-switch API test itself passed. - Frontend compilation, a development server and Playwright execution were not run for this development-stage adjustment at the user's request. Source review confirms the changed switch notice exists in the Chinese, English and Japanese dictionaries and both target-switch UI entry points use those keys. - All protocol behavior checks above use controlled loopback fixtures. They do not claim validation against live MySQL, Redis, RabbitMQ, SSH or other targets, and no real `data` directory was modified. ## MySQL performance audit highlighting (2026-09-29) - Added protocol fixture coverage for no-index and no-good-index status bits in OK, metadata EOF and row EOF packets, plus deterministic observed-duration capture without sleeping. - Added store coverage that writes an encrypted command result and verifies the command list hydrates its duration and full-scan risk in the same query. - Added frontend pure-logic coverage for the 3000 ms slow-query boundary, independent index-risk flags and compact duration formatting. - Per the development-stage instruction, these tests, compilation, a local server and browser checks were not run. Only static source inspection and `git diff --check` are claimed. The fixtures do not connect to a live MySQL server, and no real target or `data` directory was modified. ## React + Ant Design 验证(2026-10-04) 前端 TypeScript / Vite 生产构建通过;Go 1.27.1 重新嵌入 `bin/dev-build/antd/linkport.exe` 后,使用临时 SQLite 与隔离 18391/18392 端口运行 react-migration.spec.ts、ui-domain.spec.ts,13/13 通过(14.6 秒)。三个 Node domain 文件 16/16 通过;`go vet ./...` 通过。最终新程序完成 11 个菜单 × 浅深两种主题 × 1440/1024/390/320px 共 88 组检查,无 pageerror 或页面横向溢出,16 张截图在 `bin/dev-build/antd`。管理请求使用真实本机 API,阶段错误使用 HTTP 响应 fixture;没有连接真实数据库、SSH、Kubernetes 或 WebDAV 目标。恢复 `web/dist/.gitkeep`,未部署或修改真实 data。 `go test ./... -count=1 -timeout=120s` 未通过:API 的 TestWebDAVSyncSettingsAndAuthorization(同步口令未保留)、cluster 的 TestMySQLReplicationAndGroupDiscovery(fixture nil panic)、desktop 的路径相关用例、syncjob 的两个明文秘密断言失败,与既有记录一致;协议包均通过,不能视为真实上游服务器验证。日志见 `bin/dev-build/antd/go-test.log`。构建仍有 Node 22.10.0 低于 Vite 推荐版本及约 1.20 MB JS chunk 提示,构建成功。 完整 Playwright 套件发现 146 项,使用 `--max-failures=5` 执行后 5 项失败、141 项未运行,另有停止后的 suite 级错误提示。失败来自 account-editor(2 项)、account-targets(1 项)、asset-editor-dialog(2 项),仍依赖旧 Vue 的 `.target-card`、`.el-select`、`.connection-editor` 及“配置”“+ 新建目标”等旧文案;未迁移的旧用例不记为通过。日志在 `bin/dev-build/antd/playwright-suite.log`。最终 13 项当前 React 专项通过与完整旧套件结果分别记录,`git diff --check` 通过。 ## UI 密度、小屏弹窗与筛选验收(2026-10-04) 实际验证:TypeScript / Vite 生产构建通过,恢复 web/dist/.gitkeep;Go 1.27.1 新嵌入 bin/dev-build/ui-polish/linkport-final.exe,以 LINKPORT_E2E_BINARY、临时 SQLite 和 18451/18452 端口运行 React 迁移/domain Playwright,13/13 通过。额外隔离 18431 端口验收空资源创建、空搜索/范围结果清除及列偏好跨刷新保留;11 个菜单 × 浅深主题 × 1440/1024/390/320px 共 88 组检查无 pageerror 或页面横向溢出,8 组编辑器在滚动内容前后保存按钮均完全位于视口内,截图 16 张。浏览器使用本机真实管理 API 和隔离配置;没有连接真实数据库、SSH、Kubernetes 或 WebDAV 目标。日志与截图位于 bin/dev-build/ui-polish。 Go vet ./... 通过。全量 go test ./... -count=1 -timeout=120s 仍失败于 API 的同步口令保留、cluster 的 MySQL fixture nil panic、desktop 的数据路径用例与 syncjob 的两个明文秘密断言,与前轮记录一致;协议包通过但不代表真实服务器验证。首次 Go 与 Playwright 并发时,Go 目录扫描撞上 web/test-results 清理,报目录不存在;浏览器完成后重新执行 Go 检查,上述为重跑结果。 完整旧 Playwright 套件发现 146 项,使用 --max-failures=1 --timeout=15000 运行后,首项 account-editor 因依赖旧 .target-card / “配置目标”失败,145 项未运行,另有停止后的 suite 级错误提示;不能把专项通过视为旧套件全部通过。构建保留 Node 22.10.0 低于 Vite 推荐版本与约 1.22 MB JS chunk 提示。git diff --check 通过。 ## 审计查询区集中验收(2026-10-05) 前端生产构建及 Go 1.27.1 新嵌入程序成功,恢复 web/dist/.gitkeep;LINKPORT_E2E_BINARY 指向 bin/dev-build/audit-query/linkport.exe,React 迁移/domain Playwright 13/13 通过(16.2 秒),使用临时 SQLite、18511/18512 端口。命令与事件审计 × 浅深主题 × 四种屏宽的 16 组检查通过,查询区统一包含范围、字段和动作,项目/环境/关键词请求参数正确,无 pageerror 或横向溢出;仅使用本机管理 API,没有真实协议目标。 补充全量检查:Go 1.27.1 下 go vet ./... 通过;go test ./... -count=1 -timeout=120s 未通过,失败为 API 同步口令保留、cluster MySQL fixture nil panic、desktop 路径用例、pgproxy/TestPreparedRejectsDifferentIdentity 以及 syncjob 两个明文秘密断言,完整细节在 bin/dev-build/audit-query/go-test.log。未将后端全量或协议 fixture 结果当作真实目标服务器验证。完整 Playwright 发现 146 项,使用 --max-failures=1 --timeout=15000 执行后,首项 account-editor 仍依赖旧 Vue .target-card / “配置目标”而超时,145 项未运行,另有停止后的 suite 级错误提示,不记为全套通过。构建保留 Node 22.10.0 版本和约 1.22 MB chunk 提示,仍成功。 ## 底色与彩色文字按钮验收(2026-10-05) 生产构建与 Go 1.27.1 新嵌入 bin/dev-build/button-soft/linkport.exe 成功,恢复 web/dist/.gitkeep。隔离临时 SQLite、18611/18612 端口的 React 迁移/domain Playwright 13/13 通过(15.6 秒)。18621 端口的 GET 资源 fixture 验收覆盖浅深主题与 1440/390/320px,五类按钮使用 Ant Design filled variant 及对应语义色,背景非透明、文字和背景不同,无 pageerror 或横向溢出。视觉截图在 bin/dev-build/button-soft,没有执行真实网关启停或连接上游服务;git diff --check 通过。后端未改动,沿用本会话 audit-query 全量失败记录。 完整旧 Playwright 套件另发现 146 项,以新程序、18631/18632 端口及 --max-failures=1 --timeout=15000 执行,首项 account-editor 仍依赖旧 Vue .target-card / “配置目标”而超时,145 项未运行,另有停止后的 suite 级错误提示;不宣称全套通过,详见 bin/dev-build/button-soft/playwright-suite.log。 ## 审计查询下拉回归(2026-10-05) TypeScript / Vite 生产构建及 Go 1.27.1 新嵌入 bin/dev-build/audit-selects/linkport.exe 成功,恢复 web/dist/.gitkeep。以 LINKPORT_E2E_BINARY、临时 SQLite、18711/18712 端口执行 React 迁移/domain Playwright,14/14 通过(16.7 秒);新增回归使用 GET 资源 fixture,验证资源名称下拉、跨项目选项排除、项目/环境/网关 ID/目标 ID/协议/处理结果/关键词实际查询参数,以及重置清除审计条件并保留范围。18721 隔离验收两种审计页 × 两种主题 × 四种屏宽,共 16 组通过,查询字段与动作保持集中,项目/环境选择后与关键词一起提交,无 pageerror 或页面横向溢出;输出 16 张截图。日志和截图在 bin/dev-build/audit-selects,没有连接真实数据库或其他协议目标;git diff --check 通过。构建仍带 Node 22.10.0 版本及约 1.22 MB chunk 提示,成功生成产物。纯前端恢复不重复后端测试,本会话 audit-query 后端全量失败与 vet 通过记录仍保留。 完整旧 Playwright 套件发现 147 项,使用新程序、临时 SQLite、18731/18732 隔离端口及 --max-failures=1 --timeout=15000 执行;首项 account-editor 仍依赖旧 Vue .target-card / 配置目标而超时,1 项失败、146 项未运行,另有停止后的 suite 级错误提示,不宣称全套通过。日志见 bin/dev-build/audit-selects/playwright-suite.log。 2026-10-06 本轮收尾验证:新嵌入 bin/dev-build/cleanup/linkport.exe,17 项 Playwright 专项全部通过(26.4 秒),其中新增 11 页面导航/pageerror/横向溢出和协议字段测试;36 项 Node domain 测试通过。scripts/start-dev.test.ps1 通过,使用隔离 fixture 验证当前互斥锁、日志排除及原文件保护。Go 1.27.1 全量测试仅 internal/cluster 的既有 TestMySQLReplicationAndGroupDiscovery 发生 go-mysql fixture 身份协商 nil panic,其余包通过;go vet ./... 通过。新增旧配置包/模板版本拒绝测试通过。前端 TypeScript/Vite 构建成功,web/dist/.gitkeep 保留,仍有 Node 22.10.0 低于 Vite 推荐版本和大 JS chunk 提示。未做真实上游或生产部署验证。 完整 Playwright 本轮发现 150 项;max-failures=1、15 秒超时,首项 account-editor 仍依赖旧 Vue `.target-card` 而失败,149 项未运行,停止后另报 suite 错误。专项通过不等于旧全套通过。日志:bin/dev-build/cleanup/full-browser.log;当前专项:browser-final.log。git diff --check 通过。 ## 全站表单反馈回归(2026-10-07) 执行 `scripts/build.ps1 -SkipTests -RebuildWeb -OutputPath bin/dev-build/cleanup/linkport.exe`,先完成 TypeScript/Vite,再编译 Go 1.27.1 嵌入程序;成功。构建仍提示 Node 22.10.0 低于 Vite 推荐版本及 JS chunk 较大,未阻止构建,web/dist/.gitkeep 保留。 使用 `LINKPORT_E2E_BINARY=C:\work\github\LinkPort\bin\dev-build\cleanup\linkport.exe`、18761/18762 端口,运行 form-feedback、outbound-fields、current-pages、react-migration、ui-domain、request-error、csrf 七份 Playwright 文件:31 项通过(32.6 秒)。覆盖空代理/资产、Kubernetes 缺项、目标账号页签定位、模板/备份校验、同步/解密/运维范围检查、目录服务端错误、420px 小屏、SSH 指纹确认、失败草稿保留以及隔离真实 API 的保存和密码保留。HTTP 拒绝与 SSH 指纹使用 fixtures,不代表真实 SSH、SOCKS5、Kubernetes 或数据库上游验收。 额外运行 `node --test web/tests/network-proxies.test.mjs web/tests/redis-accountless.test.mjs web/tests/persistent-target.test.mjs web/tests/tcp-kube-forward.test.mjs`:24 项通过,2 个旧测试文件加载失败,分别缺少已移除的 @vue/compiler-sfc 和 KubernetesFields.vue。保持旧用例和全套发现配置不变;没有宣称旧全套通过。 日志:`bin/dev-build/cleanup/forms-final-build.log`、`forms-final-browser.log`、`forms-domain.log`。本轮仅更改前端、测试和文档,没有重新运行后端全量测试;此前记录的 cluster MySQL fixture nil panic 仍属已知失败。没有重启真实服务、部署迁移或改动真实数据。`git diff --check` 通过。 ## 后续交互排查与草稿测试(2026-10-07) TypeScript/Vite 与 Go 1.27.1 新嵌入 `bin/dev-build/cleanup/linkport.exe` 构建通过。使用该程序、临时 SQLite 和 18771/18772 端口运行 draft-feedback、sync-feedback、form-feedback、outbound-fields、current-pages、react-migration、ui-domain、request-error、csrf:37 项通过(39.6 秒)。新增覆盖未保存目标的当前地址与所选账号、成功/失败诊断、SSH 指纹确认后重试、已有目标携带 ID 并省略已保存密码、协议选择禁用提示、WebDAV 草稿保护/并发控件/双重错误保留。`GOTOOLCHAIN=go1.27.1 go test ./internal/api -run '^TestTargetDraft' -count=1 -timeout=120s` 通过(包耗时 1.371 秒),使用现有协议 fixtures 验证草稿测试不持久化及凭据解析;未验证真实上游服务器。 首次同步回归两处定位器因全局和页面都有“刷新”按钮而失败,已限定到 WebDAV 页面。中间一次以 editor-test.spec.ts 筛选时同时匹配旧 target-editor-test.spec.ts:29 项通过、2 个旧 Vue UI 用例超时、21 项未运行及一次套件停止错误;旧用例依赖 dialog、.el-form-item、.target-card,仍保留且未更改全套发现规则。新回归文件改为 draft-feedback.spec.ts 避免命名碰撞,最终专项通过不表示旧全套通过。 日志:`bin/dev-build/cleanup/ui-followup-build.log`、`ui-followup-final-browser.log`、`ui-followup-draft-api.log`;中间失败记录保留于 `ui-followup-browser.log`。构建仍有 Node 版本和大 chunk 提示;`web/dist/.gitkeep` 保留,`git diff --check` 通过。本轮没有修改后端源码或执行真实部署,未重复全量 Go/vet;此前全量 cluster fixture 失败记录仍有效。 ## 网关账号保存字段回归(2026-10-10) 使用 Go 1.27.1,定向执行 API/model 的 TestGatewayConfigurationFieldErrors、TestTCPIndependentBoundary、TestGatewayAccount 测试,通过。完整 `go test ./... -count=1 -timeout=120s` 中 API、model、store 及其他包通过,仅 internal/cluster 的既有 TestMySQLReplicationAndGroupDiscovery 发生 MySQL fixture nil panic。`go vet ./...` 最终通过;首次与 Playwright 并行时遇到 web/test-results 被清理导致的目录枚举错误,待浏览器完成后单独重跑通过。 TypeScript/Vite 与新嵌入 `bin/dev-build/cleanup/linkport.exe` 构建通过,web/dist/.gitkeep 保留;11 项 connection-draft Node 测试通过。以 LINKPORT_E2E_BINARY 指向该程序,18771/18772 隔离端口和临时 SQLite 执行 gateway-save-feedback、draft-feedback、sync-feedback、form-feedback、outbound-fields、current-pages、react-migration、ui-domain、request-error、csrf:39 项全部通过(42.3 秒)。新增场景通过真实隔离管理 API 完成既有 Redis 网关添加账号的 PUT、第二次编辑密码留空保留、目标新增账号;不会启动真实上游连接。 日志位于 `bin/dev-build/cleanup/gateway-fields-{targeted,go-test}.log`、`gateway-fields-final-{build,browser,domain,vet}.log`。后端错误回归验证非法字段路径与类型可见、密码值不回显、拒绝更新不修改配置。`git diff --check` 通过。未操作用户报错中的真实网关、部署迁移或宣称旧 Vue 全套通过。