Files
wehub-resource-sync 498b235461
Build and test / Build and test AMD64 Ubuntu 22.04 (push) Failing after 0s
Publish Builder / amazonlinux2023 (push) Failing after 1s
Build and test / UT for Go (push) Has been skipped
Publish KRTE Images / KRTE (push) Failing after 1s
Build and test / Integration Test (push) Has been skipped
Build and test / Upload Code Coverage (push) Has been skipped
Publish Builder / rockylinux9 (push) Failing after 1s
Publish Builder / ubuntu22.04 (push) Failing after 0s
Publish Builder / ubuntu24.04 (push) Failing after 0s
Publish Gpu Builder / publish-gpu-builder (push) Failing after 1s
Publish Test Images / PyTest (push) Failing after 0s
Build and test / UT for Cpp (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:31:17 +08:00

153 lines
4.9 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 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
// 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 pipeline
import (
"testing"
"github.com/samber/lo"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/suite"
"github.com/milvus-io/milvus/internal/querynodev2/delegator"
"github.com/milvus-io/milvus/internal/querynodev2/segments"
"github.com/milvus-io/milvus/internal/storage"
"github.com/milvus-io/milvus/pkg/v3/util/paramtable"
)
type DeleteNodeSuite struct {
suite.Suite
// datas
collectionID int64
collectionName string
partitionIDs []int64
deletePKs []int64
channel string
timeRange TimeRange
// mocks
manager *segments.Manager
delegator *delegator.MockShardDelegator
}
func (suite *DeleteNodeSuite) SetupSuite() {
paramtable.Init()
suite.collectionID = 111
suite.collectionName = "test-collection"
suite.partitionIDs = []int64{11, 22}
suite.channel = "test-channel"
// segment own data row whichs pk same with segments ID
suite.deletePKs = []int64{1, 2, 3, 4}
suite.timeRange = TimeRange{
timestampMin: 0,
timestampMax: 1,
}
}
func (suite *DeleteNodeSuite) buildDeleteNodeMsg() *deleteNodeMsg {
nodeMsg := &deleteNodeMsg{
deleteMsgs: []*DeleteMsg{},
timeRange: suite.timeRange,
}
for i, pk := range suite.deletePKs {
deleteMsg := buildDeleteMsg(suite.collectionID, suite.partitionIDs[i%len(suite.partitionIDs)], suite.channel, 1)
deleteMsg.PrimaryKeys = genDeletePK(pk)
nodeMsg.deleteMsgs = append(nodeMsg.deleteMsgs, deleteMsg)
}
return nodeMsg
}
func (suite *DeleteNodeSuite) TestBasic() {
// mock
mockCollectionManager := segments.NewMockCollectionManager(suite.T())
mockSegmentManager := segments.NewMockSegmentManager(suite.T())
suite.manager = &segments.Manager{
Collection: mockCollectionManager,
Segment: mockSegmentManager,
}
suite.delegator = delegator.NewMockShardDelegator(suite.T())
suite.delegator.EXPECT().ProcessDeleteBatches(mock.Anything).Run(
func(batches []delegator.DeleteBatch) {
for _, data := range batches[0].Data {
for _, pk := range data.PrimaryKeys {
suite.True(lo.Contains(suite.deletePKs, pk.GetValue().(int64)))
}
}
})
// init dependency
// build delete node and data
node := newDeleteNode(suite.collectionID, suite.channel, suite.manager, suite.delegator, 8)
in := suite.buildDeleteNodeMsg()
suite.delegator.EXPECT().UpdateTSafe(in.timeRange.timestampMax).Return()
// run
out := node.Operate(in)
suite.Nil(out)
}
func (suite *DeleteNodeSuite) TestProcessDeleteBatchesUseDeleteMsgEndTs() {
mockCollectionManager := segments.NewMockCollectionManager(suite.T())
mockSegmentManager := segments.NewMockSegmentManager(suite.T())
suite.manager = &segments.Manager{
Collection: mockCollectionManager,
Segment: mockSegmentManager,
}
suite.delegator = delegator.NewMockShardDelegator(suite.T())
first := buildDeleteMsg(suite.collectionID, suite.partitionIDs[0], suite.channel, 1)
first.SetTs(10)
first.PrimaryKeys = genDeletePK(10)
second := buildDeleteMsg(suite.collectionID, suite.partitionIDs[1], suite.channel, 1)
second.SetTs(20)
second.PrimaryKeys = genDeletePK(20)
third := buildDeleteMsg(suite.collectionID, suite.partitionIDs[0], suite.channel, 1)
third.SetTs(10)
third.PrimaryKeys = genDeletePK(30)
in := &deleteNodeMsg{
deleteMsgs: []*DeleteMsg{first, second, third},
timeRange: TimeRange{
timestampMin: 10,
timestampMax: 30,
},
}
suite.delegator.EXPECT().ProcessDeleteBatches(mock.Anything).Run(
func(batches []delegator.DeleteBatch) {
suite.Require().Len(batches, 2)
suite.Equal(uint64(10), batches[0].Ts)
suite.Equal(uint64(20), batches[1].Ts)
suite.Len(batches[0].Data, 1)
suite.Len(batches[1].Data, 1)
suite.ElementsMatch([]int64{10, 30}, lo.Map(batches[0].Data[0].PrimaryKeys, func(pk storage.PrimaryKey, _ int) int64 {
return pk.GetValue().(int64)
}))
suite.ElementsMatch([]int64{20}, lo.Map(batches[1].Data[0].PrimaryKeys, func(pk storage.PrimaryKey, _ int) int64 {
return pk.GetValue().(int64)
}))
})
suite.delegator.EXPECT().UpdateTSafe(uint64(30)).Return()
node := newDeleteNode(suite.collectionID, suite.channel, suite.manager, suite.delegator, 8)
out := node.Operate(in)
suite.Nil(out)
}
func TestDeleteNode(t *testing.T) {
suite.Run(t, new(DeleteNodeSuite))
}