github.com/unionj-cloud/go-doudou@v1.3.8-0.20221011095552-0088008e5b31/framework/configmgr/nacos_test.go (about) 1 package configmgr_test 2 3 import ( 4 "fmt" 5 "github.com/golang/mock/gomock" 6 "github.com/pkg/errors" 7 . "github.com/smartystreets/goconvey/convey" 8 "github.com/unionj-cloud/go-doudou/framework/configmgr" 9 "github.com/unionj-cloud/go-doudou/framework/configmgr/mock" 10 "github.com/unionj-cloud/go-doudou/framework/internal/config" 11 "github.com/unionj-cloud/go-doudou/toolkit/stringutils" 12 "github.com/wubin1989/nacos-sdk-go/clients/cache" 13 "github.com/wubin1989/nacos-sdk-go/clients/config_client" 14 "github.com/wubin1989/nacos-sdk-go/util" 15 "github.com/wubin1989/nacos-sdk-go/vo" 16 "io" 17 "strings" 18 "testing" 19 ) 20 21 func TestMain(m *testing.M) { 22 config.GddServiceName.Write("configmgr") 23 config.GddApolloAddr.Write("http://apollo-config-dev-svc:8080") 24 config.GddNacosServerAddr.Write("http://localhost:8848") 25 m.Run() 26 } 27 28 func TestNacosConfigMgr_AddChangeListener(t *testing.T) { 29 Convey("Add listener to Nacos config client", t, func() { 30 ctrl := gomock.NewController(t) 31 defer ctrl.Finish() 32 configClient := mock.NewMockIConfigClient(ctrl) 33 nacosClient := configmgr.NewNacosConfigMgr([]string{".env"}, 34 "DEFAULT_GROUP", "dotenv", "public", configClient, cache.NewConcurrentMap()) 35 nacosClient.AddChangeListener(configmgr.NacosConfigListenerParam{ 36 DataId: ".env", 37 OnChange: nil, 38 }) 39 nacosClient.AddChangeListener(configmgr.NacosConfigListenerParam{ 40 DataId: ".env", 41 OnChange: nil, 42 }) 43 listener, exists := nacosClient.Listeners().Get(util.GetConfigCacheKey(".env", "DEFAULT_GROUP", "public")) 44 So(exists, ShouldBeTrue) 45 So(listener, ShouldNotBeZeroValue) 46 }) 47 } 48 49 func TestNacosConfigMgr_LoadFromNacos_Dotenv(t *testing.T) { 50 Convey("Should not have error", t, func() { 51 ctrl := gomock.NewController(t) 52 defer ctrl.Finish() 53 dataId := ".env" 54 configClient := mock.NewMockIConfigClient(ctrl) 55 configClient. 56 EXPECT(). 57 GetConfig(vo.ConfigParam{ 58 DataId: dataId, 59 Group: config.DefaultGddNacosConfigGroup, 60 }). 61 AnyTimes(). 62 Return("GDD_SERVICE_NAME=configmgr\n\nGDD_READ_TIMEOUT=60s\nGDD_WRITE_TIMEOUT=60s\nGDD_IDLE_TIMEOUT=120s", nil) 63 64 configClient. 65 EXPECT(). 66 ListenConfig(gomock.Any()). 67 AnyTimes(). 68 Return(nil) 69 70 configmgr.NewConfigClient = func(param vo.NacosClientParam) (iClient config_client.IConfigClient, err error) { 71 return configClient, nil 72 } 73 74 if configmgr.NacosClient != nil { 75 configmgr.NacosClient = configmgr.NewNacosConfigMgr([]string{dataId}, 76 config.DefaultGddNacosConfigGroup, configmgr.DotenvConfigFormat, config.DefaultGddNacosNamespaceId, configClient, cache.NewConcurrentMap()) 77 } 78 79 err := configmgr.LoadFromNacos(config.GetNacosClientParam(), dataId, string(config.DefaultGddNacosConfigFormat), config.DefaultGddNacosConfigGroup) 80 So(err, ShouldBeNil) 81 }) 82 } 83 84 func TestNacosConfigMgr_LoadFromNacos_Yaml(t *testing.T) { 85 Convey("Should not have error", t, func() { 86 ctrl := gomock.NewController(t) 87 defer ctrl.Finish() 88 dataId := "app.yml" 89 configClient := mock.NewMockIConfigClient(ctrl) 90 configClient. 91 EXPECT(). 92 GetConfig(vo.ConfigParam{ 93 DataId: dataId, 94 Group: config.DefaultGddNacosConfigGroup, 95 }). 96 AnyTimes(). 97 Return("gdd:\n port: 8088", nil) 98 99 configClient. 100 EXPECT(). 101 ListenConfig(gomock.Any()). 102 AnyTimes(). 103 Return(nil) 104 105 configmgr.NewConfigClient = func(param vo.NacosClientParam) (iClient config_client.IConfigClient, err error) { 106 return configClient, nil 107 } 108 109 if configmgr.NacosClient != nil { 110 configmgr.NacosClient = configmgr.NewNacosConfigMgr([]string{dataId}, 111 config.DefaultGddNacosConfigGroup, configmgr.YamlConfigFormat, config.DefaultGddNacosNamespaceId, configClient, cache.NewConcurrentMap()) 112 } 113 114 err := configmgr.LoadFromNacos(config.GetNacosClientParam(), dataId, string(configmgr.YamlConfigFormat), config.DefaultGddNacosConfigGroup) 115 So(err, ShouldBeNil) 116 }) 117 } 118 119 func TestNacosConfigMgr_CallbackOnChange_Dotenv(t *testing.T) { 120 Convey("Should react to dotenv config change", t, func() { 121 ctrl := gomock.NewController(t) 122 defer ctrl.Finish() 123 dataId := ".env" 124 configClient := mock.NewMockIConfigClient(ctrl) 125 nacosClient := configmgr.NewNacosConfigMgr([]string{dataId}, 126 config.DefaultGddNacosConfigGroup, configmgr.DotenvConfigFormat, config.DefaultGddNacosNamespaceId, configClient, cache.NewConcurrentMap()) 127 nacosClient.AddChangeListener(configmgr.NacosConfigListenerParam{ 128 DataId: dataId, 129 OnChange: func(event *configmgr.NacosChangeEvent) { 130 So(len(event.Changes), ShouldEqual, 4) 131 }, 132 }) 133 nacosClient.CallbackOnChange(config.DefaultGddNacosNamespaceId, config.DefaultGddNacosConfigGroup, dataId, "GDD_SERVICE_NAME=configmgr\n\nGDD_READ_TIMEOUT=60s\nGDD_WRITE_TIMEOUT=60s\nGDD_IDLE_TIMEOUT=120s", "") 134 }) 135 } 136 137 func TestNacosConfigMgr_CallbackOnChange_Yaml(t *testing.T) { 138 Convey("Should react to yaml config change", t, func() { 139 ctrl := gomock.NewController(t) 140 defer ctrl.Finish() 141 dataId := "app.yml" 142 configClient := mock.NewMockIConfigClient(ctrl) 143 nacosClient := configmgr.NewNacosConfigMgr([]string{dataId}, 144 config.DefaultGddNacosConfigGroup, configmgr.YamlConfigFormat, config.DefaultGddNacosNamespaceId, configClient, cache.NewConcurrentMap()) 145 nacosClient.AddChangeListener(configmgr.NacosConfigListenerParam{ 146 DataId: dataId, 147 OnChange: func(event *configmgr.NacosChangeEvent) { 148 So(len(event.Changes), ShouldEqual, 2) 149 }, 150 }) 151 nacosClient.CallbackOnChange(config.DefaultGddNacosNamespaceId, config.DefaultGddNacosConfigGroup, dataId, "gdd:\n port: 6060\n tracing:\n metrics:\n root: \"go-doudou\"", "") 152 }) 153 } 154 155 func ErrReader(err error) io.Reader { 156 return &errReader{err: err} 157 } 158 159 type errReader struct { 160 err error 161 } 162 163 func (r *errReader) Read(p []byte) (int, error) { 164 return 0, r.err 165 } 166 167 func TestNacosConfigMgr_CallbackOnChange_Yaml_Error(t *testing.T) { 168 Convey("Should fail to react to yaml config change", t, func() { 169 ctrl := gomock.NewController(t) 170 defer ctrl.Finish() 171 dataId := "app.yml" 172 configClient := mock.NewMockIConfigClient(ctrl) 173 nacosClient := configmgr.NewNacosConfigMgr([]string{dataId}, 174 config.DefaultGddNacosConfigGroup, configmgr.YamlConfigFormat, config.DefaultGddNacosNamespaceId, configClient, cache.NewConcurrentMap()) 175 configmgr.StringReader = func(s string) io.Reader { 176 return ErrReader(errors.New("mock read error")) 177 } 178 nacosClient.CallbackOnChange(config.DefaultGddNacosNamespaceId, config.DefaultGddNacosConfigGroup, dataId, "gdd:\n port: 6060\n tracing:\n metrics:\n root: \"go-doudou\"", "") 179 }) 180 } 181 182 func TestNacosConfigMgr_CallbackOnChange_Yaml_Error2(t *testing.T) { 183 Convey("Should fail to react to yaml config change", t, func() { 184 ctrl := gomock.NewController(t) 185 defer ctrl.Finish() 186 dataId := "app.yml" 187 configClient := mock.NewMockIConfigClient(ctrl) 188 nacosClient := configmgr.NewNacosConfigMgr([]string{dataId}, 189 config.DefaultGddNacosConfigGroup, configmgr.YamlConfigFormat, config.DefaultGddNacosNamespaceId, configClient, cache.NewConcurrentMap()) 190 configmgr.StringReader = func(s string) io.Reader { 191 if stringutils.IsEmpty(s) { 192 return ErrReader(errors.New("mock read error")) 193 } else { 194 return strings.NewReader(s) 195 } 196 } 197 nacosClient.CallbackOnChange(config.DefaultGddNacosNamespaceId, config.DefaultGddNacosConfigGroup, dataId, "gdd:\n port: 6060\n tracing:\n metrics:\n root: \"go-doudou\"", "") 198 }) 199 } 200 201 func TestNacosConfigMgr_CallbackOnChange_Dotenv_Error(t *testing.T) { 202 Convey("Should fail to react to dotenv config change", t, func() { 203 ctrl := gomock.NewController(t) 204 defer ctrl.Finish() 205 dataId := ".env" 206 configClient := mock.NewMockIConfigClient(ctrl) 207 nacosClient := configmgr.NewNacosConfigMgr([]string{dataId}, 208 config.DefaultGddNacosConfigGroup, configmgr.DotenvConfigFormat, config.DefaultGddNacosNamespaceId, configClient, cache.NewConcurrentMap()) 209 configmgr.StringReader = func(s string) io.Reader { 210 return ErrReader(errors.New("mock read error")) 211 } 212 nacosClient.CallbackOnChange(config.DefaultGddNacosNamespaceId, config.DefaultGddNacosConfigGroup, dataId, "GDD_SERVICE_NAME=configmgr\n\nGDD_READ_TIMEOUT=60s\nGDD_WRITE_TIMEOUT=60s\nGDD_IDLE_TIMEOUT=120s", "") 213 }) 214 } 215 216 func TestNacosConfigMgr_CallbackOnChange_Dotenv_Error2(t *testing.T) { 217 Convey("Should fail to react to dotenv config change", t, func() { 218 ctrl := gomock.NewController(t) 219 defer ctrl.Finish() 220 dataId := ".env" 221 configClient := mock.NewMockIConfigClient(ctrl) 222 nacosClient := configmgr.NewNacosConfigMgr([]string{dataId}, 223 config.DefaultGddNacosConfigGroup, configmgr.DotenvConfigFormat, config.DefaultGddNacosNamespaceId, configClient, cache.NewConcurrentMap()) 224 configmgr.StringReader = func(s string) io.Reader { 225 if stringutils.IsEmpty(s) { 226 return ErrReader(errors.New("mock read error")) 227 } else { 228 return strings.NewReader(s) 229 } 230 } 231 nacosClient.CallbackOnChange(config.DefaultGddNacosNamespaceId, config.DefaultGddNacosConfigGroup, dataId, "GDD_SERVICE_NAME=configmgr\n\nGDD_READ_TIMEOUT=60s\nGDD_WRITE_TIMEOUT=60s\nGDD_IDLE_TIMEOUT=120s", "") 232 }) 233 } 234 235 func TestNacosConfigMgr_LoadFromNacos_Panic(t *testing.T) { 236 Convey("Should panic from listenConfig", t, func() { 237 ctrl := gomock.NewController(t) 238 defer ctrl.Finish() 239 dataId := "app.yml" 240 configClient := mock.NewMockIConfigClient(ctrl) 241 configClient. 242 EXPECT(). 243 GetConfig(vo.ConfigParam{ 244 DataId: dataId, 245 Group: config.DefaultGddNacosConfigGroup, 246 }). 247 AnyTimes(). 248 Return("gdd:\n port: 8088", nil) 249 250 configClient. 251 EXPECT(). 252 ListenConfig(gomock.Any()). 253 AnyTimes(). 254 Return(errors.New("mock returned error")) 255 256 configmgr.NewConfigClient = func(param vo.NacosClientParam) (iClient config_client.IConfigClient, err error) { 257 return configClient, nil 258 } 259 260 if configmgr.NacosClient != nil { 261 configmgr.NacosClient = configmgr.NewNacosConfigMgr([]string{dataId}, 262 config.DefaultGddNacosConfigGroup, configmgr.YamlConfigFormat, config.DefaultGddNacosNamespaceId, configClient, cache.NewConcurrentMap()) 263 } 264 265 So(func() { 266 configmgr.LoadFromNacos(config.GetNacosClientParam(), dataId, string(configmgr.YamlConfigFormat), config.DefaultGddNacosConfigGroup) 267 }, ShouldPanic) 268 }) 269 } 270 271 func TestNacosConfigMgr_LoadFromNacos_UnknownFormat(t *testing.T) { 272 Convey("Should return error", t, func() { 273 ctrl := gomock.NewController(t) 274 defer ctrl.Finish() 275 dataId := "app.yml" 276 configClient := mock.NewMockIConfigClient(ctrl) 277 configClient. 278 EXPECT(). 279 GetConfig(vo.ConfigParam{ 280 DataId: dataId, 281 Group: config.DefaultGddNacosConfigGroup, 282 }). 283 AnyTimes(). 284 Return("gdd:\n port: 8088", nil) 285 286 configClient. 287 EXPECT(). 288 ListenConfig(gomock.Any()). 289 AnyTimes(). 290 Return(nil) 291 292 configmgr.NewConfigClient = func(param vo.NacosClientParam) (iClient config_client.IConfigClient, err error) { 293 return configClient, nil 294 } 295 296 unknownFormat := "Unknown format" 297 298 if configmgr.NacosClient != nil { 299 configmgr.NacosClient = configmgr.NewNacosConfigMgr([]string{dataId}, 300 config.DefaultGddNacosConfigGroup, "Unknown format", config.DefaultGddNacosNamespaceId, configClient, cache.NewConcurrentMap()) 301 } 302 303 err := configmgr.LoadFromNacos(config.GetNacosClientParam(), dataId, unknownFormat, config.DefaultGddNacosConfigGroup) 304 So(err, ShouldResemble, fmt.Errorf("[go-doudou] unknown config format: %s\n", unknownFormat)) 305 }) 306 } 307 308 func TestNacosConfigMgr_LoadFromNacos_Yaml_Error(t *testing.T) { 309 Convey("Should return error from GetConfig", t, func() { 310 ctrl := gomock.NewController(t) 311 defer ctrl.Finish() 312 dataId := "app.yml" 313 configClient := mock.NewMockIConfigClient(ctrl) 314 configClient. 315 EXPECT(). 316 GetConfig(vo.ConfigParam{ 317 DataId: dataId, 318 Group: config.DefaultGddNacosConfigGroup, 319 }). 320 AnyTimes(). 321 Return("", errors.New("mock error from GetConfig")) 322 323 configClient. 324 EXPECT(). 325 ListenConfig(gomock.Any()). 326 AnyTimes(). 327 Return(nil) 328 329 configmgr.NewConfigClient = func(param vo.NacosClientParam) (iClient config_client.IConfigClient, err error) { 330 return configClient, nil 331 } 332 333 if configmgr.NacosClient != nil { 334 configmgr.NacosClient = configmgr.NewNacosConfigMgr([]string{dataId}, 335 config.DefaultGddNacosConfigGroup, configmgr.YamlConfigFormat, config.DefaultGddNacosNamespaceId, configClient, cache.NewConcurrentMap()) 336 } 337 338 err := configmgr.LoadFromNacos(config.GetNacosClientParam(), dataId, string(configmgr.YamlConfigFormat), config.DefaultGddNacosConfigGroup) 339 So(err, ShouldNotBeNil) 340 }) 341 } 342 343 func TestNacosConfigMgr_LoadFromNacos_Dotenv_Error(t *testing.T) { 344 Convey("Should return error from GetConfig", t, func() { 345 ctrl := gomock.NewController(t) 346 defer ctrl.Finish() 347 dataId := ".env" 348 configClient := mock.NewMockIConfigClient(ctrl) 349 configClient. 350 EXPECT(). 351 GetConfig(vo.ConfigParam{ 352 DataId: dataId, 353 Group: config.DefaultGddNacosConfigGroup, 354 }). 355 AnyTimes(). 356 Return("", errors.New("mock error from GetConfig")) 357 358 configClient. 359 EXPECT(). 360 ListenConfig(gomock.Any()). 361 AnyTimes(). 362 Return(nil) 363 364 configmgr.NewConfigClient = func(param vo.NacosClientParam) (iClient config_client.IConfigClient, err error) { 365 return configClient, nil 366 } 367 368 if configmgr.NacosClient != nil { 369 configmgr.NacosClient = configmgr.NewNacosConfigMgr([]string{dataId}, 370 config.DefaultGddNacosConfigGroup, configmgr.DotenvConfigFormat, config.DefaultGddNacosNamespaceId, configClient, cache.NewConcurrentMap()) 371 } 372 373 err := configmgr.LoadFromNacos(config.GetNacosClientParam(), dataId, string(configmgr.DotenvConfigFormat), config.DefaultGddNacosConfigGroup) 374 So(err, ShouldNotBeNil) 375 }) 376 } 377 378 func TestNacosConfigMgr_LoadFromNacos_Dotenv_Error2(t *testing.T) { 379 Convey("Should return error from GetConfig", t, func() { 380 ctrl := gomock.NewController(t) 381 defer ctrl.Finish() 382 dataId := ".env" 383 configClient := mock.NewMockIConfigClient(ctrl) 384 configClient. 385 EXPECT(). 386 GetConfig(vo.ConfigParam{ 387 DataId: dataId, 388 Group: config.DefaultGddNacosConfigGroup, 389 }). 390 AnyTimes(). 391 Return("GDD_SERVICE_NAME=configmgr\n\nGDD_READ_TIMEOUT=60s\nGDD_WRITE_TIMEOUT=60s\nGDD_IDLE_TIMEOUT=120s", nil) 392 393 configClient. 394 EXPECT(). 395 ListenConfig(gomock.Any()). 396 AnyTimes(). 397 Return(nil) 398 399 configmgr.NewConfigClient = func(param vo.NacosClientParam) (iClient config_client.IConfigClient, err error) { 400 return configClient, nil 401 } 402 403 if configmgr.NacosClient != nil { 404 configmgr.NacosClient = configmgr.NewNacosConfigMgr([]string{dataId}, 405 config.DefaultGddNacosConfigGroup, configmgr.DotenvConfigFormat, config.DefaultGddNacosNamespaceId, configClient, cache.NewConcurrentMap()) 406 } 407 408 configmgr.StringReader = func(s string) io.Reader { 409 return ErrReader(errors.New("mock read error")) 410 } 411 412 err := configmgr.LoadFromNacos(config.GetNacosClientParam(), dataId, string(configmgr.DotenvConfigFormat), config.DefaultGddNacosConfigGroup) 413 So(err, ShouldNotBeNil) 414 }) 415 } 416 417 func TestNacosConfigMgr_InitialiseNacosConfig(t *testing.T) { 418 Convey("Should panic", t, func() { 419 dataId := ".env" 420 configmgr.NewConfigClient = func(param vo.NacosClientParam) (iClient config_client.IConfigClient, err error) { 421 return nil, errors.New("mock error from NewConfigClient") 422 } 423 So(func() { 424 configmgr.InitialiseNacosConfig(config.GetNacosClientParam(), dataId, string(config.DefaultGddNacosConfigFormat), config.DefaultGddNacosConfigGroup) 425 }, ShouldPanic) 426 }) 427 }