Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add get FormatError method & fix test #236

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion ocpp1.6/central_system.go
Original file line number Diff line number Diff line change
Expand Up @@ -405,11 +405,15 @@ 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
cs.server.Endpoint.FormatError = ocppj.FormatViolationV16
// Start server
cs.server.Start(listenPort, listenPath)
}

func (cs *centralSystem) FormatError() ocpp.ErrorCode {
return cs.server.Endpoint.FormatError
}

func (cs *centralSystem) sendResponse(chargePointId string, confirmation ocpp.Response, err error, requestId string) {
if err != nil {
// Send error response
Expand Down
2 changes: 1 addition & 1 deletion ocpp1.6/charge_point.go
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,7 @@ 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
cp.client.Endpoint.FormatError = ocppj.FormatViolationV16
// Start client
cp.stopC = make(chan struct{}, 1)
err := cp.client.Start(centralSystemUrl)
Expand Down
4 changes: 3 additions & 1 deletion ocpp1.6/v16.go
Original file line number Diff line number Diff line change
Expand Up @@ -249,11 +249,13 @@ 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.
Errors() <-chan error
// FormatError returns a format-error error code.
FormatError() ocpp.ErrorCode
}

// Creates a new OCPP 1.6 central system.
Expand Down
7 changes: 3 additions & 4 deletions ocpp1.6_test/ocpp16_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -670,8 +670,8 @@ type OcppV16TestSuite struct {
ocppjCentralSystem *ocppj.Server
mockWsServer *MockWebsocketServer
mockWsClient *MockWebsocketClient
chargePoint ocpp16.ChargePoint
centralSystem ocpp16.CentralSystem
chargePoint ocpp16.ChargePoint // ocpp16.chargePoint
centralSystem ocpp16.CentralSystem // ocpp16.centralSystem
messageIdGenerator TestRandomIdGenerator
clientDispatcher ocppj.ClientDispatcher
serverDispatcher ocppj.ServerDispatcher
Expand Down Expand Up @@ -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))
}
2 changes: 1 addition & 1 deletion ocpp1.6_test/proto_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,5 +157,5 @@ 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)
assert.Equal(t, ocppj.FormatViolationV16, suite.centralSystem.FormatError())
}
2 changes: 1 addition & 1 deletion ocpp2.0.1/charging_station.go
Original file line number Diff line number Diff line change
Expand Up @@ -594,7 +594,7 @@ 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
cs.client.Endpoint.FormatError = ocppj.FormatViolationV2
// Start client
cs.stopC = make(chan struct{}, 1)
err := cs.client.Start(csmsUrl)
Expand Down
6 changes: 5 additions & 1 deletion ocpp2.0.1/csms.go
Original file line number Diff line number Diff line change
Expand Up @@ -811,11 +811,15 @@ 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
cs.server.Endpoint.FormatError = ocppj.FormatViolationV2
// Start server
cs.server.Start(listenPort, listenPath)
}

func (cs *csms) FormatError() ocpp.ErrorCode {
return cs.server.Endpoint.FormatError
}

func (cs *csms) sendResponse(chargingStationID string, response ocpp.Response, err error, requestId string) {
if err != nil {
// Send error response
Expand Down
2 changes: 2 additions & 0 deletions ocpp2.0.1/v2.go
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,8 @@ type CSMS interface {
Start(listenPort int, listenPath string)
// Errors returns a channel for error messages. If it doesn't exist it es created.
Errors() <-chan error
// FormatError returns a format-error error code.
FormatError() ocpp.ErrorCode
}

// Creates a new OCPP 2.0 CSMS.
Expand Down
2 changes: 1 addition & 1 deletion ocpp2.0.1_test/proto_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,5 +162,5 @@ 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)
assert.Equal(t, ocppj.FormatViolationV2, suite.csms.FormatError())
}
8 changes: 4 additions & 4 deletions ocppj/central_system_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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, suite.centralSystem.Endpoint.FormatError, "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))
Expand All @@ -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, suite.centralSystem.Endpoint.FormatError, 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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
8 changes: 4 additions & 4 deletions ocppj/charge_point_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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, suite.chargePoint.Endpoint.FormatError, "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))
Expand All @@ -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, suite.chargePoint.Endpoint.FormatError, 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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
27 changes: 12 additions & 15 deletions ocppj/ocppj.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,14 +198,10 @@ 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.
)

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
Expand Down Expand Up @@ -308,7 +304,8 @@ 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 {
Profiles []*ocpp.Profile
FormatError ocpp.ErrorCode
Profiles []*ocpp.Profile
}

// Adds support for a new profile on the endpoint.
Expand Down Expand Up @@ -378,25 +375,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(endpoint.FormatError, "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(endpoint.FormatError, 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(endpoint.FormatError, 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(endpoint.FormatError, "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(endpoint.FormatError, fmt.Sprintf("Invalid element %v at 2, expected action (string)", arr[2]), uniqueId)
}

profile, ok := endpoint.GetProfileForFeature(action)
Expand All @@ -405,7 +402,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(endpoint.FormatError, err.Error(), uniqueId)
}
call := Call{
MessageTypeId: CALL,
Expand All @@ -427,7 +424,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(endpoint.FormatError, err.Error(), uniqueId)
}
callResult := CallResult{
MessageTypeId: CALL_RESULT,
Expand All @@ -446,15 +443,15 @@ 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(endpoint.FormatError, "Invalid Call Error message. Expected array length >= 4", uniqueId)
}
var details interface{}
if len(arr) > 4 {
details = arr[4]
}
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(endpoint.FormatError, fmt.Sprintf("Invalid element %v at 2, expected rawErrorCode (string)", arr[2]), rawErrorCode)
}
errorCode := ocpp.ErrorCode(rawErrorCode)
errorDescription := ""
Expand Down
Loading