github.com/1aal/kubeblocks@v0.0.0-20231107070852-e1c03e598921/pkg/cli/cmd/cluster/delete_ops_test.go (about) 1 /* 2 Copyright (C) 2022-2023 ApeCloud Co., Ltd 3 4 This file is part of KubeBlocks project 5 6 This program is free software: you can redistribute it and/or modify 7 it under the terms of the GNU Affero General Public License as published by 8 the Free Software Foundation, either version 3 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU Affero General Public License for more details. 15 16 You should have received a copy of the GNU Affero General Public License 17 along with this program. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 package cluster 21 22 import ( 23 "bytes" 24 "fmt" 25 "net/http" 26 27 . "github.com/onsi/ginkgo/v2" 28 . "github.com/onsi/gomega" 29 30 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 31 "k8s.io/apimachinery/pkg/runtime" 32 "k8s.io/apimachinery/pkg/runtime/schema" 33 "k8s.io/cli-runtime/pkg/genericiooptions" 34 "k8s.io/cli-runtime/pkg/resource" 35 "k8s.io/client-go/kubernetes/scheme" 36 clientfake "k8s.io/client-go/rest/fake" 37 cmdtesting "k8s.io/kubectl/pkg/cmd/testing" 38 39 appsv1alpha1 "github.com/1aal/kubeblocks/apis/apps/v1alpha1" 40 "github.com/1aal/kubeblocks/pkg/cli/delete" 41 clitesting "github.com/1aal/kubeblocks/pkg/cli/testing" 42 "github.com/1aal/kubeblocks/pkg/cli/types" 43 "github.com/1aal/kubeblocks/pkg/cli/util" 44 ) 45 46 var _ = Describe("Expose", func() { 47 const ( 48 namespace = "test" 49 opsName = "test-ops" 50 ) 51 52 var ( 53 streams genericiooptions.IOStreams 54 tf *cmdtesting.TestFactory 55 in *bytes.Buffer 56 ) 57 generateOpsObject := func(opsName string, phase appsv1alpha1.OpsPhase) *appsv1alpha1.OpsRequest { 58 return &appsv1alpha1.OpsRequest{ 59 ObjectMeta: metav1.ObjectMeta{ 60 Name: opsName, 61 Namespace: namespace, 62 }, 63 Spec: appsv1alpha1.OpsRequestSpec{ 64 ClusterRef: "test-cluster", 65 Type: "Restart", 66 }, 67 Status: appsv1alpha1.OpsRequestStatus{ 68 Phase: phase, 69 }, 70 } 71 } 72 BeforeEach(func() { 73 streams, in, _, _ = genericiooptions.NewTestIOStreams() 74 tf = clitesting.NewTestFactory(namespace) 75 }) 76 77 AfterEach(func() { 78 tf.Cleanup() 79 }) 80 81 initClient := func(opsRequest runtime.Object) { 82 _ = appsv1alpha1.AddToScheme(scheme.Scheme) 83 codec := scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...) 84 httpResp := func(obj runtime.Object) *http.Response { 85 return &http.Response{StatusCode: http.StatusOK, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, obj)} 86 } 87 88 tf.UnstructuredClient = &clientfake.RESTClient{ 89 GroupVersion: schema.GroupVersion{Group: types.AppsAPIGroup, Version: types.AppsAPIVersion}, 90 NegotiatedSerializer: resource.UnstructuredPlusDefaultContentConfig().NegotiatedSerializer, 91 Client: clientfake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { 92 return httpResp(opsRequest), nil 93 }), 94 } 95 96 tf.FakeDynamicClient = clitesting.FakeDynamicClient(opsRequest) 97 tf.Client = tf.UnstructuredClient 98 } 99 100 It("test completeForDeleteOps function", func() { 101 clusterName := "wesql" 102 args := []string{clusterName} 103 clusterLabel := util.BuildLabelSelectorByNames("", args) 104 testLabel := "kubeblocks.io/test=test" 105 106 By("test delete OpsRequest with cluster") 107 o := delete.NewDeleteOptions(tf, streams, types.OpsGVR()) 108 Expect(completeForDeleteOps(o, args)).Should(Succeed()) 109 Expect(o.LabelSelector == clusterLabel).Should(BeTrue()) 110 111 By("test delete OpsRequest with cluster and custom label") 112 o.LabelSelector = testLabel 113 Expect(completeForDeleteOps(o, args)).Should(Succeed()) 114 Expect(o.LabelSelector == testLabel+","+clusterLabel).Should(BeTrue()) 115 116 By("test delete OpsRequest with name") 117 o.Names = []string{"test1"} 118 Expect(completeForDeleteOps(o, nil)).Should(Succeed()) 119 Expect(len(o.ConfirmedNames)).Should(Equal(1)) 120 }) 121 122 It("Testing the deletion of running OpsRequest", func() { 123 By("init opsRequests and k8s client") 124 runningOps := generateOpsObject(opsName, appsv1alpha1.OpsRunningPhase) 125 initClient(runningOps) 126 127 By("expect error when deleting running opsRequest") 128 o := delete.NewDeleteOptions(tf, streams, types.OpsGVR()) 129 o.PreDeleteHook = preDeleteOps 130 o.Names = []string{runningOps.Name} 131 in.Write([]byte(runningOps.Name + "\n")) 132 err := o.Run() 133 Expect(err).ShouldNot(BeNil()) 134 Expect(err.Error()).Should(Equal(fmt.Sprintf(`OpsRequest "%s" is Running, you can specify "--force" to delete it`, runningOps.Name))) 135 136 By("expect success when deleting running opsRequest with --force") 137 o.GracePeriod = 0 138 o.Names = []string{runningOps.Name} 139 in.Write([]byte(runningOps.Name + "\n")) 140 o.Force = true 141 err = o.Run() 142 Expect(err).Should(BeNil()) 143 }) 144 })