Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding public API test coverage for Aspire.Hosting.Garnet #5160

17 changes: 15 additions & 2 deletions src/Aspire.Hosting.Garnet/GarnetBuilderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ public static class GarnetBuilderExtensions
public static IResourceBuilder<GarnetResource> AddGarnet(this IDistributedApplicationBuilder builder, string name,
int? port = null)
{
ArgumentNullException.ThrowIfNull(builder);
ArgumentNullException.ThrowIfNull(name);

var garnet = new GarnetResource(name);
return builder.AddResource(garnet)
.WithEndpoint(port: port, targetPort: 6379, name: GarnetResource.PrimaryEndpointName)
Expand Down Expand Up @@ -79,6 +82,8 @@ public static IResourceBuilder<GarnetResource> AddGarnet(this IDistributedApplic
public static IResourceBuilder<GarnetResource> WithDataVolume(this IResourceBuilder<GarnetResource> builder,
string? name = null, bool isReadOnly = false)
{
ArgumentNullException.ThrowIfNull(builder);

builder.WithVolume(name ?? VolumeNameGenerator.CreateVolumeName(builder, "data"), GarnetContainerDataDirectory,
isReadOnly);
if (!isReadOnly)
Expand Down Expand Up @@ -110,6 +115,9 @@ public static IResourceBuilder<GarnetResource> WithDataVolume(this IResourceBuil
public static IResourceBuilder<GarnetResource> WithDataBindMount(this IResourceBuilder<GarnetResource> builder,
string source, bool isReadOnly = false)
{
ArgumentNullException.ThrowIfNull(builder);
ArgumentNullException.ThrowIfNull(source);

builder.WithBindMount(source, GarnetContainerDataDirectory, isReadOnly);
if (!isReadOnly)
{
Expand Down Expand Up @@ -137,11 +145,16 @@ public static IResourceBuilder<GarnetResource> WithDataBindMount(this IResourceB
/// <returns>The <see cref="IResourceBuilder{T}"/>.</returns>
public static IResourceBuilder<GarnetResource> WithPersistence(this IResourceBuilder<GarnetResource> builder,
TimeSpan? interval = null, long keysChangedThreshold = 1)
=> builder.WithAnnotation(new CommandLineArgsCallbackAnnotation(context =>
{
ArgumentNullException.ThrowIfNull(builder);

return builder.WithAnnotation(new CommandLineArgsCallbackAnnotation(context =>
{
context.Args.Add("--save");
context.Args.Add((interval ?? TimeSpan.FromSeconds(60)).TotalSeconds.ToString(CultureInfo.InvariantCulture));
context.Args.Add(
(interval ?? TimeSpan.FromSeconds(60)).TotalSeconds.ToString(CultureInfo.InvariantCulture));
context.Args.Add(keysChangedThreshold.ToString(CultureInfo.InvariantCulture));
return Task.CompletedTask;
}), ResourceAnnotationMutationBehavior.Replace);
}
}
8 changes: 7 additions & 1 deletion src/Aspire.Hosting.Garnet/GarnetResource.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;

namespace Aspire.Hosting.ApplicationModel;

/// <summary>
/// A resource that represents a Garnet resource independent of the hosting model.
/// </summary>
/// <param name="name">The name of the resource.</param>
public class GarnetResource(string name) : ContainerResource(name), IResourceWithConnectionString
public class GarnetResource(string name) : ContainerResource(ThrowIfNull(name)), IResourceWithConnectionString
{
internal const string PrimaryEndpointName = "tcp";

Expand All @@ -24,4 +27,7 @@ public class GarnetResource(string name) : ContainerResource(name), IResourceWit
public ReferenceExpression ConnectionStringExpression =>
ReferenceExpression.Create(
$"{PrimaryEndpoint.Property(EndpointProperty.Host)}:{PrimaryEndpoint.Property(EndpointProperty.Port)}");

private static string ThrowIfNull([NotNull] string? argument, [CallerArgumentExpression(nameof(argument))] string? paramName = null)
=> argument ?? throw new ArgumentNullException(paramName);
}
93 changes: 93 additions & 0 deletions tests/Aspire.Hosting.Garnet.Tests/GarnetPublicApiTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
// 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.Garnet.Tests;

public class GarnetPublicApiTests
{
[Fact]
public void AddGarnetContainerShouldThrowWhenBuilderIsNull()
{
IDistributedApplicationBuilder builder = null!;
const string name = "Garnet";

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

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

[Fact]
public void AddGarnetContainerShouldThrowWhenNameIsNull()
{
var builder = TestDistributedApplicationBuilder.Create();
string name = null!;

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

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

[Fact]
public void CtorGarnetResourceShouldThrowWhenNameIsNull()
{
string name = null!;

var action = () => new GarnetResource(name);

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

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

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

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

[Fact]
public void WithDataBindMountShouldThrowWhenSourceIsNull()
{
var builder = TestDistributedApplicationBuilder.Create();
var garnet = builder.AddGarnet("Garnet");
string source = null!;

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

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

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

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

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

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

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

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