Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
4097cfe0
Commit
4097cfe0
authored
Feb 24, 2016
by
jay vyas
Committed by
Jay Vyas
Feb 24, 2016
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fake backoff implementation for speeding up flakey test, fake Clock Test for sleep
parent
b9cc1282
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
61 additions
and
21 deletions
+61
-21
request.go
pkg/client/unversioned/request.go
+4
-4
request_test.go
pkg/client/unversioned/request_test.go
+16
-7
urlbackoff.go
pkg/client/unversioned/urlbackoff.go
+9
-1
backoff.go
pkg/util/backoff.go
+9
-0
backoff_test.go
pkg/util/backoff_test.go
+0
-9
clock.go
pkg/util/clock.go
+13
-0
clock_test.go
pkg/util/clock_test.go
+10
-0
No files found.
pkg/client/unversioned/request.go
View file @
4097cfe0
...
...
@@ -645,7 +645,7 @@ func (r *Request) Watch() (watch.Interface, error) {
if
client
==
nil
{
client
=
http
.
DefaultClient
}
time
.
Sleep
(
r
.
backoffMgr
.
CalculateBackoff
(
r
.
URL
()))
r
.
backoffMgr
.
Sleep
(
r
.
backoffMgr
.
CalculateBackoff
(
r
.
URL
()))
resp
,
err
:=
client
.
Do
(
req
)
updateURLMetrics
(
r
,
resp
,
err
)
if
r
.
baseURL
!=
nil
{
...
...
@@ -710,7 +710,7 @@ func (r *Request) Stream() (io.ReadCloser, error) {
if
client
==
nil
{
client
=
http
.
DefaultClient
}
time
.
Sleep
(
r
.
backoffMgr
.
CalculateBackoff
(
r
.
URL
()))
r
.
backoffMgr
.
Sleep
(
r
.
backoffMgr
.
CalculateBackoff
(
r
.
URL
()))
resp
,
err
:=
client
.
Do
(
req
)
updateURLMetrics
(
r
,
resp
,
err
)
if
r
.
baseURL
!=
nil
{
...
...
@@ -792,7 +792,7 @@ func (r *Request) request(fn func(*http.Request, *http.Response)) error {
}
req
.
Header
=
r
.
headers
time
.
Sleep
(
r
.
backoffMgr
.
CalculateBackoff
(
r
.
URL
()))
r
.
backoffMgr
.
Sleep
(
r
.
backoffMgr
.
CalculateBackoff
(
r
.
URL
()))
resp
,
err
:=
client
.
Do
(
req
)
updateURLMetrics
(
r
,
resp
,
err
)
if
err
!=
nil
{
...
...
@@ -812,7 +812,7 @@ func (r *Request) request(fn func(*http.Request, *http.Response)) error {
retries
++
if
seconds
,
wait
:=
checkWait
(
resp
);
wait
&&
retries
<
maxRetries
{
glog
.
V
(
4
)
.
Infof
(
"Got a Retry-After %s response for attempt %d to %v"
,
seconds
,
retries
,
url
)
time
.
Sleep
(
time
.
Duration
(
seconds
)
*
time
.
Second
)
r
.
backoffMgr
.
Sleep
(
time
.
Duration
(
seconds
)
*
time
.
Second
)
return
false
}
fn
(
req
,
resp
)
...
...
pkg/client/unversioned/request_test.go
View file @
4097cfe0
...
...
@@ -767,17 +767,26 @@ func TestBackoffLifecycle(t *testing.T) {
// which are used in the server implementation returning StatusOK above.
seconds
:=
[]
int
{
0
,
1
,
2
,
4
,
8
,
0
,
1
,
2
,
4
,
0
}
request
:=
c
.
Verb
(
"POST"
)
.
Prefix
(
"backofftest"
)
.
Suffix
(
"abc"
)
clock
:=
util
.
FakeClock
{}
request
.
backoffMgr
=
&
URLBackoff
{
Backoff
:
util
.
NewBackOff
(
// Use a fake backoff here to avoid flakes and speed the test up.
Backoff
:
util
.
NewFakeBackOff
(
time
.
Duration
(
1
)
*
time
.
Second
,
time
.
Duration
(
200
)
*
time
.
Second
)}
time
.
Duration
(
200
)
*
time
.
Second
,
&
clock
,
)}
for
_
,
sec
:=
range
seconds
{
start
:=
time
.
Now
()
thisBackoff
:=
request
.
backoffMgr
.
CalculateBackoff
(
request
.
URL
())
t
.
Logf
(
"Current backoff %v"
,
thisBackoff
)
if
thisBackoff
!=
time
.
Duration
(
sec
)
*
time
.
Second
{
t
.
Errorf
(
"Backoff is %v instead of %v"
,
thisBackoff
,
sec
)
}
now
:=
clock
.
Now
()
request
.
DoRaw
()
finish
:=
time
.
Since
(
start
)
t
.
Logf
(
"%v finished in %v"
,
sec
,
finish
)
if
finish
<
time
.
Duration
(
sec
)
*
time
.
Second
||
finish
>=
time
.
Duration
(
sec
+
5
)
*
time
.
Second
{
t
.
Fatalf
(
"%v not in range %v"
,
finish
,
sec
)
elapsed
:=
clock
.
Since
(
now
)
if
clock
.
Since
(
now
)
!=
thisBackoff
{
t
.
Errorf
(
"CalculatedBackoff not honored by clock: Expected time of %v, but got %v "
,
thisBackoff
,
elapsed
)
}
}
}
...
...
pkg/client/unversioned/urlbackoff.go
View file @
4097cfe0
...
...
@@ -35,6 +35,7 @@ var maxResponseCode = 499
type
BackoffManager
interface
{
UpdateBackoff
(
actualUrl
*
url
.
URL
,
err
error
,
responseCode
int
)
CalculateBackoff
(
actualUrl
*
url
.
URL
)
time
.
Duration
Sleep
(
d
time
.
Duration
)
}
// URLBackoff struct implements the semantics on top of Backoff which
...
...
@@ -54,6 +55,9 @@ func (n *NoBackoff) UpdateBackoff(actualUrl *url.URL, err error, responseCode in
func
(
n
*
NoBackoff
)
CalculateBackoff
(
actualUrl
*
url
.
URL
)
time
.
Duration
{
return
0
*
time
.
Second
}
func
(
n
*
NoBackoff
)
Sleep
(
d
time
.
Duration
)
{
return
}
// Disable makes the backoff trivial, i.e., sets it to zero. This might be used
// by tests which want to run 1000s of mock requests without slowing down.
...
...
@@ -80,7 +84,7 @@ func (b *URLBackoff) baseUrlKey(rawurl *url.URL) string {
func
(
b
*
URLBackoff
)
UpdateBackoff
(
actualUrl
*
url
.
URL
,
err
error
,
responseCode
int
)
{
// range for retry counts that we store is [0,13]
if
responseCode
>
maxResponseCode
||
serverIsOverloadedSet
.
Has
(
responseCode
)
{
b
.
Backoff
.
Next
(
b
.
baseUrlKey
(
actualUrl
),
time
.
Now
())
b
.
Backoff
.
Next
(
b
.
baseUrlKey
(
actualUrl
),
b
.
Backoff
.
Clock
.
Now
())
return
}
else
if
responseCode
>=
300
||
err
!=
nil
{
glog
.
V
(
4
)
.
Infof
(
"Client is returning errors: code %v, error %v"
,
responseCode
,
err
)
...
...
@@ -95,3 +99,7 @@ func (b *URLBackoff) UpdateBackoff(actualUrl *url.URL, err error, responseCode i
func
(
b
*
URLBackoff
)
CalculateBackoff
(
actualUrl
*
url
.
URL
)
time
.
Duration
{
return
b
.
Backoff
.
Get
(
b
.
baseUrlKey
(
actualUrl
))
}
func
(
b
*
URLBackoff
)
Sleep
(
d
time
.
Duration
)
{
b
.
Backoff
.
Clock
.
Sleep
(
d
)
}
pkg/util/backoff.go
View file @
4097cfe0
...
...
@@ -36,6 +36,15 @@ type Backoff struct {
perItemBackoff
map
[
string
]
*
backoffEntry
}
func
NewFakeBackOff
(
initial
,
max
time
.
Duration
,
tc
*
FakeClock
)
*
Backoff
{
return
&
Backoff
{
perItemBackoff
:
map
[
string
]
*
backoffEntry
{},
Clock
:
tc
,
defaultDuration
:
initial
,
maxDuration
:
max
,
}
}
func
NewBackOff
(
initial
,
max
time
.
Duration
)
*
Backoff
{
return
&
Backoff
{
perItemBackoff
:
map
[
string
]
*
backoffEntry
{},
...
...
pkg/util/backoff_test.go
View file @
4097cfe0
...
...
@@ -21,15 +21,6 @@ import (
"time"
)
func
NewFakeBackOff
(
initial
,
max
time
.
Duration
,
tc
*
FakeClock
)
*
Backoff
{
return
&
Backoff
{
perItemBackoff
:
map
[
string
]
*
backoffEntry
{},
Clock
:
tc
,
defaultDuration
:
initial
,
maxDuration
:
max
,
}
}
func
TestSlowBackoff
(
t
*
testing
.
T
)
{
id
:=
"_idSlow"
tc
:=
NewFakeClock
(
time
.
Now
())
...
...
pkg/util/clock.go
View file @
4097cfe0
...
...
@@ -27,6 +27,7 @@ type Clock interface {
Now
()
time
.
Time
Since
(
time
.
Time
)
time
.
Duration
After
(
d
time
.
Duration
)
<-
chan
time
.
Time
Sleep
(
d
time
.
Duration
)
}
var
(
...
...
@@ -53,6 +54,10 @@ func (RealClock) After(d time.Duration) <-chan time.Time {
return
time
.
After
(
d
)
}
func
(
RealClock
)
Sleep
(
d
time
.
Duration
)
{
time
.
Sleep
(
d
)
}
// FakeClock implements Clock, but returns an arbitrary time.
type
FakeClock
struct
{
lock
sync
.
RWMutex
...
...
@@ -137,6 +142,10 @@ func (f *FakeClock) HasWaiters() bool {
return
len
(
f
.
waiters
)
>
0
}
func
(
f
*
FakeClock
)
Sleep
(
d
time
.
Duration
)
{
f
.
Step
(
d
)
}
// IntervalClock implements Clock, but each invocation of Now steps the clock forward the specified duration
type
IntervalClock
struct
{
Time
time
.
Time
...
...
@@ -159,3 +168,7 @@ func (i *IntervalClock) Since(ts time.Time) time.Duration {
func
(
*
IntervalClock
)
After
(
d
time
.
Duration
)
<-
chan
time
.
Time
{
panic
(
"IntervalClock doesn't implement After"
)
}
func
(
*
IntervalClock
)
Sleep
(
d
time
.
Duration
)
{
panic
(
"IntervalClock doesn't implement Sleep"
)
}
pkg/util/clock_test.go
View file @
4097cfe0
...
...
@@ -37,6 +37,16 @@ func TestFakeClock(t *testing.T) {
}
}
func
TestFakeClockSleep
(
t
*
testing
.
T
)
{
startTime
:=
time
.
Now
()
tc
:=
NewFakeClock
(
startTime
)
tc
.
Sleep
(
time
.
Duration
(
1
)
*
time
.
Hour
)
now
:=
tc
.
Now
()
if
now
.
Sub
(
startTime
)
!=
time
.
Hour
{
t
.
Errorf
(
"Fake sleep failed, expected time to advance by one hour, instead, its %v"
,
now
.
Sub
(
startTime
))
}
}
func
TestFakeAfter
(
t
*
testing
.
T
)
{
tc
:=
NewFakeClock
(
time
.
Now
())
if
tc
.
HasWaiters
()
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment