github.com/oam-dev/kubevela@v1.9.11/pkg/multicluster/cluster_metrics_management_test.go (about) 1 /* 2 Copyright 2022 The KubeVela Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package multicluster 18 19 import ( 20 "context" 21 "errors" 22 "strconv" 23 "testing" 24 "time" 25 26 "github.com/stretchr/testify/assert" 27 corev1 "k8s.io/api/core/v1" 28 "k8s.io/apimachinery/pkg/api/resource" 29 metricsV1beta1api "k8s.io/metrics/pkg/apis/metrics/v1beta1" 30 clusterv1 "open-cluster-management.io/api/cluster/v1" 31 "sigs.k8s.io/controller-runtime/pkg/client" 32 "sigs.k8s.io/controller-runtime/pkg/client/fake" 33 34 clustercommon "github.com/oam-dev/cluster-gateway/pkg/common" 35 36 "github.com/oam-dev/kubevela/pkg/utils/common" 37 ) 38 39 const ( 40 NormalClusterName = "normal-cluster" 41 DisconnectedClusterName = "disconnected-cluster" 42 43 NodeName1 = "node-1" 44 NodeName2 = "node-2" 45 ) 46 47 func TestRefresh(t *testing.T) { 48 ClusterGatewaySecretNamespace = "default" 49 fakeClient := NewFakeClient(fake.NewClientBuilder(). 50 WithScheme(common.Scheme). 51 WithRuntimeObjects(FakeManagedCluster("managed-cluster")). 52 WithObjects(FakeSecret(NormalClusterName), FakeSecret(DisconnectedClusterName)). 53 Build()) 54 55 normalCluster := fake.NewClientBuilder(). 56 WithScheme(common.Scheme). 57 WithObjects(FakeNode(NodeName1, "8", strconv.FormatInt(16*1024*1024*1024, 10)), 58 FakeNode(NodeName2, "7", strconv.FormatInt(32*1024*1024*1024, 10)), 59 FakeNodeMetrics(NodeName1, "4", strconv.FormatInt(8*1024*1024*1024, 10)), 60 FakeNodeMetrics(NodeName2, "1", strconv.FormatInt(3*1024*1024*1024, 10))). 61 Build() 62 63 disconnectedCluster := &disconnectedClient{} 64 65 fakeClient.AddCluster(NormalClusterName, normalCluster) 66 fakeClient.AddCluster(DisconnectedClusterName, disconnectedCluster) 67 68 mgr, err := NewClusterMetricsMgr(context.Background(), fakeClient, 15*time.Second) 69 assert.NoError(t, err) 70 71 _, err = mgr.Refresh() 72 assert.NoError(t, err) 73 74 clusters, err := ListVirtualClusters(context.Background(), fakeClient) 75 assert.NoError(t, err) 76 77 for _, cluster := range clusters { 78 assertClusterMetrics(t, &cluster) 79 } 80 81 disCluster, err := GetVirtualCluster(context.Background(), fakeClient, DisconnectedClusterName) 82 assert.NoError(t, err) 83 assertClusterMetrics(t, disCluster) 84 85 norCluster, err := GetVirtualCluster(context.Background(), fakeClient, NormalClusterName) 86 assert.NoError(t, err) 87 assertClusterMetrics(t, norCluster) 88 89 exportMetrics(disCluster.Metrics, disCluster.Name) 90 exportMetrics(norCluster.Metrics, norCluster.Name) 91 } 92 93 func assertClusterMetrics(t *testing.T, cluster *VirtualCluster) { 94 metrics := cluster.Metrics 95 switch cluster.Name { 96 case DisconnectedClusterName: 97 assert.Equal(t, metrics.IsConnected, false) 98 assert.True(t, metrics.ClusterInfo == nil) 99 assert.True(t, metrics.ClusterUsageMetrics == nil) 100 case NormalClusterName: 101 assert.Equal(t, metrics.IsConnected, true) 102 103 assert.True(t, resource.MustParse("15").Equal(metrics.ClusterInfo.CPUCapacity)) 104 assert.True(t, resource.MustParse(strconv.FormatInt(48*1024*1024*1024, 10)).Equal(metrics.ClusterInfo.MemoryCapacity)) 105 assert.True(t, resource.MustParse("15").Equal(metrics.ClusterInfo.CPUAllocatable)) 106 assert.True(t, resource.MustParse(strconv.FormatInt(48*1024*1024*1024, 10)).Equal(metrics.ClusterInfo.MemoryAllocatable)) 107 108 assert.True(t, resource.MustParse("5").Equal(metrics.ClusterUsageMetrics.CPUUsage)) 109 assert.True(t, resource.MustParse(strconv.FormatInt(11*1024*1024*1024, 10)).Equal(metrics.ClusterUsageMetrics.MemoryUsage)) 110 } 111 } 112 113 func FakeNodeMetrics(name string, cpu string, memory string) *metricsV1beta1api.NodeMetrics { 114 nodeMetrics := &metricsV1beta1api.NodeMetrics{} 115 nodeMetrics.Name = name 116 nodeMetrics.Usage = corev1.ResourceList{ 117 corev1.ResourceCPU: resource.MustParse(cpu), 118 corev1.ResourceMemory: resource.MustParse(memory), 119 } 120 return nodeMetrics 121 } 122 123 func FakeNode(name string, cpu string, memory string) *corev1.Node { 124 node := &corev1.Node{} 125 node.Name = name 126 node.Status = corev1.NodeStatus{ 127 Allocatable: map[corev1.ResourceName]resource.Quantity{ 128 corev1.ResourceCPU: resource.MustParse(cpu), 129 corev1.ResourceMemory: resource.MustParse(memory), 130 }, 131 Capacity: map[corev1.ResourceName]resource.Quantity{ 132 corev1.ResourceCPU: resource.MustParse(cpu), 133 corev1.ResourceMemory: resource.MustParse(memory), 134 }, 135 } 136 return node 137 } 138 139 func FakeSecret(name string) *corev1.Secret { 140 secret := &corev1.Secret{} 141 secret.Name = name 142 secret.Namespace = ClusterGatewaySecretNamespace 143 secret.Labels = map[string]string{ 144 clustercommon.LabelKeyClusterCredentialType: "ServiceAccountToken", 145 } 146 return secret 147 } 148 149 func FakeManagedCluster(name string) *clusterv1.ManagedCluster { 150 managedCluster := &clusterv1.ManagedCluster{} 151 managedCluster.Name = name 152 return managedCluster 153 } 154 155 type disconnectedClient struct { 156 client.Client 157 } 158 159 func (cli *disconnectedClient) List(ctx context.Context, list client.ObjectList, opts ...client.ListOption) error { 160 return errors.New("no such host") 161 }