blob: a864d27c58bc86db3fe4bf80381cf02c4ccd1789 [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 active
import (
"context"
"errors"
"fmt"
"strconv"
"testing"
)
import (
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/assert"
)
import (
"dubbo.apache.org/dubbo-go/v3/common"
"dubbo.apache.org/dubbo-go/v3/common/constant"
"dubbo.apache.org/dubbo-go/v3/protocol/base"
"dubbo.apache.org/dubbo-go/v3/protocol/invocation"
"dubbo.apache.org/dubbo-go/v3/protocol/mock"
"dubbo.apache.org/dubbo-go/v3/protocol/result"
)
func TestFilterInvoke(t *testing.T) {
invoc := invocation.NewRPCInvocation("test", []any{"OK"}, make(map[string]any))
url, _ := common.NewURL(fmt.Sprintf("dubbo://%s:%d/com.ikurento.user.UserProvider", constant.LocalHostValue, constant.DefaultPort))
filter := activeFilter{}
ctrl := gomock.NewController(t)
defer ctrl.Finish()
invoker := mock.NewMockInvoker(ctrl)
invoker.EXPECT().Invoke(gomock.Any(), gomock.Any()).Return(nil)
invoker.EXPECT().GetURL().Return(url).Times(1)
filter.Invoke(context.Background(), invoker, invoc)
assert.True(t, invoc.GetAttachmentWithDefaultValue(dubboInvokeStartTime, "") != "")
}
func TestFilterOnResponse(t *testing.T) {
c := base.CurrentTimeMillis()
elapsed := 100
invoc := invocation.NewRPCInvocation("test", []any{"OK"}, map[string]any{
dubboInvokeStartTime: strconv.FormatInt(c-int64(elapsed), 10),
})
url, _ := common.NewURL(fmt.Sprintf("dubbo://%s:%d/com.ikurento.user.UserProvider", constant.LocalHostValue, constant.DefaultPort))
filter := activeFilter{}
ctrl := gomock.NewController(t)
defer ctrl.Finish()
invoker := mock.NewMockInvoker(ctrl)
invoker.EXPECT().GetURL().Return(url).Times(1)
rpcResult := &result.RPCResult{
Err: errors.New("test"),
}
filter.OnResponse(context.TODO(), rpcResult, invoker, invoc)
methodStatus := base.GetMethodStatus(url, "test")
urlStatus := base.GetURLStatus(url)
assert.Equal(t, int32(1), methodStatus.GetTotal())
assert.Equal(t, int32(1), urlStatus.GetTotal())
assert.Equal(t, int32(1), methodStatus.GetFailed())
assert.Equal(t, int32(1), urlStatus.GetFailed())
assert.Equal(t, int32(1), methodStatus.GetSuccessiveRequestFailureCount())
assert.Equal(t, int32(1), urlStatus.GetSuccessiveRequestFailureCount())
assert.True(t, methodStatus.GetFailedElapsed() >= int64(elapsed))
assert.True(t, urlStatus.GetFailedElapsed() >= int64(elapsed))
assert.True(t, urlStatus.GetLastRequestFailedTimestamp() != int64(0))
assert.True(t, methodStatus.GetLastRequestFailedTimestamp() != int64(0))
}
func TestFilterOnResponseWithDefer(t *testing.T) {
base.CleanAllStatus()
// Test scenario 1: dubboInvokeStartTime is parsed successfully and the result is correct.
t.Run("ParseSuccessAndResultSuccess", func(t *testing.T) {
defer base.CleanAllStatus()
c := base.CurrentTimeMillis()
invoc := invocation.NewRPCInvocation("test1", []any{"OK"}, map[string]any{
dubboInvokeStartTime: strconv.FormatInt(c, 10),
})
url, _ := common.NewURL(fmt.Sprintf("dubbo://%s:%d/com.ikurento.user.UserProvider", constant.LocalHostValue, constant.DefaultPort))
filter := activeFilter{}
ctrl := gomock.NewController(t)
defer ctrl.Finish()
invoker := mock.NewMockInvoker(ctrl)
invoker.EXPECT().GetURL().Return(url).Times(1)
rpcResult := &result.RPCResult{}
filter.OnResponse(context.TODO(), rpcResult, invoker, invoc)
methodStatus := base.GetMethodStatus(url, "test1")
urlStatus := base.GetURLStatus(url)
assert.Equal(t, int32(1), methodStatus.GetTotal())
assert.Equal(t, int32(1), urlStatus.GetTotal())
assert.Equal(t, int32(0), methodStatus.GetFailed())
assert.Equal(t, int32(0), urlStatus.GetFailed())
assert.Equal(t, int32(0), methodStatus.GetSuccessiveRequestFailureCount())
assert.Equal(t, int32(0), urlStatus.GetSuccessiveRequestFailureCount())
assert.True(t, methodStatus.GetTotalElapsed() >= int64(0))
assert.True(t, urlStatus.GetTotalElapsed() >= int64(0))
})
// Test scenario 2: dubboInvokeStartTime is parsed successfully, but the result is incorrect
t.Run("ParseSuccessAndResultFailed", func(t *testing.T) {
defer base.CleanAllStatus()
c := base.CurrentTimeMillis()
invoc := invocation.NewRPCInvocation("test2", []any{"OK"}, map[string]any{
dubboInvokeStartTime: strconv.FormatInt(c, 10),
})
url, _ := common.NewURL(fmt.Sprintf("dubbo://%s:%d/com.ikurento.user.UserProvider", constant.LocalHostValue, constant.DefaultPort))
filter := activeFilter{}
ctrl := gomock.NewController(t)
defer ctrl.Finish()
invoker := mock.NewMockInvoker(ctrl)
invoker.EXPECT().GetURL().Return(url).Times(1)
rpcResult := &result.RPCResult{
Err: errors.New("test error"),
}
filter.OnResponse(context.TODO(), rpcResult, invoker, invoc)
methodStatus := base.GetMethodStatus(url, "test2")
urlStatus := base.GetURLStatus(url)
assert.Equal(t, int32(1), methodStatus.GetTotal())
assert.Equal(t, int32(1), urlStatus.GetTotal())
assert.Equal(t, int32(1), methodStatus.GetFailed())
assert.Equal(t, int32(1), urlStatus.GetFailed())
assert.Equal(t, int32(1), methodStatus.GetSuccessiveRequestFailureCount())
assert.Equal(t, int32(1), urlStatus.GetSuccessiveRequestFailureCount())
assert.True(t, methodStatus.GetFailedElapsed() >= int64(0))
assert.True(t, urlStatus.GetFailedElapsed() >= int64(0))
assert.True(t, urlStatus.GetLastRequestFailedTimestamp() != int64(0))
assert.True(t, methodStatus.GetLastRequestFailedTimestamp() != int64(0))
})
// Test Scenario 3: dubboInvokeStartTime parsing failed (non-numeric string)
t.Run("ParseFailedWithInvalidString", func(t *testing.T) {
defer base.CleanAllStatus()
invoc := invocation.NewRPCInvocation("test3", []any{"OK"}, map[string]any{
dubboInvokeStartTime: "invalid-time",
})
url, _ := common.NewURL(fmt.Sprintf("dubbo://%s:%d/com.ikurento.user.UserProvider", constant.LocalHostValue, constant.DefaultPort))
filter := activeFilter{}
ctrl := gomock.NewController(t)
defer ctrl.Finish()
invoker := mock.NewMockInvoker(ctrl)
invoker.EXPECT().GetURL().Return(url).Times(1)
rpcResult := &result.RPCResult{}
result := filter.OnResponse(context.TODO(), rpcResult, invoker, invoc)
assert.NotNil(t, result.Error())
methodStatus := base.GetMethodStatus(url, "test3")
urlStatus := base.GetURLStatus(url)
// Verification count and status - should use the default duration of 1 and be marked as failed
assert.Equal(t, int32(1), methodStatus.GetTotal())
assert.Equal(t, int32(1), urlStatus.GetTotal())
assert.Equal(t, int32(1), methodStatus.GetFailed())
assert.Equal(t, int32(1), urlStatus.GetFailed())
assert.Equal(t, int32(1), methodStatus.GetSuccessiveRequestFailureCount())
assert.Equal(t, int32(1), urlStatus.GetSuccessiveRequestFailureCount())
assert.True(t, methodStatus.GetFailedElapsed() >= int64(1))
assert.True(t, urlStatus.GetFailedElapsed() >= int64(1))
})
// Test scenario 4: dubboInvokeStartTime does not exist (use the default value 0)
t.Run("ParseFailedWithDefaultValue", func(t *testing.T) {
defer base.CleanAllStatus()
invoc := invocation.NewRPCInvocation("test4", []any{"OK"}, make(map[string]any))
url, _ := common.NewURL(fmt.Sprintf("dubbo://%s:%d/com.ikurento.user.UserProvider", constant.LocalHostValue, constant.DefaultPort))
filter := activeFilter{}
ctrl := gomock.NewController(t)
defer ctrl.Finish()
invoker := mock.NewMockInvoker(ctrl)
invoker.EXPECT().GetURL().Return(url).Times(1)
rpcResult := &result.RPCResult{}
filter.OnResponse(context.TODO(), rpcResult, invoker, invoc)
methodStatus := base.GetMethodStatus(url, "test4")
urlStatus := base.GetURLStatus(url)
assert.Equal(t, int32(1), methodStatus.GetTotal())
assert.Equal(t, int32(1), urlStatus.GetTotal())
assert.Equal(t, int32(0), methodStatus.GetFailed())
assert.Equal(t, int32(0), urlStatus.GetFailed())
assert.Equal(t, int32(0), methodStatus.GetSuccessiveRequestFailureCount())
assert.Equal(t, int32(0), urlStatus.GetSuccessiveRequestFailureCount())
assert.True(t, methodStatus.GetTotalElapsed() > int64(0))
assert.True(t, urlStatus.GetTotalElapsed() > int64(0))
})
}