diff --git a/Directory.Build.props b/Directory.Build.props index 4135923..a5642b3 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -9,7 +9,7 @@ https://github.com/qdrant/qdrant-dotnet https://github.com/qdrant/qdrant-dotnet/releases qdrant, database, vector, search - v1.14.0 + v1.14.1 @@ -21,6 +21,8 @@ enable 1.0 true + $(SolutionRoot)build\keys\keypair.snk + 0024000004800000940000000602000000240000525341310004000001000100ed1d190ea5406d996c0f5b1a8acbf865fab69e948e50f3621ee36a586566357356ccb63d2bddbc967bef647c2ea7e2871c479c4aaf9dc4d4570022e0dd23d2126e60a69600d6d446b64c4413dcd07d92ee208a59f3531afc6a2afd512e8cbbdf8576887a7eaf72933f041e7134f78b358ee97fc66e80c4604c6bad7a5124fcca diff --git a/build/Build.csproj b/build/Build.csproj index c21042f..c055f56 100644 --- a/build/Build.csproj +++ b/build/Build.csproj @@ -8,10 +8,10 @@ - + - + diff --git a/build/Main.cs b/build/Main.cs index a9ccc60..a2f473c 100644 --- a/build/Main.cs +++ b/build/Main.cs @@ -53,7 +53,7 @@ Run("dotnet", "tool restore"); }); - Target(CleanBuildOutput, DependsOn(Restore), () => + Target(CleanBuildOutput, [Restore], () => { Run("dotnet", "clean -c Release -v m --nologo"); }); @@ -129,17 +129,17 @@ } }); - Target(Format, DependsOn(Restore), () => + Target(Format, [Restore], () => { Run("dotnet", "format"); }); - Target(Build, DependsOn(DownloadProtos, CleanBuildOutput, Format), () => + Target(Build, [DownloadProtos, CleanBuildOutput, Format], () => { Run("dotnet", "build -c Release --nologo"); }); - Target(Test, DependsOn(Build), () => + Target(Test, [Build], () => { Run("dotnet", "test -c Release --no-build"); }); @@ -150,14 +150,14 @@ Directory.Delete(packOutput, true); }); - Target(Pack, DependsOn(Build, CleanPackOutput), () => + Target(Pack, [Build, CleanPackOutput], () => { var outputDir = Directory.CreateDirectory(packOutput); Run("dotnet", $"pack src/{project}/{project}.csproj -c Release -o \"{outputDir.FullName}\" --no-build --nologo"); }); - Target(Default, DependsOn(Test)); + Target(Default, [Test]); await RunTargetsAndExitAsync(targets, options, messageOnly: ex => ex is SimpleExec.ExitCodeException); }); diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 41d1c6d..1551268 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -3,10 +3,7 @@ true - true - $(SolutionRoot)build\keys\keypair.snk - nuget-icon.png README.md $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb diff --git a/src/Qdrant.Client/Grpc/Expression.cs b/src/Qdrant.Client/Grpc/Expression.cs index 5e9d5cd..9d05ba8 100644 --- a/src/Qdrant.Client/Grpc/Expression.cs +++ b/src/Qdrant.Client/Grpc/Expression.cs @@ -1,126 +1,126 @@ namespace Qdrant.Client.Grpc { - /// - /// To construct a formula for score boosting. - /// - public partial class Expression - { - /// - /// Implicitly converts a float constant to a new instance of . - /// - public static implicit operator Expression(float constant) => - new() { Constant = constant }; - - /// - /// Implicitly converts a variable name (string) to a new instance of . - /// Used to reference a payload key or a score variable. - /// - public static implicit operator Expression(string variable) => - new() { Variable = variable }; - - /// - /// Implicitly converts a to a new instance of . - /// Evaluates to 1.0 if true, 0.0 if false. - /// - public static implicit operator Expression(Condition condition) => - new() { Condition = condition }; - - /// - /// Implicitly converts a to a new instance of . - /// Represents a geographic distance in meters. - /// - public static implicit operator Expression(GeoDistance geoDistance) => - new() { GeoDistance = geoDistance }; - - /// - /// Converts a date-time constant string to a new instance of . - /// - public static Expression FromDateTime(string dateTime) => - new() { Datetime = dateTime }; - - /// - /// Converts a date-time key string to a new instance of . - /// Used to reference a payload key with date-time values. - /// - public static Expression FromDateTimeKey(string dateTimeKey) => - new() { DatetimeKey = dateTimeKey }; - - /// - /// Converts a to a new instance of . - /// - public static implicit operator Expression(MultExpression mult) => - new() { Mult = mult }; - - /// - /// Implicitly converts a to a new instance of . - /// - public static implicit operator Expression(SumExpression sum) => - new() { Sum = sum }; - - /// - /// Implicitly converts a to a new instance of . - /// - public static implicit operator Expression(DivExpression div) => - new() { Div = div }; - - /// - /// Converts an to a negated expression. - /// - public static Expression FromNeg(Expression expr) => - new() { Neg = expr }; - - /// - /// Converts an to its absolute value. - /// - public static Expression FromAbs(Expression expr) => - new() { Abs = expr }; - - /// - /// Converts an to its square root. - /// - public static Expression FromSqrt(Expression expr) => - new() { Sqrt = expr }; - - /// - /// Implicitly converts a to an . - /// - public static implicit operator Expression(PowExpression pow) => - new() { Pow = pow }; - - /// - /// Converts an to an exponential. - /// - public static Expression FromExp(Expression expr) => - new() { Exp = expr }; - - /// - /// Converts an to a base-10 logarithm. - /// - public static Expression FromLog10(Expression expr) => - new() { Log10 = expr }; - - /// - /// Converts an to a natural logarithm. - /// - public static Expression FromLn(Expression expr) => - new() { Ln = expr }; - - /// - /// Converts an exponential decay parameter to a new instance of . - /// - public static Expression FromExpDecay(DecayParamsExpression decay) => - new() { ExpDecay = decay }; - - /// - /// Converts a Gaussian decay parameter to a new instance of . - /// - public static Expression FromGaussDecay(DecayParamsExpression decay) => - new() { GaussDecay = decay }; - - /// - /// Converts a linear decay parameter to a new instance of . - /// - public static Expression FromLinDecay(DecayParamsExpression decay) => - new() { LinDecay = decay }; - } + /// + /// To construct a formula for score boosting. + /// + public partial class Expression + { + /// + /// Implicitly converts a float constant to a new instance of . + /// + public static implicit operator Expression(float constant) => + new() { Constant = constant }; + + /// + /// Implicitly converts a variable name (string) to a new instance of . + /// Used to reference a payload key or a score variable. + /// + public static implicit operator Expression(string variable) => + new() { Variable = variable }; + + /// + /// Implicitly converts a to a new instance of . + /// Evaluates to 1.0 if true, 0.0 if false. + /// + public static implicit operator Expression(Condition condition) => + new() { Condition = condition }; + + /// + /// Implicitly converts a to a new instance of . + /// Represents a geographic distance in meters. + /// + public static implicit operator Expression(GeoDistance geoDistance) => + new() { GeoDistance = geoDistance }; + + /// + /// Converts a date-time constant string to a new instance of . + /// + public static Expression FromDateTime(string dateTime) => + new() { Datetime = dateTime }; + + /// + /// Converts a date-time key string to a new instance of . + /// Used to reference a payload key with date-time values. + /// + public static Expression FromDateTimeKey(string dateTimeKey) => + new() { DatetimeKey = dateTimeKey }; + + /// + /// Converts a to a new instance of . + /// + public static implicit operator Expression(MultExpression mult) => + new() { Mult = mult }; + + /// + /// Implicitly converts a to a new instance of . + /// + public static implicit operator Expression(SumExpression sum) => + new() { Sum = sum }; + + /// + /// Implicitly converts a to a new instance of . + /// + public static implicit operator Expression(DivExpression div) => + new() { Div = div }; + + /// + /// Converts an to a negated expression. + /// + public static Expression FromNeg(Expression expr) => + new() { Neg = expr }; + + /// + /// Converts an to its absolute value. + /// + public static Expression FromAbs(Expression expr) => + new() { Abs = expr }; + + /// + /// Converts an to its square root. + /// + public static Expression FromSqrt(Expression expr) => + new() { Sqrt = expr }; + + /// + /// Implicitly converts a to an . + /// + public static implicit operator Expression(PowExpression pow) => + new() { Pow = pow }; + + /// + /// Converts an to an exponential. + /// + public static Expression FromExp(Expression expr) => + new() { Exp = expr }; + + /// + /// Converts an to a base-10 logarithm. + /// + public static Expression FromLog10(Expression expr) => + new() { Log10 = expr }; + + /// + /// Converts an to a natural logarithm. + /// + public static Expression FromLn(Expression expr) => + new() { Ln = expr }; + + /// + /// Converts an exponential decay parameter to a new instance of . + /// + public static Expression FromExpDecay(DecayParamsExpression decay) => + new() { ExpDecay = decay }; + + /// + /// Converts a Gaussian decay parameter to a new instance of . + /// + public static Expression FromGaussDecay(DecayParamsExpression decay) => + new() { GaussDecay = decay }; + + /// + /// Converts a linear decay parameter to a new instance of . + /// + public static Expression FromLinDecay(DecayParamsExpression decay) => + new() { LinDecay = decay }; + } } diff --git a/src/Qdrant.Client/Grpc/PointId.cs b/src/Qdrant.Client/Grpc/PointId.cs index 3aa512d..08c4503 100644 --- a/src/Qdrant.Client/Grpc/PointId.cs +++ b/src/Qdrant.Client/Grpc/PointId.cs @@ -6,7 +6,7 @@ namespace Qdrant.Client.Grpc; public partial class PointId { /// - /// Implicitly converts a ulong to a new instance of + /// Implicitly converts an to a new instance of /// /// the id /// a new instance of diff --git a/src/Qdrant.Client/Grpc/QdrantGrpcClient.cs b/src/Qdrant.Client/Grpc/QdrantGrpcClient.cs index d87bc2a..20454ce 100644 --- a/src/Qdrant.Client/Grpc/QdrantGrpcClient.cs +++ b/src/Qdrant.Client/Grpc/QdrantGrpcClient.cs @@ -85,10 +85,23 @@ protected QdrantGrpcClient() : this(new UnimplementedCallInvoker()) /// public void Dispose() { - if (_isDisposed) - return; + Dispose(disposing: true); + GC.SuppressFinalize(this); + } + + /// + /// Releases the resources used by the current instance of . + /// + /// Indicates whether the method is called from + /// or a finalizer. + protected virtual void Dispose(bool disposing) + { + if (!_isDisposed) + { + _isDisposed = true; - _ownedChannel?.Dispose(); - _isDisposed = true; + if (disposing) + _ownedChannel?.Dispose(); + } } } diff --git a/src/Qdrant.Client/Grpc/Query.cs b/src/Qdrant.Client/Grpc/Query.cs index a28151f..d14b10f 100644 --- a/src/Qdrant.Client/Grpc/Query.cs +++ b/src/Qdrant.Client/Grpc/Query.cs @@ -96,7 +96,7 @@ public partial class Query /// /// the array of floats /// a new instance of - public static implicit operator Query(float[] values) => (VectorInput)values; + public static implicit operator Query(float[] values) => new() { Nearest = (VectorInput)values }; /// /// Implicitly converts a tuple of sparse values array of @@ -104,14 +104,14 @@ public partial class Query /// /// a tuple of arrays of values and indices /// a new instance of - public static implicit operator Query((float[], uint[]) sparseValues) => (VectorInput)sparseValues; + public static implicit operator Query((float[], uint[]) sparseValues) => new() { Nearest = (VectorInput)sparseValues }; /// /// Implicitly converts an array of sparse value index tuples to a new instance of /// /// the array of value-index pairs /// a new instance of - public static implicit operator Query((float, uint)[] sparseValues) => (VectorInput)sparseValues; + public static implicit operator Query((float, uint)[] sparseValues) => new() { Nearest = (VectorInput)sparseValues }; /// /// Implicitly converts a nested array of representing a multi-vector @@ -119,7 +119,27 @@ public partial class Query /// /// the array of floats /// a new instance of - public static implicit operator Query(float[][] values) => (VectorInput)values; + public static implicit operator Query(float[][] values) => new() { Nearest = (VectorInput)values }; + + /// + /// Implicitly converts an instance of to a new instance of for cloud inference. + /// + /// An instance of to query against + /// a new instance of + public static implicit operator Query(Document document) => new() { Nearest = (VectorInput)document }; + + /// + /// Implicitly converts an instance of to a new instance of for cloud inference. + /// + /// An instance of to query against + public static implicit operator Query(Image image) => new() { Nearest = (VectorInput)image }; + + /// + /// Implicitly converts an instance of to a new instance of for cloud inference. + /// + /// An instance of to query against + /// a new instance of + public static implicit operator Query(InferenceObject inferenceObject) => new() { Nearest = (VectorInput)inferenceObject }; #endregion } diff --git a/src/Qdrant.Client/Grpc/Vector.cs b/src/Qdrant.Client/Grpc/Vector.cs index a1837a9..e584f87 100644 --- a/src/Qdrant.Client/Grpc/Vector.cs +++ b/src/Qdrant.Client/Grpc/Vector.cs @@ -53,4 +53,35 @@ public static implicit operator Vector(float[][] values) }; } + + /// + /// Implicitly converts an instance of to a new instance of for cloud inference. + /// + /// An instance of to vectorize + /// a new instance of + public static implicit operator Vector(Document document) => new() + { + Document = document, + }; + + + /// + /// Implicitly converts an instance of to a new instance of for cloud inference. + /// + /// An instance of to vectorize + /// a new instance of + public static implicit operator Vector(Image image) => new() + { + Image = image, + }; + + /// + /// Implicitly converts an instance of to a new instance of for cloud inference. + /// + /// An instance of to vectorize + /// a new instance of + public static implicit operator Vector(InferenceObject inferenceObject) => new() + { + Object = inferenceObject, + }; } diff --git a/src/Qdrant.Client/Grpc/VectorInput.cs b/src/Qdrant.Client/Grpc/VectorInput.cs index 17a7c72..29db55c 100644 --- a/src/Qdrant.Client/Grpc/VectorInput.cs +++ b/src/Qdrant.Client/Grpc/VectorInput.cs @@ -85,33 +85,33 @@ public static implicit operator VectorInput(float[][] values) Id = id }; - // /// - // /// Implicitly converts a to a new instance of - // /// - // /// an instance of - // /// a new instance of - // public static implicit operator VectorInput(Document document) => new() - // { - // Document = document - // }; + /// + /// Implicitly converts a to a new instance of for cloud inference. + /// + /// an instance of + /// a new instance of + public static implicit operator VectorInput(Document document) => new() + { + Document = document + }; - // /// - // /// Implicitly converts an to a new instance of - // /// - // /// an instance of - // /// a new instance of - // public static implicit operator VectorInput(Image image) => new() - // { - // Image = image - // }; + /// + /// Implicitly converts an to a new instance of for cloud inference. + /// + /// an instance of + /// a new instance of + public static implicit operator VectorInput(Image image) => new() + { + Image = image + }; - // /// - // /// Implicitly converts an to a new instance of - // /// - // /// an instance of - // /// a new instance of - // public static implicit operator VectorInput(InferenceObject obj) => new() - // { - // Object = obj - // }; + /// + /// Implicitly converts an to a new instance of for cloud inference. + /// + /// an instance of + /// a new instance of + public static implicit operator VectorInput(InferenceObject @object) => new() + { + Object = @object + }; } diff --git a/src/Qdrant.Client/Grpc/Vectors.cs b/src/Qdrant.Client/Grpc/Vectors.cs index cd1173a..788128c 100644 --- a/src/Qdrant.Client/Grpc/Vectors.cs +++ b/src/Qdrant.Client/Grpc/Vectors.cs @@ -54,4 +54,35 @@ public static implicit operator Vectors((string, Vector) value) var namedVectors = new NamedVectors { Vectors = { [value.Item1] = value.Item2 } }; return new Vectors { Vectors_ = namedVectors }; } + + /// + /// Implicitly converts an instance of to a new instance of for cloud inference. + /// + /// An instance of to vectorize + /// a new instance of + public static implicit operator Vectors(Document document) => new() + { + Vector = document, + }; + + + /// + /// Implicitly converts an instance of to a new instance of for cloud inference. + /// + /// An instance of to vectorize + /// /// a new instance of + public static implicit operator Vectors(Image image) => new() + { + Vector = image, + }; + + /// + /// Implicitly converts an instance of to a new instance of for cloud inference. + /// + /// An instance of to vectorize + /// a new instance of + public static implicit operator Vectors(InferenceObject inferenceObject) => new() + { + Vector = inferenceObject, + }; } diff --git a/src/Qdrant.Client/Qdrant.Client.csproj b/src/Qdrant.Client/Qdrant.Client.csproj index 5d06cfe..b115010 100644 --- a/src/Qdrant.Client/Qdrant.Client.csproj +++ b/src/Qdrant.Client/Qdrant.Client.csproj @@ -8,9 +8,9 @@ - - - + + + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -20,7 +20,10 @@ - + + + + DeleteAsync( return DeleteAsync(collectionName, new PointsSelector { Points = idsList }, wait, ordering, shardKeySelector, cancellationToken); } + /// + /// Delete a point. + /// + /// The name of the collection. + /// The IDs to delete. + /// Whether to wait until the changes have been applied. Defaults to true. + /// Write ordering guarantees. Defaults to Weak. + /// Option for custom sharding to specify used shard keys. + /// + /// The token to monitor for cancellation requests. The default value is . + /// + public Task DeleteAsync( + string collectionName, + PointId id, + bool wait = true, + WriteOrderingType? ordering = null, + ShardKeySelector? shardKeySelector = null, + CancellationToken cancellationToken = default) + => DeleteAsync(collectionName, + new PointsSelector { Points = new PointsIdsList { Ids = { id } } }, + wait, + ordering, + shardKeySelector, + cancellationToken); + + /// + /// Delete points. + /// + /// The name of the collection. + /// The IDs to delete. + /// Whether to wait until the changes have been applied. Defaults to true. + /// Write ordering guarantees. Defaults to Weak. + /// Option for custom sharding to specify used shard keys. + /// + /// The token to monitor for cancellation requests. The default value is . + /// + public Task DeleteAsync( + string collectionName, + IReadOnlyList ids, + bool wait = true, + WriteOrderingType? ordering = null, + ShardKeySelector? shardKeySelector = null, + CancellationToken cancellationToken = default) + { + var idsList = new PointsIdsList(); + idsList.Ids.AddRange(ids); + + return DeleteAsync(collectionName, new PointsSelector { Points = idsList }, wait, ordering, shardKeySelector, cancellationToken); + } + /// /// Delete points. /// @@ -1184,6 +1234,35 @@ private async Task DeleteAsync( } } + /// + /// Retrieve a point. + /// + /// The name of the collection. + /// The ID of a point to retrieve. + /// Whether to include the payload or not. + /// Whether to include the vectors or not. + /// Options for specifying read consistency guarantees. + /// Option for custom sharding to specify used shard keys. + /// + /// The token to monitor for cancellation requests. The default value is . + /// + public Task> RetrieveAsync( + string collectionName, + PointId id, + bool withPayload = true, + bool withVectors = false, + ReadConsistency? readConsistency = null, + ShardKeySelector? shardKeySelector = null, + CancellationToken cancellationToken = default) + => RetrieveAsync( + collectionName, + new[] { id }, + new WithPayloadSelector { Enable = withPayload }, + new WithVectorsSelector { Enable = withVectors }, + readConsistency, + shardKeySelector, + cancellationToken); + /// /// Retrieve a point. /// @@ -2372,19 +2451,7 @@ public async Task CreatePayloadIndexAsync( CollectionName = collectionName, FieldName = fieldName, Wait = wait, - FieldType = schemaType switch - { - PayloadSchemaType.Keyword => FieldType.Keyword, - PayloadSchemaType.Integer => FieldType.Integer, - PayloadSchemaType.Float => FieldType.Float, - PayloadSchemaType.Bool => FieldType.Bool, - PayloadSchemaType.Geo => FieldType.Geo, - PayloadSchemaType.Text => FieldType.Text, - PayloadSchemaType.Datetime => FieldType.Datetime, - PayloadSchemaType.Uuid => FieldType.Uuid, - - _ => throw new ArgumentException("Invalid PayloadSchemaType: " + schemaType, nameof(schemaType)) - } + FieldType = FieldTypeFromPayloadSchemaType(schemaType) }; if (indexParams is not null) @@ -4000,7 +4067,7 @@ public async Task CreateSnapshotAsync(string collectionName /// Universally query points. /// Covers all capabilities of search, recommend, discover, filters. /// Also enables hybrid and multi-stage queries. - /// + /// /// /// The name of the collection. /// Query to perform. If missing, returns points ordered by their IDs. @@ -4100,7 +4167,7 @@ public async Task> QueryAsync( /// Universally query points in batch. /// Covers all capabilities of search, recommend, discover, filters. /// Also enables hybrid and multi-stage queries. - /// + /// /// /// The name of the collection. /// The queries to be performed in the batch. @@ -4153,7 +4220,7 @@ public async Task> QueryBatchAsync( /// Universally query points. /// Covers all capabilities of search, recommend, discover, filters. /// Grouped by a payload field. - /// + /// /// /// The name of the collection. /// Payload field to group by, must be a string or number field. @@ -4521,6 +4588,21 @@ await _grpcClient.Qdrant.HealthCheckAsync( deadline: _grpcTimeout == default ? null : DateTime.UtcNow.Add(_grpcTimeout), cancellationToken: cancellationToken).ConfigureAwait(false); + internal static FieldType FieldTypeFromPayloadSchemaType(PayloadSchemaType schemaType) => + schemaType switch + { + PayloadSchemaType.Keyword => FieldType.Keyword, + PayloadSchemaType.Integer => FieldType.Integer, + PayloadSchemaType.Float => FieldType.Float, + PayloadSchemaType.Bool => FieldType.Bool, + PayloadSchemaType.Geo => FieldType.Geo, + PayloadSchemaType.Text => FieldType.Text, + PayloadSchemaType.Datetime => FieldType.Datetime, + PayloadSchemaType.Uuid => FieldType.Uuid, + + _ => throw new ArgumentException("Invalid PayloadSchemaType: " + schemaType, nameof(schemaType)) + }; + private static void Populate(RepeatedField repeatedField, ReadOnlyMemory memory) { if (MemoryMarshal.TryGetArray(memory, out var segment) && @@ -4549,12 +4631,23 @@ private static ulong ConvertTimeout(TimeSpan? timeout) /// public void Dispose() { - if (_isDisposed) - return; + Dispose(true); + GC.SuppressFinalize(this); + } - if (_ownsGrpcClient) - _grpcClient.Dispose(); + /// + /// Releases the resources used by the current instance of . + /// + /// Indicates whether the method is called from + /// or a finalizer. + protected virtual void Dispose(bool disposing) + { + if (!_isDisposed) + { + _isDisposed = true; - _isDisposed = true; + if (disposing && _ownsGrpcClient) + _grpcClient.Dispose(); + } } } diff --git a/tests/Directory.Build.props b/tests/Directory.Build.props new file mode 100644 index 0000000..fd9898a --- /dev/null +++ b/tests/Directory.Build.props @@ -0,0 +1,7 @@ + + + + + true + + diff --git a/tests/Qdrant.Client.Tests/Container/QdrantBuilder.cs b/tests/Qdrant.Client.Tests/Container/QdrantBuilder.cs deleted file mode 100644 index bc682aa..0000000 --- a/tests/Qdrant.Client.Tests/Container/QdrantBuilder.cs +++ /dev/null @@ -1,55 +0,0 @@ -using Docker.DotNet.Models; -using DotNet.Testcontainers.Builders; -using DotNet.Testcontainers.Configurations; -using Qdrant.Client.Grpc; - -namespace Qdrant.Client.Tests.Container; - -public sealed class QdrantBuilder : ContainerBuilder -{ - public const string QdrantImage = "qdrant/qdrant:" + QdrantGrpcClient.QdrantVersion; - - public const ushort QdrantHttpPort = 6333; - - public const ushort QdrantGrpcPort = 6334; - - public QdrantBuilder() : this(new QdrantConfiguration()) => - DockerResourceConfiguration = Init().DockerResourceConfiguration; - - private QdrantBuilder(QdrantConfiguration dockerResourceConfiguration) : base(dockerResourceConfiguration) => - DockerResourceConfiguration = dockerResourceConfiguration; - - public QdrantBuilder WithConfigFile(string configPath) => - Merge(DockerResourceConfiguration, new QdrantConfiguration()) - .WithBindMount(configPath, "/qdrant/config/custom_config.yaml"); - - public QdrantBuilder WithCertificate(string certPath, string keyPath) => - Merge(DockerResourceConfiguration, new QdrantConfiguration()) - .WithBindMount(certPath, "/qdrant/tls/cert.pem") - .WithBindMount(keyPath, "/qdrant/tls/key.pem"); - - public override QdrantContainer Build() - { - Validate(); - return new QdrantContainer(DockerResourceConfiguration); - } - - protected override QdrantBuilder Init() => - base.Init() - .WithImage(QdrantImage) - .WithPortBinding(QdrantHttpPort, true) - .WithPortBinding(QdrantGrpcPort, true) - .WithWaitStrategy(Wait.ForUnixContainer() - .UntilMessageIsLogged(".*Actix runtime found; starting in Actix runtime.*")); - - protected override QdrantBuilder Clone(IResourceConfiguration resourceConfiguration) => - Merge(DockerResourceConfiguration, new QdrantConfiguration(resourceConfiguration)); - - protected override QdrantBuilder Merge(QdrantConfiguration oldValue, QdrantConfiguration newValue) => - new(new QdrantConfiguration(oldValue, newValue)); - - protected override QdrantConfiguration DockerResourceConfiguration { get; } - - protected override QdrantBuilder Clone(IContainerConfiguration resourceConfiguration) => - Merge(DockerResourceConfiguration, new QdrantConfiguration(resourceConfiguration)); -} diff --git a/tests/Qdrant.Client.Tests/Container/QdrantConfiguration.cs b/tests/Qdrant.Client.Tests/Container/QdrantConfiguration.cs deleted file mode 100644 index 743e82f..0000000 --- a/tests/Qdrant.Client.Tests/Container/QdrantConfiguration.cs +++ /dev/null @@ -1,52 +0,0 @@ -using Docker.DotNet.Models; -using DotNet.Testcontainers.Builders; -using DotNet.Testcontainers.Configurations; - -namespace Qdrant.Client.Tests.Container; - -public sealed class QdrantConfiguration : ContainerConfiguration -{ - /// - /// Initializes a new instance of the class. - /// - public QdrantConfiguration() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The Docker resource configuration. - public QdrantConfiguration(IResourceConfiguration resourceConfiguration) - : base(resourceConfiguration) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The Docker resource configuration. - public QdrantConfiguration(IContainerConfiguration resourceConfiguration) - : base(resourceConfiguration) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The Docker resource configuration. - public QdrantConfiguration(QdrantConfiguration resourceConfiguration) - : this(new QdrantConfiguration(), resourceConfiguration) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The old Docker resource configuration. - /// The new Docker resource configuration. - public QdrantConfiguration(QdrantConfiguration oldValue, QdrantConfiguration newValue) - : base(oldValue, newValue) - { - } -} diff --git a/tests/Qdrant.Client.Tests/Container/QdrantContainer.cs b/tests/Qdrant.Client.Tests/Container/QdrantContainer.cs deleted file mode 100644 index 4434087..0000000 --- a/tests/Qdrant.Client.Tests/Container/QdrantContainer.cs +++ /dev/null @@ -1,11 +0,0 @@ -using DotNet.Testcontainers.Containers; -using Microsoft.Extensions.Logging; - -namespace Qdrant.Client.Tests.Container; - -public class QdrantContainer : DockerContainer -{ - public QdrantContainer(QdrantConfiguration configuration) : base(configuration) - { - } -} diff --git a/tests/Qdrant.Client.Tests/Grpc/GrpcHealthTests.cs b/tests/Qdrant.Client.Tests/Grpc/GrpcHealthTests.cs index c3b8a97..386ad1f 100644 --- a/tests/Qdrant.Client.Tests/Grpc/GrpcHealthTests.cs +++ b/tests/Qdrant.Client.Tests/Grpc/GrpcHealthTests.cs @@ -1,7 +1,4 @@ using FluentAssertions; -using Qdrant.Client; -using Qdrant.Client.Grpc; -using Qdrant.Client.Tests; using Xunit; namespace Qdrant.Client.Grpc; diff --git a/tests/Qdrant.Client.Tests/Qdrant.Client.Tests.csproj b/tests/Qdrant.Client.Tests/Qdrant.Client.Tests.csproj index 55e9627..7a86765 100644 --- a/tests/Qdrant.Client.Tests/Qdrant.Client.Tests.csproj +++ b/tests/Qdrant.Client.Tests/Qdrant.Client.Tests.csproj @@ -9,11 +9,12 @@ - + + - - + + all runtime; build; native; contentfiles; analyzers @@ -22,7 +23,7 @@ - + diff --git a/tests/Qdrant.Client.Tests/QdrantFixture.cs b/tests/Qdrant.Client.Tests/QdrantFixture.cs index 8f9039f..bf654d9 100644 --- a/tests/Qdrant.Client.Tests/QdrantFixture.cs +++ b/tests/Qdrant.Client.Tests/QdrantFixture.cs @@ -4,8 +4,9 @@ using Grpc.Net.Client; #endif +using System.Text; using Qdrant.Client.Grpc; -using Qdrant.Client.Tests.Container; +using Testcontainers.Qdrant; using Xunit; namespace Qdrant.Client; @@ -21,14 +22,19 @@ public QdrantFixture() => #if NETFRAMEWORK // .NET Framework must use TLS with HTTPS _container = new QdrantBuilder() - .WithConfigFile(Path.Combine(SolutionPaths.Root, "tests/config.yaml")) + .WithImage("qdrant/qdrant:" + QdrantGrpcClient.QdrantVersion) + .WithBindMount( + Path.Combine(SolutionPaths.Root, "tests/config.yaml"), + "/qdrant/config/custom_config.yaml") .WithCertificate( - Path.Combine(SolutionPaths.Root, "tests/cert.pem"), - Path.Combine(SolutionPaths.Root, "tests/key.pem")) + File.ReadAllText(Path.Combine(SolutionPaths.Root, "tests/cert.pem"), Encoding.UTF8), + File.ReadAllText(Path.Combine(SolutionPaths.Root, "tests/key.pem"), Encoding.UTF8)) .WithCommand("./entrypoint.sh", "--config-path", "config/custom_config.yaml") .Build(); #else - _container = new QdrantBuilder().Build(); + _container = new QdrantBuilder() + .WithImage("qdrant/qdrant:" + QdrantGrpcClient.QdrantVersion) + .Build(); #endif diff --git a/tests/Qdrant.Client.Tests/QdrantSecuredFixture.cs b/tests/Qdrant.Client.Tests/QdrantSecuredFixture.cs index 32a2a84..509e138 100644 --- a/tests/Qdrant.Client.Tests/QdrantSecuredFixture.cs +++ b/tests/Qdrant.Client.Tests/QdrantSecuredFixture.cs @@ -1,4 +1,6 @@ -using Qdrant.Client.Tests.Container; +using System.Text; +using Qdrant.Client.Grpc; +using Testcontainers.Qdrant; using Xunit; namespace Qdrant.Client; @@ -9,10 +11,13 @@ public sealed class QdrantSecuredCollection : ICollectionFixture + { + var fieldType = QdrantClient.FieldTypeFromPayloadSchemaType(schemaType); + }); + + Assert.Null(ex); + } + } +}