Skip to content

Commit 16a5b02

Browse files
chore: Fix consistent ordering of NodePools and Provisioners (#860) for v0.33.x (#882)
1 parent 83ea7c2 commit 16a5b02

File tree

2 files changed

+62
-3
lines changed

2 files changed

+62
-3
lines changed

pkg/apis/v1beta1/nodepool.go

+12-3
Original file line numberDiff line numberDiff line change
@@ -155,10 +155,19 @@ type NodePoolList struct {
155155
Items []NodePool `json:"items"`
156156
}
157157

158-
// OrderByWeight orders the nodepools in the NodePoolList
159-
// by their priority weight in-place
158+
// OrderByWeight orders the NodePools in the NodePoolList by their priority weight in-place.
159+
// This priority evaluates the following things in precedence order:
160+
// 1. NodePools that have a larger weight are ordered first
161+
// 2. If two NodePools have the same weight, then the NodePool with the name later in the alphabet will come first
160162
func (pl *NodePoolList) OrderByWeight() {
161163
sort.Slice(pl.Items, func(a, b int) bool {
162-
return ptr.Int32Value(pl.Items[a].Spec.Weight) > ptr.Int32Value(pl.Items[b].Spec.Weight)
164+
weightA := ptr.Int32Value(pl.Items[a].Spec.Weight)
165+
weightB := ptr.Int32Value(pl.Items[b].Spec.Weight)
166+
167+
if weightA == weightB {
168+
// Order NodePools by name for a consistent ordering when sorting equal weight
169+
return pl.Items[a].Name > pl.Items[b].Name
170+
}
171+
return weightA > weightB
163172
})
164173
}

pkg/apis/v1beta1/suite_test.go

+50
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,16 @@ package v1beta1_test
1616

1717
import (
1818
"context"
19+
"math/rand"
1920
"testing"
2021

2122
. "github.com/onsi/ginkgo/v2"
2223
. "github.com/onsi/gomega"
24+
"github.com/samber/lo"
2325
. "knative.dev/pkg/logging/testing"
2426

2527
"sigs.k8s.io/karpenter/pkg/apis"
28+
"sigs.k8s.io/karpenter/pkg/apis/v1beta1"
2629
"sigs.k8s.io/karpenter/pkg/operator/scheme"
2730
"sigs.k8s.io/karpenter/pkg/test"
2831
. "sigs.k8s.io/karpenter/pkg/test/expectations"
@@ -48,3 +51,50 @@ var _ = AfterEach(func() {
4851
var _ = AfterSuite(func() {
4952
Expect(env.Stop()).To(Succeed(), "Failed to stop environment")
5053
})
54+
55+
var _ = Describe("OrderByWeight", func() {
56+
It("should order the NodePools by weight", func() {
57+
// Generate 10 NodePools that have random weights, some might have the same weights
58+
var nodePools []v1beta1.NodePool
59+
for i := 0; i < 10; i++ {
60+
np := test.NodePool(v1beta1.NodePool{
61+
Spec: v1beta1.NodePoolSpec{
62+
Weight: lo.ToPtr[int32](int32(rand.Intn(100) + 1)), //nolint:gosec
63+
},
64+
})
65+
nodePools = append(nodePools, *np)
66+
}
67+
68+
nodePools = lo.Shuffle(nodePools)
69+
nodePoolList := v1beta1.NodePoolList{Items: nodePools}
70+
nodePoolList.OrderByWeight()
71+
72+
lastWeight := 101 // This is above the allowed weight values
73+
for _, np := range nodePoolList.Items {
74+
Expect(lo.FromPtr(np.Spec.Weight)).To(BeNumerically("<=", lastWeight))
75+
lastWeight = int(lo.FromPtr(np.Spec.Weight))
76+
}
77+
})
78+
It("should order the NodePools by name when the weights are the same", func() {
79+
// Generate 10 NodePools with the same weight
80+
var nodePools []v1beta1.NodePool
81+
for i := 0; i < 10; i++ {
82+
np := test.NodePool(v1beta1.NodePool{
83+
Spec: v1beta1.NodePoolSpec{
84+
Weight: lo.ToPtr[int32](10),
85+
},
86+
})
87+
nodePools = append(nodePools, *np)
88+
}
89+
90+
nodePools = lo.Shuffle(nodePools)
91+
nodePoolList := v1beta1.NodePoolList{Items: nodePools}
92+
nodePoolList.OrderByWeight()
93+
94+
lastName := "zzzzzzzzzzzzzzzzzzzzzzzz" // large string value
95+
for _, np := range nodePoolList.Items {
96+
Expect(np.Name < lastName).To(BeTrue())
97+
lastName = np.Name
98+
}
99+
})
100+
})

0 commit comments

Comments
 (0)