Skip to content

Adding unit tests for Java hosting #38

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

Merged
merged 1 commit into from
Sep 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 16 additions & 21 deletions src/Aspire.CommunityToolkit.Hosting.Java/JavaAppHostingExtension.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,27 +19,21 @@ public static class JavaAppHostingExtension
/// <returns>A reference to the <see cref="IResourceBuilder{T}"/>.</returns>
public static IResourceBuilder<JavaAppContainerResource> AddJavaApp(this IDistributedApplicationBuilder builder, string name, JavaAppContainerResourceOptions options)
{
if (string.IsNullOrWhiteSpace(options.ContainerImageName) == true)
{
throw new ArgumentException("Container image name must be specified.", nameof(options));
}
ArgumentNullException.ThrowIfNull(builder, nameof(builder));
ArgumentNullException.ThrowIfNull(options, nameof(options));
ArgumentException.ThrowIfNullOrWhiteSpace(name, nameof(name));
ArgumentException.ThrowIfNullOrWhiteSpace(options.ContainerImageName, nameof(options.ContainerImageName));

var resource = new JavaAppContainerResource(name);

var rb = builder.AddResource(resource);
if (string.IsNullOrWhiteSpace(options.ContainerRegistry) == false)
{
rb.WithImageRegistry(options.ContainerRegistry);
}
rb.WithImage(options.ContainerImageName)
.WithImageTag(options.ContainerImageTag)
var rb = builder.AddResource(resource)
.WithAnnotation(new ContainerImageAnnotation { Image = options.ContainerImageName, Tag = options.ContainerImageTag, Registry = options.ContainerRegistry })
.WithHttpEndpoint(port: options.Port, targetPort: options.TargetPort, name: JavaAppContainerResource.HttpEndpointName)
.WithJavaDefaults(options);

if (options.Args is { Length: > 0 })
{
#pragma warning disable CS8604 // Possible null reference argument.
rb.WithArgs(options.Args);
#pragma warning restore CS8604 // Possible null reference argument.
}

return rb;
Expand All @@ -52,10 +46,8 @@ public static IResourceBuilder<JavaAppContainerResource> AddJavaApp(this IDistri
/// <param name="name">The name of the resource.</param>
/// <param name="options">The <see cref="JavaAppContainerResourceOptions"/> to configure the Java application.</param>"
/// <returns>A reference to the <see cref="IResourceBuilder{T}"/>.</returns>
public static IResourceBuilder<JavaAppContainerResource> AddSpringApp(this IDistributedApplicationBuilder builder, string name, JavaAppContainerResourceOptions options)
{
return builder.AddJavaApp(name, options);
}
public static IResourceBuilder<JavaAppContainerResource> AddSpringApp(this IDistributedApplicationBuilder builder, string name, JavaAppContainerResourceOptions options) =>
builder.AddJavaApp(name, options);

/// <summary>
/// Adds a Java application to the application model. Executes the executable Java app.
Expand All @@ -67,6 +59,11 @@ public static IResourceBuilder<JavaAppContainerResource> AddSpringApp(this IDist
/// <returns>A reference to the <see cref="IResourceBuilder{T}"/>.</returns>
public static IResourceBuilder<JavaAppExecutableResource> AddJavaApp(this IDistributedApplicationBuilder builder, string name, string workingDirectory, JavaAppExecutableResourceOptions options)
{
ArgumentNullException.ThrowIfNull(builder, nameof(builder));
ArgumentNullException.ThrowIfNull(options, nameof(options));
ArgumentException.ThrowIfNullOrWhiteSpace(name, nameof(name));
ArgumentException.ThrowIfNullOrWhiteSpace(workingDirectory, nameof(workingDirectory));

#pragma warning disable CS8601 // Possible null reference assignment.
string[] allArgs = options.Args is { Length: > 0 }
? ["-jar", options.ApplicationName, .. options.Args]
Expand All @@ -90,10 +87,8 @@ public static IResourceBuilder<JavaAppExecutableResource> AddJavaApp(this IDistr
/// <param name="workingDirectory">The working directory to use for the command. If null, the working directory of the current process is used.</param>
/// <param name="options">The <see cref="JavaAppExecutableResourceOptions"/> to configure the Java application.</param>"
/// <returns>A reference to the <see cref="IResourceBuilder{T}"/>.</returns>
public static IResourceBuilder<JavaAppExecutableResource> AddSpringApp(this IDistributedApplicationBuilder builder, string name, string workingDirectory, JavaAppExecutableResourceOptions options)
{
return builder.AddJavaApp(name, workingDirectory, options);
}
public static IResourceBuilder<JavaAppExecutableResource> AddSpringApp(this IDistributedApplicationBuilder builder, string name, string workingDirectory, JavaAppExecutableResourceOptions options) =>
builder.AddJavaApp(name, workingDirectory, options);

private static IResourceBuilder<JavaAppContainerResource> WithJavaDefaults(
this IResourceBuilder<JavaAppContainerResource> builder,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
namespace Aspire.CommunityToolkit.Hosting.Java.Tests;
public class ContainerResourceCreationTests
{
[Fact]
public void AddJavaAppBuilderShouldNotBeNull()
{
IDistributedApplicationBuilder builder = null!;

Assert.Throws<ArgumentNullException>(() => builder.AddJavaApp("java", new JavaAppContainerResourceOptions()));
}

[Fact]
public void AddSpringAppBuilderShouldNotBeNull()
{
IDistributedApplicationBuilder builder = null!;

Assert.Throws<ArgumentNullException>(() => builder.AddSpringApp("spring", new JavaAppContainerResourceOptions()));
}

[Fact]
public void AddJavaAppNameShouldNotBeNullOrWhiteSpace()
{
IDistributedApplicationBuilder builder = DistributedApplication.CreateBuilder();

Assert.Throws<ArgumentNullException>(() => builder.AddJavaApp(null!, new JavaAppContainerResourceOptions()));
Assert.Throws<ArgumentException>(() => builder.AddJavaApp("", new JavaAppContainerResourceOptions()));
}

[Fact]
public void AddSpringAppNameShouldNotBeNullOrWhiteSpace()
{
IDistributedApplicationBuilder builder = DistributedApplication.CreateBuilder();

Assert.Throws<ArgumentNullException>(() => builder.AddSpringApp(null!, new JavaAppContainerResourceOptions()));
Assert.Throws<ArgumentException>(() => builder.AddSpringApp("", new JavaAppContainerResourceOptions()));
}

[Fact]
public void AddJavaAppContainerImageNameShouldNotBeNullOrWhiteSpace()
{
IDistributedApplicationBuilder builder = DistributedApplication.CreateBuilder();

Assert.Throws<ArgumentNullException>(() => builder.AddJavaApp("java", new JavaAppContainerResourceOptions { ContainerImageName = null! }));
Assert.Throws<ArgumentException>(() => builder.AddJavaApp("java", new JavaAppContainerResourceOptions { ContainerImageName = "" }));
}

[Fact]
public void AddJavaAppContainerResourceOptionsShouldNotBeNull()
{
IDistributedApplicationBuilder builder = DistributedApplication.CreateBuilder();

Assert.Throws<ArgumentNullException>(() => builder.AddJavaApp("java", null!));
}

[Fact]
public void AddSpringAppContainerResourceOptionsShouldNotBeNull()
{
IDistributedApplicationBuilder builder = DistributedApplication.CreateBuilder();

Assert.Throws<ArgumentNullException>(() => builder.AddSpringApp("spring", null!));
}

[Fact]
public async Task AddJavaAppContainerDetailsSetOnResource()
{
IDistributedApplicationBuilder builder = DistributedApplication.CreateBuilder();

var options = new JavaAppContainerResourceOptions
{
ContainerImageName = "java-app",
ContainerRegistry = "docker.io",
ContainerImageTag = "latest",
Port = 8080,
TargetPort = 8080,
OtelAgentPath = "path/to/otel",
Args = ["arg1", "arg2"]
};

builder.AddJavaApp("java", options);

using var app = builder.Build();

var appModel = app.Services.GetRequiredService<DistributedApplicationModel>();

var resource = appModel.Resources.OfType<JavaAppContainerResource>().SingleOrDefault();

Assert.NotNull(resource);
Assert.Equal("java", resource.Name);

Assert.True(resource.TryGetLastAnnotation(out ContainerImageAnnotation? imageAnnotations));
Assert.Equal(options.ContainerImageName, imageAnnotations.Image);
Assert.Equal(options.ContainerRegistry, imageAnnotations.Registry);
Assert.Equal(options.ContainerImageTag, imageAnnotations.Tag);

Assert.True(resource.TryGetLastAnnotation(out EndpointAnnotation? httpEndpointAnnotations));
Assert.Equal(options.Port, httpEndpointAnnotations.Port);
Assert.Equal(options.TargetPort, httpEndpointAnnotations.TargetPort);

Assert.True(resource.TryGetLastAnnotation(out CommandLineArgsCallbackAnnotation? argsAnnotations));
CommandLineArgsCallbackContext context = new([]);
await argsAnnotations.Callback(context);
Assert.All(options.Args, arg => Assert.Contains(arg, context.Args));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
namespace Aspire.CommunityToolkit.Hosting.Java.Tests;

public class ExecutableResourceCreationTests
{
[Fact]
public void AddJavaAppBuilderShouldNotBeNull()
{
IDistributedApplicationBuilder builder = null!;

Assert.Throws<ArgumentNullException>(() => builder.AddJavaApp("java", Environment.CurrentDirectory, new JavaAppExecutableResourceOptions()));
}

[Fact]
public void AddSpringAppBuilderShouldNotBeNull()
{
IDistributedApplicationBuilder builder = null!;

Assert.Throws<ArgumentNullException>(() => builder.AddSpringApp("spring", Environment.CurrentDirectory, new JavaAppExecutableResourceOptions()));
}

[Fact]
public void AddJavaAppNameShouldNotBeNullOrWhiteSpace()
{
IDistributedApplicationBuilder builder = DistributedApplication.CreateBuilder();

Assert.Throws<ArgumentNullException>(() => builder.AddJavaApp(null!, Environment.CurrentDirectory, new JavaAppExecutableResourceOptions()));
Assert.Throws<ArgumentException>(() => builder.AddJavaApp("", Environment.CurrentDirectory, new JavaAppExecutableResourceOptions()));
}

[Fact]
public void AddSpringAppNameShouldNotBeNullOrWhiteSpace()
{
IDistributedApplicationBuilder builder = DistributedApplication.CreateBuilder();

Assert.Throws<ArgumentNullException>(() => builder.AddSpringApp(null!, Environment.CurrentDirectory, new JavaAppExecutableResourceOptions()));
Assert.Throws<ArgumentException>(() => builder.AddSpringApp("", Environment.CurrentDirectory, new JavaAppExecutableResourceOptions()));
}

[Fact]
public void AddJavaAppWorkingDirectoryShouldNotBeNullOrWhiteSpace()
{
IDistributedApplicationBuilder builder = DistributedApplication.CreateBuilder();

Assert.Throws<ArgumentNullException>(() => builder.AddJavaApp("java", null!, new JavaAppExecutableResourceOptions()));
Assert.Throws<ArgumentException>(() => builder.AddJavaApp("java", "", new JavaAppExecutableResourceOptions()));
}

[Fact]
public void AddJavaAppExecutableResourceOptionsShouldNotBeNull()
{
IDistributedApplicationBuilder builder = DistributedApplication.CreateBuilder();

Assert.Throws<ArgumentNullException>(() => builder.AddJavaApp("java", Environment.CurrentDirectory, null!));
}

[Fact]
public void AddSpringAppContainerResourceOptionsShouldNotBeNull()
{
IDistributedApplicationBuilder builder = DistributedApplication.CreateBuilder();

Assert.Throws<ArgumentNullException>(() => builder.AddSpringApp("spring", Environment.CurrentDirectory, null!));
}

[Fact]
public async Task AddJavaAppContainerDetailsSetOnResource()
{
IDistributedApplicationBuilder builder = DistributedApplication.CreateBuilder();

var options = new JavaAppExecutableResourceOptions
{
ApplicationName = "test.jar",
Args = ["--test"],
OtelAgentPath = "otel-agent",
Port = 8080
};

builder.AddJavaApp("java", Environment.CurrentDirectory, options);

using var app = builder.Build();

var appModel = app.Services.GetRequiredService<DistributedApplicationModel>();

var resource = appModel.Resources.OfType<JavaAppExecutableResource>().SingleOrDefault();

Assert.NotNull(resource);
Assert.Equal("java", resource.Name);

Assert.Equal(Environment.CurrentDirectory, resource.WorkingDirectory);
Assert.Equal("java", resource.Command);

Assert.True(resource.TryGetLastAnnotation(out EndpointAnnotation? httpEndpointAnnotations));
Assert.Equal(options.Port, httpEndpointAnnotations.Port);

Assert.True(resource.TryGetLastAnnotation(out CommandLineArgsCallbackAnnotation? argsAnnotations));
CommandLineArgsCallbackContext context = new([]);
await argsAnnotations.Callback(context);
Assert.All(options.Args, arg => Assert.Contains(arg, context.Args));
Assert.Contains("-jar", context.Args);
Assert.Contains(options.ApplicationName, context.Args);
}
}