Skip to content

Commit

Permalink
Fix CA1062 (#5048)
Browse files Browse the repository at this point in the history
  • Loading branch information
Zombach authored Jul 29, 2024
1 parent f6c940b commit ced70f6
Show file tree
Hide file tree
Showing 3 changed files with 208 additions and 2 deletions.
20 changes: 18 additions & 2 deletions src/Aspire.Hosting.Redis/RedisBuilderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ public static class RedisBuilderExtensions
/// <returns>A reference to the <see cref="IResourceBuilder{T}"/>.</returns>
public static IResourceBuilder<RedisResource> AddRedis(this IDistributedApplicationBuilder builder, string name, int? port = null)
{
ArgumentNullException.ThrowIfNull(builder);

var redis = new RedisResource(name);
return builder.AddResource(redis)
.WithEndpoint(port: port, targetPort: 6379, name: RedisResource.PrimaryEndpointName)
Expand All @@ -42,6 +44,8 @@ public static IResourceBuilder<RedisResource> AddRedis(this IDistributedApplicat
/// <returns></returns>
public static IResourceBuilder<RedisResource> WithRedisCommander(this IResourceBuilder<RedisResource> builder, Action<IResourceBuilder<RedisCommanderResource>>? configureContainer = null, string? containerName = null)
{
ArgumentNullException.ThrowIfNull(builder);

if (builder.ApplicationBuilder.Resources.OfType<RedisCommanderResource>().SingleOrDefault() is { } existingRedisCommanderResource)
{
var builderForExistingResource = builder.ApplicationBuilder.CreateResourceBuilder(existingRedisCommanderResource);
Expand Down Expand Up @@ -74,6 +78,8 @@ public static IResourceBuilder<RedisResource> WithRedisCommander(this IResourceB
/// <returns>The resource builder for PGAdmin.</returns>
public static IResourceBuilder<RedisCommanderResource> WithHostPort(this IResourceBuilder<RedisCommanderResource> builder, int? port)
{
ArgumentNullException.ThrowIfNull(builder);

return builder.WithEndpoint("http", endpoint =>
{
endpoint.Port = port;
Expand All @@ -100,6 +106,8 @@ public static IResourceBuilder<RedisCommanderResource> WithHostPort(this IResour
/// <returns>The <see cref="IResourceBuilder{T}"/>.</returns>
public static IResourceBuilder<RedisResource> WithDataVolume(this IResourceBuilder<RedisResource> builder, string? name = null, bool isReadOnly = false)
{
ArgumentNullException.ThrowIfNull(builder);

builder.WithVolume(name ?? VolumeNameGenerator.CreateVolumeName(builder, "data"), "/data", isReadOnly);
if (!isReadOnly)
{
Expand Down Expand Up @@ -128,6 +136,9 @@ public static IResourceBuilder<RedisResource> WithDataVolume(this IResourceBuild
/// <returns>The <see cref="IResourceBuilder{T}"/>.</returns>
public static IResourceBuilder<RedisResource> WithDataBindMount(this IResourceBuilder<RedisResource> builder, string source, bool isReadOnly = false)
{
ArgumentNullException.ThrowIfNull(builder);
ArgumentNullException.ThrowIfNull(source);

builder.WithBindMount(source, "/data", isReadOnly);
if (!isReadOnly)
{
Expand All @@ -153,11 +164,16 @@ public static IResourceBuilder<RedisResource> WithDataBindMount(this IResourceBu
/// <param name="keysChangedThreshold">The number of key change operations required to trigger a snapshot at the interval. Defaults to 1.</param>
/// <returns>The <see cref="IResourceBuilder{T}"/>.</returns>
public static IResourceBuilder<RedisResource> WithPersistence(this IResourceBuilder<RedisResource> 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);
}
}
2 changes: 2 additions & 0 deletions src/Aspire.Hosting.Redis/RedisCommanderConfigWriterHook.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ internal sealed class RedisCommanderConfigWriterHook : IDistributedApplicationLi
{
public Task AfterEndpointsAllocatedAsync(DistributedApplicationModel appModel, CancellationToken cancellationToken)
{
ArgumentNullException.ThrowIfNull(appModel);

if (appModel.Resources.OfType<RedisCommanderResource>().SingleOrDefault() is not { } commanderResource)
{
// No-op if there is no commander resource (removed after hook added).
Expand Down
188 changes: 188 additions & 0 deletions tests/Aspire.Hosting.Redis.Tests/RedisPublicApiTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
// 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 Xunit;

namespace Aspire.Hosting.Redis.Tests;

public class RedisPublicApiTests
{
#region RedisBuilderExtensions

[Fact]
public void AddRedisContainerShouldThrowsWhenBuilderIsNull()
{
IDistributedApplicationBuilder builder = null!;
const string name = "Redis";

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

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

[Fact]
public void AddRedisContainerShouldThrowsWhenNameIsNull()
{
IDistributedApplicationBuilder builder = new DistributedApplicationBuilder([]);
string name = null!;

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

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

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

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

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

[Fact]
public void WithHostPortShouldThrowsWhenBuilderIsNull()
{
IResourceBuilder<RedisCommanderResource> builder = null!;
const int port = 777;

var action = () => builder.WithHostPort(port);

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

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

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

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

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

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

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

[Fact]
public void WithDataBindMountShouldThrowsWhenNameIsNull()
{
var distributedApplicationBuilder = new DistributedApplicationBuilder([]);
const string name = "Redis";
var resource = new RedisResource(name);
var builder = distributedApplicationBuilder.AddResource(resource);
string source = null!;

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

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

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

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

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

#endregion

#region RedisCommanderConfigWriterHook

[Fact]
public async Task AfterEndpointsAllocatedAsyncShouldThrowsWhenDistributedApplicationModelIsNull()
{
DistributedApplicationModel appModel = null!;
var cancellationToken = CancellationToken.None;

var instance = (RedisCommanderConfigWriterHook)Activator.CreateInstance(typeof(RedisCommanderConfigWriterHook), true)!;

async Task Action() => await instance.AfterEndpointsAllocatedAsync(appModel, cancellationToken);

var exception = await Assert.ThrowsAsync<ArgumentNullException>(Action);
Assert.Equal(nameof(appModel), exception.ParamName);
}

#endregion

#region RedisCommanderResource

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

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

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

#endregion

#region RedisResource

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

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

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

#endregion
}

0 comments on commit ced70f6

Please sign in to comment.