mirror of
https://gitee.com/milvus-io/milvus.git
synced 2025-12-06 17:18:35 +08:00
Cherry-pick from master pr: #45018 #45030 Related to #44761 Refactor proxy shard client management by creating a new internal/proxy/shardclient package. This improves code organization and modularity by: - Moving load balancing logic (LookAsideBalancer, RoundRobinBalancer) to shardclient package - Extracting shard client manager and related interfaces into separate package - Relocating shard leader management and client lifecycle code - Adding package documentation (README.md, OWNERS) - Updating proxy code to use the new shardclient package interfaces This change makes the shard client functionality more maintainable and better encapsulated, reducing coupling in the proxy layer. Also consolidates the proxy package's mockery generation to use a centralized `.mockery.yaml` configuration file, aligning with the pattern used by other packages like querycoordv2. Changes - **Makefile**: Replace multiple individual mockery commands with a single config-based invocation for `generate-mockery-proxy` target - **internal/proxy/.mockery.yaml**: Add mockery configuration defining all mock interfaces for proxy and proxy/shardclient packages - **Mock files**: Regenerate mocks using the new configuration: - `mock_cache.go`: Clean up by removing unused interface methods (credential, shard cache, policy methods) - `shardclient/mock_lb_balancer.go`: Update type comments (nodeInfo → NodeInfo) - `shardclient/mock_lb_policy.go`: Update formatting - `shardclient/mock_shardclient_manager.go`: Fix parameter naming consistency (nodeInfo1 → nodeInfo) - **task_search_test.go**: Remove obsolete mock expectations for deprecated cache methods Benefits - Centralized mockery configuration for easier maintenance - Consistent with other packages (querycoordv2, etc.) - Cleaner mock interfaces by removing unused methods - Better type consistency in generated mocks --------- Signed-off-by: Congqi Xia <congqi.xia@zilliz.com>
142 lines
4.2 KiB
Go
142 lines
4.2 KiB
Go
package proxy
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/cockroachdb/errors"
|
|
"github.com/stretchr/testify/assert"
|
|
"google.golang.org/grpc/metadata"
|
|
|
|
"github.com/milvus-io/milvus/internal/proxy/privilege"
|
|
"github.com/milvus-io/milvus/internal/util/hookutil"
|
|
"github.com/milvus-io/milvus/pkg/v2/util"
|
|
"github.com/milvus-io/milvus/pkg/v2/util/crypto"
|
|
"github.com/milvus-io/milvus/pkg/v2/util/paramtable"
|
|
)
|
|
|
|
// validAuth validates the authentication
|
|
func TestValidAuth(t *testing.T) {
|
|
validAuth := func(ctx context.Context, authorization []string) bool {
|
|
if len(authorization) < 1 {
|
|
return false
|
|
}
|
|
token := authorization[0]
|
|
rawToken, _ := crypto.Base64Decode(token)
|
|
username, password := parseMD(rawToken)
|
|
if username == "" || password == "" {
|
|
return false
|
|
}
|
|
return passwordVerify(ctx, username, password, privilege.GetPrivilegeCache())
|
|
}
|
|
|
|
ctx := context.Background()
|
|
// no metadata
|
|
res := validAuth(ctx, nil)
|
|
assert.False(t, res)
|
|
// illegal metadata
|
|
res = validAuth(ctx, []string{"xxx"})
|
|
assert.False(t, res)
|
|
// normal metadata
|
|
mix := &MockMixCoordClientInterface{}
|
|
err := InitMetaCache(ctx, mix)
|
|
assert.NoError(t, err)
|
|
res = validAuth(ctx, []string{crypto.Base64Encode("mockUser:mockPass")})
|
|
assert.True(t, res)
|
|
|
|
res = validAuth(ctx, []string{crypto.Base64Encode("mock")})
|
|
assert.False(t, res)
|
|
}
|
|
|
|
func TestValidSourceID(t *testing.T) {
|
|
ctx := context.Background()
|
|
// no metadata
|
|
res := validSourceID(ctx, nil)
|
|
assert.False(t, res)
|
|
// illegal metadata
|
|
res = validSourceID(ctx, []string{"invalid_sourceid"})
|
|
assert.False(t, res)
|
|
// normal sourceId
|
|
res = validSourceID(ctx, []string{crypto.Base64Encode(util.MemberCredID)})
|
|
assert.True(t, res)
|
|
}
|
|
|
|
func TestAuthenticationInterceptor(t *testing.T) {
|
|
ctx := context.Background()
|
|
paramtable.Get().Save(Params.CommonCfg.AuthorizationEnabled.Key, "true") // mock authorization is turned on
|
|
defer paramtable.Get().Reset(Params.CommonCfg.AuthorizationEnabled.Key) // mock authorization is turned on
|
|
// no metadata
|
|
_, err := AuthenticationInterceptor(ctx)
|
|
assert.Error(t, err)
|
|
// mock metacache
|
|
queryCoord := &MockMixCoordClientInterface{}
|
|
err = InitMetaCache(ctx, queryCoord)
|
|
assert.NoError(t, err)
|
|
// with invalid metadata
|
|
md := metadata.Pairs("xxx", "yyy")
|
|
ctx = metadata.NewIncomingContext(ctx, md)
|
|
_, err = AuthenticationInterceptor(ctx)
|
|
assert.Error(t, err)
|
|
// with valid username/password
|
|
md = metadata.Pairs(util.HeaderAuthorize, crypto.Base64Encode("mockUser:mockPass"))
|
|
ctx = metadata.NewIncomingContext(ctx, md)
|
|
_, err = AuthenticationInterceptor(ctx)
|
|
assert.NoError(t, err)
|
|
// with valid sourceId
|
|
md = metadata.Pairs("sourceid", crypto.Base64Encode(util.MemberCredID))
|
|
ctx = metadata.NewIncomingContext(ctx, md)
|
|
_, err = AuthenticationInterceptor(ctx)
|
|
assert.NoError(t, err)
|
|
|
|
{
|
|
// wrong authorization style
|
|
md = metadata.Pairs(util.HeaderAuthorize, "123456")
|
|
ctx = metadata.NewIncomingContext(ctx, md)
|
|
_, err = AuthenticationInterceptor(ctx)
|
|
assert.Error(t, err)
|
|
}
|
|
|
|
{
|
|
// invalid user
|
|
md = metadata.Pairs(util.HeaderAuthorize, crypto.Base64Encode("mockUser2:mockPass"))
|
|
ctx = metadata.NewIncomingContext(ctx, md)
|
|
_, err = AuthenticationInterceptor(ctx)
|
|
assert.Error(t, err)
|
|
}
|
|
|
|
{
|
|
// default hook
|
|
md = metadata.Pairs(util.HeaderAuthorize, crypto.Base64Encode("mockapikey"))
|
|
ctx = metadata.NewIncomingContext(ctx, md)
|
|
_, err = AuthenticationInterceptor(ctx)
|
|
assert.Error(t, err)
|
|
}
|
|
|
|
{
|
|
// verify apikey error
|
|
hookutil.SetMockAPIHook("", errors.New("err"))
|
|
md = metadata.Pairs(util.HeaderAuthorize, crypto.Base64Encode("mockapikey"))
|
|
ctx = metadata.NewIncomingContext(ctx, md)
|
|
_, err = AuthenticationInterceptor(ctx)
|
|
assert.Error(t, err)
|
|
}
|
|
|
|
{
|
|
hookutil.SetMockAPIHook("mockUser", nil)
|
|
md = metadata.Pairs(util.HeaderAuthorize, crypto.Base64Encode("mockapikey"))
|
|
ctx = metadata.NewIncomingContext(ctx, md)
|
|
authCtx, err := AuthenticationInterceptor(ctx)
|
|
assert.NoError(t, err)
|
|
md, ok := metadata.FromIncomingContext(authCtx)
|
|
assert.True(t, ok)
|
|
authStrArr := md[strings.ToLower(util.HeaderAuthorize)]
|
|
token := authStrArr[0]
|
|
rawToken, err := crypto.Base64Decode(token)
|
|
assert.NoError(t, err)
|
|
user, _ := parseMD(rawToken)
|
|
assert.Equal(t, "mockUser", user)
|
|
}
|
|
hookutil.SetTestHook(hookutil.DefaultHook{})
|
|
}
|