apiserver: validate borrowing for flowcontrol API

This commit is contained in:
Abu Kashem 2022-10-07 17:03:06 -04:00 committed by Mike Spreitzer
parent ca949d5188
commit c5520d6ba2
2 changed files with 99 additions and 0 deletions

View File

@ -388,6 +388,14 @@ func ValidateLimitedPriorityLevelConfiguration(lplc *flowcontrol.LimitedPriority
allErrs = append(allErrs, field.Invalid(fldPath.Child(getVersionedFieldNameForConcurrencyShares(requestGV)), lplc.NominalConcurrencyShares, "must be positive"))
}
allErrs = append(allErrs, ValidateLimitResponse(lplc.LimitResponse, fldPath.Child("limitResponse"))...)
if lplc.LendablePercent != nil && !(*lplc.LendablePercent >= 0 && *lplc.LendablePercent <= 100) {
allErrs = append(allErrs, field.Invalid(fldPath.Child("lendablePercent"), *lplc.LendablePercent, "must be between 0 and 100, inclusive"))
}
if lplc.BorrowingLimitPercent != nil && *lplc.BorrowingLimitPercent < 0 {
allErrs = append(allErrs, field.Invalid(fldPath.Child("borrowingLimitPercent"), *lplc.BorrowingLimitPercent, "if specified, must be a non-negative integer"))
}
return allErrs
}

View File

@ -17,6 +17,7 @@ limitations under the License.
package validation
import (
"fmt"
"math"
"testing"
@ -31,6 +32,7 @@ import (
"k8s.io/apimachinery/pkg/util/validation/field"
"k8s.io/apiserver/pkg/authentication/user"
"k8s.io/kubernetes/pkg/apis/flowcontrol"
"k8s.io/utils/pointer"
)
func TestFlowSchemaValidation(t *testing.T) {
@ -1434,3 +1436,92 @@ func TestValidateLimitedPriorityLevelConfiguration(t *testing.T) {
})
}
}
func TestValidateLimitedPriorityLevelConfigurationWithBorrowing(t *testing.T) {
errLendablePercentFn := func(v int32) field.ErrorList {
return field.ErrorList{
field.Invalid(field.NewPath("spec").Child("limited").Child("lendablePercent"), v, "must be between 0 and 100, inclusive"),
}
}
errBorrowingLimitPercentFn := func(v int32) field.ErrorList {
return field.ErrorList{
field.Invalid(field.NewPath("spec").Child("limited").Child("borrowingLimitPercent"), v, "if specified, must be a non-negative integer"),
}
}
makeTestNameFn := func(lendablePercent *int32, borrowingLimitPercent *int32) string {
formatFn := func(v *int32) string {
if v == nil {
return "<nil>"
}
return fmt.Sprintf("%d", *v)
}
return fmt.Sprintf("lendablePercent %s, borrowingLimitPercent %s", formatFn(lendablePercent), formatFn(borrowingLimitPercent))
}
tests := []struct {
lendablePercent *int32
borrowingLimitPercent *int32
errExpected field.ErrorList
}{
{
lendablePercent: nil,
errExpected: nil,
},
{
lendablePercent: pointer.Int32(0),
errExpected: nil,
},
{
lendablePercent: pointer.Int32(100),
errExpected: nil,
},
{
lendablePercent: pointer.Int32(101),
errExpected: errLendablePercentFn(101),
},
{
lendablePercent: pointer.Int32(-1),
errExpected: errLendablePercentFn(-1),
},
{
borrowingLimitPercent: nil,
errExpected: nil,
},
{
borrowingLimitPercent: pointer.Int32(1),
errExpected: nil,
},
{
borrowingLimitPercent: pointer.Int32(100),
errExpected: nil,
},
{
borrowingLimitPercent: pointer.Int32(0),
errExpected: nil,
},
{
borrowingLimitPercent: pointer.Int32(-1),
errExpected: errBorrowingLimitPercentFn(-1),
},
}
for _, test := range tests {
t.Run(makeTestNameFn(test.lendablePercent, test.borrowingLimitPercent), func(t *testing.T) {
configuration := &flowcontrol.LimitedPriorityLevelConfiguration{
NominalConcurrencyShares: 1,
LimitResponse: flowcontrol.LimitResponse{
Type: flowcontrol.LimitResponseTypeReject,
},
LendablePercent: test.lendablePercent,
BorrowingLimitPercent: test.borrowingLimitPercent,
}
specPath := field.NewPath("spec").Child("limited")
errGot := ValidateLimitedPriorityLevelConfiguration(configuration, flowcontrolv1beta3.SchemeGroupVersion, specPath)
if !cmp.Equal(test.errExpected, errGot) {
t.Errorf("Expected error: %v, diff: %s", test.errExpected, cmp.Diff(test.errExpected, errGot))
}
})
}
}