github.com/nacos-group/nacos-sdk-go@v1.1.4/clients/config_client/config_client_test.go (about)

     1  /*
     2   * Copyright 1999-2020 Alibaba Group Holding Ltd.
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *      http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  
    17  package config_client
    18  
    19  import (
    20  	"errors"
    21  	"fmt"
    22  	"net/http"
    23  	"runtime"
    24  	"testing"
    25  	"time"
    26  
    27  	"github.com/golang/mock/gomock"
    28  	"github.com/nacos-group/nacos-sdk-go/clients/cache"
    29  	"github.com/nacos-group/nacos-sdk-go/clients/nacos_client"
    30  	"github.com/nacos-group/nacos-sdk-go/common/constant"
    31  	"github.com/nacos-group/nacos-sdk-go/common/http_agent"
    32  	"github.com/nacos-group/nacos-sdk-go/mock"
    33  	"github.com/nacos-group/nacos-sdk-go/util"
    34  	"github.com/nacos-group/nacos-sdk-go/vo"
    35  	"github.com/stretchr/testify/assert"
    36  )
    37  
    38  var goVersion = runtime.Version()
    39  
    40  var clientConfigTest = constant.ClientConfig{
    41  	TimeoutMs:    10000,
    42  	BeatInterval: 10000,
    43  }
    44  
    45  var serverConfigTest = constant.ServerConfig{
    46  	ContextPath: "/nacos",
    47  	Port:        80,
    48  	IpAddr:      "console.nacos.io",
    49  }
    50  
    51  var serverConfigWithOptions = constant.NewServerConfig("console.nacos.io", 80, constant.WithContextPath("/nacos"))
    52  
    53  var clientConfigWithOptions = constant.NewClientConfig(
    54  	constant.WithCustomLogger(mockLogger{}),
    55  	constant.WithTimeoutMs(10*1000),
    56  	constant.WithBeatInterval(2*1000),
    57  	constant.WithNotLoadCacheAtStart(true),
    58  )
    59  
    60  var (
    61  	dataIdKey                         = goVersion + "dataId"
    62  	groupKey                          = goVersion + "group:env"
    63  	configNoChangeKey                 = goVersion + "ConfigNoChange"
    64  	multipleClientsKey                = goVersion + "MultipleClients"
    65  	multipleClientsMultipleConfigsKey = goVersion + "MultipleClientsMultipleConfig"
    66  	specialSymbolKey                  = goVersion + "special_symbol"
    67  )
    68  
    69  var configParamMapTest = map[string]string{
    70  	"dataId": dataIdKey,
    71  	"group":  groupKey,
    72  }
    73  
    74  var configParamTest = vo.ConfigParam{
    75  	DataId: dataIdKey,
    76  	Group:  groupKey,
    77  }
    78  
    79  var localConfigTest = vo.ConfigParam{
    80  	DataId:  dataIdKey,
    81  	Group:   groupKey,
    82  	Content: "content",
    83  }
    84  
    85  var localConfigMapTest = map[string]string{
    86  	"dataId":  dataIdKey,
    87  	"group":   groupKey,
    88  	"content": "content",
    89  }
    90  var client *ConfigClient
    91  
    92  func TestMain(m *testing.M) {
    93  	nc := nacos_client.NacosClient{}
    94  	nc.SetServerConfig([]constant.ServerConfig{*serverConfigWithOptions})
    95  	nc.SetClientConfig(*clientConfigWithOptions)
    96  	nc.SetHttpAgent(&http_agent.HttpAgent{})
    97  	client, _ = NewConfigClient(&nc)
    98  	m.Run()
    99  }
   100  
   101  func createConfigClientHttpTest(mockHttpAgent http_agent.IHttpAgent) *ConfigClient {
   102  	nc := nacos_client.NacosClient{}
   103  	nc.SetServerConfig([]constant.ServerConfig{serverConfigTest})
   104  	nc.SetClientConfig(clientConfigTest)
   105  	nc.SetHttpAgent(mockHttpAgent)
   106  	client, _ := NewConfigClient(&nc)
   107  	return client
   108  }
   109  
   110  func Test_GetConfig(t *testing.T) {
   111  	success, err := client.PublishConfig(vo.ConfigParam{
   112  		DataId:  dataIdKey,
   113  		Group:   "group",
   114  		Content: "hello world!222222"})
   115  
   116  	assert.Nil(t, err)
   117  	assert.True(t, success)
   118  
   119  	content, err := client.GetConfig(vo.ConfigParam{
   120  		DataId: dataIdKey,
   121  		Group:  "group"})
   122  
   123  	assert.Nil(t, err)
   124  	assert.Equal(t, "hello world!222222", content)
   125  }
   126  
   127  func Test_SearchConfig(t *testing.T) {
   128  	client.PublishConfig(vo.ConfigParam{
   129  		DataId:  dataIdKey,
   130  		Group:   "groDEFAULT_GROUPup",
   131  		Content: "hello world!222222"})
   132  	configPage, err := client.SearchConfig(vo.SearchConfigParam{
   133  		Search:   "accurate",
   134  		DataId:   dataIdKey,
   135  		Group:    "groDEFAULT_GROUPup",
   136  		PageNo:   1,
   137  		PageSize: 10,
   138  	})
   139  	assert.Nil(t, err)
   140  	assert.NotEmpty(t, configPage)
   141  }
   142  
   143  // PublishConfig
   144  func Test_PublishConfigWithoutDataId(t *testing.T) {
   145  	_, err := client.PublishConfig(vo.ConfigParam{
   146  		DataId:  "",
   147  		Group:   "group",
   148  		Content: "content",
   149  	})
   150  	assert.NotNil(t, err)
   151  }
   152  
   153  func Test_PublishConfigWithoutGroup(t *testing.T) {
   154  	_, err := client.PublishConfig(vo.ConfigParam{
   155  		DataId:  dataIdKey,
   156  		Group:   "",
   157  		Content: "content",
   158  	})
   159  	assert.NotNil(t, err)
   160  }
   161  
   162  func Test_PublishConfigWithoutContent(t *testing.T) {
   163  	_, err := client.PublishConfig(vo.ConfigParam{
   164  		DataId:  dataIdKey,
   165  		Group:   "group",
   166  		Content: "",
   167  	})
   168  	assert.NotNil(t, err)
   169  }
   170  
   171  func Test_PublishConfig(t *testing.T) {
   172  	success, err := client.PublishConfig(vo.ConfigParam{
   173  		DataId:  dataIdKey,
   174  		Group:   "group",
   175  		Content: "hello world2!"})
   176  
   177  	assert.Nil(t, err)
   178  	assert.True(t, success)
   179  }
   180  
   181  func Test_PublishConfigWithType(t *testing.T) {
   182  	success, err := client.PublishConfig(vo.ConfigParam{
   183  		DataId:  dataIdKey,
   184  		Group:   "group",
   185  		Content: "foo",
   186  		Type:    vo.YAML,
   187  	})
   188  
   189  	assert.Nil(t, err)
   190  	assert.True(t, success)
   191  }
   192  
   193  func Test_PublishConfigWithErrorResponse(t *testing.T) {
   194  	controller := gomock.NewController(t)
   195  	defer controller.Finish()
   196  
   197  	mockHttpAgent := mock.NewMockIHttpAgent(controller)
   198  	clientHttp := createConfigClientHttpTest(mockHttpAgent)
   199  	mockHttpAgent.EXPECT().Request(gomock.Eq(http.MethodPost),
   200  		gomock.Eq("http://console.nacos.io:80/nacos/v1/cs/configs"),
   201  		gomock.AssignableToTypeOf(http.Header{}),
   202  		gomock.Eq(clientConfigTest.TimeoutMs),
   203  		gomock.Eq(localConfigMapTest),
   204  	).Times(3).Return(http_agent.FakeHttpResponse(401, "no security"), nil)
   205  	success, err := clientHttp.PublishConfig(localConfigTest)
   206  	assert.NotNil(t, err)
   207  	assert.True(t, !success)
   208  }
   209  
   210  func Test_PublishConfigWithErrorResponse_200(t *testing.T) {
   211  	controller := gomock.NewController(t)
   212  	defer controller.Finish()
   213  
   214  	mockHttpAgent := mock.NewMockIHttpAgent(controller)
   215  	clientHttp := createConfigClientHttpTest(mockHttpAgent)
   216  	mockHttpAgent.EXPECT().Request(gomock.Eq(http.MethodPost),
   217  		gomock.Eq("http://console.nacos.io:80/nacos/v1/cs/configs"),
   218  		gomock.AssignableToTypeOf(http.Header{}),
   219  		gomock.Eq(clientConfigTest.TimeoutMs),
   220  		gomock.Eq(localConfigMapTest),
   221  	).Times(1).Return(http_agent.FakeHttpResponse(200, "false"), nil)
   222  	success, err := clientHttp.PublishConfig(localConfigTest)
   223  	assert.NotNil(t, err)
   224  	assert.True(t, !success)
   225  }
   226  
   227  // DeleteConfig
   228  
   229  func Test_DeleteConfig(t *testing.T) {
   230  	success, err := client.PublishConfig(vo.ConfigParam{
   231  		DataId:  dataIdKey,
   232  		Group:   "group",
   233  		Content: "hello world!"})
   234  
   235  	assert.Nil(t, err)
   236  	assert.True(t, success)
   237  
   238  	success, err = client.DeleteConfig(vo.ConfigParam{
   239  		DataId: dataIdKey,
   240  		Group:  "group"})
   241  
   242  	assert.Nil(t, err)
   243  	assert.True(t, success)
   244  }
   245  
   246  func Test_DeleteConfigWithErrorResponse_200(t *testing.T) {
   247  	controller := gomock.NewController(t)
   248  	defer controller.Finish()
   249  
   250  	mockHttpAgent := mock.NewMockIHttpAgent(controller)
   251  	clientHttp := createConfigClientHttpTest(mockHttpAgent)
   252  
   253  	mockHttpAgent.EXPECT().Request(gomock.Eq(http.MethodDelete),
   254  		gomock.Eq("http://console.nacos.io:80/nacos/v1/cs/configs"),
   255  		gomock.AssignableToTypeOf(http.Header{}),
   256  		gomock.Eq(clientConfigTest.TimeoutMs),
   257  		gomock.Eq(configParamMapTest),
   258  	).Times(1).Return(http_agent.FakeHttpResponse(200, "false"), nil)
   259  	success, err := clientHttp.DeleteConfig(configParamTest)
   260  	assert.NotNil(t, err)
   261  	assert.Equal(t, false, success)
   262  }
   263  
   264  func Test_DeleteConfigWithErrorResponse_401(t *testing.T) {
   265  	controller := gomock.NewController(t)
   266  	defer controller.Finish()
   267  
   268  	mockHttpAgent := mock.NewMockIHttpAgent(controller)
   269  	clientHttp := createConfigClientHttpTest(mockHttpAgent)
   270  
   271  	mockHttpAgent.EXPECT().Request(gomock.Eq(http.MethodDelete),
   272  		gomock.Eq("http://console.nacos.io:80/nacos/v1/cs/configs"),
   273  		gomock.AssignableToTypeOf(http.Header{}),
   274  		gomock.Eq(clientConfigTest.TimeoutMs),
   275  		gomock.Eq(configParamMapTest),
   276  	).Times(3).Return(http_agent.FakeHttpResponse(401, "no security"), nil)
   277  	success, err := clientHttp.DeleteConfig(configParamTest)
   278  	assert.NotNil(t, err)
   279  	assert.Equal(t, false, success)
   280  }
   281  
   282  func Test_DeleteConfigWithoutDataId(t *testing.T) {
   283  	success, err := client.DeleteConfig(vo.ConfigParam{
   284  		DataId: "",
   285  		Group:  "group",
   286  	})
   287  	assert.NotNil(t, err)
   288  	assert.Equal(t, false, success)
   289  }
   290  
   291  func Test_DeleteConfigWithoutGroup(t *testing.T) {
   292  	success, err := client.DeleteConfig(vo.ConfigParam{
   293  		DataId: dataIdKey,
   294  		Group:  "",
   295  	})
   296  	assert.NotNil(t, err)
   297  	assert.Equal(t, false, success)
   298  }
   299  
   300  // ListenConfig
   301  func TestListen(t *testing.T) {
   302  	// ListenConfig
   303  	t.Run("TestListenConfig", func(t *testing.T) {
   304  		key := util.GetConfigCacheKey(localConfigTest.DataId, localConfigTest.Group, clientConfigTest.NamespaceId)
   305  		cache.WriteConfigToFile(key, client.configCacheDir, "")
   306  		var err error
   307  		var success bool
   308  		ch := make(chan string)
   309  		err = client.ListenConfig(vo.ConfigParam{
   310  			DataId: localConfigTest.DataId,
   311  			Group:  localConfigTest.Group,
   312  			OnChange: func(namespace, group, dataId, data string) {
   313  				ch <- data
   314  			},
   315  		})
   316  		assert.Nil(t, err)
   317  
   318  		success, err = client.PublishConfig(vo.ConfigParam{
   319  			DataId:  localConfigTest.DataId,
   320  			Group:   localConfigTest.Group,
   321  			Content: localConfigTest.Content})
   322  
   323  		assert.Nil(t, err)
   324  		assert.Equal(t, true, success)
   325  		select {
   326  		case c := <-ch:
   327  			assert.Equal(t, c, localConfigTest.Content)
   328  		case <-time.After(10 * time.Second):
   329  			assert.Errorf(t, errors.New("timeout"), "timeout")
   330  		}
   331  	})
   332  	// ListenConfig no dataId
   333  	t.Run("TestListenConfigNoDataId", func(t *testing.T) {
   334  		listenConfigParam := vo.ConfigParam{
   335  			Group: "gateway",
   336  			OnChange: func(namespace, group, dataId, data string) {
   337  			},
   338  		}
   339  		err := client.ListenConfig(listenConfigParam)
   340  		assert.Error(t, err)
   341  	})
   342  	// ListenConfig no change
   343  	t.Run("TestListenConfigNoChange", func(t *testing.T) {
   344  		key := util.GetConfigCacheKey(configNoChangeKey, localConfigTest.Group, clientConfigTest.NamespaceId)
   345  		cache.WriteConfigToFile(key, client.configCacheDir, localConfigTest.Content)
   346  		var err error
   347  		var success bool
   348  		var content string
   349  
   350  		err = client.ListenConfig(vo.ConfigParam{
   351  			DataId: configNoChangeKey,
   352  			Group:  localConfigTest.Group,
   353  			OnChange: func(namespace, group, dataId, data string) {
   354  				content = "data"
   355  			},
   356  		})
   357  		assert.Nil(t, err)
   358  
   359  		success, err = client.PublishConfig(vo.ConfigParam{
   360  			DataId:  configNoChangeKey,
   361  			Group:   localConfigTest.Group,
   362  			Content: localConfigTest.Content})
   363  
   364  		assert.Nil(t, err)
   365  		assert.Equal(t, true, success)
   366  		assert.Equal(t, content, "")
   367  	})
   368  	// Multiple clients listen to the same configuration file
   369  	t.Run("TestListenConfigWithMultipleClients", func(t *testing.T) {
   370  		ch := make(chan string)
   371  		listenConfigParam := vo.ConfigParam{
   372  			DataId: multipleClientsKey,
   373  			Group:  localConfigTest.Group,
   374  			OnChange: func(namespace, group, dataId, data string) {
   375  				ch <- data
   376  			},
   377  		}
   378  		key := util.GetConfigCacheKey(listenConfigParam.DataId, listenConfigParam.Group, clientConfigTest.NamespaceId)
   379  		cache.WriteConfigToFile(key, client.configCacheDir, "")
   380  		client.ListenConfig(listenConfigParam)
   381  
   382  		nc := nacos_client.NacosClient{}
   383  		nc.SetServerConfig([]constant.ServerConfig{*serverConfigWithOptions})
   384  		nc.SetClientConfig(*clientConfigWithOptions)
   385  		nc.SetHttpAgent(&http_agent.HttpAgent{})
   386  		client1, _ := NewConfigClient(&nc)
   387  		client1.ListenConfig(listenConfigParam)
   388  
   389  		success, err := client.PublishConfig(vo.ConfigParam{
   390  			DataId:  multipleClientsKey,
   391  			Group:   localConfigTest.Group,
   392  			Content: localConfigTest.Content})
   393  
   394  		assert.Nil(t, err)
   395  		assert.Equal(t, true, success)
   396  		select {
   397  		case c := <-ch:
   398  			assert.Equal(t, localConfigTest.Content, c)
   399  		case <-time.After(10 * time.Second):
   400  			assert.Errorf(t, errors.New("timeout"), "timeout")
   401  		}
   402  
   403  	})
   404  	// Multiple clients listen to multiple configuration files
   405  	t.Run("TestListenConfigWithMultipleClientsMultipleConfig", func(t *testing.T) {
   406  		ch := make(chan string)
   407  		listenConfigParam := vo.ConfigParam{
   408  			DataId: multipleClientsMultipleConfigsKey,
   409  			Group:  localConfigTest.Group,
   410  			OnChange: func(namespace, group, dataId, data string) {
   411  				ch <- data
   412  			},
   413  		}
   414  		key := util.GetConfigCacheKey(listenConfigParam.DataId, listenConfigParam.Group, clientConfigTest.NamespaceId)
   415  		cache.WriteConfigToFile(key, client.configCacheDir, "")
   416  		client.ListenConfig(listenConfigParam)
   417  
   418  		nc := nacos_client.NacosClient{}
   419  		nc.SetServerConfig([]constant.ServerConfig{*serverConfigWithOptions})
   420  		nc.SetClientConfig(*clientConfigWithOptions)
   421  		nc.SetHttpAgent(&http_agent.HttpAgent{})
   422  		client1, _ := NewConfigClient(&nc)
   423  		client1.ListenConfig(listenConfigParam)
   424  
   425  		success, err := client.PublishConfig(vo.ConfigParam{
   426  			DataId:  multipleClientsMultipleConfigsKey,
   427  			Group:   localConfigTest.Group,
   428  			Content: localConfigTest.Content})
   429  
   430  		assert.Nil(t, err)
   431  		assert.Equal(t, true, success)
   432  		select {
   433  		case c := <-ch:
   434  			assert.Equal(t, localConfigTest.Content, c)
   435  		case <-time.After(10 * time.Second):
   436  			assert.Errorf(t, errors.New("timeout"), "timeout")
   437  		}
   438  
   439  	})
   440  }
   441  
   442  func TestGetConfigWithSpecialSymbol(t *testing.T) {
   443  	contentStr := "hello world!!@#$%^&&*()"
   444  	success, err := client.PublishConfig(vo.ConfigParam{
   445  		DataId:  specialSymbolKey,
   446  		Group:   localConfigTest.Group,
   447  		Content: contentStr})
   448  
   449  	assert.Nil(t, err)
   450  	assert.True(t, success)
   451  
   452  	content, err := client.GetConfig(vo.ConfigParam{
   453  		DataId: specialSymbolKey,
   454  		Group:  localConfigTest.Group})
   455  
   456  	assert.Nil(t, err)
   457  	assert.Equal(t, contentStr, content)
   458  }
   459  
   460  type mockLogger struct {
   461  }
   462  
   463  func (m mockLogger) Info(args ...interface{}) {
   464  	fmt.Println(args...)
   465  }
   466  
   467  func (m mockLogger) Warn(args ...interface{}) {
   468  	fmt.Println(args...)
   469  }
   470  
   471  func (m mockLogger) Error(args ...interface{}) {
   472  	fmt.Println(args...)
   473  }
   474  
   475  func (m mockLogger) Debug(args ...interface{}) {
   476  	fmt.Println(args...)
   477  }
   478  
   479  func (m mockLogger) Infof(format string, args ...interface{}) {
   480  	fmt.Println(fmt.Sprintf(format, args...))
   481  }
   482  
   483  func (m mockLogger) Warnf(format string, args ...interface{}) {
   484  	fmt.Println(fmt.Sprintf(format, args...))
   485  }
   486  
   487  func (m mockLogger) Errorf(format string, args ...interface{}) {
   488  	fmt.Println(fmt.Sprintf(format, args...))
   489  }
   490  
   491  func (m mockLogger) Debugf(format string, args ...interface{}) {
   492  	fmt.Println("implement me")
   493  }