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

Split redis tests into separate test assembly #4468

Merged
merged 19 commits into from
Jul 10, 2024
Merged

Conversation

davidfowl
Copy link
Member

@davidfowl davidfowl commented Jun 11, 2024

Initial stab at #4294.

I added solution folders for tests:

image

TODO:

  • I need to make to move the functional tests for redis.
Microsoft Reviewers: Open in CodeFlow

@dotnet-issue-labeler dotnet-issue-labeler bot added the area-integrations Issues pertaining to Aspire Integrations packages label Jun 11, 2024
@@ -18,6 +18,7 @@

<ItemGroup>
<InternalsVisibleTo Include="Aspire.Hosting.Tests" />
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should aim to remove this.

public class RedisFunctionalTests
{
[Fact]
public async Task VerifyRedisResource()
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this test adds value over top of the other Redis Hosting tests, since it actually connects a client to it.

It seems like a "middle of the ground" test. Not a unit test, but not a full end-to-end functional test like

[InlineData(TestResourceNames.redis)]
[InlineData(TestResourceNames.garnet)]
[InlineData(TestResourceNames.valkey)]
[InlineData(TestResourceNames.sqlserver)]
[InlineData(TestResourceNames.milvus)]
public Task VerifyComponentWorks(TestResourceNames resourceName)
=> RunTestAsync(async () =>
{
_integrationServicesFixture.EnsureAppHasResources(resourceName);
try
{
var response = await _integrationServicesFixture.IntegrationServiceA.HttpGetAsync("http", $"/{resourceName}/verify");
var responseContent = await response.Content.ReadAsStringAsync();
Assert.True(response.IsSuccessStatusCode, responseContent);
}
catch
{
await _integrationServicesFixture.DumpComponentLogsAsync(resourceName, _testOutput);
throw;
}
});

It is definitely simpler than the end-to-end tests.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like these tests, they are a good smoke test. I do think they need to be broken up though. That way if I've made some changes in "redis" land I can run everything related to Redis just by pointing at a particular test assembly.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it's testing less than the current E2E tests, at least when looking from the Redis POV. The E2E is only creating a distinct web api project to use the component, that's the difference with this local functional test.

Do we still need the Redis portion of the E2E test if so? Or should we extract the current portion of the E2E test into a separate project?

For instance, could we not add more volumes testing with this new functional test project already?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it's testing less than the current E2E tests

The part that the current E2E tests cover that aren't covered here is the "WithReference" portion that connects a separate project with a resource. This is being simulated in the current test with:

