diff --git a/modules/weaviate/examples_test.go b/modules/weaviate/examples_test.go index e9e40481576..7082972de33 100644 --- a/modules/weaviate/examples_test.go +++ b/modules/weaviate/examples_test.go @@ -8,6 +8,7 @@ import ( "time" "github.com/weaviate/weaviate-go-client/v4/weaviate" + "github.com/weaviate/weaviate-go-client/v4/weaviate/grpc" "github.com/testcontainers/testcontainers-go" tcweaviate "github.com/testcontainers/testcontainers-go/modules/weaviate" @@ -17,7 +18,7 @@ func ExampleRunContainer() { // runWeaviateContainer { ctx := context.Background() - weaviateContainer, err := tcweaviate.RunContainer(ctx, testcontainers.WithImage("semitechnologies/weaviate:1.23.9")) + weaviateContainer, err := tcweaviate.RunContainer(ctx, testcontainers.WithImage("semitechnologies/weaviate:1.24.1")) if err != nil { log.Fatalf("failed to start container: %s", err) } @@ -58,7 +59,12 @@ func ExampleRunContainer_connectWithClient() { scheme, host, err := weaviateContainer.HttpHostAddress(ctx) if err != nil { - log.Fatalf("failed to get schema and host: %s", err) // nolint:gocritic + log.Fatalf("failed to get http schema and host: %s", err) // nolint:gocritic + } + + grpcHost, err := weaviateContainer.GrpcHostAddress(ctx) + if err != nil { + log.Fatalf("failed to get gRPC host: %s", err) // nolint:gocritic } connectionClient := &http.Client{} @@ -68,8 +74,12 @@ func ExampleRunContainer_connectWithClient() { } cli := weaviate.New(weaviate.Config{ - Scheme: scheme, - Host: host, + Scheme: scheme, + Host: host, + GrpcConfig: &grpc.Config{ + Secured: false, // set true if gRPC connection is secured + Host: grpcHost, + }, Headers: headers, AuthConfig: nil, // put here the weaviate auth.Config, if you need it ConnectionClient: connectionClient, diff --git a/modules/weaviate/go.mod b/modules/weaviate/go.mod index 9b32ebf5fa2..2871fa164b6 100644 --- a/modules/weaviate/go.mod +++ b/modules/weaviate/go.mod @@ -5,6 +5,7 @@ go 1.21 require ( github.com/testcontainers/testcontainers-go v0.29.1 github.com/weaviate/weaviate-go-client/v4 v4.12.1 + google.golang.org/grpc v1.59.0 ) require ( @@ -76,7 +77,6 @@ require ( golang.org/x/tools v0.13.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect - google.golang.org/grpc v1.59.0 // indirect google.golang.org/protobuf v1.31.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/modules/weaviate/weaviate.go b/modules/weaviate/weaviate.go index 30a196c8a6d..f45e013fce9 100644 --- a/modules/weaviate/weaviate.go +++ b/modules/weaviate/weaviate.go @@ -17,7 +17,7 @@ type WeaviateContainer struct { // RunContainer creates an instance of the Weaviate container type func RunContainer(ctx context.Context, opts ...testcontainers.ContainerCustomizer) (*WeaviateContainer, error) { req := testcontainers.ContainerRequest{ - Image: "semitechnologies/weaviate:1.23.9", + Image: "semitechnologies/weaviate:1.24.1", Cmd: []string{"--host", "0.0.0.0", "--scheme", "http", "--port", "8080"}, ExposedPorts: []string{"8080/tcp", "50051/tcp"}, Env: map[string]string{ @@ -25,7 +25,7 @@ func RunContainer(ctx context.Context, opts ...testcontainers.ContainerCustomize "AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED": "true", "PERSISTENCE_DATA_PATH": "/var/lib/weaviate", "DEFAULT_VECTORIZER_MODULE": "none", - "ENABLE_MODULES": "text2vec-cohere,text2vec-huggingface,text2vec-palm,text2vec-openai,generative-openai,generative-cohere,generative-palm,ref2vec-centroid,reranker-cohere,qna-openai", + "ENABLE_MODULES": "text2vec-cohere,text2vec-huggingface,text2vec-palm,text2vec-openai,text2vec-aws,text2vec-jinaai,generative-openai,generative-cohere,generative-palm,generative-aws,generative-anyscale,ref2vec-centroid,reranker-cohere,qna-openai", "CLUSTER_HOSTNAME": "node1", }, WaitingFor: wait.ForAll( @@ -66,3 +66,19 @@ func (c *WeaviateContainer) HttpHostAddress(ctx context.Context) (string, string return "http", fmt.Sprintf("%s:%s", host, containerPort.Port()), nil } + +// GrpcHostAddress returns the gRPC host of the Weaviate container. +// At the moment, it only supports unsecured gRPC connection. +func (c *WeaviateContainer) GrpcHostAddress(ctx context.Context) (string, error) { + containerPort, err := c.MappedPort(ctx, "50051/tcp") + if err != nil { + return "", fmt.Errorf("failed to get container port: %w", err) + } + + host, err := c.Host(ctx) + if err != nil { + return "", fmt.Errorf("failed to get container host") + } + + return fmt.Sprintf("%s:%s", host, containerPort.Port()), nil +} diff --git a/modules/weaviate/weaviate_test.go b/modules/weaviate/weaviate_test.go index dfde0a7fc16..f400d8ba043 100644 --- a/modules/weaviate/weaviate_test.go +++ b/modules/weaviate/weaviate_test.go @@ -8,12 +8,15 @@ import ( "github.com/testcontainers/testcontainers-go" "github.com/testcontainers/testcontainers-go/modules/weaviate" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" + "google.golang.org/grpc/health/grpc_health_v1" ) func TestWeaviate(t *testing.T) { ctx := context.Background() - container, err := weaviate.RunContainer(ctx, testcontainers.WithImage("semitechnologies/weaviate:1.23.9")) + container, err := weaviate.RunContainer(ctx, testcontainers.WithImage("semitechnologies/weaviate:1.24.1")) if err != nil { t.Fatal(err) } @@ -44,4 +47,29 @@ func TestWeaviate(t *testing.T) { tt.Fatalf("unexpected status code: %d", resp.StatusCode) } }) + + t.Run("GrpcHostAddress", func(tt *testing.T) { + // gRPCHostAddress { + host, err := container.GrpcHostAddress(ctx) + // } + if err != nil { + t.Fatal(err) + } + + var opts []grpc.DialOption + opts = append(opts, grpc.WithBlock()) + opts = append(opts, grpc.WithTransportCredentials(insecure.NewCredentials())) + conn, err := grpc.Dial(host, opts...) + if err != nil { + tt.Fatalf("failed to dial connection: %v", err) + } + client := grpc_health_v1.NewHealthClient(conn) + check, err := client.Check(context.TODO(), &grpc_health_v1.HealthCheckRequest{}) + if err != nil { + tt.Fatalf("failed to get a health check: %v", err) + } + if grpc_health_v1.HealthCheckResponse_SERVING.Enum().Number() != check.Status.Number() { + tt.Fatalf("unexpected status code: %d", check.Status.Number()) + } + }) }