package tests import ( "fmt" "github.com/fiskerinc/cloud-services/services/jetfire/services" "github.com/fiskerinc/cloud-services/services/jetfire/utils" "testing" "github.com/fiskerinc/cloud-services/pkg/grpc/kafka_grpc" "github.com/stretchr/testify/assert" ) const testVIN = "TESTVIN1234567890" var testCanSignalBatch = []kafka_grpc.GRPC_CANSignal{ {Vin: testVIN, Timestamp: 600.0, Id: 816, Name: "BMS_PwrBattRmngCpSOC", Value: 100}, {Vin: testVIN, Timestamp: 601.0, Id: 792, Name: "ESP_VehSpd", Value: 0}, {Vin: testVIN, Timestamp: 602.0, Id: 816, Name: "BMS_PwrBattRmngCpSOC", Value: 90}, {Vin: testVIN, Timestamp: 603.0, Id: 792, Name: "ESP_VehSpd", Value: 10}, {Vin: testVIN, Timestamp: 604.0, Id: 816, Name: "BMS_PwrBattRmngCpSOC", Value: 80}, {Vin: testVIN, Timestamp: 605.0, Id: 792, Name: "ESP_VehSpd", Value: 20}, {Vin: testVIN, Timestamp: 606.0, Id: 816, Name: "BMS_PwrBattRmngCpSOC", Value: 80}, {Vin: testVIN, Timestamp: 607.0, Id: 792, Name: "ESP_VehSpd", Value: 30}, {Vin: testVIN, Timestamp: 608.0, Id: 816, Name: "BMS_PwrBattRmngCpSOC", Value: 70}, {Vin: testVIN, Timestamp: 609.0, Id: 792, Name: "ESP_VehSpd", Value: 40}, {Vin: testVIN, Timestamp: 608.0, Id: 816, Name: "BMS_PwrBattRmngCpSOC", Value: 60}, {Vin: testVIN, Timestamp: 607.0, Id: 792, Name: "ESP_VehSpd", Value: 50}, {Vin: testVIN, Timestamp: 610.0, Id: 816, Name: "BMS_PwrBattRmngCpSOC", Value: 50}, {Vin: testVIN, Timestamp: 611.0, Id: 792, Name: "ESP_VehSpd", Value: 60}, {Vin: testVIN, Timestamp: 612.0, Id: 816, Name: "BMS_PwrBattRmngCpSOC", Value: 40}, {Vin: testVIN, Timestamp: 613.0, Id: 792, Name: "ESP_VehSpd", Value: 70}, {Vin: testVIN, Timestamp: 614.0, Id: 816, Name: "BMS_PwrBattRmngCpSOC", Value: 30}, {Vin: testVIN, Timestamp: 615.0, Id: 792, Name: "ESP_VehSpd", Value: 80}, {Vin: testVIN, Timestamp: 616.0, Id: 816, Name: "BMS_PwrBattRmngCpSOC", Value: 20}, {Vin: testVIN, Timestamp: 617.0, Id: 792, Name: "ESP_VehSpd", Value: 90}, {Vin: testVIN, Timestamp: 618.0, Id: 816, Name: "BMS_PwrBattRmngCpSOC", Value: 60}, {Vin: testVIN, Timestamp: 619.0, Id: 792, Name: "ESP_VehSpd", Value: 100}, {Vin: testVIN, Timestamp: 650.0, Id: 792, Name: "ESP_VehSpd", Value: 100}, {Vin: testVIN, Timestamp: 800.0, Id: 792, Name: "ESP_VehSpd", Value: 100}, {Vin: testVIN, Timestamp: 1500.0, Id: 816, Name: "BMS_PwrBattRmngCpSOC", Value: 20}, {Vin: testVIN, Timestamp: 1501.0, Id: 792, Name: "ESP_VehSpd", Value: 90}, {Vin: testVIN, Timestamp: 1502.0, Id: 816, Name: "BMS_PwrBattRmngCpSOC", Value: 45}, {Vin: testVIN, Timestamp: 1503.0, Id: 792, Name: "ESP_VehSpd", Value: 13}, {Vin: testVIN, Timestamp: 1510.0, Id: 819, Name: "BCM_PwrMod", Value: 0}, {Vin: testVIN, Timestamp: 1511.0, Id: 819, Name: "BCM_PwrMod", Value: 2}, {Vin: testVIN, Timestamp: 1512.0, Id: 792, Name: "ESP_VehSpd", Value: 11}, } var testCanSignalOrderBatch = []kafka_grpc.GRPC_CANSignal{ {Vin: testVIN, Timestamp: 700.0, Id: 816, Name: "BMS_PwrBattRmngCpSOC", Value: 100}, {Vin: testVIN, Timestamp: 601.0, Id: 792, Name: "ESP_VehSpd", Value: 0}, {Vin: testVIN, Timestamp: 603.0, Id: 792, Name: "ESP_VehSpd", Value: 10}, {Vin: testVIN, Timestamp: 704.0, Id: 816, Name: "BMS_PwrBattRmngCpSOC", Value: 80}, {Vin: testVIN, Timestamp: 605.0, Id: 792, Name: "ESP_VehSpd", Value: 20}, {Vin: testVIN, Timestamp: 607.0, Id: 792, Name: "ESP_VehSpd", Value: 30}, {Vin: testVIN, Timestamp: 708.0, Id: 816, Name: "BMS_PwrBattRmngCpSOC", Value: 70}, {Vin: testVIN, Timestamp: 609.0, Id: 792, Name: "ESP_VehSpd", Value: 40}, {Vin: testVIN, Timestamp: 607.0, Id: 792, Name: "ESP_VehSpd", Value: 50}, {Vin: testVIN, Timestamp: 710.0, Id: 816, Name: "BMS_PwrBattRmngCpSOC", Value: 50}, {Vin: testVIN, Timestamp: 611.0, Id: 792, Name: "ESP_VehSpd", Value: 60}, {Vin: testVIN, Timestamp: 613.0, Id: 792, Name: "ESP_VehSpd", Value: 70}, {Vin: testVIN, Timestamp: 714.0, Id: 816, Name: "BMS_PwrBattRmngCpSOC", Value: 30}, {Vin: testVIN, Timestamp: 615.0, Id: 792, Name: "ESP_VehSpd", Value: 80}, {Vin: testVIN, Timestamp: 617.0, Id: 792, Name: "ESP_VehSpd", Value: 90}, {Vin: testVIN, Timestamp: 718.0, Id: 816, Name: "BMS_PwrBattRmngCpSOC", Value: 60}, {Vin: testVIN, Timestamp: 619.0, Id: 792, Name: "ESP_VehSpd", Value: 100}, } func TestVehicleCache(t *testing.T) { cache := services.GetVehicleCache() cache.Clear() for i, signal := range testCanSignalBatch { cache.UpdateSignal(&signal, 0x0) if i == 4 { // testing signal aggregation state, containsState := cache.Cache[testVIN] assert.True(t, containsState) assert.NotNil(t, state) assert.WithinDuration(t, state.Timestamp, utils.FloatToTime(604.0), 1e8) assert.WithinDuration(t, state.TripStart, utils.FloatToTime(600.0), 1e8) assert.Equal(t, state.StateValues["BMS_PwrBattRmngCpSOC"], 80.0) assert.Equal(t, state.StateValues["ESP_VehSpd"], 10.0) } if i == 11 { // testing out of order messages state := cache.Cache[testVIN] assert.WithinDuration(t, state.Timestamp, utils.FloatToTime(609.0), 1e8) assert.WithinDuration(t, state.TripStart, utils.FloatToTime(600.0), 1e8) assert.Equal(t, state.StateValues["BMS_PwrBattRmngCpSOC"], 60.0) assert.Equal(t, state.StateValues["ESP_VehSpd"], 40.0) } if i == 17 { // testing signal aggregation after message order is restored state := cache.Cache[testVIN] assert.WithinDuration(t, state.Timestamp, utils.FloatToTime(615.0), 1e8) assert.WithinDuration(t, state.TripStart, utils.FloatToTime(600.0), 1e8) assert.Equal(t, state.StateValues["BMS_PwrBattRmngCpSOC"], 30.0) assert.Equal(t, state.StateValues["ESP_VehSpd"], 80.0) } if i == 22 { state := cache.Cache[testVIN] assert.WithinDuration(t, state.Timestamp, utils.FloatToTime(650.0), 1e8) assert.WithinDuration(t, state.TripStart, utils.FloatToTime(600.0), 1e8) assert.Equal(t, state.StateValues["BMS_PwrBattRmngCpSOC"], 60.0) assert.Equal(t, state.StateValues["ESP_VehSpd"], 100.0) } if i == 23 { state := cache.Cache[testVIN] assert.WithinDuration(t, state.Timestamp, utils.FloatToTime(800.0), 1e8) assert.WithinDuration(t, state.TripStart, utils.FloatToTime(600.0), 1e8) assert.Equal(t, state.StateValues["BMS_PwrBattRmngCpSOC"], 60.0) assert.Equal(t, state.StateValues["ESP_VehSpd"], 100.0) } if i == 25 { state := cache.Cache[testVIN] assert.WithinDuration(t, state.Timestamp, utils.FloatToTime(1501.0), 1e8) assert.WithinDuration(t, state.TripStart, utils.FloatToTime(1500.0), 1e8) assert.Equal(t, state.StateValues["BMS_PwrBattRmngCpSOC"], 20.0) assert.Equal(t, state.StateValues["ESP_VehSpd"], 90.0) } } assert.Equal(t, len(cache.Cache), 1) // testing large timestamp gap; trigger new trip state := cache.Cache[testVIN] tripStartTime := utils.FloatToTime(1511.0) assert.WithinDuration(t, state.TripStart, tripStartTime, 1e8) assert.Equal(t, state.TripID, fmt.Sprintf("%s_%d", testVIN, 1511)) assert.WithinDuration(t, state.Timestamp, utils.FloatToTime(1512.0), 1e8) assert.Equal(t, state.StateValues["BMS_PwrBattRmngCpSOC"], 45.0) assert.Equal(t, state.StateValues["ESP_VehSpd"], 11.0) } func TestVehicleCacheOrderly(t *testing.T) { cache := services.GetVehicleCache() cache.Clear() for i, signal := range testCanSignalOrderBatch { cache.UpdateSignal(&signal, 0x0) if i == 8 { state := cache.Cache[testVIN] assert.WithinDuration(t, state.Timestamp, utils.FloatToTime(708.0), 1e8) assert.WithinDuration(t, state.TripStart, utils.FloatToTime(700.0), 1e8) assert.Equal(t, state.StateValues["BMS_PwrBattRmngCpSOC"], 70.0) assert.Equal(t, state.StateValues["ESP_VehSpd"], 40.0) } } state := cache.Cache[testVIN] assert.WithinDuration(t, state.Timestamp, utils.FloatToTime(718.0), 1e8) assert.WithinDuration(t, state.TripStart, utils.FloatToTime(700.0), 1e8) assert.Equal(t, state.StateValues["BMS_PwrBattRmngCpSOC"], 60.0) assert.Equal(t, state.StateValues["ESP_VehSpd"], 100.0) } func TestVehicleCacheList(t *testing.T) { cache := services.GetVehicleCache() cache.Clear() signal := kafka_grpc.GRPC_CANSignal{ Vin: "TESTVIN1", Timestamp: 0.0, Id: 816, Name: "ESP_VehSpd", Value: 792, } cache.UpdateSignal(&signal, 0x0) signal = kafka_grpc.GRPC_CANSignal{ Vin: "TESTVIN2", Timestamp: 0.0, Id: 816, Name: "ESP_VehSpd", Value: 792, } cache.UpdateSignal(&signal, 0x0) signal = kafka_grpc.GRPC_CANSignal{ Vin: "TESTVIN3", Timestamp: 0.0, Id: 816, Name: "ESP_VehSpd", Value: 792, } cache.UpdateSignal(&signal, 0x0) expectedVins := []string{"TESTVIN1", "TESTVIN2", "TESTVIN3"} node := cache.StatesListHead i := 0 for node != nil { assert.Equal(t, expectedVins[i], node.VIN) node = node.Next i++ } node2 := cache.PopLeft() expectedVins = []string{"TESTVIN2", "TESTVIN3"} node = cache.StatesListHead i = 0 for node != nil { assert.Equal(t, expectedVins[i], node.VIN) node = node.Next i++ } cache.ReinsertRight(node2) expectedVins = []string{"TESTVIN2", "TESTVIN3", "TESTVIN1"} node = cache.StatesListHead i = 0 for node != nil { assert.Equal(t, expectedVins[i], node.VIN) node = node.Next i++ } cache.ReinsertRight(cache.Cache["TESTVIN3"]) expectedVins = []string{"TESTVIN2", "TESTVIN1", "TESTVIN3"} node = cache.StatesListHead i = 0 for node != nil { assert.Equal(t, expectedVins[i], node.VIN) node = node.Next i++ } }