Skip to content

Commit

Permalink
Extract Aspire.Hosting.Valkey.Tests project
Browse files Browse the repository at this point in the history
Contributes to dotnet#3185
Contributes to dotnet#4294
  • Loading branch information
eerhardt committed Jul 16, 2024
1 parent 602932b commit 37ddbf3
Show file tree
Hide file tree
Showing 13 changed files with 230 additions and 77 deletions.
17 changes: 12 additions & 5 deletions Aspire.sln
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aspire.Hosting.Qdrant.Tests
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aspire.Hosting.Kafka.Tests", "tests\Aspire.Hosting.Kafka.Tests\Aspire.Hosting.Kafka.Tests.csproj", "{0A83AA67-221E-44B4-9BA9-DC64DC17949E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aspire.Hosting.Valkey.Tests", "tests\Aspire.Hosting.Valkey.Tests\Aspire.Hosting.Valkey.Tests.csproj", "{1C16DC2D-3B79-4081-AC1E-F3F965C61216}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -1332,18 +1334,22 @@ Global
{1BC02557-B78B-48CE-9D3C-488A6B7672F4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1BC02557-B78B-48CE-9D3C-488A6B7672F4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1BC02557-B78B-48CE-9D3C-488A6B7672F4}.Release|Any CPU.Build.0 = Release|Any CPU
{8E2AA85E-C351-47B4-AF91-58557FAD5840}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8E2AA85E-C351-47B4-AF91-58557FAD5840}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8E2AA85E-C351-47B4-AF91-58557FAD5840}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8E2AA85E-C351-47B4-AF91-58557FAD5840}.Release|Any CPU.Build.0 = Release|Any CPU
{7425E5B2-BC47-4521-AC40-B8CECA329E08}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7425E5B2-BC47-4521-AC40-B8CECA329E08}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7425E5B2-BC47-4521-AC40-B8CECA329E08}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7425E5B2-BC47-4521-AC40-B8CECA329E08}.Release|Any CPU.Build.0 = Release|Any CPU
{8E2AA85E-C351-47B4-AF91-58557FAD5840}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8E2AA85E-C351-47B4-AF91-58557FAD5840}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8E2AA85E-C351-47B4-AF91-58557FAD5840}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8E2AA85E-C351-47B4-AF91-58557FAD5840}.Release|Any CPU.Build.0 = Release|Any CPU
{0A83AA67-221E-44B4-9BA9-DC64DC17949E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0A83AA67-221E-44B4-9BA9-DC64DC17949E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0A83AA67-221E-44B4-9BA9-DC64DC17949E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0A83AA67-221E-44B4-9BA9-DC64DC17949E}.Release|Any CPU.Build.0 = Release|Any CPU
{1C16DC2D-3B79-4081-AC1E-F3F965C61216}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1C16DC2D-3B79-4081-AC1E-F3F965C61216}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1C16DC2D-3B79-4081-AC1E-F3F965C61216}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1C16DC2D-3B79-4081-AC1E-F3F965C61216}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -1587,9 +1593,10 @@ Global
{C424395C-1235-41A4-BF55-07880A04368C} = {4981B3A5-4AFD-4191-BF7D-8692D9783D60}
{830A89EC-4029-4753-B25A-068BAE37DEC7} = {4981B3A5-4AFD-4191-BF7D-8692D9783D60}
{1BC02557-B78B-48CE-9D3C-488A6B7672F4} = {830A89EC-4029-4753-B25A-068BAE37DEC7}
{8E2AA85E-C351-47B4-AF91-58557FAD5840} = {830A89EC-4029-4753-B25A-068BAE37DEC7}
{7425E5B2-BC47-4521-AC40-B8CECA329E08} = {830A89EC-4029-4753-B25A-068BAE37DEC7}
{8E2AA85E-C351-47B4-AF91-58557FAD5840} = {830A89EC-4029-4753-B25A-068BAE37DEC7}
{0A83AA67-221E-44B4-9BA9-DC64DC17949E} = {830A89EC-4029-4753-B25A-068BAE37DEC7}
{1C16DC2D-3B79-4081-AC1E-F3F965C61216} = {830A89EC-4029-4753-B25A-068BAE37DEC7}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {6DCEDFEC-988E-4CB3-B45B-191EB5086E0C}
Expand Down
2 changes: 0 additions & 2 deletions tests/Aspire.EndToEnd.Tests/IntegrationServicesFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,6 @@ public Task DumpComponentLogsAsync(TestResourceNames resource, ITestOutputHelper
TestResourceNames.rabbitmq => "rabbitmq",
TestResourceNames.redis => "redis",
TestResourceNames.sqlserver or TestResourceNames.efsqlserver => "sqlserver",
TestResourceNames.valkey => "valkey",
_ => throw new ArgumentException($"Unknown resource: {resource}")
};

