From 0b5f3c9983a518200f0167e170b148e24ec14b76 Mon Sep 17 00:00:00 2001 From: Alireza Baloochi Date: Tue, 6 Aug 2024 23:47:39 +0330 Subject: [PATCH 1/4] Adding public API test coverage for Aspire.Hosting.MongoDB --- .../MongoDBBuilderExtensions.cs | 29 ++- .../MongoDBDatabaseResource.cs | 24 ++- .../MongoDBPublicApiTests.cs | 203 ++++++++++++++++++ 3 files changed, 247 insertions(+), 9 deletions(-) create mode 100644 tests/Aspire.Hosting.MongoDB.Tests/MongoDBPublicApiTests.cs diff --git a/src/Aspire.Hosting.MongoDB/MongoDBBuilderExtensions.cs b/src/Aspire.Hosting.MongoDB/MongoDBBuilderExtensions.cs index 796e1e5720..f5825acbbe 100644 --- a/src/Aspire.Hosting.MongoDB/MongoDBBuilderExtensions.cs +++ b/src/Aspire.Hosting.MongoDB/MongoDBBuilderExtensions.cs @@ -24,6 +24,9 @@ public static class MongoDBBuilderExtensions /// A reference to the . public static IResourceBuilder AddMongoDB(this IDistributedApplicationBuilder builder, string name, int? port = null) { + ArgumentNullException.ThrowIfNull(builder); + ArgumentNullException.ThrowIfNull(name); + var mongoDBContainer = new MongoDBServerResource(name); return builder @@ -42,6 +45,9 @@ public static IResourceBuilder AddMongoDB(this IDistribut /// A reference to the . public static IResourceBuilder AddDatabase(this IResourceBuilder builder, string name, string? databaseName = null) { + ArgumentNullException.ThrowIfNull(builder); + ArgumentNullException.ThrowIfNull(name); + // Use the resource name as the database name if it's not provided databaseName ??= name; @@ -61,6 +67,8 @@ public static IResourceBuilder AddDatabase(this IResour /// A reference to the . public static IResourceBuilder WithMongoExpress(this IResourceBuilder builder, Action>? configureContainer = null, string? containerName = null) where T : MongoDBServerResource { + ArgumentNullException.ThrowIfNull(builder); + containerName ??= $"{builder.Resource.Name}-mongoexpress"; var mongoExpressContainer = new MongoExpressContainerResource(containerName); @@ -84,6 +92,7 @@ public static IResourceBuilder WithMongoExpress(this IResourceBuilder b /// The resource builder for PGAdmin. public static IResourceBuilder WithHostPort(this IResourceBuilder builder, int? port) { + ArgumentNullException.ThrowIfNull(builder); return builder.WithEndpoint("http", endpoint => { endpoint.Port = port; @@ -98,7 +107,11 @@ public static IResourceBuilder WithHostPort(this /// 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"), "/data/db", isReadOnly); + { + ArgumentNullException.ThrowIfNull(builder); + + return builder.WithVolume(name ?? VolumeNameGenerator.CreateVolumeName(builder, "data"), "/data/db", isReadOnly); + } /// /// Adds a bind mount for the data folder to a MongoDB container resource. @@ -108,7 +121,12 @@ public static IResourceBuilder WithDataVolume(this IResou /// 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, "/data/db", isReadOnly); + { + ArgumentNullException.ThrowIfNull(builder); + ArgumentNullException.ThrowIfNull(source); + + return builder.WithBindMount(source, "/data/db", isReadOnly); + } /// /// Adds a bind mount for the init folder to a MongoDB container resource. @@ -118,7 +136,12 @@ public static IResourceBuilder WithDataBindMount(this IRe /// A flag that indicates if this is a read-only mount. /// The . public static IResourceBuilder WithInitBindMount(this IResourceBuilder builder, string source, bool isReadOnly = true) - => builder.WithBindMount(source, "/docker-entrypoint-initdb.d", isReadOnly); + { + ArgumentNullException.ThrowIfNull(builder); + ArgumentNullException.ThrowIfNull(source); + + return builder.WithBindMount(source, "/docker-entrypoint-initdb.d", isReadOnly); + } private static void ConfigureMongoExpressContainer(EnvironmentCallbackContext context, MongoDBServerResource resource) { diff --git a/src/Aspire.Hosting.MongoDB/MongoDBDatabaseResource.cs b/src/Aspire.Hosting.MongoDB/MongoDBDatabaseResource.cs index cebf6a3e0b..5a4956f53d 100644 --- a/src/Aspire.Hosting.MongoDB/MongoDBDatabaseResource.cs +++ b/src/Aspire.Hosting.MongoDB/MongoDBDatabaseResource.cs @@ -6,11 +6,23 @@ namespace Aspire.Hosting.ApplicationModel; /// /// A resource that represents a MongoDB database. This is a child resource of a . /// -/// The name of the resource. -/// The database name. -/// The MongoDB server resource associated with this database. -public class MongoDBDatabaseResource(string name, string databaseName, MongoDBServerResource parent) : Resource(name), IResourceWithParent, IResourceWithConnectionString +public class MongoDBDatabaseResource : Resource, IResourceWithParent, IResourceWithConnectionString { + /// + /// A resource that represents a MongoDB database. This is a child resource of a . + /// + /// The name of the resource. + /// The database name. + /// The MongoDB server resource associated with this database. + public MongoDBDatabaseResource(string name, string databaseName, MongoDBServerResource parent) : base(name) + { + ArgumentNullException.ThrowIfNull(databaseName); + ArgumentNullException.ThrowIfNull(parent); + + Parent = parent; + DatabaseName = databaseName; + } + /// /// Gets the connection string expression for the MongoDB database. /// @@ -20,10 +32,10 @@ public ReferenceExpression ConnectionStringExpression /// /// Gets the parent MongoDB container resource. /// - public MongoDBServerResource Parent => parent; + public MongoDBServerResource Parent { get; private set; } /// /// Gets the database name. /// - public string DatabaseName { get; } = databaseName; + public string DatabaseName { get; private set; } } diff --git a/tests/Aspire.Hosting.MongoDB.Tests/MongoDBPublicApiTests.cs b/tests/Aspire.Hosting.MongoDB.Tests/MongoDBPublicApiTests.cs new file mode 100644 index 0000000000..442f725ec8 --- /dev/null +++ b/tests/Aspire.Hosting.MongoDB.Tests/MongoDBPublicApiTests.cs @@ -0,0 +1,203 @@ +// 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.MongoDB.Tests; + +public class MongoDBPublicApiTests +{ + [Fact] + public void AddMongoDBContainerShouldThrowWhenBuilderIsNull() + { + IDistributedApplicationBuilder builder = null!; + const string name = "MongoDB"; + + var action = () => builder.AddMongoDB(name); + + var exception = Assert.Throws(action); + Assert.Equal(nameof(builder), exception.ParamName); + } + + [Fact] + public void AddMongoDBContainerShouldThrowWhenNameIsNull() + { + var builder = DistributedApplication.CreateBuilder([]); + string name = null!; + + var action = () => builder.AddMongoDB(name); + + var exception = Assert.Throws(action); + Assert.Equal(nameof(name), exception.ParamName); + } + + [Fact] + public void AddDatabaseShouldThrowWhenBuilderIsNull() + { + IResourceBuilder builder = null!; + const string name = "db1"; + + var action = () => builder.AddDatabase(name); + + var exception = Assert.Throws(action); + Assert.Equal(nameof(builder), exception.ParamName); + } + + [Fact] + public void AddDatabaseShouldThrowWhenNameIsNull() + { + var builderResource = TestDistributedApplicationBuilder.Create(); + var MongoDB = builderResource.AddMongoDB("MongoDB"); + string name = null!; + + var action = () => MongoDB.AddDatabase(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 = "/MongoDB/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 MongoDB = builderResource.AddMongoDB("MongoDB"); + string source = null!; + + var action = () => MongoDB.WithDataBindMount(source); + + var exception = Assert.Throws(action); + Assert.Equal(nameof(source), exception.ParamName); + } + + [Fact] + public void WithInitBindMountShouldThrowWhenBuilderIsNull() + { + IResourceBuilder builder = null!; + + var action = () => builder.WithInitBindMount("init.js"); + + var exception = Assert.Throws(action); + Assert.Equal(nameof(builder), exception.ParamName); + } + + [Fact] + public void WithMongoExpressShouldThrowWhenBuilderIsNull() + { + IResourceBuilder builder = null!; + + var action = () => builder.WithMongoExpress(); + + var exception = Assert.Throws(action); + Assert.Equal(nameof(builder), exception.ParamName); + } + + [Fact] + public void WithInitBindMountShouldThrowWhenSourceIsNull() + { + var builderResource = TestDistributedApplicationBuilder.Create(); + var MongoDB = builderResource.AddMongoDB("MongoDB"); + string source = null!; + + var action = () => MongoDB.WithInitBindMount(source); + + var exception = Assert.Throws(action); + Assert.Equal(nameof(source), exception.ParamName); + } + + [Fact] + public void WithHostPortShouldThrowWhenBuilderIsNull() + { + IResourceBuilder builder = null!; + + var action = () => builder.WithHostPort(6601); + + var exception = Assert.Throws(action); + Assert.Equal(nameof(builder), exception.ParamName); + } + + [Fact] + public void CtorMongoDBServerResourceShouldThrowWhenNameIsNull() + { + string name = null!; + + var action = () => new MongoDBServerResource(name); + + var exception = Assert.Throws(action); + Assert.Equal(nameof(name), exception.ParamName); + } + + [Fact] + public void CtorMongoMongoDBDatabaseResourceShouldThrowWhenNameIsNull() + { + string name = null!; + var databaseName = "db1"; + var parent = new MongoDBServerResource("mongodb"); + + var action = () => new MongoDBDatabaseResource(name,databaseName,parent); + + var exception = Assert.Throws(action); + Assert.Equal(nameof(name), exception.ParamName); + } + + [Fact] + public void CtorMongoMongoDBDatabaseResourceShouldThrowWhenDatabaseNameIsNull() + { + var name = "mongodb"; + string databaseName = null!; + var parent = new MongoDBServerResource(name); + + var action = () => new MongoDBDatabaseResource(name, databaseName, parent); + + var exception = Assert.Throws(action); + Assert.Equal(nameof(databaseName), exception.ParamName); + } + + [Fact] + public void CtorMongoMongoDBDatabaseResourceShouldThrowWhenDatabaseParentIsNull() + { + var name = "mongodb"; + var databaseName = "db1"; + MongoDBServerResource parent = null!; + + var action = () => new MongoDBDatabaseResource(name, databaseName, parent); + + var exception = Assert.Throws(action); + Assert.Equal(nameof(parent), exception.ParamName); + } + + [Fact] + public void CtorMongoExpressContainerResourceShouldThrowWhenNameIsNull() + { + string name = null!; + + var action = () => new MongoExpressContainerResource(name); + + var exception = Assert.Throws(action); + Assert.Equal(nameof(name), exception.ParamName); + } +} From bd04cdf77721f87e457e39162c97f18634fae8ee Mon Sep 17 00:00:00 2001 From: Alireza Baloochi Date: Wed, 7 Aug 2024 11:38:40 +0330 Subject: [PATCH 2/4] Apply suggestions from code review Co-authored-by: Ankit Jain --- src/Aspire.Hosting.MongoDB/MongoDBDatabaseResource.cs | 4 ++-- tests/Aspire.Hosting.MongoDB.Tests/MongoDBPublicApiTests.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Aspire.Hosting.MongoDB/MongoDBDatabaseResource.cs b/src/Aspire.Hosting.MongoDB/MongoDBDatabaseResource.cs index 5a4956f53d..fd3a4cdbf6 100644 --- a/src/Aspire.Hosting.MongoDB/MongoDBDatabaseResource.cs +++ b/src/Aspire.Hosting.MongoDB/MongoDBDatabaseResource.cs @@ -32,10 +32,10 @@ public ReferenceExpression ConnectionStringExpression /// /// Gets the parent MongoDB container resource. /// - public MongoDBServerResource Parent { get; private set; } + public MongoDBServerResource Parent { get; init; } /// /// Gets the database name. /// - public string DatabaseName { get; private set; } + public string DatabaseName { get; init; } } diff --git a/tests/Aspire.Hosting.MongoDB.Tests/MongoDBPublicApiTests.cs b/tests/Aspire.Hosting.MongoDB.Tests/MongoDBPublicApiTests.cs index 442f725ec8..c208a92684 100644 --- a/tests/Aspire.Hosting.MongoDB.Tests/MongoDBPublicApiTests.cs +++ b/tests/Aspire.Hosting.MongoDB.Tests/MongoDBPublicApiTests.cs @@ -158,7 +158,7 @@ public void CtorMongoMongoDBDatabaseResourceShouldThrowWhenNameIsNull() var databaseName = "db1"; var parent = new MongoDBServerResource("mongodb"); - var action = () => new MongoDBDatabaseResource(name,databaseName,parent); + var action = () => new MongoDBDatabaseResource(name, databaseName, parent); var exception = Assert.Throws(action); Assert.Equal(nameof(name), exception.ParamName); From 79f51b01ffffdf23c9990266cb7ac8e0c31fc568 Mon Sep 17 00:00:00 2001 From: Alireza Baloochi Date: Fri, 9 Aug 2024 17:08:22 +0330 Subject: [PATCH 3/4] fix test --- src/Aspire.Hosting.MongoDB/PublicAPI.Unshipped.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Aspire.Hosting.MongoDB/PublicAPI.Unshipped.txt b/src/Aspire.Hosting.MongoDB/PublicAPI.Unshipped.txt index 074c6ad103..262b47b268 100644 --- a/src/Aspire.Hosting.MongoDB/PublicAPI.Unshipped.txt +++ b/src/Aspire.Hosting.MongoDB/PublicAPI.Unshipped.txt @@ -1,2 +1,3 @@ #nullable enable - +Aspire.Hosting.ApplicationModel.MongoDBDatabaseResource.DatabaseName.init -> void +Aspire.Hosting.ApplicationModel.MongoDBDatabaseResource.Parent.init -> void From 895b594559b81016590d9693cea1095e38810448 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Ros?= Date: Fri, 9 Aug 2024 10:45:00 -0700 Subject: [PATCH 4/4] Remove inits --- src/Aspire.Hosting.MongoDB/MongoDBBuilderExtensions.cs | 1 + src/Aspire.Hosting.MongoDB/MongoDBDatabaseResource.cs | 4 ++-- src/Aspire.Hosting.MongoDB/PublicAPI.Unshipped.txt | 3 +-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Aspire.Hosting.MongoDB/MongoDBBuilderExtensions.cs b/src/Aspire.Hosting.MongoDB/MongoDBBuilderExtensions.cs index f5825acbbe..e7c75e9d39 100644 --- a/src/Aspire.Hosting.MongoDB/MongoDBBuilderExtensions.cs +++ b/src/Aspire.Hosting.MongoDB/MongoDBBuilderExtensions.cs @@ -93,6 +93,7 @@ public static IResourceBuilder WithMongoExpress(this IResourceBuilder b public static IResourceBuilder WithHostPort(this IResourceBuilder builder, int? port) { ArgumentNullException.ThrowIfNull(builder); + return builder.WithEndpoint("http", endpoint => { endpoint.Port = port; diff --git a/src/Aspire.Hosting.MongoDB/MongoDBDatabaseResource.cs b/src/Aspire.Hosting.MongoDB/MongoDBDatabaseResource.cs index fd3a4cdbf6..b41572913f 100644 --- a/src/Aspire.Hosting.MongoDB/MongoDBDatabaseResource.cs +++ b/src/Aspire.Hosting.MongoDB/MongoDBDatabaseResource.cs @@ -32,10 +32,10 @@ public ReferenceExpression ConnectionStringExpression /// /// Gets the parent MongoDB container resource. /// - public MongoDBServerResource Parent { get; init; } + public MongoDBServerResource Parent { get; } /// /// Gets the database name. /// - public string DatabaseName { get; init; } + public string DatabaseName { get; } } diff --git a/src/Aspire.Hosting.MongoDB/PublicAPI.Unshipped.txt b/src/Aspire.Hosting.MongoDB/PublicAPI.Unshipped.txt index 262b47b268..074c6ad103 100644 --- a/src/Aspire.Hosting.MongoDB/PublicAPI.Unshipped.txt +++ b/src/Aspire.Hosting.MongoDB/PublicAPI.Unshipped.txt @@ -1,3 +1,2 @@ #nullable enable -Aspire.Hosting.ApplicationModel.MongoDBDatabaseResource.DatabaseName.init -> void -Aspire.Hosting.ApplicationModel.MongoDBDatabaseResource.Parent.init -> void +