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) } }