refactor: 重构trustlog-sdk目录结构到trustlog/go-trustlog
- 将所有trustlog-sdk文件移动到trustlog/go-trustlog/目录 - 更新README中所有import路径从trustlog-sdk改为go-trustlog - 更新cookiecutter配置文件中的项目名称 - 更新根目录.lefthook.yml以引用新位置的配置 - 添加go.sum文件到版本控制 - 删除过时的示例文件 这次重构与trustlog-server保持一致的目录结构, 为未来支持多语言SDK(Python、Java等)预留空间。
This commit is contained in:
229
api/adapter/tcp_integration_test.go
Normal file
229
api/adapter/tcp_integration_test.go
Normal file
@@ -0,0 +1,229 @@
|
||||
package adapter
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/ThreeDotsLabs/watermill/message"
|
||||
)
|
||||
|
||||
// 简单的测试日志适配器
|
||||
type testLogger struct{}
|
||||
|
||||
func (t *testLogger) InfoContext(ctx context.Context, msg string, args ...interface{}) {}
|
||||
func (t *testLogger) DebugContext(ctx context.Context, msg string, args ...interface{}) {}
|
||||
func (t *testLogger) WarnContext(ctx context.Context, msg string, args ...interface{}) {}
|
||||
func (t *testLogger) ErrorContext(ctx context.Context, msg string, args ...interface{}) {}
|
||||
func (t *testLogger) Info(msg string, args ...interface{}) {}
|
||||
func (t *testLogger) Debug(msg string, args ...interface{}) {}
|
||||
func (t *testLogger) Warn(msg string, args ...interface{}) {}
|
||||
func (t *testLogger) Error(msg string, args ...interface{}) {}
|
||||
|
||||
func TestTCPPublisherSubscriber_Integration(t *testing.T) {
|
||||
testLogger := &testLogger{}
|
||||
|
||||
// 创建 Subscriber
|
||||
subscriberConfig := TCPSubscriberConfig{
|
||||
ListenAddr: "127.0.0.1:18080",
|
||||
}
|
||||
subscriber, err := NewTCPSubscriber(subscriberConfig, testLogger)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create subscriber: %v", err)
|
||||
}
|
||||
defer subscriber.Close()
|
||||
|
||||
// 等待服务器启动
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
|
||||
// 订阅 topic
|
||||
ctx := context.Background()
|
||||
topic := "test-topic"
|
||||
msgChan, err := subscriber.Subscribe(ctx, topic)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to subscribe: %v", err)
|
||||
}
|
||||
|
||||
// 创建 Publisher
|
||||
publisherConfig := TCPPublisherConfig{
|
||||
ServerAddr: "127.0.0.1:18080",
|
||||
ConnectTimeout: 5 * time.Second,
|
||||
}
|
||||
publisher, err := NewTCPPublisher(publisherConfig, testLogger)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create publisher: %v", err)
|
||||
}
|
||||
defer publisher.Close()
|
||||
|
||||
// 测试发送和接收消息
|
||||
testPayload := []byte("Hello, TCP Watermill!")
|
||||
testMsg := message.NewMessage("test-msg-1", testPayload)
|
||||
|
||||
// 启动接收协程
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
select {
|
||||
case receivedMsg := <-msgChan:
|
||||
if string(receivedMsg.Payload) != string(testPayload) {
|
||||
t.Errorf("Payload mismatch: got %s, want %s", receivedMsg.Payload, testPayload)
|
||||
}
|
||||
if receivedMsg.UUID != testMsg.UUID {
|
||||
t.Errorf("UUID mismatch: got %s, want %s", receivedMsg.UUID, testMsg.UUID)
|
||||
}
|
||||
// ACK 消息
|
||||
receivedMsg.Ack()
|
||||
case <-time.After(5 * time.Second):
|
||||
t.Error("Timeout waiting for message")
|
||||
}
|
||||
}()
|
||||
|
||||
// 发送消息
|
||||
err = publisher.Publish(topic, testMsg)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to publish message: %v", err)
|
||||
}
|
||||
|
||||
// 等待接收完成
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func TestTCPPublisherSubscriber_MultipleMessages(t *testing.T) {
|
||||
testLogger := &testLogger{}
|
||||
|
||||
// 创建 Subscriber
|
||||
subscriberConfig := TCPSubscriberConfig{
|
||||
ListenAddr: "127.0.0.1:18081",
|
||||
}
|
||||
subscriber, err := NewTCPSubscriber(subscriberConfig, testLogger)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create subscriber: %v", err)
|
||||
}
|
||||
defer subscriber.Close()
|
||||
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
|
||||
// 订阅
|
||||
ctx := context.Background()
|
||||
topic := "test-topic-multi"
|
||||
msgChan, err := subscriber.Subscribe(ctx, topic)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to subscribe: %v", err)
|
||||
}
|
||||
|
||||
// 创建 Publisher
|
||||
publisherConfig := TCPPublisherConfig{
|
||||
ServerAddr: "127.0.0.1:18081",
|
||||
ConnectTimeout: 5 * time.Second,
|
||||
}
|
||||
publisher, err := NewTCPPublisher(publisherConfig, testLogger)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create publisher: %v", err)
|
||||
}
|
||||
defer publisher.Close()
|
||||
|
||||
// 准备多条消息
|
||||
messageCount := 10
|
||||
messages := make([]*message.Message, messageCount)
|
||||
for i := 0; i < messageCount; i++ {
|
||||
payload := []byte("Message " + string(rune('0'+i)))
|
||||
messages[i] = message.NewMessage("msg-"+string(rune('0'+i)), payload)
|
||||
}
|
||||
|
||||
// 启动接收协程
|
||||
receivedCount := 0
|
||||
var mu sync.Mutex
|
||||
var wg sync.WaitGroup
|
||||
|
||||
for i := 0; i < messageCount; i++ {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
select {
|
||||
case receivedMsg := <-msgChan:
|
||||
mu.Lock()
|
||||
receivedCount++
|
||||
mu.Unlock()
|
||||
receivedMsg.Ack()
|
||||
case <-time.After(10 * time.Second):
|
||||
t.Error("Timeout waiting for message")
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
// 发送消息(并发发送)
|
||||
err = publisher.Publish(topic, messages...)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to publish messages: %v", err)
|
||||
}
|
||||
|
||||
// 等待接收完成
|
||||
wg.Wait()
|
||||
|
||||
if receivedCount != messageCount {
|
||||
t.Errorf("Received count mismatch: got %d, want %d", receivedCount, messageCount)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTCPPublisherSubscriber_Nack(t *testing.T) {
|
||||
testLogger := &testLogger{}
|
||||
|
||||
// 创建 Subscriber
|
||||
subscriberConfig := TCPSubscriberConfig{
|
||||
ListenAddr: "127.0.0.1:18082",
|
||||
}
|
||||
subscriber, err := NewTCPSubscriber(subscriberConfig, testLogger)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create subscriber: %v", err)
|
||||
}
|
||||
defer subscriber.Close()
|
||||
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
|
||||
// 订阅
|
||||
ctx := context.Background()
|
||||
topic := "test-topic-nack"
|
||||
msgChan, err := subscriber.Subscribe(ctx, topic)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to subscribe: %v", err)
|
||||
}
|
||||
|
||||
// 创建 Publisher
|
||||
publisherConfig := TCPPublisherConfig{
|
||||
ServerAddr: "127.0.0.1:18082",
|
||||
ConnectTimeout: 5 * time.Second,
|
||||
}
|
||||
publisher, err := NewTCPPublisher(publisherConfig, testLogger)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create publisher: %v", err)
|
||||
}
|
||||
defer publisher.Close()
|
||||
|
||||
// 准备消息
|
||||
testMsg := message.NewMessage("nack-test", []byte("This will be nacked"))
|
||||
|
||||
// 启动接收协程,这次 NACK
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
select {
|
||||
case receivedMsg := <-msgChan:
|
||||
// NACK 消息
|
||||
receivedMsg.Nack()
|
||||
case <-time.After(5 * time.Second):
|
||||
t.Error("Timeout waiting for message")
|
||||
}
|
||||
}()
|
||||
|
||||
// 发送消息,由于不等待ACK,应该立即返回成功
|
||||
// 注意:即使消费者NACK,发布者也会返回成功
|
||||
err = publisher.Publish(topic, testMsg)
|
||||
if err != nil {
|
||||
t.Errorf("Expected no error (fire-and-forget), got: %v", err)
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
}
|
||||
Reference in New Issue
Block a user