discover/Discover_test.go

165 lines
3.6 KiB
Go
Raw 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.

package discover_test
import (
"fmt"
"net"
"net/http"
"os"
"testing"
"time"
"github.com/gorilla/websocket"
"apigo.cc/go/discover"
"apigo.cc/go/redis"
)
func TestDiscover(t *testing.T) {
// 启动一个模拟服务
l, err := net.Listen("tcp", "127.0.0.1:0")
if err != nil {
t.Skip("failed to listen, skipping test")
return
}
addr := l.Addr().String()
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
_, _ = w.Write([]byte("OK"))
})
upgrader := websocket.Upgrader{}
mux.HandleFunc("/ws", func(w http.ResponseWriter, r *http.Request) {
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
return
}
defer conn.Close()
for {
mt, message, err := conn.ReadMessage()
if err != nil {
break
}
_ = conn.WriteMessage(mt, message)
}
})
server := &http.Server{Handler: mux}
go func() { _ = server.Serve(l) }()
defer server.Close()
// 配置 Discover
conf := discover.DefaultDiscoverer.GetConfig()
conf.App = "test-app"
conf.Registry = "redis://127.0.0.1:6379/15"
discover.DefaultDiscoverer.SetConfig(conf)
// 启动 Discover
if !discover.Start(addr) {
t.Skip("failed to start discover (check redis), skipping test")
return
}
defer discover.Stop()
// 添加外部应用调用配置
discover.AddExternalApp("test-app", "1")
// 等待节点同步
success := false
for i := 0; i < 20; i++ {
nodes := discover.GetAppNodes("test-app")
if len(nodes) > 0 {
success = true
break
}
time.Sleep(100 * time.Millisecond)
}
if !success {
t.Fatal("node discovery timed out")
}
// 1. 使用 Caller 调用 HTTP
caller := discover.NewCaller(nil, nil)
res := caller.Get("test-app", "/")
if res.Error != nil {
t.Errorf("http call failed: %v", res.Error)
}
if res.String() != "OK" {
t.Errorf("unexpected http response: %s", res.String())
}
// 2. 使用 Caller 调用 WebSocket
wsConn := caller.Open("test-app", "/ws")
if wsConn == nil {
t.Fatal("websocket open failed")
}
defer wsConn.Close()
msg := []byte("hello")
if err := wsConn.WriteMessage(websocket.TextMessage, msg); err != nil {
t.Fatalf("ws write failed: %v", err)
}
_, reply, err := wsConn.ReadMessage()
if err != nil {
t.Fatalf("ws read failed: %v", err)
}
if string(reply) != "hello" {
t.Errorf("unexpected ws reply: %s", string(reply))
}
// 3. 测试负载均衡和节点更新
rd := redis.GetRedis(discover.Config.Registry, nil)
if rd.Error == nil {
// 模拟发现新节点
rd.PUBLISH("CH_test-app", "127.0.0.1:18002 100")
success = false
for i := 0; i < 20; i++ {
nodes := discover.GetAppNodes("test-app")
if len(nodes) >= 2 {
success = true
break
}
time.Sleep(100 * time.Millisecond)
}
if !success {
t.Error("node update sync failed")
}
}
}
func TestEasyStart(t *testing.T) {
// 模拟环境变量
_ = os.Setenv("DISCOVER_APP", "test-app")
_ = os.Setenv("DISCOVER_LISTEN", "18003")
_ = os.Setenv("DISCOVER_REGISTRY", "redis://127.0.0.1:6379/15")
ip, port := discover.EasyStart()
if ip == "" || port == 0 {
t.Skip("EasyStart failed (check redis), skipping test")
return
}
fmt.Printf("EasyStart: %s:%d\n", ip, port)
discover.Stop()
}
func BenchmarkDiscover(b *testing.B) {
discover.Init()
discover.SetNode("bench-app", "127.0.0.1:8080", 100)
discover.SetNode("bench-app", "127.0.0.1:8081", 100)
b.ResetTimer()
for i := 0; i < b.N; i++ {
// 模拟 AppClient 的 Next 逻辑
appClient := discover.AppClient{
App: "bench-app",
Method: "GET",
Path: "/",
}
// 这里需要绕过复杂的 Caller.Do只测试核心的选择逻辑
node := appClient.Next("bench-app", nil)
if node == nil {
b.Fatal("no node")
}
}
}