@@ -38,15 +38,16 @@ import (
3838
3939// PodSetTestCase defines a test case for a single podset in the consolidated test.
4040type PodSetTestCase struct {
41- podSetName string
42- topologyRequest * kueue.PodSetTopologyRequest
43- requests resources.Requests
44- count int32
45- tolerations []corev1.Toleration
46- nodeSelector map [string ]string
47- podSetGroupName * string
48- wantAssignment * tas.TopologyAssignment
49- wantReason string
41+ podSetName string
42+ topologyRequest * kueue.PodSetTopologyRequest
43+ requests resources.Requests
44+ count int32
45+ tolerations []corev1.Toleration
46+ nodeSelector map [string ]string
47+ podSetGroupName * string
48+ previousAssignment * kueue.TopologyAssignment
49+ wantAssignment * tas.TopologyAssignment
50+ wantReason string
5051}
5152
5253func TestFindTopologyAssignments (t * testing.T ) {
@@ -5983,6 +5984,201 @@ func TestFindTopologyAssignments(t *testing.T) {
59835984 },
59845985 },
59855986 },
5987+ "elastic workload scale up: delta-only placement preserves previous assignment" : {
5988+ nodes : []corev1.Node {
5989+ * testingnode .MakeNode ("x1" ).
5990+ Label (corev1 .LabelHostname , "x1" ).
5991+ StatusAllocatable (corev1.ResourceList {
5992+ corev1 .ResourceCPU : resource .MustParse ("2" ),
5993+ corev1 .ResourcePods : resource .MustParse ("10" ),
5994+ }).
5995+ Ready ().
5996+ Obj (),
5997+ * testingnode .MakeNode ("x2" ).
5998+ Label (corev1 .LabelHostname , "x2" ).
5999+ StatusAllocatable (corev1.ResourceList {
6000+ corev1 .ResourceCPU : resource .MustParse ("2" ),
6001+ corev1 .ResourcePods : resource .MustParse ("10" ),
6002+ }).
6003+ Ready ().
6004+ Obj (),
6005+ * testingnode .MakeNode ("x3" ).
6006+ Label (corev1 .LabelHostname , "x3" ).
6007+ StatusAllocatable (corev1.ResourceList {
6008+ corev1 .ResourceCPU : resource .MustParse ("2" ),
6009+ corev1 .ResourcePods : resource .MustParse ("10" ),
6010+ }).
6011+ Ready ().
6012+ Obj (),
6013+ },
6014+ levels : defaultOneLevel ,
6015+ podSets : []PodSetTestCase {{
6016+ topologyRequest : & kueue.PodSetTopologyRequest {
6017+ Unconstrained : ptr .To (true ),
6018+ },
6019+ requests : resources.Requests {
6020+ corev1 .ResourceCPU : 1000 ,
6021+ },
6022+ count : 4 ,
6023+ previousAssignment : tas .V1Beta2From (& tas.TopologyAssignment {
6024+ Levels : []string {corev1 .LabelHostname },
6025+ Domains : []tas.TopologyDomainAssignment {
6026+ {Count : 2 , Values : []string {"x1" }},
6027+ },
6028+ }),
6029+ wantAssignment : & tas.TopologyAssignment {
6030+ Levels : []string {corev1 .LabelHostname },
6031+ Domains : []tas.TopologyDomainAssignment {
6032+ {Count : 2 , Values : []string {"x1" }},
6033+ {Count : 2 , Values : []string {"x2" }},
6034+ },
6035+ },
6036+ }},
6037+ enableFeatureGates : []featuregate.Feature {features .ElasticJobsViaWorkloadSlices , features .ElasticJobsViaWorkloadSlicesWithTAS },
6038+ },
6039+ "elastic workload scale up: spread across multiple nodes preserved" : {
6040+ nodes : []corev1.Node {
6041+ * testingnode .MakeNode ("x1" ).
6042+ Label (corev1 .LabelHostname , "x1" ).
6043+ StatusAllocatable (corev1.ResourceList {
6044+ corev1 .ResourceCPU : resource .MustParse ("2" ),
6045+ corev1 .ResourcePods : resource .MustParse ("10" ),
6046+ }).
6047+ Ready ().
6048+ Obj (),
6049+ * testingnode .MakeNode ("x2" ).
6050+ Label (corev1 .LabelHostname , "x2" ).
6051+ StatusAllocatable (corev1.ResourceList {
6052+ corev1 .ResourceCPU : resource .MustParse ("2" ),
6053+ corev1 .ResourcePods : resource .MustParse ("10" ),
6054+ }).
6055+ Ready ().
6056+ Obj (),
6057+ * testingnode .MakeNode ("x3" ).
6058+ Label (corev1 .LabelHostname , "x3" ).
6059+ StatusAllocatable (corev1.ResourceList {
6060+ corev1 .ResourceCPU : resource .MustParse ("2" ),
6061+ corev1 .ResourcePods : resource .MustParse ("10" ),
6062+ }).
6063+ Ready ().
6064+ Obj (),
6065+ },
6066+ levels : defaultOneLevel ,
6067+ podSets : []PodSetTestCase {{
6068+ topologyRequest : & kueue.PodSetTopologyRequest {
6069+ Unconstrained : ptr .To (true ),
6070+ },
6071+ requests : resources.Requests {
6072+ corev1 .ResourceCPU : 1000 ,
6073+ },
6074+ count : 4 ,
6075+ previousAssignment : tas .V1Beta2From (& tas.TopologyAssignment {
6076+ Levels : []string {corev1 .LabelHostname },
6077+ Domains : []tas.TopologyDomainAssignment {
6078+ {Count : 1 , Values : []string {"x1" }},
6079+ {Count : 1 , Values : []string {"x2" }},
6080+ },
6081+ }),
6082+ wantAssignment : & tas.TopologyAssignment {
6083+ Levels : []string {corev1 .LabelHostname },
6084+ Domains : []tas.TopologyDomainAssignment {
6085+ {Count : 1 , Values : []string {"x1" }},
6086+ {Count : 1 , Values : []string {"x2" }},
6087+ {Count : 2 , Values : []string {"x3" }},
6088+ },
6089+ },
6090+ }},
6091+ enableFeatureGates : []featuregate.Feature {features .ElasticJobsViaWorkloadSlices , features .ElasticJobsViaWorkloadSlicesWithTAS },
6092+ },
6093+ "elastic workload scale down: truncates assignment" : {
6094+ nodes : []corev1.Node {
6095+ * testingnode .MakeNode ("x1" ).
6096+ Label (corev1 .LabelHostname , "x1" ).
6097+ StatusAllocatable (corev1.ResourceList {
6098+ corev1 .ResourceCPU : resource .MustParse ("4" ),
6099+ corev1 .ResourcePods : resource .MustParse ("10" ),
6100+ }).
6101+ Ready ().
6102+ Obj (),
6103+ * testingnode .MakeNode ("x2" ).
6104+ Label (corev1 .LabelHostname , "x2" ).
6105+ StatusAllocatable (corev1.ResourceList {
6106+ corev1 .ResourceCPU : resource .MustParse ("4" ),
6107+ corev1 .ResourcePods : resource .MustParse ("10" ),
6108+ }).
6109+ Ready ().
6110+ Obj (),
6111+ },
6112+ levels : defaultOneLevel ,
6113+ podSets : []PodSetTestCase {{
6114+ topologyRequest : & kueue.PodSetTopologyRequest {
6115+ Unconstrained : ptr .To (true ),
6116+ },
6117+ requests : resources.Requests {
6118+ corev1 .ResourceCPU : 1000 ,
6119+ },
6120+ count : 3 ,
6121+ previousAssignment : tas .V1Beta2From (& tas.TopologyAssignment {
6122+ Levels : []string {corev1 .LabelHostname },
6123+ Domains : []tas.TopologyDomainAssignment {
6124+ {Count : 3 , Values : []string {"x1" }},
6125+ {Count : 2 , Values : []string {"x2" }},
6126+ },
6127+ }),
6128+ wantAssignment : & tas.TopologyAssignment {
6129+ Levels : []string {corev1 .LabelHostname },
6130+ Domains : []tas.TopologyDomainAssignment {
6131+ {Count : 3 , Values : []string {"x1" }},
6132+ },
6133+ },
6134+ }},
6135+ enableFeatureGates : []featuregate.Feature {features .ElasticJobsViaWorkloadSlices , features .ElasticJobsViaWorkloadSlicesWithTAS },
6136+ },
6137+ "elastic workload same count: reuses previous assignment exactly" : {
6138+ nodes : []corev1.Node {
6139+ * testingnode .MakeNode ("x1" ).
6140+ Label (corev1 .LabelHostname , "x1" ).
6141+ StatusAllocatable (corev1.ResourceList {
6142+ corev1 .ResourceCPU : resource .MustParse ("4" ),
6143+ corev1 .ResourcePods : resource .MustParse ("10" ),
6144+ }).
6145+ Ready ().
6146+ Obj (),
6147+ * testingnode .MakeNode ("x2" ).
6148+ Label (corev1 .LabelHostname , "x2" ).
6149+ StatusAllocatable (corev1.ResourceList {
6150+ corev1 .ResourceCPU : resource .MustParse ("4" ),
6151+ corev1 .ResourcePods : resource .MustParse ("10" ),
6152+ }).
6153+ Ready ().
6154+ Obj (),
6155+ },
6156+ levels : defaultOneLevel ,
6157+ podSets : []PodSetTestCase {{
6158+ topologyRequest : & kueue.PodSetTopologyRequest {
6159+ Unconstrained : ptr .To (true ),
6160+ },
6161+ requests : resources.Requests {
6162+ corev1 .ResourceCPU : 1000 ,
6163+ },
6164+ count : 3 ,
6165+ previousAssignment : tas .V1Beta2From (& tas.TopologyAssignment {
6166+ Levels : []string {corev1 .LabelHostname },
6167+ Domains : []tas.TopologyDomainAssignment {
6168+ {Count : 2 , Values : []string {"x1" }},
6169+ {Count : 1 , Values : []string {"x2" }},
6170+ },
6171+ }),
6172+ wantAssignment : & tas.TopologyAssignment {
6173+ Levels : []string {corev1 .LabelHostname },
6174+ Domains : []tas.TopologyDomainAssignment {
6175+ {Count : 2 , Values : []string {"x1" }},
6176+ {Count : 1 , Values : []string {"x2" }},
6177+ },
6178+ },
6179+ }},
6180+ enableFeatureGates : []featuregate.Feature {features .ElasticJobsViaWorkloadSlices , features .ElasticJobsViaWorkloadSlicesWithTAS },
6181+ },
59866182 }
59876183 for name , tc := range cases {
59886184 t .Run (name , func (t * testing.T ) {
@@ -6036,8 +6232,9 @@ func TestFindTopologyAssignments(t *testing.T) {
60366232 },
60376233 },
60386234 },
6039- SinglePodRequests : ps .requests ,
6040- Count : ps .count ,
6235+ SinglePodRequests : ps .requests ,
6236+ Count : ps .count ,
6237+ PreviousAssignment : ps .previousAssignment ,
60416238 }
60426239 if ps .podSetGroupName != nil {
60436240 tasInput .PodSetGroupName = ps .podSetGroupName
0 commit comments