forked from sonic-net/sonic-buildimage
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
CVL error reporting enhancements (sonic-net#97)
1) Enhanced cvl syntax validator to return consistent error response when data validation fails. All syntax errors will have table, keys, and error message filled. A validation error will also include errored field name and value. ConstraintErrMsg and ErrAppTag are filled if the sonic yang node has error-message and error-app-tag values. 2) Libyang is setup to fill the node path in ly_err_first() response. Attempt to resolve table name, key values and field name from this error path. For sonic yangs, the libynag returned paths will be like "/sonic-port:sonic-port/PORT/PORT_LIST[name='Ethernet0']/mtu". Elem[1] will be the table name, elem[2] predicates will be the keys and elem[3] will be the field name. 3) Try to resolve table, key and fied info from the error message if libyang did not return an error path. If not possible, table and key info are filled from the validation request data. 4) Enable error message prefixing in the cvl schema generator, which adds a "[Error]" prefix to all the error-message strings in the schema file. This helps cvl to differentiate user defined erorr messages from linyang's messages (ly_err_item struct has a single field for both). Cvl removes this prefix before filling it in ConstraintErrMsg field. 5) Modified existing test cases to verify all fields of CVLErrorInfo instead of just success/error check Signed-off-by: Sachin Holla <sachin.holla@broadcom.com>
- Loading branch information
1 parent
4a88fe7
commit 4cfc882
Showing
13 changed files
with
933 additions
and
1,354 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
//////////////////////////////////////////////////////////////////////////////// | ||
// // | ||
// Copyright 2023 Broadcom. The term Broadcom refers to Broadcom Inc. and/or // | ||
// its subsidiaries. // | ||
// // | ||
// Licensed under the Apache License, Version 2.0 (the "License"); // | ||
// you may not use this file except in compliance with the License. // | ||
// You may obtain a copy of the License at // | ||
// // | ||
// http://www.apache.org/licenses/LICENSE-2.0 // | ||
// // | ||
// Unless required by applicable law or agreed to in writing, software // | ||
// distributed under the License is distributed on an "AS IS" BASIS, // | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // | ||
// See the License for the specific language governing permissions and // | ||
// limitations under the License. // | ||
// // | ||
//////////////////////////////////////////////////////////////////////////////// | ||
|
||
package cvl_test | ||
|
||
import ( | ||
"reflect" | ||
"strings" | ||
"testing" | ||
|
||
"github.com/Azure/sonic-mgmt-common/cvl" | ||
) | ||
|
||
const ( | ||
CVL_SUCCESS = cvl.CVL_SUCCESS | ||
CVL_SYNTAX_ERROR = cvl.CVL_SYNTAX_ERROR | ||
CVL_SEMANTIC_ERROR = cvl.CVL_SEMANTIC_ERROR | ||
CVL_SYNTAX_MAXIMUM_INVALID = cvl.CVL_SYNTAX_MAXIMUM_INVALID | ||
CVL_SYNTAX_MINIMUM_INVALID = cvl.CVL_SYNTAX_MINIMUM_INVALID | ||
) | ||
|
||
var Success = CVLErrorInfo{ErrCode: CVL_SUCCESS} | ||
|
||
func compareErr(val, exp CVLErrorInfo) bool { | ||
return (val.ErrCode == exp.ErrCode) && | ||
(len(exp.TableName) == 0 || val.TableName == exp.TableName) && | ||
(len(exp.Keys) == 0 || reflect.DeepEqual(val.Keys, exp.Keys)) && | ||
(len(exp.Field) == 0 || val.Field == exp.Field) && | ||
(len(exp.Value) == 0 || val.Value == exp.Value) && | ||
(len(exp.Msg) == 0 || val.Msg == exp.Msg) && | ||
(len(exp.CVLErrDetails) == 0 || val.CVLErrDetails == exp.CVLErrDetails) && | ||
(len(exp.ConstraintErrMsg) == 0 || val.ConstraintErrMsg == exp.ConstraintErrMsg) && | ||
(len(exp.ErrAppTag) == 0 || val.ErrAppTag == exp.ErrAppTag) | ||
} | ||
|
||
func verifyErr(t *testing.T, res, exp CVLErrorInfo) { | ||
t.Helper() | ||
expandMessagePatterns(&exp) | ||
if !compareErr(res, exp) { | ||
t.Fatalf("CVLErrorInfo verification failed\nExpected: %#v\nReceived: %#v", exp, res) | ||
} | ||
} | ||
|
||
func verifyValidateEditConfig(t *testing.T, data []CVLEditConfigData, exp CVLErrorInfo) { | ||
t.Helper() | ||
c := NewTestSession(t) | ||
res, _ := c.ValidateEditConfig(data) | ||
verifyErr(t, res, exp) | ||
} | ||
|
||
func expandMessagePatterns(ex *CVLErrorInfo) { | ||
switch ex.Msg { | ||
case invalidValueErrMessage: | ||
ex.Msg = strings.ReplaceAll(ex.Msg, "{{field}}", ex.Field) | ||
ex.Msg = strings.ReplaceAll(ex.Msg, "{{value}}", ex.Value) | ||
ex.Msg = strings.TrimSuffix(ex.Msg, " \"\"") // if value is empty | ||
case unknownFieldErrMessage: | ||
ex.Msg = strings.ReplaceAll(ex.Msg, "{{field}}", ex.Field) | ||
} | ||
} | ||
|
||
const ( | ||
invalidValueErrMessage = "Field \"{{field}}\" has invalid value \"{{value}}\"" | ||
unknownFieldErrMessage = "Unknown field \"{{field}}\"" | ||
genericValueErrMessage = "Data validation failed" | ||
mustExpressionErrMessage = "Must expression validation failed" | ||
whenExpressionErrMessage = "When expression validation failed" | ||
instanceInUseErrMessage = "Validation failed for Delete operation, given instance is in use" | ||
) |
Oops, something went wrong.