fix rg e2e (#22187)

Signed-off-by: Wei Liu <wei.liu@zilliz.com>
This commit is contained in:
wei liu 2023-02-16 10:48:34 +08:00 committed by GitHub
parent 5d83781df3
commit 87a4ddc7e2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 257 additions and 198 deletions

View File

@ -4514,7 +4514,7 @@ func getErrResponse(err error, method string) *commonpb.Status {
metrics.ProxyFunctionCall.WithLabelValues(strconv.FormatInt(paramtable.GetNodeID(), 10), method, metrics.FailLabel).Inc()
return &commonpb.Status{
ErrorCode: commonpb.ErrorCode_UnexpectedError,
ErrorCode: commonpb.ErrorCode_IllegalArgument,
Reason: err.Error(),
}
}
@ -4525,13 +4525,6 @@ func (node *Proxy) DropResourceGroup(ctx context.Context, request *milvuspb.Drop
}
method := "DropResourceGroup"
if err := ValidateResourceGroupName(request.GetResourceGroup()); err != nil {
log.Warn("DropResourceGroup failed",
zap.Error(err),
)
return getErrResponse(err, method), nil
}
ctx, sp := otel.Tracer(typeutil.ProxyRole).Start(ctx, "Proxy-DropResourceGroup")
defer sp.End()
tr := timerecord.NewTimeRecorder(method)

View File

@ -301,7 +301,7 @@ func TestProxy_InvalidResourceGroupName(t *testing.T) {
ResourceGroup: "...",
})
assert.NoError(t, err)
assert.Equal(t, resp.ErrorCode, commonpb.ErrorCode_UnexpectedError)
assert.Equal(t, resp.ErrorCode, commonpb.ErrorCode_IllegalArgument)
})
t.Run("drop resource group", func(t *testing.T) {
@ -309,7 +309,7 @@ func TestProxy_InvalidResourceGroupName(t *testing.T) {
ResourceGroup: "...",
})
assert.NoError(t, err)
assert.Equal(t, resp.ErrorCode, commonpb.ErrorCode_UnexpectedError)
assert.Equal(t, resp.ErrorCode, commonpb.ErrorCode_Success)
})
t.Run("transfer node", func(t *testing.T) {
@ -319,7 +319,7 @@ func TestProxy_InvalidResourceGroupName(t *testing.T) {
NumNode: 1,
})
assert.NoError(t, err)
assert.Equal(t, resp.ErrorCode, commonpb.ErrorCode_UnexpectedError)
assert.Equal(t, resp.ErrorCode, commonpb.ErrorCode_IllegalArgument)
})
t.Run("transfer replica", func(t *testing.T) {
@ -330,6 +330,6 @@ func TestProxy_InvalidResourceGroupName(t *testing.T) {
CollectionName: "collection1",
})
assert.NoError(t, err)
assert.Equal(t, resp.ErrorCode, commonpb.ErrorCode_UnexpectedError)
assert.Equal(t, resp.ErrorCode, commonpb.ErrorCode_IllegalArgument)
})
}

View File

@ -117,7 +117,7 @@ func validateCollectionNameOrAlias(entity, entityType string) error {
func ValidateResourceGroupName(entity string) error {
if entity == "" {
return fmt.Errorf("resource group name %s should not be empty", entity)
return errors.New("resource group name couldn't be empty")
}
invalidMsg := fmt.Sprintf("Invalid resource group name %s.", entity)

View File

@ -172,12 +172,6 @@ func (job *LoadCollectionJob) PreExecute() error {
return ErrCollectionLoaded
}
if len(job.nodeMgr.GetAll()) < int(job.req.GetReplicaNumber()) {
msg := "no enough nodes to create replicas"
log.Warn(msg)
return utils.WrapError(msg, ErrNoEnoughNode)
}
return nil
}
@ -387,12 +381,6 @@ func (job *LoadPartitionJob) PreExecute() error {
return ErrCollectionLoaded
}
if len(job.nodeMgr.GetAll()) < int(job.req.GetReplicaNumber()) {
msg := "no enough nodes to create replicas"
log.Warn(msg)
return utils.WrapError(msg, ErrNoEnoughNode)
}
return nil
}

View File

@ -343,7 +343,7 @@ func (suite *JobSuite) TestLoadCollectionWithReplicas() {
)
suite.scheduler.Add(job)
err := job.Wait()
suite.ErrorIs(err, ErrNoEnoughNode)
suite.ErrorContains(err, meta.ErrNodeNotEnough.Error())
}
}
@ -605,7 +605,7 @@ func (suite *JobSuite) TestLoadPartitionWithReplicas() {
)
suite.scheduler.Add(job)
err := job.Wait()
suite.ErrorIs(err, ErrNoEnoughNode)
suite.ErrorContains(err, meta.ErrNodeNotEnough.Error())
}
}

View File

