diff --git a/ocpp/ocpp.go b/ocpp/ocpp.go index 9014a077..2defbf5f 100644 --- a/ocpp/ocpp.go +++ b/ocpp/ocpp.go @@ -112,3 +112,12 @@ func (p *Profile) ParseResponse(featureName string, rawResponse interface{}, res responseType := feature.GetResponseType() return responseParser(rawResponse, responseType) } + +// Dialect is the OCPP version the Endpoint supports +type Dialect int + +const ( + _ Dialect = iota + V16 + V2 +) diff --git a/ocpp1.6/central_system.go b/ocpp1.6/central_system.go index 73d5f291..2e313776 100644 --- a/ocpp1.6/central_system.go +++ b/ocpp1.6/central_system.go @@ -33,6 +33,7 @@ func newCentralSystem(server *ocppj.Server) centralSystem { if server == nil { panic("server must not be nil") } + server.SetDialect(ocpp.V16) return centralSystem{ server: server, callbackQueue: callbackqueue.New(), @@ -404,8 +405,6 @@ func (cs *centralSystem) SendRequestAsync(clientId string, request ocpp.Request, } func (cs *centralSystem) Start(listenPort int, listenPath string) { - // Overriding some protocol-specific values in the lower layers globally - ocppj.FormationViolation = ocppj.FormatViolationV16 // Start server cs.server.Start(listenPort, listenPath) } diff --git a/ocpp1.6/charge_point.go b/ocpp1.6/charge_point.go index 414e8829..f09c700d 100644 --- a/ocpp1.6/charge_point.go +++ b/ocpp1.6/charge_point.go @@ -333,8 +333,6 @@ func (cp *chargePoint) sendResponse(confirmation ocpp.Response, err error, reque } func (cp *chargePoint) Start(centralSystemUrl string) error { - // Overriding some protocol-specific values in the lower layers globally - ocppj.FormationViolation = ocppj.FormatViolationV16 // Start client cp.stopC = make(chan struct{}, 1) err := cp.client.Start(centralSystemUrl) diff --git a/ocpp1.6/v16.go b/ocpp1.6/v16.go index be035d71..e0fd0ffc 100644 --- a/ocpp1.6/v16.go +++ b/ocpp1.6/v16.go @@ -139,15 +139,22 @@ func NewChargePoint(id string, endpoint *ocppj.Client, client ws.WsClient) Charg client = ws.NewClient() } client.SetRequestedSubProtocol(types.V16Subprotocol) - cp := chargePoint{confirmationHandler: make(chan ocpp.Response, 1), errorHandler: make(chan error, 1), callbacks: callbackqueue.New()} if endpoint == nil { dispatcher := ocppj.NewDefaultClientDispatcher(ocppj.NewFIFOClientQueue(0)) endpoint = ocppj.NewClient(id, client, dispatcher, nil, core.Profile, localauth.Profile, firmware.Profile, reservation.Profile, remotetrigger.Profile, smartcharging.Profile) } + endpoint.SetDialect(ocpp.V16) + + cp := chargePoint{ + client: endpoint, + confirmationHandler: make(chan ocpp.Response, 1), + errorHandler: make(chan error, 1), + callbacks: callbackqueue.New(), + } + // Callback invoked by dispatcher, whenever a queued request is canceled, due to timeout. endpoint.SetOnRequestCanceled(cp.onRequestTimeout) - cp.client = endpoint cp.client.SetResponseHandler(func(confirmation ocpp.Response, requestId string) { cp.confirmationHandler <- confirmation @@ -249,7 +256,7 @@ type CentralSystem interface { SendRequestAsync(clientId string, request ocpp.Request, callback func(ocpp.Response, error)) error // Starts running the central system on the specified port and URL. // The central system runs as a daemon and handles incoming charge point connections and messages. - // + // The function blocks forever, so it is suggested to wrap it in a goroutine, in case other functionality needs to be executed on the main program thread. Start(listenPort int, listenPath string) // Errors returns a channel for error messages. If it doesn't exist it es created. diff --git a/ocpp1.6_test/ocpp16_test.go b/ocpp1.6_test/ocpp16_test.go index 3e206edd..69cb7cd5 100644 --- a/ocpp1.6_test/ocpp16_test.go +++ b/ocpp1.6_test/ocpp16_test.go @@ -720,8 +720,7 @@ func (suite *OcppV16TestSuite) TestIsConnected() { assert.False(t, suite.chargePoint.IsConnected()) } -//TODO: implement generic protocol tests - +// TODO: implement generic protocol tests func TestOcpp16Protocol(t *testing.T) { suite.Run(t, new(OcppV16TestSuite)) } diff --git a/ocpp1.6_test/proto_test.go b/ocpp1.6_test/proto_test.go index 39815663..b843d039 100644 --- a/ocpp1.6_test/proto_test.go +++ b/ocpp1.6_test/proto_test.go @@ -154,8 +154,5 @@ func (suite *OcppV16TestSuite) TestCentralSystemSendResponseError() { } func (suite *OcppV16TestSuite) TestErrorCodes() { - t := suite.T() - suite.mockWsServer.On("Start", mock.AnythingOfType("int"), mock.AnythingOfType("string")).Return(nil) - suite.centralSystem.Start(8887, "somePath") - assert.Equal(t, ocppj.FormatViolationV16, ocppj.FormationViolation) + suite.Equal(ocppj.FormatViolationV16, ocppj.FormatErrorType(suite.ocppjCentralSystem)) } diff --git a/ocpp2.0.1/charging_station.go b/ocpp2.0.1/charging_station.go index c1ef9ea0..065af9a2 100644 --- a/ocpp2.0.1/charging_station.go +++ b/ocpp2.0.1/charging_station.go @@ -593,8 +593,6 @@ func (cs *chargingStation) sendResponse(response ocpp.Response, err error, reque } func (cs *chargingStation) Start(csmsUrl string) error { - // Overriding some protocol-specific values in the lower layers globally - ocppj.FormationViolation = ocppj.FormatViolationV2 // Start client cs.stopC = make(chan struct{}, 1) err := cs.client.Start(csmsUrl) diff --git a/ocpp2.0.1/csms.go b/ocpp2.0.1/csms.go index 7b66ac70..eddb0292 100644 --- a/ocpp2.0.1/csms.go +++ b/ocpp2.0.1/csms.go @@ -53,6 +53,7 @@ func newCSMS(server *ocppj.Server) csms { if server == nil { panic("server must not be nil") } + server.SetDialect(ocpp.V2) return csms{ server: server, callbackQueue: callbackqueue.New(), @@ -810,8 +811,6 @@ func (cs *csms) SendRequestAsync(clientId string, request ocpp.Request, callback } func (cs *csms) Start(listenPort int, listenPath string) { - // Overriding some protocol-specific values in the lower layers globally - ocppj.FormationViolation = ocppj.FormatViolationV2 // Start server cs.server.Start(listenPort, listenPath) } diff --git a/ocpp2.0.1/v2.go b/ocpp2.0.1/v2.go index 8627d8ee..83953e60 100644 --- a/ocpp2.0.1/v2.go +++ b/ocpp2.0.1/v2.go @@ -34,8 +34,10 @@ type ChargingStationConnection interface { TLSConnectionState() *tls.ConnectionState } -type ChargingStationValidationHandler ws.CheckClientHandler -type ChargingStationConnectionHandler func(chargePoint ChargingStationConnection) +type ( + ChargingStationValidationHandler ws.CheckClientHandler + ChargingStationConnectionHandler func(chargePoint ChargingStationConnection) +) // -------------------- v2.0 Charging Station -------------------- @@ -204,16 +206,22 @@ func NewChargingStation(id string, endpoint *ocppj.Client, client ws.WsClient) C client = ws.NewClient() } client.SetRequestedSubProtocol(types.V201Subprotocol) - cs := chargingStation{responseHandler: make(chan ocpp.Response, 1), errorHandler: make(chan error, 1), callbacks: callbackqueue.New()} if endpoint == nil { dispatcher := ocppj.NewDefaultClientDispatcher(ocppj.NewFIFOClientQueue(0)) endpoint = ocppj.NewClient(id, client, dispatcher, nil, authorization.Profile, availability.Profile, data.Profile, diagnostics.Profile, display.Profile, firmware.Profile, iso15118.Profile, localauth.Profile, meter.Profile, provisioning.Profile, remotecontrol.Profile, reservation.Profile, security.Profile, smartcharging.Profile, tariffcost.Profile, transactions.Profile) } + endpoint.SetDialect(ocpp.V2) + + cs := chargingStation{ + client: endpoint, + responseHandler: make(chan ocpp.Response, 1), + errorHandler: make(chan error, 1), + callbacks: callbackqueue.New(), + } // Callback invoked by dispatcher, whenever a queued request is canceled, due to timeout. endpoint.SetOnRequestCanceled(cs.onRequestTimeout) - cs.client = endpoint cs.client.SetResponseHandler(func(confirmation ocpp.Response, requestId string) { cs.responseHandler <- confirmation diff --git a/ocpp2.0.1_test/proto_test.go b/ocpp2.0.1_test/proto_test.go index 95b3af2d..5a28ecff 100644 --- a/ocpp2.0.1_test/proto_test.go +++ b/ocpp2.0.1_test/proto_test.go @@ -159,8 +159,5 @@ func (suite *OcppV2TestSuite) TestCentralSystemSendResponseError() { } func (suite *OcppV2TestSuite) TestErrorCodes() { - t := suite.T() - suite.mockWsServer.On("Start", mock.AnythingOfType("int"), mock.AnythingOfType("string")).Return(nil) - suite.csms.Start(8887, "somePath") - assert.Equal(t, ocppj.FormatViolationV2, ocppj.FormationViolation) + suite.Equal(ocppj.FormatViolationV2, ocppj.FormatErrorType(suite.ocppjServer)) } diff --git a/ocppj/central_system_test.go b/ocppj/central_system_test.go index 5d6ec7ed..e2506f68 100644 --- a/ocppj/central_system_test.go +++ b/ocppj/central_system_test.go @@ -117,7 +117,7 @@ func (suite *OcppJTestSuite) TestCentralSystemInvalidMessageHook() { serializedPayload, err := json.Marshal(mockPayload) require.NoError(t, err) invalidMessage := fmt.Sprintf("[2,\"%v\",\"%s\",%v]", mockID, MockFeatureName, string(serializedPayload)) - expectedError := fmt.Sprintf("[4,\"%v\",\"%v\",\"%v\",{}]", mockID, ocppj.FormationViolation, "json: cannot unmarshal number into Go struct field MockRequest.mockValue of type string") + expectedError := fmt.Sprintf("[4,\"%v\",\"%v\",\"%v\",{}]", mockID, ocppj.FormatErrorType(suite.centralSystem), "json: cannot unmarshal number into Go struct field MockRequest.mockValue of type string") writeHook := suite.mockServer.On("Write", mockChargePointId, mock.Anything).Return(nil).Run(func(args mock.Arguments) { data := args.Get(1).([]byte) assert.Equal(t, expectedError, string(data)) @@ -138,7 +138,7 @@ func (suite *OcppJTestSuite) TestCentralSystemInvalidMessageHook() { err = suite.mockServer.MessageHandler(mockChargePoint, []byte(invalidMessage)) ocppErr, ok := err.(*ocpp.Error) require.True(t, ok) - assert.Equal(t, ocppj.FormationViolation, ocppErr.Code) + assert.Equal(t, ocppj.FormatErrorType(suite.centralSystem), ocppErr.Code) // Setup hook 2 mockError := ocpp.NewError(ocppj.InternalError, "custom error", mockID) expectedError = fmt.Sprintf("[4,\"%v\",\"%v\",\"%v\",{}]", mockError.MessageId, mockError.Code, mockError.Description) @@ -197,7 +197,7 @@ func (suite *OcppJTestSuite) TestCentralSystemSendRequestFailed() { suite.serverDispatcher.CreateClient(mockChargePointId) mockRequest := newMockRequest("mockValue") err := suite.centralSystem.SendRequest(mockChargePointId, mockRequest) - //TODO: currently the network error is not returned by SendRequest, but is only generated internally + // TODO: currently the network error is not returned by SendRequest, but is only generated internally assert.Nil(t, err) // Assert that pending request was removed time.Sleep(500 * time.Millisecond) @@ -578,7 +578,7 @@ func (suite *OcppJTestSuite) TestEnqueueMultipleRequests() { assert.False(t, q.IsEmpty()) assert.Equal(t, messagesToQueue, q.Size()) // Analyze enqueued bundle - var i = 0 + var i int for !q.IsEmpty() { popped := q.Pop() require.NotNil(t, popped) diff --git a/ocppj/charge_point_test.go b/ocppj/charge_point_test.go index e0da3a16..aea81dde 100644 --- a/ocppj/charge_point_test.go +++ b/ocppj/charge_point_test.go @@ -122,7 +122,7 @@ func (suite *OcppJTestSuite) TestChargePointInvalidMessageHook() { serializedPayload, err := json.Marshal(mockPayload) require.NoError(t, err) invalidMessage := fmt.Sprintf("[2,\"%v\",\"%s\",%v]", mockID, MockFeatureName, string(serializedPayload)) - expectedError := fmt.Sprintf("[4,\"%v\",\"%v\",\"%v\",{}]", mockID, ocppj.FormationViolation, "json: cannot unmarshal number into Go struct field MockRequest.mockValue of type string") + expectedError := fmt.Sprintf("[4,\"%v\",\"%v\",\"%v\",{}]", mockID, ocppj.FormatErrorType(suite.chargePoint), "json: cannot unmarshal number into Go struct field MockRequest.mockValue of type string") writeHook := suite.mockClient.On("Write", mock.Anything).Return(nil).Run(func(args mock.Arguments) { data := args.Get(0).([]byte) assert.Equal(t, expectedError, string(data)) @@ -142,7 +142,7 @@ func (suite *OcppJTestSuite) TestChargePointInvalidMessageHook() { err = suite.mockClient.MessageHandler([]byte(invalidMessage)) ocppErr, ok := err.(*ocpp.Error) require.True(t, ok) - assert.Equal(t, ocppj.FormationViolation, ocppErr.Code) + assert.Equal(t, ocppj.FormatErrorType(suite.chargePoint), ocppErr.Code) // Setup hook 2 mockError := ocpp.NewError(ocppj.InternalError, "custom error", mockID) expectedError = fmt.Sprintf("[4,\"%v\",\"%v\",\"%v\",{}]", mockError.MessageId, mockError.Code, mockError.Description) @@ -193,7 +193,7 @@ func (suite *OcppJTestSuite) TestChargePointSendRequestFailed() { _ = suite.chargePoint.Start("someUrl") mockRequest := newMockRequest("mockValue") err := suite.chargePoint.SendRequest(mockRequest) - //TODO: currently the network error is not returned by SendRequest, but is only generated internally + // TODO: currently the network error is not returned by SendRequest, but is only generated internally assert.Nil(t, err) // Assert that pending request was removed time.Sleep(500 * time.Millisecond) @@ -472,7 +472,7 @@ func (suite *OcppJTestSuite) TestClientEnqueueMultipleRequests() { require.False(t, suite.clientRequestQueue.IsEmpty()) assert.Equal(t, messagesToQueue, suite.clientRequestQueue.Size()) // Analyze enqueued bundle - var i = 0 + var i int for !suite.clientRequestQueue.IsEmpty() { popped := suite.clientRequestQueue.Pop() require.NotNil(t, popped) diff --git a/ocppj/ocppj.go b/ocppj/ocppj.go index 5999eaaf..5688e42a 100644 --- a/ocppj/ocppj.go +++ b/ocppj/ocppj.go @@ -198,14 +198,25 @@ const ( FormatViolationV16 ocpp.ErrorCode = "FormationViolation" // Payload for Action is syntactically incorrect or not conform the PDU structure for Action. This is only valid for OCPP 1.6 ) -var ( - FormationViolation = FormatViolationV16 // Used as constant, but can be overwritten depending on protocol version. Sett FormatViolationV16 and FormatViolationV2. -) +type dialector interface { + Dialect() ocpp.Dialect +} + +func FormatErrorType(d dialector) ocpp.ErrorCode { + switch d.Dialect() { + case ocpp.V16: + return FormatViolationV16 + case ocpp.V2: + return FormatViolationV2 + default: + panic(fmt.Sprintf("invalid dialect: %v", d)) + } +} func IsErrorCodeValid(fl validator.FieldLevel) bool { code := ocpp.ErrorCode(fl.Field().String()) switch code { - case NotImplemented, NotSupported, InternalError, MessageTypeNotSupported, ProtocolError, SecurityError, FormationViolation, PropertyConstraintViolation, OccurrenceConstraintViolation, TypeConstraintViolation, GenericError: + case NotImplemented, NotSupported, InternalError, MessageTypeNotSupported, ProtocolError, SecurityError, FormatViolationV16, FormatViolationV2, PropertyConstraintViolation, OccurrenceConstraintViolation, TypeConstraintViolation, GenericError: return true } return false @@ -308,9 +319,20 @@ func jsonMarshal(t interface{}) ([]byte, error) { // An OCPP-J endpoint is one of the two entities taking part in the communication. // The endpoint keeps state for supported OCPP profiles and current pending requests. type Endpoint struct { + dialect ocpp.Dialect Profiles []*ocpp.Profile } +// Sets endpoint dialect. +func (endpoint *Endpoint) SetDialect(d ocpp.Dialect) { + endpoint.dialect = d +} + +// Gets endpoint dialect. +func (endpoint *Endpoint) Dialect() ocpp.Dialect { + return endpoint.dialect +} + // Adds support for a new profile on the endpoint. func (endpoint *Endpoint) AddProfile(profile *ocpp.Profile) { endpoint.Profiles = append(endpoint.Profiles, profile) @@ -378,25 +400,25 @@ func parseRawJsonConfirmation(raw interface{}, confirmationType reflect.Type) (o func (endpoint *Endpoint) ParseMessage(arr []interface{}, pendingRequestState ClientState) (Message, error) { // Checking message fields if len(arr) < 3 { - return nil, ocpp.NewError(FormationViolation, "Invalid message. Expected array length >= 3", "") + return nil, ocpp.NewError(FormatErrorType(endpoint), "Invalid message. Expected array length >= 3", "") } rawTypeId, ok := arr[0].(float64) if !ok { - return nil, ocpp.NewError(FormationViolation, fmt.Sprintf("Invalid element %v at 0, expected message type (int)", arr[0]), "") + return nil, ocpp.NewError(FormatErrorType(endpoint), fmt.Sprintf("Invalid element %v at 0, expected message type (int)", arr[0]), "") } typeId := MessageType(rawTypeId) uniqueId, ok := arr[1].(string) if !ok { - return nil, ocpp.NewError(FormationViolation, fmt.Sprintf("Invalid element %v at 1, expected unique ID (string)", arr[1]), "") + return nil, ocpp.NewError(FormatErrorType(endpoint), fmt.Sprintf("Invalid element %v at 1, expected unique ID (string)", arr[1]), uniqueId) } // Parse message if typeId == CALL { if len(arr) != 4 { - return nil, ocpp.NewError(FormationViolation, "Invalid Call message. Expected array length 4", uniqueId) + return nil, ocpp.NewError(FormatErrorType(endpoint), "Invalid Call message. Expected array length 4", uniqueId) } action, ok := arr[2].(string) if !ok { - return nil, ocpp.NewError(FormationViolation, fmt.Sprintf("Invalid element %v at 2, expected action (string)", arr[2]), uniqueId) + return nil, ocpp.NewError(FormatErrorType(endpoint), fmt.Sprintf("Invalid element %v at 2, expected action (string)", arr[2]), uniqueId) } profile, ok := endpoint.GetProfileForFeature(action) @@ -405,7 +427,7 @@ func (endpoint *Endpoint) ParseMessage(arr []interface{}, pendingRequestState Cl } request, err := profile.ParseRequest(action, arr[3], parseRawJsonRequest) if err != nil { - return nil, ocpp.NewError(FormationViolation, err.Error(), uniqueId) + return nil, ocpp.NewError(FormatErrorType(endpoint), err.Error(), uniqueId) } call := Call{ MessageTypeId: CALL, @@ -427,7 +449,7 @@ func (endpoint *Endpoint) ParseMessage(arr []interface{}, pendingRequestState Cl profile, _ := endpoint.GetProfileForFeature(request.GetFeatureName()) confirmation, err := profile.ParseResponse(request.GetFeatureName(), arr[2], parseRawJsonConfirmation) if err != nil { - return nil, ocpp.NewError(FormationViolation, err.Error(), uniqueId) + return nil, ocpp.NewError(FormatErrorType(endpoint), err.Error(), uniqueId) } callResult := CallResult{ MessageTypeId: CALL_RESULT, @@ -446,7 +468,7 @@ func (endpoint *Endpoint) ParseMessage(arr []interface{}, pendingRequestState Cl return nil, nil } if len(arr) < 4 { - return nil, ocpp.NewError(FormationViolation, "Invalid Call Error message. Expected array length >= 4", uniqueId) + return nil, ocpp.NewError(FormatErrorType(endpoint), "Invalid Call Error message. Expected array length >= 4", uniqueId) } var details interface{} if len(arr) > 4 { @@ -454,7 +476,7 @@ func (endpoint *Endpoint) ParseMessage(arr []interface{}, pendingRequestState Cl } rawErrorCode, ok := arr[2].(string) if !ok { - return nil, ocpp.NewError(FormationViolation, fmt.Sprintf("Invalid element %v at 2, expected rawErrorCode (string)", arr[2]), rawErrorCode) + return nil, ocpp.NewError(FormatErrorType(endpoint), fmt.Sprintf("Invalid element %v at 2, expected rawErrorCode (string)", arr[2]), rawErrorCode) } errorCode := ocpp.ErrorCode(rawErrorCode) errorDescription := "" diff --git a/ocppj/ocppj_test.go b/ocppj/ocppj_test.go index dcdbb1d4..97a6f984 100644 --- a/ocppj/ocppj_test.go +++ b/ocppj/ocppj_test.go @@ -29,7 +29,6 @@ type MockWebSocket struct { func (websocket MockWebSocket) ID() string { return websocket.id - } func (websocket MockWebSocket) RemoteAddr() net.Addr { @@ -375,6 +374,9 @@ func (suite *OcppJTestSuite) SetupTest() { suite.serverRequestMap = ocppj.NewFIFOQueueMap(queueCapacity) suite.serverDispatcher = ocppj.NewDefaultServerDispatcher(suite.serverRequestMap) suite.centralSystem = ocppj.NewServer(suite.mockServer, suite.serverDispatcher, nil, mockProfile) + defaultDialect := ocpp.V16 // set default to version 1.6 format error *for test only + suite.centralSystem.SetDialect(defaultDialect) + suite.chargePoint.SetDialect(defaultDialect) } func (suite *OcppJTestSuite) TearDownTest() { @@ -405,8 +407,6 @@ func (suite *OcppJTestSuite) TestGetProfileForFeature() { assert.Equal(t, "mock", profile.Name) } -//func (suite *OcppJTestSuite) TestAddFeature - func (suite *OcppJTestSuite) TestGetProfileForInvalidFeature() { t := suite.T() profile, ok := suite.chargePoint.GetProfileForFeature("test") @@ -535,7 +535,7 @@ func (suite *OcppJTestSuite) TestParseMessageInvalidLength() { protoErr := err.(*ocpp.Error) require.NotNil(t, protoErr) assert.Equal(t, "", protoErr.MessageId) - assert.Equal(t, ocppj.FormationViolation, protoErr.Code) + assert.Equal(t, ocppj.FormatErrorType(suite.chargePoint), protoErr.Code) assert.Equal(t, "Invalid message. Expected array length >= 3", protoErr.Description) } @@ -553,7 +553,7 @@ func (suite *OcppJTestSuite) TestParseMessageInvalidTypeId() { protoErr := err.(*ocpp.Error) require.NotNil(t, protoErr) assert.Equal(t, "", protoErr.MessageId) - assert.Equal(t, ocppj.FormationViolation, protoErr.Code) + assert.Equal(t, ocppj.FormatErrorType(suite.chargePoint), protoErr.Code) assert.Equal(t, fmt.Sprintf("Invalid element %v at 0, expected message type (int)", invalidTypeId), protoErr.Description) } @@ -570,7 +570,7 @@ func (suite *OcppJTestSuite) TestParseMessageInvalidMessageId() { protoErr := err.(*ocpp.Error) require.NotNil(t, protoErr) assert.Equal(t, "", protoErr.MessageId) - assert.Equal(t, ocppj.FormationViolation, protoErr.Code) + assert.Equal(t, ocppj.FormatErrorType(suite.chargePoint), protoErr.Code) assert.Equal(t, fmt.Sprintf("Invalid element %v at 1, expected unique ID (string)", invalidMessageId), protoErr.Description) } @@ -625,7 +625,7 @@ func (suite *OcppJTestSuite) TestParseMessageInvalidCall() { protoErr := err.(*ocpp.Error) require.NotNil(t, protoErr) assert.Equal(t, messageId, protoErr.MessageId) - assert.Equal(t, ocppj.FormationViolation, protoErr.Code) + assert.Equal(t, ocppj.FormatErrorType(suite.chargePoint), protoErr.Code) assert.Equal(t, "Invalid Call message. Expected array length 4", protoErr.Description) } @@ -645,7 +645,7 @@ func (suite *OcppJTestSuite) TestParseMessageInvalidActionCall() { protoErr := err.(*ocpp.Error) require.NotNil(t, protoErr) assert.Equal(t, protoErr.MessageId, messageId) // unique id is returned even after invalid type cast error - assert.Equal(t, ocppj.FormationViolation, protoErr.Code) + assert.Equal(t, ocppj.FormatErrorType(suite.chargePoint), protoErr.Code) assert.Equal(t, "Invalid element 42 at 2, expected action (string)", protoErr.Description) } @@ -680,7 +680,7 @@ func (suite *OcppJTestSuite) TestParseMessageInvalidCallError() { protoErr := err.(*ocpp.Error) require.NotNil(t, protoErr) assert.Equal(t, messageId, protoErr.MessageId) - assert.Equal(t, ocppj.FormationViolation, protoErr.Code) + assert.Equal(t, ocppj.FormatErrorType(suite.chargePoint), protoErr.Code) assert.Equal(t, "Invalid Call Error message. Expected array length >= 4", protoErr.Description) } @@ -701,7 +701,7 @@ func (suite *OcppJTestSuite) TestParseMessageInvalidRawErrorCode() { protoErr := err.(*ocpp.Error) require.NotNil(t, protoErr) assert.Equal(t, protoErr.MessageId, "") // unique id is never set after invalid type cast return - assert.Equal(t, ocppj.FormationViolation, protoErr.Code) + assert.Equal(t, ocppj.FormatErrorType(suite.chargePoint), protoErr.Code) assert.Equal(t, "Invalid element 42 at 2, expected rawErrorCode (string)", protoErr.Description) } @@ -787,8 +787,7 @@ func (suite *OcppJTestSuite) TestParseCall() { assert.Equal(t, mockValue, mockRequest.MockValue) } -//TODO: implement further ocpp-j protocol tests - +// TODO: implement further ocpp-j protocol tests type testLogger struct { c chan string } @@ -796,18 +795,23 @@ type testLogger struct { func (l *testLogger) Debug(args ...interface{}) { l.c <- "debug" } + func (l *testLogger) Debugf(format string, args ...interface{}) { l.c <- "debugf" } + func (l *testLogger) Info(args ...interface{}) { l.c <- "info" } + func (l *testLogger) Infof(format string, args ...interface{}) { l.c <- "infof" } + func (l *testLogger) Error(args ...interface{}) { l.c <- "error" } + func (l *testLogger) Errorf(format string, args ...interface{}) { l.c <- "errorf" }