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
f50696ad
Commit
f50696ad
authored
Apr 11, 2019
by
Joel Smith
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix potential test flakes in HPA tests TestEventNotCreated and TestAvoidUncessaryUpdates
Also, re-work the code so that the lock is never held while writing to the chan
parent
0889c3e4
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
68 additions
and
50 deletions
+68
-50
horizontal_test.go
pkg/controller/podautoscaler/horizontal_test.go
+53
-38
legacy_horizontal_test.go
pkg/controller/podautoscaler/legacy_horizontal_test.go
+15
-12
No files found.
pkg/controller/podautoscaler/horizontal_test.go
View file @
f50696ad
...
@@ -330,38 +330,43 @@ func (tc *testCase) prepareTestClient(t *testing.T) (*fake.Clientset, *metricsfa
...
@@ -330,38 +330,43 @@ func (tc *testCase) prepareTestClient(t *testing.T) (*fake.Clientset, *metricsfa
})
})
fakeClient
.
AddReactor
(
"update"
,
"horizontalpodautoscalers"
,
func
(
action
core
.
Action
)
(
handled
bool
,
ret
runtime
.
Object
,
err
error
)
{
fakeClient
.
AddReactor
(
"update"
,
"horizontalpodautoscalers"
,
func
(
action
core
.
Action
)
(
handled
bool
,
ret
runtime
.
Object
,
err
error
)
{
tc
.
Lock
()
handled
,
obj
,
err
:=
func
()
(
handled
bool
,
ret
*
autoscalingv1
.
HorizontalPodAutoscaler
,
err
error
)
{
defer
tc
.
Unlock
()
tc
.
Lock
()
defer
tc
.
Unlock
()
obj
:=
action
.
(
core
.
UpdateAction
)
.
GetObject
()
.
(
*
autoscalingv1
.
HorizontalPodAutoscaler
)
assert
.
Equal
(
t
,
namespace
,
obj
.
Namespace
,
"the HPA namespace should be as expected"
)
obj
:=
action
.
(
core
.
UpdateAction
)
.
GetObject
()
.
(
*
autoscalingv1
.
HorizontalPodAutoscaler
)
assert
.
Equal
(
t
,
hpaName
,
obj
.
Name
,
"the HPA name should be as expected"
)
assert
.
Equal
(
t
,
namespace
,
obj
.
Namespace
,
"the HPA namespace should be as expected"
)
assert
.
Equal
(
t
,
tc
.
expectedDesiredReplicas
,
obj
.
Status
.
DesiredReplicas
,
"the desired replica count reported in the object status should be as expected"
)
assert
.
Equal
(
t
,
hpaName
,
obj
.
Name
,
"the HPA name should be as expected"
)
if
tc
.
verifyCPUCurrent
{
assert
.
Equal
(
t
,
tc
.
expectedDesiredReplicas
,
obj
.
Status
.
DesiredReplicas
,
"the desired replica count reported in the object status should be as expected"
)
if
assert
.
NotNil
(
t
,
obj
.
Status
.
CurrentCPUUtilizationPercentage
,
"the reported CPU utilization percentage should be non-nil"
)
{
if
tc
.
verifyCPUCurrent
{
assert
.
Equal
(
t
,
tc
.
CPUCurrent
,
*
obj
.
Status
.
CurrentCPUUtilizationPercentage
,
"the report CPU utilization percentage should be as expected"
)
if
assert
.
NotNil
(
t
,
obj
.
Status
.
CurrentCPUUtilizationPercentage
,
"the reported CPU utilization percentage should be non-nil"
)
{
assert
.
Equal
(
t
,
tc
.
CPUCurrent
,
*
obj
.
Status
.
CurrentCPUUtilizationPercentage
,
"the report CPU utilization percentage should be as expected"
)
}
}
}
var
actualConditions
[]
autoscalingv1
.
HorizontalPodAutoscalerCondition
if
err
:=
json
.
Unmarshal
([]
byte
(
obj
.
ObjectMeta
.
Annotations
[
autoscaling
.
HorizontalPodAutoscalerConditionsAnnotation
]),
&
actualConditions
);
err
!=
nil
{
return
true
,
nil
,
err
}
// TODO: it's ok not to sort these becaues statusOk
// contains all the conditions, so we'll never be appending.
// Default to statusOk when missing any specific conditions
if
tc
.
expectedConditions
==
nil
{
tc
.
expectedConditions
=
statusOkWithOverrides
()
}
// clear the message so that we can easily compare
for
i
:=
range
actualConditions
{
actualConditions
[
i
]
.
Message
=
""
actualConditions
[
i
]
.
LastTransitionTime
=
metav1
.
Time
{}
}
assert
.
Equal
(
t
,
tc
.
expectedConditions
,
actualConditions
,
"the status conditions should have been as expected"
)
tc
.
statusUpdated
=
true
// Every time we reconcile HPA object we are updating status.
return
true
,
obj
,
nil
}()
if
obj
!=
nil
{
tc
.
processed
<-
obj
.
Name
}
}
var
actualConditions
[]
autoscalingv1
.
HorizontalPodAutoscalerCondition
return
handled
,
obj
,
err
if
err
:=
json
.
Unmarshal
([]
byte
(
obj
.
ObjectMeta
.
Annotations
[
autoscaling
.
HorizontalPodAutoscalerConditionsAnnotation
]),
&
actualConditions
);
err
!=
nil
{
return
true
,
nil
,
err
}
// TODO: it's ok not to sort these becaues statusOk
// contains all the conditions, so we'll never be appending.
// Default to statusOk when missing any specific conditions
if
tc
.
expectedConditions
==
nil
{
tc
.
expectedConditions
=
statusOkWithOverrides
()
}
// clear the message so that we can easily compare
for
i
:=
range
actualConditions
{
actualConditions
[
i
]
.
Message
=
""
actualConditions
[
i
]
.
LastTransitionTime
=
metav1
.
Time
{}
}
assert
.
Equal
(
t
,
tc
.
expectedConditions
,
actualConditions
,
"the status conditions should have been as expected"
)
tc
.
statusUpdated
=
true
// Every time we reconcile HPA object we are updating status.
tc
.
processed
<-
obj
.
Name
return
true
,
obj
,
nil
})
})
fakeScaleClient
:=
&
scalefake
.
FakeScaleClient
{}
fakeScaleClient
:=
&
scalefake
.
FakeScaleClient
{}
...
@@ -701,15 +706,25 @@ func (tc *testCase) runTestWithController(t *testing.T, hpaController *Horizonta
...
@@ -701,15 +706,25 @@ func (tc *testCase) runTestWithController(t *testing.T, hpaController *Horizonta
go
hpaController
.
Run
(
stop
)
go
hpaController
.
Run
(
stop
)
tc
.
Lock
()
tc
.
Lock
()
if
tc
.
verifyEvents
{
shouldWait
:=
tc
.
verifyEvents
tc
.
Unlock
()
tc
.
Unlock
()
if
shouldWait
{
// We need to wait for events to be broadcasted (sleep for longer than record.sleepDuration).
// We need to wait for events to be broadcasted (sleep for longer than record.sleepDuration).
time
.
Sleep
(
2
*
time
.
Second
)
timeoutTime
:=
time
.
Now
()
.
Add
(
2
*
time
.
Second
)
for
now
:=
time
.
Now
();
timeoutTime
.
After
(
now
);
now
=
time
.
Now
()
{
sleepUntil
:=
timeoutTime
.
Sub
(
now
)
select
{
case
<-
tc
.
processed
:
// drain the chan of any sent events to keep it from filling before the timeout
case
<-
time
.
After
(
sleepUntil
)
:
// timeout reached, ready to verifyResults
}
}
}
else
{
}
else
{
tc
.
Unlock
()
// Wait for HPA to be processed.
<-
tc
.
processed
}
}
// Wait for HPA to be processed.
<-
tc
.
processed
tc
.
verifyResults
(
t
)
tc
.
verifyResults
(
t
)
}
}
...
@@ -2418,7 +2433,9 @@ func TestAvoidUncessaryUpdates(t *testing.T) {
...
@@ -2418,7 +2433,9 @@ func TestAvoidUncessaryUpdates(t *testing.T) {
// wait a tick and then mark that we're finished (otherwise, we have no
// wait a tick and then mark that we're finished (otherwise, we have no
// way to indicate that we're finished, because the function decides not to do anything)
// way to indicate that we're finished, because the function decides not to do anything)
time
.
Sleep
(
1
*
time
.
Second
)
time
.
Sleep
(
1
*
time
.
Second
)
tc
.
Lock
()
tc
.
statusUpdated
=
true
tc
.
statusUpdated
=
true
tc
.
Unlock
()
tc
.
processed
<-
"test-hpa"
tc
.
processed
<-
"test-hpa"
}()
}()
...
@@ -2493,8 +2510,6 @@ func TestAvoidUncessaryUpdates(t *testing.T) {
...
@@ -2493,8 +2510,6 @@ func TestAvoidUncessaryUpdates(t *testing.T) {
return
true
,
objv1
,
nil
return
true
,
objv1
,
nil
})
})
testClient
.
PrependReactor
(
"update"
,
"horizontalpodautoscalers"
,
func
(
action
core
.
Action
)
(
handled
bool
,
ret
runtime
.
Object
,
err
error
)
{
testClient
.
PrependReactor
(
"update"
,
"horizontalpodautoscalers"
,
func
(
action
core
.
Action
)
(
handled
bool
,
ret
runtime
.
Object
,
err
error
)
{
tc
.
Lock
()
defer
tc
.
Unlock
()
assert
.
Fail
(
t
,
"should not have attempted to update the HPA when nothing changed"
)
assert
.
Fail
(
t
,
"should not have attempted to update the HPA when nothing changed"
)
// mark that we've processed this HPA
// mark that we've processed this HPA
tc
.
processed
<-
""
tc
.
processed
<-
""
...
...
pkg/controller/podautoscaler/legacy_horizontal_test.go
View file @
f50696ad
...
@@ -332,19 +332,22 @@ func (tc *legacyTestCase) prepareTestClient(t *testing.T) (*fake.Clientset, *sca
...
@@ -332,19 +332,22 @@ func (tc *legacyTestCase) prepareTestClient(t *testing.T) (*fake.Clientset, *sca
})
})
fakeClient
.
AddReactor
(
"update"
,
"horizontalpodautoscalers"
,
func
(
action
core
.
Action
)
(
handled
bool
,
ret
runtime
.
Object
,
err
error
)
{
fakeClient
.
AddReactor
(
"update"
,
"horizontalpodautoscalers"
,
func
(
action
core
.
Action
)
(
handled
bool
,
ret
runtime
.
Object
,
err
error
)
{
tc
.
Lock
()
obj
:=
func
()
*
autoscalingv1
.
HorizontalPodAutoscaler
{
defer
tc
.
Unlock
()
tc
.
Lock
()
defer
tc
.
Unlock
()
obj
:=
action
.
(
core
.
UpdateAction
)
.
GetObject
()
.
(
*
autoscalingv1
.
HorizontalPodAutoscaler
)
assert
.
Equal
(
t
,
namespace
,
obj
.
Namespace
,
"the HPA namespace should be as expected"
)
obj
:=
action
.
(
core
.
UpdateAction
)
.
GetObject
()
.
(
*
autoscalingv1
.
HorizontalPodAutoscaler
)
assert
.
Equal
(
t
,
hpaName
,
obj
.
Name
,
"the HPA name should be as expected"
)
assert
.
Equal
(
t
,
namespace
,
obj
.
Namespace
,
"the HPA namespace should be as expected"
)
assert
.
Equal
(
t
,
tc
.
desiredReplicas
,
obj
.
Status
.
DesiredReplicas
,
"the desired replica count reported in the object status should be as expected"
)
assert
.
Equal
(
t
,
hpaName
,
obj
.
Name
,
"the HPA name should be as expected"
)
if
tc
.
verifyCPUCurrent
{
assert
.
Equal
(
t
,
tc
.
desiredReplicas
,
obj
.
Status
.
DesiredReplicas
,
"the desired replica count reported in the object status should be as expected"
)
if
assert
.
NotNil
(
t
,
obj
.
Status
.
CurrentCPUUtilizationPercentage
,
"the reported CPU utilization percentage should be non-nil"
)
{
if
tc
.
verifyCPUCurrent
{
assert
.
Equal
(
t
,
tc
.
CPUCurrent
,
*
obj
.
Status
.
CurrentCPUUtilizationPercentage
,
"the report CPU utilization percentage should be as expected"
)
if
assert
.
NotNil
(
t
,
obj
.
Status
.
CurrentCPUUtilizationPercentage
,
"the reported CPU utilization percentage should be non-nil"
)
{
assert
.
Equal
(
t
,
tc
.
CPUCurrent
,
*
obj
.
Status
.
CurrentCPUUtilizationPercentage
,
"the report CPU utilization percentage should be as expected"
)
}
}
}
}
tc
.
statusUpdated
=
true
tc
.
statusUpdated
=
true
return
obj
}()
// Every time we reconcile HPA object we are updating status.
// Every time we reconcile HPA object we are updating status.
tc
.
processed
<-
obj
.
Name
tc
.
processed
<-
obj
.
Name
return
true
,
obj
,
nil
return
true
,
obj
,
nil
...
...
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