You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

220 lines
5.6 KiB
Go

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package integration
import (
"fmt"
"net"
"testing"
"time"
"github.com/noahlann/nnet/pkg/nnet"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
// TestBasicServerClient 测试基本服务器-客户端通信
func TestBasicServerClient(t *testing.T) {
// 创建服务器配置使用StartTestServer会自动处理随机端口
cfg := &nnet.Config{
Addr: "tcp://:0",
Codec: &nnet.CodecConfig{
DefaultCodec: "json",
EnableProtocolEncode: false, // 明确禁用协议编码
},
Logger: &nnet.LoggerConfig{
Level: "debug", // 使用debug级别查看详细日志
Format: "text",
Output: "stdout",
},
}
// 先获取随机端口
listener, err := net.Listen("tcp", "127.0.0.1:0")
require.NoError(t, err)
port := listener.Addr().(*net.TCPAddr).Port
listener.Close()
cfg.Addr = fmt.Sprintf("tcp://127.0.0.1:%d", port)
// 创建服务器(不启动)
server, err := nnet.NewServer(cfg)
require.NoError(t, err, "Failed to create server")
// 在启动前注册路由
server.Router().RegisterString("hello", func(ctx nnet.Context) error {
return ctx.Response().WriteString("Hello, nnet!\n")
})
server.Router().RegisterString("ping", func(ctx nnet.Context) error {
return ctx.Response().WriteString("pong\n")
})
// 启动服务器
ts := &TestServer{
Server: server,
Addr: cfg.Addr,
stopCh: make(chan struct{}),
}
ts.wg.Add(1)
go func() {
defer ts.wg.Done()
if err := server.Start(); err != nil {
t.Logf("Server error: %v", err)
}
}()
// 等待服务器启动
require.Eventually(t, func() bool {
return server.Started()
}, 3*time.Second, 50*time.Millisecond, "Server should start within 3 seconds")
time.Sleep(200 * time.Millisecond)
defer CleanupTestServer(t, ts)
// 创建客户端
client := NewTestClient(t, ts.Addr, nil)
defer CleanupTestClient(t, client)
// 连接客户端
ConnectTestClient(t, client)
// 等待一下,确保服务器完全启动
time.Sleep(100 * time.Millisecond)
// 测试 hello 路由
resp := RequestWithTimeout(t, client, []byte("hello"), 3*time.Second)
t.Logf("Response for 'hello': %q", string(resp))
assert.Contains(t, string(resp), "Hello", "Response should contain 'Hello'")
// 测试 ping 路由
resp = RequestWithTimeout(t, client, []byte("ping"), 3*time.Second)
t.Logf("Response for 'ping': %q", string(resp))
assert.Contains(t, string(resp), "pong", "Response should contain 'pong'")
}
// TestEchoRoute 测试 Echo 路由
func TestEchoRoute(t *testing.T) {
cfg := &nnet.Config{
Addr: "tcp://:0",
}
// 获取随机端口
listener, err := net.Listen("tcp", "127.0.0.1:0")
require.NoError(t, err)
port := listener.Addr().(*net.TCPAddr).Port
listener.Close()
cfg.Addr = fmt.Sprintf("tcp://127.0.0.1:%d", port)
// 创建服务器并在启动前注册路由
server, err := nnet.NewServer(cfg)
require.NoError(t, err)
server.Router().RegisterString("echo*", func(ctx nnet.Context) error {
request := string(ctx.Request().Raw())
return ctx.Response().WriteString("Echo: " + request + "\n")
})
// 启动服务器
ts := &TestServer{
Server: server,
Addr: cfg.Addr,
stopCh: make(chan struct{}),
}
ts.wg.Add(1)
go func() {
defer ts.wg.Done()
if err := server.Start(); err != nil {
t.Logf("Server error: %v", err)
}
}()
require.Eventually(t, func() bool {
return server.Started()
}, 3*time.Second, 50*time.Millisecond, "Server should start within 3 seconds")
time.Sleep(200 * time.Millisecond)
defer CleanupTestServer(t, ts)
client := NewTestClient(t, ts.Addr, nil)
defer CleanupTestClient(t, client)
ConnectTestClient(t, client)
// 等待一下,确保服务器完全启动
time.Sleep(100 * time.Millisecond)
// 发送 echo 请求
testData := "echo test message"
resp := RequestWithTimeout(t, client, []byte(testData), 3*time.Second)
t.Logf("Response for 'echo': %q", string(resp))
assert.Contains(t, string(resp), "test message", "Response should echo the message")
}
// TestMultipleClients 测试多个客户端连接
func TestMultipleClients(t *testing.T) {
cfg := &nnet.Config{
Addr: "tcp://:0",
}
// 获取随机端口
listener, err := net.Listen("tcp", "127.0.0.1:0")
require.NoError(t, err)
port := listener.Addr().(*net.TCPAddr).Port
listener.Close()
cfg.Addr = fmt.Sprintf("tcp://127.0.0.1:%d", port)
// 创建服务器并在启动前注册路由
server, err := nnet.NewServer(cfg)
require.NoError(t, err)
server.Router().RegisterString("test", func(ctx nnet.Context) error {
return ctx.Response().WriteString("OK\n")
})
// 启动服务器
ts := &TestServer{
Server: server,
Addr: cfg.Addr,
stopCh: make(chan struct{}),
}
ts.wg.Add(1)
go func() {
defer ts.wg.Done()
if err := server.Start(); err != nil {
t.Logf("Server error: %v", err)
}
}()
require.Eventually(t, func() bool {
return server.Started()
}, 3*time.Second, 50*time.Millisecond, "Server should start within 3 seconds")
time.Sleep(200 * time.Millisecond)
defer CleanupTestServer(t, ts)
// 创建多个客户端
clients := make([]nnet.Client, 3)
for i := 0; i < 3; i++ {
client := NewTestClient(t, ts.Addr, nil)
ConnectTestClient(t, client)
clients[i] = client
}
// 等待一下,确保服务器完全启动
time.Sleep(100 * time.Millisecond)
// 所有客户端都应该能够发送请求
for i, client := range clients {
resp := RequestWithTimeout(t, client, []byte("test"), 3*time.Second)
t.Logf("Response for client %d: %q", i, string(resp))
assert.Contains(t, string(resp), "OK", "Response should contain 'OK'")
}
// 清理所有客户端
for _, client := range clients {
CleanupTestClient(t, client)
}
}