Skip to content

Commit

Permalink
Refactor functional tests
Browse files Browse the repository at this point in the history
- Split the functional Components Integration tests out of Aspire.Hosting.Tests into a new EndToEnd project.
- Start the test AppHost project using `dotnet run` instead of running the DistributedAppBuilder inline in the tests. This allows for the tests to run on a separate machine than where the tests are built.
    - Along with this, we need to pass information from the test AppHost to the test about its endpoints, and give it a signal to "stop". Instead of trying to find a way to CTRL+C cross-platform, read from stdin for a "Stop" command.
  • Loading branch information
eerhardt committed Feb 2, 2024
1 parent 0d7749b commit b8d0c21
Show file tree
Hide file tree
Showing 20 changed files with 292 additions and 159 deletions.
7 changes: 7 additions & 0 deletions Aspire.sln
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mongo.ApiService", "playgro
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CatalogModel", "playground\eShopLite\CatalogModel\CatalogModel.csproj", "{83267206-9438-42CD-860C-C92E7DBAA4C3}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aspire.EndToEnd.Tests", "tests\Aspire.EndToEnd.Tests\Aspire.EndToEnd.Tests.csproj", "{C1483B79-4FE9-47FF-B544-EB5DBB7A0A3E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -585,6 +587,10 @@ Global
{83267206-9438-42CD-860C-C92E7DBAA4C3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{83267206-9438-42CD-860C-C92E7DBAA4C3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{83267206-9438-42CD-860C-C92E7DBAA4C3}.Release|Any CPU.Build.0 = Release|Any CPU
{C1483B79-4FE9-47FF-B544-EB5DBB7A0A3E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C1483B79-4FE9-47FF-B544-EB5DBB7A0A3E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C1483B79-4FE9-47FF-B544-EB5DBB7A0A3E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C1483B79-4FE9-47FF-B544-EB5DBB7A0A3E}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -688,6 +694,7 @@ Global
{8F132275-233C-4121-AC6F-352C902FA064} = {C544D8A6-977E-40EA-8B1A-1FB2146A2108}
{40EC38A2-69DB-4759-81C8-13F31090FEA6} = {C544D8A6-977E-40EA-8B1A-1FB2146A2108}
{83267206-9438-42CD-860C-C92E7DBAA4C3} = {A68BA1A5-1604-433D-9778-DC0199831C2A}
{C1483B79-4FE9-47FF-B544-EB5DBB7A0A3E} = {4981B3A5-4AFD-4191-BF7D-8692D9783D60}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {6DCEDFEC-988E-4CB3-B45B-191EB5086E0C}
Expand Down
7 changes: 7 additions & 0 deletions tests/Aspire.EndToEnd.Tests/Aspire.EndToEnd.Tests.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

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

</Project>
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
// 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.Tests.Helpers;
using Xunit;

namespace Aspire.Hosting.Tests.Cosmos;
namespace Aspire.EndToEnd.Tests.Cosmos;

[Collection("IntegrationServices")]
public class CosmosFunctionalTests
Expand All @@ -16,15 +15,14 @@ public CosmosFunctionalTests(IntegrationServicesFixture integrationServicesFixtu
_integrationServicesFixture = integrationServicesFixture;
}

[LocalOnlyFact()]
[Fact]
public async Task VerifyCosmosWorks()
{
var testProgram = _integrationServicesFixture.TestProgram;
var client = _integrationServicesFixture.HttpClient;

using var cts = new CancellationTokenSource(TimeSpan.FromMinutes(6));

var response = await testProgram.IntegrationServiceABuilder!.HttpGetAsync(client, "http", "/cosmos/verify", cts.Token);
var response = await _integrationServicesFixture.IntegrationServiceA.HttpGetAsync(client, "http", "/cosmos/verify", cts.Token);
var responseContent = await response.Content.ReadAsStringAsync();

Assert.True(response.IsSuccessStatusCode, responseContent);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
// 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.Tests.Helpers;
using Xunit;

namespace Aspire.Hosting.Tests;
namespace Aspire.EndToEnd.Tests;

[Collection("IntegrationServices")]
public class IntegrationServicesTests
Expand All @@ -16,22 +15,15 @@ public IntegrationServicesTests(IntegrationServicesFixture integrationServicesFi
_integrationServicesFixture = integrationServicesFixture;
}

[LocalOnlyFact]
[Fact]
public async Task VerifyHealthyOnIntegrationServiceA()
{
var testProgram = _integrationServicesFixture.TestProgram;
var client = _integrationServicesFixture.HttpClient;

using var cts = new CancellationTokenSource(TimeSpan.FromMinutes(1));

// Make sure all services are running
await testProgram.ServiceABuilder.HttpGetPidAsync(client, "http", cts.Token);
await testProgram.ServiceBBuilder.HttpGetPidAsync(client, "http", cts.Token);
await testProgram.ServiceCBuilder.HttpGetPidAsync(client, "http", cts.Token);
await testProgram.IntegrationServiceABuilder!.HttpGetPidAsync(client, "http", cts.Token);

// We wait until timeout for the /health endpoint to return successfully. We assume
// that components wired up into this project have health checks enabled.
await testProgram.IntegrationServiceABuilder!.WaitForHealthyStatusAsync(client, "http", cts.Token);
await _integrationServicesFixture.IntegrationServiceA.WaitForHealthyStatusAsync(client, "http", cts.Token);
}
}
Original file line number Diff line number Diff line change
@@ -1,30 +1,27 @@
// 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.Tests.Helpers;
using Xunit;

namespace Aspire.Hosting.Tests.Kafka;
namespace Aspire.EndToEnd.Tests.Kafka;

[Collection("IntegrationServices")]
public class KafkaFunctionalTests(IntegrationServicesFixture integrationServicesFixture)
{
[LocalOnlyFact]
[Fact]
public async Task KafkaComponentCanProduceAndConsume()
{
var testProgram = integrationServicesFixture.TestProgram;

var client = integrationServicesFixture.HttpClient;

using var cts = new CancellationTokenSource(TimeSpan.FromMinutes(1));

string topic = $"topic-{Guid.NewGuid()}";

var response = await testProgram.IntegrationServiceABuilder!.HttpGetAsync(client, "http", $"/kafka/produce/{topic}", cts.Token);
var response = await integrationServicesFixture.IntegrationServiceA.HttpGetAsync(client, "http", $"/kafka/produce/{topic}", cts.Token);
var responseContent = await response.Content.ReadAsStringAsync();
Assert.True(response.IsSuccessStatusCode, responseContent);

response = await testProgram.IntegrationServiceABuilder!.HttpGetAsync(client, "http", $"/kafka/consume/{topic}", cts.Token);
response = await integrationServicesFixture.IntegrationServiceA.HttpGetAsync(client, "http", $"/kafka/consume/{topic}", cts.Token);
responseContent = await response.Content.ReadAsStringAsync();
Assert.True(response.IsSuccessStatusCode, responseContent);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
// 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.Tests.Helpers;
using Xunit;

namespace Aspire.Hosting.Tests.MongoDB;
namespace Aspire.EndToEnd.Tests.MongoDB;

[Collection("IntegrationServices")]
public class MongoDBFunctionalTests
Expand All @@ -16,15 +15,14 @@ public MongoDBFunctionalTests(IntegrationServicesFixture integrationServicesFixt
_integrationServicesFixture = integrationServicesFixture;
}

[LocalOnlyFact()]
[Fact]
public async Task VerifyMongoWorks()
{
var testProgram = _integrationServicesFixture.TestProgram;
var client = _integrationServicesFixture.HttpClient;

using var cts = new CancellationTokenSource(TimeSpan.FromMinutes(1));

var response = await testProgram.IntegrationServiceABuilder!.HttpGetAsync(client, "http", "/mongodb/verify", cts.Token);
var response = await _integrationServicesFixture.IntegrationServiceA.HttpGetAsync(client, "http", "/mongodb/verify", cts.Token);
var responseContent = await response.Content.ReadAsStringAsync();

Assert.True(response.IsSuccessStatusCode, responseContent);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
// 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.Tests.Helpers;
using Xunit;

namespace Aspire.Hosting.Tests.MySql;
namespace Aspire.EndToEnd.Tests.MySql;

[Collection("IntegrationServices")]
public class MySqlFunctionalTests
Expand All @@ -16,18 +15,17 @@ public MySqlFunctionalTests(IntegrationServicesFixture integrationServicesFixtur
_integrationServicesFixture = integrationServicesFixture;
}

[LocalOnlyFact()]
[Fact]
public async Task VerifyMySqlWorks()
{
// MySql health check reports healthy during temporary server phase, c.f. https://github.com/Xabaril/AspNetCore.Diagnostics.HealthChecks/issues/2031
// This is mitigated by standard resilience handlers in the IntegrationServicesFixture HttpClient configuration

var testProgram = _integrationServicesFixture.TestProgram;
var client = _integrationServicesFixture.HttpClient;

using var cts = new CancellationTokenSource(TimeSpan.FromMinutes(1));

var response = await testProgram.IntegrationServiceABuilder!.HttpGetAsync(client, "http", "/mysql/verify", cts.Token);
var response = await _integrationServicesFixture.IntegrationServiceA.HttpGetAsync(client, "http", "/mysql/verify", cts.Token);
var responseContent = await response.Content.ReadAsStringAsync();

Assert.True(response.IsSuccessStatusCode, responseContent);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
// 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.Tests.Helpers;
using Xunit;

namespace Aspire.Hosting.Tests.MySql;
namespace Aspire.EndToEnd.Tests.MySql;

[Collection("IntegrationServices")]
public class PomeloEFCoreMySqlFunctionalTests
Expand All @@ -16,15 +15,14 @@ public PomeloEFCoreMySqlFunctionalTests(IntegrationServicesFixture integrationSe
_integrationServicesFixture = integrationServicesFixture;
}

[LocalOnlyFact()]
[Fact]
public async Task VerifyPomeloEFCoreMySqlWorks()
{
var testProgram = _integrationServicesFixture.TestProgram;
var client = _integrationServicesFixture.HttpClient;

using var cts = new CancellationTokenSource(TimeSpan.FromMinutes(1));

var response = await testProgram.IntegrationServiceABuilder!.HttpGetAsync(client, "http", "/pomelo/verify", cts.Token);
var response = await _integrationServicesFixture.IntegrationServiceA.HttpGetAsync(client, "http", "/pomelo/verify", cts.Token);
var responseContent = await response.Content.ReadAsStringAsync();

Assert.True(response.IsSuccessStatusCode, responseContent);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
// 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.Tests.Helpers;
using Xunit;

namespace Aspire.Hosting.Tests.Oracle;
namespace Aspire.EndToEnd.Tests.Oracle;

[Collection("IntegrationServices")]
public class OracleDatabaseFunctionalTests
Expand All @@ -16,15 +15,14 @@ public OracleDatabaseFunctionalTests(IntegrationServicesFixture integrationServi
_integrationServicesFixture = integrationServicesFixture;
}

[LocalOnlyFact()]
[Fact]
public async Task VerifyOracleDatabaseWorks()
{
var testProgram = _integrationServicesFixture.TestProgram;
var client = _integrationServicesFixture.HttpClient;

using var cts = new CancellationTokenSource(TimeSpan.FromMinutes(1));

var response = await testProgram.IntegrationServiceABuilder!.HttpGetAsync(client, "http", "/oracledatabase/verify", cts.Token);
var response = await _integrationServicesFixture.IntegrationServiceA.HttpGetAsync(client, "http", "/oracledatabase/verify", cts.Token);
var responseContent = await response.Content.ReadAsStringAsync();

Assert.True(response.IsSuccessStatusCode, responseContent);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
// 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.Tests.Helpers;
using Xunit;

namespace Aspire.Hosting.Tests.Postgres;
namespace Aspire.EndToEnd.Tests.Postgres;

[Collection("IntegrationServices")]
public class PostgresFunctionalTests
Expand All @@ -16,15 +15,14 @@ public PostgresFunctionalTests(IntegrationServicesFixture integrationServicesFix
_integrationServicesFixture = integrationServicesFixture;
}

[LocalOnlyFact()]
[Fact]
public async Task VerifyPostgresWorks()
{
var testProgram = _integrationServicesFixture.TestProgram;
var client = _integrationServicesFixture.HttpClient;

using var cts = new CancellationTokenSource(TimeSpan.FromMinutes(1));

var response = await testProgram.IntegrationServiceABuilder!.HttpGetAsync(client, "http", "/postgres/verify", cts.Token);
var response = await _integrationServicesFixture.IntegrationServiceA.HttpGetAsync(client, "http", "/postgres/verify", cts.Token);
var responseContent = await response.Content.ReadAsStringAsync();

Assert.True(response.IsSuccessStatusCode, responseContent);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
// 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.Tests.Helpers;
using Xunit;

namespace Aspire.Hosting.Tests.RabbitMQ;
namespace Aspire.EndToEnd.Tests.RabbitMQ;

[Collection("IntegrationServices")]
public class RabbitMQFunctionalTests
Expand All @@ -16,15 +15,14 @@ public RabbitMQFunctionalTests(IntegrationServicesFixture integrationServicesFix
_integrationServicesFixture = integrationServicesFixture;
}

[LocalOnlyFact()]
[Fact]
public async Task VerifyRabbitMQWorks()
{
var testProgram = _integrationServicesFixture.TestProgram;
var client = _integrationServicesFixture.HttpClient;

using var cts = new CancellationTokenSource(TimeSpan.FromMinutes(1));

var response = await testProgram.IntegrationServiceABuilder!.HttpGetAsync(client, "http", "/rabbitmq/verify", cts.Token);
var response = await _integrationServicesFixture.IntegrationServiceA.HttpGetAsync(client, "http", "/rabbitmq/verify", cts.Token);
var responseContent = await response.Content.ReadAsStringAsync();

Assert.True(response.IsSuccessStatusCode, responseContent);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
// 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.Tests.Helpers;
using Xunit;

namespace Aspire.Hosting.Tests.Redis;
namespace Aspire.EndToEnd.Tests.Redis;

[Collection("IntegrationServices")]
public class RedisFunctionalTests
Expand All @@ -16,15 +15,14 @@ public RedisFunctionalTests(IntegrationServicesFixture integrationServicesFixtur
_integrationServicesFixture = integrationServicesFixture;
}

[LocalOnlyFact()]
[Fact]
public async Task VerifyRedisWorks()
{
var testProgram = _integrationServicesFixture.TestProgram;
var client = _integrationServicesFixture.HttpClient;

using var cts = new CancellationTokenSource(TimeSpan.FromMinutes(1));

var response = await testProgram.IntegrationServiceABuilder!.HttpGetAsync(client, "http", "/redis/verify", cts.Token);
var response = await _integrationServicesFixture.IntegrationServiceA.HttpGetAsync(client, "http", "/redis/verify", cts.Token);
var responseContent = await response.Content.ReadAsStringAsync();

Assert.True(response.IsSuccessStatusCode, responseContent);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
// 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.Tests.Helpers;
using Xunit;

namespace Aspire.Hosting.Tests.SqlServer;
namespace Aspire.EndToEnd.Tests.SqlServer;

[Collection("IntegrationServices")]
public class SqlServerFunctionalTests
Expand All @@ -16,15 +15,14 @@ public SqlServerFunctionalTests(IntegrationServicesFixture integrationServicesFi
_integrationServicesFixture = integrationServicesFixture;
}

[LocalOnlyFact()]
[Fact]
public async Task VerifySqlServerWorks()
{
var testProgram = _integrationServicesFixture.TestProgram;
var client = _integrationServicesFixture.HttpClient;

using var cts = new CancellationTokenSource(TimeSpan.FromMinutes(1));

var response = await testProgram.IntegrationServiceABuilder!.HttpGetAsync(client, "http", "/sqlserver/verify", cts.Token);
var response = await _integrationServicesFixture.IntegrationServiceA.HttpGetAsync(client, "http", "/sqlserver/verify", cts.Token);
var responseContent = await response.Content.ReadAsStringAsync();

Assert.True(response.IsSuccessStatusCode, responseContent);
Expand Down
Loading

0 comments on commit b8d0c21

Please sign in to comment.