2021-12-02 22:32:42 +08:00
|
|
|
// Licensed to the LF AI & Data foundation 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
|
2021-07-14 11:15:54 +08:00
|
|
|
// with the License. You may obtain a copy of the License at
|
|
|
|
//
|
2021-12-02 22:32:42 +08:00
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
2021-07-14 11:15:54 +08:00
|
|
|
//
|
2021-12-02 22:32:42 +08:00
|
|
|
// 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.
|
2021-07-14 11:15:54 +08:00
|
|
|
|
|
|
|
package querynode
|
|
|
|
|
|
|
|
import (
|
2021-09-15 15:25:49 +08:00
|
|
|
"context"
|
2021-07-14 11:15:54 +08:00
|
|
|
"strconv"
|
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/golang/protobuf/proto"
|
|
|
|
"github.com/milvus-io/milvus/internal/proto/querypb"
|
2021-11-17 12:13:10 +08:00
|
|
|
"github.com/milvus-io/milvus/internal/util"
|
|
|
|
"github.com/stretchr/testify/assert"
|
2021-07-14 11:15:54 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
func TestHistorical_GlobalSealedSegments(t *testing.T) {
|
|
|
|
n := newQueryNodeMock()
|
|
|
|
|
|
|
|
// init meta
|
|
|
|
segmentID := UniqueID(0)
|
|
|
|
partitionID := UniqueID(1)
|
|
|
|
collectionID := UniqueID(2)
|
|
|
|
segmentInfo := &querypb.SegmentInfo{
|
|
|
|
SegmentID: segmentID,
|
|
|
|
CollectionID: collectionID,
|
|
|
|
PartitionID: partitionID,
|
|
|
|
}
|
|
|
|
|
|
|
|
emptySegmentCheck := func() {
|
|
|
|
segmentIDs := n.historical.getGlobalSegmentIDsByCollectionID(collectionID)
|
|
|
|
assert.Equal(t, 0, len(segmentIDs))
|
|
|
|
segmentIDs = n.historical.getGlobalSegmentIDsByPartitionIds([]UniqueID{partitionID})
|
|
|
|
assert.Equal(t, 0, len(segmentIDs))
|
|
|
|
}
|
|
|
|
|
|
|
|
// static test
|
|
|
|
emptySegmentCheck()
|
|
|
|
n.historical.addGlobalSegmentInfo(segmentID, segmentInfo)
|
|
|
|
segmentIDs := n.historical.getGlobalSegmentIDsByCollectionID(collectionID)
|
|
|
|
assert.Equal(t, 1, len(segmentIDs))
|
|
|
|
assert.Equal(t, segmentIDs[0], segmentID)
|
|
|
|
|
|
|
|
segmentIDs = n.historical.getGlobalSegmentIDsByPartitionIds([]UniqueID{partitionID})
|
|
|
|
assert.Equal(t, 1, len(segmentIDs))
|
|
|
|
assert.Equal(t, segmentIDs[0], segmentID)
|
|
|
|
|
|
|
|
n.historical.removeGlobalSegmentInfo(segmentID)
|
|
|
|
emptySegmentCheck()
|
|
|
|
|
|
|
|
n.historical.addGlobalSegmentInfo(segmentID, segmentInfo)
|
|
|
|
n.historical.removeGlobalSegmentIDsByCollectionID(collectionID)
|
|
|
|
emptySegmentCheck()
|
|
|
|
|
|
|
|
n.historical.addGlobalSegmentInfo(segmentID, segmentInfo)
|
|
|
|
n.historical.removeGlobalSegmentIDsByPartitionIds([]UniqueID{partitionID})
|
|
|
|
emptySegmentCheck()
|
|
|
|
|
|
|
|
// watch test
|
|
|
|
go n.historical.watchGlobalSegmentMeta()
|
2021-07-23 19:55:07 +08:00
|
|
|
time.Sleep(100 * time.Millisecond) // for etcd latency
|
2021-09-29 20:26:00 +08:00
|
|
|
segmentInfoBytes, err := proto.Marshal(segmentInfo)
|
|
|
|
assert.Nil(t, err)
|
2021-07-14 11:15:54 +08:00
|
|
|
assert.NotNil(t, n.etcdKV)
|
2021-11-17 12:13:10 +08:00
|
|
|
segmentKey := util.SegmentMetaPrefix + "/" + strconv.FormatInt(segmentID, 10)
|
2021-09-29 20:26:00 +08:00
|
|
|
err = n.etcdKV.Save(segmentKey, string(segmentInfoBytes))
|
2021-07-14 11:15:54 +08:00
|
|
|
assert.NoError(t, err)
|
|
|
|
|
2021-07-23 19:55:07 +08:00
|
|
|
time.Sleep(200 * time.Millisecond) // for etcd latency
|
2021-07-14 11:15:54 +08:00
|
|
|
segmentIDs = n.historical.getGlobalSegmentIDsByCollectionID(collectionID)
|
|
|
|
assert.Equal(t, 1, len(segmentIDs))
|
|
|
|
assert.Equal(t, segmentIDs[0], segmentID)
|
|
|
|
|
|
|
|
segmentIDs = n.historical.getGlobalSegmentIDsByPartitionIds([]UniqueID{partitionID})
|
|
|
|
assert.Equal(t, 1, len(segmentIDs))
|
|
|
|
assert.Equal(t, segmentIDs[0], segmentID)
|
|
|
|
|
|
|
|
err = n.etcdKV.Remove(segmentKey)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
time.Sleep(100 * time.Millisecond) // for etcd latency
|
|
|
|
emptySegmentCheck()
|
|
|
|
}
|
2021-09-15 15:25:49 +08:00
|
|
|
|
|
|
|
func TestHistorical_Search(t *testing.T) {
|
|
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
|
|
defer cancel()
|
|
|
|
|
|
|
|
t.Run("test search", func(t *testing.T) {
|
2021-12-17 14:41:33 +08:00
|
|
|
tSafe := newTSafeReplica()
|
2021-11-06 11:02:58 +08:00
|
|
|
his, err := genSimpleHistorical(ctx, tSafe)
|
2021-09-15 15:25:49 +08:00
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
plan, searchReqs, err := genSimpleSearchPlanAndRequests()
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
2021-12-10 18:51:08 +08:00
|
|
|
_, _, _, err = his.search(searchReqs, defaultCollectionID, []UniqueID{defaultPartitionID}, plan, Timestamp(0))
|
2021-09-15 15:25:49 +08:00
|
|
|
assert.NoError(t, err)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("test no collection - search partitions", func(t *testing.T) {
|
2021-12-17 14:41:33 +08:00
|
|
|
tSafe := newTSafeReplica()
|
2021-11-06 11:02:58 +08:00
|
|
|
his, err := genSimpleHistorical(ctx, tSafe)
|
2021-09-15 15:25:49 +08:00
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
plan, searchReqs, err := genSimpleSearchPlanAndRequests()
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
err = his.replica.removeCollection(defaultCollectionID)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
2021-12-10 18:51:08 +08:00
|
|
|
_, _, _, err = his.search(searchReqs, defaultCollectionID, []UniqueID{}, plan, Timestamp(0))
|
2021-09-15 15:25:49 +08:00
|
|
|
assert.Error(t, err)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("test no collection - search all collection", func(t *testing.T) {
|
2021-12-17 14:41:33 +08:00
|
|
|
tSafe := newTSafeReplica()
|
2021-11-06 11:02:58 +08:00
|
|
|
his, err := genSimpleHistorical(ctx, tSafe)
|
2021-09-15 15:25:49 +08:00
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
plan, searchReqs, err := genSimpleSearchPlanAndRequests()
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
err = his.replica.removeCollection(defaultCollectionID)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
2021-12-10 18:51:08 +08:00
|
|
|
_, _, _, err = his.search(searchReqs, defaultCollectionID, []UniqueID{defaultPartitionID}, plan, Timestamp(0))
|
2021-09-15 15:25:49 +08:00
|
|
|
assert.Error(t, err)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("test load partition and partition has been released", func(t *testing.T) {
|
2021-12-17 14:41:33 +08:00
|
|
|
tSafe := newTSafeReplica()
|
2021-11-06 11:02:58 +08:00
|
|
|
his, err := genSimpleHistorical(ctx, tSafe)
|
2021-09-15 15:25:49 +08:00
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
plan, searchReqs, err := genSimpleSearchPlanAndRequests()
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
col, err := his.replica.getCollectionByID(defaultCollectionID)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
col.setLoadType(loadTypePartition)
|
|
|
|
|
|
|
|
err = his.replica.removePartition(defaultPartitionID)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
2021-12-10 18:51:08 +08:00
|
|
|
_, _, _, err = his.search(searchReqs, defaultCollectionID, []UniqueID{}, plan, Timestamp(0))
|
2021-09-15 15:25:49 +08:00
|
|
|
assert.Error(t, err)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("test no partition in collection", func(t *testing.T) {
|
2021-12-17 14:41:33 +08:00
|
|
|
tSafe := newTSafeReplica()
|
2021-11-06 11:02:58 +08:00
|
|
|
his, err := genSimpleHistorical(ctx, tSafe)
|
2021-09-15 15:25:49 +08:00
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
plan, searchReqs, err := genSimpleSearchPlanAndRequests()
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
err = his.replica.removePartition(defaultPartitionID)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
2021-12-10 18:51:08 +08:00
|
|
|
res, ids, _, err := his.search(searchReqs, defaultCollectionID, []UniqueID{}, plan, Timestamp(0))
|
|
|
|
assert.Equal(t, 0, len(res))
|
|
|
|
assert.Equal(t, 0, len(ids))
|
2021-09-15 15:25:49 +08:00
|
|
|
assert.NoError(t, err)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("test load collection partition released in collection", func(t *testing.T) {
|
2021-12-17 14:41:33 +08:00
|
|
|
tSafe := newTSafeReplica()
|
2021-11-06 11:02:58 +08:00
|
|
|
his, err := genSimpleHistorical(ctx, tSafe)
|
2021-09-15 15:25:49 +08:00
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
plan, searchReqs, err := genSimpleSearchPlanAndRequests()
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
col, err := his.replica.getCollectionByID(defaultCollectionID)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
col.addReleasedPartition(defaultPartitionID)
|
|
|
|
|
|
|
|
err = his.replica.removePartition(defaultPartitionID)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
2021-12-10 18:51:08 +08:00
|
|
|
res, ids, _, err := his.search(searchReqs, defaultCollectionID, []UniqueID{defaultPartitionID}, plan, Timestamp(0))
|
|
|
|
assert.Equal(t, 0, len(res))
|
|
|
|
assert.Equal(t, 0, len(ids))
|
2021-09-15 15:25:49 +08:00
|
|
|
assert.Error(t, err)
|
|
|
|
})
|
|
|
|
}
|