From 71d76815749db7529df9447800135a28a44a8472 Mon Sep 17 00:00:00 2001
From: LaurenceLiZhixin <382673304@qq.com>
Date: Thu, 25 Mar 2021 23:28:13 +0800
Subject: [PATCH] fix: add test case

---
 cluster/router/uniform/internal/dest_rule.yml |  17 ++
 .../uniform/internal/virtual_service.yml      | 170 ++++++++++++++++
 .../match_judger/string_match_judger_test.go  |   4 -
 cluster/router/uniform/router_chain.go        |   6 +-
 cluster/router/uniform/router_chain_test.go   | 185 ++++++++++++++++++
 cluster/router/uniform/uniform_route_test.go  |  92 ---------
 cluster/router/uniform/uniform_rule_test.go   |  53 -----
 7 files changed, 373 insertions(+), 154 deletions(-)
 create mode 100644 cluster/router/uniform/internal/dest_rule.yml
 create mode 100644 cluster/router/uniform/internal/virtual_service.yml
 create mode 100644 cluster/router/uniform/router_chain_test.go
 delete mode 100644 cluster/router/uniform/uniform_route_test.go
 delete mode 100644 cluster/router/uniform/uniform_rule_test.go

diff --git a/cluster/router/uniform/internal/dest_rule.yml b/cluster/router/uniform/internal/dest_rule.yml
new file mode 100644
index 000000000..89bd88f01
--- /dev/null
+++ b/cluster/router/uniform/internal/dest_rule.yml
@@ -0,0 +1,17 @@
+apiVersion: service.dubbo.apache.org/v1alpha1
+kind: DestinationRule
+metadata:
+  name: demo-route
+spec:
+  host: demo
+  subsets:
+    - name: v1
+      labels:
+        sigma.ali/mg: v1-host
+        generic: false
+    - name: v2
+      labels:
+        generic: false
+    - name: v3
+      labels:
+        sigma.ali/mg: v3-host
\ No newline at end of file
diff --git a/cluster/router/uniform/internal/virtual_service.yml b/cluster/router/uniform/internal/virtual_service.yml
new file mode 100644
index 000000000..49aef1a99
--- /dev/null
+++ b/cluster/router/uniform/internal/virtual_service.yml
@@ -0,0 +1,170 @@
+apiVersion: service.dubbo.apache.org/v1alpha1
+kind: VirtualService
+metadata:
+  name: demo-route
+spec:
+  hosts:
+    - demo  # app name
+  dubbo:
+    - service:
+        - exact: com.taobao.hsf.demoService:1.0.0
+        - exact: com.taobao.hsf.demoService:2.0.0
+      routedetail:
+        - name: sayHello-String-method-route
+          match:
+            - method:
+                name_match:
+                  exact: "sayHello"
+          #                  argp:
+          #                    - string
+          route:
+            - destination:
+                host: demo
+                subset: v1
+              fallback:
+                destination:
+                  host: demo
+                  subset: v2
+                fallback:
+                  destination:
+                    host: demo
+                    subset: v3
+
+        - name: sayHello-method-route
+          match:
+            - method:
+                name_match:
+                  exact: "s-method"
+          route:
+            - destination:
+                host: demo
+                subset: v2
+              fallback:
+                destination:
+                  host: demo
+                  subset: v3
+        - name: some-method-route
+          match:
+            - method:
+                name_match:
+                  exact: "some-method"
+          route:
+            - destination:
+                host: demo
+                subset: v4
+
+#        - name: interface-route
+#          route:
+#            - destination:
+#              host: demo
+#              subset: v3
+        - name: final
+          match:
+            - method:
+                name_match:
+                  exact: "GetUser"
+
+          route:
+            - destination:
+                host: demo
+                subset: v1
+              fallback:
+                destination:
+                  host: demo
+                  subset: v2
+                fallback:
+                  destination:
+                    host: demo
+                    subset: v3
+            - destination:
+                host: demo
+                subset: v3
+              fallback:
+                destination:
+                  host: demo
+                  subset: v2
+                fallback:
+                  destination:
+                    host: demo
+                    subset: v1
+    - service:
+        - exact: com.taobao.hsf.demoService:1.0.0
+        - exact: org.apache.dubbo.UserProvider
+      routedetail:
+        - name: sayHello-String-method-route
+          match:
+            - method:
+                name_match:
+                  exact: "sayHello"
+          #                  argp:
+          #                    - string
+          route:
+            - destination:
+                host: demo
+                subset: v1
+              fallback:
+                destination:
+                  host: demo
+                  subset: v2
+                fallback:
+                  destination:
+                    host: demo
+                    subset: v3
+
+        - name: sayHello-method-route
+          match:
+            - method:
+                name_match:
+                  exact: "s-method"
+          route:
+            - destination:
+                host: demo
+                subset: v2
+              fallback:
+                destination:
+                  host: demo
+                  subset: v3
+        - name: some-method-route
+          match:
+            - method:
+                name_match:
+                  exact: "some-method"
+          route:
+            - destination:
+                host: demo
+                subset: v4
+
+        #        - name: interface-route
+        #          route:
+        #            - destination:
+        #              host: demo
+        #              subset: v3
+        - name: final
+          match:
+            - method:
+                name_match:
+                  exact: "GetUser"
+
+          route:
+            - destination:
+                host: demo
+                subset: v1
+              fallback:
+                destination:
+                  host: demo
+                  subset: v2
+                fallback:
+                  destination:
+                    host: demo
+                    subset: v3
+            - destination:
+                host: demo
+                subset: v3
+              fallback:
+                destination:
+                  host: demo
+                  subset: v2
+                fallback:
+                  destination:
+                    host: demo
+                    subset: v1
\ No newline at end of file
diff --git a/cluster/router/uniform/match_judger/string_match_judger_test.go b/cluster/router/uniform/match_judger/string_match_judger_test.go
index 328a7c3d3..f2e9c7cc2 100644
--- a/cluster/router/uniform/match_judger/string_match_judger_test.go
+++ b/cluster/router/uniform/match_judger/string_match_judger_test.go
@@ -48,7 +48,3 @@ func TestNewStringMatchJudger(t *testing.T) {
 		NoEmpty: "true",
 	}).Judge(""))
 }
