mirror of https://github.com/k3s-io/k3s
136 lines
3.7 KiB
Go
136 lines
3.7 KiB
Go
/*
|
|
Copyright 2016 The Kubernetes Authors.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
package aws
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
// There follows a group of tests for the backoff logic. There's nothing
|
|
// particularly special about the values chosen: if we tweak the values in the
|
|
// backoff logic then we might well have to update the tests. However the key
|
|
// behavioural elements should remain (e.g. no errors => no backoff), and these
|
|
// are each tested by one of the tests below.
|
|
|
|
// Test that we don't apply any delays when there are no errors
|
|
func TestBackoffNoErrors(t *testing.T) {
|
|
b := &Backoff{}
|
|
b.init(decayIntervalSeconds, decayFraction, maxDelay)
|
|
|
|
now := time.Now()
|
|
for i := 0; i < 100; i++ {
|
|
d := b.ComputeDelayForRequest(now)
|
|
if d.Nanoseconds() != 0 {
|
|
t.Fatalf("unexpected delay during no-error case")
|
|
}
|
|
now = now.Add(time.Second)
|
|
}
|
|
}
|
|
|
|
// Test that we always apply a delay when there are errors, and also that we
|
|
// don't "flap" - that our own delay doesn't cause us to oscillate between
|
|
// delay and no-delay.
|
|
func TestBackoffAllErrors(t *testing.T) {
|
|
b := &Backoff{}
|
|
b.init(decayIntervalSeconds, decayFraction, maxDelay)
|
|
|
|
now := time.Now()
|
|
// Warm up
|
|
for i := 0; i < 10; i++ {
|
|
_ = b.ComputeDelayForRequest(now)
|
|
b.ReportError()
|
|
now = now.Add(time.Second)
|
|
}
|
|
|
|
for i := 0; i < 100; i++ {
|
|
d := b.ComputeDelayForRequest(now)
|
|
b.ReportError()
|
|
if d.Seconds() < 5 {
|
|
t.Fatalf("unexpected short-delay during all-error case: %v", d)
|
|
}
|
|
t.Logf("delay @%d %v", i, d)
|
|
now = now.Add(d)
|
|
}
|
|
}
|
|
|
|
// Test that we do come close to our max delay, when we see all errors at 1
|
|
// second intervals (this simulates multiple concurrent requests, because we
|
|
// don't wait for delay in between requests)
|
|
func TestBackoffHitsMax(t *testing.T) {
|
|
b := &Backoff{}
|
|
b.init(decayIntervalSeconds, decayFraction, maxDelay)
|
|
|
|
now := time.Now()
|
|
for i := 0; i < 100; i++ {
|
|
_ = b.ComputeDelayForRequest(now)
|
|
b.ReportError()
|
|
now = now.Add(time.Second)
|
|
}
|
|
|
|
for i := 0; i < 10; i++ {
|
|
d := b.ComputeDelayForRequest(now)
|
|
b.ReportError()
|
|
if float32(d.Nanoseconds()) < (float32(maxDelay.Nanoseconds()) * 0.95) {
|
|
t.Fatalf("expected delay to be >= 95 percent of max delay, was %v", d)
|
|
}
|
|
t.Logf("delay @%d %v", i, d)
|
|
now = now.Add(time.Second)
|
|
}
|
|
}
|
|
|
|
// Test that after a phase of errors, we eventually stop applying a delay once there are
|
|
// no more errors.
|
|
func TestBackoffRecovers(t *testing.T) {
|
|
b := &Backoff{}
|
|
b.init(decayIntervalSeconds, decayFraction, maxDelay)
|
|
|
|
now := time.Now()
|
|
|
|
// Phase of all-errors
|
|
for i := 0; i < 100; i++ {
|
|
_ = b.ComputeDelayForRequest(now)
|
|
b.ReportError()
|
|
now = now.Add(time.Second)
|
|
}
|
|
|
|
for i := 0; i < 10; i++ {
|
|
d := b.ComputeDelayForRequest(now)
|
|
b.ReportError()
|
|
if d.Seconds() < 5 {
|
|
t.Fatalf("unexpected short-delay during all-error phase: %v", d)
|
|
}
|
|
t.Logf("error phase delay @%d %v", i, d)
|
|
now = now.Add(time.Second)
|
|
}
|
|
|
|
// Phase of no errors
|
|
for i := 0; i < 100; i++ {
|
|
_ = b.ComputeDelayForRequest(now)
|
|
now = now.Add(3 * time.Second)
|
|
}
|
|
|
|
for i := 0; i < 10; i++ {
|
|
d := b.ComputeDelayForRequest(now)
|
|
if d.Seconds() != 0 {
|
|
t.Fatalf("unexpected delay during error recovery phase: %v", d)
|
|
}
|
|
t.Logf("no-error phase delay @%d %v", i, d)
|
|
now = now.Add(time.Second)
|
|
}
|
|
}
|