package adapter_test import ( "testing" "time" "github.com/ThreeDotsLabs/watermill/message" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.yandata.net/iod/iod/trustlog-sdk/api/adapter" "go.yandata.net/iod/iod/trustlog-sdk/api/logger" ) // 验证 TCPPublisher 实现了 message.Publisher 接口 func TestTCPPublisher_ImplementsPublisherInterface(t *testing.T) { var _ message.Publisher = (*adapter.TCPPublisher)(nil) } func TestNewTCPPublisher_Success(t *testing.T) { t.Parallel() log := logger.NewNopLogger() // 首先创建一个订阅者作为服务器 subscriberConfig := adapter.TCPSubscriberConfig{ ListenAddr: "127.0.0.1:19090", } subscriber, err := adapter.NewTCPSubscriber(subscriberConfig, log) require.NoError(t, err) defer subscriber.Close() // 等待服务器启动 time.Sleep(100 * time.Millisecond) // 创建 Publisher config := adapter.TCPPublisherConfig{ ServerAddr: "127.0.0.1:19090", ConnectTimeout: 2 * time.Second, } publisher, err := adapter.NewTCPPublisher(config, log) require.NoError(t, err) assert.NotNil(t, publisher) err = publisher.Close() require.NoError(t, err) } func TestNewTCPPublisher_InvalidServerAddr(t *testing.T) { t.Parallel() log := logger.NewNopLogger() config := adapter.TCPPublisherConfig{ ServerAddr: "", ConnectTimeout: 2 * time.Second, } _, err := adapter.NewTCPPublisher(config, log) require.Error(t, err) assert.ErrorIs(t, err, adapter.ErrServerAddrRequired) } func TestNewTCPPublisher_ConnectionFailed(t *testing.T) { t.Parallel() log := logger.NewNopLogger() // 尝试连接到不存在的服务器 config := adapter.TCPPublisherConfig{ ServerAddr: "127.0.0.1:19999", ConnectTimeout: 1 * time.Second, } _, err := adapter.NewTCPPublisher(config, log) require.Error(t, err) assert.Contains(t, err.Error(), "failed to connect") } func TestTCPPublisher_Publish_NoWaitForAck(t *testing.T) { t.Parallel() log := logger.NewNopLogger() // 创建订阅者 subscriberConfig := adapter.TCPSubscriberConfig{ ListenAddr: "127.0.0.1:19091", } subscriber, err := adapter.NewTCPSubscriber(subscriberConfig, log) require.NoError(t, err) defer subscriber.Close() time.Sleep(100 * time.Millisecond) // 创建 Publisher config := adapter.TCPPublisherConfig{ ServerAddr: "127.0.0.1:19091", ConnectTimeout: 2 * time.Second, } publisher, err := adapter.NewTCPPublisher(config, log) require.NoError(t, err) defer publisher.Close() // 发送消息,应该立即返回成功,不等待ACK msg := message.NewMessage("test-uuid-1", []byte("test payload")) start := time.Now() err = publisher.Publish("test-topic", msg) elapsed := time.Since(start) // 验证发送成功 require.NoError(t, err) // 验证发送速度很快(不应该等待ACK超时) // 应该在100ms内返回(实际应该只需要几毫秒) assert.Less(t, elapsed, 100*time.Millisecond, "Publish should return immediately without waiting for ACK") } func TestTCPPublisher_Publish_MultipleMessages(t *testing.T) { t.Parallel() log := logger.NewNopLogger() // 创建订阅者 subscriberConfig := adapter.TCPSubscriberConfig{ ListenAddr: "127.0.0.1:19092", } subscriber, err := adapter.NewTCPSubscriber(subscriberConfig, log) require.NoError(t, err) defer subscriber.Close() time.Sleep(100 * time.Millisecond) // 创建 Publisher config := adapter.TCPPublisherConfig{ ServerAddr: "127.0.0.1:19092", ConnectTimeout: 2 * time.Second, } publisher, err := adapter.NewTCPPublisher(config, log) require.NoError(t, err) defer publisher.Close() // 发送多条消息 msg1 := message.NewMessage("uuid-1", []byte("payload-1")) msg2 := message.NewMessage("uuid-2", []byte("payload-2")) msg3 := message.NewMessage("uuid-3", []byte("payload-3")) start := time.Now() err = publisher.Publish("test-topic", msg1, msg2, msg3) elapsed := time.Since(start) require.NoError(t, err) // 发送3条消息应该很快完成 assert.Less(t, elapsed, 200*time.Millisecond, "Publishing multiple messages should be fast") } func TestTCPPublisher_Publish_AfterClose(t *testing.T) { t.Parallel() log := logger.NewNopLogger() // 创建订阅者 subscriberConfig := adapter.TCPSubscriberConfig{ ListenAddr: "127.0.0.1:19093", } subscriber, err := adapter.NewTCPSubscriber(subscriberConfig, log) require.NoError(t, err) defer subscriber.Close() time.Sleep(100 * time.Millisecond) // 创建 Publisher config := adapter.TCPPublisherConfig{ ServerAddr: "127.0.0.1:19093", ConnectTimeout: 2 * time.Second, } publisher, err := adapter.NewTCPPublisher(config, log) require.NoError(t, err) // 关闭 Publisher err = publisher.Close() require.NoError(t, err) // 尝试在关闭后发送消息 msg := message.NewMessage("uuid", []byte("payload")) err = publisher.Publish("test-topic", msg) require.Error(t, err) assert.ErrorIs(t, err, adapter.ErrPublisherClosed) } func TestTCPPublisher_Publish_NilMessage(t *testing.T) { t.Parallel() log := logger.NewNopLogger() // 创建订阅者 subscriberConfig := adapter.TCPSubscriberConfig{ ListenAddr: "127.0.0.1:19094", } subscriber, err := adapter.NewTCPSubscriber(subscriberConfig, log) require.NoError(t, err) defer subscriber.Close() time.Sleep(100 * time.Millisecond) // 创建 Publisher config := adapter.TCPPublisherConfig{ ServerAddr: "127.0.0.1:19094", ConnectTimeout: 2 * time.Second, } publisher, err := adapter.NewTCPPublisher(config, log) require.NoError(t, err) defer publisher.Close() // 发送 nil 消息应该被忽略 err = publisher.Publish("test-topic", nil) require.NoError(t, err) } func TestTCPPublisher_Close_Multiple(t *testing.T) { t.Parallel() log := logger.NewNopLogger() // 创建订阅者 subscriberConfig := adapter.TCPSubscriberConfig{ ListenAddr: "127.0.0.1:19095", } subscriber, err := adapter.NewTCPSubscriber(subscriberConfig, log) require.NoError(t, err) defer subscriber.Close() time.Sleep(100 * time.Millisecond) // 创建 Publisher config := adapter.TCPPublisherConfig{ ServerAddr: "127.0.0.1:19095", ConnectTimeout: 2 * time.Second, } publisher, err := adapter.NewTCPPublisher(config, log) require.NoError(t, err) // 多次关闭应该不会报错 err = publisher.Close() require.NoError(t, err) err = publisher.Close() require.NoError(t, err) }