-
-func TestStringMatchJudger_Judge(t *testing.T) {
-
-}
diff --git a/cluster/router/uniform/router_chain.go b/cluster/router/uniform/router_chain.go
index c15339344..147247be9 100644
--- a/cluster/router/uniform/router_chain.go
+++ b/cluster/router/uniform/router_chain.go
@@ -220,11 +220,7 @@ func parseFromConfigToRouters(virtualServiceConfig, destinationRuleConfig []byte
 			// copy to new Map
 			mapCombine(tempSerivceNeedsDescMap, targetDestMap)
 		}
-		data, err := json.Marshal(v.Spec.Dubbo)
-		if err != nil {
-			logger.Error("v.Spec.Dubbo unmarshal error = ", err)
-		}
-		fmt.Printf("===v.Spec.Dubbo = %s\n", string(data))
+		// change single config to one rule
 		newRule, err := newDubboRouterRule(v.Spec.Dubbo, tempSerivceNeedsDescMap)
 		if err != nil {
 			logger.Error("Parse config to uniform rule err = ", err)
diff --git a/cluster/router/uniform/router_chain_test.go b/cluster/router/uniform/router_chain_test.go
new file mode 100644
index 000000000..d27f9780a
--- /dev/null
+++ b/cluster/router/uniform/router_chain_test.go
@@ -0,0 +1,185 @@
+package uniform
+
+import (
+	"fmt"
+	"github.com/apache/dubbo-go/common"
+	"github.com/apache/dubbo-go/common/yaml"
+	"github.com/apache/dubbo-go/protocol"
+	"github.com/apache/dubbo-go/protocol/invocation"
+	"github.com/stretchr/testify/assert"
+	"testing"
+)
+
+const (
+	mockVSConfigPath = "./internal/virtual_service.yml"
+	mockDRConfigPath = "./internal/dest_rule.yml"
+)
+
+func TestNewUniformRouterChain(t *testing.T) {
+	vsBytes, _ := yaml.LoadYMLConfig(mockVSConfigPath)
+	drBytes, _ := yaml.LoadYMLConfig(mockDRConfigPath)
+	rc, err := NewUniformRouterChain(vsBytes, drBytes, make(chan struct{}))
+	assert.Nil(t, err)
+	assert.NotNil(t, rc)
+}
+
+type ruleTestItemStruct struct {
+	name                             string
+	matchMethodNameExact             string
+	RouterDestHost                   string
+	RouterDestSubset                 string
+	RouterFallBackDestHost           string
+	RouterFallBackDestSubset         string
+	RouterFallBackFallBackDestHost   string
+	RouterFallBackFallBackDestSubset string
+	fallbackLevel                    int
+	RouterSize                       int
+}
+
+func TestParseConfigFromFile(t *testing.T) {
+	vsBytes, _ := yaml.LoadYMLConfig(mockVSConfigPath)
+	drBytes, _ := yaml.LoadYMLConfig(mockDRConfigPath)
+	routers, err := parseFromConfigToRouters(vsBytes, drBytes, make(chan struct{}, 1))
+	fmt.Println(routers, err)
+	assert.Equal(t, len(routers), 1)
+	assert.NotNil(t, routers[0].dubboRouter)
+	assert.Equal(t, len(routers[0].dubboRouter.uniformRules), 2)
+	for i, v := range routers[0].dubboRouter.uniformRules {
+		if i == 0 {
+			assert.Equal(t, len(v.services), 2)
+			assert.Equal(t, "com.taobao.hsf.demoService:1.0.0", v.services[0].Exact)
+			assert.Equal(t, "", v.services[0].Regex)
+			assert.Equal(t, "", v.services[0].NoEmpty)
+			assert.Equal(t, "", v.services[0].Empty)
+			assert.Equal(t, "", v.services[0].Prefix)
+
+			assert.Equal(t, "com.taobao.hsf.demoService:2.0.0", v.services[1].Exact)
+			assert.Equal(t, "", v.services[1].Regex)
+			assert.Equal(t, "", v.services[1].NoEmpty)
+			assert.Equal(t, "", v.services[1].Empty)
+			assert.Equal(t, "", v.services[1].Prefix)
+
+			assert.Equal(t, len(v.virtualServiceRules), 4)
+
+			ruleTestItemStructList := []ruleTestItemStruct{
+				{
+					name:                             "sayHello-String-method-route",
+					matchMethodNameExact:             "sayHello",
+					RouterDestHost:                   "demo",
+					RouterDestSubset:                 "v1",
+					RouterFallBackDestHost:           "demo",
+					RouterFallBackDestSubset:         "v2",
+					RouterFallBackFallBackDestHost:   "demo",
+					RouterFallBackFallBackDestSubset: "v3",
+					RouterSize:                       1,
+					fallbackLevel:                    3,
+				},
+				{
+					name:                     "sayHello-method-route",
+					matchMethodNameExact:     "s-method",
+					RouterDestHost:           "demo",
+					RouterDestSubset:         "v2",
+					RouterFallBackDestHost:   "demo",
+					RouterFallBackDestSubset: "v3",
+					RouterSize:               1,
+					fallbackLevel:            2,
+				},
+				{
+					name:                 "some-method-route",
+					matchMethodNameExact: "some-method",
+					RouterDestHost:       "demo",
+					RouterDestSubset:     "v4",
+					RouterSize:           1,
+					fallbackLevel:        1,
+				},
+				{
+					name:                             "final",
+					matchMethodNameExact:             "GetUser",
+					RouterDestHost:                   "demo",
+					RouterDestSubset:                 "v1",
+					RouterFallBackDestHost:           "demo",
+					RouterFallBackDestSubset:         "v2",
+					RouterFallBackFallBackDestHost:   "demo",
+					RouterFallBackFallBackDestSubset: "v3",
+					RouterSize:                       2,
+					fallbackLevel:                    3,
+				},
+			}
+			for i, vsRule := range v.virtualServiceRules {
+				assert.NotNil(t, v.virtualServiceRules[i].routerItem)
+				assert.Equal(t, ruleTestItemStructList[i].name, vsRule.routerItem.Name)
+				assert.Equal(t, 1, len(vsRule.routerItem.Match))
+				assert.NotNil(t, vsRule.routerItem.Match[0].Method)
+				assert.Equal(t, ruleTestItemStructList[i].matchMethodNameExact, vsRule.routerItem.Match[0].Method.NameMatch.Exact)
+				assert.Equal(t, ruleTestItemStructList[i].RouterSize, len(vsRule.routerItem.Router))
+				assert.NotNil(t, vsRule.routerItem.Router[0].Destination)
+				assert.Equal(t, ruleTestItemStructList[i].RouterDestHost, vsRule.routerItem.Router[0].Destination.Host)
+				assert.Equal(t, ruleTestItemStructList[i].RouterDestSubset, vsRule.routerItem.Router[0].Destination.Subset)
+				if vsRule.routerItem.Router[0].Fallback == nil {
+					assert.Equal(t, 1, ruleTestItemStructList[i].fallbackLevel)
+					continue
+				}
+				newRule := vsRule.routerItem.Router[0].Fallback
+				assert.NotNil(t, newRule.Destination)
+				assert.Equal(t, ruleTestItemStructList[i].RouterFallBackDestHost, newRule.Destination.Host)
+				assert.Equal(t, ruleTestItemStructList[i].RouterFallBackDestSubset, newRule.Destination.Subset)
+				if newRule.Fallback == nil {
+					assert.Equal(t, 2, ruleTestItemStructList[i].fallbackLevel)
+					continue
+				}
+
+				newRule = newRule.Fallback
+				assert.NotNil(t, newRule.Destination)
+				assert.Equal(t, ruleTestItemStructList[i].RouterFallBackFallBackDestHost, newRule.Destination.Host)
+				assert.Equal(t, ruleTestItemStructList[i].RouterFallBackFallBackDestSubset, newRule.Destination.Subset)
+				if newRule.Fallback == nil {
+					assert.Equal(t, 3, ruleTestItemStructList[i].fallbackLevel)
+				}
+			}
+
+			destMap := v.DestinationLabelListMap
+			v1Val, ok := destMap["v1"]
+			assert.True(t, ok)
+			v1SigmaVal, ok := v1Val["sigma.ali/mg"]
+			assert.True(t, ok)
+			assert.Equal(t, "v1-host", v1SigmaVal)
+			v1Generic, ok := v1Val["generic"]
+			assert.True(t, ok)
+			assert.Equal(t, "false", v1Generic)
+
+			v2Val, ok := destMap["v2"]
+			assert.True(t, ok)
+			v2Generic, ok := v2Val["generic"]
+			assert.True(t, ok)
+			assert.Equal(t, "false", v2Generic)
+
+			v3Val, ok := destMap["v3"]
+			assert.True(t, ok)
+			v3SigmaVal, ok := v3Val["sigma.ali/mg"]
+			assert.True(t, ok)
+			assert.Equal(t, "v3-host", v3SigmaVal)
+
+		}
+	}
+}
+
+func TestRouterChain_Route(t *testing.T) {
+	vsBytes, _ := yaml.LoadYMLConfig(mockVSConfigPath)
+	drBytes, _ := yaml.LoadYMLConfig(mockDRConfigPath)
+	rc, err := NewUniformRouterChain(vsBytes, drBytes, make(chan struct{}))
+	assert.Nil(t, err)
+	assert.NotNil(t, rc)
+	newGoodURL, _ := common.NewURL("dubbo://127.0.0.1:20000/com.ikurento.user.UserProvider?interface=com.ikurento.user.UserProvider&group=&version=2.6.0")
+	newBadURL1, _ := common.NewURL("dubbo://127.0.0.1:20000/com.ikurento.user.UserProvider?interface=com.ikurento.user.UserProvider&group=&version=2.6.0")
+	newBadURL2, _ := common.NewURL("dubbo://127.0.0.1:20000/com.ikurento.user.UserProvider?interface=com.ikurento.user.UserProvider&group=&version=2.6.0")
+	goodIvk := protocol.NewBaseInvoker(newGoodURL)
+	b1 := protocol.NewBaseInvoker(newBadURL1)
+	b2 := protocol.NewBaseInvoker(newBadURL2)
+	invokerList := make([]protocol.Invoker, 3)
+	invokerList = append(invokerList, goodIvk)
+	invokerList = append(invokerList, b1)
+	invokerList = append(invokerList, b2)
+	result := rc.Route(invokerList, newGoodURL, invocation.NewRPCInvocation("GetUser", nil, nil))
+	assert.Equal(t, 0, len(result))
+	//todo test find target invoker
+}
diff --git a/cluster/router/uniform/uniform_route_test.go b/cluster/router/uniform/uniform_route_test.go
deleted file mode 100644
index 5d3bf6110..000000000
--- a/cluster/router/uniform/uniform_route_test.go
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package uniform
-
-//
-//const (
-//	connCheckRoute1010IP         = "192.168.10.10"
-//	connCheckRoute1011IP         = "192.168.10.11"
-//	connCheckRoute1012IP         = "192.168.10.12"
-//	connCheckRouteMethodNameTest = "test"
-//	connCheck1001URL             = "dubbo://192.168.10.1/com.ikurento.user.UserProvider"
-//	connCheckRouteUrlFormat      = "dubbo://%s:20000/com.ikurento.user.UserProvider"
-//)
-//
-//func TestConnCheckRouterRoute(t *testing.T) {
-//	defer protocol.CleanAllStatus()
-//	notify := make(chan struct{})
-//	go func() {
-//		for range notify {
-//		}
-//	}()
-//	consumerURL, _ := common.NewURL(connCheck1001URL)
-//	url1, _ := common.NewURL(fmt.Sprintf(connCheckRouteUrlFormat, connCheckRoute1010IP))
-//	url2, _ := common.NewURL(fmt.Sprintf(connCheckRouteUrlFormat, connCheckRoute1011IP))
-//	url3, _ := common.NewURL(fmt.Sprintf(connCheckRouteUrlFormat, connCheckRoute1012IP))
-//	hcr, _ := NewConnCheckRouter(consumerURL, notify)
-//
-//	var invokers []protocol.Invoker
-//	invoker1 := NewMockInvoker(url1)
-//	invoker2 := NewMockInvoker(url2)
-//	invoker3 := NewMockInvoker(url3)
-//	protocol.SetInvokerUnhealthyStatus(invoker1)
-//	protocol.SetInvokerUnhealthyStatus(invoker2)
-//
-//	invokers = append(invokers, invoker1, invoker2, invoker3)
-//	inv := invocation.NewRPCInvocation(connCheckRouteMethodNameTest, nil, nil)
-//	res := hcr.Route(utils.ToBitmap(invokers), setUpAddrCache(hcr.(*ConnCheckRouter), invokers), consumerURL, inv)
-//
-//	// now  invoker3 is healthy
-//	assert.True(t, len(res.ToArray()) == 1)
-//
-//	// check blacklist remove
-//	protocol.RemoveInvokerUnhealthyStatus(invoker1)
-//	res = hcr.Route(utils.ToBitmap(invokers), setUpAddrCache(hcr.(*ConnCheckRouter), invokers), consumerURL, inv)
-//	// now  invoker3 invoker1 is healthy
-//	assert.True(t, len(res.ToArray()) == 2)
-//
-//}
-//
-//func TestRecovery(t *testing.T) {
-//	// check recover
-//
-//	ctrl := gomock.NewController(t)
-//	defer ctrl.Finish()
-//
-//	invoker1 := mock.NewMockInvoker(ctrl)
-//	invoker2 := mock.NewMockInvoker(ctrl)
-//
-//	invoker1.EXPECT().GetUrl().Return(&common.URL{Path: "path1"}).AnyTimes()
-//	invoker2.EXPECT().GetUrl().Return(&common.URL{Path: "path2"}).AnyTimes()
-//	invoker1.EXPECT().IsAvailable().Return(true).AnyTimes()
-//	invoker2.EXPECT().IsAvailable().Return(true).AnyTimes()
-//
-//	protocol.SetInvokerUnhealthyStatus(invoker1)
-//	protocol.SetInvokerUnhealthyStatus(invoker2)
-//	assert.Equal(t, len(protocol.GetBlackListInvokers(16)), 2)
-//	protocol.TryRefreshBlackList()
-//	assert.Equal(t, len(protocol.GetBlackListInvokers(16)), 0)
-//}
-//
-//func setUpAddrCache(r router.Poolable, addrs []protocol.Invoker) router.Cache {
-//	pool, info := r.Pool(addrs)
-//	cache := chain.BuildCache(addrs)
-//	cache.SetAddrMeta(r.Name(), info)
-//	cache.SetAddrPool(r.Name(), pool)
-//	return cache
-//}
diff --git a/cluster/router/uniform/uniform_rule_test.go b/cluster/router/uniform/uniform_rule_test.go
deleted file mode 100644
index 9e6bb7da1..000000000
--- a/cluster/router/uniform/uniform_rule_test.go
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package uniform
-
-//
-//import (
-//	"fmt"
-//	"testing"
-//)
-//
-//import (
-//	"github.com/stretchr/testify/assert"
-//)
-//
-//import (
-//	"github.com/apache/dubbo-go/common"
-//	"github.com/apache/dubbo-go/protocol"
-//)
-//
-//const (
-//	connCheckDubbo1010IP    = "192.168.10.10"
-//	connCheckDubboUrlFormat = "dubbo://%s:20000/com.ikurento.user.UserProvider"
-//)
-//
-//func TestDefaultConnCheckerIsHealthy(t *testing.T) {
-//	defer protocol.CleanAllStatus()
-//	url, _ := common.NewURL(fmt.Sprintf(connCheckDubboUrlFormat, connCheckDubbo1010IP))
-//	cc := NewDefaultConnChecker(url).(*DefaultConnChecker)
-//	invoker := NewMockInvoker(url)
-//	healthy := cc.IsConnHealthy(invoker)
-//	assert.True(t, healthy)
-//
-//	invoker = NewMockInvoker(url)
-//	cc = NewDefaultConnChecker(url).(*DefaultConnChecker)
-//	// add to black list
-//	protocol.SetInvokerUnhealthyStatus(invoker)
-//	assert.False(t, cc.IsConnHealthy(invoker))
-//}
-- 
GitLab