Spaces:
Sleeping
Sleeping
| // _ _ | |
| // __ _____ __ ___ ___ __ _| |_ ___ | |
| // \ \ /\ / / _ \/ _` \ \ / / |/ _` | __/ _ \ | |
| // \ V V / __/ (_| |\ V /| | (_| | || __/ | |
| // \_/\_/ \___|\__,_| \_/ |_|\__,_|\__\___| | |
| // | |
| // Copyright © 2016 - 2024 Weaviate B.V. All rights reserved. | |
| // | |
| // CONTACT: [email protected] | |
| // | |
| package test | |
| import ( | |
| "context" | |
| "math/big" | |
| "strings" | |
| "testing" | |
| "github.com/stretchr/testify/assert" | |
| "github.com/stretchr/testify/require" | |
| pb "github.com/weaviate/weaviate/grpc/generated/protocol/v1" | |
| "github.com/weaviate/weaviate/test/helper" | |
| "github.com/weaviate/weaviate/test/helper/sample-schema/books" | |
| "google.golang.org/grpc/health/grpc_health_v1" | |
| ) | |
| func idByte(id string) []byte { | |
| hexInteger, _ := new(big.Int).SetString(strings.Replace(id, "-", "", -1), 16) | |
| return hexInteger.Bytes() | |
| } | |
| func TestGRPC(t *testing.T) { | |
| conn, err := helper.CreateGrpcConnectionClient(":50051") | |
| require.NoError(t, err) | |
| require.NotNil(t, conn) | |
| grpcClient := helper.CreateGrpcWeaviateClient(conn) | |
| require.NotNil(t, grpcClient) | |
| // delete if exists and then re-create Books class | |
| booksClass := books.ClassContextionaryVectorizer() | |
| helper.DeleteClass(t, booksClass.Class) | |
| helper.CreateClass(t, booksClass) | |
| defer helper.DeleteClass(t, booksClass.Class) | |
| t.Run("Health Check", func(t *testing.T) { | |
| client := grpc_health_v1.NewHealthClient(conn) | |
| check, err := client.Check(context.TODO(), &grpc_health_v1.HealthCheckRequest{}) | |
| require.NoError(t, err) | |
| require.NotNil(t, check) | |
| assert.Equal(t, grpc_health_v1.HealthCheckResponse_SERVING.Enum().Number(), check.Status.Number()) | |
| }) | |
| t.Run("Batch import", func(t *testing.T) { | |
| resp, err := grpcClient.BatchObjects(context.TODO(), &pb.BatchObjectsRequest{ | |
| Objects: books.BatchObjects(), | |
| }) | |
| require.NoError(t, err) | |
| require.NotNil(t, resp) | |
| }) | |
| tests := []struct { | |
| name string | |
| req *pb.SearchRequest | |
| }{ | |
| { | |
| name: "Search with props", | |
| req: &pb.SearchRequest{ | |
| Collection: booksClass.Class, | |
| Properties: &pb.PropertiesRequest{ | |
| NonRefProperties: []string{"title"}, | |
| ObjectProperties: []*pb.ObjectPropertiesRequest{ | |
| { | |
| PropName: "meta", | |
| PrimitiveProperties: []string{"isbn"}, | |
| ObjectProperties: []*pb.ObjectPropertiesRequest{ | |
| { | |
| PropName: "obj", | |
| PrimitiveProperties: []string{"text"}, | |
| }, | |
| { | |
| PropName: "objs", | |
| PrimitiveProperties: []string{"text"}, | |
| }, | |
| }, | |
| }, | |
| {PropName: "reviews", PrimitiveProperties: []string{"tags"}}, | |
| }, | |
| }, | |
| Metadata: &pb.MetadataRequest{ | |
| Uuid: true, | |
| }, | |
| Uses_123Api: true, | |
| }, | |
| }, | |
| { | |
| name: "Search without props", | |
| req: &pb.SearchRequest{ | |
| Collection: booksClass.Class, | |
| Metadata: &pb.MetadataRequest{ | |
| Uuid: true, | |
| }, | |
| Uses_123Api: true, | |
| }, | |
| }, | |
| } | |
| for _, tt := range tests { | |
| t.Run(tt.name, func(t *testing.T) { | |
| scifi := "sci-fi" | |
| resp, err := grpcClient.Search(context.TODO(), tt.req) | |
| require.NoError(t, err) | |
| require.NotNil(t, resp) | |
| require.NotNil(t, resp.Results) | |
| assert.Equal(t, len(books.BatchObjects()), len(resp.Results)) | |
| for i := range resp.Results { | |
| res := resp.Results[i] | |
| id := res.Metadata.Id | |
| assert.True(t, id == books.Dune.String() || id == books.ProjectHailMary.String() || id == books.TheLordOfTheIceGarden.String()) | |
| titleRaw := res.Properties.NonRefProps.Fields["title"] | |
| require.NotNil(t, titleRaw) | |
| title := titleRaw.GetStringValue() | |
| require.NotNil(t, title) | |
| metaRaw := res.Properties.NonRefProps.Fields["meta"] | |
| require.NotNil(t, metaRaw) | |
| meta := metaRaw.GetObjectValue() | |
| require.NotNil(t, meta) | |
| isbnRaw := meta.GetFields()["isbn"] | |
| require.NotNil(t, isbnRaw) | |
| isbn := isbnRaw.GetStringValue() | |
| require.NotNil(t, isbn) | |
| objRaw := meta.GetFields()["obj"] | |
| require.NotNil(t, objRaw) | |
| obj := objRaw.GetObjectValue() | |
| require.NotNil(t, obj) | |
| objsRaw := meta.GetFields()["objs"] | |
| require.NotNil(t, objsRaw) | |
| objs := objsRaw.GetListValue() | |
| require.NotNil(t, objs) | |
| objEntryRaw := objs.Values[0] | |
| require.NotNil(t, objEntryRaw) | |
| objEntry := objEntryRaw.GetObjectValue() | |
| require.NotNil(t, objEntry) | |
| reviewsRaw := res.Properties.NonRefProps.Fields["reviews"] | |
| require.NotNil(t, reviewsRaw) | |
| reviews := reviewsRaw.GetListValue() | |
| require.NotNil(t, reviews) | |
| require.Len(t, reviews.Values, 1) | |
| review := reviews.Values[0].GetObjectValue() | |
| require.NotNil(t, review) | |
| tags := review.Fields["tags"].GetListValue() | |
| require.NotNil(t, tags) | |
| strTags := make([]string, len(tags.Values)) | |
| for i, tag := range tags.Values { | |
| strTags[i] = tag.GetStringValue() | |
| } | |
| expectedTitle := "" | |
| expectedIsbn := "" | |
| expectedTags := []string{} | |
| if id == books.Dune.String() { | |
| expectedTitle = "Dune" | |
| expectedIsbn = "978-0593099322" | |
| expectedTags = []string{scifi, "epic"} | |
| } | |
| if id == books.ProjectHailMary.String() { | |
| expectedTitle = "Project Hail Mary" | |
| expectedIsbn = "978-0593135204" | |
| expectedTags = []string{scifi} | |
| } | |
| if id == books.TheLordOfTheIceGarden.String() { | |
| expectedTitle = "The Lord of the Ice Garden" | |
| expectedIsbn = "978-8374812962" | |
| expectedTags = []string{scifi, "fantasy"} | |
| } | |
| assert.Equal(t, expectedTitle, title) | |
| assert.Equal(t, expectedIsbn, isbn) | |
| assert.Equal(t, expectedTags, strTags) | |
| expectedObj := &pb.Properties{ | |
| Fields: map[string]*pb.Value{ | |
| "text": {Kind: &pb.Value_StringValue{StringValue: "some text"}}, | |
| }, | |
| } | |
| assert.Equal(t, expectedObj, obj) | |
| assert.Equal(t, expectedObj, objEntry) | |
| } | |
| }) | |
| } | |
| t.Run("Batch delete", func(t *testing.T) { | |
| resp, err := grpcClient.BatchDelete(context.TODO(), &pb.BatchDeleteRequest{ | |
| Collection: "Books", | |
| Filters: &pb.Filters{Operator: pb.Filters_OPERATOR_EQUAL, TestValue: &pb.Filters_ValueText{ValueText: "Dune"}, Target: &pb.FilterTarget{Target: &pb.FilterTarget_Property{Property: "title"}}}, | |
| DryRun: true, | |
| Verbose: true, | |
| }) | |
| require.NoError(t, err) | |
| require.NotNil(t, resp) | |
| require.Equal(t, resp.Matches, int64(1)) | |
| require.Equal(t, resp.Successful, int64(1)) | |
| require.Equal(t, resp.Failed, int64(0)) | |
| require.Equal(t, resp.Objects[0].Uuid, idByte(books.Dune.String())) | |
| }) | |
| t.Run("gRPC Search removed", func(t *testing.T) { | |
| _, err := grpcClient.Search(context.TODO(), &pb.SearchRequest{}) | |
| require.NotNil(t, err) | |
| }) | |
| } | |