449 lines
13 KiB
Go
449 lines
13 KiB
Go
package dbc_test
|
|
|
|
import (
|
|
"fmt"
|
|
"reflect"
|
|
"regexp"
|
|
"testing"
|
|
|
|
"fiskerinc.com/modules/dbc"
|
|
fm29_frs90 "fiskerinc.com/modules/dbc/fm29_frs90"
|
|
fm29_frsd0 "fiskerinc.com/modules/dbc/fm29_frsd0"
|
|
fm29_frsd21 "fiskerinc.com/modules/dbc/fm29_frsd21"
|
|
fm29_frsd390 "fiskerinc.com/modules/dbc/fm29_frsd390"
|
|
|
|
"fiskerinc.com/modules/dbc/state"
|
|
"fiskerinc.com/modules/grpc/kafka_grpc"
|
|
"fiskerinc.com/modules/testhelper"
|
|
"github.com/golang/protobuf/proto"
|
|
"github.com/jinzhu/copier"
|
|
)
|
|
|
|
const vin = "11111111111111111"
|
|
|
|
var epoch = int64(1642455023642165)
|
|
var payloadFRS90 = kafka_grpc.GRPC_BatchPayload{
|
|
Version: fm29_frs90.Hash,
|
|
Data: &kafka_grpc.GRPC_CANData{
|
|
Frames: []*kafka_grpc.GRPC_CANFrame{
|
|
{
|
|
Epoch: epoch,
|
|
ID: 608,
|
|
Value: []byte("AAEAAAAAAAA="),
|
|
},
|
|
{
|
|
Epoch: epoch,
|
|
ID: 757,
|
|
Value: []byte("CgAAAAAUAAA="),
|
|
},
|
|
{
|
|
Epoch: epoch,
|
|
ID: 801,
|
|
Value: []byte("AAAUKDxQ/wA="),
|
|
},
|
|
{
|
|
Epoch: epoch,
|
|
ID: 816,
|
|
Value: []byte("AAAAfQAAAAA="),
|
|
},
|
|
{
|
|
Epoch: epoch,
|
|
ID: 821,
|
|
Value: []byte("AAAAAAgAAP8="),
|
|
},
|
|
{
|
|
Epoch: epoch,
|
|
ID: 835,
|
|
Value: []byte("AAAFbAAAMgA="),
|
|
},
|
|
{
|
|
Epoch: epoch,
|
|
ID: 873,
|
|
Value: []byte("AAB4jKAAAAE="),
|
|
},
|
|
{
|
|
Epoch: epoch,
|
|
ID: 882,
|
|
Value: []byte("AAAwADCKADA="),
|
|
},
|
|
{
|
|
Epoch: epoch,
|
|
ID: 883,
|
|
Value: []byte("AAAAAACcAAA="),
|
|
},
|
|
{
|
|
Epoch: epoch,
|
|
ID: 902,
|
|
Value: []byte("AQAAAAAAAAA="),
|
|
},
|
|
{
|
|
Epoch: epoch,
|
|
ID: 1284,
|
|
Value: []byte("AAAAAAAwNAA="),
|
|
},
|
|
{
|
|
Epoch: epoch,
|
|
ID: 1298,
|
|
Value: []byte("EAAAAAAAAAA="),
|
|
},
|
|
{
|
|
Epoch: epoch,
|
|
ID: 1304,
|
|
Value: []byte("AgAAAAAAAAA="),
|
|
},
|
|
{
|
|
Epoch: epoch,
|
|
ID: 1329,
|
|
Value: []byte("AAADlAQAAAA="),
|
|
},
|
|
{
|
|
Epoch: epoch,
|
|
ID: 1408,
|
|
Value: []byte("AAAAABOIAAA="),
|
|
},
|
|
{
|
|
Epoch: epoch,
|
|
ID: 1410,
|
|
Value: []byte("nAB4AAAAAAA="),
|
|
},
|
|
{
|
|
Epoch: epoch,
|
|
ID: 1317,
|
|
Value: []byte("AABAg6NJ64c="),
|
|
},
|
|
},
|
|
},
|
|
}
|
|
var payloadFRSD0 = kafka_grpc.GRPC_BatchPayload{
|
|
Version: fm29_frsd0.Hash,
|
|
Data: &kafka_grpc.GRPC_CANData{
|
|
Frames: []*kafka_grpc.GRPC_CANFrame{
|
|
{
|
|
Epoch: epoch,
|
|
ID: 608,
|
|
Value: []byte("AAAA+gH0Aec="),
|
|
},
|
|
{
|
|
Epoch: epoch,
|
|
ID: 757,
|
|
Value: []byte("CgAAAAAUAAA="),
|
|
},
|
|
{
|
|
Epoch: epoch,
|
|
ID: 801,
|
|
Value: []byte("AAAUKDxQ/wA="),
|
|
},
|
|
{
|
|
Epoch: epoch,
|
|
ID: 816,
|
|
Value: []byte("AAAAfQAAAAA="),
|
|
},
|
|
{
|
|
Epoch: epoch,
|
|
ID: 821,
|
|
Value: []byte("AAAAAAgAAP8="),
|
|
},
|
|
{
|
|
Epoch: epoch,
|
|
ID: 835,
|
|
Value: []byte("AAAFbAAAZAA="),
|
|
},
|
|
{
|
|
Epoch: epoch,
|
|
ID: 873,
|
|
Value: []byte("AAB4jKAAAAE="),
|
|
},
|
|
{
|
|
Epoch: epoch,
|
|
ID: 882,
|
|
Value: []byte("AAAwADCKADA="),
|
|
},
|
|
{
|
|
Epoch: epoch,
|
|
ID: 883,
|
|
Value: []byte("AAAAAACcAAA="),
|
|
},
|
|
{
|
|
Epoch: epoch,
|
|
ID: 902,
|
|
Value: []byte("AQAAAAAAAAA="),
|
|
},
|
|
{
|
|
Epoch: epoch,
|
|
ID: 1284,
|
|
Value: []byte("AAAAAAAwNAA="),
|
|
},
|
|
{
|
|
Epoch: epoch,
|
|
ID: 1298,
|
|
Value: []byte("EAAAAAAAAAA="),
|
|
},
|
|
{
|
|
Epoch: epoch,
|
|
ID: 1304,
|
|
Value: []byte("AgAAAAAAAAA="),
|
|
},
|
|
{
|
|
Epoch: epoch,
|
|
ID: 1329,
|
|
Value: []byte("AAADlAQAAAA="),
|
|
},
|
|
{
|
|
Epoch: epoch,
|
|
ID: 1408,
|
|
Value: []byte("AMgBLBOIAZA="),
|
|
},
|
|
{
|
|
Epoch: epoch,
|
|
ID: 1410,
|
|
Value: []byte("nAB4AAAAAAA="),
|
|
},
|
|
{
|
|
Epoch: epoch,
|
|
ID: 1317,
|
|
Value: []byte("ZAVAgAAAAAA="),
|
|
},
|
|
{
|
|
Epoch: epoch,
|
|
ID: 1318,
|
|
Value: []byte("A414OAeAC0A="),
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
var expectedValuesFRS90 = map[string]interface{}{
|
|
state.BCM_AP_FL_LeFrntWinPosnInfo: interface{}(10),
|
|
state.BCM_AP_FL_LeReWinPosnInfo: interface{}(30),
|
|
state.BCM_AP_FL_RiFrntWinPosnInfo: interface{}(20),
|
|
state.BCM_AP_FL_RiReWinPosnInfo: interface{}(40),
|
|
state.BCM_AP_RW_WinPosnInfo: interface{}(80),
|
|
state.BCM_AP_TL_LeReWinPosnInfo: interface{}(60),
|
|
state.BCM_AP_TL_RiReWinPosnInfo: interface{}(70),
|
|
state.BCM_CenLockSwtSts: interface{}(3),
|
|
state.BCM_DrFrntDoorSts: interface{}(false),
|
|
state.BCM_FrntDrDoorLockSts: interface{}(true),
|
|
state.BCM_FrntHoodLidSts: interface{}(true),
|
|
state.BCM_HeatedSteerWhlSt: interface{}(true),
|
|
state.BCM_LeReDoorSts: interface{}(true),
|
|
state.BCM_PasFrntDoorSts: interface{}(false),
|
|
state.BCM_ReDefrstHeatgCmd: interface{}(true),
|
|
state.BCM_RiReDoorSts: interface{}(true),
|
|
state.BCM_SunroofPosnInfo: interface{}(50),
|
|
state.BMS_Bat_SOH: interface{}(20),
|
|
state.BMS_Bat_SoC_usable: interface{}(10),
|
|
state.BMS_BattAvrgT: interface{}(90),
|
|
state.BMS_PwrBattRmngCpSOC: interface{}(50),
|
|
state.DSMC_DrvrSeatHeatgSts: interface{}(2),
|
|
state.ECC_InsdT: interface{}(30),
|
|
state.ECC_OutdT: interface{}(30),
|
|
state.ECC_RemTSetSts: interface{}(120),
|
|
state.ICC_TotMilg_ODO: interface{}(float64(2345)),
|
|
state.PSM_PassSeatHeatgSts: interface{}(4),
|
|
state.TBOX_GPSHei: interface{}(float64(16)),
|
|
state.TBOX_GPSLati: interface{}(float64(35.831)),
|
|
state.TBOX_GPSLongi: interface{}(float64(-120.398)),
|
|
state.VCU_DCChrgRmngTi: interface{}(5000),
|
|
state.VCU_DrvgMilg: interface{}(1234),
|
|
state.VCU_VehChrgDchgMod: interface{}("DC_charging"),
|
|
state.UPDATED_AT: interface{}([]byte{34, 50, 48, 50, 50, 45, 48, 49, 45, 49, 55, 84, 50, 49, 58, 51, 48, 58, 50, 51, 46, 54, 52, 50, 49, 54, 53, 90, 34}),
|
|
}
|
|
var expectedValuesFRSD0 = map[string]interface{}{
|
|
state.BCM_AP_FL_LeFrntWinPosnInfo: interface{}(10),
|
|
state.BCM_AP_FL_LeReWinPosnInfo: interface{}(30),
|
|
state.BCM_AP_FL_RiFrntWinPosnInfo: interface{}(20),
|
|
state.BCM_AP_FL_RiReWinPosnInfo: interface{}(40),
|
|
state.BCM_AP_RW_WinPosnInfo: interface{}(80),
|
|
state.BCM_AP_TL_LeReWinPosnInfo: interface{}(60),
|
|
state.BCM_AP_TL_RiReWinPosnInfo: interface{}(70),
|
|
state.BCM_CenLockSwtSts: interface{}(3),
|
|
state.BCM_DrFrntDoorSts: interface{}(false),
|
|
state.BCM_FrntDrDoorLockSts: interface{}(true),
|
|
state.BCM_FrntHoodLidSts: interface{}(true),
|
|
state.BCM_HeatedSteerWhlSt: interface{}(true),
|
|
state.BCM_LeReDoorSts: interface{}(true),
|
|
state.BCM_PasFrntDoorSts: interface{}(false),
|
|
state.BCM_ReDefrstHeatgCmd: interface{}(true),
|
|
state.BCM_RiReDoorSts: interface{}(true),
|
|
state.BCM_SunroofPosnInfo: interface{}(50),
|
|
state.BMS_Bat_SOH: interface{}(20),
|
|
state.BMS_Bat_SoC_usable: interface{}(10),
|
|
state.BMS_BattAvrgT: interface{}(90),
|
|
state.BMS_PwrBattRmngCpSOC: interface{}(50),
|
|
state.DSMC_DrvrSeatHeatgSts: interface{}(2),
|
|
state.ECC_InsdT: interface{}(30),
|
|
state.ECC_OutdT: interface{}(30),
|
|
state.ECC_RemTSetSts: interface{}(120),
|
|
state.ICC_TotMilg_ODO: interface{}(float64(2345)),
|
|
state.PSM_PassSeatHeatgSts: interface{}(4),
|
|
state.TBOX_GPSHei: interface{}(float64(16)),
|
|
state.TBOX_GPSLati: interface{}(float64(35.832)),
|
|
state.TBOX_GPSLongi: interface{}(float64(-120.397)),
|
|
state.VCU_DCChrgRmngTi: interface{}(5000),
|
|
state.VCU_DrvgMilg: interface{}(1234),
|
|
state.VCU_VehChrgDchgMod: interface{}("DC_charging"),
|
|
state.UPDATED_AT: interface{}([]byte{34, 50, 48, 50, 50, 45, 48, 49, 45, 49, 55, 84, 50, 49, 58, 51, 48, 58, 50, 51, 46, 54, 52, 50, 49, 54, 53, 90, 34}),
|
|
}
|
|
|
|
var expectedValuesFRSD21 = map[string]interface{}{
|
|
state.BCM_AP_FL_LeFrntWinPosnInfo: interface{}(10),
|
|
state.BCM_AP_FL_LeReWinPosnInfo: interface{}(30),
|
|
state.BCM_AP_FL_RiFrntWinPosnInfo: interface{}(20),
|
|
state.BCM_AP_FL_RiReWinPosnInfo: interface{}(40),
|
|
state.BCM_AP_RW_WinPosnInfo: interface{}(80),
|
|
state.BCM_AP_TL_LeReWinPosnInfo: interface{}(60),
|
|
state.BCM_AP_TL_RiReWinPosnInfo: interface{}(70),
|
|
state.BCM_CenLockSwtSts: interface{}(3),
|
|
state.BCM_DrFrntDoorSts: interface{}(false),
|
|
state.BCM_FrntDrDoorLockSts: interface{}(true),
|
|
state.BCM_FrntHoodLidSts: interface{}(true),
|
|
state.BCM_HeatedSteerWhlSt: interface{}(true),
|
|
state.BCM_LeReDoorSts: interface{}(true),
|
|
state.BCM_PasFrntDoorSts: interface{}(false),
|
|
state.BCM_ReDefrstHeatgCmd: interface{}(true),
|
|
state.BCM_RiReDoorSts: interface{}(true),
|
|
state.BCM_SunroofPosnInfo: interface{}(50),
|
|
state.BMS_Bat_SOH: interface{}(20),
|
|
state.BMS_Bat_SoC_usable: interface{}(10),
|
|
state.BMS_BattAvrgT: interface{}(90),
|
|
state.BMS_PwrBattRmngCpSOC: interface{}(50),
|
|
state.DSMC_DrvrSeatHeatgSts: interface{}(2),
|
|
state.ECC_InsdT: interface{}(30),
|
|
state.ECC_OutdT: interface{}(30),
|
|
state.ECC_RemTSetSts: interface{}(120),
|
|
state.ICC_TotMilg_ODO: interface{}(2345),
|
|
state.PSM_PassSeatHeatgSts: interface{}(4),
|
|
state.TBOX_GPSHei: interface{}(float64(2802.4)),
|
|
state.TBOX_GPSLati: interface{}(float64(-54.168)),
|
|
state.TBOX_GPSLongi: interface{}(float64(-300.397)),
|
|
state.VCU_DCChrgRmngTi: interface{}(5000),
|
|
state.VCU_DrvgMilg: interface{}(1234),
|
|
state.VCU_VehChrgDchgMod: interface{}("DC_charging"),
|
|
state.UPDATED_AT: interface{}([]byte{34, 50, 48, 50, 50, 45, 48, 49, 45, 49, 55, 84, 50, 49, 58, 51, 48, 58, 50, 51, 46, 54, 52, 50, 49, 54, 53, 90, 34}),
|
|
}
|
|
|
|
func getExpectedValuesFRS390() map[string]interface{} {
|
|
expectedValuesFRS390 := map[string]interface{}{}
|
|
copier.Copy(&expectedValuesFRS390, &expectedValuesFRSD21)
|
|
// DBC 390 does not have a definition for VCU_DCChrgRmngTi
|
|
delete(expectedValuesFRS390, state.VCU_DCChrgRmngTi)
|
|
expectedValuesFRS390[state.TBOX_GPSLati] = interface{}(float64(35.832))
|
|
expectedValuesFRS390[state.TBOX_GPSLongi] = interface{}(float64(-120.397))
|
|
|
|
return expectedValuesFRS390
|
|
}
|
|
|
|
func copyPayload(source *kafka_grpc.GRPC_BatchPayload, hash string) *kafka_grpc.GRPC_BatchPayload {
|
|
payload := kafka_grpc.GRPC_BatchPayload{}
|
|
proto.Merge(&payload, source)
|
|
payload.Version = hash
|
|
|
|
return &payload
|
|
}
|
|
|
|
func ignoreSignalUpdateTimestamp(input map[string]interface{}) map[string]interface{} {
|
|
m := make(map[string]interface{})
|
|
pattern, _ := regexp.Compile(`:updated$`)
|
|
for key, val := range input {
|
|
matched := pattern.MatchString(key)
|
|
if matched {
|
|
continue
|
|
}
|
|
m[key] = val
|
|
}
|
|
return m
|
|
}
|
|
|
|
func TestFM29_FRS90_ParseState(t *testing.T) {
|
|
payloadFRSD21 := copyPayload(&payloadFRSD0, fm29_frsd21.Hash)
|
|
payloadFRSD390 := copyPayload(&payloadFRSD0, fm29_frsd390.Hash)
|
|
expectedValuesFRS390 := getExpectedValuesFRS390()
|
|
|
|
collection := dbc.NewDBCCollection()
|
|
type testCase struct {
|
|
name string
|
|
payload *kafka_grpc.GRPC_BatchPayload
|
|
expected map[string]interface{}
|
|
expectedCommandCount int
|
|
}
|
|
tests := []testCase{
|
|
{
|
|
name: "FRS90",
|
|
payload: &payloadFRS90,
|
|
expected: expectedValuesFRS90,
|
|
expectedCommandCount: 34,
|
|
},
|
|
{
|
|
name: "FRSD0",
|
|
payload: &payloadFRSD0,
|
|
expected: expectedValuesFRSD0,
|
|
expectedCommandCount: 34,
|
|
},
|
|
{
|
|
name: "FRSD21",
|
|
payload: payloadFRSD21,
|
|
expected: expectedValuesFRSD21,
|
|
expectedCommandCount: 34,
|
|
},
|
|
{
|
|
name: "FRSD390",
|
|
payload: payloadFRSD390,
|
|
expected: expectedValuesFRS390,
|
|
expectedCommandCount: 33,
|
|
},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
keyvalues, err := collection.ParseState(vin, test.payload, nil)
|
|
if err != nil {
|
|
t.Errorf(testhelper.TestErrorTemplate, fmt.Sprintf("ParseState %s", test.name), nil, err)
|
|
}
|
|
expectedCommandCount := 2*test.expectedCommandCount - 1
|
|
if len(keyvalues) != expectedCommandCount {
|
|
t.Errorf(testhelper.TestErrorTemplate, fmt.Sprintf("key value len %s", test.name), expectedCommandCount, len(keyvalues))
|
|
}
|
|
mKeyVal := ignoreSignalUpdateTimestamp(keyvalues)
|
|
if !reflect.DeepEqual(mKeyVal, test.expected) {
|
|
t.Errorf(testhelper.TestErrorTemplate, fmt.Sprintf("key value compare %s", test.name), test.expected, keyvalues)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestBadMsgID(t *testing.T) {
|
|
collection := dbc.NewDBCCollection()
|
|
payload := kafka_grpc.GRPC_BatchPayload{
|
|
Version: fm29_frsd0.Hash,
|
|
Data: &kafka_grpc.GRPC_CANData{
|
|
Frames: []*kafka_grpc.GRPC_CANFrame{
|
|
{
|
|
Epoch: epoch,
|
|
ID: 576,
|
|
Value: []byte("AAAAA414OAeAC0A="),
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
// This test should not set anything in Redis cache
|
|
keyvalues, _ := collection.ParseState(vin, &payload, nil)
|
|
if len(keyvalues) != 0 {
|
|
t.Errorf(testhelper.TestErrorTemplate, "bad message id", 0, len(keyvalues))
|
|
}
|
|
}
|
|
|
|
func BenchmarkNewFM29_FRS90_DBC(b *testing.B) {
|
|
for n := 0; n < b.N; n++ {
|
|
dbc.NewFM29_FRS90_DBC()
|
|
}
|
|
}
|
|
|
|
func BenchmarkParseState(b *testing.B) {
|
|
collection := dbc.NewDBCCollection()
|
|
|
|
for n := 0; n < b.N; n++ {
|
|
collection.ParseState(vin, &payloadFRS90, nil)
|
|
}
|
|
}
|