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.
nnet/test/integration/protocol_header_test.go

160 lines
4.1 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 (
"encoding/json"
"fmt"
"net"
"testing"
"time"
internalprotocol "git.noahlan.cn/noahlan/nnet/v2/internal/protocol/nnet"
"git.noahlan.cn/noahlan/nnet/v2/pkg/nnet"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
// TestProtocolFrameHeader 测试协议帧头匹配
func TestProtocolFrameHeader(t *testing.T) {
listener, err := net.Listen("tcp", "127.0.0.1:0")
require.NoError(t, err)
port := listener.Addr().(*net.TCPAddr).Port
listener.Close()
cfg := &nnet.Config{
Addr: fmt.Sprintf("tcp://127.0.0.1:%d", port),
ApplicationProtocol: "nnet",
Codec: &nnet.CodecConfig{
DefaultCodec: "json",
EnableProtocolEncode: true,
},
}
server, err := nnet.NewServer(cfg)
require.NoError(t, err)
// 注册协议
pm := server.ProtocolManager()
proto := internalprotocol.NewNNetProtocol("1.0")
require.NoError(t, pm.Register(proto), "Should register protocol")
// 注册帧头匹配路由nnet帧头包含magic/version/length/checksum等字段。
server.Router().RegisterFrameHeader("version", "==", byte(1), func(ctx nnet.Context) error {
return ctx.Response().Write(map[string]any{
"op": "pong",
"status": "ok",
})
})
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")
time.Sleep(200 * time.Millisecond)
defer CleanupTestServer(t, ts)
// 创建客户端
client := NewTestClient(t, ts.Addr, &nnet.ClientConfig{
ApplicationProtocol: "nnet",
})
defer CleanupTestClient(t, client)
ConnectTestClient(t, client)
time.Sleep(100 * time.Millisecond)
pingData := []byte(`{"op":"ping"}`)
resp := RequestWithTimeout(t, client, pingData, 3*time.Second)
t.Logf("Response: %q", string(resp))
var result map[string]any
err = json.Unmarshal(resp, &result)
assert.NoError(t, err, "Response should be valid JSON")
assert.Equal(t, "pong", result["op"], "Op should be pong")
assert.Equal(t, "ok", result["status"], "Status should be ok")
}
// TestProtocolFrameData 测试协议帧数据匹配
func TestProtocolFrameData(t *testing.T) {
listener, err := net.Listen("tcp", "127.0.0.1:0")
require.NoError(t, err)
port := listener.Addr().(*net.TCPAddr).Port
listener.Close()
cfg := &nnet.Config{
Addr: fmt.Sprintf("tcp://127.0.0.1:%d", port),
ApplicationProtocol: "nnet",
Codec: &nnet.CodecConfig{
DefaultCodec: "json",
EnableProtocolEncode: true,
},
}
server, err := nnet.NewServer(cfg)
require.NoError(t, err)
// 注册协议
pm := server.ProtocolManager()
proto := internalprotocol.NewNNetProtocol("1.0")
require.NoError(t, pm.Register(proto), "Should register protocol")
// 注册帧数据匹配路由
server.Router().RegisterFrameData("action", "==", "test", func(ctx nnet.Context) error {
return ctx.Response().Write(map[string]any{
"action": "test",
"result": "success",
})
})
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")
time.Sleep(200 * time.Millisecond)
defer CleanupTestServer(t, ts)
client := NewTestClient(t, ts.Addr, &nnet.ClientConfig{
ApplicationProtocol: "nnet",
})
defer CleanupTestClient(t, client)
ConnectTestClient(t, client)
time.Sleep(100 * time.Millisecond)
testData := []byte(`{"action":"test"}`)
resp := RequestWithTimeout(t, client, testData, 3*time.Second)
t.Logf("Response: %q", string(resp))
var result map[string]any
err = json.Unmarshal(resp, &result)
assert.NoError(t, err, "Response should be valid JSON")
assert.Equal(t, "test", result["action"], "Action should be test")
assert.Equal(t, "success", result["result"], "Result should be success")
}