diff --git a/src/Aspire.Hosting.Qdrant/QdrantBuilderExtensions.cs b/src/Aspire.Hosting.Qdrant/QdrantBuilderExtensions.cs index 9688528b607..74174ca5881 100644 --- a/src/Aspire.Hosting.Qdrant/QdrantBuilderExtensions.cs +++ b/src/Aspire.Hosting.Qdrant/QdrantBuilderExtensions.cs @@ -36,6 +36,9 @@ public static IResourceBuilder AddQdrant(this IDistributed int? grpcPort = null, int? httpPort = null) { + ArgumentNullException.ThrowIfNull(builder); + ArgumentNullException.ThrowIfNull(name); + var apiKeyParameter = apiKey?.Resource ?? ParameterResourceBuilderExtensions.CreateDefaultPasswordParameter(builder, $"{name}-Key", special: false); var qdrant = new QdrantServerResource(name, apiKeyParameter); @@ -69,7 +72,12 @@ public static IResourceBuilder AddQdrant(this IDistributed /// A flag that indicates if this is a read-only volume. /// The . public static IResourceBuilder WithDataVolume(this IResourceBuilder builder, string? name = null, bool isReadOnly = false) - => builder.WithVolume(name ?? VolumeNameGenerator.CreateVolumeName(builder, "data"), "/qdrant/storage", isReadOnly); + { + ArgumentNullException.ThrowIfNull(builder); + + return builder.WithVolume(name ?? VolumeNameGenerator.CreateVolumeName(builder, "data"), "/qdrant/storage", + isReadOnly); + } /// /// Adds a bind mount for the data folder to a Qdrant container resource. @@ -79,7 +87,12 @@ public static IResourceBuilder WithDataVolume(this IResour /// A flag that indicates if this is a read-only mount. /// The . public static IResourceBuilder WithDataBindMount(this IResourceBuilder builder, string source, bool isReadOnly = false) - => builder.WithBindMount(source, "/qdrant/storage", isReadOnly); + { + ArgumentNullException.ThrowIfNull(builder); + ArgumentNullException.ThrowIfNull(source); + + return builder.WithBindMount(source, "/qdrant/storage", isReadOnly); + } /// /// Add a reference to a Qdrant server to the resource. @@ -90,6 +103,9 @@ public static IResourceBuilder WithDataBindMount(this IRes public static IResourceBuilder WithReference(this IResourceBuilder builder, IResourceBuilder qdrantResource) where TDestination : IResourceWithEnvironment { + ArgumentNullException.ThrowIfNull(builder); + ArgumentNullException.ThrowIfNull(qdrantResource); + builder.WithEnvironment(context => { // primary endpoint (gRPC) diff --git a/tests/Aspire.Hosting.Qdrant.Tests/QdrantPublicApiTests.cs b/tests/Aspire.Hosting.Qdrant.Tests/QdrantPublicApiTests.cs new file mode 100644 index 00000000000..3b5e07b8092 --- /dev/null +++ b/tests/Aspire.Hosting.Qdrant.Tests/QdrantPublicApiTests.cs @@ -0,0 +1,123 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Aspire.Hosting.ApplicationModel; +using Aspire.Hosting.Utils; +using Xunit; + +namespace Aspire.Hosting.Qdrant.Tests; + +public class QdrantPublicApiTests +{ + [Fact] + public void AddQdrantContainerShouldThrowWhenBuilderIsNull() + { + IDistributedApplicationBuilder builder = null!; + const string name = "Qdrant"; + + var action = () => builder.AddQdrant(name); + + var exception = Assert.Throws(action); + Assert.Equal(nameof(builder), exception.ParamName); + } + + [Fact] + public void AddQdrantContainerShouldThrowWhenNameIsNull() + { + var builder = DistributedApplication.CreateBuilder([]); + string name = null!; + + var action = () => builder.AddQdrant(name); + + var exception = Assert.Throws(action); + Assert.Equal(nameof(name), exception.ParamName); + } + + [Fact] + public void WithDataVolumeShouldThrowWhenBuilderIsNull() + { + IResourceBuilder builder = null!; + + var action = () => builder.WithDataVolume(); + + var exception = Assert.Throws(action); + Assert.Equal(nameof(builder), exception.ParamName); + } + + [Fact] + public void WithDataBindMountShouldThrowWhenBuilderIsNull() + { + IResourceBuilder builder = null!; + const string source = "/qdrant/storage"; + + var action = () => builder.WithDataBindMount(source); + + var exception = Assert.Throws(action); + Assert.Equal(nameof(builder), exception.ParamName); + } + + [Fact] + public void WithDataBindMountShouldThrowWhenSourceIsNull() + { + var builderResource = TestDistributedApplicationBuilder.Create(); + var qdrant = builderResource.AddQdrant("Qdrant"); + string source = null!; + + var action = () => qdrant.WithDataBindMount(source); + + var exception = Assert.Throws(action); + Assert.Equal(nameof(source), exception.ParamName); + } + + [Fact] + public void WithReferenceShouldThrowWhenBuilderIsNull() + { + IResourceBuilder builder = null!; + var builderResource = TestDistributedApplicationBuilder.Create(); + var qdrantResource = builderResource.AddQdrant("Qdrant"); + + var action = () => builder.WithReference(qdrantResource); + + var exception = Assert.Throws(action); + Assert.Equal(nameof(builder), exception.ParamName); + } + + [Fact] + public void WithReferenceShouldThrowWhenQdrantResourceIsNull() + { + var builder = TestDistributedApplicationBuilder.Create(); + var qdrant = builder.AddQdrant("Qdrant"); + IResourceBuilder qdrantResource = null!; + + var action = () => qdrant.WithReference(qdrantResource); + + var exception = Assert.Throws(action); + Assert.Equal(nameof(qdrantResource), exception.ParamName); + } + + [Fact] + public void CtorQdrantServerResourceShouldThrowWhenNameIsNull() + { + var distributedApplicationBuilder = DistributedApplication.CreateBuilder([]); + string name = null!; + const string key = nameof(key); + var apiKey = ParameterResourceBuilderExtensions.CreateDefaultPasswordParameter(distributedApplicationBuilder, key, special: false); + + var action = () => new QdrantServerResource(name, apiKey); + + var exception = Assert.Throws(action); + Assert.Equal(nameof(name), exception.ParamName); + } + + [Fact] + public void CtorQdrantServerResourceShouldThrowWhenApiKeyIsNull() + { + const string name = "Qdrant"; + ParameterResource apiKey = null!; + + var action = () => new QdrantServerResource(name, apiKey); + + var exception = Assert.Throws(action); + Assert.Equal(nameof(apiKey), exception.ParamName); + } +}