github.com/polarismesh/polaris@v1.17.8/test/suit/test_suit.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 testsuit 19 20 import ( 21 "context" 22 "database/sql" 23 "errors" 24 "fmt" 25 "net/http" 26 _ "net/http/pprof" 27 "os" 28 "path/filepath" 29 "strings" 30 "time" 31 32 _ "github.com/go-sql-driver/mysql" 33 "github.com/google/uuid" 34 apiservice "github.com/polarismesh/specification/source/go/api/v1/service_manage" 35 apitraffic "github.com/polarismesh/specification/source/go/api/v1/traffic_manage" 36 bolt "go.etcd.io/bbolt" 37 "gopkg.in/yaml.v2" 38 39 "github.com/polarismesh/polaris/auth" 40 _ "github.com/polarismesh/polaris/auth/defaultauth" 41 "github.com/polarismesh/polaris/cache" 42 cachetypes "github.com/polarismesh/polaris/cache/api" 43 api "github.com/polarismesh/polaris/common/api/v1" 44 "github.com/polarismesh/polaris/common/eventhub" 45 "github.com/polarismesh/polaris/common/log" 46 commonlog "github.com/polarismesh/polaris/common/log" 47 "github.com/polarismesh/polaris/common/metrics" 48 "github.com/polarismesh/polaris/common/utils" 49 "github.com/polarismesh/polaris/config" 50 ns "github.com/polarismesh/polaris/namespace" 51 "github.com/polarismesh/polaris/plugin" 52 _ "github.com/polarismesh/polaris/plugin/cmdb/memory" 53 _ "github.com/polarismesh/polaris/plugin/crypto/aes" 54 _ "github.com/polarismesh/polaris/plugin/discoverevent/local" 55 _ "github.com/polarismesh/polaris/plugin/healthchecker/leader" 56 _ "github.com/polarismesh/polaris/plugin/healthchecker/memory" 57 _ "github.com/polarismesh/polaris/plugin/healthchecker/redis" 58 _ "github.com/polarismesh/polaris/plugin/history/logger" 59 _ "github.com/polarismesh/polaris/plugin/password" 60 _ "github.com/polarismesh/polaris/plugin/ratelimit/lrurate" 61 _ "github.com/polarismesh/polaris/plugin/ratelimit/token" 62 _ "github.com/polarismesh/polaris/plugin/statis/logger" 63 _ "github.com/polarismesh/polaris/plugin/statis/prometheus" 64 "github.com/polarismesh/polaris/service" 65 "github.com/polarismesh/polaris/service/batch" 66 "github.com/polarismesh/polaris/service/healthcheck" 67 "github.com/polarismesh/polaris/store" 68 "github.com/polarismesh/polaris/store/boltdb" 69 _ "github.com/polarismesh/polaris/store/boltdb" 70 sqldb "github.com/polarismesh/polaris/store/mysql" 71 testdata "github.com/polarismesh/polaris/test/data" 72 ) 73 74 func init() { 75 go func() { 76 http.ListenAndServe("0.0.0.0:16060", nil) 77 }() 78 } 79 80 const ( 81 tblNameNamespace = "namespace" 82 tblNameInstance = "instance" 83 tblNameService = "service" 84 tblNameRouting = "routing" 85 tblRateLimitConfig = "ratelimit_config" 86 tblRateLimitRevision = "ratelimit_revision" 87 tblCircuitBreaker = "circuitbreaker_rule" 88 tblCircuitBreakerRelation = "circuitbreaker_rule_relation" 89 tblNameL5 = "l5" 90 tblNameRoutingV2 = "routing_config_v2" 91 tblClient = "client" 92 ) 93 94 var ( 95 testNamespace = "testNamespace123qwe" 96 testGroup = "testGroup" 97 testFile = "testFile" 98 testContent = "testContent" 99 operator = "polaris" 100 size = 7 101 ) 102 103 const ( 104 templateName1 = "t1" 105 templateName2 = "t2" 106 ) 107 108 type Bootstrap struct { 109 Logger map[string]*commonlog.Options 110 } 111 112 type TestConfig struct { 113 Bootstrap Bootstrap `yaml:"bootstrap"` 114 Cache cache.Config `yaml:"cache"` 115 Namespace ns.Config `yaml:"namespace"` 116 Naming service.Config `yaml:"naming"` 117 Config config.Config `yaml:"config"` 118 HealthChecks healthcheck.Config `yaml:"healthcheck"` 119 Store store.Config `yaml:"store"` 120 Auth auth.Config `yaml:"auth"` 121 Plugin plugin.Config `yaml:"plugin"` 122 ReplaceStore store.Store 123 } 124 125 var InjectTestDataClean func() TestDataClean 126 127 func SetTestDataClean(callback func() TestDataClean) { 128 InjectTestDataClean = callback 129 } 130 131 type DiscoverTestSuit struct { 132 cfg *TestConfig 133 configServer config.ConfigCenterServer 134 configOriginSvr config.ConfigCenterServer 135 server service.DiscoverServer 136 originSvr service.DiscoverServer 137 healthCheckServer *healthcheck.Server 138 cacheMgr *cache.CacheManager 139 userMgn auth.UserServer 140 strategyMgn auth.StrategyServer 141 namespaceSvr ns.NamespaceOperateServer 142 cancelFlag bool 143 updateCacheInterval time.Duration 144 DefaultCtx context.Context 145 cancel context.CancelFunc 146 Storage store.Store 147 bc *batch.Controller 148 cleanDataOp TestDataClean 149 caller func() store.Store 150 } 151 152 func (d *DiscoverTestSuit) InjectSuit(*DiscoverTestSuit) { 153 154 } 155 156 func (d *DiscoverTestSuit) CacheMgr() *cache.CacheManager { 157 return d.cacheMgr 158 } 159 160 func (d *DiscoverTestSuit) GetTestDataClean() TestDataClean { 161 return d.cleanDataOp 162 } 163 164 func (d *DiscoverTestSuit) DiscoverServer() service.DiscoverServer { 165 return d.server 166 } 167 168 func (d *DiscoverTestSuit) OriginDiscoverServer() service.DiscoverServer { 169 return d.originSvr 170 } 171 172 func (d *DiscoverTestSuit) ConfigServer() config.ConfigCenterServer { 173 return d.configServer 174 } 175 176 func (d *DiscoverTestSuit) OriginConfigServer() *config.Server { 177 return d.configOriginSvr.(*config.Server) 178 } 179 180 func (d *DiscoverTestSuit) HealthCheckServer() *healthcheck.Server { 181 return d.healthCheckServer 182 } 183 184 func (d *DiscoverTestSuit) NamespaceServer() ns.NamespaceOperateServer { 185 return d.namespaceSvr 186 } 187 188 func (d *DiscoverTestSuit) UserServer() auth.UserServer { 189 return d.userMgn 190 } 191 192 func (d *DiscoverTestSuit) StrategyServer() auth.StrategyServer { 193 return d.strategyMgn 194 } 195 196 func (d *DiscoverTestSuit) UpdateCacheInterval() time.Duration { 197 return d.updateCacheInterval 198 } 199 200 func (d *DiscoverTestSuit) BatchController() *batch.Controller { 201 return d.bc 202 } 203 204 // 加载配置 205 func (d *DiscoverTestSuit) loadConfig() error { 206 207 d.cfg = new(TestConfig) 208 209 confFileName := testdata.Path("service_test.yaml") 210 if os.Getenv("STORE_MODE") == "sqldb" { 211 fmt.Printf("run store mode : sqldb\n") 212 confFileName = testdata.Path("service_test_sqldb.yaml") 213 d.DefaultCtx = context.WithValue(d.DefaultCtx, utils.ContextAuthTokenKey, 214 "nu/0WRA4EqSR1FagrjRj0fZwPXuGlMpX+zCuWu4uMqy8xr1vRjisSbA25aAC3mtU8MeeRsKhQiDAynUR09I=") 215 } else { 216 fmt.Printf("run store mode : boltdb\n") 217 } 218 // 如果有额外定制的配置文件,优先采用 219 if val := os.Getenv("POLARIS_TEST_BOOTSTRAP_FILE"); val != "" { 220 confFileName = val 221 } 222 buf, err := os.ReadFile(confFileName) 223 if nil != err { 224 return fmt.Errorf("read file %s error", confFileName) 225 } 226 227 if err = parseYamlContent(string(buf), d.cfg); err != nil { 228 fmt.Printf("[ERROR] %v\n", err) 229 return err 230 } 231 232 resources := d.cfg.Cache.Resources 233 for i := range resources { 234 item := resources[i] 235 if item.Name == "configFile" { 236 item.Option = map[string]interface{}{ 237 "cachePath": filepath.Join("/tmp/polaris/cache/", uuid.NewString()), 238 } 239 } 240 resources[i] = item 241 } 242 d.cfg.Cache.Resources = resources 243 244 return err 245 } 246 247 func parseYamlContent(content string, conf *TestConfig) error { 248 if err := yaml.Unmarshal([]byte(replaceEnv(content)), conf); nil != err { 249 return fmt.Errorf("parse yaml %s error:%w", content, err) 250 } 251 return nil 252 } 253 254 // replaceEnv replace holder by env list 255 func replaceEnv(configContent string) string { 256 return os.ExpandEnv(configContent) 257 } 258 259 // 判断一个resp是否执行成功 260 func RespSuccess(resp api.ResponseMessage) bool { 261 ret := api.CalcCode(resp) == 200 262 return ret 263 } 264 265 type options func(cfg *TestConfig) 266 267 func (d *DiscoverTestSuit) Initialize(opts ...options) error { 268 return d.initialize(opts...) 269 } 270 271 func (d *DiscoverTestSuit) ReplaceStore(caller func() store.Store) { 272 d.caller = caller 273 } 274 275 // 内部初始化函数 276 func (d *DiscoverTestSuit) initialize(opts ...options) error { 277 // 初始化defaultCtx 278 d.DefaultCtx = context.WithValue(context.Background(), utils.StringContext("request-id"), "test-1") 279 d.DefaultCtx = context.WithValue(d.DefaultCtx, utils.ContextAuthTokenKey, 280 "nu/0WRA4EqSR1FagrjRj0fZwPXuGlMpX+zCuWu4uMqy8xr1vRjisSbA25aAC3mtU8MeeRsKhQiDAynUR09I=") 281 282 if err := os.RemoveAll("polaris.bolt"); err != nil { 283 if !errors.Is(err, os.ErrNotExist) { 284 panic(err) 285 } 286 } 287 288 if err := d.loadConfig(); err != nil { 289 panic(err) 290 } 291 292 for i := range opts { 293 opts[i](d.cfg) 294 } 295 296 d.cleanDataOp = d 297 if InjectTestDataClean != nil { 298 d.cleanDataOp = InjectTestDataClean() 299 } 300 // 注入测试套件相关数据信息 301 d.cleanDataOp.InjectSuit(d) 302 303 _ = commonlog.Configure(d.cfg.Bootstrap.Logger) 304 305 metrics.InitMetrics() 306 eventhub.InitEventHub() 307 308 // 初始化存储层 309 if d.caller != nil { 310 d.Storage = d.caller() 311 } else { 312 store.SetStoreConfig(&d.cfg.Store) 313 s, _ := store.TestGetStore() 314 d.Storage = s 315 } 316 317 plugin.SetPluginConfig(&d.cfg.Plugin) 318 319 ctx, cancel := context.WithCancel(context.Background()) 320 321 d.cancel = cancel 322 323 // 初始化缓存模块 324 cacheMgn, err := cache.TestCacheInitialize(ctx, &d.cfg.Cache, d.Storage) 325 if err != nil { 326 panic(err) 327 } 328 d.cacheMgr = cacheMgn 329 330 // 初始化鉴权层 331 userMgn, strategyMgn, err := auth.TestInitialize(ctx, &d.cfg.Auth, d.Storage, cacheMgn) 332 if err != nil { 333 panic(err) 334 } 335 d.userMgn = userMgn 336 d.strategyMgn = strategyMgn 337 338 // 初始化命名空间模块 339 namespaceSvr, err := ns.TestInitialize(ctx, &d.cfg.Namespace, d.Storage, cacheMgn, userMgn, strategyMgn) 340 if err != nil { 341 panic(err) 342 } 343 d.namespaceSvr = namespaceSvr 344 345 // 批量控制器 346 namingBatchConfig, err := batch.ParseBatchConfig(d.cfg.Naming.Batch) 347 if err != nil { 348 panic(err) 349 } 350 healthBatchConfig, err := batch.ParseBatchConfig(d.cfg.HealthChecks.Batch) 351 if err != nil { 352 panic(err) 353 } 354 355 batchConfig := &batch.Config{ 356 Register: namingBatchConfig.Register, 357 Deregister: namingBatchConfig.Register, 358 ClientRegister: namingBatchConfig.ClientRegister, 359 ClientDeregister: namingBatchConfig.ClientDeregister, 360 Heartbeat: healthBatchConfig.Heartbeat, 361 } 362 363 bc, err := batch.NewBatchCtrlWithConfig(d.Storage, cacheMgn, batchConfig) 364 if err != nil { 365 log.Errorf("new batch ctrl with config err: %s", err.Error()) 366 panic(err) 367 } 368 bc.Start(ctx) 369 d.bc = bc 370 371 if len(d.cfg.HealthChecks.LocalHost) == 0 { 372 d.cfg.HealthChecks.LocalHost = utils.LocalHost // 补充healthCheck的配置 373 } 374 healthCheckServer, err := healthcheck.TestInitialize(ctx, &d.cfg.HealthChecks, d.cfg.Cache.Open, bc, d.Storage) 375 if err != nil { 376 panic(err) 377 } 378 healthcheck.SetServer(healthCheckServer) 379 d.healthCheckServer = healthCheckServer 380 cacheProvider, err := healthCheckServer.CacheProvider() 381 if err != nil { 382 panic(err) 383 } 384 healthCheckServer.SetServiceCache(cacheMgn.Service()) 385 healthCheckServer.SetInstanceCache(cacheMgn.Instance()) 386 387 // 为 instance 的 cache 添加 健康检查的 Listener 388 cacheMgn.AddListener(cachetypes.CacheInstance, []cachetypes.Listener{cacheProvider}) 389 cacheMgn.AddListener(cachetypes.CacheClient, []cachetypes.Listener{cacheProvider}) 390 391 val, originVal, err := service.TestInitialize(ctx, &d.cfg.Naming, &d.cfg.Cache, bc, cacheMgn, d.Storage, namespaceSvr, 392 healthCheckServer, userMgn, strategyMgn) 393 if err != nil { 394 panic(err) 395 } 396 d.server = val 397 d.originSvr = originVal 398 399 confVal, confOriginVal, err := config.TestInitialize(ctx, d.cfg.Config, d.Storage, cacheMgn, namespaceSvr, userMgn, strategyMgn) 400 if err != nil { 401 panic(err) 402 } 403 d.configServer = confVal 404 d.configOriginSvr = confOriginVal 405 406 // 多等待一会 407 d.updateCacheInterval = d.server.Cache().GetUpdateCacheInterval() + time.Millisecond*500 408 409 time.Sleep(5 * time.Second) 410 return nil 411 } 412 413 func (d *DiscoverTestSuit) Destroy() { 414 d.cancel() 415 d.healthCheckServer.Destroy() 416 _ = d.cacheMgr.Close() 417 _ = d.Storage.Destroy() 418 } 419 420 func (d *DiscoverTestSuit) CleanReportClient() { 421 if d.Storage.Name() == sqldb.STORENAME { 422 func() { 423 tx, err := d.Storage.StartTx() 424 if err != nil { 425 panic(err) 426 } 427 428 dbTx := tx.GetDelegateTx().(*sqldb.BaseTx) 429 defer rollbackDbTx(dbTx) 430 431 if _, err := dbTx.Exec("delete from client"); err != nil { 432 panic(err) 433 } 434 if _, err := dbTx.Exec("delete from client_stat"); err != nil { 435 panic(err) 436 } 437 438 commitDbTx(dbTx) 439 }() 440 } else if d.Storage.Name() == boltdb.STORENAME { 441 func() { 442 tx, err := d.Storage.StartTx() 443 if err != nil { 444 panic(err) 445 } 446 447 dbTx := tx.GetDelegateTx().(*bolt.Tx) 448 defer rollbackBoltTx(dbTx) 449 450 if err := dbTx.DeleteBucket([]byte(tblClient)); err != nil { 451 if !errors.Is(err, bolt.ErrBucketNotFound) { 452 rollbackBoltTx(dbTx) 453 panic(err) 454 } 455 } 456 457 commitBoltTx(dbTx) 458 }() 459 } 460 } 461 462 func rollbackDbTx(dbTx *sqldb.BaseTx) { 463 if err := dbTx.Rollback(); err != nil { 464 log.Errorf("fail to rollback db tx, err %v", err) 465 } 466 } 467 468 func commitDbTx(dbTx *sqldb.BaseTx) { 469 if err := dbTx.Commit(); err != nil { 470 log.Errorf("fail to commit db tx, err %v", err) 471 } 472 } 473 474 func rollbackBoltTx(tx *bolt.Tx) { 475 if err := tx.Rollback(); err != nil { 476 log.Errorf("fail to rollback bolt tx, err %v", err) 477 } 478 } 479 480 func commitBoltTx(tx *bolt.Tx) { 481 if err := tx.Commit(); err != nil { 482 log.Errorf("fail to commit bolt tx, err %v", err) 483 } 484 } 485 486 // 从数据库彻底删除命名空间 487 func (d *DiscoverTestSuit) CleanNamespace(name string) { 488 if name == "" { 489 panic("name is empty") 490 } 491 492 log.Infof("clean namespace: %s", name) 493 494 if d.Storage.Name() == sqldb.STORENAME { 495 str := "delete from namespace where name = ?" 496 func() { 497 tx, err := d.Storage.StartTx() 498 if err != nil { 499 panic(err) 500 } 501 502 dbTx := tx.GetDelegateTx().(*sqldb.BaseTx) 503 defer rollbackDbTx(dbTx) 504 505 if _, err := dbTx.Exec(str, name); err != nil { 506 panic(err) 507 } 508 509 commitDbTx(dbTx) 510 }() 511 } else if d.Storage.Name() == boltdb.STORENAME { 512 func() { 513 tx, err := d.Storage.StartTx() 514 if err != nil { 515 panic(err) 516 } 517 518 dbTx := tx.GetDelegateTx().(*bolt.Tx) 519 if err := dbTx.Bucket([]byte(tblNameNamespace)).DeleteBucket([]byte(name)); err != nil { 520 if !errors.Is(err, bolt.ErrBucketNotFound) { 521 rollbackBoltTx(dbTx) 522 panic(err) 523 } 524 } 525 526 commitBoltTx(dbTx) 527 }() 528 } 529 } 530 531 // 从数据库彻底删除全部服务 532 func (d *DiscoverTestSuit) CleanAllService() { 533 534 if d.Storage.Name() == sqldb.STORENAME { 535 func() { 536 tx, err := d.Storage.StartTx() 537 if err != nil { 538 panic(err) 539 } 540 541 dbTx := tx.GetDelegateTx().(*sqldb.BaseTx) 542 543 defer rollbackDbTx(dbTx) 544 545 if _, err := dbTx.Exec("delete from service_metadata"); err != nil { 546 rollbackDbTx(dbTx) 547 panic(err) 548 } 549 550 if _, err := dbTx.Exec("delete from service"); err != nil { 551 rollbackDbTx(dbTx) 552 panic(err) 553 } 554 555 if _, err := dbTx.Exec("delete from owner_service_map"); err != nil { 556 rollbackDbTx(dbTx) 557 panic(err) 558 } 559 560 commitDbTx(dbTx) 561 }() 562 } else if d.Storage.Name() == boltdb.STORENAME { 563 func() { 564 tx, err := d.Storage.StartTx() 565 if err != nil { 566 panic(err) 567 } 568 569 dbTx := tx.GetDelegateTx().(*bolt.Tx) 570 defer rollbackBoltTx(dbTx) 571 572 if err := dbTx.DeleteBucket([]byte(tblNameService)); err != nil { 573 if !errors.Is(err, bolt.ErrBucketNotFound) { 574 rollbackBoltTx(dbTx) 575 panic(err) 576 } 577 } 578 579 commitBoltTx(dbTx) 580 }() 581 } 582 } 583 584 // 从数据库彻底删除服务 585 func (d *DiscoverTestSuit) CleanService(name, namespace string) { 586 587 if d.Storage.Name() == sqldb.STORENAME { 588 func() { 589 tx, err := d.Storage.StartTx() 590 if err != nil { 591 panic(err) 592 } 593 594 dbTx := tx.GetDelegateTx().(*sqldb.BaseTx) 595 596 defer rollbackDbTx(dbTx) 597 598 str := "select id from service where name = ? and namespace = ?" 599 var id string 600 err = dbTx.QueryRow(str, name, namespace).Scan(&id) 601 switch { 602 case err == sql.ErrNoRows: 603 return 604 case err != nil: 605 panic(err) 606 } 607 608 if _, err := dbTx.Exec("delete from service_metadata where id = ?", id); err != nil { 609 rollbackDbTx(dbTx) 610 panic(err) 611 } 612 613 if _, err := dbTx.Exec("delete from service where id = ?", id); err != nil { 614 rollbackDbTx(dbTx) 615 panic(err) 616 } 617 618 if _, err := dbTx.Exec( 619 "delete from owner_service_map where service=? and namespace=?", name, namespace); err != nil { 620 rollbackDbTx(dbTx) 621 panic(err) 622 } 623 624 commitDbTx(dbTx) 625 }() 626 } else if d.Storage.Name() == boltdb.STORENAME { 627 func() { 628 svc, err := d.Storage.GetService(name, namespace) 629 if err != nil { 630 panic(err) 631 } 632 if svc == nil { 633 return 634 } 635 636 tx, err := d.Storage.StartTx() 637 if err != nil { 638 panic(err) 639 } 640 641 dbTx := tx.GetDelegateTx().(*bolt.Tx) 642 defer rollbackBoltTx(dbTx) 643 644 if err := dbTx.Bucket([]byte(tblNameService)).DeleteBucket([]byte(svc.ID)); err != nil { 645 if !errors.Is(err, bolt.ErrBucketNotFound) { 646 rollbackBoltTx(dbTx) 647 panic(err) 648 } 649 } 650 651 commitBoltTx(dbTx) 652 }() 653 } 654 } 655 656 // clean services 657 func (d *DiscoverTestSuit) CleanServices(services []*apiservice.Service) { 658 659 if d.Storage.Name() == sqldb.STORENAME { 660 func() { 661 tx, err := d.Storage.StartTx() 662 if err != nil { 663 panic(err) 664 } 665 666 dbTx := tx.GetDelegateTx().(*sqldb.BaseTx) 667 668 defer rollbackDbTx(dbTx) 669 670 str := "delete from service where name = ? and namespace = ?" 671 cleanOwnerSql := "delete from owner_service_map where service=? and namespace=?" 672 for _, service := range services { 673 if _, err := dbTx.Exec( 674 str, service.GetName().GetValue(), service.GetNamespace().GetValue()); err != nil { 675 panic(err) 676 } 677 if _, err := dbTx.Exec( 678 cleanOwnerSql, service.GetName().GetValue(), service.GetNamespace().GetValue()); err != nil { 679 panic(err) 680 } 681 } 682 683 commitDbTx(dbTx) 684 }() 685 } else if d.Storage.Name() == boltdb.STORENAME { 686 func() { 687 ids := make([]string, 0, len(services)) 688 689 for _, service := range services { 690 svc, err := d.Storage.GetService(service.GetName().GetValue(), service.GetNamespace().GetValue()) 691 if err != nil { 692 panic(err) 693 } 694 695 ids = append(ids, svc.ID) 696 } 697 698 tx, err := d.Storage.StartTx() 699 if err != nil { 700 panic(err) 701 } 702 703 dbTx := tx.GetDelegateTx().(*bolt.Tx) 704 705 for i := range ids { 706 if err := dbTx.Bucket([]byte(tblNameService)).DeleteBucket([]byte(ids[i])); err != nil { 707 if !errors.Is(err, bolt.ErrBucketNotFound) { 708 rollbackBoltTx(dbTx) 709 panic(err) 710 } 711 } 712 } 713 commitBoltTx(dbTx) 714 }() 715 } 716 717 } 718 719 // 从数据库彻底删除实例 720 func (d *DiscoverTestSuit) CleanInstance(instanceID string) { 721 if instanceID == "" { 722 panic("instanceID is empty") 723 } 724 log.Infof("clean instance: %s", instanceID) 725 726 if d.Storage.Name() == sqldb.STORENAME { 727 func() { 728 tx, err := d.Storage.StartTx() 729 if err != nil { 730 panic(err) 731 } 732 733 dbTx := tx.GetDelegateTx().(*sqldb.BaseTx) 734 735 defer rollbackDbTx(dbTx) 736 737 str := "delete from instance where id = ?" 738 if _, err := dbTx.Exec(str, instanceID); err != nil { 739 rollbackDbTx(dbTx) 740 panic(err) 741 } 742 743 commitDbTx(dbTx) 744 }() 745 } else if d.Storage.Name() == boltdb.STORENAME { 746 func() { 747 tx, err := d.Storage.StartTx() 748 if err != nil { 749 panic(err) 750 } 751 752 dbTx := tx.GetDelegateTx().(*bolt.Tx) 753 754 if err := dbTx.Bucket([]byte(tblNameInstance)).DeleteBucket([]byte(instanceID)); err != nil { 755 if !errors.Is(err, bolt.ErrBucketNotFound) { 756 rollbackBoltTx(dbTx) 757 panic(err) 758 } 759 } 760 commitBoltTx(dbTx) 761 }() 762 } 763 } 764 765 // 彻底删除一个路由配置 766 func (d *DiscoverTestSuit) CleanCommonRoutingConfig(service string, namespace string) { 767 768 if d.Storage.Name() == sqldb.STORENAME { 769 func() { 770 tx, err := d.Storage.StartTx() 771 if err != nil { 772 panic(err) 773 } 774 775 dbTx := tx.GetDelegateTx().(*sqldb.BaseTx) 776 777 defer rollbackDbTx(dbTx) 778 779 str := "delete from routing_config where id in (select id from service where name = ? and namespace = ?)" 780 // fmt.Printf("%s %s %s\n", str, service, namespace) 781 if _, err := dbTx.Exec(str, service, namespace); err != nil { 782 panic(err) 783 } 784 str = "delete from routing_config_v2" 785 // fmt.Printf("%s %s %s\n", str, service, namespace) 786 if _, err := dbTx.Exec(str); err != nil { 787 panic(err) 788 } 789 790 commitDbTx(dbTx) 791 }() 792 } else if d.Storage.Name() == boltdb.STORENAME { 793 func() { 794 svc, err := d.Storage.GetService(service, namespace) 795 if err != nil { 796 panic(err) 797 } 798 799 if svc == nil { 800 return 801 } 802 803 tx, err := d.Storage.StartTx() 804 if err != nil { 805 panic(err) 806 } 807 808 dbTx := tx.GetDelegateTx().(*bolt.Tx) 809 defer rollbackBoltTx(dbTx) 810 811 v1Bucket := dbTx.Bucket([]byte(tblNameRouting)) 812 if v1Bucket != nil { 813 if err := v1Bucket.DeleteBucket([]byte(svc.ID)); err != nil { 814 if !errors.Is(err, bolt.ErrBucketNotFound) { 815 rollbackBoltTx(dbTx) 816 panic(err) 817 } 818 } 819 } 820 821 if err := dbTx.DeleteBucket([]byte(tblNameRoutingV2)); err != nil { 822 if !errors.Is(err, bolt.ErrBucketNotFound) { 823 rollbackBoltTx(dbTx) 824 panic(err) 825 } 826 } 827 commitBoltTx(dbTx) 828 }() 829 } 830 } 831 832 func (d *DiscoverTestSuit) TruncateCommonRoutingConfigV2() { 833 if d.Storage.Name() == sqldb.STORENAME { 834 func() { 835 tx, err := d.Storage.StartTx() 836 if err != nil { 837 panic(err) 838 } 839 840 dbTx := tx.GetDelegateTx().(*sqldb.BaseTx) 841 defer rollbackDbTx(dbTx) 842 843 str := "delete from routing_config_v2" 844 if _, err := dbTx.Exec(str); err != nil { 845 panic(err) 846 } 847 848 commitDbTx(dbTx) 849 }() 850 } else if d.Storage.Name() == boltdb.STORENAME { 851 func() { 852 853 tx, err := d.Storage.StartTx() 854 if err != nil { 855 panic(err) 856 } 857 858 dbTx := tx.GetDelegateTx().(*bolt.Tx) 859 defer rollbackBoltTx(dbTx) 860 861 if err := dbTx.DeleteBucket([]byte(tblNameRoutingV2)); err != nil { 862 if !errors.Is(err, bolt.ErrBucketNotFound) { 863 rollbackBoltTx(dbTx) 864 panic(err) 865 } 866 } 867 868 commitBoltTx(dbTx) 869 }() 870 } 871 } 872 873 // 彻底删除一个路由配置 874 func (d *DiscoverTestSuit) CleanCommonRoutingConfigV2(rules []*apitraffic.RouteRule) { 875 876 if d.Storage.Name() == sqldb.STORENAME { 877 func() { 878 tx, err := d.Storage.StartTx() 879 if err != nil { 880 panic(err) 881 } 882 883 dbTx := tx.GetDelegateTx().(*sqldb.BaseTx) 884 defer rollbackDbTx(dbTx) 885 886 str := "delete from routing_config_v2 where id in (%s)" 887 888 places := []string{} 889 args := []interface{}{} 890 for i := range rules { 891 places = append(places, "?") 892 args = append(args, rules[i].Id) 893 } 894 895 str = fmt.Sprintf(str, strings.Join(places, ",")) 896 // fmt.Printf("%s %s %s\n", str, service, namespace) 897 if _, err := dbTx.Exec(str, args...); err != nil { 898 panic(err) 899 } 900 901 commitDbTx(dbTx) 902 }() 903 } else if d.Storage.Name() == boltdb.STORENAME { 904 func() { 905 906 tx, err := d.Storage.StartTx() 907 if err != nil { 908 panic(err) 909 } 910 911 dbTx := tx.GetDelegateTx().(*bolt.Tx) 912 defer rollbackBoltTx(dbTx) 913 914 for i := range rules { 915 if err := dbTx.Bucket([]byte(tblNameRoutingV2)).DeleteBucket([]byte(rules[i].Id)); err != nil { 916 if !errors.Is(err, bolt.ErrBucketNotFound) { 917 rollbackBoltTx(dbTx) 918 panic(err) 919 } 920 } 921 } 922 923 commitBoltTx(dbTx) 924 }() 925 } 926 } 927 928 // 彻底删除限流规则 929 func (d *DiscoverTestSuit) CleanRateLimit(id string) { 930 931 if d.Storage.Name() == sqldb.STORENAME { 932 func() { 933 tx, err := d.Storage.StartTx() 934 if err != nil { 935 panic(err) 936 } 937 938 dbTx := tx.GetDelegateTx().(*sqldb.BaseTx) 939 940 defer rollbackDbTx(dbTx) 941 942 str := `delete from ratelimit_config where id = ?` 943 if _, err := dbTx.Exec(str, id); err != nil { 944 panic(err) 945 } 946 947 commitDbTx(dbTx) 948 }() 949 } else if d.Storage.Name() == boltdb.STORENAME { 950 func() { 951 tx, err := d.Storage.StartTx() 952 if err != nil { 953 panic(err) 954 } 955 956 dbTx := tx.GetDelegateTx().(*bolt.Tx) 957 958 if err := dbTx.Bucket([]byte(tblRateLimitConfig)).DeleteBucket([]byte(id)); err != nil { 959 if !errors.Is(err, bolt.ErrBucketNotFound) { 960 rollbackBoltTx(dbTx) 961 panic(err) 962 } 963 } 964 commitBoltTx(dbTx) 965 }() 966 } 967 } 968 969 func buildCircuitBreakerKey(id, version string) string { 970 return fmt.Sprintf("%s_%s", id, version) 971 } 972 973 // 彻底删除熔断规则 974 func (d *DiscoverTestSuit) CleanCircuitBreaker(id, version string) { 975 log.Infof("clean circuit breaker, id: %s, version: %s", id, version) 976 977 if d.Storage.Name() == sqldb.STORENAME { 978 func() { 979 tx, err := d.Storage.StartTx() 980 if err != nil { 981 panic(err) 982 } 983 984 dbTx := tx.GetDelegateTx().(*sqldb.BaseTx) 985 986 defer rollbackDbTx(dbTx) 987 988 str := `delete from circuitbreaker_rule where id = ? and version = ?` 989 if _, err := dbTx.Exec(str, id, version); err != nil { 990 panic(err) 991 } 992 993 commitDbTx(dbTx) 994 }() 995 } else if d.Storage.Name() == boltdb.STORENAME { 996 func() { 997 tx, err := d.Storage.StartTx() 998 if err != nil { 999 panic(err) 1000 } 1001 1002 dbTx := tx.GetDelegateTx().(*bolt.Tx) 1003 1004 if err := dbTx.Bucket( 1005 []byte(tblCircuitBreaker)).DeleteBucket([]byte(buildCircuitBreakerKey(id, version))); err != nil { 1006 if !errors.Is(err, bolt.ErrBucketNotFound) { 1007 panic(err) 1008 } 1009 } 1010 1011 commitBoltTx(dbTx) 1012 }() 1013 } 1014 } 1015 1016 // 彻底删除熔断规则发布记录 1017 func (d *DiscoverTestSuit) CleanCircuitBreakerRelation(name, namespace, ruleID, ruleVersion string) { 1018 } 1019 1020 func (d *DiscoverTestSuit) ClearTestDataWhenUseRDS() error { 1021 if d.Storage.Name() == boltdb.STORENAME { 1022 proxyTx, err := d.Storage.StartTx() 1023 if err != nil { 1024 return err 1025 } 1026 1027 tx := proxyTx.GetDelegateTx().(*bolt.Tx) 1028 1029 bucketName := []string{ 1030 "ConfigFileGroup", 1031 "ConfigFileGroupID", 1032 "ConfigFile", 1033 "ConfigFileID", 1034 "ConfigFileReleaseHistory", 1035 "ConfigFileReleaseHistoryID", 1036 "ConfigFileRelease", 1037 "ConfigFileReleaseID", 1038 "ConfigFileTag", 1039 "ConfigFileTagID", 1040 "namespace", 1041 } 1042 1043 defer tx.Rollback() 1044 1045 for i := range bucketName { 1046 if err := tx.DeleteBucket([]byte(bucketName[i])); err != nil { 1047 if !errors.Is(err, bolt.ErrBucketNotFound) { 1048 return err 1049 } 1050 } 1051 } 1052 return tx.Commit() 1053 } 1054 if d.Storage.Name() == sqldb.STORENAME { 1055 proxyTx, err := d.Storage.StartTx() 1056 if err != nil { 1057 return err 1058 } 1059 1060 tx := proxyTx.GetDelegateTx().(*sqldb.BaseTx) 1061 1062 defer tx.Rollback() 1063 1064 _, err = tx.Exec("delete from config_file_group where namespace = ? ", testNamespace) 1065 if err != nil { 1066 return err 1067 } 1068 _, err = tx.Exec("delete from config_file where namespace = ? ", testNamespace) 1069 if err != nil { 1070 return err 1071 } 1072 _, err = tx.Exec("delete from config_file_release where namespace = ? ", testNamespace) 1073 if err != nil { 1074 return err 1075 } 1076 _, err = tx.Exec("delete from config_file_release_history where namespace = ? ", testNamespace) 1077 if err != nil { 1078 return err 1079 } 1080 _, err = tx.Exec("delete from config_file_tag where namespace = ? ", testNamespace) 1081 if err != nil { 1082 return err 1083 } 1084 _, err = tx.Exec("delete from namespace where name = ? ", testNamespace) 1085 if err != nil { 1086 return err 1087 } 1088 _, err = tx.Exec("delete from config_file_template where name in (?,?) ", templateName1, templateName2) 1089 if err != nil { 1090 return err 1091 } 1092 return tx.Commit() 1093 } 1094 return nil 1095 }