@ -51,6 +51,7 @@ var (
)
var DefaultResourceGroupName = "__default_resource_group"
var DefaultResourceGroupCapacity = 1000000
type ResourceGroup struct {
nodes UniqueSet
@ -67,54 +68,30 @@ func NewResourceGroup(capacity int) *ResourceGroup {
}
// assign node to resource group
func (rg *ResourceGroup) assignNode(id int64) error {
func (rg *ResourceGroup) assignNode(id int64, deltaCapacity int) error {
if rg.containsNode(id) {
return ErrNodeAlreadyAssign
}
rg.nodes.Insert(id)
rg.capacity++
rg.capacity += deltaCapacity
return nil
}
// unassign node from resource group
func (rg *ResourceGroup) unassignNode(id int64) error {
func (rg *ResourceGroup) unassignNode(id int64, deltaCapacity int) error {
if !rg.containsNode(id) {
// remove non exist node should be tolerable
return nil
}
rg.nodes.Remove(id)
rg.capacity--
rg.capacity += deltaCapacity
return nil
}
func (rg *ResourceGroup) handleNodeUp(id int64) error {
if rg.containsNode(id) {
return ErrNodeAlreadyAssign
}
if len(rg.nodes) >= rg.capacity {
// handleNodeUp can grow the capacity
rg.capacity++
}
rg.nodes.Insert(id)
return nil
}
func (rg *ResourceGroup) handleNodeDown(id int64) error {
if !rg.containsNode(id) {
// remove non exist node should be tolerable
return nil
}
rg.nodes.Remove(id)
return nil
}
func (rg *ResourceGroup) LackOfNodes() int {
return rg.capacity - len(rg.nodes)
}
@ -141,7 +118,7 @@ type ResourceManager struct {
func NewResourceManager(store Store, nodeMgr *session.NodeManager) *ResourceManager {
groupMap := make(map[string]*ResourceGroup)
groupMap[DefaultResourceGroupName] = NewResourceGroup(0)
groupMap[DefaultResourceGroupName] = NewResourceGroup(DefaultResourceGroupCapacity)
return &ResourceManager{
groups: groupMap,
store: store,
@ -241,9 +218,14 @@ func (rm *ResourceManager) assignNode(rgName string, node int64) error {
newNodes := rm.groups[rgName].GetNodes()
newNodes = append(newNodes, node)
deltaCapacity := 1
if rgName == DefaultResourceGroupName {
// default rg capacity won't be changed
deltaCapacity = 0
}
err := rm.store.SaveResourceGroup(&querypb.ResourceGroup{
Name: rgName,
Capacity: int32(rm.groups[rgName].GetCapacity()) + 1,
Capacity: int32(rm.groups[rgName].GetCapacity() + deltaCapacity),
Nodes: newNodes,
})
if err != nil {
@ -255,7 +237,7 @@ func (rm *ResourceManager) assignNode(rgName string, node int64) error {
return err
}
err = rm.groups[rgName].assignNode(node)
err = rm.groups[rgName].assignNode(node, deltaCapacity)
if err != nil {
return err
}
@ -290,7 +272,7 @@ func (rm *ResourceManager) unassignNode(rgName string, node int64) error {
return ErrRGNotExist
}
if rm.nodeMgr.Get(node) == nil {
if rm.nodeMgr.Get(node) == nil || !rm.groups[rgName].containsNode(node) {
// remove non exist node should be tolerable
return nil
}
@ -302,9 +284,15 @@ func (rm *ResourceManager) unassignNode(rgName string, node int64) error {
}
}
deltaCapacity := -1
if rgName == DefaultResourceGroupName {
// default rg capacity won't be changed
deltaCapacity = 0
}
err := rm.store.SaveResourceGroup(&querypb.ResourceGroup{
Name: rgName,
Capacity: int32(rm.groups[rgName].GetCapacity()) - 1,
Capacity: int32(rm.groups[rgName].GetCapacity() + deltaCapacity),
Nodes: newNodes,
})
if err != nil {
@ -317,7 +305,7 @@ func (rm *ResourceManager) unassignNode(rgName string, node int64) error {
}
rm.checkRGNodeStatus(rgName)
err = rm.groups[rgName].unassignNode(node)
err = rm.groups[rgName].unassignNode(node, deltaCapacity)
if err != nil {
return err
}
@ -461,7 +449,7 @@ func (rm *ResourceManager) HandleNodeUp(node int64) (string, error) {
}
// assign new node to default rg
rm.groups[DefaultResourceGroupName].handleNodeUp(node)
rm.groups[DefaultResourceGroupName].assignNode(node, 0)
log.Info("HandleNodeUp: add node to default resource group",
zap.String("rgName", DefaultResourceGroupName),
zap.Int64("node", node),
@ -483,7 +471,7 @@ func (rm *ResourceManager) HandleNodeDown(node int64) (string, error) {
zap.String("rgName", rgName),
zap.Int64("node", node),
)
return rgName, rm.groups[rgName].handleNodeDown(node)
return rgName, rm.groups[rgName].unassignNode(node, 0)
}
return "", ErrNodeNotAssignToRG
@ -509,14 +497,23 @@ func (rm *ResourceManager) TransferNode(from string, to string, numNode int) err
return err
}
deltaFromCapacity := -1
if from == DefaultResourceGroupName {
deltaFromCapacity = 0
}
deltaToCapacity := 1
if to == DefaultResourceGroupName {
deltaToCapacity = 0
}
for _, node := range movedNodes {
err := rm.groups[from].unassignNode(node)
err := rm.groups[from].unassignNode(node, deltaFromCapacity)
if err != nil {
// interrupt transfer, unreachable logic path
return err
}
err = rm.groups[to].assignNode(node)
err = rm.groups[to].assignNode(node, deltaToCapacity)
if err != nil {
// interrupt transfer, unreachable logic path
return err
@ -544,15 +541,27 @@ func (rm *ResourceManager) transferNodeInStore(from string, to string, numNode i
}
}
fromCapacity := rm.groups[from].GetCapacity()
if from != DefaultResourceGroupName {
// default rg capacity won't be changed
fromCapacity = rm.groups[from].GetCapacity() - numNode
}
fromRG := &querypb.ResourceGroup{
Name: from,
Capacity: int32(rm.groups[from].GetCapacity() - numNode),
Capacity: int32(fromCapacity),
Nodes: fromNodeList,
}
toCapacity := rm.groups[to].GetCapacity()
if from != DefaultResourceGroupName {
// default rg capacity won't be changed
toCapacity = rm.groups[to].GetCapacity() + numNode
}
toRG := &querypb.ResourceGroup{
Name: to,
Capacity: int32(rm.groups[to].GetCapacity() + numNode),
Capacity: int32(toCapacity),
Nodes: toNodeList,
}
@ -580,7 +589,7 @@ func (rm *ResourceManager) AutoRecoverResourceGroup(rgName string) (int, error)
return i + 1, err
}
err = rm.groups[rgName].handleNodeUp(node)
err = rm.groups[rgName].assignNode(node, 0)
if err != nil {
// roll back, unreachable logic path
rm.assignNode(DefaultResourceGroupName, node)
@ -599,10 +608,18 @@ func (rm *ResourceManager) Recover() error {
}
for _, rg := range rgs {
rm.groups[rg.GetName()] = NewResourceGroup(0)
for _, node := range rg.GetNodes() {
rm.groups[rg.GetName()].assignNode(node)
if rg.GetName() == DefaultResourceGroupName {
rm.groups[rg.GetName()] = NewResourceGroup(DefaultResourceGroupCapacity)
for _, node := range rg.GetNodes() {
rm.groups[rg.GetName()].assignNode(node, 0)
}
} else {
rm.groups[rg.GetName()] = NewResourceGroup(0)
for _, node := range rg.GetNodes() {
rm.groups[rg.GetName()].assignNode(node, 1)
}
}
rm.checkRGNodeStatus(rg.GetName())
log.Info("Recover resource group",
zap.String("rgName", rg.GetName()),
@ -623,7 +640,7 @@ func (rm *ResourceManager) checkRGNodeStatus(rgName string) {
zap.Int64("nodeID", node),
)
rm.groups[rgName].handleNodeDown(node)
rm.groups[rgName].unassignNode(node, 0)
}
}
}

View File

@ -111,7 +111,6 @@ func (suite *ResourceManagerSuite) TestManipulateNode() {
err = suite.manager.AssignNode("rg1", 1)
suite.NoError(err)
err = suite.manager.AssignNode("rg2", 1)
println(err.Error())
suite.ErrorIs(err, ErrNodeAlreadyAssign)
// transfer node between rgs
@ -175,14 +174,14 @@ func (suite *ResourceManagerSuite) TestHandleNodeUp() {
suite.NoError(err)
defaultRG, err := suite.manager.GetResourceGroup(DefaultResourceGroupName)
suite.NoError(err)
suite.Equal(0, defaultRG.GetCapacity())
suite.Equal(DefaultResourceGroupCapacity, defaultRG.GetCapacity())
suite.manager.HandleNodeUp(101)
rg, err = suite.manager.GetResourceGroup("rg1")
suite.NoError(err)
suite.Equal(rg.GetCapacity(), 3)
suite.Equal(len(rg.GetNodes()), 2)
suite.False(suite.manager.ContainsNode("rg1", 101))
suite.Equal(1, defaultRG.GetCapacity())
suite.Equal(DefaultResourceGroupCapacity, defaultRG.GetCapacity())
}
func (suite *ResourceManagerSuite) TestRecover() {
@ -311,13 +310,13 @@ func (suite *ResourceManagerSuite) TestDefaultResourceGroup() {
}
defaultRG, err := suite.manager.GetResourceGroup(DefaultResourceGroupName)
suite.NoError(err)
suite.Equal(defaultRG.GetCapacity(), 0)
suite.Equal(defaultRG.GetCapacity(), DefaultResourceGroupCapacity)
suite.Len(defaultRG.GetNodes(), 0)
suite.manager.HandleNodeUp(1)
suite.manager.HandleNodeUp(2)
suite.manager.HandleNodeUp(3)
suite.Equal(defaultRG.GetCapacity(), 3)
suite.Equal(defaultRG.GetCapacity(), DefaultResourceGroupCapacity)
suite.Len(defaultRG.GetNodes(), 3)
// shutdown node 1 and 2
@ -326,18 +325,18 @@ func (suite *ResourceManagerSuite) TestDefaultResourceGroup() {
defaultRG, err = suite.manager.GetResourceGroup(DefaultResourceGroupName)
suite.NoError(err)
suite.Equal(defaultRG.GetCapacity(), 3)
suite.Equal(defaultRG.GetCapacity(), DefaultResourceGroupCapacity)
suite.Len(defaultRG.GetNodes(), 1)
suite.manager.HandleNodeUp(4)
suite.manager.HandleNodeUp(5)
suite.Equal(defaultRG.GetCapacity(), 3)
suite.Equal(defaultRG.GetCapacity(), DefaultResourceGroupCapacity)
suite.Len(defaultRG.GetNodes(), 3)
suite.manager.HandleNodeUp(7)
suite.manager.HandleNodeUp(8)
suite.manager.HandleNodeUp(9)
suite.Equal(defaultRG.GetCapacity(), 6)
suite.Equal(defaultRG.GetCapacity(), DefaultResourceGroupCapacity)
suite.Len(defaultRG.GetNodes(), 6)
}

View File

@ -1060,12 +1060,19 @@ func (s *Server) TransferReplica(ctx context.Context, req *querypb.TransferRepli
fmt.Sprintf("the target resource group[%s] doesn't exist", req.GetTargetResourceGroup()), meta.ErrRGNotExist), nil
}
replicas := s.meta.ReplicaManager.GetByCollectionAndRG(req.GetCollectionID(), req.GetTargetResourceGroup())
if len(replicas) > 0 {
return utils.WrapStatus(commonpb.ErrorCode_IllegalArgument,
fmt.Sprintf("found [%d] replicas of same collection in target resource group[%s], dynamically increase replica num is unsupported",
len(replicas), req.GetSourceResourceGroup())), nil
}
// for now, we don't support to transfer replica of same collection to same resource group
replicas := s.meta.ReplicaManager.GetByCollectionAndRG(req.GetCollectionID(), req.GetSourceResourceGroup())
replicas = s.meta.ReplicaManager.GetByCollectionAndRG(req.GetCollectionID(), req.GetSourceResourceGroup())
if len(replicas) < int(req.GetNumReplica()) {
return utils.WrapStatus(commonpb.ErrorCode_IllegalArgument,
fmt.Sprintf("found [%d] replicas of collection[%d] in source resource group[%s]",
len(replicas), req.GetCollectionID(), req.GetSourceResourceGroup())), nil
fmt.Sprintf("only found [%d] replicas in source resource group[%s]",
len(replicas), req.GetSourceResourceGroup())), nil
}
err := s.transferReplica(req.GetTargetResourceGroup(), replicas[:req.GetNumReplica()])

View File

@ -561,7 +561,7 @@ func (suite *ServiceSuite) TestTransferReplica() {
NumReplica: 2,
})
suite.NoError(err)
suite.Contains(resp.Reason, "found [0] replicas of collection[1] in source resource group")
suite.Contains(resp.Reason, "only found [0] replicas in source resource group")
resp, err = suite.server.TransferReplica(ctx, &querypb.TransferReplicaRequest{
SourceResourceGroup: "rgg",
@ -591,6 +591,11 @@ func (suite *ServiceSuite) TestTransferReplica() {
ID: 222,
ResourceGroup: meta.DefaultResourceGroupName,
}, typeutil.NewUniqueSet(2)))
suite.server.meta.Put(meta.NewReplica(&querypb.Replica{
CollectionID: 1,
ID: 333,
ResourceGroup: meta.DefaultResourceGroupName,
}, typeutil.NewUniqueSet(3)))
suite.server.nodeMgr.Add(session.NewNodeInfo(1001, "localhost"))
suite.server.nodeMgr.Add(session.NewNodeInfo(1002, "localhost"))
@ -611,6 +616,14 @@ func (suite *ServiceSuite) TestTransferReplica() {
suite.NoError(err)
suite.Equal(resp.ErrorCode, commonpb.ErrorCode_Success)
suite.Len(suite.server.meta.GetByResourceGroup("rg3"), 2)
resp, err = suite.server.TransferReplica(ctx, &querypb.TransferReplicaRequest{
SourceResourceGroup: meta.DefaultResourceGroupName,
TargetResourceGroup: "rg3",
CollectionID: 1,
NumReplica: 2,
})
suite.NoError(err)
suite.Contains(resp.Reason, "dynamically increase replica num is unsupported")
// server unhealthy
server.status.Store(commonpb.StateCode_Abnormal)

View File

@ -33,7 +33,7 @@ var (
ErrGetNodesFromRG = errors.New("failed to get node from rg")
ErrNoReplicaFound = errors.New("no replica found during assign nodes")
ErrReplicasInconsistent = errors.New("all replicas should belong to same collection during assign nodes")
ErrUseWrongNumRG = errors.New("resource num can only be 0, 1 or same as replica number")
ErrUseWrongNumRG = errors.New("resource group num can only be 0, 1 or same as replica number")
)
func GetReplicaNodesInfo(replicaMgr *meta.ReplicaManager, nodeMgr *session.NodeManager, replicaID int64) []*session.NodeInfo {

View File

@ -215,11 +215,11 @@ class ResponseChecker:
if check_items.get("num_available_node", None):
assert rg.num_available_node == check_items["num_available_node"]
if check_items.get("num_loaded_replica", None):
assert rg.num_loaded_replica == check_items["num_loaded_replica"]
assert dict(rg.num_loaded_replica).items() >= check_items["num_loaded_replica"].items()
if check_items.get("num_outgoing_node", None):
assert rg.num_outgoing_node == check_items["num_outgoing_node"]
assert dict(rg.num_outgoing_node).items() >= check_items["num_outgoing_node"].items()
if check_items.get("num_incoming_node", None):
assert rg.num_incoming_node == check_items["num_incoming_node"]
assert dict(rg.num_incoming_node).items() >= check_items["num_incoming_node"].items()
return True
@staticmethod

View File

@ -38,6 +38,7 @@ another_float_vec_field_name = "float_vector1"
default_binary_vec_field_name = "binary_vector"
default_partition_name = "_default"
default_resource_group_name = '__default_resource_group'
default_resource_group_capacity = 1000000
default_tag = "1970_01_01"
row_count = "row_count"
default_length = 65535

View File

@ -12,7 +12,7 @@ allure-pytest==2.7.0
pytest-print==0.2.1
pytest-level==0.1.1
pytest-xdist==2.5.0
pymilvus==2.3.0.dev34
pymilvus==2.3.0.dev35
pytest-rerunfailures==9.1.1
git+https://github.com/Projectplace/pytest-tags
ndg-httpsclient

View File

@ -7,8 +7,6 @@ from common.common_type import CaseLabel, CheckTasks
from utils.util_pymilvus import *
from utils.util_log import test_log as log
@pytest.mark.skip(reason="still debugging")
class TestResourceGroupParams(TestcaseBase):
@pytest.mark.tags(CaseLabel.L0)
def test_rg_default(self):
@ -28,10 +26,9 @@ class TestResourceGroupParams(TestcaseBase):
self._connect()
rgs, _ = self.utility_wrap.list_resource_groups()
rgs_count = len(rgs)
default_rg_init_cap = 2
default_rg_init_available_node = 1
default_rg_info = {"name": ct.default_resource_group_name,
"capacity": default_rg_init_cap,
"capacity": ct.default_resource_group_capacity,
"num_available_node": default_rg_init_available_node,
"num_loaded_replica": {},
"num_outgoing_node": {},
@ -73,7 +70,7 @@ class TestResourceGroupParams(TestcaseBase):
check_task=ct.CheckTasks.check_rg_property,
check_items=target_rg_info)
source_rg_info = {"name": ct.default_resource_group_name,
"capacity": default_rg_init_cap - num_node,
"capacity": ct.default_resource_group_capacity,
"num_available_node": default_rg_init_available_node - num_node,
}
self.utility_wrap.describe_resource_group(name=ct.default_resource_group_name,
@ -98,8 +95,7 @@ class TestResourceGroupParams(TestcaseBase):
self.utility_wrap.drop_resource_group(name=m_rg_name)
rgs, _ = self.utility_wrap.list_resource_groups()
assert len(rgs) == rgs_count
# pytest.skip(reason='issue #21962')
error = {ct.err_code: 999, ct.err_msg: 'failed to describe resource group, err=rg is not existing'}
error = {ct.err_code: 999, ct.err_msg: "failed to describe resource group, err=resource group doesn't exist"}
self.utility_wrap.describe_resource_group(name=m_rg_name,
check_task=ct.CheckTasks.err_res,
check_items=error)
@ -113,7 +109,7 @@ class TestResourceGroupParams(TestcaseBase):
"""
self._connect()
error = {ct.err_code: 999,
ct.err_msg: "failed to create resource group, err=resource group name couldn't be empty"}
ct.err_msg: "`resource_group_name` value {} is illegal".format(rg_name)}
self.init_resource_group(name=rg_name, check_task=ct.CheckTasks.err_res, check_items=error)
@pytest.mark.tags(CaseLabel.L1)
@ -124,17 +120,29 @@ class TestResourceGroupParams(TestcaseBase):
"""
pass
@pytest.mark.skip(reason="need define rules of valid names")
@pytest.mark.tags(CaseLabel.L1)
@pytest.mark.parametrize("rg_name", ct.get_invalid_strs)
@pytest.mark.parametrize("rg_name", [[], 1, [1, "2", 3], (1,), {1: 1}, None])
def test_create_rg_illegal_names(self, rg_name):
"""
method: create a rg with an invalid name(what are invalid names? types, length, chinese,symbols)
verify: fail with error msg
"""
self._connect()
error = {ct.err_code: 999,
ct.err_msg: "`resource_group_name` value {} is illegal".format(rg_name)}
self.init_resource_group(rg_name, check_task=ct.CheckTasks.err_res, check_items=error)
@pytest.mark.tags(CaseLabel.L1)
@pytest.mark.parametrize("rg_name", [" ", "12-s", "12 s", "(mn)", "中文", "%$#", "qw$_o90", "1ns_", "a".join("a" for i in range(256))])
def test_create_rg_invalid_names(self, rg_name):
"""
method: create a rg with an invalid name(what are invalid names? types, length, chinese,symbols)
verify: fail with error msg
"""
self._connect()
self.init_resource_group(name=rg_name)
# TODO: check error msg
error = {ct.err_code: 999,
ct.err_msg: "Invalid resource group name"}
self.init_resource_group(rg_name, check_task=ct.CheckTasks.err_res, check_items=error)
@pytest.mark.tags(CaseLabel.L1)
def test_create_rg_max_length_name(self):
@ -164,7 +172,6 @@ class TestResourceGroupParams(TestcaseBase):
check_task=ct.CheckTasks.err_res,
check_items=error)
@pytest.mark.skip(reason="issue #21971")
@pytest.mark.tags(CaseLabel.L1)
def test_create_rg_dropped_name(self):
"""
@ -187,15 +194,13 @@ class TestResourceGroupParams(TestcaseBase):
# drop the rg
self.utility_wrap.drop_resource_group(name=rg_name)
assert len(self.utility_wrap.list_resource_groups()[0]) == rgs_count - 1
# error = {ct.err_code: 999,
# ct.err_msg: "failed to create resource group, err=resource group not exist"}
# self.utility_wrap.describe_resource_group(name=rg_name,
# check_task=ct.CheckTasks.err_res,
# check_items=error)
# create the rg with the same name again
error = {ct.err_code: 999,
ct.err_msg: "failed to describe resource group, err=resource group doesn't exist"}
self.utility_wrap.describe_resource_group(name=rg_name,
check_task=ct.CheckTasks.check_rg_property,
check_items={"name": rg_name})
check_task=ct.CheckTasks.err_res,
check_items=error)
# create the rg with the same name again
self.init_resource_group(name=rg_name)
assert rgs_count == len(self.utility_wrap.list_resource_groups()[0])
self.utility_wrap.describe_resource_group(name=rg_name,
check_task=ct.CheckTasks.check_rg_property,
@ -233,9 +238,9 @@ class TestResourceGroupParams(TestcaseBase):
verify: drop successfully
"""
self._connect()
rgs_count = len(self.utility_wrap.list_collections()[0])
self.utility_wrap.drop_resource_group(name=rg_name)
assert rgs_count == len(self.utility_wrap.list_collections()[0])
error = {ct.err_code: 999,
ct.err_msg: "`resource_group_name` value {} is illegal".format(rg_name)}
self.utility_wrap.drop_resource_group(name=rg_name, check_task=ct.CheckTasks.err_res, check_items=error)
@pytest.mark.tags(CaseLabel.L1)
def test_drop_rg_invalid_names(self):
@ -301,7 +306,6 @@ class TestResourceGroupParams(TestcaseBase):
check_task=CheckTasks.check_rg_property,
check_items=default_rg_info)
# @pytest.mark.skip(reason="issue #21971")
@pytest.mark.tags(CaseLabel.L1)
@pytest.mark.parametrize("rg_name", ["", None])
def test_describe_rg_empty_name(self, rg_name):
@ -310,8 +314,9 @@ class TestResourceGroupParams(TestcaseBase):
verify: fail with error msg
"""
self._connect()
self.utility_wrap.describe_resource_group(name=rg_name)
# TODO: check error
error = {ct.err_code: 999,
ct.err_msg: "`resource_group_name` value {} is illegal".format(rg_name)}
self.utility_wrap.drop_resource_group(name=rg_name, check_task=ct.CheckTasks.err_res, check_items=error)
@pytest.mark.tags(CaseLabel.L1)
def test_describe_rg_invalid_names(self):
@ -321,8 +326,7 @@ class TestResourceGroupParams(TestcaseBase):
"""
pass
# @pytest.mark.skip(reason="issue #21962")
# @pytest.mark.tags(CaseLabel.L1)
@pytest.mark.tags(CaseLabel.L1)
def test_describe_rg_non_existing(self):
"""
method: describe an non existing rg
@ -330,7 +334,7 @@ class TestResourceGroupParams(TestcaseBase):
"""
self._connect()
non_existing_rg = 'non_existing'
error = {ct.err_code: 999, ct.err_msg: 'failed to describe resource group, err=rg is not existing'}
error = {ct.err_code: 999, ct.err_msg: "failed to describe resource group, err=resource group doesn't exist"}
self.utility_wrap.describe_resource_group(name=non_existing_rg,
check_task=ct.CheckTasks.err_res,
check_items=error)
@ -343,7 +347,7 @@ class TestResourceGroupParams(TestcaseBase):
num_outgoing_node and num_incoming_node
"""
self._connect()
default_rg_init_cap = 2
default_rg_init_cap = 1000000
default_rg_init_available_node = 1
default_rg_info = {"name": ct.default_resource_group_name,
"capacity": default_rg_init_cap,
@ -356,8 +360,7 @@ class TestResourceGroupParams(TestcaseBase):
check_task=ct.CheckTasks.check_rg_property,
check_items=default_rg_info)
@pytest.mark.skip(reason="still debugging")
@pytest.mark.skip(reason="will cause concurrent problems")
class TestTransferNode(TestcaseBase):
@pytest.mark.tags(CaseLabel.L0)
def test_transfer_node_default(self):
@ -425,6 +428,9 @@ class TestTransferNode(TestcaseBase):
check_items=error
)
self.utility_wrap.drop_resource_group(name=rg1_name)
# clean
self.utility_wrap.transfer_node(source=rg2_name, target=ct.default_resource_group_name, num_node=1)
self.utility_wrap.drop_resource_group(name=rg2_name)
@pytest.mark.tags(CaseLabel.L0)
@pytest.mark.parametrize("with_growing", [True, False])
@ -454,11 +460,11 @@ class TestTransferNode(TestcaseBase):
ct.default_limit,
check_task=CheckTasks.check_search_results,
check_items={"nq": nq,
"ids": insert_ids,
"ids": insert_ids.copy(),
"limit": ct.default_limit}
)
default_rg_info = {"name": ct.default_resource_group_name,
"capacity": 2,
"capacity": ct.default_resource_group_capacity,
"num_available_node": 1,
"num_loaded_replica": {collection_w.name: 1},
"num_outgoing_node": {},
@ -489,7 +495,7 @@ class TestTransferNode(TestcaseBase):
check_task=CheckTasks.check_rg_property,
check_items=rg_info)
default_rg_info = {"name": ct.default_resource_group_name,
"capacity": 1,
"capacity": ct.default_resource_group_capacity,
"num_available_node": 0,
"num_loaded_replica": {collection_w.name: 1},
"num_outgoing_node": {collection_w.name: 1},
@ -506,7 +512,7 @@ class TestTransferNode(TestcaseBase):
ct.default_limit,
check_task=CheckTasks.check_search_results,
check_items={"nq": nq,
"ids": insert_ids,
"ids": insert_ids.copy(),
"limit": ct.default_limit}
)
@ -523,7 +529,7 @@ class TestTransferNode(TestcaseBase):
ct.default_limit,
check_task=CheckTasks.check_search_results,
check_items={"nq": nq,
"ids": insert_ids,
"ids": insert_ids.copy(),
"limit": ct.default_limit}
)
# verify rg state
@ -538,7 +544,7 @@ class TestTransferNode(TestcaseBase):
check_task=CheckTasks.check_rg_property,
check_items=rg_info)
default_rg_info = {"name": ct.default_resource_group_name,
"capacity": 2,
"capacity": ct.default_resource_group_capacity,
"num_available_node": 1,
"num_loaded_replica": {collection_w.name: 1},
"num_outgoing_node": {},
@ -547,8 +553,12 @@ class TestTransferNode(TestcaseBase):
self.utility_wrap.describe_resource_group(name=ct.default_resource_group_name,
check_task=CheckTasks.check_rg_property,
check_items=default_rg_info)
# clean
collection_w.release()
collection_w.drop()
self.utility_wrap.drop_resource_group(name=rg_name)
@pytest.mark.xfail(reason="issue #22051")
@pytest.mark.tags(CaseLabel.L0)
def test_load_collection_with_no_available_node(self):
"""
@ -607,7 +617,7 @@ class TestTransferNode(TestcaseBase):
ct.default_limit,
check_task=CheckTasks.check_search_results,
check_items={"nq": nq,
"ids": insert_ids,
"ids": insert_ids.copy(),
"limit": ct.default_limit}
)
# check rgA info
@ -633,7 +643,7 @@ class TestTransferNode(TestcaseBase):
ct.default_limit,
check_task=CheckTasks.check_search_results,
check_items={"nq": nq,
"ids": insert_ids,
"ids": insert_ids.copy(),
"limit": ct.default_limit}
)
# check rgA info after transfer
@ -648,7 +658,7 @@ class TestTransferNode(TestcaseBase):
check_task=CheckTasks.check_rg_property,
check_items=rg_info)
default_rg_info = {"name": ct.default_resource_group_name,
"capacity": 1,
"capacity": ct.default_resource_group_capacity,
"num_available_node": 1,
"num_loaded_replica": {},
"num_outgoing_node": {},
@ -659,13 +669,12 @@ class TestTransferNode(TestcaseBase):
check_items=default_rg_info)
# 8. load the collection with default rg
error = {ct.err_code: 999,
ct.err_msg: 'failed to load, err=already loaded in the other rg'}
collection_w.load(check_task=CheckTasks.err_res, check_items=error)
# error = {ct.err_code: 5,
# ct.err_msg: 'failed to load, err=already loaded in the other rg'}
# collection_w.load(_resource_groups=[rg_name], check_task=CheckTasks.err_res, check_items=error)
@pytest.mark.xfail(reason="issue #22058")
@pytest.mark.tags(CaseLabel.L0)
@pytest.mark.parametrize("replicas", [1, 2, 3])
@pytest.mark.parametrize("replicas", [1, 3])
def test_load_collection_with_multi_replicas_multi_rgs(self, replicas):
"""
Method:
@ -688,20 +697,17 @@ class TestTransferNode(TestcaseBase):
# load with different replicas
error = {ct.err_code: 999,
ct.err_msg: 'failed to load collection, err=no enough nodes to create replicas[NoEnoughNode]'}
ct.err_msg: 'failed to load collection, err=failed to spawn replica for collection[resource group num can only be 0, 1 or same as replica number]'}
collection_w.load(replica_number=replicas,
_resource_groups=[rgA_name, rgB_name],
check_task=CheckTasks.err_res, check_items=error)
# error = {ct.err_code: 999,
# ct.err_msg: 'failed to load collection, err=failed to spawn replica for collection[nodes not enough]'}
collection_w.load(replica_number=replicas,
_resource_groups=[ct.default_resource_group_name, rgB_name],
check_task=CheckTasks.err_res, check_items=error)
@pytest.mark.xfail("reason=issue #22058")
@pytest.mark.tags(CaseLabel.L0)
@pytest.mark.parametrize("rg_names", [[], [""], ["non_existing"], "不合法"])
@pytest.mark.parametrize("rg_names", [[""], ["non_existing"], "不合法"])
def test_load_collection_with_empty_rg_name(self, rg_names):
"""
Method:
@ -710,12 +716,11 @@ class TestTransferNode(TestcaseBase):
"""
collection_w = self.init_collection_wrap()
collection_w.create_index(ct.default_float_vec_field_name, ct.default_flat_index)
error = {ct.err_code: 999,
ct.err_msg: 'failed to load collection, err=failed to spawn replica for collection[nodes not enough]'}
error = {ct.err_code: 1,
ct.err_msg: "failed to load collection, err=failed to spawn replica for collection[resource group doesn't exist]"}
collection_w.load(_resource_groups=rg_names,
check_task=CheckTasks.err_res, check_items=error)
@pytest.mark.xfail(reason="issue #22051")
@pytest.mark.tags(CaseLabel.L0)
def test_load_partition_with_no_available_node(self):
"""
@ -807,7 +812,7 @@ class TestTransferNode(TestcaseBase):
check_task=CheckTasks.check_rg_property,
check_items=rg_info)
default_rg_info = {"name": ct.default_resource_group_name,
"capacity": 1,
"capacity": ct.default_resource_group_capacity,
"num_available_node": 1,
"num_loaded_replica": {},
"num_outgoing_node": {},
@ -818,12 +823,12 @@ class TestTransferNode(TestcaseBase):
check_items=default_rg_info)
# 8. load the collection with default rg
error = {ct.err_code: 999,
ct.err_msg: 'failed to load, err=already loaded in the other rg'}
partition_w.load(check_task=CheckTasks.err_res, check_items=error)
# error = {ct.err_code: 999,
# ct.err_msg: 'failed to load, err=already loaded in the other rg'}
# partition_w.load(check_task=CheckTasks.err_res, check_items=error)
@pytest.mark.tags(CaseLabel.L0)
@pytest.mark.parametrize("replicas", [1, 2, 3])
@pytest.mark.parametrize("replicas", [1, 3])
def test_load_partition_with_multi_replicas_multi_rgs(self, replicas):
"""
Method:
@ -849,19 +854,17 @@ class TestTransferNode(TestcaseBase):
# load with different replicas
error = {ct.err_code: 999,
ct.err_msg: 'failed to load partitions, err=no enough nodes to create replicas[NoEnoughNode]'}
ct.err_msg: 'failed to load partitions, err=failed to spawn replica for collection[resource group num can only be 0, 1 or same as replica number]'}
partition_w.load(replica_number=replicas,
_resource_groups=[rgA_name, rgB_name],
check_task=CheckTasks.err_res, check_items=error)
error = {ct.err_code: 999,
ct.err_msg: 'failed to load partitions, err=no enough nodes to create replicas[NoEnoughNode]'}
partition_w.load(replica_number=replicas,
_resource_groups=[ct.default_resource_group_name, rgB_name],
check_task=CheckTasks.err_res, check_items=error)
@pytest.mark.tags(CaseLabel.L0)
@pytest.mark.parametrize("rg_names", [[], [""], ["non_existing"], "不合法"])
@pytest.mark.parametrize("rg_names", [[""], ["non_existing"], "不合法"])
def test_load_partition_with_empty_rg_name(self, rg_names):
"""
Method:
@ -872,16 +875,17 @@ class TestTransferNode(TestcaseBase):
dim = ct.default_dim
# 1. create a partition
collection_w = self.init_collection_wrap()
collection_w.create_index(ct.default_float_vec_field_name, ct.default_flat_index)
partition_name = cf.gen_unique_str('par')
partition_w = self.init_partition_wrap(collection_w, partition_name)
error = {ct.err_code: 999,
ct.err_msg: 'failed to load partition, err=failed to spawn replica for collection[nodes not enough]'}
error = {ct.err_code: 1,
ct.err_msg: 'failed to load partitions, err=failed to spawn replica for collection[resource num can only be 0, 1 or same as replica number]'}
partition_w.load(_resource_groups=rg_names,
check_task=CheckTasks.err_res, check_items=error)
@pytest.mark.skip(reason="still debugging")
@pytest.mark.skip(reason="need 8 query nodes for this test")
# run the multi node tests with 8 query nodes
class TestResourceGroupMultiNodes(TestcaseBase):
@pytest.mark.tags(CaseLabel.L0)
@ -913,7 +917,8 @@ class TestResourceGroupMultiNodes(TestcaseBase):
# make growing
if with_growing:
collection_w.insert(cf.gen_default_list_data(nb=500, dim=dim, start=6*nb))
res, _ = collection_w.insert(cf.gen_default_list_data(nb, dim=dim, start=6 * nb))
insert_ids.extend(res.primary_keys)
# create rgA
rg_name = cf.gen_unique_str('rg')
@ -960,16 +965,17 @@ class TestResourceGroupMultiNodes(TestcaseBase):
# verify replica state
replicas = collection_w.get_replicas()
num_nodes_for_replicas = 0
assert len(replicas) == replica_number
for rep in replicas:
assert rep.resource_group_name == rg_name
assert len(replicas[0].groups) == replica_number
for rep in replicas[0].groups:
assert rep.resource_group == rg_name
assert rep.num_outbound_node == {}
num_nodes_for_replicas += len(rep.node_ids)
num_nodes_for_replicas += len(rep.group_nodes)
assert num_nodes_for_replicas == num_nodes_to_rg
# make growing
if with_growing:
collection_w.insert(cf.gen_default_list_data(nb=200, dim=dim, start=7 * nb))
res, _ = collection_w.insert(cf.gen_default_list_data(nb, dim=dim, start=7 * nb))
insert_ids.extend(res.primary_keys)
# verify search succ
nq = 5
@ -980,7 +986,7 @@ class TestResourceGroupMultiNodes(TestcaseBase):
ct.default_limit,
check_task=CheckTasks.check_search_results,
check_items={"nq": nq,
"ids": insert_ids,
"ids": insert_ids.copy(),
"limit": ct.default_limit}
)
@ -1015,15 +1021,16 @@ class TestResourceGroupMultiNodes(TestcaseBase):
# verify replica state
replicas = collection_w.get_replicas()
assert len(replicas) == replica_number
for rep in replicas:
assert rep.resource_group_name == rg_name
assert len(replicas[0].groups) == replica_number
for rep in replicas[0].groups:
assert rep.resource_group == rg_name
assert rep.num_outbound_node == {}
assert len(rep.node_ids) == 1 # one replica for each node
assert len(rep.group_nodes) == 1 # one replica for each node
# make growing
if with_growing:
collection_w.insert(cf.gen_default_list_data(nb=200, dim=dim, start=8 * nb))
res, _ = collection_w.insert(cf.gen_default_list_data(nb, dim=dim, start=8 * nb))
insert_ids.extend(res.primary_keys)
# verify search succ
collection_w.search(vectors[:nq],
@ -1032,20 +1039,25 @@ class TestResourceGroupMultiNodes(TestcaseBase):
ct.default_limit,
check_task=CheckTasks.check_search_results,
check_items={"nq": nq,
"ids": insert_ids,
"ids": insert_ids.copy(),
"limit": ct.default_limit}
)
# verify load successfully again with no parameters
collection_w.load()
collection_w.load(replica_number=replica_number)
collection_w.search(vectors[:nq],
ct.default_float_vec_field_name,
ct.default_search_params,
ct.default_limit,
check_task=CheckTasks.check_search_results,
check_items={"nq": nq,
"ids": insert_ids,
"ids": insert_ids.copy(),
"limit": ct.default_limit}
)
collection_w.release()
collection_w.drop()
self.utility_wrap.transfer_node(source=rg_name,
target=ct.default_resource_group_name,
num_node=num_nodes_to_rg)
@pytest.mark.tags(CaseLabel.L0)
@pytest.mark.parametrize("with_growing", [True, False])
@ -1076,7 +1088,8 @@ class TestResourceGroupMultiNodes(TestcaseBase):
# make growing
if with_growing:
collection_w.insert(cf.gen_default_list_data(nb=500, dim=dim, start=6 * nb))
res, _ = collection_w.insert(cf.gen_default_list_data(nb, dim=dim, start=6 * nb))
insert_ids.extend(res.primary_keys)
# create rgA and rgB
rgA_name = cf.gen_unique_str('rgA')
@ -1090,12 +1103,12 @@ class TestResourceGroupMultiNodes(TestcaseBase):
num_node=num_nodes_rgA)
num_nodes_rgB = 3
self.utility_wrap.transfer_node(source=ct.default_resource_group_name,
target=rgA_name,
target=rgB_name,
num_node=num_nodes_rgB)
# load 3 replicas in rgA and rgB
replica_number = 3
error = {ct.err_code: 999,
ct.err_msg: 'failed to load collection, err=failed to spawn replica for collection[nodes not enough]'}
ct.err_msg: 'failed to load collection, err=failed to spawn replica for collection[resource group num can only be 0, 1 or same as replica number]'}
collection_w.load(replica_number=replica_number,
_resource_groups=[rgA_name, rgB_name],
check_task=CheckTasks.err_res,
@ -1104,7 +1117,7 @@ class TestResourceGroupMultiNodes(TestcaseBase):
# load 1 replica in rgA and rgB
replica_number = 1
error = {ct.err_code: 999,
ct.err_msg: 'failed to load collection, err=failed to spawn replica for collection[nodes not enough]'}
ct.err_msg: 'failed to load collection, err=failed to spawn replica for collection[resource group num can only be 0, 1 or same as replica number]'}
collection_w.load(replica_number=replica_number,
_resource_groups=[rgA_name, rgB_name],
check_task=CheckTasks.err_res,
@ -1116,18 +1129,19 @@ class TestResourceGroupMultiNodes(TestcaseBase):
_resource_groups=[rgA_name, rgB_name])
# verify replica state: each replica occupies one rg
replicas = collection_w.get_replicas()
assert len(replicas) == replica_number
for rep in replicas:
assert len(replicas[0].groups) == replica_number
for rep in replicas[0].groups:
assert rep.num_outbound_node == {}
assert rep.resource_group_name in [rgA_name, rgB_name]
if rep.resource_group_name == rgA_name:
assert len(rep.node_ids) == num_nodes_rgA # one replica for each rg
assert rep.resource_group in [rgA_name, rgB_name]
if rep.resource_group == rgA_name:
assert len(rep.group_nodes) == num_nodes_rgA # one replica for each rg
else:
assert len(rep.node_ids) == num_nodes_rgB # one replica for each rg
assert len(rep.group_nodes) == num_nodes_rgB # one replica for each rg
# make growing
if with_growing:
collection_w.insert(cf.gen_default_list_data(nb=200, dim=dim, start=8 * nb))
res, _ = collection_w.insert(cf.gen_default_list_data(nb=200, dim=dim, start=8 * nb))
insert_ids.extend(res.primary_keys)
# verify search succ
nq = 5
@ -1138,20 +1152,28 @@ class TestResourceGroupMultiNodes(TestcaseBase):
ct.default_limit,
check_task=CheckTasks.check_search_results,
check_items={"nq": nq,
"ids": insert_ids,
"ids": insert_ids.copy(),
"limit": ct.default_limit}
)
# verify load successfully again with no parameters
collection_w.load()
collection_w.load(replica_number=2)
collection_w.search(vectors[:nq],
ct.default_float_vec_field_name,
ct.default_search_params,
ct.default_limit,
check_task=CheckTasks.check_search_results,
check_items={"nq": nq,
"ids": insert_ids,
"ids": insert_ids.copy(),
"limit": ct.default_limit}
)
collection_w.release()
collection_w.drop()
self.utility_wrap.transfer_node(source=rgA_name,
target=ct.default_resource_group_name,
num_node=num_nodes_rgA)
self.utility_wrap.transfer_node(source=rgB_name,
target=ct.default_resource_group_name,
num_node=num_nodes_rgB)
@pytest.mark.tags(CaseLabel.L0)
@pytest.mark.parametrize("with_growing", [True, False])
@ -1173,12 +1195,12 @@ class TestResourceGroupMultiNodes(TestcaseBase):
rgB_name = cf.gen_unique_str('rgB')
self.init_resource_group(name=rgB_name)
# transfer 2 nodes to rgA, 4 nodes to rgB
# transfer 1 nodes to rgA, 2 nodes to rgB
self.utility_wrap.transfer_node(source=ct.default_resource_group_name,
target=rgA_name,
num_node=1)
self.utility_wrap.transfer_node(source=ct.default_resource_group_name,
target=rgA_name,
target=rgB_name,
num_node=2)
dim = 128
@ -1195,7 +1217,8 @@ class TestResourceGroupMultiNodes(TestcaseBase):
# make growing
if with_growing:
collection_w.insert(cf.gen_default_list_data(nb=200, dim=dim, start=6 * nb))
res, _ = collection_w.insert(cf.gen_default_list_data(nb, dim=dim, start=6 * nb))
insert_ids.extend(res.primary_keys)
nq = 5
vectors = [[random.random() for _ in range(dim)] for _ in range(nq)]
@ -1206,23 +1229,28 @@ class TestResourceGroupMultiNodes(TestcaseBase):
ct.default_limit,
check_task=CheckTasks.check_search_results,
check_items={"nq": nq,
"ids": insert_ids,
"ids": insert_ids.copy(),
"limit": ct.default_limit}
)
# transfer 1 replica from rgB to rgA
error = {ct.err_code: 999,
ct.err_msg: 'failed to load collection, err=failed to spawn replica for collection[nodes not enough]'}
ct.err_msg: 'dynamically increase replica num is unsupported'}
self.utility_wrap.transfer_replica(source=rgB_name, target=rgA_name,
collection_name=collection_w.name, num_replica=1,
check_task=CheckTasks.err_res,
check_items=error)
error = {ct.err_code: 999,
ct.err_msg: 'dynamically increase replica num is unsupported'}
# transfer 1 replica from rgA to rgB
self.utility_wrap.transfer_replica(source=rgA_name, target=rgB_name,
collection_name=collection_w.name, num_replica=1)
collection_name=collection_w.name, num_replica=1,
check_task=CheckTasks.err_res,
check_items=error)
# make growing
if with_growing:
collection_w.insert(cf.gen_default_list_data(nb=200, dim=dim, start=7 * nb))
res, _ = collection_w.insert(cf.gen_default_list_data(nb, dim=dim, start=7 * nb))
insert_ids.extend(res.primary_keys)
# verify search succ
nq = 5
@ -1233,9 +1261,15 @@ class TestResourceGroupMultiNodes(TestcaseBase):
ct.default_limit,
check_task=CheckTasks.check_search_results,
check_items={"nq": nq,
"ids": insert_ids,
"ids": insert_ids.copy(),
"limit": ct.default_limit}
)
self.utility_wrap.transfer_node(source=rgA_name,
target=ct.default_resource_group_name,
num_node=1)
self.utility_wrap.transfer_node(source=rgB_name,
target=ct.default_resource_group_name,
num_node=2)
@pytest.mark.tags(CaseLabel.L0)
def test_transfer_replica_not_enough_replicas_to_transfer(self):
@ -1261,12 +1295,17 @@ class TestResourceGroupMultiNodes(TestcaseBase):
num_node=3)
# transfer 2 replicas to rgA
error = {ct.err_code: 999,
ct.err_msg: 'failed to load collection, err=failed to spawn replica for collection[nodes not enough]'}
error = {ct.err_code: 5,
ct.err_msg: 'only found [1] replicas in source resource group[__default_resource_group]'}
self.utility_wrap.transfer_replica(source=ct.default_resource_group_name, target=rg_name,
collection_name=collection_w.name, num_replica=2,
check_task=CheckTasks.err_res,
check_items=error)
collection_w.release()
collection_w.drop()
self.utility_wrap.transfer_node(source=rg_name,
target=ct.default_resource_group_name,
num_node=3)
@pytest.mark.tags(CaseLabel.L0)
def test_transfer_replica_non_existing_rg(self):
@ -1283,18 +1322,20 @@ class TestResourceGroupMultiNodes(TestcaseBase):
# transfer replica to a non_existing rg
rg_name = "non_existing"
error = {ct.err_code: 999,
ct.err_msg: 'failed to load collection, err=failed to spawn replica for collection[nodes not enough]'}
ct.err_msg: "the target resource group[non_existing] doesn't exist, err=resource group doesn't exist"}
self.utility_wrap.transfer_replica(source=ct.default_resource_group_name,
target=rg_name,
collection_name=collection_w.name,
num_replica=1,
check_task=CheckTasks.err_res,
check_items=error)
# transfer replica from a non_existing rg
error = {ct.err_code: 999,
ct.err_msg: 'failed to load collection, err=failed to spawn replica for collection[nodes not enough]'}
ct.err_msg: "the source resource group[non_existing] doesn't exist, err=resource group doesn't exist"}
self.utility_wrap.transfer_replica(source=rg_name,
target=ct.default_resource_group_name,
collection_name=collection_w.name,
num_replica=1,
check_task=CheckTasks.err_res,
check_items=error)