246 lines
6.1 KiB
Go
246 lines
6.1 KiB
Go
package memory
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
"time"
|
|
|
|
"git.pyer.club/kingecg/gotidb/pkg/engine"
|
|
)
|
|
|
|
func TestMemoryEngine(t *testing.T) {
|
|
// 创建引擎配置
|
|
config := engine.NewEngineConfig()
|
|
|
|
// 创建内存引擎
|
|
eng, err := NewMemoryEngine(config)
|
|
if err != nil {
|
|
t.Fatalf("Failed to create memory engine: %v", err)
|
|
}
|
|
|
|
// 打开引擎
|
|
if err := eng.Open(); err != nil {
|
|
t.Fatalf("Failed to open engine: %v", err)
|
|
}
|
|
defer eng.Close()
|
|
|
|
// 测试写入单个数据点
|
|
t.Run("WritePoint", func(t *testing.T) {
|
|
point := engine.DataPoint{
|
|
DeviceID: "device001",
|
|
MetricCode: "temperature",
|
|
Labels: map[string]string{
|
|
"location": "room1",
|
|
},
|
|
Value: 25.5,
|
|
Timestamp: time.Now().UnixNano(),
|
|
}
|
|
|
|
if err := eng.WritePoint(context.Background(), point); err != nil {
|
|
t.Fatalf("Failed to write point: %v", err)
|
|
}
|
|
|
|
// 刷新缓冲区确保数据写入
|
|
if err := eng.Flush(); err != nil {
|
|
t.Fatalf("Failed to flush: %v", err)
|
|
}
|
|
|
|
// 查询最新数据
|
|
query := engine.NewQueryBuilder().
|
|
ForMetric("temperature").
|
|
WithTag("location", engine.OpEqual, "room1").
|
|
Build()
|
|
query.Type = engine.QueryTypeLatest
|
|
|
|
result, err := eng.Query(context.Background(), query)
|
|
if err != nil {
|
|
t.Fatalf("Failed to query latest data: %v", err)
|
|
}
|
|
|
|
tsResult, ok := result.(*engine.TimeSeriesResult)
|
|
if !ok {
|
|
t.Fatalf("Expected TimeSeriesResult, got %T", result)
|
|
}
|
|
|
|
if len(tsResult.Points) != 1 {
|
|
t.Fatalf("Expected 1 point, got %d", len(tsResult.Points))
|
|
}
|
|
|
|
if tsResult.Points[0].Value != 25.5 {
|
|
t.Errorf("Expected value 25.5, got %.2f", tsResult.Points[0].Value)
|
|
}
|
|
})
|
|
|
|
// 测试批量写入
|
|
t.Run("WriteBatch", func(t *testing.T) {
|
|
now := time.Now()
|
|
var points []engine.DataPoint
|
|
for i := 0; i < 10; i++ {
|
|
points = append(points, engine.DataPoint{
|
|
DeviceID: "device002",
|
|
MetricCode: "cpu",
|
|
Labels: map[string]string{
|
|
"host": "server1",
|
|
},
|
|
Value: float64(i * 10),
|
|
Timestamp: now.Add(time.Duration(i) * time.Second).UnixNano(),
|
|
})
|
|
}
|
|
|
|
if err := eng.WriteBatch(context.Background(), points); err != nil {
|
|
t.Fatalf("Failed to write batch: %v", err)
|
|
}
|
|
|
|
// 查询原始数据
|
|
query := engine.NewQueryBuilder().
|
|
ForMetric("cpu").
|
|
WithTimeRange(now.Add(-1*time.Hour).UnixNano(), now.Add(1*time.Hour).UnixNano()).
|
|
WithTag("host", engine.OpEqual, "server1").
|
|
Build()
|
|
|
|
result, err := eng.Query(context.Background(), query)
|
|
if err != nil {
|
|
t.Fatalf("Failed to query raw data: %v", err)
|
|
}
|
|
|
|
tsResult, ok := result.(*engine.TimeSeriesResult)
|
|
if !ok {
|
|
t.Fatalf("Expected TimeSeriesResult, got %T", result)
|
|
}
|
|
|
|
if len(tsResult.Points) != 10 {
|
|
t.Fatalf("Expected 10 points, got %d", len(tsResult.Points))
|
|
}
|
|
})
|
|
|
|
// 测试聚合查询
|
|
t.Run("AggregateQuery", func(t *testing.T) {
|
|
now := time.Now()
|
|
var points []engine.DataPoint
|
|
for i := 0; i < 10; i++ {
|
|
points = append(points, engine.DataPoint{
|
|
DeviceID: "device003",
|
|
MetricCode: "memory",
|
|
Labels: map[string]string{
|
|
"host": "server2",
|
|
},
|
|
Value: float64(i * 10),
|
|
Timestamp: now.Add(time.Duration(i) * time.Second).UnixNano(),
|
|
})
|
|
}
|
|
|
|
if err := eng.WriteBatch(context.Background(), points); err != nil {
|
|
t.Fatalf("Failed to write batch: %v", err)
|
|
}
|
|
|
|
// 查询聚合数据
|
|
query := engine.NewQueryBuilder().
|
|
ForMetric("memory").
|
|
WithTimeRange(now.Add(-1*time.Hour).UnixNano(), now.Add(1*time.Hour).UnixNano()).
|
|
WithTag("host", engine.OpEqual, "server2").
|
|
WithAggregation(engine.AggAvg, 1*time.Minute).
|
|
Build()
|
|
|
|
result, err := eng.Query(context.Background(), query)
|
|
if err != nil {
|
|
t.Fatalf("Failed to query aggregate data: %v", err)
|
|
}
|
|
|
|
aggResult, ok := result.(*engine.AggregateResult)
|
|
if !ok {
|
|
t.Fatalf("Expected AggregateResult, got %T", result)
|
|
}
|
|
|
|
if len(aggResult.Groups) == 0 {
|
|
t.Fatalf("Expected at least one aggregate group")
|
|
}
|
|
})
|
|
|
|
// 测试引擎统计信息
|
|
t.Run("EngineStats", func(t *testing.T) {
|
|
stats := eng.Stats()
|
|
if stats.PointsCount == 0 {
|
|
t.Errorf("Expected non-zero points count")
|
|
}
|
|
})
|
|
|
|
// 测试引擎能力
|
|
t.Run("EngineCapabilities", func(t *testing.T) {
|
|
caps := eng.Capabilities()
|
|
if !caps.SupportsCompression {
|
|
t.Errorf("Expected compression support")
|
|
}
|
|
if caps.SupportsPersistence {
|
|
t.Errorf("Memory engine should not support persistence")
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestCircularBuffer(t *testing.T) {
|
|
// 创建引擎配置
|
|
config := engine.NewEngineConfig()
|
|
memConfig := config.MemoryConfig()
|
|
memConfig.MaxPointsPerSeries = 5 // 设置为较小的值以便测试
|
|
|
|
// 创建内存引擎
|
|
eng, err := NewMemoryEngine(config)
|
|
if err != nil {
|
|
t.Fatalf("Failed to create memory engine: %v", err)
|
|
}
|
|
|
|
// 打开引擎
|
|
if err := eng.Open(); err != nil {
|
|
t.Fatalf("Failed to open engine: %v", err)
|
|
}
|
|
defer eng.Close()
|
|
|
|
// 写入超过缓冲区容量的数据点
|
|
now := time.Now()
|
|
var points []engine.DataPoint
|
|
for i := 0; i < 10; i++ {
|
|
points = append(points, engine.DataPoint{
|
|
DeviceID: "device004",
|
|
MetricCode: "disk",
|
|
Labels: map[string]string{
|
|
"path": "/data",
|
|
},
|
|
Value: float64(i),
|
|
Timestamp: now.Add(time.Duration(i) * time.Second).UnixNano(),
|
|
})
|
|
}
|
|
|
|
if err := eng.WriteBatch(context.Background(), points); err != nil {
|
|
t.Fatalf("Failed to write batch: %v", err)
|
|
}
|
|
|
|
// 查询原始数据
|
|
query := engine.NewQueryBuilder().
|
|
ForMetric("disk").
|
|
WithTimeRange(now.Add(-1*time.Hour).UnixNano(), now.Add(1*time.Hour).UnixNano()).
|
|
WithTag("path", engine.OpEqual, "/data").
|
|
Build()
|
|
|
|
result, err := eng.Query(context.Background(), query)
|
|
if err != nil {
|
|
t.Fatalf("Failed to query raw data: %v", err)
|
|
}
|
|
|
|
tsResult, ok := result.(*engine.TimeSeriesResult)
|
|
if !ok {
|
|
t.Fatalf("Expected TimeSeriesResult, got %T", result)
|
|
}
|
|
|
|
// 应该只返回最近的5个点
|
|
if len(tsResult.Points) != 5 {
|
|
t.Fatalf("Expected 5 points (MaxPointsPerSeries), got %d", len(tsResult.Points))
|
|
}
|
|
|
|
// 检查返回的是最新的5个点
|
|
for i, point := range tsResult.Points {
|
|
expectedValue := float64(i + 5) // 5-9
|
|
if point.Value != expectedValue {
|
|
t.Errorf("Expected point value %.1f, got %.1f", expectedValue, point.Value)
|
|
}
|
|
}
|
|
}
|