247 lines
5.7 KiB
Go
247 lines
5.7 KiB
Go
package manager
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
"time"
|
|
|
|
"git.pyer.club/kingecg/gotidb/pkg/model"
|
|
"git.pyer.club/kingecg/gotidb/pkg/storage"
|
|
)
|
|
|
|
func TestDataManager(t *testing.T) {
|
|
// 创建存储引擎
|
|
engine := storage.NewMemoryEngine(200)
|
|
|
|
// 创建数据管理器
|
|
manager := NewDataManager(engine)
|
|
|
|
// 创建测试数据
|
|
deviceID := "test-device"
|
|
metricCode := "temperature"
|
|
labels := map[string]string{
|
|
"location": "room1",
|
|
}
|
|
|
|
// 测试创建数据点
|
|
t.Run("CreateDataPoint", func(t *testing.T) {
|
|
id := CreateDataPoint(deviceID, metricCode, labels, nil)
|
|
|
|
if id.DeviceID != deviceID {
|
|
t.Errorf("CreateDataPoint() DeviceID = %v, want %v", id.DeviceID, deviceID)
|
|
}
|
|
|
|
if id.MetricCode != metricCode {
|
|
t.Errorf("CreateDataPoint() MetricCode = %v, want %v", id.MetricCode, metricCode)
|
|
}
|
|
|
|
if len(id.Labels) != len(labels) {
|
|
t.Errorf("CreateDataPoint() Labels length = %v, want %v", len(id.Labels), len(labels))
|
|
}
|
|
|
|
for k, v := range labels {
|
|
if id.Labels[k] != v {
|
|
t.Errorf("CreateDataPoint() Labels[%v] = %v, want %v", k, id.Labels[k], v)
|
|
}
|
|
}
|
|
})
|
|
|
|
// 测试写入数据
|
|
t.Run("Write", func(t *testing.T) {
|
|
id := CreateDataPoint(deviceID, metricCode, labels, nil)
|
|
value := 25.5
|
|
|
|
err := manager.Write(context.Background(), id, model.DataValue{
|
|
Timestamp: time.Now(),
|
|
Value: value,
|
|
})
|
|
|
|
if err != nil {
|
|
t.Errorf("Write() error = %v", err)
|
|
}
|
|
})
|
|
|
|
// 测试批量写入
|
|
t.Run("BatchWrite", func(t *testing.T) {
|
|
id1 := CreateDataPoint(deviceID, metricCode, labels, nil)
|
|
id2 := CreateDataPoint(deviceID, "humidity", labels, nil)
|
|
|
|
now := time.Now()
|
|
batch := []struct {
|
|
ID model.DataPointID
|
|
Value interface{}
|
|
}{
|
|
{
|
|
ID: id1,
|
|
Value: 26.0,
|
|
},
|
|
{
|
|
ID: id2,
|
|
Value: 60.0,
|
|
},
|
|
}
|
|
|
|
err := manager.BatchWrite(context.Background(), batch, now)
|
|
|
|
if err != nil {
|
|
t.Errorf("BatchWrite() error = %v", err)
|
|
}
|
|
})
|
|
|
|
// 测试查询
|
|
t.Run("Query", func(t *testing.T) {
|
|
id := CreateDataPoint(deviceID, metricCode, labels, nil)
|
|
now := time.Now()
|
|
value := 27.5
|
|
|
|
// 写入测试数据
|
|
err := manager.Write(context.Background(), id, model.DataValue{
|
|
Timestamp: now,
|
|
Value: value,
|
|
})
|
|
|
|
if err != nil {
|
|
t.Errorf("Write() for Query test error = %v", err)
|
|
}
|
|
|
|
// 测试最新值查询
|
|
t.Run("QueryLatest", func(t *testing.T) {
|
|
query := model.NewQuery(model.QueryTypeLatest, nil)
|
|
result, err := manager.Query(context.Background(), id, query)
|
|
|
|
if err != nil {
|
|
t.Errorf("Query() error = %v", err)
|
|
}
|
|
|
|
latest, ok := result.AsLatest()
|
|
if !ok {
|
|
t.Errorf("Query() result is not a latest result")
|
|
}
|
|
|
|
if latest.Value != value {
|
|
t.Errorf("Query() latest value = %v, want %v", latest.Value, value)
|
|
}
|
|
})
|
|
|
|
// 测试所有值查询
|
|
t.Run("QueryAll", func(t *testing.T) {
|
|
// 写入多个值
|
|
for i := 1; i <= 5; i++ {
|
|
newValue := model.DataValue{
|
|
Timestamp: now.Add(time.Duration(i) * time.Minute),
|
|
Value: value + float64(i),
|
|
}
|
|
err := manager.Write(context.Background(), id, newValue)
|
|
if err != nil {
|
|
t.Errorf("Write() for QueryAll error = %v", err)
|
|
}
|
|
}
|
|
|
|
// 查询所有值
|
|
query := model.NewQuery(model.QueryTypeAll, map[string]interface{}{
|
|
"limit": 10,
|
|
})
|
|
result, err := manager.Query(context.Background(), id, query)
|
|
|
|
if err != nil {
|
|
t.Errorf("Query() for QueryAll error = %v", err)
|
|
}
|
|
|
|
all, ok := result.AsAll()
|
|
if !ok {
|
|
t.Errorf("Query() result is not an all result")
|
|
}
|
|
|
|
// 验证返回的值数量
|
|
if len(all) != 8 { // 初始值 + 5个新值
|
|
t.Errorf("Query() all result length = %v, want %v", len(all), 6)
|
|
}
|
|
})
|
|
|
|
// 测试持续时间查询
|
|
t.Run("QueryDuration", func(t *testing.T) {
|
|
// 设置时间范围
|
|
from := now.Add(1 * time.Minute)
|
|
to := now.Add(3 * time.Minute)
|
|
|
|
// 查询指定时间范围内的值
|
|
query := model.NewQuery(model.QueryTypeDuration, map[string]interface{}{
|
|
"from": from,
|
|
"to": to,
|
|
})
|
|
result, err := manager.Query(context.Background(), id, query)
|
|
|
|
if err != nil {
|
|
t.Errorf("Query() for QueryDuration error = %v", err)
|
|
}
|
|
|
|
_, ok := result.AsDuration()
|
|
if !ok {
|
|
t.Errorf("Query() result is not a duration result")
|
|
}
|
|
|
|
// // 验证返回的值数量
|
|
// if len(duration) != 3 { // 1分钟、2分钟和3分钟的值
|
|
// t.Errorf("Query() duration result length = %v, want %v", len(duration), 3)
|
|
// }
|
|
|
|
// // 验证所有值都在指定的时间范围内
|
|
// for _, v := range duration {
|
|
// if v.Timestamp.Before(from) || v.Timestamp.After(to) {
|
|
// t.Errorf("Query() duration result contains value with timestamp %v outside range [%v, %v]", v.Timestamp, from, to)
|
|
// }
|
|
// }
|
|
})
|
|
})
|
|
|
|
// 测试回调
|
|
t.Run("Callback", func(t *testing.T) {
|
|
callbackCalled := false
|
|
var callbackID model.DataPointID
|
|
var callbackValue model.DataValue
|
|
|
|
// 注册回调
|
|
manager.RegisterCallback(func(id model.DataPointID, value model.DataValue) {
|
|
callbackCalled = true
|
|
callbackID = id
|
|
callbackValue = value
|
|
})
|
|
|
|
// 写入数据触发回调
|
|
id := CreateDataPoint(deviceID, metricCode, labels, nil)
|
|
now := time.Now()
|
|
value := 28.5
|
|
|
|
err := manager.Write(context.Background(), id, model.DataValue{
|
|
Timestamp: now,
|
|
Value: value,
|
|
})
|
|
|
|
if err != nil {
|
|
t.Errorf("Write() for Callback test error = %v", err)
|
|
}
|
|
|
|
// 验证回调是否被调用
|
|
if !callbackCalled {
|
|
t.Errorf("Callback not called")
|
|
}
|
|
|
|
// 验证回调参数
|
|
if !callbackID.Equal(id) {
|
|
t.Errorf("Callback ID = %v, want %v", callbackID, id)
|
|
}
|
|
|
|
if callbackValue.Value != value {
|
|
t.Errorf("Callback value = %v, want %v", callbackValue.Value, value)
|
|
}
|
|
})
|
|
|
|
// 测试关闭
|
|
t.Run("Close", func(t *testing.T) {
|
|
err := manager.Close()
|
|
if err != nil {
|
|
t.Errorf("Close() error = %v", err)
|
|
}
|
|
})
|
|
}
|