Skip to content

Commit

Permalink
Adding public API test coverage for Aspire.Hosting.SqlServer (#5241)
Browse files Browse the repository at this point in the history
  • Loading branch information
Alirexaa authored Aug 9, 2024
1 parent a7f23ec commit d5a99e9
Show file tree
Hide file tree
Showing 3 changed files with 228 additions and 7 deletions.
15 changes: 14 additions & 1 deletion src/Aspire.Hosting.SqlServer/SqlServerBuilderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ public static class SqlServerBuilderExtensions
/// <returns>A reference to the <see cref="IResourceBuilder{T}"/>.</returns>
public static IResourceBuilder<SqlServerServerResource> AddSqlServer(this IDistributedApplicationBuilder builder, string name, IResourceBuilder<ParameterResource>? password = null, int? port = null)
{
ArgumentNullException.ThrowIfNull(builder);
ArgumentException.ThrowIfNullOrEmpty(name);

// The password must be at least 8 characters long and contain characters from three of the following four sets: Uppercase letters, Lowercase letters, Base 10 digits, and Symbols
var passwordParameter = password?.Resource ?? ParameterResourceBuilderExtensions.CreateDefaultPasswordParameter(builder, $"{name}-password", minLower: 1, minUpper: 1, minNumeric: 1);

Expand All @@ -45,6 +48,9 @@ public static IResourceBuilder<SqlServerServerResource> AddSqlServer(this IDistr
/// <returns>A reference to the <see cref="IResourceBuilder{T}"/>.</returns>
public static IResourceBuilder<SqlServerDatabaseResource> AddDatabase(this IResourceBuilder<SqlServerServerResource> builder, string name, string? databaseName = null)
{
ArgumentNullException.ThrowIfNull(builder);
ArgumentException.ThrowIfNullOrEmpty(name);

// Use the resource name as the database name if it's not provided
databaseName ??= name;

Expand All @@ -61,7 +67,11 @@ public static IResourceBuilder<SqlServerDatabaseResource> AddDatabase(this IReso
/// <param name="isReadOnly">A flag that indicates if this is a read-only volume.</param>
/// <returns>The <see cref="IResourceBuilder{T}"/>.</returns>
public static IResourceBuilder<SqlServerServerResource> WithDataVolume(this IResourceBuilder<SqlServerServerResource> builder, string? name = null, bool isReadOnly = false)
=> builder.WithVolume(name ?? VolumeNameGenerator.CreateVolumeName(builder, "data"), "/var/opt/mssql", isReadOnly);
{
ArgumentNullException.ThrowIfNull(builder);

return builder.WithVolume(name ?? VolumeNameGenerator.CreateVolumeName(builder, "data"), "/var/opt/mssql", isReadOnly);
}

/// <summary>
/// Adds a bind mount for the data folder to a SQL Server resource.
Expand All @@ -72,6 +82,9 @@ public static IResourceBuilder<SqlServerServerResource> WithDataVolume(this IRes
/// <returns>The <see cref="IResourceBuilder{T}"/>.</returns>
public static IResourceBuilder<SqlServerServerResource> WithDataBindMount(this IResourceBuilder<SqlServerServerResource> builder, string source, bool isReadOnly = false)
{
ArgumentNullException.ThrowIfNull(builder);
ArgumentException.ThrowIfNullOrEmpty(source);

// c.f. https://learn.microsoft.com/sql/linux/sql-server-linux-docker-container-configure?view=sql-server-ver15&pivots=cs1-bash#mount-a-host-directory-as-data-volume

foreach (var dir in new string[] { "data", "log", "secrets" })
Expand Down
22 changes: 16 additions & 6 deletions src/Aspire.Hosting.SqlServer/SqlServerDatabaseResource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,12 @@ namespace Aspire.Hosting.ApplicationModel;
/// <summary>
/// A resource that represents a SQL Server database that is a child of a SQL Server container resource.
/// </summary>
/// <param name="name">The name of the resource.</param>
/// <param name="databaseName">The database name.</param>
/// <param name="parent">The parent SQL Server server resource.</param>
public class SqlServerDatabaseResource(string name, string databaseName, SqlServerServerResource parent) : Resource(name), IResourceWithParent<SqlServerServerResource>, IResourceWithConnectionString
public class SqlServerDatabaseResource : Resource, IResourceWithParent<SqlServerServerResource>, IResourceWithConnectionString
{
/// <summary>
/// Gets the parent SQL Server container resource.
/// </summary>
public SqlServerServerResource Parent { get; } = parent;
public SqlServerServerResource Parent { get; }

/// <summary>
/// Gets the connection string expression for the SQL Server database.
Expand All @@ -25,5 +22,18 @@ public class SqlServerDatabaseResource(string name, string databaseName, SqlServ
/// <summary>
/// Gets the database name.
/// </summary>
public string DatabaseName { get; } = databaseName;
public string DatabaseName { get; }

/// <param name="name">The name of the resource.</param>
/// <param name="databaseName">The database name.</param>
/// <param name="parent">The parent SQL Server server resource.</param>
public SqlServerDatabaseResource(string name, string databaseName, SqlServerServerResource parent) : base(name)
{
ArgumentException.ThrowIfNullOrEmpty(databaseName);
ArgumentNullException.ThrowIfNull(parent);

DatabaseName = databaseName;
Parent = parent;

}
}
198 changes: 198 additions & 0 deletions tests/Aspire.Hosting.SqlServer.Tests/SqlServerPublicApiTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
// 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.SqlServer.Tests;

public class SqlServerPublicApiTests
{
[Fact]
public void AddSqlServerContainerShouldThrowWhenBuilderIsNull()
{
IDistributedApplicationBuilder builder = null!;
const string name = "SqlServer";

var action = () => builder.AddSqlServer(name);

var exception = Assert.Throws<ArgumentNullException>(action);
Assert.Equal(nameof(builder), exception.ParamName);
}

[Fact]
public void AddSqlServerContainerShouldThrowWhenNameIsNull()
{
var builder = DistributedApplication.CreateBuilder([]);
string name = null!;

var action = () => builder.AddSqlServer(name);

var exception = Assert.Throws<ArgumentNullException>(action);
Assert.Equal(nameof(name), exception.ParamName);
}

[Fact]
public void AddDatabaseShouldThrowWhenBuilderIsNull()
{
IResourceBuilder<SqlServerServerResource> builder = null!;
const string name = "SqlServer";

var action = () => builder.AddDatabase(name);

var exception = Assert.Throws<ArgumentNullException>(action);
Assert.Equal(nameof(builder), exception.ParamName);
}

[Fact]
public void AddDatabaseShouldThrowWhenNameIsNull()
{
var builder = DistributedApplication.CreateBuilder([])
.AddSqlServer("sqlserver");
string name = null!;

var action = () => builder.AddDatabase(name);

var exception = Assert.Throws<ArgumentNullException>(action);
Assert.Equal(nameof(name), exception.ParamName);
}

[Fact]
public void AddDatabaseShouldThrowWhenNameIsEmpty()
{
var builder = DistributedApplication.CreateBuilder([])
.AddSqlServer("sqlserver");
string name = "";

var action = () => builder.AddDatabase(name);

var exception = Assert.Throws<ArgumentException>(action);
Assert.Equal(nameof(name), exception.ParamName);
}

[Fact]
public void WithDataVolumeShouldThrowWhenBuilderIsNull()
{
IResourceBuilder<SqlServerServerResource> builder = null!;

var action = () => builder.WithDataVolume();

var exception = Assert.Throws<ArgumentNullException>(action);
Assert.Equal(nameof(builder), exception.ParamName);
}

[Fact]
public void WithDataBindMountShouldThrowWhenBuilderIsNull()
{
IResourceBuilder<SqlServerServerResource> builder = null!;
const string source = "/sqlserver/data";

var action = () => builder.WithDataBindMount(source);

var exception = Assert.Throws<ArgumentNullException>(action);
Assert.Equal(nameof(builder), exception.ParamName);
}

[Fact]
public void WithDataBindMountShouldThrowWhenSourceIsNull()
{
var builderResource = TestDistributedApplicationBuilder.Create();
var SqlServer = builderResource.AddSqlServer("SqlServer");
string source = null!;

var action = () => SqlServer.WithDataBindMount(source);

var exception = Assert.Throws<ArgumentNullException>(action);
Assert.Equal(nameof(source), exception.ParamName);
}

[Fact]
public void CtorSqlServerServerResourceShouldThrowWhenNameIsNull()
{
var distributedApplicationBuilder = DistributedApplication.CreateBuilder([]);
string name = null!;
const string key = nameof(key);
var password = ParameterResourceBuilderExtensions.CreateDefaultPasswordParameter(distributedApplicationBuilder, key, special: false);

var action = () => new SqlServerServerResource(name, password);

var exception = Assert.Throws<ArgumentNullException>(action);
Assert.Equal(nameof(name), exception.ParamName);
}

[Fact]
public void CtorSqlServerDatabaseResourceShouldThrowWhenNameIsNull()
{
var distributedApplicationBuilder = DistributedApplication.CreateBuilder([]);

string name = null!;
var databaseName = "db1";
var password = ParameterResourceBuilderExtensions.CreateDefaultPasswordParameter(distributedApplicationBuilder, "password", special: false);
var parent = new SqlServerServerResource("sqlserver",password);
var action = () => new SqlServerDatabaseResource(name, databaseName, parent);

var exception = Assert.Throws<ArgumentNullException>(action);
Assert.Equal(nameof(name), exception.ParamName);
}

[Fact]
public void CtorSqlServerDatabaseResourceShouldThrowWhenNameIsEmpty()
{
var distributedApplicationBuilder = DistributedApplication.CreateBuilder([]);

string name = "";
var databaseName = "db1";
var password = ParameterResourceBuilderExtensions.CreateDefaultPasswordParameter(distributedApplicationBuilder, "password", special: false);
var parent = new SqlServerServerResource("sqlserver", password);
var action = () => new SqlServerDatabaseResource(name, databaseName, parent);

var exception = Assert.Throws<ArgumentException>(action);
Assert.Equal(nameof(name), exception.ParamName);
}

[Fact]
public void CtorSqlServerDatabaseResourceShouldThrowWhenDatabaseNameIsNull()
{
var distributedApplicationBuilder = DistributedApplication.CreateBuilder([]);

string name = "sqlserver";
string databaseName = null!;
var password = ParameterResourceBuilderExtensions.CreateDefaultPasswordParameter(distributedApplicationBuilder, "password", special: false);
var parent = new SqlServerServerResource("sqlserver", password);
var action = () => new SqlServerDatabaseResource(name, databaseName, parent);

var exception = Assert.Throws<ArgumentNullException>(action);
Assert.Equal(nameof(databaseName), exception.ParamName);
}

[Fact]
public void CtorSqlServerDatabaseResourceShouldThrowWhenDatabaseNameIsEmpty()
{
var distributedApplicationBuilder = DistributedApplication.CreateBuilder([]);

string name = "sqlserver";
string databaseName = null!;
var password = ParameterResourceBuilderExtensions.CreateDefaultPasswordParameter(distributedApplicationBuilder, "password", special: false);
var parent = new SqlServerServerResource("sqlserver", password);
var action = () => new SqlServerDatabaseResource(name, databaseName, parent);

var exception = Assert.Throws<ArgumentNullException>(action);
Assert.Equal(nameof(databaseName), exception.ParamName);
}

[Fact]
public void CtorSqlServerDatabaseResourceShouldThrowWhenParentIsNull()
{
var distributedApplicationBuilder = DistributedApplication.CreateBuilder([]);

string name = "sqlserver";
string databaseName = "db1";
var password = ParameterResourceBuilderExtensions.CreateDefaultPasswordParameter(distributedApplicationBuilder, "password", special: false);
SqlServerServerResource parent = null!;
var action = () => new SqlServerDatabaseResource(name, databaseName, parent);

var exception = Assert.Throws<ArgumentNullException>(action);
Assert.Equal(nameof(parent), exception.ParamName);
}
}

0 comments on commit d5a99e9

Please sign in to comment.