blob: 8d6bf453f72b3c56d0c4e7ef57a33d4fab7d9cff [file] [log] [blame]
/*
* 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 script
import (
"context"
"testing"
)
import (
"github.com/stretchr/testify/assert"
)
import (
"dubbo.apache.org/dubbo-go/v3/common"
"dubbo.apache.org/dubbo-go/v3/config_center"
"dubbo.apache.org/dubbo-go/v3/protocol/base"
"dubbo.apache.org/dubbo-go/v3/protocol/invocation"
"dubbo.apache.org/dubbo-go/v3/remoting"
)
var url1 = func() *common.URL {
i, _ := common.NewURL("dubbo://127.0.0.1:20000/com.ikurento.user.UserProvider?anyhost=true&" +
"application=BDTService&category=providers&default.timeout=10000&dubbo=dubbo-provider-golang-1.0.0&" +
"environment=dev&interface=com.ikurento.user.UserProvider&ip=192.168.56.1&methods=GetUser%2C&" +
"module=dubbogo+user-info+server&org=ikurento.com&owner=ZX&pid=1447&revision=0.0.1&" +
"side=provider&timeout=3000&timestamp=1556509797245")
return i
}
var url2 = func() *common.URL {
u, _ := common.NewURL("dubbo://127.0.0.1:20001/com.ikurento.user.UserProvider?anyhost=true&" +
"application=BDTService&category=providers&default.timeout=10000&dubbo=dubbo-provider-golang-1.0.0&" +
"environment=dev&interface=com.ikurento.user.UserProvider&ip=192.168.56.1&methods=GetUser%2C&" +
"module=dubbogo+user-info+server&org=ikurento.com&owner=ZX&pid=1448&revision=0.0.1&" +
"side=provider&timeout=3000&timestamp=1556509797246")
return u
}
var url3 = func() *common.URL {
i, _ := common.NewURL("dubbo://127.0.0.1:20002/com.ikurento.user.UserProvider?anyhost=true&" +
"application=BDTService&category=providers&default.timeout=10000&dubbo=dubbo-provider-golang-1.0.0&" +
"environment=dev&interface=com.ikurento.user.UserProvider&ip=192.168.56.1&methods=GetUser%2C&" +
"module=dubbogo+user-info+server&org=ikurento.com&owner=ZX&pid=1449&revision=0.0.1&" +
"side=provider&timeout=3000&timestamp=1556509797247")
return i
}
func getRouteCheckArgs() ([]base.Invoker, base.Invocation, context.Context) {
return []base.Invoker{
base.NewBaseInvoker(url1()), base.NewBaseInvoker(url2()), base.NewBaseInvoker(url3()),
}, invocation.NewRPCInvocation("GetUser", nil, map[string]any{
"attachmentKey": []string{"attachmentValue"},
}),
context.TODO()
}
func TestScriptRouter_Route(t *testing.T) {
type fields struct {
cfgContent string
}
type args struct {
invokers []base.Invoker
invocation base.Invocation
}
tests := []struct {
name string
fields fields
args args
want func([]base.Invoker) bool
}{
{
name: "base test",
fields: fields{cfgContent: `configVersion: v3.0
key: dubbo.io
type: javascript
enabled: true
script: |
(function route(invokers,invocation,context) {
var result = [];
for (var i = 0; i < invokers.length; i++) {
invokers[i].GetURL().Port = "20001"
result.push(invokers[i]);
}
return result;
}(invokers,invocation,context));
`},
args: func() args {
res := args{}
res.invokers, res.invocation, _ = getRouteCheckArgs()
return res
}(),
want: func(invokers []base.Invoker) bool {
for _, invoker := range invokers {
if invoker.GetURL().Port != "20001" {
return false
}
}
return true
},
}, {
name: "disable test",
fields: fields{cfgContent: `configVersion: v3.0
key: dubbo.io
type: javascript
enabled: false
script: |
(function route(invokers,invocation,context) {
var result = [];
for (var i = 0; i < invokers.length; i++) {
invokers[i].GetURL().Port = "20001"
result.push(invokers[i]);
}
return result;
}(invokers,invocation,context));
`},
args: func() args {
res := args{}
res.invokers, res.invocation, _ = getRouteCheckArgs()
return res
}(),
want: func(invokers []base.Invoker) bool {
expect_invokers, _, _ := getRouteCheckArgs()
return checkInvokersSame(invokers, expect_invokers)
},
}, {
name: "bad input",
fields: fields{cfgContent: `configVersion: v3.0
key: dubbo.io
type: javascript
enabled: true
script: |
badInPut
(().Port = "20001"
result.push(invokers[i]);
}
}
}
return result;
}(invokers,invocation,context));
`},
args: func() args {
res := args{}
res.invokers, res.invocation, _ = getRouteCheckArgs()
return res
}(),
want: func(invokers []base.Invoker) bool {
expect_invokers, _, _ := getRouteCheckArgs()
return checkInvokersSame(invokers, expect_invokers)
},
}, {
name: "bad call and recover",
fields: fields{cfgContent: `configVersion: v3.0
key: dubbo.io
type: javascript
enabled: true
script: |
(function route(invokers, invocation, context) {
var result = [];
for (var i = 0; i < invokers.length; i++) {
if ("127.0.0.1" === invokers[i].GetURL().Ip) {
if (invokers[i].GetURLS(" Err Here ").Port !== "20000") {
invokers[i].GetURLS().Ip = "anotherIP"
result.push(invokers[i]);
}
}
}
return result;
}(invokers, invocation, context));
`},
args: func() args {
res := args{}
res.invokers, res.invocation, _ = getRouteCheckArgs()
return res
}(),
want: func(invokers []base.Invoker) bool {
expect_invokers, _, _ := getRouteCheckArgs()
return checkInvokersSame(invokers, expect_invokers)
},
}, {
name: "bad type",
fields: fields{cfgContent: `configVersion: v3.0
key: dubbo.io
type: errorType # <---
enabled: true
script: |
(function route(invokers,invocation,context) {
var result = [];
for (var i = 0; i < invokers.length; i++) {
invokers[i].GetURL().Port = "20001"
result.push(invokers[i]);
}
return result;
}(invokers,invocation,context));
`},
args: func() args {
res := args{}
res.invokers, res.invocation, _ = getRouteCheckArgs()
return res
}(),
want: func(invokers []base.Invoker) bool {
expect_invokers, _, _ := getRouteCheckArgs()
return checkInvokersSame(invokers, expect_invokers)
},
},
}
for _, tt := range tests {
s := &ScriptRouter{}
t.Run(tt.name, func(t *testing.T) {
s.Process(&config_center.ConfigChangeEvent{Key: "", Value: tt.fields.cfgContent, ConfigType: remoting.EventTypeUpdate})
got := s.Route(tt.args.invokers, nil, tt.args.invocation)
assert.True(t, tt.want(got))
})
}
}
func checkInvokersSame(invokers []base.Invoker, otherInvokers []base.Invoker) bool {
k := map[string]struct{}{}
for _, invoker := range otherInvokers {
k[invoker.GetURL().String()] = struct{}{}
}
for _, invoker := range invokers {
_, ok := k[invoker.GetURL().String()]
if !ok {
return false
}
delete(k, invoker.GetURL().String())
}
return len(k) == 0
}