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  }