package config import ( "regexp" "strconv" "testing" ) // serviceDefaultPorts 各服务 main.go 顶部 flag.Int("port", ...) 默认端口 // // 单一事实源:必须与 backend/services//main.go 中 // // flag.Int("port", getEnvInt("PORT", <这里>), "Dubbo service port") // // 的硬编码回退值一致。漂移会让网关 Dubbo URL 默认指向错误端口(本目录 DubboConfig)。 // // ★ 批次 4.2:starbookService 已删除,故此处不含。 var serviceDefaultPorts = map[string]int{ "user": 20000, "social": 20002, "asset": 20003, "gallery": 20001, "activity": 20004, "task": 20006, "aiChat": 20008, "statistic": 20009, "notification": 20010, "moderation": 20011, } // TestGateway_DefaultDubboURL_MatchesServiceBinds 校验 Load() 返回的 Dubbo URL // 默认端口 == 各服务 main.go 的默认绑定端口。 // // 该测试是 4.1 端口对齐的回归保险:任一服务修改了 main.go 的 flag 默认值但忘了 // 同步 gateway/config 默认(或反之),会立即失败。 func TestGateway_DefaultDubboURL_MatchesServiceBinds(t *testing.T) { cfg := Load() cases := map[string]string{ "user": cfg.Dubbo.UserServiceURL, "social": cfg.Dubbo.SocialServiceURL, "asset": cfg.Dubbo.AssetServiceURL, "gallery": cfg.Dubbo.GalleryServiceURL, "activity": cfg.Dubbo.ActivityServiceURL, "task": cfg.Dubbo.TaskServiceURL, "aiChat": cfg.Dubbo.AIChatServiceURL, "statistic": cfg.Dubbo.StatisticServiceURL, "notification": cfg.Dubbo.NotificationServiceURL, "moderation": cfg.Dubbo.ModerationServiceURL, } re := regexp.MustCompile(`:(\d+)$`) for name, url := range cases { m := re.FindStringSubmatch(url) if len(m) != 2 { t.Fatalf("%s: URL %q 缺端口", name, url) } got, _ := strconv.Atoi(m[1]) want, ok := serviceDefaultPorts[name] if !ok { t.Fatalf("%s: 在 serviceDefaultPorts 中未声明默认端口", name) } if got != want { t.Errorf("%s: 网关默认 Dubbo URL 端口=%d, 服务实际默认绑定=%d", name, got, want) } } } // TestServiceDefaultPorts_AllListed 防止后续新增服务但忘记在本表声明默认端口, // 进而让 TestGateway_DefaultDubboURL_MatchesServiceBinds 漏掉校验。 func TestServiceDefaultPorts_AllListed(t *testing.T) { // 与 DubboConfig 字段对齐的 10 个常驻服务(批次 4.2 starbookService 已删除) want := []string{ "user", "social", "asset", "gallery", "activity", "task", "aiChat", "statistic", "notification", "moderation", } if got := len(serviceDefaultPorts); got != len(want) { t.Errorf("serviceDefaultPorts 数量=%d, 期望=%d (新增/删除服务需同步此表)", got, len(want)) } for _, name := range want { if _, ok := serviceDefaultPorts[name]; !ok { t.Errorf("service %q 缺失默认端口声明", name) } } } // TestDubboConfig_AllURLsHavePort 防 Load() 后 DubboConfig 任一 URL 解析失败(空串/格式错)。 func TestDubboConfig_AllURLsHavePort(t *testing.T) { cfg := Load() urls := map[string]string{ "UserServiceURL": cfg.Dubbo.UserServiceURL, "SocialServiceURL": cfg.Dubbo.SocialServiceURL, "AssetServiceURL": cfg.Dubbo.AssetServiceURL, "GalleryServiceURL": cfg.Dubbo.GalleryServiceURL, "ActivityServiceURL": cfg.Dubbo.ActivityServiceURL, "TaskServiceURL": cfg.Dubbo.TaskServiceURL, "AIChatServiceURL": cfg.Dubbo.AIChatServiceURL, "StatisticServiceURL": cfg.Dubbo.StatisticServiceURL, "NotificationServiceURL": cfg.Dubbo.NotificationServiceURL, "ModerationServiceURL": cfg.Dubbo.ModerationServiceURL, } re := regexp.MustCompile(`tri://[^:]+:(\d+)$`) for name, url := range urls { if !re.MatchString(url) { t.Errorf("%s=%q 不符合 tri://host:port 格式", name, url) } } }