github.com/polarismesh/polaris@v1.17.8/service/routing_config_v1_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 service_test 19 20 import ( 21 "encoding/json" 22 "fmt" 23 "reflect" 24 "testing" 25 26 "github.com/golang/protobuf/ptypes" 27 "github.com/polarismesh/specification/source/go/api/v1/model" 28 apimodel "github.com/polarismesh/specification/source/go/api/v1/model" 29 apiservice "github.com/polarismesh/specification/source/go/api/v1/service_manage" 30 apitraffic "github.com/polarismesh/specification/source/go/api/v1/traffic_manage" 31 "github.com/stretchr/testify/assert" 32 "google.golang.org/protobuf/types/known/wrapperspb" 33 34 api "github.com/polarismesh/polaris/common/api/v1" 35 "github.com/polarismesh/polaris/common/utils" 36 testsuit "github.com/polarismesh/polaris/test/suit" 37 ) 38 39 // 检查routingConfig前后是否一致 40 func checkSameRoutingConfig(t *testing.T, lhs *apitraffic.Routing, rhs *apitraffic.Routing) { 41 if lhs.GetService().GetValue() != rhs.GetService().GetValue() || 42 lhs.GetNamespace().GetValue() != rhs.GetNamespace().GetValue() { 43 t.Fatalf("error: (%s), (%s)", lhs, rhs) 44 } 45 46 checkFunc := func(labels string, in []*apitraffic.Route, out []*apitraffic.Route) bool { 47 if len(in) == 0 && len(out) == 0 { 48 return true 49 } 50 51 inStr, err := json.Marshal(in) 52 assert.NoError(t, err) 53 outStr, err := json.Marshal(out) 54 assert.NoError(t, err) 55 56 if in == nil || out == nil { 57 t.Fatalf("%s error: empty (%s), (%s)", labels, string(inStr), string(outStr)) 58 return false 59 } 60 61 assert.Equalf(t, len(in), len(out), "%s len(in) != len(out)", labels) 62 63 inRoutes := []*apitraffic.Route{} 64 outRoutes := []*apitraffic.Route{} 65 66 if err := json.Unmarshal(inStr, &inRoutes); err != nil { 67 t.Fatal(err) 68 } 69 70 if err := json.Unmarshal(outStr, &outRoutes); err != nil { 71 t.Fatal(err) 72 } 73 74 for i := range inRoutes { 75 for j := range inRoutes[i].Destinations { 76 inRoutes[i].Destinations[j].Name = nil 77 inRoutes[i].Destinations[j].Isolate = nil 78 outRoutes[i].Destinations[j].Name = nil 79 outRoutes[i].Destinations[j].Isolate = nil 80 } 81 } 82 83 if !reflect.DeepEqual(inRoutes, outRoutes) { 84 t.Fatalf("%s error: (%s), (%s)", labels, string(inStr), string(outStr)) 85 return false 86 } 87 88 return true 89 } 90 91 checkFunc("Inbounds", lhs.Inbounds, rhs.Inbounds) 92 checkFunc("Outbounds", lhs.Outbounds, rhs.Outbounds) 93 } 94 95 // 测试创建路由配置 96 func TestCreateRoutingConfig(t *testing.T) { 97 t.Run("正常创建路由配置配置请求", func(t *testing.T) { 98 discoverSuit := &DiscoverTestSuit{} 99 if err := discoverSuit.Initialize(); err != nil { 100 t.Fatal(err) 101 } 102 103 defer discoverSuit.Destroy() 104 _, serviceResp := discoverSuit.createCommonService(t, 200) 105 defer discoverSuit.cleanServiceName(serviceResp.GetName().GetValue(), serviceResp.GetNamespace().GetValue()) 106 _, _ = discoverSuit.createCommonRoutingConfig(t, serviceResp, 3, 0) 107 108 // 对写进去的数据进行查询 109 _ = discoverSuit.DiscoverServer().Cache().TestUpdate() 110 out := discoverSuit.DiscoverServer().GetRoutingConfigWithCache(discoverSuit.DefaultCtx, serviceResp) 111 defer discoverSuit.cleanCommonRoutingConfig(serviceResp.GetName().GetValue(), serviceResp.GetNamespace().GetValue()) 112 if !respSuccess(out) { 113 t.Fatalf("error: %+v", out) 114 } 115 }) 116 117 t.Run("参数缺失,报错", func(t *testing.T) { 118 discoverSuit := &DiscoverTestSuit{} 119 if err := discoverSuit.Initialize(); err != nil { 120 t.Fatal(err) 121 } 122 defer discoverSuit.Destroy() 123 124 _, serviceResp := discoverSuit.createCommonService(t, 20) 125 defer discoverSuit.cleanServiceName(serviceResp.GetName().GetValue(), serviceResp.GetNamespace().GetValue()) 126 127 req := &apitraffic.Routing{} 128 resp := discoverSuit.DiscoverServer().CreateRoutingConfigs(discoverSuit.DefaultCtx, []*apitraffic.Routing{req}) 129 assert.False(t, respSuccess(resp)) 130 t.Logf("%s", resp.GetInfo().GetValue()) 131 132 req.Service = serviceResp.Name 133 resp = discoverSuit.DiscoverServer().CreateRoutingConfigs(discoverSuit.DefaultCtx, []*apitraffic.Routing{req}) 134 assert.False(t, respSuccess(resp)) 135 t.Logf("%s", resp.GetInfo().GetValue()) 136 137 req.Namespace = serviceResp.Namespace 138 resp = discoverSuit.DiscoverServer().CreateRoutingConfigs(discoverSuit.DefaultCtx, []*apitraffic.Routing{req}) 139 defer discoverSuit.cleanCommonRoutingConfig(req.GetService().GetValue(), req.GetNamespace().GetValue()) 140 assert.True(t, respSuccess(resp)) 141 t.Logf("%s", resp.GetInfo().GetValue()) 142 }) 143 144 t.Run("服务不存在,创建路由配置不报错", func(t *testing.T) { 145 discoverSuit := &DiscoverTestSuit{} 146 if err := discoverSuit.Initialize(); err != nil { 147 t.Fatal(err) 148 } 149 defer discoverSuit.Destroy() 150 151 _, serviceResp := discoverSuit.createCommonService(t, 120) 152 discoverSuit.cleanServiceName(serviceResp.GetName().GetValue(), serviceResp.GetNamespace().GetValue()) 153 154 _ = discoverSuit.DiscoverServer().Cache().TestUpdate() 155 req := &apitraffic.Routing{} 156 req.Service = serviceResp.Name 157 req.Namespace = serviceResp.Namespace 158 req.ServiceToken = serviceResp.Token 159 resp := discoverSuit.DiscoverServer().CreateRoutingConfigs(discoverSuit.DefaultCtx, []*apitraffic.Routing{req}) 160 assert.False(t, respSuccess(resp)) 161 t.Logf("%s", resp.GetInfo().GetValue()) 162 }) 163 } 164 165 // 测试创建路由配置 166 func TestUpdateRoutingConfig(t *testing.T) { 167 t.Run("更新V1路由规则, 成功转为V2规则", func(t *testing.T) { 168 discoverSuit := &DiscoverTestSuit{} 169 if err := discoverSuit.Initialize(); err != nil { 170 t.Fatal(err) 171 } 172 173 _, svc := discoverSuit.createCommonService(t, 200) 174 v1Rule, _ := discoverSuit.createCommonRoutingConfigV1IntoOldStore(t, svc, 3, 0) 175 t.Cleanup(func() { 176 discoverSuit.cleanServiceName(svc.GetName().GetValue(), svc.GetNamespace().GetValue()) 177 discoverSuit.cleanCommonRoutingConfig(svc.GetName().GetValue(), svc.GetNamespace().GetValue()) 178 discoverSuit.truncateCommonRoutingConfigV2() 179 discoverSuit.Destroy() 180 }) 181 182 v1Rule.Outbounds = v1Rule.Inbounds 183 uResp := discoverSuit.DiscoverServer().UpdateRoutingConfigs(discoverSuit.DefaultCtx, []*apitraffic.Routing{v1Rule}) 184 assert.True(t, respSuccess(uResp)) 185 186 // 等缓存层更新 187 _ = discoverSuit.DiscoverServer().Cache().TestUpdate() 188 189 // 直接查询存储无法查询到 v1 的路由规则 190 total, routingsV1, err := discoverSuit.Storage.GetRoutingConfigs(map[string]string{}, 0, 100) 191 assert.NoError(t, err, err) 192 assert.Equal(t, uint32(0), total, "v1 routing must delete and transfer to v1") 193 assert.Equal(t, 0, len(routingsV1), "v1 routing ret len need zero") 194 195 // 从缓存中查询应该查到 6 条 v2 的路由规则 196 out := discoverSuit.DiscoverServer().QueryRoutingConfigsV2(discoverSuit.DefaultCtx, map[string]string{ 197 "limit": "100", 198 "offset": "0", 199 }) 200 if !respSuccess(out) { 201 t.Fatalf("error: %+v", out) 202 } 203 assert.Equal(t, int(6), int(out.GetAmount().GetValue()), "query routing size") 204 rulesV2, err := unmarshalRoutingV2toAnySlice(out.GetData()) 205 assert.NoError(t, err) 206 for i := range rulesV2 { 207 item := rulesV2[i] 208 assert.True(t, item.Enable, "v1 to v2 need default open enable") 209 msg := &apitraffic.RuleRoutingConfig{} 210 err := ptypes.UnmarshalAny(item.GetRoutingConfig(), msg) 211 assert.NoError(t, err) 212 assert.True(t, len(msg.GetSources()) == 0, "RuleRoutingConfig.Sources len != 0") 213 assert.True(t, len(msg.GetDestinations()) == 0, "RuleRoutingConfig.Destinations len != 0") 214 assert.True(t, len(msg.GetRules()) != 0, "RuleRoutingConfig.Rules len == 0") 215 } 216 }) 217 } 218 219 // 测试缓存获取路由配置 220 func TestGetRoutingConfigWithCache(t *testing.T) { 221 222 t.Run("多个服务的,多个路由配置,都可以查询到", func(t *testing.T) { 223 discoverSuit := &DiscoverTestSuit{} 224 if err := discoverSuit.Initialize(); err != nil { 225 t.Fatal(err) 226 } 227 defer discoverSuit.Destroy() 228 229 total := 20 230 serviceResps := make([]*apiservice.Service, 0, total) 231 routingResps := make([]*apitraffic.Routing, 0, total) 232 for i := 0; i < total; i++ { 233 _, resp := discoverSuit.createCommonService(t, i) 234 defer discoverSuit.cleanServiceName(resp.GetName().GetValue(), resp.GetNamespace().GetValue()) 235 serviceResps = append(serviceResps, resp) 236 237 _, routingResp := discoverSuit.createCommonRoutingConfig(t, resp, 2, 0) 238 defer discoverSuit.cleanCommonRoutingConfig(resp.GetName().GetValue(), resp.GetNamespace().GetValue()) 239 routingResps = append(routingResps, routingResp) 240 } 241 242 _ = discoverSuit.DiscoverServer().Cache().TestUpdate() 243 for i := 0; i < total; i++ { 244 t.Logf("service : name=%s namespace=%s", serviceResps[i].GetName().GetValue(), serviceResps[i].GetNamespace().GetValue()) 245 out := discoverSuit.DiscoverServer().GetRoutingConfigWithCache(discoverSuit.DefaultCtx, serviceResps[i]) 246 checkSameRoutingConfig(t, routingResps[i], out.GetRouting()) 247 } 248 }) 249 250 t.Run("走v2接口创建路由规则,不启用查不到,启用可以查到", func(t *testing.T) { 251 discoverSuit := &DiscoverTestSuit{} 252 if err := discoverSuit.Initialize(); err != nil { 253 t.Fatal(err) 254 } 255 defer discoverSuit.Destroy() 256 257 resp := discoverSuit.createCommonRoutingConfigV2(t, 1) 258 assert.Equal(t, 1, len(resp)) 259 260 svcName := fmt.Sprintf("in-source-service-%d", 0) 261 namespaceName := fmt.Sprintf("in-source-service-%d", 0) 262 263 svcResp := discoverSuit.DiscoverServer().CreateServices(discoverSuit.DefaultCtx, []*apiservice.Service{{ 264 Name: utils.NewStringValue(svcName), 265 Namespace: utils.NewStringValue(namespaceName), 266 }}) 267 defer discoverSuit.cleanServiceName(svcName, namespaceName) 268 if !respSuccess(svcResp) { 269 t.Fatal(svcResp.Info) 270 } 271 272 _ = discoverSuit.DiscoverServer().Cache().TestUpdate() 273 t.Logf("service : name=%s namespace=%s", svcName, namespaceName) 274 out := discoverSuit.DiscoverServer().GetRoutingConfigWithCache(discoverSuit.DefaultCtx, &apiservice.Service{ 275 Name: utils.NewStringValue(svcName), 276 Namespace: utils.NewStringValue(namespaceName), 277 }) 278 279 assert.True(t, len(out.GetRouting().GetOutbounds()) == 0, "inBounds must be zero") 280 281 _ = discoverSuit.DiscoverServer().Cache().TestUpdate() 282 283 enableResp := discoverSuit.DiscoverServer().EnableRoutings(discoverSuit.DefaultCtx, []*apitraffic.RouteRule{ 284 { 285 Id: resp[0].Id, 286 Enable: true, 287 }, 288 }) 289 290 if !respSuccess(enableResp) { 291 t.Fatal(enableResp.Info) 292 } 293 294 _ = discoverSuit.DiscoverServer().Cache().TestUpdate() 295 out = discoverSuit.DiscoverServer().GetRoutingConfigWithCache(discoverSuit.DefaultCtx, &apiservice.Service{ 296 Name: utils.NewStringValue(svcName), 297 Namespace: utils.NewStringValue(namespaceName), 298 }) 299 300 assert.True(t, len(out.GetRouting().GetOutbounds()) == 1, "inBounds must be one") 301 }) 302 303 t.Run("走v2接口创建路由规则,通配服务", func(t *testing.T) { 304 discoverSuit := &DiscoverTestSuit{} 305 if err := discoverSuit.Initialize(); err != nil { 306 t.Fatal(err) 307 } 308 defer discoverSuit.Destroy() 309 310 rules := testsuit.MockRoutingV2(t, 1) 311 ruleRoutings := &apitraffic.RuleRoutingConfig{ 312 Sources: []*apitraffic.SourceService{ 313 { 314 Service: "*", 315 Namespace: "*", 316 Arguments: []*apitraffic.SourceMatch{ 317 { 318 Type: apitraffic.SourceMatch_CUSTOM, 319 Key: "key", 320 Value: &apimodel.MatchString{ 321 Type: apimodel.MatchString_EXACT, 322 Value: &wrapperspb.StringValue{ 323 Value: "123", 324 }, 325 ValueType: apimodel.MatchString_TEXT, 326 }, 327 }, 328 }, 329 }, 330 }, 331 Destinations: []*apitraffic.DestinationGroup{ 332 { 333 Service: "mock-servcie-test1", 334 Namespace: "mock-namespace-test1", 335 Labels: map[string]*apimodel.MatchString{ 336 "key": { 337 Type: apimodel.MatchString_EXACT, 338 Value: &wrapperspb.StringValue{ 339 Value: "value", 340 }, 341 ValueType: apimodel.MatchString_TEXT, 342 }, 343 }, 344 Priority: 0, 345 Weight: 0, 346 Transfer: "", 347 Isolate: false, 348 Name: "123", 349 }, 350 }, 351 } 352 353 any, err := ptypes.MarshalAny(ruleRoutings) 354 if err != nil { 355 t.Fatal(err) 356 return 357 } 358 rules[0].RoutingPolicy = apitraffic.RoutingPolicy_RulePolicy 359 rules[0].RoutingConfig = any 360 361 resp := discoverSuit.createCommonRoutingConfigV2WithReq(t, rules) 362 defer discoverSuit.truncateCommonRoutingConfigV2() 363 assert.Equal(t, 1, len(resp)) 364 365 svcName := fmt.Sprintf("mock-source-service-%d", 0) 366 namespaceName := fmt.Sprintf("mock-source-service-%d", 0) 367 368 svcResp := discoverSuit.DiscoverServer().CreateServices(discoverSuit.DefaultCtx, []*apiservice.Service{{ 369 Name: utils.NewStringValue(svcName), 370 Namespace: utils.NewStringValue(namespaceName), 371 }}) 372 defer discoverSuit.cleanServiceName(svcName, namespaceName) 373 if !respSuccess(svcResp) { 374 t.Fatal(svcResp.Info) 375 } 376 377 _ = discoverSuit.DiscoverServer().Cache().TestUpdate() 378 t.Logf("service : name=%s namespace=%s", svcName, namespaceName) 379 out := discoverSuit.DiscoverServer().GetRoutingConfigWithCache(discoverSuit.DefaultCtx, &apiservice.Service{ 380 Name: utils.NewStringValue(svcName), 381 Namespace: utils.NewStringValue(namespaceName), 382 }) 383 384 assert.True(t, len(out.GetRouting().GetOutbounds()) == 0, "inBounds must be zero") 385 _ = discoverSuit.DiscoverServer().Cache().TestUpdate() 386 enableResp := discoverSuit.DiscoverServer().EnableRoutings(discoverSuit.DefaultCtx, []*apitraffic.RouteRule{ 387 { 388 Id: resp[0].Id, 389 Enable: true, 390 }, 391 }) 392 393 if !respSuccess(enableResp) { 394 t.Fatal(enableResp.Info) 395 } 396 397 _ = discoverSuit.DiscoverServer().Cache().TestUpdate() 398 out = discoverSuit.DiscoverServer().GetRoutingConfigWithCache(discoverSuit.DefaultCtx, &apiservice.Service{ 399 Name: utils.NewStringValue(svcName), 400 Namespace: utils.NewStringValue(namespaceName), 401 }) 402 403 assert.True(t, len(out.GetRouting().GetOutbounds()) == 1, "inBounds must be one") 404 }) 405 406 t.Run("服务路由数据不改变,传递了路由revision,不返回数据", func(t *testing.T) { 407 discoverSuit := &DiscoverTestSuit{} 408 if err := discoverSuit.Initialize(); err != nil { 409 t.Fatal(err) 410 } 411 defer discoverSuit.Destroy() 412 413 _, serviceResp := discoverSuit.createCommonService(t, 10) 414 defer discoverSuit.cleanServiceName(serviceResp.GetName().GetValue(), serviceResp.GetNamespace().GetValue()) 415 416 _, routingResp := discoverSuit.createCommonRoutingConfig(t, serviceResp, 2, 0) 417 defer discoverSuit.cleanCommonRoutingConfig(serviceResp.GetName().GetValue(), serviceResp.GetNamespace().GetValue()) 418 419 _ = discoverSuit.DiscoverServer().Cache().TestUpdate() 420 firstResp := discoverSuit.DiscoverServer().GetRoutingConfigWithCache(discoverSuit.DefaultCtx, serviceResp) 421 checkSameRoutingConfig(t, routingResp, firstResp.GetRouting()) 422 423 serviceResp.Revision = firstResp.Service.Revision 424 secondResp := discoverSuit.DiscoverServer().GetRoutingConfigWithCache(discoverSuit.DefaultCtx, serviceResp) 425 if secondResp.GetService().GetRevision().GetValue() != serviceResp.GetRevision().GetValue() { 426 t.Fatalf("error") 427 } 428 assert.Equal(t, model.Code(secondResp.GetCode().GetValue()), apimodel.Code_DataNoChange) 429 }) 430 t.Run("路由不存在,不会出异常", func(t *testing.T) { 431 discoverSuit := &DiscoverTestSuit{} 432 if err := discoverSuit.Initialize(); err != nil { 433 t.Fatal(err) 434 } 435 defer discoverSuit.Destroy() 436 437 _, serviceResp := discoverSuit.createCommonService(t, 10) 438 defer discoverSuit.cleanServiceName(serviceResp.GetName().GetValue(), serviceResp.GetNamespace().GetValue()) 439 _ = discoverSuit.DiscoverServer().Cache().TestUpdate() 440 if resp := discoverSuit.DiscoverServer().GetRoutingConfigWithCache(discoverSuit.DefaultCtx, serviceResp); !respSuccess(resp) { 441 t.Fatalf("error: %s", resp.GetInfo().GetValue()) 442 } 443 }) 444 } 445 446 // test对routing字段进行校验 447 func TestCheckRoutingFieldLen(t *testing.T) { 448 449 discoverSuit := &DiscoverTestSuit{} 450 if err := discoverSuit.Initialize(); err != nil { 451 t.Fatal(err) 452 } 453 defer discoverSuit.Destroy() 454 455 req := &apitraffic.Routing{ 456 ServiceToken: utils.NewStringValue("test"), 457 Service: utils.NewStringValue("test"), 458 Namespace: utils.NewStringValue("default"), 459 } 460 461 t.Run("创建路由规则,服务名超长", func(t *testing.T) { 462 str := genSpecialStr(129) 463 oldName := req.Service 464 req.Service = utils.NewStringValue(str) 465 resp := discoverSuit.DiscoverServer().CreateRoutingConfigs(discoverSuit.DefaultCtx, []*apitraffic.Routing{req}) 466 req.Service = oldName 467 if resp.Code.Value != api.InvalidServiceName { 468 t.Fatalf("%+v", resp) 469 } 470 }) 471 t.Run("创建路由规则,命名空间超长", func(t *testing.T) { 472 str := genSpecialStr(129) 473 oldNamespace := req.Namespace 474 req.Namespace = utils.NewStringValue(str) 475 resp := discoverSuit.DiscoverServer().CreateRoutingConfigs(discoverSuit.DefaultCtx, []*apitraffic.Routing{req}) 476 req.Namespace = oldNamespace 477 if resp.Code.Value != api.InvalidNamespaceName { 478 t.Fatalf("%+v", resp) 479 } 480 }) 481 t.Run("创建路由规则,toeken超长", func(t *testing.T) { 482 str := genSpecialStr(2049) 483 oldServiceToken := req.ServiceToken 484 req.ServiceToken = utils.NewStringValue(str) 485 resp := discoverSuit.DiscoverServer().CreateRoutingConfigs(discoverSuit.DefaultCtx, []*apitraffic.Routing{req}) 486 req.ServiceToken = oldServiceToken 487 if resp.Code.Value != api.InvalidServiceToken { 488 t.Fatalf("%+v", resp) 489 } 490 }) 491 }