Skip to content

Commit ae4f0ba

Browse files
committed
Improve update and contenthash logic for ToplogoSpreadConstraints
Signed-off-by: Aurel Canciu <[email protected]>
1 parent 79dca91 commit ae4f0ba

File tree

5 files changed

+116
-13
lines changed

5 files changed

+116
-13
lines changed

pkg/operator/contenthash/topology_spread_constraints.go

+14-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ package contenthash
2020
import (
2121
"crypto/md5"
2222
"encoding/hex"
23+
"fmt"
24+
"strings"
2325

2426
corev1 "k8s.io/api/core/v1"
2527
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -42,7 +44,18 @@ func TopologySpreadConstraints(in []corev1.TopologySpreadConstraint) string {
4244
labelSelectors = map[string]string{}
4345
}
4446
writeStringHash(h, StringMap(labelSelectors))
45-
47+
writeStringHash(h, strings.Join(tsc.MatchLabelKeys, ""))
48+
minDomainsSeconds := "nil"
49+
if tsc.MinDomains != nil {
50+
minDomainsSeconds = fmt.Sprint(*tsc.MinDomains)
51+
}
52+
writeStringHash(h, minDomainsSeconds)
53+
if tsc.NodeAffinityPolicy != nil {
54+
writeStringHash(h, string(*tsc.NodeAffinityPolicy))
55+
}
56+
if tsc.NodeTaintsPolicy != nil {
57+
writeStringHash(h, string(*tsc.NodeTaintsPolicy))
58+
}
4659
}
4760

4861
sum := h.Sum(nil)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
Copyright 2020 PlanetScale Inc.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package contenthash
18+
19+
import (
20+
"testing"
21+
22+
corev1 "k8s.io/api/core/v1"
23+
"k8s.io/utils/ptr"
24+
)
25+
26+
func TestTopologySpreadConstraintMinDomainsSecondsNil(t *testing.T) {
27+
// Make sure nil is distinguishable from 0.
28+
nilHash := TopologySpreadConstraints([]corev1.TopologySpreadConstraint{
29+
{MinDomains: nil},
30+
})
31+
zeroHash := TopologySpreadConstraints([]corev1.TopologySpreadConstraint{
32+
33+
{MinDomains: ptr.To(int32(0))},
34+
})
35+
if nilHash == zeroHash {
36+
t.Errorf("nilHash = zeroHash = %v; expected different values", nilHash)
37+
}
38+
}
39+
40+
func TestTopologySpreadConstraintNodeAffinityPolicysNil(t *testing.T) {
41+
// Make sure nil is distinguishable from 0.
42+
nilHash := TopologySpreadConstraints([]corev1.TopologySpreadConstraint{
43+
{NodeAffinityPolicy: nil},
44+
})
45+
honorHash := TopologySpreadConstraints([]corev1.TopologySpreadConstraint{
46+
{NodeAffinityPolicy: ptr.To(corev1.NodeInclusionPolicyHonor)},
47+
})
48+
if nilHash == honorHash {
49+
t.Errorf("nilHash = zeroHash = %v; expected different values", nilHash)
50+
}
51+
}
52+
53+
func TestTopologySpreadConstraintNodeTaintsPolicysNil(t *testing.T) {
54+
// Make sure nil is distinguishable from 0.
55+
nilHash := TopologySpreadConstraints([]corev1.TopologySpreadConstraint{
56+
{NodeTaintsPolicy: nil},
57+
})
58+
honorHash := TopologySpreadConstraints([]corev1.TopologySpreadConstraint{
59+
{NodeTaintsPolicy: ptr.To(corev1.NodeInclusionPolicyHonor)},
60+
})
61+
if nilHash == honorHash {
62+
t.Errorf("nilHash = zeroHash = %v; expected different values", nilHash)
63+
}
64+
}

pkg/operator/desiredstatehash/builder_test.go

+2
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ func TestEmptyValues(t *testing.T) {
4646
b.AddContainersUpdates("empty ContainersUpdates", []corev1.Container{})
4747
b.AddTolerations("nil Tolerations", nil)
4848
b.AddTolerations("empty Tolerations", []corev1.Toleration{})
49+
b.AddTopologySpreadConstraints("nil TopologySpreadConstraints", nil)
50+
b.AddTopologySpreadConstraints("empty TopologySpreadConstraints", []corev1.TopologySpreadConstraint{})
4951
b.AddVolumeNames("nil VolumeNames", nil)
5052
b.AddVolumeNames("empty VolumeNames", []corev1.Volume{})
5153

pkg/operator/update/podspec.go

+1-12
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import (
2020
"reflect"
2121

2222
corev1 "k8s.io/api/core/v1"
23-
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2423
)
2524

2625
// Volumes updates entries in 'dst' based on the values in 'src'.
@@ -302,20 +301,10 @@ func TopologySpreadConstraints(dst *[]corev1.TopologySpreadConstraint, src []cor
302301
srcLoop:
303302
for srcIndex := range src {
304303
srcObj := &src[srcIndex]
305-
srcMap, srcErr := metav1.LabelSelectorAsMap(srcObj.LabelSelector)
306-
if srcErr != nil {
307-
// There is no return of error for this function
308-
// or its callers, which makes this a bit of a hack
309-
srcMap = map[string]string{}
310-
}
311304
// If this item is already there, update it.
312305
for dstIndex := range *dst {
313306
dstObj := &(*dst)[dstIndex]
314-
dstMap, dstErr := metav1.LabelSelectorAsMap(dstObj.LabelSelector)
315-
if dstErr != nil {
316-
dstMap = map[string]string{}
317-
}
318-
if reflect.DeepEqual(dstMap, srcMap) {
307+
if reflect.DeepEqual(srcObj, dstObj) {
319308
*dstObj = *srcObj
320309
continue srcLoop
321310
}

pkg/operator/update/podspec_test.go

+35
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,38 @@ func TestTolerations(t *testing.T) {
4141
t.Errorf("val = %#v; want %#v", val, want)
4242
}
4343
}
44+
45+
func TestTopologySpreadConstraints(t *testing.T) {
46+
// Make sure we don't touch tolerations that were already there.
47+
val := []corev1.TopologySpreadConstraint{
48+
{
49+
MaxSkew: 1,
50+
TopologyKey: "alreadyExists",
51+
WhenUnsatisfiable: corev1.DoNotSchedule,
52+
},
53+
}
54+
want := []corev1.TopologySpreadConstraint{
55+
{
56+
MaxSkew: 1,
57+
TopologyKey: "alreadyExists",
58+
WhenUnsatisfiable: corev1.DoNotSchedule,
59+
},
60+
{
61+
MaxSkew: 2,
62+
TopologyKey: "newKey",
63+
WhenUnsatisfiable: corev1.ScheduleAnyway,
64+
},
65+
}
66+
67+
TopologySpreadConstraints(&val, []corev1.TopologySpreadConstraint{
68+
{
69+
MaxSkew: 2,
70+
TopologyKey: "newKey",
71+
WhenUnsatisfiable: corev1.ScheduleAnyway,
72+
},
73+
})
74+
75+
if !equality.Semantic.DeepEqual(val, want) {
76+
t.Errorf("val = %#v; want %#v", val, want)
77+
}
78+
}

0 commit comments

Comments
 (0)