github.com/weaviate/weaviate@v1.24.6/adapters/handlers/grpc/v1/batch_delete_test.go (about) 1 // _ _ 2 // __ _____ __ ___ ___ __ _| |_ ___ 3 // \ \ /\ / / _ \/ _` \ \ / / |/ _` | __/ _ \ 4 // \ V V / __/ (_| |\ V /| | (_| | || __/ 5 // \_/\_/ \___|\__,_| \_/ |_|\__,_|\__\___| 6 // 7 // Copyright © 2016 - 2024 Weaviate B.V. All rights reserved. 8 // 9 // CONTACT: hello@weaviate.io 10 // 11 12 package v1 13 14 import ( 15 "errors" 16 "fmt" 17 "testing" 18 19 "github.com/stretchr/testify/require" 20 "github.com/weaviate/weaviate/entities/filters" 21 "github.com/weaviate/weaviate/entities/models" 22 "github.com/weaviate/weaviate/entities/schema" 23 pb "github.com/weaviate/weaviate/grpc/generated/protocol/v1" 24 "github.com/weaviate/weaviate/usecases/objects" 25 ) 26 27 func TestBatchDeleteRequest(t *testing.T) { 28 collection := "TestClass" 29 scheme := schema.Schema{ 30 Objects: &models.Schema{ 31 Classes: []*models.Class{ 32 { 33 Class: collection, 34 Properties: []*models.Property{ 35 {Name: "name", DataType: schema.DataTypeText.PropString()}, 36 }, 37 }, 38 }, 39 }, 40 } 41 42 simpleFilterOutput := &filters.LocalFilter{ 43 Root: &filters.Clause{ 44 On: &filters.Path{Class: schema.ClassName(collection), Property: "name"}, 45 Operator: filters.OperatorEqual, 46 Value: &filters.Value{Value: "test", Type: schema.DataTypeText}, 47 }, 48 } 49 simpleFilterInput := &pb.Filters{Operator: pb.Filters_OPERATOR_EQUAL, TestValue: &pb.Filters_ValueText{ValueText: "test"}, Target: &pb.FilterTarget{Target: &pb.FilterTarget_Property{Property: "name"}}} 50 51 tests := []struct { 52 name string 53 req *pb.BatchDeleteRequest 54 out objects.BatchDeleteParams 55 error error 56 }{ 57 { 58 name: "simple filter", 59 req: &pb.BatchDeleteRequest{ 60 Collection: collection, 61 Filters: simpleFilterInput, 62 }, 63 out: objects.BatchDeleteParams{ 64 ClassName: schema.ClassName(collection), 65 DryRun: false, 66 Output: "minimal", 67 Filters: simpleFilterOutput, 68 }, 69 error: nil, 70 }, 71 { 72 name: "collection does not exist", 73 req: &pb.BatchDeleteRequest{Collection: "does not exist"}, 74 error: errors.New("no such class with name 'does not exist' found in the schema. Check your schema files for which classes are available"), 75 }, 76 { 77 name: "no filter", 78 req: &pb.BatchDeleteRequest{Collection: collection}, 79 error: fmt.Errorf("no filters in batch delete request"), 80 }, 81 { 82 name: "dry run", 83 req: &pb.BatchDeleteRequest{ 84 Collection: collection, 85 Filters: simpleFilterInput, 86 DryRun: true, 87 }, 88 out: objects.BatchDeleteParams{ 89 ClassName: schema.ClassName(collection), 90 DryRun: true, 91 Output: "minimal", 92 Filters: simpleFilterOutput, 93 }, 94 error: nil, 95 }, 96 { 97 name: "verbose", 98 req: &pb.BatchDeleteRequest{ 99 Collection: collection, 100 Filters: simpleFilterInput, 101 DryRun: false, 102 Verbose: true, 103 }, 104 out: objects.BatchDeleteParams{ 105 ClassName: schema.ClassName(collection), 106 DryRun: false, 107 Output: "verbose", 108 Filters: simpleFilterOutput, 109 }, 110 error: nil, 111 }, 112 } 113 114 for _, tt := range tests { 115 t.Run(tt.name, func(t *testing.T) { 116 out, err := batchDeleteParamsFromProto(tt.req, scheme) 117 require.Equal(t, tt.error, err) 118 119 if tt.error == nil { 120 require.Equal(t, tt.out, out) 121 } 122 }) 123 } 124 } 125 126 var ( 127 errorString = "error" 128 noErrorString = "" 129 ) 130 131 func TestBatchDeleteReply(t *testing.T) { 132 tests := []struct { 133 name string 134 response objects.BatchDeleteResult 135 verbose bool 136 out *pb.BatchDeleteReply 137 }{ 138 { 139 name: "single object", 140 response: objects.BatchDeleteResult{Matches: 1, Objects: objects.BatchSimpleObjects{{UUID: UUID1, Err: nil}}}, 141 out: &pb.BatchDeleteReply{Matches: 1, Successful: 1, Failed: 0}, 142 }, 143 { 144 name: "single object with err", 145 response: objects.BatchDeleteResult{Matches: 1, Objects: objects.BatchSimpleObjects{{UUID: UUID1, Err: errors.New("error")}}}, 146 out: &pb.BatchDeleteReply{Matches: 1, Successful: 0, Failed: 1}, 147 }, 148 { 149 name: "one error, one successful", 150 response: objects.BatchDeleteResult{Matches: 2, Objects: objects.BatchSimpleObjects{{UUID: UUID1, Err: errors.New("error")}, {UUID: UUID2, Err: nil}}}, 151 out: &pb.BatchDeleteReply{Matches: 2, Successful: 1, Failed: 1}, 152 }, 153 { 154 name: "one error, one successful - with verbosity", 155 response: objects.BatchDeleteResult{Matches: 2, Objects: objects.BatchSimpleObjects{{UUID: UUID1, Err: errors.New("error")}, {UUID: UUID2, Err: nil}}}, 156 verbose: true, 157 out: &pb.BatchDeleteReply{Matches: 2, Successful: 1, Failed: 1, Objects: []*pb.BatchDeleteObject{ 158 {Uuid: idByte(string(UUID1)), Successful: false, Error: &errorString}, 159 {Uuid: idByte(string(UUID2)), Successful: true, Error: &noErrorString}, 160 }}, 161 }, 162 } 163 164 for _, tt := range tests { 165 t.Run(tt.name, func(t *testing.T) { 166 out, err := batchDeleteReplyFromObjects(tt.response, tt.verbose) 167 require.Nil(t, err) 168 require.Equal(t, tt.out, out) 169 }) 170 } 171 }