Skip to content

Commit

Permalink
fix(kumactl) backoff durations validation (#1352) (#1353)
Browse files Browse the repository at this point in the history
There were two bugs, one was happening when there was only seconds in
timeout durations provided (`1s`) as the validator was not checking if
seconds are provided and assuming that if nanoseconds field is empty, it
means the value is equal 0 and then rejecting valid values.

The second bug was that we were not validating `maxInterval` values of
the backOff properties

Signed-off-by: Bart Smykla <[email protected]>
(cherry picked from commit a7c1f39)

Co-authored-by: Bart Smykla <[email protected]>
  • Loading branch information
mergify[bot] and bartsmykla authored Dec 22, 2020
1 parent 70ac31e commit 4a31b15
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 7 deletions.
21 changes: 14 additions & 7 deletions pkg/core/resources/apis/mesh/retry_validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ func validateDuration_GreaterThan0(
path validators.PathBuilder,
duration *duration.Duration,
) (err validators.ValidationError) {
if duration.Nanos == 0 {
if duration.Seconds == 0 && duration.Nanos == 0 {
err.AddViolationAt(path, HasToBeGreaterThan0Violation)
}

Expand All @@ -121,7 +121,7 @@ func validateDuration_GreaterThan0OrNil(
return
}

if duration.Nanos == 0 {
if duration.Seconds == 0 && duration.Nanos == 0 {
err.AddViolationAt(path, WhenDefinedHasToBeGreaterThan0Violation)
}

Expand All @@ -141,11 +141,18 @@ func validateConfProtocolBackOff(
path.Field("baseInterval"),
HasToBeDefinedViolation,
)
} else if conf.BaseInterval.Nanos == 0 {
err.Add(validateDuration_GreaterThan0(
path.Field("baseInterval"),
conf.BaseInterval,
))
} else {
if conf.BaseInterval.Seconds == 0 && conf.BaseInterval.Nanos == 0 {
err.Add(validateDuration_GreaterThan0(
path.Field("baseInterval"),
conf.BaseInterval,
))
} else {
err.Add(validateDuration_GreaterThan0OrNil(
path.Field("maxInterval"),
conf.MaxInterval,
))
}
}

return
Expand Down
74 changes: 74 additions & 0 deletions pkg/core/resources/apis/mesh/retry_validator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ var _ = Describe("Retry", func() {
retry string
expected string
}

type testCaseWithNoErrors struct {
retry string
}

DescribeTable("should validate all fields and return as much individual errors as possible",
func(given testCase) {
// setup
Expand Down Expand Up @@ -233,6 +238,27 @@ var _ = Describe("Retry", func() {
violations:
- field: conf.grpc.backOff.baseInterval
message: has to be greater than 0
`,
}),
Entry("conf.grpc.backOff.maxInterval equal 0s", testCase{
retry: `
sources:
- match:
kuma.io/service: web
region: eu
destinations:
- match:
kuma.io/service: backend
conf:
grpc:
backOff:
baseInterval: 20ms
maxInterval: 0s
`,
expected: `
violations:
- field: conf.grpc.backOff.maxInterval
message: has to be greater than 0 when defined
`,
}),
Entry("empty conf.tcp", testCase{
Expand All @@ -251,6 +277,54 @@ var _ = Describe("Retry", func() {
violations:
- field: conf.tcp.maxConnectAttempts
message: has to be greater than 0
`,
}),
)

DescribeTable("should validate all fields and return no errors if all are valid",
func(given testCaseWithNoErrors) {
// setup
retry := NewRetryResource()

// when
err := util_proto.FromYAML([]byte(given.retry), retry.Spec)
// then
Expect(err).ToNot(HaveOccurred())

// when
verr := retry.Validate()

// then
Expect(verr).To(BeNil())
},
Entry("all protocols configuration provided", testCaseWithNoErrors{
retry: `
sources:
- match:
kuma.io/service: web
region: eu
destinations:
- match:
kuma.io/service: backend
conf:
http:
numRetries: 3
perTryTimeout: 200ms
backOff:
baseInterval: 30ms
maxInterval: 1.2s
retriableStatusCodes: [501, 502]
grpc:
numRetries: 3
perTryTimeout: 200ms
backOff:
baseInterval: 58ms
maxInterval: 1s
retryOn:
- cancelled
- unavailable
tcp:
maxConnectAttempts: 5
`,
}),
)
Expand Down

0 comments on commit 4a31b15

Please sign in to comment.