        hb.Configuration.AddInMemoryCollection(new Dictionary<string, string?>
        {
            ["ConnectionStrings:redis"] = await redis.Resource.GetConnectionStringAsync()
        });

Do we still need the Redis portion of the E2E test if so? Or should we extract the current portion of the E2E test into a separate project?

I think once we have all the AppHost resource tests split into separate test assemblies, and FunctionalTests like this one for each resource, we can remove the bulk of the resources from the E2E test, and only keep maybe ~5 core resources being tested there. That way when a new resource/component gets added we don't need to update the E2E test and have it continually grow, like it is doing today.

# Conflicts:
#	Aspire.sln
#	src/Aspire.Hosting/Aspire.Hosting.csproj
#	tests/Aspire.Hosting.Containers.Tests/ContainerResourceBuilderTests.cs
Otherwise would try to run it on Windows in CI where Docker is not available
@sebastienros
Copy link
Member

Added some tests for WithDataVolume() for now. I don't know yet how we can clean these once the test is done.

@dotnet-bot
Copy link
Contributor

‼️ Found issues ‼️

Project Coverage Type Expected Actual
Microsoft.Extensions.ServiceDiscovery Branch 81 79.31 🔻
Microsoft.Extensions.ServiceDiscovery Line 81 79.01 🔻

Full code coverage report: https://dev.azure.com/dnceng-public/public/_build/results?buildId=726269&view=codecoverage-tab

@sebastienros sebastienros marked this pull request as ready for review July 3, 2024 05:42
@sebastienros sebastienros requested a review from eerhardt July 3, 2024 16:17
@eerhardt
Copy link
Member

eerhardt commented Jul 3, 2024

@sebastienros - it looks like the tests are still failing

@radical
Copy link
Member

radical commented Jul 3, 2024

Aspire.Hosting.Redis.Tests logs show:

could not create the container {"Container": {"name":"redis-mcqtmvnk-64491c08"}, "Reconciliation": 3, "error": "docker command 'CreateContainer' returned with non-zero exit code 1: command output: Stdout: '' Stderr: 'Unable to find image 'redis:7.2' locally\nError response from daemon: toomanyrequests: You have reached your pull rate limit. You may increase the limit by authenticating and upgrading: https://www.docker.com/increase-rate-limit\n'"}

@radical
Copy link
Member

radical commented Jul 3, 2024

At least that was the case with the first attempt.

I'm not sure about the second one because this shows ##[error]Artifact Logs_Build_Linux_Release already exists for build 728907. for that. That file name needs to append the attempt number.

Copy link
Member

@eerhardt eerhardt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should split this apart and add the Volume/BindMount tests in a separate PR?

@@ -22,6 +22,7 @@

<ItemGroup>
<InternalsVisibleTo Include="Aspire.Hosting.Tests" />
<InternalsVisibleTo Include="Aspire.Hosting.Redis.Tests" />
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sebastienros - can we remove this? What is it needed for?

Copy link
Member

@sebastienros sebastienros Jul 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RedisContainerImageTags
RedisCommanderConfigWriterHook

Are used in these tests and internal.
This is why Aspire.Hosting.Tests was already listed, because these tests are coming from this project (moved to this new Aspire.Hosting.Redis.Tests)

src/Aspire.Hosting/Aspire.Hosting.csproj Outdated Show resolved Hide resolved
Comment on lines 57 to 58
var redis = builder.AddRedis("redis").WithImageTag("7.1");
Assert.Equal("7.1", redis.Resource.Annotations.OfType<ContainerImageAnnotation>().Single().Tag);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be reverted? Why it is using Redis in the core "Hosting.Containers" tests?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reverted

Comment on lines 8 to 9
<ProjectReference Include="..\..\src\Aspire.Hosting.AppHost\Aspire.Hosting.AppHost.csproj" IsAspireProjectResource="false" />
<ProjectReference Include="..\..\src\Aspire.Hosting.Redis\Aspire.Hosting.Redis.csproj" IsAspireProjectResource="false" />
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<ProjectReference Include="..\..\src\Aspire.Hosting.AppHost\Aspire.Hosting.AppHost.csproj" IsAspireProjectResource="false" />
<ProjectReference Include="..\..\src\Aspire.Hosting.Redis\Aspire.Hosting.Redis.csproj" IsAspireProjectResource="false" />
<ProjectReference Include="..\..\src\Aspire.Hosting.AppHost\Aspire.Hosting.AppHost.csproj" />
<ProjectReference Include="..\..\src\Aspire.Hosting.Redis\Aspire.Hosting.Redis.csproj" />

Are these needed? This project doesn't have <IsAspireHost>true</IsAspireHost>

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works as you suggest

tests/Aspire.Hosting.Redis.Tests/RedisFunctionalTests.cs Outdated Show resolved Hide resolved
tests/Aspire.Hosting.Tests/Aspire.Hosting.Tests.csproj Outdated Show resolved Hide resolved

await VerifyDataPersistence(
options => options.WithDataVolume(volumeName).WithPersistence(snapshotInterval),
async redisClient => await Task.Delay(snapshotInterval + TimeSpan.FromSeconds(1))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like it will be flaky - especially on slow machines.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am ok to remove it, as long as we agree that the other explicit SAVE call is sufficient to test the functionality since we already have a unit test that ensures the correct --save argument is passed with a custom timespan. This test is only validating that the feature actually works in Redis. Or we can add more that "1 more second after the time that Redis should have saved it".

@@ -169,7 +171,10 @@ public async Task SingleRedisInstanceProducesCorrectRedisHostsVariable(string co

var commander = builder.Resources.Single(r => r.Name.EndsWith("-commander"));

var config = await EnvironmentVariableEvaluator.GetEnvironmentVariablesAsync(commander, DistributedApplicationOperation.Run, TestServiceProvider.Instance);
var config = await EnvironmentVariableEvaluator.GetEnvironmentVariablesAsync(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line too long couldn't read the code.

tests/Aspire.Hosting.Redis.Tests/RedisFunctionalTests.cs Outdated Show resolved Hide resolved
Assert.True(value.IsNull);
}

await app.StopAsync();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This required with AttemptDeleteDockerVolume as otherwise the container is still running until the test is done, and holds a ref to it. Also the two containers exist concurrently without it.

I would expect app.Dispose to call StopAsync but it's not the case.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would expect app.Dispose to call StopAsync but it's not the case.

I would expect the same thing. @mitchdenny - is this a bug in DistributedApplication?

@eerhardt
Copy link
Member

eerhardt commented Jul 9, 2024

/azp run

Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@sebastienros sebastienros merged commit 3ddc4ca into main Jul 10, 2024
9 checks passed
@sebastienros sebastienros deleted the davidfowl/redis-tests branch July 10, 2024 06:45
@mitchdenny
Copy link
Member

@sebastienros looks like the restructured tests are failing.

@sebastienros
Copy link
Member

@mitchdenny are you aware of #4786 ?
This is hitting us hard, we are working on it.

@mitchdenny
Copy link
Member

I'm aware of that, although I think these test failures aren't related (I could be wrong). If they are then feel free to ignore, and obviously #4786 takes priority.

@sebastienros
Copy link
Member

I think it's related, last time I had the same issue I asked @radical and he showed me the throttling issue. Also these tests worked earlier when Eric triggered a new build (when the quotas got renewed apparently). But I'll check in the log to see if I can find a confirmation.

@sebastienros
Copy link
Member

Confirmed in the logs:

fail: Aspire.Hosting.Dcp.dcpctrl.ContainerReconciler[0]
      could not create the container	{"Container": {"name":"redis-fexhgyze-5dedf3af"}, "Reconciliation": 3, "error": "docker command 'CreateContainer' returned with non-zero exit code 1: command output: Stdout: '' Stderr: 'Unable to find image 'redis:7.2' locally\nError response from daemon: toomanyrequests: You have reached your pull rate limit. You may increase the limit by authenticating and upgrading: 

It's showing up first because it's a job before Helix runs, it's the first tests that try to download docker images. Then the Job is terminated.

@github-actions github-actions bot locked and limited conversation to collaborators Aug 10, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-integrations Issues pertaining to Aspire Integrations packages
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants