gotidb/pkg/engine/integration_test.go

323 lines
7.1 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 engine
import (
"context"
"testing"
"time"
)
// engineFactory 是一个用于创建引擎实例的函数类型
type engineFactory func(t *testing.T) Engine
// engineTest 包含所有引擎测试用例
type engineTest struct {
name string
factory engineFactory
}
// 运行所有引擎测试
func runEngineTests(t *testing.T, tests []engineTest) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
engine := tt.factory(t)
// 测试基本操作
t.Run("Basic Operations", func(t *testing.T) {
testBasicOperations(t, engine)
})
// 测试查询功能
t.Run("Query Operations", func(t *testing.T) {
testQueryOperations(t, engine)
})
// 测试压缩和清理
t.Run("Maintenance Operations", func(t *testing.T) {
testMaintenanceOperations(t, engine)
})
// 测试统计信息
t.Run("Stats Operations", func(t *testing.T) {
testStatsOperations(t, engine)
})
})
}
}
// testBasicOperations 测试基本的CRUD操作
func testBasicOperations(t *testing.T, engine Engine) {
ctx := context.Background()
// 测试打开引擎
if err := engine.Open(); err != nil {
t.Fatalf("Failed to open engine: %v", err)
}
// 准备测试数据
points := []DataPoint{
{
Timestamp: time.Now().UnixNano(),
Value: 42.0,
Labels: map[string]string{
"host": "server1",
"service": "api",
},
},
{
Timestamp: time.Now().UnixNano(),
Value: 43.0,
Labels: map[string]string{
"host": "server2",
"service": "api",
},
},
}
// 测试写入
if err := engine.Write(ctx, points); err != nil {
t.Fatalf("Failed to write points: %v", err)
}
// 测试查询
query := Query{
Type: QueryTypeRaw,
StartTime: time.Now().Add(-1 * time.Hour).UnixNano(),
EndTime: time.Now().Add(1 * time.Hour).UnixNano(),
Tags: map[string]string{
"service": "api",
},
}
result, err := engine.Query(ctx, query)
if err != nil {
t.Fatalf("Failed to query points: %v", err)
}
// 验证查询结果
if len(result) == 0 {
t.Error("Query returned no results")
}
// 测试关闭引擎
if err := engine.Close(); err != nil {
t.Fatalf("Failed to close engine: %v", err)
}
}
// testQueryOperations 测试不同类型的查询操作
func testQueryOperations(t *testing.T, engine Engine) {
ctx := context.Background()
// 打开引擎
if err := engine.Open(); err != nil {
t.Fatalf("Failed to open engine: %v", err)
}
defer engine.Close()
// 准备测试数据
now := time.Now()
points := []DataPoint{
{
Timestamp: now.Add(-2 * time.Hour).UnixNano(),
Value: 10.0,
Labels: map[string]string{
"host": "server1",
"app": "test",
},
},
{
Timestamp: now.Add(-1 * time.Hour).UnixNano(),
Value: 20.0,
Labels: map[string]string{
"host": "server1",
"app": "test",
},
},
{
Timestamp: now.UnixNano(),
Value: 30.0,
Labels: map[string]string{
"host": "server1",
"app": "test",
},
},
}
// 写入测试数据
if err := engine.Write(ctx, points); err != nil {
t.Fatalf("Failed to write points: %v", err)
}
// 测试最新值查询
t.Run("Latest Query", func(t *testing.T) {
query := Query{
Type: QueryTypeLatest,
Tags: map[string]string{
"host": "server1",
"app": "test",
},
}
result, err := engine.Query(ctx, query)
if err != nil {
t.Fatalf("Failed to query latest points: %v", err)
}
if len(result) != 1 {
t.Errorf("Expected 1 series result, got %d", len(result))
}
if len(result[0].Points) != 1 {
t.Errorf("Expected 1 point, got %d", len(result[0].Points))
}
if result[0].Points[0].Value != 30.0 {
t.Errorf("Expected latest value 30.0, got %f", result[0].Points[0].Value)
}
})
// 测试聚合查询
t.Run("Aggregate Query", func(t *testing.T) {
query := Query{
Type: QueryTypeAggregate,
StartTime: now.Add(-3 * time.Hour).UnixNano(),
EndTime: now.Add(1 * time.Hour).UnixNano(),
Tags: map[string]string{"app": "test"},
AggregateType: AggregateTypeAvg,
}
result, err := engine.Query(ctx, query)
if err != nil {
t.Fatalf("Failed to query aggregate: %v", err)
}
if len(result) != 1 {
t.Errorf("Expected 1 series result, got %d", len(result))
}
// 验证平均值
expectedAvg := 20.0 // (10 + 20 + 30) / 3
if len(result[0].Points) > 0 && result[0].Points[0].Value != expectedAvg {
t.Errorf("Expected average value %f, got %f", expectedAvg, result[0].Points[0].Value)
}
})
// 测试原始数据查询
t.Run("Raw Query", func(t *testing.T) {
query := Query{
Type: QueryTypeRaw,
StartTime: now.Add(-3 * time.Hour).UnixNano(),
EndTime: now.Add(1 * time.Hour).UnixNano(),
Tags: map[string]string{"app": "test"},
Limit: 10,
}
result, err := engine.Query(ctx, query)
if err != nil {
t.Fatalf("Failed to query raw data: %v", err)
}
if len(result) != 1 {
t.Errorf("Expected 1 series result, got %d", len(result))
}
if len(result[0].Points) != 3 {
t.Errorf("Expected 3 points, got %d", len(result[0].Points))
}
})
}
// testMaintenanceOperations 测试压缩和清理操作
func testMaintenanceOperations(t *testing.T, engine Engine) {
// 打开引擎
if err := engine.Open(); err != nil {
t.Fatalf("Failed to open engine: %v", err)
}
defer engine.Close()
// 测试压缩
if err := engine.Compact(); err != nil {
t.Errorf("Failed to compact: %v", err)
}
// 测试清理
if err := engine.Cleanup(); err != nil {
t.Errorf("Failed to cleanup: %v", err)
}
}
// testStatsOperations 测试统计信息收集
func testStatsOperations(t *testing.T, engine Engine) {
ctx := context.Background()
// 打开引擎
if err := engine.Open(); err != nil {
t.Fatalf("Failed to open engine: %v", err)
}
defer engine.Close()
beforeStats := engine.Stats()
// 写入一些数据
points := []DataPoint{
{
Timestamp: time.Now().UnixNano(),
Value: 42.0,
Labels: map[string]string{"test": "stats"},
},
}
if err := engine.Write(ctx, points); err != nil {
t.Fatalf("Failed to write points: %v", err)
}
// 获取统计信息
stats := engine.Stats()
// 验证统计信息
if stats.PointsCount-beforeStats.PointsCount != 1 {
t.Errorf("Expected points count 1, got %d", stats.PointsCount)
}
if stats.LastWriteTime.IsZero() {
t.Error("LastWriteTime should not be zero")
}
}
// TestEngines 运行所有引擎的集成测试
func TestEngines(t *testing.T) {
tests := []engineTest{
{
name: "MockEngine",
factory: func(t *testing.T) Engine {
return NewMockEngine()
},
},
// 当实现了Memory和Bolt引擎后可以添加它们的测试
/*
{
name: "MemoryEngine",
factory: func(t *testing.T) Engine {
config := NewMemoryEngineConfig()
engine, err := NewEngine(config)
if err != nil {
t.Fatalf("Failed to create memory engine: %v", err)
}
return engine
},
},
{
name: "BoltEngine",
factory: func(t *testing.T) Engine {
config := NewBoltEngineConfig("test.db")
engine, err := NewEngine(config)
if err != nil {
t.Fatalf("Failed to create bolt engine: %v", err)
}
return engine
},
},
*/
}
runEngineTests(t, tests)
}