feat: make jsonpath wait logics consistent with condition

Signed-off-by: jonyhy96 <hy352144278@gmail.com>
This commit is contained in:
jonyhy96 2022-06-29 12:28:24 +08:00
parent a750d8054a
commit 7a1493be56
3 changed files with 16 additions and 5 deletions

View File

@ -227,7 +227,7 @@ func conditionFuncFor(condition string, errOut io.Writer) (ConditionFunc, error)
// newJSONPathParser will create a new JSONPath parser based on the jsonPathExpression // newJSONPathParser will create a new JSONPath parser based on the jsonPathExpression
func newJSONPathParser(jsonPathExpression string) (*jsonpath.JSONPath, error) { func newJSONPathParser(jsonPathExpression string) (*jsonpath.JSONPath, error) {
j := jsonpath.New("wait") j := jsonpath.New("wait").AllowMissingKeys(true)
if jsonPathExpression == "" { if jsonPathExpression == "" {
return nil, errors.New("jsonpath expression cannot be empty") return nil, errors.New("jsonpath expression cannot be empty")
} }
@ -589,6 +589,9 @@ func (j JSONPathWait) checkCondition(obj *unstructured.Unstructured) (bool, erro
if err != nil { if err != nil {
return false, err return false, err
} }
if len(parseResults) == 0 || len(parseResults[0]) == 0 {
return false, nil
}
if err := verifyParsedJSONPath(parseResults); err != nil { if err := verifyParsedJSONPath(parseResults); err != nil {
return false, err return false, err
} }
@ -602,9 +605,6 @@ func (j JSONPathWait) checkCondition(obj *unstructured.Unstructured) (bool, erro
// verifyParsedJSONPath verifies the JSON received from the API server is valid. // verifyParsedJSONPath verifies the JSON received from the API server is valid.
// It will only accept a single JSON // It will only accept a single JSON
func verifyParsedJSONPath(results [][]reflect.Value) error { func verifyParsedJSONPath(results [][]reflect.Value) error {
if len(results) == 0 {
return errors.New("given jsonpath expression does not match any value")
}
if len(results) > 1 { if len(results) > 1 {
return errors.New("given jsonpath expression matches more than one list") return errors.New("given jsonpath expression matches more than one list")
} }

View File

@ -1173,7 +1173,7 @@ func TestWaitForDifferentJSONPathExpression(t *testing.T) {
jsonPathExp: "{.foo.bar}", jsonPathExp: "{.foo.bar}",
jsonPathCond: "baz", jsonPathCond: "baz",
expectedErr: "foo is not found", expectedErr: "timed out waiting for the condition on theresource/foo-b6699dcfb-rnv7t",
}, },
{ {
name: "compare boolean JSONPath entry", name: "compare boolean JSONPath entry",

View File

@ -35,6 +35,17 @@ run_wait_tests() {
# Post-Condition: deployments exists # Post-Condition: deployments exists
kube::test::get_object_assert "deployments" "{{range .items}}{{.metadata.name}},{{end}}" 'test-1,test-2,' kube::test::get_object_assert "deployments" "{{range .items}}{{.metadata.name}},{{end}}" 'test-1,test-2,'
# wait with jsonpath will timout for busybox deployment
set +o errexit
# Command: Wait with jsonpath support fields not exist in the first place
output_message=$(kubectl wait --for=jsonpath=.status.readyReplicas=1 deploy/test-1)
# Post-Condition: Wait failed
kube::test::if_has_string "${output_message}" 'timed out'
set -o errexit
# Delete all deployments async to kubectl wait # Delete all deployments async to kubectl wait
( sleep 2 && kubectl delete deployment --all ) & ( sleep 2 && kubectl delete deployment --all ) &