github.com/polarismesh/polaris@v1.17.8/config/config_file_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 config_test 19 20 import ( 21 "context" 22 "encoding/base64" 23 "encoding/hex" 24 "errors" 25 "fmt" 26 "reflect" 27 "testing" 28 29 . "github.com/agiledragon/gomonkey/v2" 30 "github.com/golang/mock/gomock" 31 "github.com/golang/protobuf/ptypes/wrappers" 32 apiconfig "github.com/polarismesh/specification/source/go/api/v1/config_manage" 33 apimodel "github.com/polarismesh/specification/source/go/api/v1/model" 34 "github.com/stretchr/testify/assert" 35 "google.golang.org/protobuf/types/known/wrapperspb" 36 37 api "github.com/polarismesh/polaris/common/api/v1" 38 "github.com/polarismesh/polaris/common/model" 39 "github.com/polarismesh/polaris/common/utils" 40 "github.com/polarismesh/polaris/plugin" 41 "github.com/polarismesh/polaris/plugin/crypto/aes" 42 storemock "github.com/polarismesh/polaris/store/mock" 43 ) 44 45 var ( 46 testNamespace = "testNamespace123qwe" 47 testGroup = "testGroup" 48 testFile = "testFile" 49 testContent = "testContent" 50 operator = "polaris" 51 size = 7 52 ) 53 54 // TestConfigFileCRUD 测试配置文件增删改查 55 func TestConfigFileCRUD(t *testing.T) { 56 testSuit := &ConfigCenterTest{} 57 if err := testSuit.Initialize(); err != nil { 58 t.Fatal(err) 59 } 60 t.Cleanup(func() { 61 if err := testSuit.clearTestData(); err != nil { 62 t.Fatal(err) 63 } 64 testSuit.Destroy() 65 }) 66 67 t.Run("step1-query", func(t *testing.T) { 68 rsp := testSuit.ConfigServer().GetConfigFileRichInfo(testSuit.DefaultCtx, &apiconfig.ConfigFile{ 69 Namespace: utils.NewStringValue(testNamespace), 70 Group: utils.NewStringValue(testGroup), 71 Name: utils.NewStringValue(testFile), 72 }) 73 assert.Equal(t, uint32(api.NotFoundResource), rsp.Code.GetValue()) 74 assert.Nil(t, rsp.ConfigFile) 75 }) 76 77 t.Run("step2-create", func(t *testing.T) { 78 configFile := assembleConfigFile() 79 rsp := testSuit.ConfigServer().CreateConfigFile(testSuit.DefaultCtx, configFile) 80 assert.Equal(t, api.ExecuteSuccess, rsp.Code.GetValue()) 81 82 // 重复创建 83 rsp2 := testSuit.ConfigServer().CreateConfigFile(testSuit.DefaultCtx, configFile) 84 assert.Equal(t, uint32(api.ExistedResource), rsp2.Code.GetValue()) 85 86 // 创建完之后再查询 87 rsp3 := testSuit.ConfigServer().GetConfigFileRichInfo(testSuit.DefaultCtx, &apiconfig.ConfigFile{ 88 Namespace: utils.NewStringValue(testNamespace), 89 Group: utils.NewStringValue(testGroup), 90 Name: utils.NewStringValue(testFile), 91 }) 92 assert.Equal(t, api.ExecuteSuccess, rsp3.Code.GetValue()) 93 assert.NotNil(t, rsp3.ConfigFile) 94 assert.Equal(t, testNamespace, rsp3.ConfigFile.Namespace.GetValue()) 95 assert.Equal(t, testGroup, rsp3.ConfigFile.Group.GetValue()) 96 assert.Equal(t, testFile, rsp3.ConfigFile.Name.GetValue()) 97 assert.Equal(t, configFile.Content.GetValue(), rsp3.ConfigFile.Content.GetValue()) 98 assert.Equal(t, configFile.Format.GetValue(), rsp3.ConfigFile.Format.GetValue()) 99 }) 100 101 t.Run("step3-update", func(t *testing.T) { 102 testSuit.DefaultCtx = context.WithValue(testSuit.DefaultCtx, utils.ContextUserNameKey, "polaris") 103 104 rsp := testSuit.ConfigServer().GetConfigFileRichInfo(testSuit.DefaultCtx, &apiconfig.ConfigFile{ 105 Namespace: utils.NewStringValue(testNamespace), 106 Group: utils.NewStringValue(testGroup), 107 Name: utils.NewStringValue(testFile), 108 }) 109 assert.Equal(t, api.ExecuteSuccess, rsp.Code.GetValue()) 110 111 configFile := rsp.ConfigFile 112 newContent := "k1=v1" 113 modifyBy := "polaris" 114 configFile.Content = utils.NewStringValue(newContent) 115 configFile.ModifyBy = utils.NewStringValue(modifyBy) 116 117 rsp2 := testSuit.ConfigServer().UpdateConfigFile(testSuit.DefaultCtx, configFile) 118 assert.Equal(t, api.ExecuteSuccess, rsp2.Code.GetValue()) 119 assert.Equal(t, newContent, rsp2.ConfigFile.Content.GetValue()) 120 121 // 更新完之后再查询 122 rsp3 := testSuit.ConfigServer().GetConfigFileRichInfo(testSuit.DefaultCtx, &apiconfig.ConfigFile{ 123 Namespace: utils.NewStringValue(testNamespace), 124 Group: utils.NewStringValue(testGroup), 125 Name: utils.NewStringValue(testFile), 126 }) 127 assert.Equal(t, api.ExecuteSuccess, rsp3.Code.GetValue()) 128 assert.NotNil(t, rsp.ConfigFile) 129 assert.Equal(t, testNamespace, rsp.ConfigFile.Namespace.GetValue()) 130 assert.Equal(t, testGroup, rsp.ConfigFile.Group.GetValue()) 131 assert.Equal(t, testFile, rsp.ConfigFile.Name.GetValue()) 132 assert.Equal(t, configFile.Content.GetValue(), rsp.ConfigFile.Content.GetValue()) 133 assert.Equal(t, configFile.Format.GetValue(), rsp.ConfigFile.Format.GetValue()) 134 assert.Equal(t, operator, rsp.ConfigFile.CreateBy.GetValue()) 135 assert.Equal(t, modifyBy, rsp.ConfigFile.ModifyBy.GetValue()) 136 }) 137 138 t.Run("step4-delete", func(t *testing.T) { 139 // 删除前先发布一次 140 configFile := assembleConfigFile() 141 configFileRelease := assembleConfigFileRelease(configFile) 142 rsp := testSuit.ConfigServer().PublishConfigFile(testSuit.DefaultCtx, configFileRelease) 143 assert.Equal(t, api.ExecuteSuccess, rsp.Code.GetValue()) 144 145 rsp2 := testSuit.ConfigServer().DeleteConfigFile(testSuit.DefaultCtx, &apiconfig.ConfigFile{ 146 Namespace: utils.NewStringValue(testNamespace), 147 Group: utils.NewStringValue(testGroup), 148 Name: utils.NewStringValue(testFile), 149 }) 150 assert.Equal(t, api.ExecuteSuccess, rsp2.Code.GetValue()) 151 152 // 删除后,查询不到 153 rsp3 := testSuit.ConfigServer().GetConfigFileRichInfo(testSuit.DefaultCtx, &apiconfig.ConfigFile{ 154 Namespace: utils.NewStringValue(testNamespace), 155 Group: utils.NewStringValue(testGroup), 156 Name: utils.NewStringValue(testFile), 157 }) 158 assert.Equal(t, uint32(api.NotFoundResource), rsp3.Code.GetValue()) 159 assert.Nil(t, rsp2.ConfigFile) 160 }) 161 162 t.Run("step5-search-by-group", func(t *testing.T) { 163 group := "group11" 164 for i := 0; i < size; i++ { 165 rsp := testSuit.ConfigServer().CreateConfigFile(testSuit.DefaultCtx, assembleConfigFileWithFixedGroupAndRandomFileName(group)) 166 assert.Equal(t, api.ExecuteSuccess, rsp.Code.GetValue()) 167 } 168 169 // 第一页 170 rsp2 := testSuit.ConfigServer().SearchConfigFile(testSuit.DefaultCtx, map[string]string{ 171 "namespace": testNamespace, 172 "group": group, 173 "offset": "0", 174 "limit": "3", 175 }) 176 assert.Equal(t, api.ExecuteSuccess, rsp2.Code.GetValue()) 177 assert.Equal(t, uint32(size), rsp2.Total.GetValue()) 178 assert.Equal(t, 3, len(rsp2.ConfigFiles)) 179 180 // 最后一页 181 rsp3 := testSuit.ConfigServer().SearchConfigFile(testSuit.DefaultCtx, map[string]string{ 182 "namespace": testNamespace, 183 "group": group, 184 "offset": "6", 185 "limit": "3", 186 }) 187 assert.Equal(t, api.ExecuteSuccess, rsp3.Code.GetValue()) 188 assert.Equal(t, uint32(size), rsp3.Total.GetValue()) 189 assert.Equal(t, 1, len(rsp3.ConfigFiles)) 190 191 // group为空 192 rsp4 := testSuit.ConfigServer().SearchConfigFile(testSuit.DefaultCtx, map[string]string{ 193 "namespace": testNamespace, 194 "group": "", 195 "offset": "0", 196 "limit": "3", 197 }) 198 assert.Equal(t, api.ExecuteSuccess, rsp4.Code.GetValue()) 199 assert.Equal(t, uint32(size), rsp4.Total.GetValue()) 200 assert.Equal(t, 3, len(rsp4.ConfigFiles)) 201 202 // group 模糊搜索 203 rsp5 := testSuit.ConfigServer().SearchConfigFile(testSuit.DefaultCtx, map[string]string{ 204 "namespace": testNamespace, 205 "group": "group1*", 206 "offset": "0", 207 "limit": "3", 208 }) 209 assert.Equal(t, api.ExecuteSuccess, rsp5.Code.GetValue()) 210 assert.Equal(t, uint32(size), rsp5.Total.GetValue()) 211 assert.Equal(t, 3, len(rsp5.ConfigFiles)) 212 }) 213 214 t.Run("step5-find-by-group", func(t *testing.T) { 215 group := "group12" 216 for i := 0; i < size; i++ { 217 rsp := testSuit.ConfigServer().CreateConfigFile(testSuit.DefaultCtx, assembleConfigFileWithFixedGroupAndRandomFileName(group)) 218 assert.Equal(t, api.ExecuteSuccess, rsp.Code.GetValue()) 219 } 220 221 // 第一页 222 rsp2 := testSuit.ConfigServer().SearchConfigFile(testSuit.DefaultCtx, map[string]string{ 223 "namespace": testNamespace, 224 "group": group, 225 "offset": "0", 226 "limit": "3", 227 }) 228 assert.Equal(t, api.ExecuteSuccess, rsp2.Code.GetValue()) 229 assert.Equal(t, uint32(size), rsp2.Total.GetValue()) 230 assert.Equal(t, 3, len(rsp2.ConfigFiles)) 231 232 // 最后一页 233 rsp3 := testSuit.ConfigServer().SearchConfigFile(testSuit.DefaultCtx, map[string]string{ 234 "namespace": testNamespace, 235 "group": group, 236 "offset": "6", 237 "limit": "3", 238 }) 239 assert.Equal(t, api.ExecuteSuccess, rsp3.Code.GetValue()) 240 assert.Equal(t, uint32(size), rsp3.Total.GetValue()) 241 assert.Equal(t, 1, len(rsp3.ConfigFiles)) 242 }) 243 244 t.Run("step6-search-by-file", func(t *testing.T) { 245 file := "file1.txt" 246 for i := 0; i < size; i++ { 247 rsp := testSuit.ConfigServer().CreateConfigFile(testSuit.DefaultCtx, assembleConfigFileWithRandomGroupAndFixedFileName(file)) 248 assert.Equal(t, api.ExecuteSuccess, rsp.Code.GetValue()) 249 } 250 251 // 第一页 252 rsp2 := testSuit.ConfigServer().SearchConfigFile(testSuit.DefaultCtx, map[string]string{ 253 "namespace": testNamespace, 254 "name": file, 255 "offset": "0", 256 "limit": "3", 257 }) 258 assert.Equal(t, api.ExecuteSuccess, rsp2.Code.GetValue()) 259 assert.Equal(t, uint32(size), rsp2.Total.GetValue()) 260 assert.Equal(t, 3, len(rsp2.ConfigFiles)) 261 262 // 最后一页 263 rsp3 := testSuit.ConfigServer().SearchConfigFile(testSuit.DefaultCtx, map[string]string{ 264 "namespace": testNamespace, 265 "name": file, 266 "offset": "6", 267 "limit": "3", 268 }) 269 assert.Equal(t, api.ExecuteSuccess, rsp3.Code.GetValue()) 270 assert.Equal(t, uint32(size), rsp3.Total.GetValue()) 271 assert.Equal(t, 1, len(rsp3.ConfigFiles)) 272 273 // group,name都为空 274 rsp4 := testSuit.ConfigServer().SearchConfigFile(testSuit.DefaultCtx, map[string]string{ 275 "namespace": testNamespace, 276 "offset": "0", 277 "limit": "3", 278 }) 279 assert.Equal(t, api.ExecuteSuccess, rsp4.Code.GetValue()) 280 assert.Equal(t, uint32(size*3), rsp4.Total.GetValue()) // 总数为随机 group 和随机 fileName 总和 281 assert.Equal(t, 3, len(rsp4.ConfigFiles)) 282 283 // fileName 模糊搜索 284 rsp5 := testSuit.ConfigServer().SearchConfigFile(testSuit.DefaultCtx, map[string]string{ 285 "namespace": testNamespace, 286 "name": "file1*", 287 "offset": "0", 288 "limit": "3", 289 }) 290 assert.Equal(t, api.ExecuteSuccess, rsp5.Code.GetValue()) 291 assert.Equal(t, uint32(size), rsp5.Total.GetValue()) 292 assert.Equal(t, 3, len(rsp5.ConfigFiles)) 293 }) 294 295 t.Run("step7-search-by-tag", func(t *testing.T) { 296 t.Skip() 297 // 按 tag k1=v1 搜索 298 rsp := testSuit.ConfigServer().SearchConfigFile(testSuit.DefaultCtx, map[string]string{ 299 "namespace": testNamespace, 300 "tags": "k1,v1", 301 "offset": "0", 302 "limit": "3", 303 }) 304 assert.Equal(t, api.ExecuteSuccess, rsp.Code.GetValue()) 305 assert.Equal(t, uint32(size*3), rsp.Total.GetValue()) 306 assert.Equal(t, 3, len(rsp.ConfigFiles)) 307 }) 308 309 t.Run("step8-export", func(t *testing.T) { 310 namespace := "namespace_0" 311 for i := 0; i < 3; i++ { 312 group := fmt.Sprintf("group_%d", i) 313 for j := 0; j < 3; j++ { 314 name := fmt.Sprintf("file_%d", j) 315 configFile := assembleConfigFileWithNamespaceAndGroupAndName(namespace, group, name) 316 rsp := testSuit.ConfigServer().CreateConfigFile(testSuit.DefaultCtx, configFile) 317 assert.Equal(t, api.ExecuteSuccess, rsp.Code.GetValue()) 318 } 319 } 320 // 导出 group 321 configFileExport := &apiconfig.ConfigFileExportRequest{ 322 Namespace: utils.NewStringValue("namespace_0"), 323 Groups: []*wrappers.StringValue{ 324 utils.NewStringValue("group_0"), 325 utils.NewStringValue("group_1"), 326 }, 327 } 328 rsp := testSuit.ConfigServer().ExportConfigFile(testSuit.DefaultCtx, configFileExport) 329 assert.Equal(t, api.ExecuteSuccess, rsp.Code.GetValue()) 330 // 导出 file 331 configFileExport = &apiconfig.ConfigFileExportRequest{ 332 Namespace: utils.NewStringValue("namespace_0"), 333 Groups: []*wrappers.StringValue{ 334 utils.NewStringValue("group_0"), 335 }, 336 Names: []*wrappers.StringValue{ 337 utils.NewStringValue("file_0"), 338 utils.NewStringValue("file_1"), 339 utils.NewStringValue("file_2"), 340 }, 341 } 342 rsp = testSuit.ConfigServer().ExportConfigFile(testSuit.DefaultCtx, configFileExport) 343 assert.Equal(t, api.ExecuteSuccess, rsp.Code.GetValue()) 344 // 导出参数错误:无效的命名空间 345 configFileExport = &apiconfig.ConfigFileExportRequest{ 346 Namespace: utils.NewStringValue(""), 347 } 348 rsp = testSuit.ConfigServer().ExportConfigFile(testSuit.DefaultCtx, configFileExport) 349 assert.Equal(t, api.InvalidNamespaceName, rsp.Code.GetValue()) 350 // 导出参数错误:无效的组和文件 351 configFileExport = &apiconfig.ConfigFileExportRequest{ 352 Namespace: utils.NewStringValue("namespace_0"), 353 Groups: []*wrappers.StringValue{ 354 utils.NewStringValue("group_0"), 355 utils.NewStringValue("group_1"), 356 }, 357 Names: []*wrappers.StringValue{ 358 utils.NewStringValue("file_0"), 359 }, 360 } 361 rsp = testSuit.ConfigServer().ExportConfigFile(testSuit.DefaultCtx, configFileExport) 362 assert.Equal(t, api.InvalidParameter, rsp.Code.GetValue()) 363 // 导出配置不存在 364 configFileExport = &apiconfig.ConfigFileExportRequest{ 365 Namespace: utils.NewStringValue("namespace_0"), 366 Groups: []*wrappers.StringValue{ 367 utils.NewStringValue("group_10"), 368 }, 369 } 370 rsp = testSuit.ConfigServer().ExportConfigFile(testSuit.DefaultCtx, configFileExport) 371 assert.Equal(t, api.NotFoundResourceConfigFile, rsp.Code.GetValue()) 372 }) 373 374 t.Run("step9-import", func(t *testing.T) { 375 // 导入配置文件错误 376 namespace := "namespace_0" 377 var configFiles []*apiconfig.ConfigFile 378 for i := 0; i < 2; i++ { 379 group := fmt.Sprintf("group_%d", i) 380 for j := 1; j < 4; j++ { 381 name := "" 382 configFile := assembleConfigFileWithNamespaceAndGroupAndName(namespace, group, name) 383 configFiles = append(configFiles, configFile) 384 } 385 } 386 rsp := testSuit.ConfigServer().ImportConfigFile(testSuit.DefaultCtx, configFiles, utils.ConfigFileImportConflictSkip) 387 assert.Equal(t, api.InvalidConfigFileName, rsp.Code.GetValue(), rsp.GetInfo().GetValue()) 388 }) 389 t.Run("step10-import-conflict-skip", func(t *testing.T) { 390 namespace := "namespace_import_skip" 391 group := fmt.Sprintf("group_0") 392 for j := 0; j < 3; j++ { 393 name := fmt.Sprintf("file_%d", j) 394 configFile := assembleConfigFileWithNamespaceAndGroupAndName(namespace, group, name) 395 rsp := testSuit.ConfigServer().CreateConfigFile(testSuit.DefaultCtx, configFile) 396 assert.Equal(t, api.ExecuteSuccess, rsp.Code.GetValue()) 397 } 398 399 var configFiles []*apiconfig.ConfigFile 400 for i := 0; i < 2; i++ { 401 group := fmt.Sprintf("group_%d", i) 402 for j := 1; j < 4; j++ { 403 name := fmt.Sprintf("file_%d", j) 404 configFile := assembleConfigFileWithNamespaceAndGroupAndName(namespace, group, name) 405 configFiles = append(configFiles, configFile) 406 } 407 } 408 rsp := testSuit.ConfigServer().ImportConfigFile(testSuit.DefaultCtx, configFiles, utils.ConfigFileImportConflictSkip) 409 t.Log(rsp.Code.GetValue()) 410 assert.Equal(t, api.ExecuteSuccess, rsp.Code.GetValue()) 411 assert.Equal(t, 4, len(rsp.CreateConfigFiles)) 412 assert.Equal(t, 2, len(rsp.SkipConfigFiles)) 413 assert.Equal(t, 0, len(rsp.OverwriteConfigFiles)) 414 }) 415 416 t.Run("step11-import-conflict-overwrite", func(t *testing.T) { 417 namespace := "namespace_import_overwrite" 418 group := fmt.Sprintf("group_0") 419 for j := 0; j < 3; j++ { 420 name := fmt.Sprintf("file_%d", j) 421 configFile := assembleConfigFileWithNamespaceAndGroupAndName(namespace, group, name) 422 rsp := testSuit.ConfigServer().CreateConfigFile(testSuit.DefaultCtx, configFile) 423 assert.Equal(t, api.ExecuteSuccess, rsp.Code.GetValue()) 424 } 425 426 var configFiles []*apiconfig.ConfigFile 427 for i := 0; i < 2; i++ { 428 group := fmt.Sprintf("group_%d", i) 429 for j := 1; j < 4; j++ { 430 name := fmt.Sprintf("file_%d", j) 431 configFile := assembleConfigFileWithNamespaceAndGroupAndName(namespace, group, name) 432 configFiles = append(configFiles, configFile) 433 } 434 } 435 rsp := testSuit.ConfigServer().ImportConfigFile(testSuit.DefaultCtx, configFiles, utils.ConfigFileImportConflictOverwrite) 436 t.Log(rsp.Code.GetValue()) 437 assert.Equal(t, api.ExecuteSuccess, rsp.Code.GetValue()) 438 assert.Equal(t, 4, len(rsp.CreateConfigFiles)) 439 assert.Equal(t, 0, len(rsp.SkipConfigFiles)) 440 assert.Equal(t, 2, len(rsp.OverwriteConfigFiles)) 441 }) 442 443 t.Run("step12-create-entrypted", func(t *testing.T) { 444 configFile := assembleConfigFile() 445 configFile.Encrypted = utils.NewBoolValue(true) 446 configFile.EncryptAlgo = utils.NewStringValue("AES") 447 rsp := testSuit.ConfigServer().CreateConfigFile(testSuit.DefaultCtx, configFile) 448 assert.Equal(t, api.ExecuteSuccess, rsp.Code.GetValue(), rsp.GetInfo().GetValue()) 449 450 // 重复创建 451 rsp2 := testSuit.ConfigServer().CreateConfigFile(testSuit.DefaultCtx, configFile) 452 assert.Equal(t, uint32(api.ExistedResource), rsp2.Code.GetValue(), rsp2.GetInfo().GetValue()) 453 454 // 创建完之后再查询 455 rsp3 := testSuit.ConfigServer().GetConfigFileRichInfo(testSuit.DefaultCtx, &apiconfig.ConfigFile{ 456 Namespace: utils.NewStringValue(testNamespace), 457 Group: utils.NewStringValue(testGroup), 458 Name: utils.NewStringValue(testFile), 459 }) 460 assert.Equal(t, api.ExecuteSuccess, rsp3.Code.GetValue(), rsp3.GetInfo().GetValue()) 461 assert.NotNil(t, rsp3.ConfigFile) 462 assert.Equal(t, testNamespace, rsp3.ConfigFile.Namespace.GetValue()) 463 assert.Equal(t, testGroup, rsp3.ConfigFile.Group.GetValue()) 464 assert.Equal(t, testFile, rsp3.ConfigFile.Name.GetValue()) 465 assert.Equal(t, configFile.Content.GetValue(), rsp3.ConfigFile.Content.GetValue()) 466 assert.Equal(t, configFile.Format.GetValue(), rsp3.ConfigFile.Format.GetValue()) 467 }) 468 } 469 470 // TestPublishConfigFile 测试配置文件发布相关的用例 471 func TestPublishConfigFile(t *testing.T) { 472 testSuit := &ConfigCenterTest{} 473 if err := testSuit.Initialize(); err != nil { 474 t.Fatal(err) 475 } 476 t.Cleanup(func() { 477 if err := testSuit.clearTestData(); err != nil { 478 t.Fatal(err) 479 } 480 testSuit.Destroy() 481 }) 482 483 configFile := assembleConfigFile() 484 rsp := testSuit.ConfigServer().CreateConfigFile(testSuit.DefaultCtx, configFile) 485 assert.Equal(t, api.ExecuteSuccess, rsp.Code.GetValue()) 486 487 configFileRelease := assembleConfigFileRelease(configFile) 488 rsp2 := testSuit.ConfigServer().PublishConfigFile(testSuit.DefaultCtx, configFileRelease) 489 assert.Equal(t, api.ExecuteSuccess, rsp2.Code.GetValue()) 490 491 rsp3 := testSuit.ConfigServer().GetConfigFileRelease(testSuit.DefaultCtx, &apiconfig.ConfigFileRelease{ 492 Namespace: utils.NewStringValue(testNamespace), 493 Group: utils.NewStringValue(testGroup), 494 FileName: utils.NewStringValue(testFile), 495 }) 496 assert.Equal(t, api.ExecuteSuccess, rsp3.Code.GetValue(), rsp3.GetInfo().GetValue()) 497 assert.Equal(t, uint64(1), rsp3.ConfigFileRelease.Version.GetValue()) 498 assert.Equal(t, configFileRelease.Name.GetValue(), rsp3.ConfigFileRelease.Name.GetValue()) 499 assert.Equal(t, configFileRelease.CreateBy.GetValue(), rsp3.ConfigFileRelease.CreateBy.GetValue()) 500 assert.Equal(t, configFileRelease.CreateBy.GetValue(), rsp3.ConfigFileRelease.ModifyBy.GetValue()) 501 assert.Equal(t, configFile.Content.GetValue(), rsp3.ConfigFileRelease.Content.GetValue()) 502 503 rsp5 := testSuit.ConfigServer().GetConfigFileRichInfo(testSuit.DefaultCtx, &apiconfig.ConfigFile{ 504 Namespace: utils.NewStringValue(testNamespace), 505 Group: utils.NewStringValue(testGroup), 506 Name: utils.NewStringValue(testFile), 507 }) 508 assert.Equal(t, uint32(apimodel.Code_ExecuteSuccess), rsp5.GetCode().GetValue()) 509 510 // 第二次修改发布 511 secondReleaseContent := "k3=v3" 512 secondReleaseFormat := utils.FileFormatHtml 513 configFile.Content = utils.NewStringValue(secondReleaseContent) 514 configFile.Format = utils.NewStringValue(secondReleaseFormat) 515 516 rsp6 := testSuit.ConfigServer().UpdateConfigFile(testSuit.DefaultCtx, configFile) 517 assert.Equal(t, api.ExecuteSuccess, rsp6.Code.GetValue()) 518 519 configFileRelease.Name = utils.NewStringValue("") 520 configFileRelease.CreateBy = utils.NewStringValue("ledou3") 521 rsp7 := testSuit.ConfigServer().PublishConfigFile(testSuit.DefaultCtx, configFileRelease) 522 assert.Equal(t, api.ExecuteSuccess, rsp7.Code.GetValue(), rsp7.GetInfo().GetValue()) 523 524 rsp9 := testSuit.ConfigServer().GetConfigFileReleaseHistories(testSuit.DefaultCtx, map[string]string{ 525 "namespace": testNamespace, 526 "group": testGroup, 527 "name": testFile, 528 "offset": "0", 529 "limit": "10", 530 "endId": "0", 531 }) 532 assert.Equal(t, api.ExecuteSuccess, rsp9.Code.GetValue()) 533 assert.Equal(t, 2, len(rsp9.ConfigFileReleaseHistories)) 534 535 } 536 537 func Test_encryptConfigFile(t *testing.T) { 538 testSuit := &ConfigCenterTest{} 539 if err := testSuit.Initialize(); err != nil { 540 t.Fatal(err) 541 } 542 t.Cleanup(func() { 543 testSuit.Destroy() 544 }) 545 546 defer func() { 547 if err := testSuit.clearTestData(); err != nil { 548 t.Fatal(err) 549 } 550 }() 551 type args struct { 552 ctx context.Context 553 algorithm string 554 configFile *model.ConfigFile 555 dataKey string 556 } 557 dataKey, _ := hex.DecodeString("777b162a185673cb1b72b467a78221cd") 558 fmt.Println(base64.StdEncoding.EncodeToString(dataKey)) 559 560 tests := []struct { 561 name string 562 args args 563 want string 564 wantErr error 565 }{ 566 { 567 name: "encrypt config file", 568 args: args{ 569 ctx: context.Background(), 570 algorithm: "AES", 571 configFile: &model.ConfigFile{ 572 Content: "polaris", 573 }, 574 dataKey: "", 575 }, 576 wantErr: nil, 577 }, 578 { 579 name: "encrypt config file with dataKey", 580 args: args{ 581 ctx: context.Background(), 582 algorithm: "AES", 583 configFile: &model.ConfigFile{ 584 Content: "polaris", 585 }, 586 dataKey: base64.StdEncoding.EncodeToString(dataKey), 587 }, 588 want: "YnLZ0SYuujFBHjYHAZVN5A==", 589 wantErr: nil, 590 }, 591 } 592 for _, tt := range tests { 593 t.Run(tt.name, func(t *testing.T) { 594 s := testSuit.OriginConfigServer() 595 err := s.TestEncryptConfigFile(tt.args.ctx, tt.args.configFile, tt.args.algorithm, tt.args.dataKey) 596 assert.Equal(t, tt.wantErr, err) 597 if tt.want != "" { 598 assert.Equal(t, tt.want, tt.args.configFile.Content) 599 } 600 hasDataKeyTag := false 601 hasAlgoTag := false 602 for tagKey, tagVal := range tt.args.configFile.Metadata { 603 if tagKey == utils.ConfigFileTagKeyDataKey { 604 hasDataKeyTag = true 605 if tt.args.dataKey != "" { 606 assert.Equal(t, tt.args.dataKey, tagVal) 607 } 608 } 609 if tagKey == utils.ConfigFileTagKeyEncryptAlgo { 610 hasAlgoTag = true 611 assert.Equal(t, tt.args.algorithm, tagVal) 612 } 613 } 614 assert.True(t, hasDataKeyTag) 615 assert.True(t, hasAlgoTag) 616 }) 617 } 618 } 619 620 func Test_decryptConfigFile(t *testing.T) { 621 testSuit := &ConfigCenterTest{} 622 if err := testSuit.Initialize(); err != nil { 623 t.Fatal(err) 624 } 625 t.Cleanup(func() { 626 testSuit.Destroy() 627 }) 628 defer func() { 629 if err := testSuit.clearTestData(); err != nil { 630 t.Fatal(err) 631 } 632 }() 633 type args struct { 634 ctx context.Context 635 configFile *model.ConfigFile 636 } 637 638 dataKey, _ := hex.DecodeString("777b162a185673cb1b72b467a78221cd") 639 640 tests := []struct { 641 name string 642 args args 643 want string 644 wantErr error 645 }{ 646 { 647 name: "decrypt config file", 648 args: args{ 649 ctx: context.WithValue(context.Background(), utils.ContextUserNameKey, "polaris"), 650 configFile: &model.ConfigFile{ 651 Content: "YnLZ0SYuujFBHjYHAZVN5A==", 652 Metadata: map[string]string{ 653 utils.ConfigFileTagKeyDataKey: base64.StdEncoding.EncodeToString(dataKey), 654 utils.ConfigFileTagKeyEncryptAlgo: "AES", 655 }, 656 CreateBy: "polaris", 657 }, 658 }, 659 want: "polaris", 660 wantErr: nil, 661 }, 662 { 663 name: "non creator can decrypt config file", 664 args: args{ 665 ctx: context.WithValue(context.Background(), utils.ContextUserNameKey, "test"), 666 configFile: &model.ConfigFile{ 667 Content: "YnLZ0SYuujFBHjYHAZVN5A==", 668 Metadata: map[string]string{ 669 utils.ConfigFileTagKeyDataKey: base64.StdEncoding.EncodeToString(dataKey), 670 utils.ConfigFileTagKeyEncryptAlgo: "AES", 671 }, 672 CreateBy: "polaris", 673 }, 674 }, 675 want: "polaris", 676 wantErr: nil, 677 }, 678 } 679 for _, tt := range tests { 680 t.Run(tt.name, func(t *testing.T) { 681 s := testSuit.OriginConfigServer() 682 err := s.TestDecryptConfigFile(tt.args.ctx, tt.args.configFile) 683 assert.Equal(t, tt.wantErr, err, tt.name) 684 assert.Equal(t, tt.want, tt.args.configFile.Content, tt.name) 685 for tagKey := range tt.args.configFile.Metadata { 686 if tagKey == utils.ConfigFileTagKeyDataKey { 687 t.Fatal("config tags has data key") 688 } 689 } 690 }) 691 } 692 } 693 694 func Test_GetConfigEncryptAlgorithm(t *testing.T) { 695 testSuit := &ConfigCenterTest{} 696 if err := testSuit.Initialize(); err != nil { 697 t.Fatal(err) 698 } 699 t.Cleanup(func() { 700 testSuit.Destroy() 701 }) 702 defer func() { 703 if err := testSuit.clearTestData(); err != nil { 704 t.Fatal(err) 705 } 706 }() 707 tests := []struct { 708 name string 709 want []*wrapperspb.StringValue 710 }{ 711 { 712 name: "get config encrypt algorithm", 713 want: []*wrapperspb.StringValue{ 714 utils.NewStringValue("AES"), 715 }, 716 }, 717 } 718 for _, tt := range tests { 719 t.Run(tt.name, func(t *testing.T) { 720 rsp := testSuit.OriginConfigServer().GetAllConfigEncryptAlgorithms(testSuit.DefaultCtx) 721 assert.Equal(t, api.ExecuteSuccess, rsp.Code.GetValue()) 722 assert.Equal(t, tt.want, rsp.GetAlgorithms()) 723 }) 724 } 725 } 726 727 func Test_CreateConfigFile(t *testing.T) { 728 testSuit := &ConfigCenterTest{} 729 if err := testSuit.Initialize(); err != nil { 730 t.Fatal(err) 731 } 732 t.Cleanup(func() { 733 if err := testSuit.clearTestData(); err != nil { 734 t.Fatal(err) 735 } 736 testSuit.Destroy() 737 }) 738 ctrl := gomock.NewController(t) 739 defer ctrl.Finish() 740 741 t.Run("加密配置文件-返回error", func(t *testing.T) { 742 crypto := &MockCrypto{} 743 testSuit.OriginConfigServer().TestMockCryptoManager(&MockCryptoManager{ 744 repos: map[string]plugin.Crypto{ 745 crypto.Name(): crypto, 746 }, 747 }) 748 749 configFile := assembleEncryptConfigFile() 750 got := testSuit.ConfigServer().CreateConfigFile(testSuit.DefaultCtx, configFile) 751 assert.Equal(t, apimodel.Code_EncryptConfigFileException, apimodel.Code(got.GetCode().GetValue())) 752 }) 753 } 754 755 func Test_GetConfigFileRichInfo(t *testing.T) { 756 testSuit := &ConfigCenterTest{} 757 if err := testSuit.Initialize(); err != nil { 758 t.Fatal(err) 759 } 760 t.Cleanup(func() { 761 if err := testSuit.clearTestData(); err != nil { 762 t.Fatal(err) 763 } 764 testSuit.Destroy() 765 }) 766 ctrl := gomock.NewController(t) 767 defer ctrl.Finish() 768 769 t.Run("获取配置文件基本信息-解密配置文件-返回error", func(t *testing.T) { 770 crypto := &aes.AESCrypto{} 771 encryptFunc := ApplyMethod(reflect.TypeOf(crypto), "Decrypt", func(_ *aes.AESCrypto, plaintext string, key []byte) (string, error) { 772 return "", errors.New("mock encrypt error") 773 }) 774 defer encryptFunc.Reset() 775 776 configFile := assembleConfigFile() 777 778 storage := storemock.NewMockStore(ctrl) 779 storage.EXPECT().GetConfigFile(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes().Return(&model.ConfigFile{ 780 Namespace: configFile.Namespace.Value, 781 Group: configFile.Group.Value, 782 Name: configFile.Name.Value, 783 CreateBy: operator, 784 }, nil) 785 786 svr := testSuit.OriginConfigServer() 787 svr.TestMockStore(storage) 788 svr.TestMockCryptoManager(&MockCryptoManager{ 789 repos: map[string]plugin.Crypto{ 790 crypto.Name(): crypto, 791 }, 792 }) 793 got := testSuit.ConfigServer().GetConfigFileRichInfo(testSuit.DefaultCtx, configFile) 794 assert.Equal(t, apimodel.Code_ExecuteSuccess, apimodel.Code(got.GetCode().GetValue()), got.GetInfo().GetValue()) 795 }) 796 } 797 798 type MockCryptoManager struct { 799 repos map[string]plugin.Crypto 800 } 801 802 func (m *MockCryptoManager) Name() string { 803 return "" 804 } 805 806 func (m *MockCryptoManager) Initialize() error { 807 return nil 808 } 809 810 func (m *MockCryptoManager) Destroy() error { 811 return nil 812 } 813 814 func (m *MockCryptoManager) GetCryptoAlgoNames() []string { 815 return []string{} 816 } 817 818 func (m *MockCryptoManager) GetCrypto(algo string) (plugin.Crypto, error) { 819 val, ok := m.repos[algo] 820 if !ok { 821 return nil, errors.New("Not Exist") 822 } 823 return val, nil 824 } 825 826 type MockCrypto struct { 827 } 828 829 func (m *MockCrypto) Name() string { 830 return (&aes.AESCrypto{}).Name() 831 } 832 833 func (m *MockCrypto) Initialize(c *plugin.ConfigEntry) error { 834 return nil 835 } 836 837 func (m *MockCrypto) Destroy() error { 838 return nil 839 } 840 841 func (m *MockCrypto) GenerateKey() ([]byte, error) { 842 return nil, errors.New("Not Support") 843 } 844 845 func (m *MockCrypto) Encrypt(plaintext string, key []byte) (string, error) { 846 return "", errors.New("Not Support") 847 } 848 849 func (m *MockCrypto) Decrypt(cryptotext string, key []byte) (string, error) { 850 return "", errors.New("Not Support") 851 }