Skip to content

Commit 3f86aa6

Browse files
committed
Fix update of uneeded threshold
1 parent dffccf2 commit 3f86aa6

File tree

2 files changed

+54
-6
lines changed

2 files changed

+54
-6
lines changed

cluster-autoscaler/core/scaledown/unneeded/nodes.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -136,12 +136,12 @@ func (n *Nodes) updateInternalState(autoscalingCtx *ca_context.AutoscalingContex
136136

137137
val, found := n.byName[name]
138138
if found {
139-
updated[name] = &node{
140-
ntbr: nn,
141-
since: val.since,
142-
removalThreshold: val.removalThreshold,
143-
thresholdRetrievalFailed: val.thresholdRetrievalFailed,
139+
newNodeState := &node{
140+
ntbr: nn,
141+
since: val.since,
144142
}
143+
n.lookupAndSetRemovalThreshold(newNodeState, autoscalingCtx.CloudProvider)
144+
updated[name] = newNodeState
145145
} else {
146146
updated[name] = n.newNode(nn, timestampGetter, ts, autoscalingCtx.CloudProvider)
147147
}

cluster-autoscaler/core/scaledown/unneeded/nodes_test.go

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ const (
4444
defaultNodeCpu = 10
4545
defaultNodeMem = 100
4646
defaultNodeGroupMaxSize = 100
47+
defaultUnneededTime = 10 * time.Minute
48+
defaultUnreadyTime = 5 * time.Minute
4749
)
4850

4951
func TestUpdate(t *testing.T) {
@@ -55,6 +57,7 @@ func TestUpdate(t *testing.T) {
5557
finalNodes []simulator.NodeToBeRemoved
5658
wantTimestamps map[string]time.Time
5759
wantVersions map[string]string
60+
wantThresholds map[string]time.Duration
5861
}{
5962
{
6063
desc: "added then deleted",
@@ -75,6 +78,7 @@ func TestUpdate(t *testing.T) {
7578
},
7679
wantTimestamps: map[string]time.Time{"n1": finalTimestamp, "n2": finalTimestamp, "n3": finalTimestamp},
7780
wantVersions: map[string]string{"n1": "v1", "n2": "v1", "n3": "v1"},
81+
wantThresholds: map[string]time.Duration{"n1": defaultUnreadyTime, "n2": defaultUnreadyTime, "n3": defaultUnreadyTime},
7882
},
7983
{
8084
desc: "single one remaining",
@@ -88,6 +92,7 @@ func TestUpdate(t *testing.T) {
8892
},
8993
wantTimestamps: map[string]time.Time{"n2": initialTimestamp},
9094
wantVersions: map[string]string{"n2": "v2"},
95+
wantThresholds: map[string]time.Duration{"n2": defaultUnreadyTime},
9196
},
9297
{
9398
desc: "single one older",
@@ -101,15 +106,51 @@ func TestUpdate(t *testing.T) {
101106
},
102107
wantTimestamps: map[string]time.Time{"n1": finalTimestamp, "n2": initialTimestamp, "n3": finalTimestamp},
103108
wantVersions: map[string]string{"n1": "v2", "n2": "v2", "n3": "v2"},
109+
wantThresholds: map[string]time.Duration{"n1": defaultUnreadyTime, "n2": defaultUnreadyTime, "n3": defaultUnreadyTime},
110+
},
111+
{
112+
desc: "threshold updated on existing node (Ready -> Unready)",
113+
initialNodes: []simulator.NodeToBeRemoved{
114+
makeNodeWithReadyStatus("n2", "v1", true),
115+
},
116+
finalNodes: []simulator.NodeToBeRemoved{
117+
makeNodeWithReadyStatus("n2", "v2", false),
118+
},
119+
wantTimestamps: map[string]time.Time{"n2": initialTimestamp},
120+
wantVersions: map[string]string{"n2": "v2"},
121+
wantThresholds: map[string]time.Duration{"n2": defaultUnreadyTime},
122+
},
123+
{
124+
desc: "mixed update and preservation",
125+
initialNodes: []simulator.NodeToBeRemoved{
126+
makeNodeWithReadyStatus("n1", "v1", true),
127+
},
128+
finalNodes: []simulator.NodeToBeRemoved{
129+
makeNodeWithReadyStatus("n1", "v2", true),
130+
makeNodeWithReadyStatus("n2", "v2", false),
131+
},
132+
wantTimestamps: map[string]time.Time{"n1": initialTimestamp, "n2": finalTimestamp},
133+
wantVersions: map[string]string{"n1": "v2", "n2": "v2"},
134+
wantThresholds: map[string]time.Duration{"n1": defaultUnneededTime, "n2": defaultUnreadyTime},
104135
},
105136
}
106137

107138
for _, tc := range testCases {
108139
t.Run(tc.desc, func(t *testing.T) {
109140
t.Parallel()
110-
nodes := NewNodes(nil, nil)
111141

112142
provider := testprovider.NewTestCloudProviderBuilder().Build()
143+
ng := testprovider.NewTestNodeGroup("ng1", 100, 0, 10, true, false, "", nil, nil)
144+
provider.InsertNodeGroup(ng)
145+
for _, nn := range append(tc.initialNodes, tc.finalNodes...) {
146+
provider.AddNode("ng1", nn.Node)
147+
}
148+
fakeTimeGetter := &fakeScaleDownTimeGetter{
149+
unneededTime: defaultUnneededTime,
150+
unreadyTime: defaultUnreadyTime,
151+
}
152+
153+
nodes := NewNodes(fakeTimeGetter, nil)
113154
ctx := &ca_context.AutoscalingContext{CloudProvider: provider}
114155

115156
nodes.Update(ctx, tc.initialNodes, initialTimestamp)
@@ -123,6 +164,7 @@ func TestUpdate(t *testing.T) {
123164
assert.True(t, found)
124165
assert.Equal(t, tc.wantTimestamps[n.Node.Name], nn.since)
125166
assert.Equal(t, tc.wantVersions[n.Node.Name], version(nn.ntbr))
167+
assert.Equal(t, tc.wantThresholds[n.Node.Name], n.RemovalThreshold)
126168
}
127169
})
128170
}
@@ -136,6 +178,12 @@ func makeNode(name, version string) simulator.NodeToBeRemoved {
136178
return simulator.NodeToBeRemoved{Node: n}
137179
}
138180

181+
func makeNodeWithReadyStatus(name, version string, ready bool) simulator.NodeToBeRemoved {
182+
nn := makeNode(name, version)
183+
SetNodeReadyState(nn.Node, ready, time.Now())
184+
return nn
185+
}
186+
139187
func version(n simulator.NodeToBeRemoved) string {
140188
return n.Node.Annotations[testVersion]
141189
}

0 commit comments

Comments
 (0)