Skip to content
Snippets Groups Projects
chain_test.go 8.51 KiB
Newer Older
AlexStocks's avatar
AlexStocks committed
/*
 * 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.
 */
fangyincheng's avatar
fangyincheng committed

邹毅贤's avatar
邹毅贤 committed
package chain
邹毅贤's avatar
邹毅贤 committed

import (
邹毅贤's avatar
邹毅贤 committed
	"encoding/base64"
邹毅贤's avatar
邹毅贤 committed
	"fmt"
邹毅贤's avatar
邹毅贤 committed
	"testing"
	"time"
)

import (
邹毅贤's avatar
邹毅贤 committed
	"github.com/stretchr/testify/assert"
)

import (
邹毅贤's avatar
邹毅贤 committed
	"github.com/apache/dubbo-go/cluster/router"
邹毅贤's avatar
邹毅贤 committed
	"github.com/apache/dubbo-go/cluster/router/condition"
	"github.com/apache/dubbo-go/common"
	"github.com/apache/dubbo-go/common/config"
邹毅贤's avatar
邹毅贤 committed
	"github.com/apache/dubbo-go/common/constant"
邹毅贤's avatar
邹毅贤 committed
	"github.com/apache/dubbo-go/common/extension"
	_ "github.com/apache/dubbo-go/config_center/zookeeper"
邹毅贤's avatar
邹毅贤 committed
	"github.com/apache/dubbo-go/protocol"
	"github.com/apache/dubbo-go/protocol/invocation"
邹毅贤's avatar
邹毅贤 committed
	"github.com/apache/dubbo-go/remoting/zookeeper"
邹毅贤's avatar
邹毅贤 committed
)

