github.com/weaviate/weaviate@v1.24.6/test/acceptance/grpc/grpc_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 test 13 14 import ( 15 "context" 16 "math/big" 17 "strings" 18 "testing" 19 20 "github.com/stretchr/testify/assert" 21 "github.com/stretchr/testify/require" 22 pb "github.com/weaviate/weaviate/grpc/generated/protocol/v1" 23 "github.com/weaviate/weaviate/test/helper" 24 "github.com/weaviate/weaviate/test/helper/sample-schema/books" 25 "google.golang.org/grpc" 26 "google.golang.org/grpc/health/grpc_health_v1" 27 ) 28 29 func idByte(id string) []byte { 30 hexInteger, _ := new(big.Int).SetString(strings.Replace(id, "-", "", -1), 16) 31 return hexInteger.Bytes() 32 } 33 34 func TestGRPC(t *testing.T) { 35 grpcClient, conn := newClient(t) 36 37 // delete if exists and then re-create Books class 38 booksClass := books.ClassContextionaryVectorizer() 39 helper.DeleteClass(t, booksClass.Class) 40 helper.CreateClass(t, booksClass) 41 defer helper.DeleteClass(t, booksClass.Class) 42 43 t.Run("Health Check", func(t *testing.T) { 44 client := grpc_health_v1.NewHealthClient(conn) 45 check, err := client.Check(context.TODO(), &grpc_health_v1.HealthCheckRequest{}) 46 require.NoError(t, err) 47 require.NotNil(t, check) 48 assert.Equal(t, grpc_health_v1.HealthCheckResponse_SERVING.Enum().Number(), check.Status.Number()) 49 }) 50 51 t.Run("Batch import", func(t *testing.T) { 52 resp, err := grpcClient.BatchObjects(context.TODO(), &pb.BatchObjectsRequest{ 53 Objects: books.BatchObjects(), 54 }) 55 require.NoError(t, err) 56 require.NotNil(t, resp) 57 }) 58 59 tests := []struct { 60 name string 61 req *pb.SearchRequest 62 }{ 63 { 64 name: "Search with props", 65 req: &pb.SearchRequest{ 66 Collection: booksClass.Class, 67 Properties: &pb.PropertiesRequest{ 68 NonRefProperties: []string{"title"}, 69 ObjectProperties: []*pb.ObjectPropertiesRequest{ 70 { 71 PropName: "meta", 72 PrimitiveProperties: []string{"isbn"}, 73 ObjectProperties: []*pb.ObjectPropertiesRequest{ 74 { 75 PropName: "obj", 76 PrimitiveProperties: []string{"text"}, 77 }, 78 { 79 PropName: "objs", 80 PrimitiveProperties: []string{"text"}, 81 }, 82 }, 83 }, 84 {PropName: "reviews", PrimitiveProperties: []string{"tags"}}, 85 }, 86 }, 87 Metadata: &pb.MetadataRequest{ 88 Uuid: true, 89 }, 90 Uses_123Api: true, 91 }, 92 }, 93 { 94 name: "Search without props", 95 req: &pb.SearchRequest{ 96 Collection: booksClass.Class, 97 Metadata: &pb.MetadataRequest{ 98 Uuid: true, 99 }, 100 Uses_123Api: true, 101 }, 102 }, 103 } 104 for _, tt := range tests { 105 t.Run(tt.name, func(t *testing.T) { 106 scifi := "sci-fi" 107 resp, err := grpcClient.Search(context.TODO(), tt.req) 108 require.NoError(t, err) 109 require.NotNil(t, resp) 110 require.NotNil(t, resp.Results) 111 assert.Equal(t, len(books.BatchObjects()), len(resp.Results)) 112 for i := range resp.Results { 113 res := resp.Results[i] 114 id := res.Metadata.Id 115 116 assert.True(t, id == books.Dune.String() || id == books.ProjectHailMary.String() || id == books.TheLordOfTheIceGarden.String()) 117 titleRaw := res.Properties.NonRefProps.Fields["title"] 118 require.NotNil(t, titleRaw) 119 title := titleRaw.GetStringValue() 120 require.NotNil(t, title) 121 122 metaRaw := res.Properties.NonRefProps.Fields["meta"] 123 require.NotNil(t, metaRaw) 124 meta := metaRaw.GetObjectValue() 125 require.NotNil(t, meta) 126 isbnRaw := meta.GetFields()["isbn"] 127 require.NotNil(t, isbnRaw) 128 isbn := isbnRaw.GetStringValue() 129 require.NotNil(t, isbn) 130 131 objRaw := meta.GetFields()["obj"] 132 require.NotNil(t, objRaw) 133 obj := objRaw.GetObjectValue() 134 require.NotNil(t, obj) 135 136 objsRaw := meta.GetFields()["objs"] 137 require.NotNil(t, objsRaw) 138 objs := objsRaw.GetListValue() 139 require.NotNil(t, objs) 140 141 objEntryRaw := objs.Values[0] 142 require.NotNil(t, objEntryRaw) 143 objEntry := objEntryRaw.GetObjectValue() 144 require.NotNil(t, objEntry) 145 146 reviewsRaw := res.Properties.NonRefProps.Fields["reviews"] 147 require.NotNil(t, reviewsRaw) 148 reviews := reviewsRaw.GetListValue() 149 require.NotNil(t, reviews) 150 require.Len(t, reviews.Values, 1) 151 152 review := reviews.Values[0].GetObjectValue() 153 require.NotNil(t, review) 154 155 tags := review.Fields["tags"].GetListValue() 156 require.NotNil(t, tags) 157 158 strTags := make([]string, len(tags.Values)) 159 for i, tag := range tags.Values { 160 strTags[i] = tag.GetStringValue() 161 } 162 163 expectedTitle := "" 164 expectedIsbn := "" 165 expectedTags := []string{} 166 if id == books.Dune.String() { 167 expectedTitle = "Dune" 168 expectedIsbn = "978-0593099322" 169 expectedTags = []string{scifi, "epic"} 170 } 171 if id == books.ProjectHailMary.String() { 172 expectedTitle = "Project Hail Mary" 173 expectedIsbn = "978-0593135204" 174 expectedTags = []string{scifi} 175 } 176 if id == books.TheLordOfTheIceGarden.String() { 177 expectedTitle = "The Lord of the Ice Garden" 178 expectedIsbn = "978-8374812962" 179 expectedTags = []string{scifi, "fantasy"} 180 } 181 assert.Equal(t, expectedTitle, title) 182 assert.Equal(t, expectedIsbn, isbn) 183 assert.Equal(t, expectedTags, strTags) 184 185 expectedObj := &pb.Properties{ 186 Fields: map[string]*pb.Value{ 187 "text": {Kind: &pb.Value_StringValue{StringValue: "some text"}}, 188 }, 189 } 190 assert.Equal(t, expectedObj, obj) 191 assert.Equal(t, expectedObj, objEntry) 192 } 193 }) 194 } 195 196 t.Run("Batch delete", func(t *testing.T) { 197 resp, err := grpcClient.BatchDelete(context.TODO(), &pb.BatchDeleteRequest{ 198 Collection: "Books", 199 Filters: &pb.Filters{Operator: pb.Filters_OPERATOR_EQUAL, TestValue: &pb.Filters_ValueText{ValueText: "Dune"}, Target: &pb.FilterTarget{Target: &pb.FilterTarget_Property{Property: "title"}}}, 200 DryRun: true, 201 Verbose: true, 202 }) 203 require.NoError(t, err) 204 require.NotNil(t, resp) 205 require.Equal(t, resp.Matches, int64(1)) 206 require.Equal(t, resp.Successful, int64(1)) 207 require.Equal(t, resp.Failed, int64(0)) 208 require.Equal(t, resp.Objects[0].Uuid, idByte(books.Dune.String())) 209 }) 210 211 t.Run("gRPC Search removed", func(t *testing.T) { 212 _, err := grpcClient.Search(context.TODO(), &pb.SearchRequest{}) 213 require.NotNil(t, err) 214 }) 215 } 216 217 func newClient(t *testing.T) (pb.WeaviateClient, *grpc.ClientConn) { 218 conn, err := helper.CreateGrpcConnectionClient(":50051") 219 require.NoError(t, err) 220 require.NotNil(t, conn) 221 grpcClient := helper.CreateGrpcWeaviateClient(conn) 222 require.NotNil(t, grpcClient) 223 return grpcClient, conn 224 }