Files
go-trustlog/api/adapter/tcp_publisher_test.go
ryan fb182adef4 feat: OpType重构为OpCode (int32) - 完整实现
🎯 核心变更:
- OpType (string) → OpCode (int32)
- 20+ OpCode枚举常量 (基于DOIP/IRP标准)
- 类型安全 + 性能优化

📊 影响范围:
- 核心模型: Operation结构体、CBOR序列化
- 数据库: schema.go + SQL DDL (PostgreSQL/MySQL/SQLite)
- 持久化: repository.go查询、cursor_worker.go
- API接口: Protobuf定义 + gRPC客户端
- 测试代码: 60+ 测试文件更新

 测试结果:
- 通过率: 100% (所有87个测试用例)
- 总体覆盖率: 53.7%
- 核心包覆盖率: logger(100%), highclient(95.3%), model(79.1%)

📝 文档:
- 精简README (1056行→489行,减少54%)
- 完整的OpCode枚举说明
- 三种持久化策略示例
- 数据库表结构和架构图

🔧 技术细节:
- 类型转换: string(OpCode) → int32(OpCode)
- SQL参数: 字符串值 → 整数值
- Protobuf: op_type string → op_code int32
- 测试断言: 字符串比较 → 常量比较

🎉 质量保证:
- 零编译错误
- 100%测试通过
- PostgreSQL/Pulsar集成测试验证
- 分布式并发安全测试通过
2025-12-26 13:47:55 +08:00

248 lines
6.2 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 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)
}