Files

639 lines
24 KiB
JSON
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"generated_at": "2026-09-30T08:17:19Z",
"items": [
{
"id": "F01",
"status": "pass",
"note": "F01a 通过(test/accept/accept_test.go runEndpointCreate);F01b 通过(internal/admin/endpoints_test.go TestEndpointImportDuplicateRejectsAll、TestEndpointImportBOMAndCreate);F01c 通过(internal/app/identity/lifecycle_test.go TestF01DisableVoidsScheduledAndRejectsNew;internal/admin/endpoints_test.go TestEndpointDisableKickAndUnlock);F01d 通过(internal/app/identity/lifecycle_test.go TestF01DeleteOwnerTransfersEarliest);F01e 通过(internal/app/identity/lifecycle_test.go TestF01DeleteReopenNoOldReceipts)",
"subs": [
{
"id": "F01a",
"summary": "开通一端并可 MQTT 登录",
"status": "pass",
"evidence": "test/accept/accept_test.go runEndpointCreate"
},
{
"id": "F01b",
"summary": "批量开通整批校验",
"status": "pass",
"evidence": "internal/admin/endpoints_test.go TestEndpointImportDuplicateRejectsAll、TestEndpointImportBOMAndCreate"
},
{
"id": "F01c",
"summary": "停用",
"status": "pass",
"evidence": "internal/app/identity/lifecycle_test.go TestF01DisableVoidsScheduledAndRejectsNew;internal/admin/endpoints_test.go TestEndpointDisableKickAndUnlock"
},
{
"id": "F01d",
"summary": "删除群主转让",
"status": "pass",
"evidence": "internal/app/identity/lifecycle_test.go TestF01DeleteOwnerTransfersEarliest"
},
{
"id": "F01e",
"summary": "删除后同编号重开不串数据",
"status": "pass",
"evidence": "internal/app/identity/lifecycle_test.go TestF01DeleteReopenNoOldReceipts"
}
],
"passed": 5,
"total": 5
},
{
"id": "F02",
"status": "pass",
"note": "F02a 通过(test/accept/accept_test.go;internal/broker/f02_test.go TestF02PasswordLoginReturnsTokenAndHandshake);F02b 通过(internal/broker/f02_test.go TestF02TakenOverByPasswordLogin、TestF02OldTokenRejectedAfterPasswordLogin);F02c 通过(internal/broker/f02_test.go TestF02TokenReconnectDifferentIPKeepsToken);F02d 通过(internal/broker/f02_test.go TestF02IPLockDoesNotAffectOtherIP、TestF02EndpointLockAllowsTokenReconnect);F02e 通过(internal/broker/f02_test.go TestF02AdminResetPasswordFatal;cmd/nixmsg/fatal_revoked_integration_test.go TestUplinkResetPasswordFatal);F02f 通过(internal/broker/f02_test.go TestF02DBErrorClosesWithout086;internal/broker/broker_test.go TestInternalAuthErrorDoesNotReturnBadPassword)",
"subs": [
{
"id": "F02a",
"summary": "密码登录后 hello / 会话令牌",
"status": "pass",
"evidence": "test/accept/accept_test.go;internal/broker/f02_test.go TestF02PasswordLoginReturnsTokenAndHandshake"
},
{
"id": "F02b",
"summary": "新设备密码登录后旧设备退出",
"status": "pass",
"evidence": "internal/broker/f02_test.go TestF02TakenOverByPasswordLogin、TestF02OldTokenRejectedAfterPasswordLogin"
},
{
"id": "F02c",
"summary": "换 IP 用令牌重连",
"status": "pass",
"evidence": "internal/broker/f02_test.go TestF02TokenReconnectDifferentIPKeepsToken"
},
{
"id": "F02d",
"summary": "两种密码锁定",
"status": "pass",
"evidence": "internal/broker/f02_test.go TestF02IPLockDoesNotAffectOtherIP、TestF02EndpointLockAllowsTokenReconnect"
},
{
"id": "F02e",
"summary": "重置密码后被踢",
"status": "pass",
"evidence": "internal/broker/f02_test.go TestF02AdminResetPasswordFatal;cmd/nixmsg/fatal_revoked_integration_test.go TestUplinkResetPasswordFatal"
},
{
"id": "F02f",
"summary": "服务器故障不误报密码错误",
"status": "pass",
"evidence": "internal/broker/f02_test.go TestF02DBErrorClosesWithout086;internal/broker/broker_test.go TestInternalAuthErrorDoesNotReturnBadPassword"
}
],
"passed": 6,
"total": 6
},
{
"id": "F03",
"status": "partial",
"note": "F03a 通过(test/accept/rest_accept_test.go;internal/app/presence/presence_test.go TestF03PresenceAndDirectory);F03b 通过(test/accept/rest_accept_test.go;internal/app/presence/presence_test.go TestF03PresenceAndDirectory);F03c 未测(环境/时长限制,本波不跑);F03d 未测(环境限制;验收用关连接模拟断线)",
"subs": [
{
"id": "F03a",
"summary": "断开后状态及时变离线",
"status": "pass",
"evidence": "test/accept/rest_accept_test.go;internal/app/presence/presence_test.go TestF03PresenceAndDirectory"
},
{
"id": "F03b",
"summary": "目录可列出",
"status": "pass",
"evidence": "test/accept/rest_accept_test.go;internal/app/presence/presence_test.go TestF03PresenceAndDirectory"
},
{
"id": "F03c",
"summary": "1000 端全表 1s 内返回",
"status": "untested",
"note": "环境/时长限制,本波不跑"
},
{
"id": "F03d",
"summary": "真拔网线后心跳超时离线",
"status": "untested",
"note": "环境限制;验收用关连接模拟断线"
}
],
"passed": 2,
"total": 4
},
{
"id": "F04",
"status": "pass",
"note": "F04a 通过(test/accept/rest_accept_test.go;internal/app/presence/presence_test.go TestF04PresenceWatch)",
"subs": [
{
"id": "F04a",
"summary": "只通知订阅了的端",
"status": "pass",
"evidence": "test/accept/rest_accept_test.go;internal/app/presence/presence_test.go TestF04PresenceWatch"
}
],
"passed": 1,
"total": 1
},
{
"id": "F05",
"status": "pass",
"note": "F05a 通过(test/accept/accept_test.go runMessagingAccept);F05b 通过(test/chaos/q3_crash_test.go TestQ3CrashSubmitThenRestart);F05c 通过(internal/app/message/submit_test.go TestSubmitTable/conflict);F05d 通过(internal/app/message/submit_test.go TestSubmitTable 对话密码用例);F05e 通过(internal/app/message/submit_test.go TestSubmitTable/quota_exceeded)",
"subs": [
{
"id": "F05a",
"summary": "双端在线单聊送达与确认",
"status": "pass",
"evidence": "test/accept/accept_test.go runMessagingAccept"
},
{
"id": "F05b",
"summary": "崩溃不丢已提交消息",
"status": "pass",
"evidence": "test/chaos/q3_crash_test.go TestQ3CrashSubmitThenRestart"
},
{
"id": "F05c",
"summary": "消息号冲突",
"status": "pass",
"evidence": "internal/app/message/submit_test.go TestSubmitTable/conflict"
},
{
"id": "F05d",
"summary": "密码门生效",
"status": "pass",
"evidence": "internal/app/message/submit_test.go TestSubmitTable 对话密码用例"
},
{
"id": "F05e",
"summary": "配额生效",
"status": "pass",
"evidence": "internal/app/message/submit_test.go TestSubmitTable/quota_exceeded"
}
],
"passed": 5,
"total": 5
},
{
"id": "F06",
"status": "pass",
"note": "F06a 通过(test/accept/accept_test.go;internal/app/group/group_test.go TestF06GroupSendMembership);F06b 通过(internal/app/group/group_test.go TestF06GroupSendMembership(发送后入群无旧投递))",
"subs": [
{
"id": "F06a",
"summary": "群成员收到同一份、发送者不收到自己的",
"status": "pass",
"evidence": "test/accept/accept_test.go;internal/app/group/group_test.go TestF06GroupSendMembership"
},
{
"id": "F06b",
"summary": "入群前不补",
"status": "pass",
"evidence": "internal/app/group/group_test.go TestF06GroupSendMembership(发送后入群无旧投递)"
}
],
"passed": 2,
"total": 2
},
{
"id": "F07",
"status": "pass",
"note": "F07a 通过(test/accept/rest_accept_test.go);F07b 通过(test/accept/rest_accept_test.go body_too_large);F07c 通过(test/accept/rest_accept_test.go max_receive_bytes=1024)",
"subs": [
{
"id": "F07a",
"summary": "256 KiB 通过",
"status": "pass",
"evidence": "test/accept/rest_accept_test.go"
},
{
"id": "F07b",
"summary": "超出拒绝",
"status": "pass",
"evidence": "test/accept/rest_accept_test.go body_too_large"
},
{
"id": "F07c",
"summary": "接收上限生效",
"status": "pass",
"evidence": "test/accept/rest_accept_test.go max_receive_bytes=1024"
}
],
"passed": 3,
"total": 3
},
{
"id": "F08",
"status": "partial",
"note": "F08a 通过(test/accept/accept_test.go;test/chaos/q3_crash_test.go);F08b 通过(internal/app/message/submit_test.go TestSubmitTable/idempotent_hit);F08c 通过(test/chaos/q3_weak_test.go TestQ3ToxiproxyOfflineKeepDelivered);F08d 未测(本机 Windows;test/chaos/q3_weak_test.go TestQ3NetemUntested)",
"subs": [
{
"id": "F08a",
"summary": "重启后续传",
"status": "pass",
"evidence": "test/accept/accept_test.go;test/chaos/q3_crash_test.go"
},
{
"id": "F08b",
"summary": "应用层不重复(同号同指纹)",
"status": "pass",
"evidence": "internal/app/message/submit_test.go TestSubmitTable/idempotent_hit"
},
{
"id": "F08c",
"summary": "toxiproxy 弱网保留送达",
"status": "pass",
"evidence": "test/chaos/q3_weak_test.go TestQ3ToxiproxyOfflineKeepDelivered"
},
{
"id": "F08d",
"summary": "Linux netem 20% 丢包",
"status": "untested",
"note": "本机 Windows;test/chaos/q3_weak_test.go TestQ3NetemUntested"
}
],
"passed": 3,
"total": 4
},
{
"id": "F09",
"status": "pass",
"note": "F09a 通过(test/accept/accept_test.go);F09b 通过(internal/app/message/delivery_test.go TestDeliveryStateMachine/F09_keep_ttl_expire_via_cleanup)",
"subs": [
{
"id": "F09a",
"summary": "离线保留期内上线送达",
"status": "pass",
"evidence": "test/accept/accept_test.go"
},
{
"id": "F09b",
"summary": "超时过期",
"status": "pass",
"evidence": "internal/app/message/delivery_test.go TestDeliveryStateMachine/F09_keep_ttl_expire_via_cleanup"
}
],
"passed": 2,
"total": 2
},
{
"id": "F10",
"status": "pass",
"note": "F10a 通过(test/accept/rest_accept_test.go);F10b 通过(test/accept/rest_accept_test.go);F10c 通过(test/accept/rest_accept_test.go)",
"subs": [
{
"id": "F10a",
"summary": "短断线送到",
"status": "pass",
"evidence": "test/accept/rest_accept_test.go"
},
{
"id": "F10b",
"summary": "长断线丢弃",
"status": "pass",
"evidence": "test/accept/rest_accept_test.go"
},
{
"id": "F10c",
"summary": "服务器重启后宽限内重连送到",
"status": "pass",
"evidence": "test/accept/rest_accept_test.go"
}
],
"passed": 3,
"total": 3
},
{
"id": "F11",
"status": "pass",
"note": "F11a 通过(test/accept/rest_accept_test.go)",
"subs": [
{
"id": "F11a",
"summary": "发送方离线后到点仍发送",
"status": "pass",
"evidence": "test/accept/rest_accept_test.go"
}
],
"passed": 1,
"total": 1
},
{
"id": "F12",
"status": "pass",
"note": "F12a 通过(test/accept/accept_test.go)",
"subs": [
{
"id": "F12a",
"summary": "延迟窗口内撤回对方收不到",
"status": "pass",
"evidence": "test/accept/accept_test.go"
}
],
"passed": 1,
"total": 1
},
{
"id": "F13",
"status": "pass",
"note": "F13a 通过(test/accept/accept_test.go);F13b 通过(internal/app/message/delivery_test.go TestDeliveryStateMachine/F13_recall_race_partial)",
"subs": [
{
"id": "F13a",
"summary": "未推送必撤成功",
"status": "pass",
"evidence": "test/accept/accept_test.go"
},
{
"id": "F13b",
"summary": "群部分确认得到部分撤回",
"status": "pass",
"evidence": "internal/app/message/delivery_test.go TestDeliveryStateMachine/F13_recall_race_partial"
}
],
"passed": 2,
"total": 2
},
{
"id": "F14",
"status": "pass",
"note": "F14a 通过(test/accept/rest_accept_test.go)",
"subs": [
{
"id": "F14a",
"summary": "回执能补送给当时离线的发送方",
"status": "pass",
"evidence": "test/accept/rest_accept_test.go"
}
],
"passed": 1,
"total": 1
},
{
"id": "F15",
"status": "pass",
"note": "F15a 通过(test/accept/rest_accept_test.go;internal/app/identity/self_talk_test.go TestF15TalkPasswordAuth);F15b 通过(test/accept/rest_accept_test.go;internal/app/identity/self_talk_test.go TestF15ReplyGrantAndChange);F15c 通过(test/accept/rest_accept_test.go;internal/app/identity/self_talk_test.go);F15d 通过(test/accept/rest_accept_test.go;internal/app/identity/self_talk_test.go TestF15JoinNeedsPasswordDespiteGrant);F15e 通过(test/accept/rest_accept_test.go)",
"subs": [
{
"id": "F15a",
"summary": "输一次记住",
"status": "pass",
"evidence": "test/accept/rest_accept_test.go;internal/app/identity/self_talk_test.go TestF15TalkPasswordAuth"
},
{
"id": "F15b",
"summary": "改密失效",
"status": "pass",
"evidence": "test/accept/rest_accept_test.go;internal/app/identity/self_talk_test.go TestF15ReplyGrantAndChange"
},
{
"id": "F15c",
"summary": "回复免密",
"status": "pass",
"evidence": "test/accept/rest_accept_test.go;internal/app/identity/self_talk_test.go"
},
{
"id": "F15d",
"summary": "进群仍要密码",
"status": "pass",
"evidence": "test/accept/rest_accept_test.go;internal/app/identity/self_talk_test.go TestF15JoinNeedsPasswordDespiteGrant"
},
{
"id": "F15e",
"summary": "防多账号轮流猜",
"status": "pass",
"evidence": "test/accept/rest_accept_test.go"
}
],
"passed": 5,
"total": 5
},
{
"id": "F16",
"status": "pass",
"note": "F16a 通过(test/accept/accept_test.go);F16b 通过(internal/app/group/group_test.go TestF16CreateAddPasswordAndOwner);F16c 通过(internal/app/group/group_test.go TestF16LeaveRemoveDissolve);F16d 通过(internal/app/group/group_test.go TestF16LeaveRemoveDissolve)",
"subs": [
{
"id": "F16a",
"summary": "建群拉成员后可群发",
"status": "pass",
"evidence": "test/accept/accept_test.go"
},
{
"id": "F16b",
"summary": "群主权限",
"status": "pass",
"evidence": "internal/app/group/group_test.go TestF16CreateAddPasswordAndOwner"
},
{
"id": "F16c",
"summary": "退出后不再收到",
"status": "pass",
"evidence": "internal/app/group/group_test.go TestF16LeaveRemoveDissolve"
},
{
"id": "F16d",
"summary": "解散后同编号新群不收旧消息",
"status": "pass",
"evidence": "internal/app/group/group_test.go TestF16LeaveRemoveDissolve"
}
],
"passed": 4,
"total": 4
},
{
"id": "F17",
"status": "pass",
"note": "F17a 通过(test/accept/accept_test.go runAdminAuth);F17b 通过(test/accept/accept_test.go runEndpointCreate);F17c 通过(test/accept/accept_test.go runRegistration;internal/admin/a3_test.go TestRegistrationToggleAndGenerate);F17d 通过(internal/admin/a3_test.go TestGroupsCRUD);F17e 通过(internal/admin/a3_test.go TestMessageDetailHasNoBody);F17f 通过(internal/admin/admin_test.go TestAPITokenAuthAndRestrictions)",
"subs": [
{
"id": "F17a",
"summary": "管理登录、CSRF、错误密码锁定",
"status": "pass",
"evidence": "test/accept/accept_test.go runAdminAuth"
},
{
"id": "F17b",
"summary": "管端开通",
"status": "pass",
"evidence": "test/accept/accept_test.go runEndpointCreate"
},
{
"id": "F17c",
"summary": "管注册",
"status": "pass",
"evidence": "test/accept/accept_test.go runRegistration;internal/admin/a3_test.go TestRegistrationToggleAndGenerate"
},
{
"id": "F17d",
"summary": "管群",
"status": "pass",
"evidence": "internal/admin/a3_test.go TestGroupsCRUD"
},
{
"id": "F17e",
"summary": "查记录响应无正文",
"status": "pass",
"evidence": "internal/admin/a3_test.go TestMessageDetailHasNoBody"
},
{
"id": "F17f",
"summary": "API 令牌可用且不能越权",
"status": "pass",
"evidence": "internal/admin/admin_test.go TestAPITokenAuthAndRestrictions"
}
],
"passed": 6,
"total": 6
},
{
"id": "F18",
"status": "pass",
"note": "F18a 通过(test/accept/rest_accept_test.go;internal/app/message/delivery_test.go TestDeliveryStateMachine/F18_body_gone_record_zero_idempotent_kept);F18b 通过(test/accept/rest_accept_test.go);F18c 通过(test/accept/rest_accept_test.go;internal/app/message/submit_test.go TestSubmitTable/idempotent_hit)",
"subs": [
{
"id": "F18a",
"summary": "送达后正文消失",
"status": "pass",
"evidence": "test/accept/rest_accept_test.go;internal/app/message/delivery_test.go TestDeliveryStateMachine/F18_body_gone_record_zero_idempotent_kept"
},
{
"id": "F18b",
"summary": "记录天数 0 时连记录消失",
"status": "pass",
"evidence": "test/accept/rest_accept_test.go"
},
{
"id": "F18c",
"summary": "防重仍在",
"status": "pass",
"evidence": "test/accept/rest_accept_test.go;internal/app/message/submit_test.go TestSubmitTable/idempotent_hit"
}
],
"passed": 3,
"total": 3
},
{
"id": "F19",
"status": "pass",
"note": "F19a 通过(sdk/go/itest_checklist_test.go;sdk/js/test/checklist.test.ts;sdk/python/tests/test_checklist.py;sdk/java ChecklistTest)",
"subs": [
{
"id": "F19a",
"summary": "四种 SDK 接入清单(仓库内已有测试,本波不重跑全量)",
"status": "pass",
"evidence": "sdk/go/itest_checklist_test.go;sdk/js/test/checklist.test.ts;sdk/python/tests/test_checklist.py;sdk/java ChecklistTest"
}
],
"passed": 1,
"total": 1
},
{
"id": "F20",
"status": "pass",
"note": "F20a 通过(test/accept/accept_test.go runMessagingAccept)",
"subs": [
{
"id": "F20a",
"summary": "裸 MQTT WebSocket 登录、收、确认、发",
"status": "pass",
"evidence": "test/accept/accept_test.go runMessagingAccept"
}
],
"passed": 1,
"total": 1
},
{
"id": "F21",
"status": "partial",
"note": "F21a 通过(test/accept/accept_test.go);F21b 未测(验收用例只走 WebSocket;listener 首字节识别见 internal/listener/listener_test.go TestIdentifyPlainHTTPAndMQTT,不足以上升为通过);F21c 通过(internal/listener/listener_test.go TestAdminSeparateMQTTClosedAndAdmin404OnListen)",
"subs": [
{
"id": "F21a",
"summary": "同一 listen 端口提供后台、WebSocket、注册",
"status": "pass",
"evidence": "test/accept/accept_test.go"
},
{
"id": "F21b",
"summary": "裸 TCP MQTT 登录收发",
"status": "untested",
"note": "验收用例只走 WebSocket;listener 首字节识别见 internal/listener/listener_test.go TestIdentifyPlainHTTPAndMQTT,不足以上升为通过"
},
{
"id": "F21c",
"summary": "后台可分到单独端口",
"status": "pass",
"evidence": "internal/listener/listener_test.go TestAdminSeparateMQTTClosedAndAdmin404OnListen"
}
],
"passed": 2,
"total": 3
},
{
"id": "F22",
"status": "partial",
"note": "F22a 通过(test/accept/accept_test.go runInitHealthz);F22b 通过(cmd/nixmsg/commands_test.go TestBackupVacuumInto);F22c 通过(internal/store/db_test.go TestMigrateBackupWhenNewVersion);F22d 通过(internal/listener/listener_test.go TestCertReloadUsesNewCert);F22e 通过(internal/metrics/metrics_test.go TestMetricsHandlerExposesText;internal/httpx/metrics_test.go TestMetricsGateSharedPort);F22f 未测(镜像未推送;本波未跑 compose 全量)",
"subs": [
{
"id": "F22a",
"summary": "空目录 admin init + serve 健康检查",
"status": "pass",
"evidence": "test/accept/accept_test.go runInitHealthz"
},
{
"id": "F22b",
"summary": "备份",
"status": "pass",
"evidence": "cmd/nixmsg/commands_test.go TestBackupVacuumInto"
},
{
"id": "F22c",
"summary": "升级迁移前备份",
"status": "pass",
"evidence": "internal/store/db_test.go TestMigrateBackupWhenNewVersion"
},
{
"id": "F22d",
"summary": "证书按 mtime 重载",
"status": "pass",
"evidence": "internal/listener/listener_test.go TestCertReloadUsesNewCert"
},
{
"id": "F22e",
"summary": "指标可抓取",
"status": "pass",
"evidence": "internal/metrics/metrics_test.go TestMetricsHandlerExposesText;internal/httpx/metrics_test.go TestMetricsGateSharedPort"
},
{
"id": "F22f",
"summary": "Docker 全量冒烟",
"status": "untested",
"note": "镜像未推送;本波未跑 compose 全量"
}
],
"passed": 5,
"total": 6
},
{
"id": "F23",
"status": "pass",
"note": "F23a 通过(test/accept/accept_test.go runRegistration;internal/app/identity/register_test.go TestRegisterF23_*);F23b 通过(internal/app/identity/register_test.go TestRegisterF23_WrongCodeLock)",
"subs": [
{
"id": "F23a",
"summary": "注册开关、安全码校验、换码不影响已注册",
"status": "pass",
"evidence": "test/accept/accept_test.go runRegistration;internal/app/identity/register_test.go TestRegisterF23_*"
},
{
"id": "F23b",
"summary": "输错锁定",
"status": "pass",
"evidence": "internal/app/identity/register_test.go TestRegisterF23_WrongCodeLock"
}
],
"passed": 2,
"total": 2
}
]
}