github.com/1aal/kubeblocks@v0.0.0-20231107070852-e1c03e598921/pkg/cli/cmd/cluster/list_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 "net/http" 25 "strings" 26 27 . "github.com/onsi/ginkgo/v2" 28 . "github.com/onsi/gomega" 29 corev1 "k8s.io/api/core/v1" 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/cluster" 41 "github.com/1aal/kubeblocks/pkg/cli/testing" 42 "github.com/1aal/kubeblocks/pkg/cli/types" 43 ) 44 45 var _ = Describe("list", func() { 46 var ( 47 streams genericiooptions.IOStreams 48 out *bytes.Buffer 49 tf *cmdtesting.TestFactory 50 ) 51 52 const ( 53 namespace = "test" 54 clusterName = "test" 55 clusterName1 = "test1" 56 clusterName2 = "test2" 57 verticalScalingReason = "VerticalScaling" 58 ) 59 60 BeforeEach(func() { 61 streams, _, out, _ = genericiooptions.NewTestIOStreams() 62 tf = testing.NewTestFactory(namespace) 63 64 _ = appsv1alpha1.AddToScheme(scheme.Scheme) 65 codec := scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...) 66 cluster := testing.FakeCluster(clusterName, namespace, metav1.Condition{ 67 Type: appsv1alpha1.ConditionTypeApplyResources, 68 Status: metav1.ConditionFalse, 69 Reason: "HorizontalScaleFailed", 70 }) 71 clusterWithVerticalScaling := testing.FakeCluster(clusterName1, namespace, metav1.Condition{ 72 Type: appsv1alpha1.ConditionTypeReady, 73 Status: metav1.ConditionFalse, 74 Reason: verticalScalingReason, 75 }) 76 clusterWithVerticalScaling.Status.Phase = appsv1alpha1.UpdatingClusterPhase 77 clusterWithAbnormalPhase := testing.FakeCluster(clusterName2, namespace) 78 clusterWithAbnormalPhase.Status.Phase = appsv1alpha1.AbnormalClusterPhase 79 pods := testing.FakePods(3, namespace, clusterName) 80 httpResp := func(obj runtime.Object) *http.Response { 81 return &http.Response{StatusCode: http.StatusOK, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, obj)} 82 } 83 84 tf.UnstructuredClient = &clientfake.RESTClient{ 85 GroupVersion: schema.GroupVersion{Group: types.AppsAPIGroup, Version: types.AppsAPIVersion}, 86 NegotiatedSerializer: resource.UnstructuredPlusDefaultContentConfig().NegotiatedSerializer, 87 Client: clientfake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { 88 urlPrefix := "/api/v1/namespaces/" + namespace 89 return map[string]*http.Response{ 90 "/namespaces/" + namespace + "/clusters": httpResp(&appsv1alpha1.ClusterList{Items: []appsv1alpha1.Cluster{*cluster}}), 91 "/namespaces/" + namespace + "/clusters/" + clusterName: httpResp(cluster), 92 "/namespaces/" + namespace + "/clusters/" + clusterName1: httpResp(clusterWithVerticalScaling), 93 "/namespaces/" + namespace + "/clusters/" + clusterName2: httpResp(clusterWithAbnormalPhase), 94 "/namespaces/" + namespace + "/secrets": httpResp(testing.FakeSecrets(namespace, clusterName)), 95 "/api/v1/nodes/" + testing.NodeName: httpResp(testing.FakeNode()), 96 urlPrefix + "/services": httpResp(&corev1.ServiceList{}), 97 urlPrefix + "/secrets": httpResp(testing.FakeSecrets(namespace, clusterName)), 98 urlPrefix + "/pods": httpResp(pods), 99 urlPrefix + "/events": httpResp(testing.FakeEvents()), 100 }[req.URL.Path], nil 101 }), 102 } 103 104 tf.Client = tf.UnstructuredClient 105 tf.FakeDynamicClient = testing.FakeDynamicClient(cluster, clusterWithVerticalScaling, clusterWithAbnormalPhase, testing.FakeClusterDef(), testing.FakeClusterVersion()) 106 }) 107 108 AfterEach(func() { 109 tf.Cleanup() 110 }) 111 112 It("list", func() { 113 cmd := NewListCmd(tf, streams) 114 Expect(cmd).ShouldNot(BeNil()) 115 116 cmd.Run(cmd, []string{clusterName, clusterName1, clusterName2}) 117 Expect(out.String()).Should(ContainSubstring(testing.ClusterDefName)) 118 Expect(out.String()).Should(ContainSubstring(string(appsv1alpha1.UpdatingClusterPhase))) 119 Expect(out.String()).Should(ContainSubstring(cluster.ConditionsError)) 120 Expect(out.String()).Should(ContainSubstring(string(appsv1alpha1.AbnormalClusterPhase))) 121 }) 122 123 It("list instances", func() { 124 cmd := NewListInstancesCmd(tf, streams) 125 Expect(cmd).ShouldNot(BeNil()) 126 127 cmd.Run(cmd, []string{"test"}) 128 Expect(out.String()).Should(ContainSubstring(testing.NodeName)) 129 }) 130 131 It("list components", func() { 132 cmd := NewListComponentsCmd(tf, streams) 133 Expect(cmd).ShouldNot(BeNil()) 134 135 cmd.Run(cmd, []string{"test"}) 136 Expect(out.String()).Should(ContainSubstring(testing.ComponentName)) 137 }) 138 139 It("list events", func() { 140 cmd := NewListEventsCmd(tf, streams) 141 Expect(cmd).ShouldNot(BeNil()) 142 143 cmd.Run(cmd, []string{"test"}) 144 Expect(len(strings.Split(out.String(), "\n")) > 1).Should(BeTrue()) 145 }) 146 147 It("output wide", func() { 148 cmd := NewListCmd(tf, streams) 149 Expect(cmd).ShouldNot(BeNil()) 150 151 Expect(cmd.Flags().Set("output", "wide")).Should(Succeed()) 152 cmd.Run(cmd, []string{"test"}) 153 Expect(out.String()).Should(ContainSubstring(testing.ClusterVersionName)) 154 }) 155 156 It("output wide without args", func() { 157 cmd := NewListCmd(tf, streams) 158 Expect(cmd).ShouldNot(BeNil()) 159 160 Expect(cmd.Flags().Set("output", "wide")).Should(Succeed()) 161 cmd.Run(cmd, []string{}) 162 Expect(out.String()).Should(ContainSubstring(testing.ClusterVersionName)) 163 }) 164 })