-
Notifications
You must be signed in to change notification settings - Fork 103
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
Updated object specs to pass tests #27
Conversation
runyontr
commented
Dec 4, 2018
@fabianbaier did this fix what you were asking for? |
} | ||
|
||
//Phase specifies a list of steps that contain Kubernetes objects. | ||
type Phase struct { | ||
Name string `json:"name"` | ||
Strategy Ordering `json:"strategy"` | ||
Name string `json:"name" validate:"required,gt=0"` // makes field mandatory and checks if set and non empty |
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.
should we make this a pointer? *string
//Phases maps a phase name to a Phase object | ||
Phases []Phase `json:"phases"` | ||
Phases []Phase `json:"phases" validate:"gt=0,dive"` // makes field mandatory and checks if its gt 0 |
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.
[]*Phase
?
//Steps maps a step name to a list of mustached kubernetes objects stored as a string | ||
Steps []Step `json:"steps"` | ||
Steps []Step `json:"steps" validate:"gt=0,dive"` // makes field mandatory and checks if its gt 0 |
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.
[]*Steps
?
} | ||
|
||
type Step struct { | ||
Name string `json:"name"` | ||
Mustache string `json:"mustache"` | ||
Name string `json:"name" validate:"required,gt=0"` // makes field mandatory and checks if set and non empty |
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.
*string
?
Name string `json:"name"` | ||
Mustache string `json:"mustache"` | ||
Name string `json:"name" validate:"required,gt=0"` // makes field mandatory and checks if set and non empty | ||
Mustache string `json:"mustache" validate:"required,gt=0"` // makes field mandatory and checks if set and non empty |
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.
*string
?
//Objects will be serialized for each instance as the params and defaults | ||
// are provided | ||
Objects []runtime.Object `json:"-"` | ||
Objects []runtime.Object `json:"-"` // no checks needed |
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.
Is this optional or mandatory?
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.
Your part looks good 👍
I pushed the logic changes for my part with some comments to look at.
"ServiceSpec.Pods[pod2].HostVolumes[].HostPath:required: cannot be <nil>", | ||
"ServiceSpec.Pods[pod2].HostVolumes[].ContainerPath:required: cannot be <nil>", | ||
"ServiceSpec.Plans[]:required: cannot be empty", | ||
"ServiceSpec.Plans[].Strategy:required: cannot be ", |
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.
because we have no pointer we cannot tell the difference of something being set or with its zeroValue.
# Conflicts: # config/crds/kudo_v1alpha1_instance.yaml # config/crds/maestro_v1alpha1_instance.yaml # pkg/apis/kudo/v1alpha1/frameworkversion_types.go # pkg/apis/kudo/v1alpha1/planexecution_types.go
This LGTM for now. Lets make sure we make a ticket addressing adding tests for validation for Plans, and FVs. |
Awesome! Can I get your approval so I am able to merge it? |
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.
lgtm
//Phases maps a phase name to a Phase object | ||
Phases []Phase `json:"phases"` | ||
Phases []Phase `json:"phases" validate:"gt=0,dive"` // makes field mandatory and checks if its gt 0 |
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.
Is this dive needed? It feels weird at the end of the chain?
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.
Should that field be required
?
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.
Is this dive needed? It feels weird at the end of the chain?
Phases []Phase 'json:"phases" validate:"gt=0,dive"'
GreaterThan looks at the slice and ensures it has at least one item - it doesn't check if its an empty item or anything else with the item is wrong. Therefor we have dive
.
Dive is used here to ensure that the values of the Phase
struct will be validated after its validate tags. If I leave dive
out here what happens it just looks at the slice, but I need it one level deeper. The test would fail as each Phase
item in the slice wouldn't be validated anymore:
=== RUN TestFrameworkType_Validation
--- FAIL: TestFrameworkType_Validation (0.00s)
frameworkversion_types_test.go:408: Missed expected error: ServiceSpec.Plans[plan2].Phases[0].Name:required: cannot be empty
frameworkversion_types_test.go:408: Missed expected error: ServiceSpec.Plans[plan2].Phases[0].Strategy:required: cannot be
frameworkversion_types_test.go:408: Missed expected error: ServiceSpec.Plans[plan2].Phases[0].Steps:gt: cannot be []
frameworkversion_types_test.go:408: Missed expected error: ServiceSpec.Plans[plan2].Phases[1].Steps[0].Name:required: cannot be empty
frameworkversion_types_test.go:408: Missed expected error: ServiceSpec.Plans[plan2].Phases[1].Steps[0].Tasks:required: cannot be []
frameworkversion_types_test.go:408: Missed expected error: ServiceSpec.Plans[plan2].Phases[1].Steps[1].Tasks[0]:gt: cannot be empty
FAIL
You don't find at the end of the chain dives
in the official examples because they deal already with the final string data type. E.g.
[][]string with validation tag "gt=0,dive,len=1,dive,required"
// gt=0 will be applied to []
// len=1 will be applied to []string
// required will be applied to string
There is no nested level in string
so that is why after dive
a required
is applied to the string type. Without the dive
tag required
would just be applied to []string
. While it says for validate.Struct that it will automatically validate nested structs I noticed the opposite. I filed already an issue with go-playground/validator#458 but for the desired outcome it requires us right now to use dive
at the end to kick off the validation of a nested struct imo.
I intended to make the validation tests more consistent. This isnt in any way an attempt to be perfect. I am sure we will find some oversight. For now the tests pass though. With f58f998 comes this gist Validation Lexicon that I used to explain the various different appearances and how to validate them. Hope this gets |