haohongfan's avatar
haohongfan committed
const (
	localIP    = "127.0.0.1"
	test1234IP = "1.2.3.4"
	test1111IP = "1.1.1.1"
	test0000IP = "0.0.0.0"
	port20000  = 20000

	path             = "/dubbo/config/dubbo/test-condition.condition-router"
	zkFormat         = "zookeeper://%s:%d"
	consumerFormat   = "consumer://%s/com.foo.BarService"
	dubboForamt      = "dubbo://%s:%d/com.foo.BarService"
	anyUrlFormat     = "condition://%s/com.foo.BarService"
	zk               = "zookeeper"
	applicationKey   = "test-condition"
	applicationField = "application"
	forceField       = "force"
	forceValue       = "true"
邹毅贤's avatar
邹毅贤 committed
func TestNewRouterChain(t *testing.T) {
	ts, z, _, err := zookeeper.NewMockZookeeperClient("test", 15*time.Second)
	assert.NoError(t, err)
haohongfan's avatar
haohongfan committed
	err = z.Create(path)
邹毅贤's avatar
邹毅贤 committed
	assert.NoError(t, err)
william feng's avatar
william feng committed
	testyml := `scope: application
key: mock-app
enabled: true
邹毅贤's avatar
邹毅贤 committed
force: true
runtime: false
conditions:
  - => host != 172.22.3.91
`

haohongfan's avatar
haohongfan committed
	_, err = z.Conn.Set(path, []byte(testyml), 0)
邹毅贤's avatar
邹毅贤 committed
	assert.NoError(t, err)
邹毅贤's avatar
邹毅贤 committed
	defer ts.Stop()
	defer z.Close()

	zkUrl, _ := common.NewURL(fmt.Sprintf(zkFormat, localIP, ts.Servers[0].Port))
haohongfan's avatar
haohongfan committed
	configuration, err := extension.GetConfigCenterFactory(zk).GetDynamicConfiguration(zkUrl)
邹毅贤's avatar
邹毅贤 committed
	config.GetEnvInstance().SetDynamicConfiguration(configuration)

邹毅贤's avatar
邹毅贤 committed
	assert.Nil(t, err)
	assert.NotNil(t, configuration)

	chain, err := NewRouterChain(getRouteUrl(applicationKey))
邹毅贤's avatar
邹毅贤 committed
	assert.Nil(t, err)
邹毅贤's avatar
邹毅贤 committed
	assert.Equal(t, 1, len(chain.routers))
	appRouter := chain.routers[0].(*condition.AppRouter)

	assert.NotNil(t, appRouter)
	assert.NotNil(t, appRouter.RouterRule())
	rule := appRouter.RouterRule()
william feng's avatar
william feng committed
	assert.Equal(t, "application", rule.Scope)
邹毅贤's avatar
邹毅贤 committed
	assert.True(t, rule.Force)
	assert.True(t, rule.Enabled)
	assert.True(t, rule.Valid)

	assert.Equal(t, testyml, rule.RawRule)
	assert.Equal(t, false, rule.Runtime)
	assert.Equal(t, false, rule.Dynamic)
william feng's avatar
william feng committed
	assert.Equal(t, "mock-app", rule.Key)
邹毅贤's avatar
邹毅贤 committed
}

邹毅贤's avatar
邹毅贤 committed
func TestNewRouterChainURLNil(t *testing.T) {
	chain, err := NewRouterChain(nil)
邹毅贤's avatar
邹毅贤 committed
	assert.NoError(t, err)
	assert.NotNil(t, chain)
邹毅贤's avatar
邹毅贤 committed
}

haohongfan's avatar
haohongfan committed
func TestRouterChainAddRouters(t *testing.T) {
邹毅贤's avatar
邹毅贤 committed
	ts, z, _, err := zookeeper.NewMockZookeeperClient("test", 15*time.Second)
	assert.NoError(t, err)
haohongfan's avatar
haohongfan committed
	err = z.Create(path)
邹毅贤's avatar
邹毅贤 committed
	assert.NoError(t, err)

william feng's avatar
william feng committed
	testyml := `scope: application
key: mock-app
enabled: true
邹毅贤's avatar
邹毅贤 committed
force: true
runtime: false
conditions:
  - => host != 172.22.3.91
`

haohongfan's avatar
haohongfan committed
	_, err = z.Conn.Set(path, []byte(testyml), 0)
邹毅贤's avatar
邹毅贤 committed
	assert.NoError(t, err)
	defer ts.Stop()
	defer z.Close()

	zkUrl, _ := common.NewURL(fmt.Sprintf(zkFormat, localIP, ts.Servers[0].Port))
haohongfan's avatar
haohongfan committed
	configuration, err := extension.GetConfigCenterFactory(zk).GetDynamicConfiguration(zkUrl)
邹毅贤's avatar
邹毅贤 committed
	config.GetEnvInstance().SetDynamicConfiguration(configuration)

	chain, err := NewRouterChain(getConditionRouteUrl(applicationKey))
邹毅贤's avatar
邹毅贤 committed
	assert.Nil(t, err)
邹毅贤's avatar
邹毅贤 committed
	assert.Equal(t, 2, len(chain.routers))
邹毅贤's avatar
邹毅贤 committed

	url := getConditionRouteUrl(applicationKey)
邹毅贤's avatar
邹毅贤 committed
	assert.NotNil(t, url)
	factory := extension.GetRouterFactory(url.Protocol)
邹毅贤's avatar
邹毅贤 committed
	r, err := factory.NewPriorityRouter(url)
邹毅贤's avatar
邹毅贤 committed
	assert.Nil(t, err)
	assert.NotNil(t, r)

邹毅贤's avatar
邹毅贤 committed
	routers := make([]router.PriorityRouter, 0)
邹毅贤's avatar
邹毅贤 committed
	routers = append(routers, r)
	chain.AddRouters(routers)
邹毅贤's avatar
邹毅贤 committed
	assert.Equal(t, 3, len(chain.routers))
邹毅贤's avatar
邹毅贤 committed
}

haohongfan's avatar
haohongfan committed
func TestRouterChainRoute(t *testing.T) {
邹毅贤's avatar
邹毅贤 committed
	ts, z, _, err := zookeeper.NewMockZookeeperClient("test", 15*time.Second)
	defer ts.Stop()
	defer z.Close()

	zkUrl, _ := common.NewURL(fmt.Sprintf(zkFormat, localIP, ts.Servers[0].Port))
haohongfan's avatar
haohongfan committed
	configuration, err := extension.GetConfigCenterFactory(zk).GetDynamicConfiguration(zkUrl)
邹毅贤's avatar
邹毅贤 committed
	config.GetEnvInstance().SetDynamicConfiguration(configuration)

	chain, err := NewRouterChain(getConditionRouteUrl(applicationKey))
邹毅贤's avatar
邹毅贤 committed
	assert.Nil(t, err)
	assert.Equal(t, 1, len(chain.routers))

	url := getConditionRouteUrl(applicationKey)
邹毅贤's avatar
邹毅贤 committed
	assert.NotNil(t, url)

haohongfan's avatar
haohongfan committed
	var invokers []protocol.Invoker
	dubboURL, _ := common.NewURL(fmt.Sprintf(dubboForamt, test1234IP, port20000))
邹毅贤's avatar
邹毅贤 committed
	invokers = append(invokers, protocol.NewBaseInvoker(dubboURL))
	chain.SetInvokers(invokers)
	chain.buildCache()
邹毅贤's avatar
邹毅贤 committed

	targetURL, _ := common.NewURL(fmt.Sprintf(consumerFormat, test1111IP))
邹毅贤's avatar
邹毅贤 committed
	inv := &invocation.RPCInvocation{}
haohongfan's avatar
haohongfan committed
	finalInvokers := chain.Route(targetURL, inv)
邹毅贤's avatar
邹毅贤 committed

	assert.Equal(t, 1, len(finalInvokers))
}

haohongfan's avatar
haohongfan committed
func TestRouterChainRouteAppRouter(t *testing.T) {
邹毅贤's avatar
邹毅贤 committed
	ts, z, _, err := zookeeper.NewMockZookeeperClient("test", 15*time.Second)
	assert.NoError(t, err)
haohongfan's avatar
haohongfan committed
	err = z.Create(path)
邹毅贤's avatar
邹毅贤 committed
	assert.NoError(t, err)

william feng's avatar
william feng committed
	testyml := `scope: application
key: mock-app
enabled: true
邹毅贤's avatar
邹毅贤 committed
force: true
runtime: false
conditions:
  - => host = 1.1.1.1 => host != 1.2.3.4
`

haohongfan's avatar
haohongfan committed
	_, err = z.Conn.Set(path, []byte(testyml), 0)
邹毅贤's avatar
邹毅贤 committed
	assert.NoError(t, err)
	defer ts.Stop()
	defer z.Close()

	zkUrl, _ := common.NewURL(fmt.Sprintf(zkFormat, localIP, ts.Servers[0].Port))
haohongfan's avatar
haohongfan committed
	configuration, err := extension.GetConfigCenterFactory(zk).GetDynamicConfiguration(zkUrl)
邹毅贤's avatar
邹毅贤 committed
	config.GetEnvInstance().SetDynamicConfiguration(configuration)

	chain, err := NewRouterChain(getConditionRouteUrl(applicationKey))
邹毅贤's avatar
邹毅贤 committed
	assert.Nil(t, err)
	assert.Equal(t, 2, len(chain.routers))

haohongfan's avatar
haohongfan committed
	var invokers []protocol.Invoker
	dubboURL, _ := common.NewURL(fmt.Sprintf(dubboForamt, test1234IP, port20000))
邹毅贤's avatar
邹毅贤 committed
	invokers = append(invokers, protocol.NewBaseInvoker(dubboURL))
	chain.SetInvokers(invokers)
	chain.buildCache()
邹毅贤's avatar
邹毅贤 committed

	targetURL, _ := common.NewURL(fmt.Sprintf(consumerFormat, test1111IP))
邹毅贤's avatar
邹毅贤 committed
	inv := &invocation.RPCInvocation{}
haohongfan's avatar
haohongfan committed
	finalInvokers := chain.Route(targetURL, inv)
邹毅贤's avatar
邹毅贤 committed

	assert.Equal(t, 0, len(finalInvokers))
}

func TestRouterChainRouteNoRoute(t *testing.T) {
邹毅贤's avatar
邹毅贤 committed
	ts, z, _, err := zookeeper.NewMockZookeeperClient("test", 15*time.Second)
	defer ts.Stop()
	defer z.Close()

	zkUrl, _ := common.NewURL(fmt.Sprintf(zkFormat, localIP, ts.Servers[0].Port))
haohongfan's avatar
haohongfan committed
	configuration, err := extension.GetConfigCenterFactory(zk).GetDynamicConfiguration(zkUrl)
邹毅贤's avatar
邹毅贤 committed
	config.GetEnvInstance().SetDynamicConfiguration(configuration)

	chain, err := NewRouterChain(getConditionNoRouteUrl(applicationKey))
邹毅贤's avatar
邹毅贤 committed
	assert.Nil(t, err)
	assert.Equal(t, 1, len(chain.routers))

	url := getConditionRouteUrl(applicationKey)
邹毅贤's avatar
邹毅贤 committed
	assert.NotNil(t, url)

haohongfan's avatar
haohongfan committed
	var invokers []protocol.Invoker
	dubboURL, _ := common.NewURL(fmt.Sprintf(dubboForamt, test1234IP, port20000))
邹毅贤's avatar
邹毅贤 committed
	invokers = append(invokers, protocol.NewBaseInvoker(dubboURL))
	chain.SetInvokers(invokers)
	chain.buildCache()
邹毅贤's avatar
邹毅贤 committed

	targetURL, _ := common.NewURL(fmt.Sprintf(consumerFormat, test1111IP))
邹毅贤's avatar
邹毅贤 committed
	inv := &invocation.RPCInvocation{}
haohongfan's avatar
haohongfan committed
	finalInvokers := chain.Route(targetURL, inv)
邹毅贤's avatar
邹毅贤 committed

	assert.Equal(t, 0, len(finalInvokers))
}

func getConditionNoRouteUrl(applicationKey string) *common.URL {
	url, _ := common.NewURL(fmt.Sprintf(anyUrlFormat, test0000IP))
	url.AddParam(applicationField, applicationKey)
	url.AddParam(forceField, forceValue)
邹毅贤's avatar
邹毅贤 committed
	rule := base64.URLEncoding.EncodeToString([]byte("host = 1.1.1.1 => host != 1.2.3.4"))
	url.AddParam(constant.RULE_KEY, rule)
haohongfan's avatar
haohongfan committed
	return url
邹毅贤's avatar
邹毅贤 committed
}

邹毅贤's avatar
邹毅贤 committed
func getConditionRouteUrl(applicationKey string) *common.URL {
	url, _ := common.NewURL(fmt.Sprintf(anyUrlFormat, test0000IP))
	url.AddParam(applicationField, applicationKey)
	url.AddParam(forceField, forceValue)
邹毅贤's avatar
邹毅贤 committed
	rule := base64.URLEncoding.EncodeToString([]byte("host = 1.1.1.1 => host = 1.2.3.4"))
邹毅贤's avatar
邹毅贤 committed
	url.AddParam(constant.RULE_KEY, rule)
haohongfan's avatar
haohongfan committed
	return url
邹毅贤's avatar
邹毅贤 committed
}

邹毅贤's avatar
邹毅贤 committed
func getRouteUrl(applicationKey string) *common.URL {
	url, _ := common.NewURL(fmt.Sprintf(anyUrlFormat, test0000IP))
	url.AddParam(applicationField, applicationKey)
	url.AddParam(forceField, forceValue)
haohongfan's avatar
haohongfan committed
	return url
邹毅贤's avatar
邹毅贤 committed
}