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) }