-
Notifications
You must be signed in to change notification settings - Fork 24
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
conntrack: config validation #285
Conversation
Codecov Report
@@ Coverage Diff @@
## main #285 +/- ##
==========================================
+ Coverage 66.89% 67.38% +0.48%
==========================================
Files 73 73
Lines 4157 4271 +114
==========================================
+ Hits 2781 2878 +97
- Misses 1197 1209 +12
- Partials 179 184 +5
Flags with carried forward coverage won't be shown. Click here to find out more.
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. |
/lgtm Or there could be another approach, defining a different error for every case. It's even more ceremony in errors definition :) but not on the caller side, and also, it's more accurate testing (e.g. you test not only the error type, but also its parameters) e.g.: type fieldGroupABOnlyOneIsSetError struct{}
func newFieldGroupABOnlyOneIsSetError() error {
return fieldGroupABOnlyOneIsSetError{}
}
func (e fieldGroupABOnlyOneIsSetError) Error() string {
return "only one of 'fieldGroupARef' and 'fieldGroupBRef' is set. They should both be set or both unset"
}
type splitABWithNoBidiError struct{ name string }
func newSplitABWithNoBidiError(name string) error {
return splitABWithNoBidiError{name}
}
func (e splitABWithNoBidiError) Error() string {
return fmt.Sprintf("output field %q has splitAB=true although bidirection is not enabled (fieldGroupARef is empty)", e.name)
}
// Etc. And on callers side: if isGroupAEmpty != isGroupBEmpty { // XOR
return newFieldGroupABOnlyOneIsSetError()
}
isBidi := !isGroupAEmpty
for _, of := range ct.OutputFields {
if of.SplitAB && !isBidi {
return newSplitABWithNoBidiError(of.Name)
} And test is like: {
"splitAB in non bidirectional configuration",
ConnTrack{
KeyDefinition: KeyDefinition{},
OutputFields: []OutputField{
{Name: "Bytes", Operation: "sum", SplitAB: true},
},
},
newSplitABWithNoBidiError("Bytes"),
}, |
pkg/api/conntrack.go
Outdated
isGroupAEmpty := ct.KeyDefinition.Hash.FieldGroupARef == "" | ||
isGroupBEmpty := ct.KeyDefinition.Hash.FieldGroupBRef == "" | ||
if isGroupAEmpty != isGroupBEmpty { // XOR | ||
return fmt.Errorf("only one of 'fieldGroupARef' and 'fieldGroupBRef' is set. They should both be set or both unset %w", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is perhaps the weird part of these errors, I would say: having to include them as "%w", and conntrackInvalidError Error()
returning an empty string
@joel Thanks for reviewing and suggesting alternatives. type conntrackInvalidError struct {
msg error
fieldGroupABOnlyOneIsSet bool
splitABWithNoBidi bool
// ...
}
func (err conntrackInvalidError) Error() string {
if err.msg != nil {
return err.msg.Error()
}
return ""
} The caller will be changed to: if isGroupAEmpty != isGroupBEmpty { // XOR
return conntrackInvalidError{fieldGroupABOnlyOneIsSet: true,
msg: fmt.Errorf("only one of 'fieldGroupARef' and 'fieldGroupBRef' is set. They should both be set or both unset")}
} And to make the test compare only the booleans and not the error messages, we can either implement func (err conntrackInvalidError) Is(target error) bool {
err.msg = nil
return err == target
} func (err conntrackInvalidError) Unwrap() error {
err.msg = nil
return err
} https://cs.opensource.google/go/go/+/refs/tags/go1.19:src/errors/wrap.go;l=40 @jotak if you stil don't like this idea, I'll go with your approach of multi error definition. 😄 |
@ronensc your suggestion looks good to me 👍 |
This PR adds validation checks to the connection tracking config.
I created an internal error type with a list of booleans to verify in the unit tests that the config under test is invalid because of the right reason. I'm not sure if this is the most idiomatic way to do this in Go. @jotak @mariomac please let me know if you have a better idea.