Add e2e test for kubectl interactive delete
This commit is contained in:
		@@ -427,7 +427,6 @@ type FeatureGate string
 | 
				
			|||||||
const (
 | 
					const (
 | 
				
			||||||
	ApplySet                FeatureGate = "KUBECTL_APPLYSET"
 | 
						ApplySet                FeatureGate = "KUBECTL_APPLYSET"
 | 
				
			||||||
	CmdPluginAsSubcommand   FeatureGate = "KUBECTL_ENABLE_CMD_SHADOW"
 | 
						CmdPluginAsSubcommand   FeatureGate = "KUBECTL_ENABLE_CMD_SHADOW"
 | 
				
			||||||
	InteractiveDelete       FeatureGate = "KUBECTL_INTERACTIVE_DELETE"
 | 
					 | 
				
			||||||
	OpenAPIV3Patch          FeatureGate = "KUBECTL_OPENAPIV3_PATCH"
 | 
						OpenAPIV3Patch          FeatureGate = "KUBECTL_OPENAPIV3_PATCH"
 | 
				
			||||||
	RemoteCommandWebsockets FeatureGate = "KUBECTL_REMOTE_COMMAND_WEBSOCKETS"
 | 
						RemoteCommandWebsockets FeatureGate = "KUBECTL_REMOTE_COMMAND_WEBSOCKETS"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										114
									
								
								test/e2e/kubectl/delete.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										114
									
								
								test/e2e/kubectl/delete.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,114 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					Copyright 2024 The Kubernetes Authors.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					You may obtain a copy of the License at
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					limitations under the License.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// OWNER = sig/cli
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package kubectl
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"context"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/onsi/ginkgo/v2"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						apierrors "k8s.io/apimachinery/pkg/api/errors"
 | 
				
			||||||
 | 
						metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
				
			||||||
 | 
						"k8s.io/apimachinery/pkg/util/wait"
 | 
				
			||||||
 | 
						clientset "k8s.io/client-go/kubernetes"
 | 
				
			||||||
 | 
						admissionapi "k8s.io/pod-security-admission/api"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						commonutils "k8s.io/kubernetes/test/e2e/common"
 | 
				
			||||||
 | 
						"k8s.io/kubernetes/test/e2e/framework"
 | 
				
			||||||
 | 
						e2ekubectl "k8s.io/kubernetes/test/e2e/framework/kubectl"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var _ = SIGDescribe("Kubectl delete", func() {
 | 
				
			||||||
 | 
						defer ginkgo.GinkgoRecover()
 | 
				
			||||||
 | 
						var deploymentYaml string
 | 
				
			||||||
 | 
						f := framework.NewDefaultFramework("kubectl-delete")
 | 
				
			||||||
 | 
						f.NamespacePodSecurityLevel = admissionapi.LevelBaseline
 | 
				
			||||||
 | 
						deploymentName := "httpd-deployment"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var ns string
 | 
				
			||||||
 | 
						var c clientset.Interface
 | 
				
			||||||
 | 
						ginkgo.BeforeEach(func() {
 | 
				
			||||||
 | 
							c = f.ClientSet
 | 
				
			||||||
 | 
							ns = f.Namespace.Name
 | 
				
			||||||
 | 
							deploymentYaml = commonutils.SubstituteImageName(string(readTestFileOrDie(httpdDeployment1Filename)))
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ginkgo.Describe("interactive", func() {
 | 
				
			||||||
 | 
							ginkgo.It("based on user confirmation input", func(ctx context.Context) {
 | 
				
			||||||
 | 
								ginkgo.By("apply deployment with replicas 2")
 | 
				
			||||||
 | 
								e2ekubectl.RunKubectlOrDieInput(ns, deploymentYaml, "apply", "-f", "-")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								ginkgo.By("verifying the deployment is created and running")
 | 
				
			||||||
 | 
								err := wait.PollUntilContextTimeout(ctx, 2*time.Second, 30*time.Second, true, func(ctx context.Context) (done bool, err error) {
 | 
				
			||||||
 | 
									d, err := c.AppsV1().Deployments(ns).Get(ctx, deploymentName, metav1.GetOptions{})
 | 
				
			||||||
 | 
									if err != nil {
 | 
				
			||||||
 | 
										if apierrors.IsNotFound(err) {
 | 
				
			||||||
 | 
											return false, nil
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										return false, err
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									if d != nil && d.Status.AvailableReplicas == 2 {
 | 
				
			||||||
 | 
										return true, nil
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									return false, nil
 | 
				
			||||||
 | 
								})
 | 
				
			||||||
 | 
								framework.ExpectNoError(err, "waiting for the deployment has 2 available replicas")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								ginkgo.By("check that resource is not deleted when user types no")
 | 
				
			||||||
 | 
								output := e2ekubectl.RunKubectlOrDieInput(ns, "n", "delete", "--interactive", "deployment", deploymentName)
 | 
				
			||||||
 | 
								expectedOutput := "You are about to delete the following 1 resource(s):"
 | 
				
			||||||
 | 
								if !strings.Contains(output, expectedOutput) ||
 | 
				
			||||||
 | 
									!strings.Contains(output, "deployment.apps/httpd-deployment") ||
 | 
				
			||||||
 | 
									!strings.Contains(output, "deletion is cancelled") {
 | 
				
			||||||
 | 
									framework.Failf("unexpected output %s", output)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								ginkgo.By("verify that deployment is not deleted")
 | 
				
			||||||
 | 
								d, err := c.AppsV1().Deployments(ns).Get(ctx, deploymentName, metav1.GetOptions{})
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									framework.Failf("Failed getting deployment that shouldn't be deleted %v", err)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if d == nil || d.Status.AvailableReplicas != 2 {
 | 
				
			||||||
 | 
									framework.Failf("unexpected available replicas")
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								ginkgo.By("check that resource is deleted when user types yes")
 | 
				
			||||||
 | 
								e2ekubectl.RunKubectlOrDieInput(ns, "y", "delete", "--interactive", "deployment", deploymentName)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								ginkgo.By("ensure that the deployment is deleted successfully")
 | 
				
			||||||
 | 
								err = wait.PollUntilContextTimeout(ctx, 2*time.Second, 30*time.Second, true, func(ctx context.Context) (bool, error) {
 | 
				
			||||||
 | 
									_, err = c.AppsV1().Deployments(ns).Get(ctx, deploymentName, metav1.GetOptions{})
 | 
				
			||||||
 | 
									if err == nil {
 | 
				
			||||||
 | 
										return false, nil
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									if apierrors.IsNotFound(err) {
 | 
				
			||||||
 | 
										return true, nil
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									return false, err
 | 
				
			||||||
 | 
								})
 | 
				
			||||||
 | 
								framework.ExpectNoError(err, "waiting for the deployment that is deleted after getting confirmation by user")
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
		Reference in New Issue
	
	Block a user