github.com/polarismesh/polaris@v1.17.8/apiserver/eurekaserver/applications_test.go (about) 1 /** 2 * Tencent is pleased to support the open source community by making Polaris available. 3 * 4 * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. 5 * 6 * Licensed under the BSD 3-Clause License (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * https://opensource.org/licenses/BSD-3-Clause 11 * 12 * Unless required by applicable law or agreed to in writing, software distributed 13 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 14 * CONDITIONS OF ANY KIND, either express or implied. See the License for the 15 * specific language governing permissions and limitations under the License. 16 */ 17 18 package eurekaserver 19 20 import ( 21 "strconv" 22 "strings" 23 "testing" 24 "time" 25 26 "github.com/golang/protobuf/ptypes/wrappers" 27 "github.com/google/uuid" 28 apimodel "github.com/polarismesh/specification/source/go/api/v1/model" 29 apiservice "github.com/polarismesh/specification/source/go/api/v1/service_manage" 30 "github.com/stretchr/testify/assert" 31 32 "github.com/polarismesh/polaris/common/model" 33 "github.com/polarismesh/polaris/service" 34 ) 35 36 const ( 37 defaultSvcCount = 10 38 productionSvcCount = 5 39 unhealthySvcCount = 5 40 instanceCount = 20 41 namespaceDefault = "default" 42 namespaceProduction = "production" 43 hostPrefix = "127.0.0." 44 port = 10011 45 ) 46 47 type svcName struct { 48 name string 49 namespace string 50 } 51 52 var ( 53 mockServices = map[svcName]*model.Service{} 54 mockInstances = map[string]map[string]*model.Instance{} 55 mockUnhealthyServices = map[svcName]*model.Service{} 56 mockUnhealthyInstances = map[string]map[string]*model.Instance{} 57 ) 58 59 func buildServices(count int, namespace string, services map[svcName]*model.Service) { 60 for i := 0; i < count; i++ { 61 name := svcName{ 62 name: namespace + "_svc_" + strconv.Itoa(i), 63 namespace: namespace, 64 } 65 services[name] = &model.Service{ 66 ID: uuid.NewString(), 67 Name: name.name, 68 Namespace: name.namespace, 69 } 70 } 71 } 72 73 func buildMockInstance(idx int, svc *model.Service, healthy bool, vipAddresses string, svipAddresses string) *model.Instance { 74 instance := &model.Instance{ 75 Proto: &apiservice.Instance{ 76 Id: &wrappers.StringValue{Value: uuid.NewString()}, 77 Service: &wrappers.StringValue{Value: svc.Name}, 78 Namespace: &wrappers.StringValue{Value: svc.Namespace}, 79 Host: &wrappers.StringValue{Value: hostPrefix + strconv.Itoa(idx)}, 80 Port: &wrappers.UInt32Value{Value: port}, 81 Protocol: &wrappers.StringValue{Value: InsecureProtocol}, 82 Version: &wrappers.StringValue{Value: "1.0.0"}, 83 Weight: &wrappers.UInt32Value{Value: 100}, 84 EnableHealthCheck: &wrappers.BoolValue{Value: true}, 85 HealthCheck: &apiservice.HealthCheck{Type: apiservice.HealthCheck_HEARTBEAT, Heartbeat: &apiservice.HeartbeatHealthCheck{ 86 Ttl: nil, 87 }}, 88 Healthy: &wrappers.BoolValue{Value: healthy}, 89 Isolate: &wrappers.BoolValue{Value: false}, 90 Location: &apimodel.Location{ 91 Region: &wrappers.StringValue{Value: "South China"}, 92 Zone: &wrappers.StringValue{Value: "ShangHai"}, 93 Campus: &wrappers.StringValue{Value: "CampusOne"}, 94 }, 95 Metadata: map[string]string{ 96 MetadataRegisterFrom: ServerEureka, 97 MetadataCountryId: DefaultCountryId, 98 MetadataHostName: svc.Namespace + "." + svc.Name + "." + strconv.Itoa(port) + "." + strconv.Itoa(idx), 99 MetadataInsecurePort: strconv.Itoa(port), 100 MetadataInsecurePortEnabled: "true", 101 MetadataSecurePortEnabled: "false", 102 }, 103 }, 104 ServiceID: svc.ID, 105 Valid: true, 106 ModifyTime: time.Now(), 107 } 108 if len(vipAddresses) > 0 { 109 instance.Proto.Metadata[MetadataVipAddress] = vipAddresses 110 } 111 if len(svipAddresses) > 0 { 112 instance.Proto.Metadata[MetadataSecureVipAddress] = svipAddresses 113 } 114 return instance 115 } 116 117 func buildMockSvcInstances() { 118 buildServices(defaultSvcCount, namespaceDefault, mockServices) 119 buildServices(productionSvcCount, namespaceProduction, mockServices) 120 idx := 0 121 for _, svc := range mockServices { 122 instances := make(map[string]*model.Instance, instanceCount) 123 for i := 0; i < instanceCount; i++ { 124 idx++ 125 instance := buildMockInstance(idx, svc, true, "", "") 126 instances[instance.ID()] = instance 127 } 128 mockInstances[svc.ID] = instances 129 } 130 } 131 132 func buildMockUnhealthyInstances() { 133 buildServices(unhealthySvcCount, namespaceDefault, mockUnhealthyServices) 134 idx := 0 135 for _, svc := range mockUnhealthyServices { 136 var allUnhealthy bool 137 if idx%(3*instanceCount) == 0 { 138 allUnhealthy = true 139 } 140 instances := make(map[string]*model.Instance, instanceCount) 141 for i := 0; i < instanceCount; i++ { 142 idx++ 143 instance := buildMockInstance(idx, svc, !allUnhealthy, "", "") 144 instances[instance.ID()] = instance 145 } 146 mockUnhealthyInstances[svc.ID] = instances 147 } 148 149 } 150 151 func mockGetCacheServices(namingServer service.DiscoverServer, namespace string) map[string]*model.Service { 152 var newServices = make(map[string]*model.Service) 153 for _, svc := range mockServices { 154 if namespace == svc.Namespace { 155 newServices[svc.ID] = svc 156 } 157 } 158 return newServices 159 } 160 161 func mockGetCacheInstances(namingServer service.DiscoverServer, svcId string) ([]*model.Instance, string, error) { 162 instances := mockInstances[svcId] 163 var retValue = make([]*model.Instance, 0, len(instances)) 164 if len(instances) == 0 { 165 return retValue, uuid.NewString(), nil 166 } 167 for _, instance := range instances { 168 retValue = append(retValue, instance) 169 } 170 return retValue, uuid.NewString(), nil 171 } 172 173 func doFunctionMock() { 174 buildMockSvcInstances() 175 getCacheServicesFunc = mockGetCacheServices 176 getCacheInstancesFunc = mockGetCacheInstances 177 } 178 179 // TestApplicationsBuilder_BuildApplications testing method for application builder 180 func TestApplicationsBuilder_BuildApplications(t *testing.T) { 181 doFunctionMock() 182 builder := &ApplicationsBuilder{ 183 namespace: DefaultNamespace, 184 enableSelfPreservation: true, 185 } 186 appResCache := builder.BuildApplications(nil) 187 applications := appResCache.AppsResp.Applications.Application 188 assert.Equal(t, defaultSvcCount, len(applications)) 189 for _, application := range applications { 190 serviceName := svcName{ 191 name: strings.ToLower(application.Name), 192 namespace: DefaultNamespace, 193 } 194 svc, ok := mockServices[serviceName] 195 assert.True(t, ok) 196 instances := application.Instance 197 mInstances := mockInstances[svc.ID] 198 for _, instance := range instances { 199 mInstance, ok := mInstances[instance.InstanceId] 200 assert.True(t, ok) 201 assert.Equal(t, instance.Port.Port, int(mInstance.Port())) 202 assert.Equal(t, instance.IpAddr, mInstance.Host()) 203 assert.Equal(t, mInstance.Location().GetRegion().GetValue(), instance.Metadata.Meta[KeyRegion]) 204 assert.Equal(t, mInstance.Location().GetZone().GetValue(), instance.Metadata.Meta[keyZone]) 205 assert.Equal(t, mInstance.Location().GetCampus().GetValue(), instance.Metadata.Meta[keyCampus]) 206 } 207 } 208 } 209 210 func doUnhealthyFunctionMock() { 211 buildMockUnhealthyInstances() 212 getCacheServicesFunc = mockGetUnhealthyServices 213 getCacheInstancesFunc = mockGetUnhealthyInstances 214 } 215 216 func mockGetUnhealthyServices(namingServer service.DiscoverServer, namespace string) map[string]*model.Service { 217 var newServices = make(map[string]*model.Service) 218 for _, svc := range mockUnhealthyServices { 219 if namespace == svc.Namespace { 220 newServices[svc.ID] = svc 221 } 222 } 223 return newServices 224 } 225 226 func mockGetUnhealthyInstances(namingServer service.DiscoverServer, svcId string) ([]*model.Instance, string, error) { 227 instances := mockUnhealthyInstances[svcId] 228 var retValue = make([]*model.Instance, 0, len(instances)) 229 if len(instances) == 0 { 230 return retValue, uuid.NewString(), nil 231 } 232 for _, instance := range instances { 233 retValue = append(retValue, instance) 234 } 235 return retValue, uuid.NewString(), nil 236 } 237 238 // TestBuildDataCenterInfo test to build dci info 239 func TestBuildDataCenterInfo(t *testing.T) { 240 CustomEurekaParameters[CustomKeyDciClass] = "com.netflix.appinfo.AmazonInfo" 241 CustomEurekaParameters[CustomKeyDciName] = "testOwn" 242 dciInfo := buildDataCenterInfo() 243 assert.Equal(t, CustomEurekaParameters[CustomKeyDciClass], dciInfo.Clazz) 244 assert.Equal(t, CustomEurekaParameters[CustomKeyDciName], dciInfo.Name) 245 delete(CustomEurekaParameters, CustomKeyDciName) 246 dciInfo = buildDataCenterInfo() 247 assert.Equal(t, CustomEurekaParameters[CustomKeyDciClass], dciInfo.Clazz) 248 assert.Equal(t, DefaultDciName, dciInfo.Name) 249 delete(CustomEurekaParameters, CustomKeyDciClass) 250 CustomEurekaParameters[CustomKeyDciName] = "testOwn" 251 dciInfo = buildDataCenterInfo() 252 assert.Equal(t, DefaultDciClazz, dciInfo.Clazz) 253 assert.Equal(t, CustomEurekaParameters[CustomKeyDciName], dciInfo.Name) 254 delete(CustomEurekaParameters, CustomKeyDciName) 255 dciInfo = buildDataCenterInfo() 256 assert.Equal(t, DefaultDciClazz, dciInfo.Clazz) 257 assert.Equal(t, DefaultDciName, dciInfo.Name) 258 } 259 260 // TestBuildInstance test to build the instance 261 func TestBuildInstance(t *testing.T) { 262 CustomEurekaParameters[CustomKeyDciClass] = "com.netflix.appinfo.AmazonInfo" 263 svc := &model.Service{ID: "111", Name: "testInst0", Namespace: "test"} 264 instance := buildMockInstance(0, svc, true, "xxx.com", "yyyy.com") 265 instanceInfo := buildInstance(svc.Name, instance.Proto, 123345550) 266 assert.Equal(t, CustomEurekaParameters[CustomKeyDciClass], instanceInfo.DataCenterInfo.Clazz) 267 }