重构:重命名核心组件并增强查询功能
主要更改: 1. 核心重命名 - Seqlog -> LogHub (更准确地反映其作为日志中枢的角色) - NewSeqlog() -> NewLogHub() - LogCursor -> ProcessCursor (更准确地反映其用于处理场景) - seqlog_manager.go -> loghub.go (文件名与结构体名对应) 2. TopicProcessor.Reset 增强 - 如果正在运行且没有待处理的日志,会自动停止后重置 - 如果有待处理的日志,返回详细错误(显示已处理/总记录数) - 简化了 LogHub.ResetTopic,移除显式 Stop 调用 3. 新增查询方法 - TopicProcessor.QueryFromFirst(count) - 从第一条记录向索引递增方向查询 - TopicProcessor.QueryFromLast(count) - 从最后一条记录向索引递减方向查询 - LogHub.QueryFromFirst(topic, count) - LogHub.QueryFromLast(topic, count) 4. 测试覆盖 - 添加 query_test.go - QueryFromProcessing 测试 - 添加 TestQueryFromFirstAndLast - TopicProcessor 查询测试 - 添加 TestLogHubQueryFromFirstAndLast - LogHub 查询测试 - 添加 TestTopicResetWithPendingRecords - Reset 增强功能测试 5. 示例代码 - 添加 example/get_record/ - 演示 QueryFromProcessing 用法 - 更新所有示例以使用 LogHub 和新 API 所有测试通过 ✅ 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
344
seqlog_test.go
344
seqlog_test.go
@@ -437,7 +437,7 @@ func TestSeqlogBasic(t *testing.T) {
|
||||
os.MkdirAll(tmpDir, 0755)
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
seqlog := NewSeqlog(tmpDir, slog.Default(), nil)
|
||||
seqlog := NewLogHub(tmpDir, slog.Default(), nil)
|
||||
|
||||
// 注册 handler
|
||||
appLogs := make([]string, 0)
|
||||
@@ -493,7 +493,7 @@ func TestSeqlogDefaultHandler(t *testing.T) {
|
||||
return nil
|
||||
}
|
||||
|
||||
seqlog := NewSeqlog(tmpDir, slog.Default(), defaultHandler)
|
||||
seqlog := NewLogHub(tmpDir, slog.Default(), defaultHandler)
|
||||
|
||||
// 注册特定 handler
|
||||
seqlog.RegisterHandler("special", func(rec *Record) error {
|
||||
@@ -534,7 +534,7 @@ func TestSeqlogDynamicRegistration(t *testing.T) {
|
||||
os.MkdirAll(tmpDir, 0755)
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
seqlog := NewSeqlog(tmpDir, slog.Default(), nil)
|
||||
seqlog := NewLogHub(tmpDir, slog.Default(), nil)
|
||||
|
||||
// 先注册 handler(handler 现在是必填项)
|
||||
logs := make([]string, 0)
|
||||
@@ -566,7 +566,7 @@ func TestDynamicConfigUpdate(t *testing.T) {
|
||||
os.MkdirAll(tmpDir, 0755)
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
seqlog := NewSeqlog(tmpDir, slog.Default(), nil)
|
||||
seqlog := NewLogHub(tmpDir, slog.Default(), nil)
|
||||
|
||||
// 注册 handler
|
||||
logs := make([]string, 0)
|
||||
@@ -746,7 +746,7 @@ func TestSeqlogAutoRecovery(t *testing.T) {
|
||||
return nil
|
||||
}
|
||||
|
||||
seqlog1 := NewSeqlog(tmpDir, slog.Default(), defaultHandler)
|
||||
seqlog1 := NewLogHub(tmpDir, slog.Default(), defaultHandler)
|
||||
seqlog1.Start()
|
||||
|
||||
// 写入一些日志
|
||||
@@ -777,7 +777,7 @@ func TestSeqlogAutoRecovery(t *testing.T) {
|
||||
mu.Unlock()
|
||||
|
||||
// 第二阶段:重启并自动恢复
|
||||
seqlog2 := NewSeqlog(tmpDir, slog.Default(), defaultHandler)
|
||||
seqlog2 := NewLogHub(tmpDir, slog.Default(), defaultHandler)
|
||||
seqlog2.Start()
|
||||
|
||||
// 写入新日志
|
||||
@@ -880,7 +880,7 @@ func TestSeqlogCleanup(t *testing.T) {
|
||||
os.MkdirAll(tmpDir, 0755)
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
seqlog := NewSeqlog(tmpDir, slog.Default(), nil)
|
||||
seqlog := NewLogHub(tmpDir, slog.Default(), nil)
|
||||
seqlog.Start()
|
||||
|
||||
// 写入多个 topic 的日志
|
||||
@@ -1118,7 +1118,7 @@ func TestSeqlogStats(t *testing.T) {
|
||||
return nil
|
||||
}
|
||||
|
||||
seq := NewSeqlog(tmpDir, slog.Default(), handler)
|
||||
seq := NewLogHub(tmpDir, slog.Default(), handler)
|
||||
if err := seq.Start(); err != nil {
|
||||
t.Fatalf("failed to start seqlog: %v", err)
|
||||
}
|
||||
@@ -1229,16 +1229,19 @@ func TestRecordQuery(t *testing.T) {
|
||||
}
|
||||
defer query.Close()
|
||||
|
||||
// 测试查询当前位置
|
||||
current, err := query.QueryOldest(startIdx, 1)
|
||||
// 测试查询当前位置(使用 QueryNewest 查询 startIdx)
|
||||
current, err := query.QueryNewest(startIdx-1, 1)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to query current: %v", err)
|
||||
}
|
||||
if len(current) != 1 {
|
||||
t.Fatalf("expected 1 current result, got %d", len(current))
|
||||
}
|
||||
if string(current[0].Data) != "message 5" {
|
||||
t.Errorf("expected current 'message 5', got '%s'", string(current[0].Data))
|
||||
if string(current[0].Record.Data) != "message 5" {
|
||||
t.Errorf("expected current 'message 5', got '%s'", string(current[0].Record.Data))
|
||||
}
|
||||
if current[0].Index != startIdx {
|
||||
t.Errorf("expected index %d, got %d", startIdx, current[0].Index)
|
||||
}
|
||||
// 手动判断状态
|
||||
status := GetRecordStatus(startIdx, startIdx, endIdx)
|
||||
@@ -1246,43 +1249,53 @@ func TestRecordQuery(t *testing.T) {
|
||||
t.Errorf("expected status Processing, got %s", status)
|
||||
}
|
||||
|
||||
// 测试向后查询(查询更早的记录,返回按索引递增排序)
|
||||
backResults, err := query.QueryNewest(startIdx-1, 3)
|
||||
// 测试 QueryOldest:查询更早的记录(向索引递减方向)
|
||||
// QueryOldest(5, 3) 查询索引 2, 3, 4
|
||||
backResults, err := query.QueryOldest(startIdx, 3)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to query backward: %v", err)
|
||||
}
|
||||
if len(backResults) != 3 {
|
||||
t.Errorf("expected 3 backward results, got %d", len(backResults))
|
||||
}
|
||||
// 向后查询返回按索引递增排序的结果
|
||||
// 返回按索引递增排序的结果:2, 3, 4
|
||||
expectedBack := []string{"message 2", "message 3", "message 4"}
|
||||
for i, rec := range backResults {
|
||||
if string(rec.Data) != expectedBack[i] {
|
||||
t.Errorf("backward[%d]: expected '%s', got '%s'", i, expectedBack[i], string(rec.Data))
|
||||
if string(rec.Record.Data) != expectedBack[i] {
|
||||
t.Errorf("backward[%d]: expected '%s', got '%s'", i, expectedBack[i], string(rec.Record.Data))
|
||||
}
|
||||
// 手动判断状态:索引 2, 3, 4
|
||||
recStatus := GetRecordStatus(startIdx-3+i, startIdx, endIdx)
|
||||
expectedIndex := startIdx - 3 + i
|
||||
if rec.Index != expectedIndex {
|
||||
t.Errorf("backward[%d]: expected index %d, got %d", i, expectedIndex, rec.Index)
|
||||
}
|
||||
// 手动判断状态:索引 2, 3, 4 都已处理
|
||||
recStatus := GetRecordStatus(rec.Index, startIdx, endIdx)
|
||||
if recStatus != StatusProcessed {
|
||||
t.Errorf("backward[%d]: expected status Processed, got %s", i, recStatus)
|
||||
}
|
||||
}
|
||||
|
||||
// 测试向前查询(查询更新的记录)
|
||||
forwardResults, err := query.QueryOldest(endIdx, 3)
|
||||
// 测试 QueryNewest:查询更新的记录(向索引递增方向)
|
||||
// QueryNewest(endIdx, 3) 从 endIdx 向后查询,查询索引 6, 7, 8
|
||||
forwardResults, err := query.QueryNewest(endIdx-1, 3)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to query forward: %v", err)
|
||||
}
|
||||
if len(forwardResults) != 3 {
|
||||
t.Errorf("expected 3 forward results, got %d", len(forwardResults))
|
||||
}
|
||||
// 向前查询返回顺序结果
|
||||
// 返回按索引递增排序的结果:6, 7, 8
|
||||
expectedForward := []string{"message 6", "message 7", "message 8"}
|
||||
for i, rec := range forwardResults {
|
||||
if string(rec.Data) != expectedForward[i] {
|
||||
t.Errorf("forward[%d]: expected '%s', got '%s'", i, expectedForward[i], string(rec.Data))
|
||||
if string(rec.Record.Data) != expectedForward[i] {
|
||||
t.Errorf("forward[%d]: expected '%s', got '%s'", i, expectedForward[i], string(rec.Record.Data))
|
||||
}
|
||||
// 手动判断状态:索引 6, 7, 8
|
||||
recStatus := GetRecordStatus(endIdx+i, startIdx, endIdx)
|
||||
expectedIndex := endIdx + i
|
||||
if rec.Index != expectedIndex {
|
||||
t.Errorf("forward[%d]: expected index %d, got %d", i, expectedIndex, rec.Index)
|
||||
}
|
||||
// 手动判断状态:索引 6, 7, 8 待处理
|
||||
recStatus := GetRecordStatus(rec.Index, startIdx, endIdx)
|
||||
if recStatus != StatusPending {
|
||||
t.Errorf("forward[%d]: expected status Pending, got %s", i, recStatus)
|
||||
}
|
||||
@@ -1384,7 +1397,7 @@ func TestSeqlogQuery(t *testing.T) {
|
||||
return nil
|
||||
}
|
||||
|
||||
seq := NewSeqlog(tmpDir, slog.Default(), handler)
|
||||
seq := NewLogHub(tmpDir, slog.Default(), handler)
|
||||
if err := seq.Start(); err != nil {
|
||||
t.Fatalf("failed to start seqlog: %v", err)
|
||||
}
|
||||
@@ -1414,7 +1427,7 @@ func TestSeqlogQuery(t *testing.T) {
|
||||
|
||||
// 获取 processor 用于查询(带状态)
|
||||
processor, _ := seq.GetProcessor("app")
|
||||
index := processor.Index()
|
||||
totalCount := processor.GetRecordCount()
|
||||
|
||||
// 测试查询当前
|
||||
if startIdx < endIdx {
|
||||
@@ -1439,7 +1452,7 @@ func TestSeqlogQuery(t *testing.T) {
|
||||
}
|
||||
|
||||
// 测试向前查询
|
||||
if startIdx < index.Count() {
|
||||
if startIdx < totalCount {
|
||||
forward, err := processor.QueryOldest(endIdx, 3)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to query forward: %v", err)
|
||||
@@ -1569,7 +1582,7 @@ func TestSeqlogEventSubscription(t *testing.T) {
|
||||
return nil
|
||||
}
|
||||
|
||||
seq := NewSeqlog(tmpDir, slog.Default(), handler)
|
||||
seq := NewLogHub(tmpDir, slog.Default(), handler)
|
||||
if err := seq.Start(); err != nil {
|
||||
t.Fatalf("failed to start seqlog: %v", err)
|
||||
}
|
||||
@@ -1612,7 +1625,7 @@ func TestMultiTopicEventSubscription(t *testing.T) {
|
||||
return nil
|
||||
}
|
||||
|
||||
seq := NewSeqlog(tmpDir, slog.Default(), handler)
|
||||
seq := NewLogHub(tmpDir, slog.Default(), handler)
|
||||
if err := seq.Start(); err != nil {
|
||||
t.Fatalf("failed to start seqlog: %v", err)
|
||||
}
|
||||
@@ -1658,7 +1671,7 @@ func TestMultiTopicEventSubscription(t *testing.T) {
|
||||
func TestTopicReset(t *testing.T) {
|
||||
tmpDir := t.TempDir()
|
||||
|
||||
seqlog := NewSeqlog(tmpDir, slog.Default(), nil)
|
||||
seqlog := NewLogHub(tmpDir, slog.Default(), nil)
|
||||
|
||||
// 注册 handler
|
||||
seqlog.RegisterHandler("test", func(rec *Record) error {
|
||||
@@ -1750,6 +1763,50 @@ func TestTopicReset(t *testing.T) {
|
||||
seqlog.Stop()
|
||||
}
|
||||
|
||||
// TestTopicResetWithPendingRecords 测试当有待处理日志时 Reset 返回错误
|
||||
func TestTopicResetWithPendingRecords(t *testing.T) {
|
||||
tmpDir := t.TempDir()
|
||||
|
||||
seqlog := NewLogHub(tmpDir, slog.Default(), nil)
|
||||
|
||||
// 注册一个慢速 handler,让日志堆积
|
||||
slowHandler := func(rec *Record) error {
|
||||
time.Sleep(100 * time.Millisecond) // 模拟慢速处理
|
||||
return nil
|
||||
}
|
||||
|
||||
seqlog.RegisterHandler("test", slowHandler)
|
||||
seqlog.Start()
|
||||
|
||||
// 快速写入多条日志
|
||||
for i := 0; i < 10; i++ {
|
||||
data := []byte(fmt.Sprintf("message %d", i))
|
||||
if _, err := seqlog.Write("test", data); err != nil {
|
||||
t.Fatalf("写入失败: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// 短暂等待,让一部分日志开始处理但不是全部
|
||||
time.Sleep(200 * time.Millisecond)
|
||||
|
||||
// 尝试重置,应该失败因为有待处理的日志
|
||||
err := seqlog.ResetTopic("test")
|
||||
if err == nil {
|
||||
t.Fatal("期望 Reset 失败因为有待处理的日志,但成功了")
|
||||
}
|
||||
|
||||
t.Logf("预期的错误: %v", err)
|
||||
|
||||
// 停止处理
|
||||
seqlog.Stop()
|
||||
|
||||
// 现在 Reset 应该成功(停止后没有待处理的日志)
|
||||
processor, _ := seqlog.GetProcessor("test")
|
||||
if err := processor.Reset(); err != nil {
|
||||
t.Fatalf("停止后 Reset 应该成功: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// TestQueryOldestNewest 测试 QueryOldest 和 QueryNewest
|
||||
func TestQueryOldestNewest(t *testing.T) {
|
||||
tmpDir := t.TempDir()
|
||||
@@ -1773,10 +1830,11 @@ func TestQueryOldestNewest(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// 测试 QueryOldest - 从索引 0 开始查询 3 条
|
||||
oldest, err := processor.QueryOldest(0, 3)
|
||||
// 测试 QueryNewest - 查询索引 0, 1, 2(向索引递增方向)
|
||||
// QueryNewest(-1, 3) 从 -1 向后查询,得到索引 0, 1, 2
|
||||
oldest, err := processor.QueryNewest(-1, 3)
|
||||
if err != nil {
|
||||
t.Fatalf("QueryOldest failed: %v", err)
|
||||
t.Fatalf("QueryNewest failed: %v", err)
|
||||
}
|
||||
if len(oldest) != 3 {
|
||||
t.Errorf("expected 3 records, got %d", len(oldest))
|
||||
@@ -1787,14 +1845,18 @@ func TestQueryOldestNewest(t *testing.T) {
|
||||
if string(oldest[i].Record.Data) != expected {
|
||||
t.Errorf("oldest[%d]: expected %s, got %s", i, expected, string(oldest[i].Record.Data))
|
||||
}
|
||||
t.Logf("Oldest[%d]: %s - %s", i, string(oldest[i].Record.Data), oldest[i].Status)
|
||||
if oldest[i].Index != i {
|
||||
t.Errorf("oldest[%d]: expected index %d, got %d", i, i, oldest[i].Index)
|
||||
}
|
||||
t.Logf("Oldest[%d]: index=%d, %s - %s", i, oldest[i].Index, string(oldest[i].Record.Data), oldest[i].Status)
|
||||
}
|
||||
|
||||
// 测试 QueryNewest - 从索引 9 结束查询 3 条
|
||||
// 测试 QueryOldest - 查询索引 7, 8, 9(向索引递减方向)
|
||||
// QueryOldest(10, 3) 从 10 向前查询,得到索引 7, 8, 9
|
||||
totalCount := processor.GetRecordCount()
|
||||
newest, err := processor.QueryNewest(totalCount-1, 3)
|
||||
newest, err := processor.QueryOldest(totalCount, 3)
|
||||
if err != nil {
|
||||
t.Fatalf("QueryNewest failed: %v", err)
|
||||
t.Fatalf("QueryOldest failed: %v", err)
|
||||
}
|
||||
if len(newest) != 3 {
|
||||
t.Errorf("expected 3 records, got %d", len(newest))
|
||||
@@ -1805,13 +1867,17 @@ func TestQueryOldestNewest(t *testing.T) {
|
||||
if string(newest[i].Record.Data) != expected {
|
||||
t.Errorf("newest[%d]: expected %s, got %s", i, expected, string(newest[i].Record.Data))
|
||||
}
|
||||
t.Logf("Newest[%d]: %s - %s", i, string(newest[i].Record.Data), newest[i].Status)
|
||||
if newest[i].Index != 7+i {
|
||||
t.Errorf("newest[%d]: expected index %d, got %d", i, 7+i, newest[i].Index)
|
||||
}
|
||||
t.Logf("Newest[%d]: index=%d, %s - %s", i, newest[i].Index, string(newest[i].Record.Data), newest[i].Status)
|
||||
}
|
||||
|
||||
// 测试超出范围
|
||||
all, err := processor.QueryOldest(0, 100)
|
||||
// 测试超出范围 - 查询所有记录
|
||||
// QueryNewest(-1, 100) 从 -1 向后查询,会返回所有记录(最多 100 条)
|
||||
all, err := processor.QueryNewest(-1, 100)
|
||||
if err != nil {
|
||||
t.Fatalf("QueryOldest(0, 100) failed: %v", err)
|
||||
t.Fatalf("QueryNewest(-1, 100) failed: %v", err)
|
||||
}
|
||||
if len(all) != 10 {
|
||||
t.Errorf("expected 10 records, got %d", len(all))
|
||||
@@ -1828,11 +1894,195 @@ func TestQueryOldestNewest(t *testing.T) {
|
||||
}
|
||||
defer processor2.Close()
|
||||
|
||||
emptyOldest, err := processor2.QueryOldest(0, 10)
|
||||
emptyNewest, err := processor2.QueryNewest(-1, 10)
|
||||
if err != nil {
|
||||
t.Fatalf("QueryOldest on empty failed: %v", err)
|
||||
t.Fatalf("QueryNewest on empty failed: %v", err)
|
||||
}
|
||||
if len(emptyOldest) != 0 {
|
||||
t.Errorf("expected 0 records, got %d", len(emptyOldest))
|
||||
if len(emptyNewest) != 0 {
|
||||
t.Errorf("expected 0 records, got %d", len(emptyNewest))
|
||||
}
|
||||
}
|
||||
|
||||
// TestQueryFromFirstAndLast 测试 QueryFromFirst 和 QueryFromLast
|
||||
func TestQueryFromFirstAndLast(t *testing.T) {
|
||||
tmpDir := t.TempDir()
|
||||
|
||||
// 创建 TopicProcessor
|
||||
processor, err := NewTopicProcessor(tmpDir, "test", nil, &TopicConfig{
|
||||
Handler: func(rec *Record) error {
|
||||
return nil
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer processor.Close()
|
||||
|
||||
// 写入 10 条测试数据
|
||||
for i := 0; i < 10; i++ {
|
||||
data := fmt.Sprintf("message %d", i)
|
||||
if _, err := processor.Write([]byte(data)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// 测试 QueryFromFirst - 从第一条记录向索引递增方向查询
|
||||
t.Run("QueryFromFirst", func(t *testing.T) {
|
||||
// 查询前 3 条记录
|
||||
records, err := processor.QueryFromFirst(3)
|
||||
if err != nil {
|
||||
t.Fatalf("QueryFromFirst failed: %v", err)
|
||||
}
|
||||
|
||||
if len(records) != 3 {
|
||||
t.Fatalf("expected 3 records, got %d", len(records))
|
||||
}
|
||||
|
||||
// 验证结果:应该是索引 0, 1, 2
|
||||
for i := 0; i < 3; i++ {
|
||||
expectedData := fmt.Sprintf("message %d", i)
|
||||
if string(records[i].Record.Data) != expectedData {
|
||||
t.Errorf("records[%d]: expected %s, got %s", i, expectedData, string(records[i].Record.Data))
|
||||
}
|
||||
if records[i].Index != i {
|
||||
t.Errorf("records[%d]: expected index %d, got %d", i, i, records[i].Index)
|
||||
}
|
||||
t.Logf("FromFirst[%d]: index=%d, %s - %s", i, records[i].Index, string(records[i].Record.Data), records[i].Status)
|
||||
}
|
||||
|
||||
// 查询超过总数的记录
|
||||
allRecords, err := processor.QueryFromFirst(100)
|
||||
if err != nil {
|
||||
t.Fatalf("QueryFromFirst(100) failed: %v", err)
|
||||
}
|
||||
if len(allRecords) != 10 {
|
||||
t.Errorf("expected 10 records, got %d", len(allRecords))
|
||||
}
|
||||
})
|
||||
|
||||
// 测试 QueryFromLast - 从最后一条记录向索引递减方向查询
|
||||
t.Run("QueryFromLast", func(t *testing.T) {
|
||||
// 查询最后 3 条记录
|
||||
records, err := processor.QueryFromLast(3)
|
||||
if err != nil {
|
||||
t.Fatalf("QueryFromLast failed: %v", err)
|
||||
}
|
||||
|
||||
if len(records) != 3 {
|
||||
t.Fatalf("expected 3 records, got %d", len(records))
|
||||
}
|
||||
|
||||
// 验证结果:应该是索引 7, 8, 9(按索引递增顺序排列)
|
||||
for i := 0; i < 3; i++ {
|
||||
expectedIndex := 7 + i
|
||||
expectedData := fmt.Sprintf("message %d", expectedIndex)
|
||||
if string(records[i].Record.Data) != expectedData {
|
||||
t.Errorf("records[%d]: expected %s, got %s", i, expectedData, string(records[i].Record.Data))
|
||||
}
|
||||
if records[i].Index != expectedIndex {
|
||||
t.Errorf("records[%d]: expected index %d, got %d", i, expectedIndex, records[i].Index)
|
||||
}
|
||||
t.Logf("FromLast[%d]: index=%d, %s - %s", i, records[i].Index, string(records[i].Record.Data), records[i].Status)
|
||||
}
|
||||
|
||||
// 查询超过总数的记录
|
||||
allRecords, err := processor.QueryFromLast(100)
|
||||
if err != nil {
|
||||
t.Fatalf("QueryFromLast(100) failed: %v", err)
|
||||
}
|
||||
if len(allRecords) != 10 {
|
||||
t.Errorf("expected 10 records, got %d", len(allRecords))
|
||||
}
|
||||
})
|
||||
|
||||
// 测试空数据库
|
||||
t.Run("EmptyDatabase", func(t *testing.T) {
|
||||
emptyProcessor, err := NewTopicProcessor(t.TempDir(), "empty", nil, &TopicConfig{
|
||||
Handler: func(rec *Record) error {
|
||||
return nil
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer emptyProcessor.Close()
|
||||
|
||||
// QueryFromFirst 应该返回空数组
|
||||
firstRecords, err := emptyProcessor.QueryFromFirst(10)
|
||||
if err != nil {
|
||||
t.Fatalf("QueryFromFirst on empty failed: %v", err)
|
||||
}
|
||||
if len(firstRecords) != 0 {
|
||||
t.Errorf("expected 0 records, got %d", len(firstRecords))
|
||||
}
|
||||
|
||||
// QueryFromLast 应该返回空数组
|
||||
lastRecords, err := emptyProcessor.QueryFromLast(10)
|
||||
if err != nil {
|
||||
t.Fatalf("QueryFromLast on empty failed: %v", err)
|
||||
}
|
||||
if len(lastRecords) != 0 {
|
||||
t.Errorf("expected 0 records, got %d", len(lastRecords))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// TestLogHubQueryFromFirstAndLast 测试 LogHub 的 QueryFromFirst 和 QueryFromLast
|
||||
func TestLogHubQueryFromFirstAndLast(t *testing.T) {
|
||||
tmpDir := t.TempDir()
|
||||
|
||||
seqlog := NewLogHub(tmpDir, slog.Default(), nil)
|
||||
seqlog.RegisterHandler("test", func(rec *Record) error {
|
||||
return nil
|
||||
})
|
||||
seqlog.Start()
|
||||
defer seqlog.Stop()
|
||||
|
||||
// 写入测试数据
|
||||
for i := 0; i < 10; i++ {
|
||||
data := fmt.Sprintf("message %d", i)
|
||||
if _, err := seqlog.Write("test", []byte(data)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// 测试 QueryFromFirst
|
||||
firstRecords, err := seqlog.QueryFromFirst("test", 3)
|
||||
if err != nil {
|
||||
t.Fatalf("QueryFromFirst failed: %v", err)
|
||||
}
|
||||
if len(firstRecords) != 3 {
|
||||
t.Fatalf("expected 3 records, got %d", len(firstRecords))
|
||||
}
|
||||
for i := 0; i < 3; i++ {
|
||||
if firstRecords[i].Index != i {
|
||||
t.Errorf("firstRecords[%d]: expected index %d, got %d", i, i, firstRecords[i].Index)
|
||||
}
|
||||
}
|
||||
|
||||
// 测试 QueryFromLast
|
||||
lastRecords, err := seqlog.QueryFromLast("test", 3)
|
||||
if err != nil {
|
||||
t.Fatalf("QueryFromLast failed: %v", err)
|
||||
}
|
||||
if len(lastRecords) != 3 {
|
||||
t.Fatalf("expected 3 records, got %d", len(lastRecords))
|
||||
}
|
||||
for i := 0; i < 3; i++ {
|
||||
expectedIndex := 7 + i
|
||||
if lastRecords[i].Index != expectedIndex {
|
||||
t.Errorf("lastRecords[%d]: expected index %d, got %d", i, expectedIndex, lastRecords[i].Index)
|
||||
}
|
||||
}
|
||||
|
||||
// 测试不存在的 topic
|
||||
_, err = seqlog.QueryFromFirst("nonexistent", 10)
|
||||
if err == nil {
|
||||
t.Error("expected error for nonexistent topic")
|
||||
}
|
||||
|
||||
_, err = seqlog.QueryFromLast("nonexistent", 10)
|
||||
if err == nil {
|
||||
t.Error("expected error for nonexistent topic")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user