github.com/polarismesh/polaris@v1.17.8/service/client_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 service_test
    19  
    20  import (
    21  	"context"
    22  	"fmt"
    23  	"sync"
    24  	"testing"
    25  
    26  	apimodel "github.com/polarismesh/specification/source/go/api/v1/model"
    27  	"github.com/polarismesh/specification/source/go/api/v1/service_manage"
    28  	apiservice "github.com/polarismesh/specification/source/go/api/v1/service_manage"
    29  	"github.com/stretchr/testify/assert"
    30  
    31  	api "github.com/polarismesh/polaris/common/api/v1"
    32  	apiv1 "github.com/polarismesh/polaris/common/api/v1"
    33  	"github.com/polarismesh/polaris/common/model"
    34  	"github.com/polarismesh/polaris/common/utils"
    35  	"github.com/polarismesh/polaris/service"
    36  )
    37  
    38  // 测试discover instances
    39  func TestDiscoverInstances(t *testing.T) {
    40  
    41  	discoverSuit := &DiscoverTestSuit{}
    42  	if err := discoverSuit.Initialize(); err != nil {
    43  		t.Fatal(err)
    44  	}
    45  	defer discoverSuit.Destroy()
    46  
    47  	t.Run("服务发现测试", func(t *testing.T) {
    48  		_, service := discoverSuit.createCommonService(t, 5)
    49  		defer discoverSuit.cleanServiceName(service.GetName().GetValue(), service.GetNamespace().GetValue())
    50  		count := 5
    51  		var instances []*apiservice.Instance
    52  		var reqInstances []*apiservice.Instance
    53  		defer func() {
    54  			for _, entry := range instances {
    55  				discoverSuit.cleanInstance(entry.GetId().GetValue())
    56  			}
    57  		}()
    58  		for i := 0; i < count; i++ {
    59  			req, instance := discoverSuit.createCommonInstance(t, service, i)
    60  			instances = append(instances, instance)
    61  			reqInstances = append(reqInstances, req)
    62  		}
    63  		t.Run("正常服务发现,返回的数据齐全", func(t *testing.T) {
    64  			_ = discoverSuit.DiscoverServer().Cache().TestUpdate()
    65  			out := discoverSuit.DiscoverServer().ServiceInstancesCache(discoverSuit.DefaultCtx, service)
    66  			assert.True(t, respSuccess(out))
    67  			assert.Equal(t, count, len(out.GetInstances()))
    68  			// 返回必须包含服务元数据
    69  			assert.True(t, len(out.GetService().Metadata) > 0)
    70  
    71  			for _, resp := range out.GetInstances() {
    72  				found := false
    73  				for _, req := range reqInstances {
    74  					if resp.GetHost().GetValue() == req.GetHost().GetValue() {
    75  						instanceCheck(t, req, resp) // expect actual
    76  						// 检查resp中必须包含额外的metadata
    77  						assert.Equal(t, resp.Metadata["version"], req.GetVersion().GetValue())
    78  						assert.Equal(t, resp.Metadata["protocol"], req.GetProtocol().GetValue())
    79  						found = true
    80  						t.Logf("%+v", resp)
    81  						break
    82  					}
    83  				}
    84  				assert.True(t, found)
    85  			}
    86  		})
    87  		t.Run("service-metadata修改,revision会修改", func(t *testing.T) {
    88  			out := discoverSuit.DiscoverServer().ServiceInstancesCache(discoverSuit.DefaultCtx, service)
    89  			assert.True(t, respSuccess(out))
    90  			oldRevision := out.GetService().GetRevision().GetValue()
    91  
    92  			service.Metadata = make(map[string]string)
    93  			service.Metadata["new-metadata1"] = "1233"
    94  			service.Metadata["new-metadata2"] = "2342"
    95  			resp := discoverSuit.DiscoverServer().UpdateServices(discoverSuit.DefaultCtx, []*apiservice.Service{service})
    96  			_ = discoverSuit.DiscoverServer().Cache().TestUpdate()
    97  			assert.True(t, respSuccess(resp))
    98  			assert.NotEqual(t, resp.Responses[0].GetService().GetRevision().GetValue(), oldRevision)
    99  			assert.Equal(t, resp.Responses[0].GetService().GetMetadata()["new-metadata1"], "1233")
   100  			assert.Equal(t, resp.Responses[0].GetService().GetMetadata()["new-metadata2"], "2342")
   101  			serviceCheck(t, service, resp.Responses[0].GetService())
   102  		})
   103  	})
   104  }
   105  
   106  // 测试discover circuitbreaker
   107  func TestDiscoverCircuitBreaker(t *testing.T) {
   108  
   109  	discoverSuit := &DiscoverTestSuit{}
   110  	if err := discoverSuit.Initialize(); err != nil {
   111  		t.Fatal(err)
   112  	}
   113  	defer discoverSuit.Destroy()
   114  
   115  	t.Run("熔断规则测试", func(t *testing.T) {
   116  		rules, resp := createCircuitBreakerRules(discoverSuit, 5)
   117  		defer cleanCircuitBreakerRules(discoverSuit, resp)
   118  		service := &apiservice.Service{Name: utils.NewStringValue("testDestService"), Namespace: utils.NewStringValue("test")}
   119  		t.Run("正常获取熔断规则", func(t *testing.T) {
   120  			_ = discoverSuit.DiscoverServer().Cache().TestUpdate()
   121  			out := discoverSuit.DiscoverServer().GetCircuitBreakerWithCache(discoverSuit.DefaultCtx, service)
   122  			assert.True(t, respSuccess(out))
   123  			assert.Equal(t, len(out.GetCircuitBreaker().GetRules()), len(rules))
   124  			t.Logf("pass: out is %+v", out)
   125  
   126  			// 再次请求
   127  			out = discoverSuit.DiscoverServer().GetCircuitBreakerWithCache(discoverSuit.DefaultCtx, out.GetService())
   128  			assert.True(t, respSuccess(out))
   129  			assert.Equal(t, out.GetCode().GetValue(), api.DataNoChange)
   130  			t.Logf("pass: out is %+v", out)
   131  		})
   132  	})
   133  }
   134  
   135  // 测试discover circuitbreaker
   136  func TestDiscoverCircuitBreaker2(t *testing.T) {
   137  
   138  	discoverSuit := &DiscoverTestSuit{}
   139  	if err := discoverSuit.Initialize(); err != nil {
   140  		t.Fatal(err)
   141  	}
   142  	defer discoverSuit.Destroy()
   143  
   144  	t.Run("熔断规则异常测试", func(t *testing.T) {
   145  		_, resp := createCircuitBreakerRules(discoverSuit, 1)
   146  		defer cleanCircuitBreakerRules(discoverSuit, resp)
   147  		service := &apiservice.Service{Name: utils.NewStringValue("testDestService"), Namespace: utils.NewStringValue("default")}
   148  		t.Run("熔断规则不存在", func(t *testing.T) {
   149  			_ = discoverSuit.DiscoverServer().Cache().TestUpdate()
   150  			out := discoverSuit.DiscoverServer().GetCircuitBreakerWithCache(discoverSuit.DefaultCtx, service)
   151  			assert.True(t, respSuccess(out))
   152  			assert.Equal(t, 0, len(out.GetCircuitBreaker().GetRules()))
   153  			t.Logf("pass: out is %+v", out)
   154  		})
   155  	})
   156  }
   157  
   158  // 测试discover service
   159  func TestDiscoverService(t *testing.T) {
   160  
   161  	discoverSuit := &DiscoverTestSuit{}
   162  	if err := discoverSuit.Initialize(); err != nil {
   163  		t.Fatal(err)
   164  	}
   165  	defer discoverSuit.Destroy()
   166  
   167  	t.Run("服务测试", func(t *testing.T) {
   168  		expectService1 := &apiservice.Service{}
   169  		expectService2 := &apiservice.Service{}
   170  		for id := 0; id < 5; id++ {
   171  			_, service := discoverSuit.createCommonService(t, id)
   172  			if id == 3 {
   173  				expectService1 = service
   174  			}
   175  			if id == 4 {
   176  				expectService2 = service
   177  			}
   178  			defer discoverSuit.cleanServiceName(service.GetName().GetValue(), service.GetNamespace().GetValue())
   179  		}
   180  
   181  		meta := make(map[string]string)
   182  		requestMeta := make(map[string]string)
   183  		for i := 0; i < 5; i++ {
   184  			k := fmt.Sprintf("key-%d", i)
   185  			v := fmt.Sprintf("value-%d", i)
   186  			if i == 0 || i == 1 {
   187  				requestMeta[k] = v
   188  			}
   189  			meta[k] = v
   190  		}
   191  
   192  		expectService1.Metadata = meta
   193  		expectService2.Metadata = meta
   194  		_ = discoverSuit.DiscoverServer().UpdateServices(discoverSuit.DefaultCtx, []*apiservice.Service{expectService1})
   195  		_ = discoverSuit.DiscoverServer().UpdateServices(discoverSuit.DefaultCtx, []*apiservice.Service{expectService1})
   196  		_ = discoverSuit.DiscoverServer().Cache().TestUpdate()
   197  
   198  		t.Run("正常获取服务", func(t *testing.T) {
   199  			requestService := &apiservice.Service{
   200  				Metadata: requestMeta,
   201  			}
   202  			out := discoverSuit.DiscoverServer().GetServiceWithCache(discoverSuit.DefaultCtx, requestService)
   203  			assert.True(t, respSuccess(out))
   204  			if len(out.GetServices()) == 2 {
   205  				t.Logf("pass: out service is %+v", out.GetServices())
   206  			} else {
   207  				t.Logf("error: out is %+v", out)
   208  			}
   209  		})
   210  
   211  		t.Run("元数据匹配到的服务为空", func(t *testing.T) {
   212  			requestMeta := make(map[string]string)
   213  			requestMeta["test"] = "test"
   214  			requestService := &apiservice.Service{
   215  				Metadata: requestMeta,
   216  			}
   217  			out := discoverSuit.DiscoverServer().GetServiceWithCache(discoverSuit.DefaultCtx, requestService)
   218  			assert.True(t, respSuccess(out))
   219  			if len(out.GetServices()) == 0 {
   220  				t.Logf("pass: out service is %+v", out.GetServices())
   221  			} else {
   222  				t.Logf("error: out is %+v", out)
   223  			}
   224  		})
   225  	})
   226  }
   227  
   228  // 测试discover service
   229  func TestDiscoverService2(t *testing.T) {
   230  
   231  	discoverSuit := &DiscoverTestSuit{}
   232  	if err := discoverSuit.Initialize(); err != nil {
   233  		t.Fatal(err)
   234  	}
   235  	defer discoverSuit.Destroy()
   236  
   237  	t.Run("服务正常测试", func(t *testing.T) {
   238  		t.Run("元数据不存在", func(t *testing.T) {
   239  			service := &apiservice.Service{}
   240  			out := discoverSuit.DiscoverServer().GetServiceWithCache(discoverSuit.DefaultCtx, service)
   241  			assert.True(t, respSuccess(out))
   242  			t.Logf("pass: out is %+v", out)
   243  		})
   244  		t.Run("元数据为空", func(t *testing.T) {
   245  			service := &apiservice.Service{
   246  				Metadata: make(map[string]string),
   247  			}
   248  			out := discoverSuit.DiscoverServer().GetServiceWithCache(discoverSuit.DefaultCtx, service)
   249  			assert.True(t, respSuccess(out))
   250  			t.Logf("pass: out is %+v", out)
   251  		})
   252  	})
   253  }
   254  
   255  // 测试discover ratelimit
   256  func TestDiscoverRateLimits(t *testing.T) {
   257  
   258  	discoverSuit := &DiscoverTestSuit{}
   259  	if err := discoverSuit.Initialize(); err != nil {
   260  		t.Fatal(err)
   261  	}
   262  	defer discoverSuit.Destroy()
   263  
   264  	t.Run("限流规则测试", func(t *testing.T) {
   265  		_, service := discoverSuit.createCommonService(t, 1)
   266  		defer discoverSuit.cleanServiceName(service.GetName().GetValue(), service.GetNamespace().GetValue())
   267  		_, rateLimitResp := discoverSuit.createCommonRateLimit(t, service, 1)
   268  		defer discoverSuit.cleanRateLimit(rateLimitResp.GetId().GetValue())
   269  		defer discoverSuit.cleanRateLimitRevision(service.GetName().GetValue(), service.GetNamespace().GetValue())
   270  		t.Run("正常获取限流规则", func(t *testing.T) {
   271  			_ = discoverSuit.DiscoverServer().Cache().TestUpdate()
   272  			out := discoverSuit.DiscoverServer().GetRateLimitWithCache(discoverSuit.DefaultCtx, service)
   273  			assert.True(t, respSuccess(out))
   274  			assert.Equal(t, len(out.GetRateLimit().GetRules()), 1)
   275  			checkRateLimit(t, rateLimitResp, out.GetRateLimit().GetRules()[0])
   276  			t.Logf("pass: out is %+v", out)
   277  			// 再次请求
   278  			out = discoverSuit.DiscoverServer().GetRateLimitWithCache(discoverSuit.DefaultCtx, out.GetService())
   279  			assert.True(t, respSuccess(out))
   280  			assert.Equal(t, out.GetCode().GetValue(), api.DataNoChange)
   281  			t.Logf("pass: out is %+v", out)
   282  		})
   283  		t.Run("限流规则已删除", func(t *testing.T) {
   284  			discoverSuit.deleteRateLimit(t, rateLimitResp)
   285  			_ = discoverSuit.DiscoverServer().Cache().TestUpdate()
   286  			out := discoverSuit.DiscoverServer().GetRateLimitWithCache(discoverSuit.DefaultCtx, service)
   287  			assert.True(t, respSuccess(out))
   288  			assert.Equal(t, len(out.GetRateLimit().GetRules()), 0)
   289  			t.Logf("pass: out is %+v", out)
   290  		})
   291  	})
   292  }
   293  
   294  // 测试discover ratelimit
   295  func TestDiscoverRateLimits2(t *testing.T) {
   296  
   297  	discoverSuit := &DiscoverTestSuit{}
   298  	if err := discoverSuit.Initialize(); err != nil {
   299  		t.Fatal(err)
   300  	}
   301  	defer discoverSuit.Destroy()
   302  
   303  	t.Run("限流规则异常测试", func(t *testing.T) {
   304  		_, service := discoverSuit.createCommonService(t, 1)
   305  		defer discoverSuit.cleanServiceName(service.GetName().GetValue(), service.GetNamespace().GetValue())
   306  		t.Run("限流规则不存在", func(t *testing.T) {
   307  			_ = discoverSuit.DiscoverServer().Cache().TestUpdate()
   308  			out := discoverSuit.DiscoverServer().GetRateLimitWithCache(discoverSuit.DefaultCtx, service)
   309  			assert.True(t, respSuccess(out))
   310  			assert.Nil(t, out.GetRateLimit())
   311  			t.Logf("pass: out is %+v", out)
   312  		})
   313  		t.Run("服务不存在", func(t *testing.T) {
   314  			_ = discoverSuit.DiscoverServer().Cache().TestUpdate()
   315  			out := discoverSuit.DiscoverServer().GetRateLimitWithCache(discoverSuit.DefaultCtx, &apiservice.Service{
   316  				Name:      utils.NewStringValue("not_exist_service"),
   317  				Namespace: utils.NewStringValue("not_exist_namespace"),
   318  			})
   319  			assert.True(t, respSuccess(out))
   320  			t.Logf("pass: out is %+v", out)
   321  		})
   322  	})
   323  }
   324  
   325  func mockReportClients(cnt int) []*apiservice.Client {
   326  	ret := make([]*apiservice.Client, 0, 4)
   327  
   328  	for i := 0; i < cnt; i++ {
   329  		ret = append(ret, &apiservice.Client{
   330  			Host:     utils.NewStringValue("127.0.0.1"),
   331  			Type:     apiservice.Client_SDK,
   332  			Version:  utils.NewStringValue("v1.0.0"),
   333  			Location: &apimodel.Location{},
   334  			Id:       utils.NewStringValue(utils.NewUUID()),
   335  			Stat: []*apiservice.StatInfo{
   336  				{
   337  					Target:   utils.NewStringValue(model.StatReportPrometheus),
   338  					Port:     utils.NewUInt32Value(uint32(1000 + i)),
   339  					Path:     utils.NewStringValue("/metrics"),
   340  					Protocol: utils.NewStringValue("http"),
   341  				},
   342  			},
   343  		})
   344  	}
   345  
   346  	return ret
   347  }
   348  
   349  func TestServer_ReportClient(t *testing.T) {
   350  	t.Run("正常客户端上报", func(t *testing.T) {
   351  		discoverSuit := &DiscoverTestSuit{}
   352  		if err := discoverSuit.Initialize(); err != nil {
   353  			t.Fatal(err)
   354  		}
   355  		defer discoverSuit.Destroy()
   356  
   357  		clients := mockReportClients(1)
   358  		defer discoverSuit.cleanReportClient()
   359  
   360  		for i := range clients {
   361  			resp := discoverSuit.DiscoverServer().ReportClient(discoverSuit.DefaultCtx, clients[i])
   362  			assert.True(t, respSuccess(resp), resp.GetInfo().GetValue())
   363  		}
   364  	})
   365  }
   366  
   367  func TestServer_GetReportClient(t *testing.T) {
   368  	t.Run("客户端上报-查询客户端信息", func(t *testing.T) {
   369  		discoverSuit := &DiscoverTestSuit{}
   370  		if err := discoverSuit.Initialize(); err != nil {
   371  			t.Fatal(err)
   372  		}
   373  		defer discoverSuit.Destroy()
   374  
   375  		clients := mockReportClients(5)
   376  		defer discoverSuit.cleanReportClient()
   377  
   378  		wait := sync.WaitGroup{}
   379  		wait.Add(5)
   380  		for i := range clients {
   381  			go func(client *apiservice.Client) {
   382  				defer wait.Done()
   383  				resp := discoverSuit.DiscoverServer().ReportClient(discoverSuit.DefaultCtx, client)
   384  				assert.True(t, respSuccess(resp), resp.GetInfo().GetValue())
   385  				t.Logf("create one client success : %s", client.GetId().GetValue())
   386  			}(clients[i])
   387  		}
   388  
   389  		wait.Wait()
   390  		_ = discoverSuit.DiscoverServer().Cache().TestUpdate()
   391  		t.Log("finish sleep to wait cache refresh")
   392  
   393  		resp := discoverSuit.DiscoverServer().GetPrometheusTargets(context.Background(), map[string]string{})
   394  		assert.Equal(t, apiv1.ExecuteSuccess, resp.Code)
   395  		assert.True(t, len(resp.Response) >= 0 && len(resp.Response) <= 5)
   396  	})
   397  }
   398  
   399  func TestServer_GetReportClients(t *testing.T) {
   400  	discoverSuit := &DiscoverTestSuit{}
   401  	if err := discoverSuit.Initialize(); err != nil {
   402  		t.Fatal(err)
   403  	}
   404  
   405  	t.Run("create client", func(t *testing.T) {
   406  		svr := discoverSuit.OriginDiscoverServer()
   407  
   408  		mockClientId := utils.NewUUID()
   409  		resp := svr.ReportClient(context.Background(), &service_manage.Client{
   410  			Host:    utils.NewStringValue("127.0.0.1"),
   411  			Type:    service_manage.Client_SDK,
   412  			Version: utils.NewStringValue("1.0.0"),
   413  			Location: &apimodel.Location{
   414  				Region: utils.NewStringValue("region"),
   415  				Zone:   utils.NewStringValue("zone"),
   416  				Campus: utils.NewStringValue("campus"),
   417  			},
   418  			Id: utils.NewStringValue(mockClientId),
   419  			Stat: []*service_manage.StatInfo{
   420  				{
   421  					Target:   utils.NewStringValue("prometheus"),
   422  					Port:     utils.NewUInt32Value(8080),
   423  					Path:     utils.NewStringValue("/metrics"),
   424  					Protocol: utils.NewStringValue("http"),
   425  				},
   426  			},
   427  		})
   428  
   429  		assert.Equal(t, resp.GetCode().GetValue(), uint32(apimodel.Code_ExecuteSuccess))
   430  		// 强制刷新到 cache
   431  		svr.Cache().TestUpdate()
   432  
   433  		originSvr := discoverSuit.OriginDiscoverServer().(*service.Server)
   434  		qresp := originSvr.GetReportClients(discoverSuit.DefaultCtx, map[string]string{})
   435  		assert.Equal(t, resp.GetCode().GetValue(), uint32(apimodel.Code_ExecuteSuccess))
   436  		assert.Equal(t, qresp.GetAmount().GetValue(), uint32(1))
   437  		assert.Equal(t, qresp.GetSize().GetValue(), uint32(1))
   438  	})
   439  }