Expand Down Expand Up @@ -154,7 +153,6 @@ private static TestResourceNames GetResourcesToSkip()
| TestResourceNames.rabbitmq
| TestResourceNames.redis
| TestResourceNames.garnet
| TestResourceNames.valkey
| TestResourceNames.postgres
| TestResourceNames.efnpgsql
| TestResourceNames.mysql
Expand Down
1 change: 0 additions & 1 deletion tests/Aspire.EndToEnd.Tests/IntegrationServicesTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ public IntegrationServicesTests(ITestOutputHelper testOutput, IntegrationService
[InlineData(TestResourceNames.rabbitmq)]
[InlineData(TestResourceNames.redis)]
[InlineData(TestResourceNames.garnet)]
[InlineData(TestResourceNames.valkey)]
[InlineData(TestResourceNames.sqlserver)]
[InlineData(TestResourceNames.efsqlserver)]
[InlineData(TestResourceNames.milvus)]
Expand Down
2 changes: 0 additions & 2 deletions tests/Aspire.Hosting.Tests/Aspire.Hosting.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
<ProjectReference Include="..\..\src\Aspire.Hosting.Nats\Aspire.Hosting.Nats.csproj" IsAspireProjectResource="false" />
<ProjectReference Include="..\..\src\Aspire.Hosting.Testing\Aspire.Hosting.Testing.csproj" />
<ProjectReference Include="..\..\src\Aspire.Hosting.Python\Aspire.Hosting.Python.csproj" IsAspireProjectResource="false" />
<ProjectReference Include="..\..\src\Aspire.Hosting.Valkey\Aspire.Hosting.Valkey.csproj" IsAspireProjectResource="false" />
<ProjectReference Include="..\Aspire.Components.Common.Tests\Aspire.Components.Common.Tests.csproj" IsAspireProjectResource="false" />
<ProjectReference Include="..\testproject\TestProject.AppHost\TestProject.AppHost.csproj" IsAspireProjectResource="false" />
<ProjectReference Include="..\Aspire.Hosting.Tests.SharedShim\Aspire.Hosting.Tests.SharedShim.csproj" IsAspireProjectResource="false" Aliases="AspireHostingShared" />
Expand All @@ -63,7 +62,6 @@
<Compile Include="$(RepoRoot)src\Aspire.Hosting.Redis\RedisContainerImageTags.cs" />
<Compile Include="$(RepoRoot)src\Aspire.Hosting.Qdrant\QdrantContainerImageTags.cs" />
<Compile Include="$(RepoRoot)src\Aspire.Hosting.SqlServer\SqlServerContainerImageTags.cs" />
<Compile Include="$(RepoRoot)src\Aspire.Hosting.Valkey\ValkeyContainerImageTags.cs" />
<Compile Include="$(RepoRoot)src\Aspire.Hosting.Azure.EventHubs\EventHubsEmulatorContainerImageTags.cs" />

<Compile Include="$(RepoRoot)tests\Aspire.Hosting.Testing.Tests\DistributedApplicationHttpClientExtensionsForTests.cs" />
Expand Down
15 changes: 0 additions & 15 deletions tests/Aspire.Hosting.Tests/ManifestGenerationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
using Aspire.Hosting.Redis;
using Aspire.Hosting.Tests.Helpers;
using Aspire.Hosting.Utils;
using Aspire.Hosting.Valkey;
using Microsoft.Extensions.DependencyInjection;
using Xunit;

Expand Down Expand Up @@ -484,7 +483,6 @@ public void VerifyTestProgramFullManifest()
"ConnectionStrings__mysqldb": "{mysqldb.connectionString}",
"ConnectionStrings__redis": "{redis.connectionString}",
"ConnectionStrings__garnet": "{garnet.connectionString}",
"ConnectionStrings__valkey": "{valkey.connectionString}",
"ConnectionStrings__postgresdb": "{postgresdb.connectionString}",
"ConnectionStrings__rabbitmq": "{rabbitmq.connectionString}",
"ConnectionStrings__mymongodb": "{mymongodb.connectionString}",
Expand Down Expand Up @@ -574,19 +572,6 @@ public void VerifyTestProgramFullManifest()
}
}
},
"valkey": {
"type": "container.v0",
"connectionString": "{valkey.bindings.tcp.host}:{valkey.bindings.tcp.port}",
"image": "{{TestConstants.AspireTestContainerRegistry}}/{{ValkeyContainerImageTags.Image}}:{{ValkeyContainerImageTags.Tag}}",
"bindings": {
"tcp": {
"scheme": "tcp",
"protocol": "tcp",
"transport": "tcp",
"targetPort": 6379
}
}
},
"postgres": {
"type": "container.v0",
"connectionString": "Host={postgres.bindings.tcp.host};Port={postgres.bindings.tcp.port};Username=postgres;Password={postgres-password.value}",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
// The .NET Foundation licenses this file to you under the MIT license.

using System.Net.Sockets;
using Aspire.Hosting.ApplicationModel;
using Aspire.Hosting.Utils;
using Aspire.Hosting.Valkey;
using Microsoft.Extensions.DependencyInjection;
using Xunit;

namespace Aspire.Hosting.Tests.Valkey;
namespace Aspire.Hosting.Valkey.Tests;

public class AddValkeyTests
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>$(NetCurrent)</TargetFramework>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\Aspire.Hosting.Valkey\Aspire.Hosting.Valkey.csproj" />
<ProjectReference Include="..\..\src\Components\Aspire.StackExchange.Redis\Aspire.StackExchange.Redis.csproj" />
<ProjectReference Include="..\Aspire.Hosting.Tests\Aspire.Hosting.Tests.csproj" />
</ItemGroup>

<ItemGroup>
<Compile Include="$(RepoRoot)src\Aspire.Hosting.Valkey\ValkeyContainerImageTags.cs" />
<Compile Include="$(SharedDir)VolumeNameGenerator.cs" Link="Utils\VolumeNameGenerator.cs" />
</ItemGroup>

</Project>
197 changes: 197 additions & 0 deletions tests/Aspire.Hosting.Valkey.Tests/ValkeyFunctionalTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using Aspire.Components.Common.Tests;
using Aspire.Hosting.Utils;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using StackExchange.Redis;
using Xunit;
using Xunit.Abstractions;

namespace Aspire.Hosting.Valkey.Tests;

public class ValkeyFunctionalTests(ITestOutputHelper testOutputHelper)
{
[Fact]
[RequiresDocker]
public async Task VerifyValkeyResource()
{
var cts = new CancellationTokenSource(TimeSpan.FromMinutes(3));

var builder = CreateDistributedApplicationBuilder();

var valkey = builder.AddValkey("valkey");

using var app = builder.Build();

await app.StartAsync();

var hb = Host.CreateApplicationBuilder();

hb.Configuration.AddInMemoryCollection(new Dictionary<string, string?>
{
[$"ConnectionStrings:{valkey.Resource.Name}"] = await valkey.Resource.ConnectionStringExpression.GetValueAsync(default)
});

hb.AddRedisClient(valkey.Resource.Name);

using var host = hb.Build();

await host.StartAsync();

var redisClient = host.Services.GetRequiredService<IConnectionMultiplexer>();

var db = redisClient.GetDatabase();

await db.StringSetAsync("key", "value");

var value = await db.StringGetAsync("key");

Assert.Equal("value", value);
}

[Theory]
[InlineData(true)]
[InlineData(false)]
[RequiresDocker]
public async Task WithDataShouldPersistStateBetweenUsages(bool useVolume)
{
var cts = new CancellationTokenSource(TimeSpan.FromMinutes(3));
string? volumeName = null;
string? bindMountPath = null;

try
{
var builder1 = CreateDistributedApplicationBuilder();
var valkey1 = builder1.AddValkey("valkey");

if (useVolume)
{
// Use a deterministic volume name to prevent them from exhausting the machines if deletion fails
volumeName = VolumeNameGenerator.CreateVolumeName(valkey1, nameof(WithDataShouldPersistStateBetweenUsages));

// if the volume already exists (because of a crashing previous run), try to delete it
DockerUtils.AttemptDeleteDockerVolume(volumeName);
valkey1.WithDataVolume(volumeName);
}
else
{
bindMountPath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
valkey1.WithDataBindMount(bindMountPath);
}

using (var app = builder1.Build())
{
await app.StartAsync();
try
{
var hb = Host.CreateApplicationBuilder();

// BGSAVE is only available in admin mode, enable it for this instance
hb.Configuration.AddInMemoryCollection(new Dictionary<string, string?>
{
[$"ConnectionStrings:{valkey1.Resource.Name}"] = $"{await valkey1.Resource.ConnectionStringExpression.GetValueAsync(default)},allowAdmin=true"
});

hb.AddRedisClient(valkey1.Resource.Name);

using (var host = hb.Build())
{
await host.StartAsync();

var redisClient = host.Services.GetRequiredService<IConnectionMultiplexer>();

var db = redisClient.GetDatabase();

await db.StringSetAsync("key", "value");

// Force Redis to save the keys (snapshotting)
// c.f. https://redis.io/docs/latest/operate/oss_and_stack/management/persistence/

await redisClient.GetServers().First().SaveAsync(SaveType.BackgroundSave);
}
}
finally
{
// Stops the container, or the Volume/mount would still be in use
await app.StopAsync();
}
}

var builder2 = CreateDistributedApplicationBuilder();
var valkey2 = builder2.AddValkey("valkey");

if (useVolume)
{
valkey2.WithDataVolume(volumeName);
}
else
{
valkey2.WithDataBindMount(bindMountPath!);
}

using (var app = builder2.Build())
{
await app.StartAsync();
try
{
var hb = Host.CreateApplicationBuilder();

hb.Configuration.AddInMemoryCollection(new Dictionary<string, string?>
{
[$"ConnectionStrings:{valkey2.Resource.Name}"] = await valkey2.Resource.ConnectionStringExpression.GetValueAsync(default)
});

hb.AddRedisClient(valkey2.Resource.Name);

using (var host = hb.Build())
{
await host.StartAsync();

var redisClient = host.Services.GetRequiredService<IConnectionMultiplexer>();

var db = redisClient.GetDatabase();

var value = await db.StringGetAsync("key");

Assert.Equal("value", value);
}
}
finally
{
// Stops the container, or the Volume/mount would still be in use
await app.StopAsync();
}
}
}
finally
{
if (volumeName is not null)
{
DockerUtils.AttemptDeleteDockerVolume(volumeName);
}

if (bindMountPath is not null)
{
try
{
File.Delete(bindMountPath);
}
catch
{
// Don't fail test if we can't clean the temporary folder
}
}
}
}

private TestDistributedApplicationBuilder CreateDistributedApplicationBuilder()
{
var builder = TestDistributedApplicationBuilder.CreateWithTestContainerRegistry();
builder.Services.AddXunitLogging(testOutputHelper);
return builder;
}
}
3 changes: 1 addition & 2 deletions tests/testproject/Common/TestResourceNames.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,9 @@ public enum TestResourceNames
garnet = 1 << 12,
eventhubs = 1 << 13,
milvus = 1 << 14,
valkey = 1 << 15,
efsqlserver = 1 << 16,
efcosmos = 1 << 17,
All = cosmos | dashboard | mongodb | mysql | oracledatabase | efmysql | postgres | rabbitmq | redis | sqlserver | efnpgsql | garnet | eventhubs | milvus | valkey | efsqlserver | efcosmos
All = cosmos | dashboard | mongodb | mysql | oracledatabase | efmysql | postgres | rabbitmq | redis | sqlserver | efnpgsql | garnet | eventhubs | milvus | efsqlserver | efcosmos
}

