Add depot, attendant, jetfire, optimus, ota services with kustomize overlays
This commit is contained in:
317
services/ota_update_go/handlers/carupdate_add_test.go
Normal file
317
services/ota_update_go/handlers/carupdate_add_test.go
Normal file
@@ -0,0 +1,317 @@
|
||||
package handlers_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"otaupdate/handlers"
|
||||
"otaupdate/services"
|
||||
|
||||
"github.com/fiskerinc/cloud-services/pkg/common"
|
||||
dbm "github.com/fiskerinc/cloud-services/pkg/db/queries/mocks"
|
||||
"github.com/fiskerinc/cloud-services/pkg/grpc/kafka_grpc"
|
||||
htc "github.com/fiskerinc/cloud-services/pkg/httpclient/tester"
|
||||
"github.com/fiskerinc/cloud-services/pkg/httphandlers"
|
||||
"github.com/fiskerinc/cloud-services/pkg/kafka"
|
||||
km "github.com/fiskerinc/cloud-services/pkg/kafka/mock"
|
||||
"github.com/fiskerinc/cloud-services/pkg/redis"
|
||||
rm "github.com/fiskerinc/cloud-services/pkg/redis/tester"
|
||||
th "github.com/fiskerinc/cloud-services/pkg/testhelper"
|
||||
"github.com/fiskerinc/cloud-services/pkg/testrunner"
|
||||
uhelpers "github.com/fiskerinc/cloud-services/pkg/usecase_helpers"
|
||||
"github.com/fiskerinc/cloud-services/pkg/utils/whereami"
|
||||
"github.com/fiskerinc/cloud-services/pkg/validator"
|
||||
"github.com/go-pg/pg/v10"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
func TestCarUpdateAdd(t *testing.T) {
|
||||
whereami.SetService(whereami.OTA)
|
||||
redis.MockRedisConnection()
|
||||
mockDB := dbm.MockCarUpdates{}
|
||||
mockKafka := km.KafkaMock{}
|
||||
mockRedis := rm.MockRedis{}
|
||||
vin := "1G1FP87S3GN100062"
|
||||
mockFoa := FoaServiceMock{}
|
||||
services.SetFoaService(&mockFoa)
|
||||
services.GetDB().SetCarUpdates(&mockDB)
|
||||
services.SetKafkaProducer(&mockKafka)
|
||||
services.SetRedisClientPool(rm.NewMockClientPool(&mockRedis))
|
||||
otaUpdateKey := common.Service.Key(vin)
|
||||
attendentTopic := kafka.AttendantServiceGRPCKafka
|
||||
updateMsg := &kafka_grpc.GRPC_AttendantPayload_UpdateManifest{
|
||||
UpdateManifest: &kafka_grpc.UpdateManifest{
|
||||
CarUpdateId: 1,
|
||||
},
|
||||
}
|
||||
kafkaMSG := kafka_grpc.GRPC_AttendantPayload{
|
||||
Handler: "send_manifest",
|
||||
Data: updateMsg,
|
||||
}
|
||||
binaryPayload, _ := proto.Marshal(&kafkaMSG)
|
||||
validMessage := fmt.Sprintf(`"%s"`, base64.StdEncoding.EncodeToString(binaryPayload))
|
||||
standardManifest := common.UpdateManifest{
|
||||
ID: 100,
|
||||
Name: "TEST",
|
||||
Version: "10000",
|
||||
Type: "standard",
|
||||
Country: "US",
|
||||
PowerTrain: "MD23",
|
||||
Restraint: "None",
|
||||
Model: "Ocean",
|
||||
Trim: "Sport",
|
||||
Year: 2022,
|
||||
BodyType: "truck",
|
||||
ECUs: []*common.UpdateManifestECU{
|
||||
{
|
||||
ECU: "ICC",
|
||||
Version: "SWVERSION",
|
||||
HWVersions: []string{"HWVERSION"},
|
||||
Mode: "ICC",
|
||||
SelfDownload: true,
|
||||
Files: []*common.UpdateManifestFile{
|
||||
{
|
||||
FileID: "AAAAAAA",
|
||||
URL: "http://download.com/file1.bin",
|
||||
FileSize: 1000,
|
||||
Checksum: "AAAAAAA",
|
||||
WriteRegionID: 100,
|
||||
WriteRegion: common.MemoryRegion{
|
||||
Offset: 101,
|
||||
Length: 102,
|
||||
},
|
||||
EraseRegionID: 200,
|
||||
EraseRegion: &common.MemoryRegion{
|
||||
Offset: 201,
|
||||
Length: 202,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
ECU: "ECU",
|
||||
Version: "SWVERSION",
|
||||
HWVersions: []string{"HWVERSION"},
|
||||
Mode: "D",
|
||||
Files: []*common.UpdateManifestFile{
|
||||
{
|
||||
FileID: "BBBBBBB",
|
||||
URL: "http://download.com/file2.bin",
|
||||
FileSize: 2000,
|
||||
Checksum: "BBBBBBB",
|
||||
WriteRegionID: 300,
|
||||
WriteRegion: common.MemoryRegion{
|
||||
Offset: 301,
|
||||
Length: 302,
|
||||
},
|
||||
EraseRegionID: 400,
|
||||
EraseRegion: &common.MemoryRegion{
|
||||
Offset: 401,
|
||||
Length: 402,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
forcedManifest := standardManifest
|
||||
forcedManifest.Type = "forced"
|
||||
|
||||
tests := []testrunner.TestCase{
|
||||
{
|
||||
Name: "Bad car ids",
|
||||
HttpTestCase: &htc.HttpTestCase{
|
||||
Request: th.MakeTestRequest(http.MethodPost, "http://example.com/carupdate", uhelpers.JSONCarUpdatesRequest{
|
||||
UpdateManifestID: 1,
|
||||
}),
|
||||
ExpectedStatus: http.StatusBadRequest,
|
||||
ExpectedResponse: `{"message":"VINs required","error":"Bad Request"}`,
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "No data",
|
||||
HttpTestCase: &htc.HttpTestCase{
|
||||
Request: th.MakeTestRequest(http.MethodPost, "http://example.com/carupdate", nil),
|
||||
ExpectedStatus: http.StatusBadRequest,
|
||||
ExpectedResponse: `{"message":"UpdateManifestID required. VINs required","error":"Bad Request"}`,
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "Bad package ids",
|
||||
HttpTestCase: &htc.HttpTestCase{
|
||||
Request: th.MakeTestRequest(http.MethodPost, "http://example.com/carupdate", uhelpers.JSONCarUpdatesRequest{
|
||||
VINs: []string{"NONEXISTENT", "NONEXISTENT2"},
|
||||
}),
|
||||
ExpectedStatus: http.StatusBadRequest,
|
||||
ExpectedResponse: `{"message":"UpdateManifestID required. VINs[0] 'NONEXISTENT' invalid. VINs[1] 'NONEXISTENT2' invalid","error":"Bad Request"}`,
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "Good data standard manifest id",
|
||||
HttpTestCase: &htc.HttpTestCase{
|
||||
Request: th.MakeTestRequest(http.MethodPost, "http://example.com/carupdate", uhelpers.JSONCarUpdatesRequest{
|
||||
UpdateManifestID: 1,
|
||||
VINs: []string{"1G1FP87S3GN100062"},
|
||||
}),
|
||||
ExpectedStatus: http.StatusOK,
|
||||
ExpectedResponse: `{"data":[{"id":1,"vin":"1G1FP87S3GN100062","manifest_id":1,"status":"pending","username":"testusername","UpdateSource":"OTA"}]}`,
|
||||
},
|
||||
DBTestCase: &dbm.DBTestCase{
|
||||
SetupMockResponse: func() {
|
||||
services.GetDB().SetUpdateManifests(&dbm.MockUpdateManifests{
|
||||
LoadResponse: &standardManifest,
|
||||
})
|
||||
},
|
||||
},
|
||||
RedisTestCase: &rm.RedisTestCase{},
|
||||
KafkaTestCase: &km.KafkaTestCase{
|
||||
ExpectedProduceMessages: map[string]map[string]interface{}{
|
||||
attendentTopic: {
|
||||
otaUpdateKey: validMessage,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "Case where manifest id does not exist",
|
||||
HttpTestCase: &htc.HttpTestCase{
|
||||
Request: th.MakeTestRequest(http.MethodPost, "http://example.com/carupdate", uhelpers.JSONCarUpdatesRequest{
|
||||
UpdateManifestID: 1,
|
||||
VINs: []string{"1G1FP87S3GN100062"},
|
||||
}),
|
||||
ExpectedStatus: http.StatusNotFound,
|
||||
ExpectedResponse: `{"message":"pg: no rows in result set","error":"Not Found"}`,
|
||||
Setup: func() {
|
||||
services.GetDB().SetUpdateManifests(&dbm.MockUpdateManifests{
|
||||
LoadResponse: nil,
|
||||
DBMockHelper: dbm.DBMockHelper{
|
||||
Error: pg.ErrNoRows,
|
||||
},
|
||||
})
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "Good data forced manifest id",
|
||||
HttpTestCase: &htc.HttpTestCase{
|
||||
Request: th.MakeTestRequest(http.MethodPost, "http://example.com/carupdate", uhelpers.JSONCarUpdatesRequest{
|
||||
UpdateManifestID: 1,
|
||||
VINs: []string{"1G1FP87S3GN100062"},
|
||||
}),
|
||||
ExpectedStatus: http.StatusOK,
|
||||
ExpectedResponse: `{"data":[{"id":1,"vin":"1G1FP87S3GN100062","manifest_id":1,"status":"pending","username":"testusername","UpdateSource":"OTA"}]}`,
|
||||
},
|
||||
DBTestCase: &dbm.DBTestCase{
|
||||
SetupMockResponse: func() {
|
||||
services.GetDB().SetUpdateManifests(&dbm.MockUpdateManifests{
|
||||
LoadResponse: &forcedManifest,
|
||||
})
|
||||
},
|
||||
},
|
||||
RedisTestCase: &rm.RedisTestCase{},
|
||||
KafkaTestCase: &km.KafkaTestCase{
|
||||
ExpectedProduceMessages: map[string]map[string]interface{}{
|
||||
attendentTopic: {
|
||||
otaUpdateKey: validMessage,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "Error",
|
||||
HttpTestCase: &htc.HttpTestCase{
|
||||
Request: th.MakeTestRequest(http.MethodPost, "http://example.com/carupdate", uhelpers.JSONCarUpdatesRequest{
|
||||
UpdateManifestID: 1,
|
||||
VINs: []string{"1G1FP87S3GN100062"},
|
||||
}),
|
||||
ExpectedStatus: http.StatusServiceUnavailable,
|
||||
ExpectedResponse: `{"message":"something went wrong","error":"Service Unavailable"}`,
|
||||
},
|
||||
DBTestCase: &dbm.DBTestCase{
|
||||
MockError: fmt.Errorf("something went wrong"),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
mockRedis.Reset()
|
||||
mockKafka.Reset()
|
||||
|
||||
if test.DBTestCase != nil {
|
||||
test.DBTestCase.SetupDB(&mockDB)
|
||||
}
|
||||
if test.RedisTestCase != nil {
|
||||
test.RedisTestCase.SetupRedis(&mockRedis)
|
||||
}
|
||||
if test.KafkaTestCase != nil {
|
||||
test.KafkaTestCase.Setup(&mockKafka)
|
||||
}
|
||||
|
||||
if test.HttpTestCase != nil {
|
||||
if test.HttpTestCase.Setup != nil {
|
||||
test.HttpTestCase.Setup()
|
||||
}
|
||||
|
||||
ctx := context.WithValue(test.HttpTestCase.Request.Context(), httphandlers.ClientIDContextKey, "testusername")
|
||||
test.HttpTestCase.Request = test.HttpTestCase.Request.WithContext(ctx)
|
||||
|
||||
w := test.HttpTestCase.Test(handlers.HandleCarUpdatesAdd)
|
||||
test.HttpTestCase.ValidateHttp(t, test.Name, w)
|
||||
}
|
||||
|
||||
if test.DBTestCase != nil {
|
||||
test.DBTestCase.Validate(t, test.Name, &mockDB)
|
||||
}
|
||||
if test.RedisTestCase != nil {
|
||||
test.RedisTestCase.Validate(t, test.Name, &mockRedis)
|
||||
}
|
||||
if test.KafkaTestCase != nil {
|
||||
test.KafkaTestCase.Validate(t, test.Name, &mockKafka)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestJSONCarUpdatesRequestValidation(t *testing.T) {
|
||||
request := uhelpers.JSONCarUpdatesRequest{
|
||||
UpdateManifestID: 1,
|
||||
VINs: []string{},
|
||||
}
|
||||
|
||||
err := validator.ValidateStruct(request)
|
||||
if err == nil {
|
||||
t.Errorf(th.TestErrorTemplate, "Validate VINs count", nil, err)
|
||||
} else {
|
||||
_, msg := validator.GetValidationErrorMsg(err)
|
||||
expected := "VINs less than 1"
|
||||
if msg != expected {
|
||||
t.Errorf(th.TestErrorTemplate, "Validate VINs count", expected, msg)
|
||||
}
|
||||
}
|
||||
|
||||
request.VINs = []string{"1G1FP87S3GN100062"}
|
||||
err = validator.ValidateStruct(request)
|
||||
if err != nil {
|
||||
t.Errorf(th.TestErrorTemplate, "Validate Good VIN", nil, err)
|
||||
}
|
||||
|
||||
request.VINs = []string{"1G1FP87S3GN10006I"}
|
||||
err = validator.ValidateStruct(request)
|
||||
if err == nil {
|
||||
t.Errorf(th.TestErrorTemplate, "Validate Bad VIN", nil, err)
|
||||
} else {
|
||||
_, msg := validator.GetValidationErrorMsg(err)
|
||||
expected := "VINs[0] '1G1FP87S3GN10006I' invalid"
|
||||
if msg != expected {
|
||||
t.Errorf(th.TestErrorTemplate, "Validate Bad VIN", expected, msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type FoaServiceMock struct{}
|
||||
|
||||
func (f *FoaServiceMock) OtaUpdateStatus(vin string, carUpdate *common.CarUpdate, status *common.CarUpdateProgress) (*http.Response, error) {
|
||||
return &http.Response{StatusCode: 200}, nil
|
||||
}
|
||||
Reference in New Issue
Block a user