Files
hi-server/internal/model/node/model_test.go
T
shanshanzhong147 634b5a7bd0 feat(simnet): add SimNet protocol end-to-end support
- model: SimNet protocol fields + NormalizeSimnet; type+port protocol uniqueness
- server config: OmnXT runtime config delivery via compatible() simnet case
- credentials: derive per-user psk/key_id from subscription (pkg/simnet), no new table
- subscription: adapter buildOmnxtSimnetConfigs + base64 buildOmnxtProtocolLinks + OmnXT SimNet application (migration 02161)
- UA gating: hide experimental protocols from non first-party clients (download + JSON node-list)
- admin: normalize simnet on create/update and on GET responses
- tests: 21 simnet unit tests; full suite green
2026-07-27 00:17:02 -07:00

78 lines
2.2 KiB
Go

package node
import (
"fmt"
"sort"
"strings"
"testing"
)
// TestServerUserListCacheKeysForServer 验证按 server 枚举出的协议缓存 key 覆盖
// 所有客户端可能携带的 protocol(包括 hysteria2 兼容字段),形态为
// `server:user:{server_id}:{protocol}`。HIF-1: Del 路径必须用枚举而非 SCAN。
func TestServerUserListCacheKeysForServer(t *testing.T) {
const serverId int64 = 42
keys := ServerUserListCacheKeysForServer(serverId)
if len(keys) != len(AllProtocols) {
t.Fatalf("expected %d keys, got %d: %v", len(AllProtocols), len(keys), keys)
}
got := make([]string, len(keys))
copy(got, keys)
sort.Strings(got)
want := make([]string, 0, len(AllProtocols))
for _, p := range AllProtocols {
want = append(want, fmt.Sprintf("%s%d:%s", ServerUserListCacheKey, serverId, p))
}
sort.Strings(want)
for i := range got {
if got[i] != want[i] {
t.Errorf("key[%d] = %q, want %q", i, got[i], want[i])
}
}
}
// TestServerUserListCacheKeysForServer_NoLegacyFlatKey 验证清缓存路径不再使用
// 旧的扁平 key `server:user:{server_id}`(无 protocol 维度)——旧 key 一旦再出现,
// 与 P0-1 写入的带 protocol key 形态不一致,Del 会失效,回归 HIF-1 缺陷。
func TestServerUserListCacheKeysForServer_NoLegacyFlatKey(t *testing.T) {
const serverId int64 = 7
legacy := fmt.Sprintf("%s%d", ServerUserListCacheKey, serverId)
for _, key := range ServerUserListCacheKeysForServer(serverId) {
if key == legacy {
t.Fatalf("Del path still emits legacy flat key %q without protocol", legacy)
}
if !strings.HasPrefix(key, legacy+":") {
t.Errorf("key %q does not match `<flat>:<protocol>` shape", key)
}
}
}
// TestAllProtocolsContainsKnownProtocols 兜底保证 AllProtocols 至少覆盖关键协议;
// 缺失任一会让对应协议的用户列表缓存清不掉。
func TestAllProtocolsContainsKnownProtocols(t *testing.T) {
required := []string{
"shadowsocks",
"vmess",
"vless",
"trojan",
"tuic",
"hysteria",
"hysteria2",
"simnet",
}
set := make(map[string]struct{}, len(AllProtocols))
for _, p := range AllProtocols {
set[p] = struct{}{}
}
for _, r := range required {
if _, ok := set[r]; !ok {
t.Errorf("AllProtocols missing %q", r)
}
}
}