@@ -28,9 +28,12 @@ import (
2828 "k8s.io/apimachinery/pkg/util/intstr"
2929 "k8s.io/apimachinery/pkg/util/uuid"
3030 "k8s.io/apimachinery/pkg/util/wait"
31+ utilfeature "k8s.io/apiserver/pkg/util/feature"
3132 "k8s.io/client-go/util/retry"
33+ featuregatetesting "k8s.io/component-base/featuregate/testing"
3234 "k8s.io/klog/v2/ktesting"
3335 deploymentutil "k8s.io/kubernetes/pkg/controller/deployment/util"
36+ "k8s.io/kubernetes/pkg/features"
3437 "k8s.io/kubernetes/test/integration/framework"
3538 testutil "k8s.io/kubernetes/test/utils"
3639 "k8s.io/utils/ptr"
@@ -965,7 +968,7 @@ func TestDeploymentAvailableCondition(t *testing.T) {
965968 }
966969
967970 // Verify all replicas fields of DeploymentStatus have desired counts
968- if err = tester .checkDeploymentStatusReplicasFields (10 , 10 , 0 , 0 , 10 ); err != nil {
971+ if err = tester .checkDeploymentStatusReplicasFields (10 , 10 , 0 , 0 , 10 , nil ); err != nil {
969972 t .Fatal (err )
970973 }
971974
@@ -985,7 +988,7 @@ func TestDeploymentAvailableCondition(t *testing.T) {
985988 }
986989
987990 // Verify all replicas fields of DeploymentStatus have desired counts
988- if err = tester .checkDeploymentStatusReplicasFields (10 , 10 , 10 , 0 , 10 ); err != nil {
991+ if err = tester .checkDeploymentStatusReplicasFields (10 , 10 , 10 , 0 , 10 , nil ); err != nil {
989992 t .Fatal (err )
990993 }
991994
@@ -1008,7 +1011,7 @@ func TestDeploymentAvailableCondition(t *testing.T) {
10081011 }
10091012
10101013 // Verify all replicas fields of DeploymentStatus have desired counts
1011- if err = tester .checkDeploymentStatusReplicasFields (10 , 10 , 10 , 10 , 0 ); err != nil {
1014+ if err = tester .checkDeploymentStatusReplicasFields (10 , 10 , 10 , 10 , 0 , nil ); err != nil {
10121015 t .Fatal (err )
10131016 }
10141017}
@@ -1303,3 +1306,98 @@ func TestReplicaSetOrphaningAndAdoptionWhenLabelsChange(t *testing.T) {
13031306 t .Fatalf ("failed waiting for replicaset adoption by deployment %q to complete: %v" , deploymentName , err )
13041307 }
13051308}
1309+
1310+ func TestTerminatingReplicasDeploymentStatus (t * testing.T ) {
1311+ featuregatetesting .SetFeatureGateDuringTest (t , utilfeature .DefaultFeatureGate , features .DeploymentPodReplacementPolicy , false )
1312+
1313+ _ , ctx := ktesting .NewTestContext (t )
1314+ ctx , cancel := context .WithCancel (ctx )
1315+ defer cancel ()
1316+
1317+ closeFn , rm , dc , informers , c := dcSetup (ctx , t )
1318+ defer closeFn ()
1319+
1320+ name := "test-terminating-replica-status"
1321+ ns := framework .CreateNamespaceOrDie (c , name , t )
1322+ defer framework .DeleteNamespaceOrDie (c , ns , t )
1323+
1324+ deploymentName := "deployment"
1325+ replicas := int32 (6 )
1326+ tester := & deploymentTester {t : t , c : c , deployment : newDeployment (deploymentName , ns .Name , replicas )}
1327+ tester .deployment .Spec .Strategy .Type = apps .RecreateDeploymentStrategyType
1328+ tester .deployment .Spec .Strategy .RollingUpdate = nil
1329+ tester .deployment .Spec .Template .Spec .NodeName = "fake-node"
1330+ tester .deployment .Spec .Template .Spec .TerminationGracePeriodSeconds = ptr .To (int64 (300 ))
1331+
1332+ var err error
1333+ tester .deployment , err = c .AppsV1 ().Deployments (ns .Name ).Create (context .TODO (), tester .deployment , metav1.CreateOptions {})
1334+ if err != nil {
1335+ t .Fatalf ("failed to create deployment %q: %v" , deploymentName , err )
1336+ }
1337+
1338+ // Start informer and controllers
1339+ stopControllers := runControllersAndInformers (t , rm , dc , informers )
1340+ defer stopControllers ()
1341+
1342+ // Ensure the deployment completes while marking its pods as ready simultaneously
1343+ if err := tester .waitForDeploymentCompleteAndMarkPodsReady (); err != nil {
1344+ t .Fatal (err )
1345+ }
1346+ // Should not update terminating replicas when feature gate is disabled
1347+ // Verify all replicas fields of DeploymentStatus have desired counts
1348+ if err = tester .checkDeploymentStatusReplicasFields (6 , 6 , 6 , 6 , 0 , nil ); err != nil {
1349+ t .Fatal (err )
1350+ }
1351+
1352+ // Scale down the deployment
1353+ tester .deployment , err = tester .updateDeployment (func (update * apps.Deployment ) {
1354+ update .Spec .Replicas = ptr .To (int32 (4 ))
1355+ })
1356+ if err != nil {
1357+ t .Fatalf ("failed updating deployment %q: %v" , deploymentName , err )
1358+ }
1359+ // Wait for number of ready replicas to equal number of replicas.
1360+ if err = tester .waitForReadyReplicas (); err != nil {
1361+ t .Fatal (err )
1362+ }
1363+ // Verify all replicas fields of DeploymentStatus have desired counts
1364+ if err = tester .checkDeploymentStatusReplicasFields (4 , 4 , 4 , 4 , 0 , nil ); err != nil {
1365+ t .Fatal (err )
1366+ }
1367+
1368+ // should update terminating replicas when feature gate is enabled
1369+ featuregatetesting .SetFeatureGateDuringTest (t , utilfeature .DefaultFeatureGate , features .DeploymentPodReplacementPolicy , true )
1370+ // Scale down the deployment
1371+ tester .deployment , err = tester .updateDeployment (func (update * apps.Deployment ) {
1372+ update .Spec .Replicas = ptr .To (int32 (3 ))
1373+ })
1374+ if err != nil {
1375+ t .Fatalf ("failed updating deployment %q: %v" , deploymentName , err )
1376+ }
1377+ // Wait for number of ready replicas to equal number of replicas.
1378+ if err = tester .waitForReadyReplicas (); err != nil {
1379+ t .Fatal (err )
1380+ }
1381+ // Verify all replicas fields of DeploymentStatus have desired counts
1382+ if err = tester .checkDeploymentStatusReplicasFields (3 , 3 , 3 , 3 , 0 , ptr.To [int32 ](3 )); err != nil {
1383+ t .Fatal (err )
1384+ }
1385+
1386+ // should not update terminating replicas when feature gate is disabled
1387+ featuregatetesting .SetFeatureGateDuringTest (t , utilfeature .DefaultFeatureGate , features .DeploymentPodReplacementPolicy , false )
1388+ // Scale down the deployment
1389+ tester .deployment , err = tester .updateDeployment (func (update * apps.Deployment ) {
1390+ update .Spec .Replicas = ptr .To (int32 (2 ))
1391+ })
1392+ if err != nil {
1393+ t .Fatalf ("failed updating deployment %q: %v" , deploymentName , err )
1394+ }
1395+ // Wait for number of ready replicas to equal number of replicas.
1396+ if err = tester .waitForReadyReplicas (); err != nil {
1397+ t .Fatal (err )
1398+ }
1399+ // Verify all replicas fields of DeploymentStatus have desired counts
1400+ if err = tester .checkDeploymentStatusReplicasFields (2 , 2 , 2 , 2 , 0 , nil ); err != nil {
1401+ t .Fatal (err )
1402+ }
1403+ }
0 commit comments