132 lines
4.4 KiB
Go
132 lines
4.4 KiB
Go
package telemetry
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"lingniu-vehicle-ingest/go/vehicle-gateway/internal/envelope"
|
|
)
|
|
|
|
func TestLocationProjectionForProtocolUsesProtocolFields(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
protocol envelope.Protocol
|
|
fields map[string]any
|
|
assert func(*testing.T, LocationProjection)
|
|
}{
|
|
{
|
|
name: "gb32960",
|
|
protocol: envelope.ProtocolGB32960,
|
|
fields: map[string]any{
|
|
"gb32960.position.latitude": "30.56",
|
|
"gb32960.position.longitude": "121.0",
|
|
"gb32960.vehicle.speed_kmh": "54.3",
|
|
"gb32960.vehicle.soc_percent": "85",
|
|
"gb32960.vehicle.total_mileage": "123",
|
|
},
|
|
assert: func(t *testing.T, location LocationProjection) {
|
|
assertFloatPointer(t, location.SpeedKMH, 54.3)
|
|
assertFloatPointer(t, location.SOCPercent, 85)
|
|
},
|
|
},
|
|
{
|
|
name: "jt808",
|
|
protocol: envelope.ProtocolJT808,
|
|
fields: map[string]any{
|
|
"jt808.location.latitude": "30.590151",
|
|
"jt808.location.longitude": "121.069881",
|
|
"jt808.location.speed_kmh": "23",
|
|
"jt808.location.altitude_m": "5",
|
|
"jt808.location.direction_deg": "79",
|
|
"jt808.location.alarm_flag": "2",
|
|
"jt808.location.status_flag": "786435",
|
|
},
|
|
assert: func(t *testing.T, location LocationProjection) {
|
|
assertFloatPointer(t, location.SpeedKMH, 23)
|
|
assertFloatPointer(t, location.AltitudeM, 5)
|
|
assertFloatPointer(t, location.DirectionDeg, 79)
|
|
assertIntPointer(t, location.AlarmFlag, 2)
|
|
assertIntPointer(t, location.StatusFlag, 786435)
|
|
},
|
|
},
|
|
{
|
|
name: "yutong root fallback",
|
|
protocol: envelope.ProtocolYutongMQTT,
|
|
fields: map[string]any{
|
|
"yutong_mqtt.root.data.latitude": "30.590921",
|
|
"yutong_mqtt.root.data.longitude": "121.075044",
|
|
"yutong_mqtt.root.data.meter_speed": "27",
|
|
"yutong_mqtt.root.data.battery_capacity_soc": "78.4",
|
|
"yutong_mqtt.root.data.gpsdirection": "88",
|
|
},
|
|
assert: func(t *testing.T, location LocationProjection) {
|
|
assertFloatPointer(t, location.SpeedKMH, 27)
|
|
assertFloatPointer(t, location.SOCPercent, 78.4)
|
|
assertFloatPointer(t, location.DirectionDeg, 88)
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
location, ok := LocationProjectionForProtocol(tt.protocol, tt.fields)
|
|
if !ok {
|
|
t.Fatal("LocationProjectionForProtocol() did not find coordinates")
|
|
}
|
|
if location.Latitude == 0 || location.Longitude == 0 {
|
|
t.Fatalf("coordinates = %v,%v", location.Latitude, location.Longitude)
|
|
}
|
|
tt.assert(t, location)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestLocationProjectionForProtocolRejectsBareStandardizedFields(t *testing.T) {
|
|
for _, protocol := range []envelope.Protocol{
|
|
envelope.ProtocolGB32960,
|
|
envelope.ProtocolJT808,
|
|
envelope.ProtocolYutongMQTT,
|
|
} {
|
|
if location, ok := LocationProjectionForProtocol(protocol, map[string]any{
|
|
"latitude": 30.5,
|
|
"longitude": 121.0,
|
|
"speed_kmh": 20,
|
|
}); ok {
|
|
t.Fatalf("protocol %s unexpectedly accepted bare fields: %#v", protocol, location)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestHasRealtimeFieldsExcludesMetadataOnlyPayloads(t *testing.T) {
|
|
tests := []struct {
|
|
protocol envelope.Protocol
|
|
fields map[string]any
|
|
want bool
|
|
}{
|
|
{protocol: envelope.ProtocolGB32960, fields: map[string]any{"gb32960.header.command": "0x02"}, want: false},
|
|
{protocol: envelope.ProtocolGB32960, fields: map[string]any{"gb32960.gd_fc_stack.stack_count": "1"}, want: true},
|
|
{protocol: envelope.ProtocolJT808, fields: map[string]any{"jt808.registration.plate": "粤A00001"}, want: false},
|
|
{protocol: envelope.ProtocolJT808, fields: map[string]any{"jt808.location.speed_kmh": "20"}, want: true},
|
|
{protocol: envelope.ProtocolYutongMQTT, fields: map[string]any{"yutong_mqtt.metadata.topic": "/ytforward/shln/3"}, want: false},
|
|
{protocol: envelope.ProtocolYutongMQTT, fields: map[string]any{"yutong_mqtt.data.meter_speed": "20"}, want: true},
|
|
}
|
|
for _, tt := range tests {
|
|
if got := HasRealtimeFields(tt.protocol, tt.fields); got != tt.want {
|
|
t.Fatalf("HasRealtimeFields(%s, %#v) = %v, want %v", tt.protocol, tt.fields, got, tt.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func assertFloatPointer(t *testing.T, value *float64, want float64) {
|
|
t.Helper()
|
|
if value == nil || *value != want {
|
|
t.Fatalf("float pointer = %v, want %v", value, want)
|
|
}
|
|
}
|
|
|
|
func assertIntPointer(t *testing.T, value *int64, want int64) {
|
|
t.Helper()
|
|
if value == nil || *value != want {
|
|
t.Fatalf("int pointer = %v, want %v", value, want)
|
|
}
|
|
}
|