public static class TestResourceNamesExtensions
Expand Down
6 changes: 0 additions & 6 deletions tests/testproject/TestProject.AppHost/TestProgram.cs
Original file line number Diff line number Diff line change
Expand Up @@ -109,12 +109,6 @@ private TestProgram(
var garnet = AppBuilder.AddGarnet("garnet");
IntegrationServiceABuilder = IntegrationServiceABuilder.WithReference(garnet);
}
if (!resourcesToSkip.HasFlag(TestResourceNames.valkey))
{
var valkey = AppBuilder.AddValkey("valkey")
.WithImageRegistry(AspireTestContainerRegistry);
IntegrationServiceABuilder = IntegrationServiceABuilder.WithReference(valkey);
}
if (!resourcesToSkip.HasFlag(TestResourceNames.postgres) || !resourcesToSkip.HasFlag(TestResourceNames.efnpgsql))
{
var postgresDbName = "postgresdb";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
<ProjectReference Include="..\..\..\src\Aspire.Hosting.RabbitMQ\Aspire.Hosting.RabbitMQ.csproj" IsAspireProjectResource="false" />
<ProjectReference Include="..\..\..\src\Aspire.Hosting.Redis\Aspire.Hosting.Redis.csproj" IsAspireProjectResource="false" />
<ProjectReference Include="..\..\..\src\Aspire.Hosting.SqlServer\Aspire.Hosting.SqlServer.csproj" IsAspireProjectResource="false" />
<ProjectReference Include="..\..\..\src\Aspire.Hosting.Valkey\Aspire.Hosting.Valkey.csproj" IsAspireProjectResource="false" />

</ItemGroup>
<ItemGroup Condition="'$(TestsRunningOutsideOfRepo)' == 'true'">
Expand All @@ -40,7 +39,6 @@
<PackageReference Include="Aspire.Hosting.RabbitMQ" />
<PackageReference Include="Aspire.Hosting.Redis" />
<PackageReference Include="Aspire.Hosting.SqlServer" />
<PackageReference Include="Aspire.Hosting.Valkey" />
</ItemGroup>

<ItemGroup>
Expand Down
Loading

0 comments on commit 37ddbf3

Please sign in to comment.