diff --git a/playground/AzureSearchEndToEnd/AzureSearch.AppHost/Program.cs b/playground/AzureSearchEndToEnd/AzureSearch.AppHost/Program.cs index 254c1b047fb..bba4bbaf561 100644 --- a/playground/AzureSearchEndToEnd/AzureSearch.AppHost/Program.cs +++ b/playground/AzureSearchEndToEnd/AzureSearch.AppHost/Program.cs @@ -9,11 +9,14 @@ .WithExternalHttpEndpoints() .WithReference(azureSearch); +#if !SKIP_DASHBOARD_REFERENCE // This project is only added in playground projects to support development/debugging // of the dashboard. It is not required in end developer code. Comment out this code -// to test end developer dashboard launch experience. Refer to Directory.Build.props -// for the path to the dashboard binary (defaults to the Aspire.Dashboard bin output -// in the artifacts dir). +// or build with `/p:SkipDashboardReference=true`, to test end developer +// dashboard launch experience, Refer to Directory.Build.props for the path to +// the dashboard binary (defaults to the Aspire.Dashboard bin output in the +// artifacts dir). builder.AddProject(KnownResourceNames.AspireDashboard); +#endif builder.Build().Run(); diff --git a/playground/BrowserTelemetry/BrowserTelemetry.AppHost/Program.cs b/playground/BrowserTelemetry/BrowserTelemetry.AppHost/Program.cs index 7eb73fdb8e1..1934185e924 100644 --- a/playground/BrowserTelemetry/BrowserTelemetry.AppHost/Program.cs +++ b/playground/BrowserTelemetry/BrowserTelemetry.AppHost/Program.cs @@ -6,11 +6,14 @@ builder.AddProject("web") .WithExternalHttpEndpoints(); +#if !SKIP_DASHBOARD_REFERENCE // This project is only added in playground projects to support development/debugging // of the dashboard. It is not required in end developer code. Comment out this code -// to test end developer dashboard launch experience. Refer to Directory.Build.props -// for the path to the dashboard binary (defaults to the Aspire.Dashboard bin output -// in the artifacts dir). +// or build with `/p:SkipDashboardReference=true`, to test end developer +// dashboard launch experience, Refer to Directory.Build.props for the path to +// the dashboard binary (defaults to the Aspire.Dashboard bin output in the +// artifacts dir). builder.AddProject(KnownResourceNames.AspireDashboard); +#endif builder.Build().Run(); diff --git a/playground/BrowserTelemetry/BrowserTelemetry.Web/BrowserTelemetry.Web.csproj b/playground/BrowserTelemetry/BrowserTelemetry.Web/BrowserTelemetry.Web.csproj index f9179c2ca90..dce9feb1d9a 100644 --- a/playground/BrowserTelemetry/BrowserTelemetry.Web/BrowserTelemetry.Web.csproj +++ b/playground/BrowserTelemetry/BrowserTelemetry.Web/BrowserTelemetry.Web.csproj @@ -4,13 +4,15 @@ net8.0 enable enable + + true - + - + diff --git a/playground/Directory.Build.targets b/playground/Directory.Build.targets index 994e9b855d5..4ffec86c99f 100644 --- a/playground/Directory.Build.targets +++ b/playground/Directory.Build.targets @@ -1,6 +1,12 @@ + + + true + + diff --git a/playground/OpenAIEndToEnd/OpenAIEndToEnd.AppHost/Program.cs b/playground/OpenAIEndToEnd/OpenAIEndToEnd.AppHost/Program.cs index 2dae8e07479..d80fb1f50f5 100644 --- a/playground/OpenAIEndToEnd/OpenAIEndToEnd.AppHost/Program.cs +++ b/playground/OpenAIEndToEnd/OpenAIEndToEnd.AppHost/Program.cs @@ -15,11 +15,14 @@ .WithReference(openai) .WithEnvironment("OpenAI__DeploymentName", deploymentAndModelName); +#if !SKIP_DASHBOARD_REFERENCE // This project is only added in playground projects to support development/debugging // of the dashboard. It is not required in end developer code. Comment out this code -// to test end developer dashboard launch experience. Refer to Directory.Build.props -// for the path to the dashboard binary (defaults to the Aspire.Dashboard bin output -// in the artifacts dir). +// or build with `/p:SkipDashboardReference=true`, to test end developer +// dashboard launch experience, Refer to Directory.Build.props for the path to +// the dashboard binary (defaults to the Aspire.Dashboard bin output in the +// artifacts dir). builder.AddProject(KnownResourceNames.AspireDashboard); +#endif builder.Build().Run(); diff --git a/playground/OracleEndToEnd/OracleEndToEnd.AppHost/Program.cs b/playground/OracleEndToEnd/OracleEndToEnd.AppHost/Program.cs index a76fea896d9..0d526537fb2 100644 --- a/playground/OracleEndToEnd/OracleEndToEnd.AppHost/Program.cs +++ b/playground/OracleEndToEnd/OracleEndToEnd.AppHost/Program.cs @@ -10,11 +10,14 @@ builder.AddProject("api") .WithReference(pdb); +#if !SKIP_DASHBOARD_REFERENCE // This project is only added in playground projects to support development/debugging // of the dashboard. It is not required in end developer code. Comment out this code -// to test end developer dashboard launch experience. Refer to Directory.Build.props -// for the path to the dashboard binary (defaults to the Aspire.Dashboard bin output -// in the artifacts dir). +// or build with `/p:SkipDashboardReference=true`, to test end developer +// dashboard launch experience, Refer to Directory.Build.props for the path to +// the dashboard binary (defaults to the Aspire.Dashboard bin output in the +// artifacts dir). builder.AddProject(KnownResourceNames.AspireDashboard); +#endif builder.Build().Run(); diff --git a/playground/bicep/BicepSample.AppHost/Program.cs b/playground/bicep/BicepSample.AppHost/Program.cs index b63a68f688d..3de3fe59c6a 100644 --- a/playground/bicep/BicepSample.AppHost/Program.cs +++ b/playground/bicep/BicepSample.AppHost/Program.cs @@ -79,11 +79,14 @@ .WithEnvironment("bicepValue0", bicep1.GetOutput("val0")) .WithEnvironment("bicepValue1", bicep1.GetOutput("val1")); +#if !SKIP_DASHBOARD_REFERENCE // This project is only added in playground projects to support development/debugging // of the dashboard. It is not required in end developer code. Comment out this code -// to test end developer dashboard launch experience. Refer to Directory.Build.props -// for the path to the dashboard binary (defaults to the Aspire.Dashboard bin output -// in the artifacts dir). +// or build with `/p:SkipDashboardReference=true`, to test end developer +// dashboard launch experience, Refer to Directory.Build.props for the path to +// the dashboard binary (defaults to the Aspire.Dashboard bin output in the +// artifacts dir). builder.AddProject(KnownResourceNames.AspireDashboard); +#endif builder.Build().Run(); diff --git a/playground/cdk/CdkSample.AppHost/Program.cs b/playground/cdk/CdkSample.AppHost/Program.cs index f8aca506744..2f0f786c329 100644 --- a/playground/cdk/CdkSample.AppHost/Program.cs +++ b/playground/cdk/CdkSample.AppHost/Program.cs @@ -102,11 +102,14 @@ .WithReference(search) .WithReference(appInsights); +#if !SKIP_DASHBOARD_REFERENCE // This project is only added in playground projects to support development/debugging // of the dashboard. It is not required in end developer code. Comment out this code -// to test end developer dashboard launch experience. Refer to Directory.Build.props -// for the path to the dashboard binary (defaults to the Aspire.Dashboard bin output -// in the artifacts dir). +// or build with `/p:SkipDashboardReference=true`, to test end developer +// dashboard launch experience, Refer to Directory.Build.props for the path to +// the dashboard binary (defaults to the Aspire.Dashboard bin output in the +// artifacts dir). builder.AddProject(KnownResourceNames.AspireDashboard); +#endif builder.Build().Run(); diff --git a/playground/dapr/Dapr.AppHost/Program.cs b/playground/dapr/Dapr.AppHost/Program.cs index 1e9250d047e..32216d54c0b 100644 --- a/playground/dapr/Dapr.AppHost/Program.cs +++ b/playground/dapr/Dapr.AppHost/Program.cs @@ -12,12 +12,15 @@ .WithDaprSidecar() .WithReference(pubSub); +#if !SKIP_DASHBOARD_REFERENCE // This project is only added in playground projects to support development/debugging // of the dashboard. It is not required in end developer code. Comment out this code -// to test end developer dashboard launch experience. Refer to Directory.Build.props -// for the path to the dashboard binary (defaults to the Aspire.Dashboard bin output -// in the artifacts dir). +// or build with `/p:SkipDashboardReference=true`, to test end developer +// dashboard launch experience, Refer to Directory.Build.props for the path to +// the dashboard binary (defaults to the Aspire.Dashboard bin output in the +// artifacts dir). builder.AddProject(KnownResourceNames.AspireDashboard); +#endif using var app = builder.Build(); diff --git a/tests/Aspire.Hosting.MySql.Tests/MySqlFunctionalTests.cs b/tests/Aspire.Hosting.MySql.Tests/MySqlFunctionalTests.cs index 41fb1577fa2..976d5c44b58 100644 --- a/tests/Aspire.Hosting.MySql.Tests/MySqlFunctionalTests.cs +++ b/tests/Aspire.Hosting.MySql.Tests/MySqlFunctionalTests.cs @@ -3,6 +3,7 @@ using System.Data; using Aspire.Components.Common.Tests; +using Aspire.Hosting.Tests.Utils; using Aspire.Hosting.Utils; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; @@ -19,6 +20,8 @@ namespace Aspire.Hosting.MySql.Tests; public class MySqlFunctionalTests(ITestOutputHelper testOutputHelper) { + private static readonly Predicate s_mySqlReadyText = log => log.Contains("ready for connections") && log.Contains("port: 3306"); + [Fact] [RequiresDocker] public async Task VerifyMySqlResource() @@ -39,6 +42,8 @@ public async Task VerifyMySqlResource() await app.StartAsync(); + await app.WaitForTextAsync(s_mySqlReadyText).WaitAsync(TimeSpan.FromMinutes(2)); + var hb = Host.CreateApplicationBuilder(); hb.Configuration.AddInMemoryCollection(new Dictionary @@ -108,6 +113,8 @@ public async Task WithDataShouldPersistStateBetweenUsages(bool useVolume) { await app.StartAsync(); + await app.WaitForTextAsync(s_mySqlReadyText).WaitAsync(TimeSpan.FromMinutes(2)); + try { var hb = Host.CreateApplicationBuilder(); @@ -175,6 +182,9 @@ await pipeline.ExecuteAsync(async token => using (var app = builder2.Build()) { await app.StartAsync(); + + await app.WaitForTextAsync(s_mySqlReadyText).WaitAsync(TimeSpan.FromMinutes(2)); + try { var hb = Host.CreateApplicationBuilder(); @@ -281,6 +291,8 @@ public async Task VerifyWithInitBindMount() await app.StartAsync(); + await app.WaitForTextAsync(s_mySqlReadyText).WaitAsync(TimeSpan.FromMinutes(2)); + var hb = Host.CreateApplicationBuilder(); hb.Configuration.AddInMemoryCollection(new Dictionary @@ -349,6 +361,8 @@ public async Task VerifyEfMySql() await app.StartAsync(); + await app.WaitForTextAsync(s_mySqlReadyText).WaitAsync(TimeSpan.FromMinutes(2)); + var hb = Host.CreateApplicationBuilder(); hb.Configuration.AddInMemoryCollection(new Dictionary diff --git a/tests/Aspire.Hosting.Tests/Utils/LoggerNotificationExtensions.cs b/tests/Aspire.Hosting.Tests/Utils/LoggerNotificationExtensions.cs index 1787f9ca47a..d52bae4bb62 100644 --- a/tests/Aspire.Hosting.Tests/Utils/LoggerNotificationExtensions.cs +++ b/tests/Aspire.Hosting.Tests/Utils/LoggerNotificationExtensions.cs @@ -1,6 +1,9 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#pragma warning disable IDE0005 // Using directive is unnecessary. This using is required when building this file in Aspire.Playground.Tests.csproj. +using Aspire.Hosting.ApplicationModel; +#pragma warning restore IDE0005 // Using directive is unnecessary. using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; @@ -22,7 +25,7 @@ public static Task WaitForTextAsync(this DistributedApplication app, string logT ArgumentNullException.ThrowIfNull(app); ArgumentException.ThrowIfNullOrEmpty(logText); - return WaitForTextAsync(app, [logText], resourceName, cancellationToken); + return WaitForTextAsync(app, (log) => log.Contains(logText), resourceName, cancellationToken); } /// @@ -38,18 +41,34 @@ public static Task WaitForTextAsync(this DistributedApplication app, IEnumerable ArgumentNullException.ThrowIfNull(app); ArgumentNullException.ThrowIfNull(logTexts); + return app.WaitForTextAsync((log) => logTexts.Any(x => log.Contains(x)), resourceName, cancellationToken); + } + + /// + /// Waits for the specified text to be logged. + /// + /// The instance to watch. + /// A predicate checking the text to wait for. + /// An optional resource name to filter the logs for. + /// The cancellation token. + /// + public static Task WaitForTextAsync(this DistributedApplication app, Predicate predicate, string? resourceName = null, CancellationToken cancellationToken = default) + { + ArgumentNullException.ThrowIfNull(app); + ArgumentNullException.ThrowIfNull(predicate); + var hostApplicationLifetime = app.Services.GetRequiredService(); var watchCts = CancellationTokenSource.CreateLinkedTokenSource(hostApplicationLifetime.ApplicationStopping, cancellationToken); var tcs = new TaskCompletionSource(); - _ = Task.Run(() => WatchNotifications(app, resourceName, logTexts, tcs, watchCts), watchCts.Token); + _ = Task.Run(() => WatchNotifications(app, resourceName, predicate, tcs, watchCts), watchCts.Token); return tcs.Task; } - private static async Task WatchNotifications(DistributedApplication app, string? resourceName, IEnumerable logTexts, TaskCompletionSource tcs, CancellationTokenSource cancellationTokenSource) + private static async Task WatchNotifications(DistributedApplication app, string? resourceName, Predicate predicate, TaskCompletionSource tcs, CancellationTokenSource cancellationTokenSource) { var resourceNotificationService = app.Services.GetRequiredService(); var resourceLoggerService = app.Services.GetRequiredService(); @@ -62,7 +81,7 @@ private static async Task WatchNotifications(DistributedApplication app, string? { await foreach (var resourceEvent in resourceNotificationService.WatchAsync(cancellationTokenSource.Token).ConfigureAwait(false)) { - if (resourceName != null && !string.Equals(resourceEvent.Resource.Name, resourceName, StringComparisons.ResourceName)) + if (resourceName != null && !string.Equals(resourceEvent.Resource.Name, resourceName, StringComparison.OrdinalIgnoreCase)) { continue; } @@ -72,7 +91,7 @@ private static async Task WatchNotifications(DistributedApplication app, string? if (loggingResourceIds.Add(resourceId)) { // Start watching the logs for this resource ID - logWatchTasks.Add(WatchResourceLogs(tcs, resourceId, logTexts, resourceLoggerService, cancellationTokenSource)); + logWatchTasks.Add(WatchResourceLogs(tcs, resourceId, predicate, resourceLoggerService, cancellationTokenSource)); } } } @@ -86,20 +105,17 @@ private static async Task WatchNotifications(DistributedApplication app, string? } } - private static async Task WatchResourceLogs(TaskCompletionSource tcs, string resourceId, IEnumerable logTexts, ResourceLoggerService resourceLoggerService, CancellationTokenSource cancellationTokenSource) + private static async Task WatchResourceLogs(TaskCompletionSource tcs, string resourceId, Predicate predicate, ResourceLoggerService resourceLoggerService, CancellationTokenSource cancellationTokenSource) { await foreach (var logEvent in resourceLoggerService.WatchAsync(resourceId).WithCancellation(cancellationTokenSource.Token).ConfigureAwait(false)) { foreach (var line in logEvent) { - foreach (var log in logTexts) + if (predicate(line.Content)) { - if (line.Content.Contains(log)) - { - tcs.SetResult(); - cancellationTokenSource.Cancel(); - return; - } + tcs.SetResult(); + cancellationTokenSource.Cancel(); + return; } } } diff --git a/tests/Aspire.Playground.Tests/AppHostTests.cs b/tests/Aspire.Playground.Tests/AppHostTests.cs index d5f3e1bea91..d16123d0f1a 100644 --- a/tests/Aspire.Playground.Tests/AppHostTests.cs +++ b/tests/Aspire.Playground.Tests/AppHostTests.cs @@ -3,7 +3,9 @@ using System.Net; using System.Text.Json; +using System.Text.RegularExpressions; using Aspire.Hosting.ApplicationModel; +using Aspire.Hosting.Tests.Utils; using Microsoft.Extensions.DependencyInjection; using SamplesIntegrationTests; using SamplesIntegrationTests.Infrastructure; @@ -67,19 +69,28 @@ public async Task TestEndpointsReturnOk(TestEndpoints testEndpoints) await app.StartAsync(); - var applicationModel = app.Services.GetRequiredService(); - var resourceNotificationService = app.Services.GetRequiredService(); + if (testEndpoints.WaitForTexts != null) + { + // If specific ready to start texts are available use it + var tasks = testEndpoints.WaitForTexts.Select(x => app.WaitForTextAsync(log => new Regex(x.Pattern).IsMatch(log), x.ResourceName)); + await Task.WhenAll(tasks).WaitAsync(TimeSpan.FromMinutes(5)); + } + else + { + var applicationModel = app.Services.GetRequiredService(); + var resourceNotificationService = app.Services.GetRequiredService(); - await app.WaitForResources().WaitAsync(TimeSpan.FromMinutes(2)); + await app.WaitForResources().WaitAsync(TimeSpan.FromMinutes(5)); - if (testEndpoints.WaitForResources?.Count > 0) - { - // Wait until each resource transitions to the required state - var timeout = TimeSpan.FromMinutes(5); - foreach (var (ResourceName, TargetState) in testEndpoints.WaitForResources) + if (testEndpoints.WaitForResources?.Count > 0) { - _testOutput.WriteLine($"Waiting for resource '{ResourceName}' to reach state '{TargetState}' in app '{Path.GetFileNameWithoutExtension(appHostPath)}'"); - await app.WaitForResource(ResourceName, TargetState).WaitAsync(TimeSpan.FromMinutes(5)); + // Wait until each resource transitions to the required state + var timeout = TimeSpan.FromMinutes(5); + foreach (var (ResourceName, TargetState) in testEndpoints.WaitForResources) + { + _testOutput.WriteLine($"Waiting for resource '{ResourceName}' to reach state '{TargetState}' in app '{Path.GetFileNameWithoutExtension(appHostPath)}'"); + await app.WaitForResource(ResourceName, TargetState).WaitAsync(TimeSpan.FromMinutes(5)); + } } } @@ -145,20 +156,67 @@ public static TheoryData TestEndpoints() { IList candidates = [ - new TestEndpoints("CosmosEndToEnd.AppHost", new() { { "api", ["/alive", "/health", "/", "/ef"] } }), - new TestEndpoints("Mongo.AppHost", new() { { "api", ["/alive", "/health", "/"] } }), - new TestEndpoints("MySqlDb.AppHost", new() { { "apiservice", ["/alive", "/health", "/catalog"] }, }), - new TestEndpoints("Nats.AppHost", new() { - { "api", ["/alive", "/health"] }, - { "backend", ["/alive", "/health"] } - }), - new TestEndpoints("ProxylessEndToEnd.AppHost", new() { { "api", ["/alive", "/health", "/redis"] } }), - new TestEndpoints("Qdrant.AppHost", new() { { "apiservice", ["/alive", "/health"] } }), - new TestEndpoints("Seq.AppHost", new() { { "api", ["/alive", "/health"] } }), - new TestEndpoints("TestShop.AppHost", new() { - { "catalogdbapp", ["/alive", "/health"] }, - { "frontend", ["/alive", "/health"] }, - }), + new TestEndpoints("CosmosEndToEnd.AppHost", + resourceEndpoints: new() { { "api", ["/alive", "/health", "/", "/ef"] } }, + waitForTexts: [ + new ("cosmos", "Started$"), + new ("api", "Application started") + ]), + // Issue: https://github.com/dotnet/aspire/issues/5274 + //new TestEndpoints("Mongo.AppHost", + //resourceEndpoints: new() { { "api", ["/alive", "/health", "/"] } }, + //waitForTexts: [ + //new ("mongo", "Waiting for connections"), + //new ("mongo-mongoexpress", "Mongo Express server listening"), + //new("api", "Application started.") + //]), + new TestEndpoints("MySqlDb.AppHost", + resourceEndpoints: new() { { "apiservice", ["/alive", "/health", "/catalog"] } }, + waitForTexts: [ + new ("mysql", "ready for connections.* port: 33060"), + new ("apiservice", "Application started") + ]), + new TestEndpoints("Nats.AppHost", + resourceEndpoints: new() { + { "api", ["/alive", "/health"] }, + { "backend", ["/alive", "/health"] } + }, + waitForTexts: [ + new ("nats", "Server is ready"), + new("api", "Application started") + ]), + new TestEndpoints("ProxylessEndToEnd.AppHost", + resourceEndpoints: new() { { "api", ["/alive", "/health", "/redis"] } }, + waitForTexts: [ + new ("redis", "Ready to accept connections"), + new("api", "Application started"), + new("api2", "Application started") + ]), + new TestEndpoints("Qdrant.AppHost", + resourceEndpoints: new() { { "apiservice", ["/alive", "/health"] } }, + waitForTexts: [ + new ("qdrant", "Qdrant HTTP listening"), + new ("apiservice", "Application started") + ]), + new TestEndpoints("Seq.AppHost", + resourceEndpoints: new() { { "api", ["/alive", "/health"] } }, + waitForTexts: [ + new ("seq", "Seq listening"), + new ("api", "Application started") + ]), + new TestEndpoints("TestShop.AppHost", + resourceEndpoints: new() { + { "catalogdbapp", ["/alive", "/health"] }, + { "frontend", ["/alive", "/health"] } + }, + waitForTexts: [ + new ("messaging", "started TCP listener"), + new ("basketcache", "Ready to accept connections"), + new ("frontend", "Application started"), + new ("catalogdbapp", "Application started"), + new ("basketservice", "Application started"), + new ("postgres", "database system is ready to accept connections"), + ]) ]; TheoryData theoryData = new(); @@ -191,22 +249,26 @@ public class TestEndpoints : IXunitSerializable // Required for deserialization public TestEndpoints() { } - public TestEndpoints(string appHost, Dictionary> resourceEndpoints) + public TestEndpoints(string appHost, Dictionary> resourceEndpoints, List? waitForTexts = null) { AppHost = appHost; ResourceEndpoints = resourceEndpoints; + WaitForTexts = waitForTexts; } public string? AppHost { get; set; } public List? WaitForResources { get; set; } + public List? WaitForTexts { get; set; } + public Dictionary>? ResourceEndpoints { get; set; } public void Deserialize(IXunitSerializationInfo info) { AppHost = info.GetValue(nameof(AppHost)); WaitForResources = JsonSerializer.Deserialize>(info.GetValue(nameof(WaitForResources))); + WaitForTexts = JsonSerializer.Deserialize>(info.GetValue(nameof(WaitForTexts))); ResourceEndpoints = JsonSerializer.Deserialize>>(info.GetValue(nameof(ResourceEndpoints))); } @@ -214,6 +276,7 @@ public void Serialize(IXunitSerializationInfo info) { info.AddValue(nameof(AppHost), AppHost); info.AddValue(nameof(WaitForResources), JsonSerializer.Serialize(WaitForResources)); + info.AddValue(nameof(WaitForTexts), JsonSerializer.Serialize(WaitForTexts)); info.AddValue(nameof(ResourceEndpoints), JsonSerializer.Serialize(ResourceEndpoints)); } @@ -231,4 +294,6 @@ public void Deconstruct(out string resourceName, out string targetState) targetState = TargetState; } } + + public record class ReadyStateText(string ResourceName, string Pattern); } diff --git a/tests/Aspire.Playground.Tests/Aspire.Playground.Tests.csproj b/tests/Aspire.Playground.Tests/Aspire.Playground.Tests.csproj index 2e543e3f1cc..120533b2bdb 100644 --- a/tests/Aspire.Playground.Tests/Aspire.Playground.Tests.csproj +++ b/tests/Aspire.Playground.Tests/Aspire.Playground.Tests.csproj @@ -20,6 +20,7 @@ + @@ -31,19 +32,39 @@ + + + + + + + + + + + + - - - - - - - - + + + + + + + + + + + + + + + + diff --git a/tests/helix/send-to-helix-basictests.targets b/tests/helix/send-to-helix-basictests.targets index a12228b85ab..cb04e1e4648 100644 --- a/tests/helix/send-to-helix-basictests.targets +++ b/tests/helix/send-to-helix-basictests.targets @@ -6,6 +6,11 @@ true + + + + + @@ -26,9 +31,6 @@ %(Identity) $(_EnvVarSetKeyword) "TEST_NAME=%(FileName)" - cp $(_HelixLogsPath)/TestResults.trx $(_HelixLogsPath)/$(_TestNameEnvVar).trx - copy "$(_HelixLogsPath)\TestResults.trx" "$(_HelixLogsPath)\$(_TestNameEnvVar).trx" - $(_TestRunCommand) $(_workItemTimeout) diff --git a/tests/helix/send-to-helix-buildonhelixtests.targets b/tests/helix/send-to-helix-buildonhelixtests.targets index 4d8748635d3..8956f0b3f77 100644 --- a/tests/helix/send-to-helix-buildonhelixtests.targets +++ b/tests/helix/send-to-helix-buildonhelixtests.targets @@ -17,6 +17,9 @@ + + + @@ -52,7 +55,7 @@ 00:15:00 - logs/%(FileName).cobertura.xml + logs/%(FileName).cobertura.xml;logs/%(FileName).trx diff --git a/tests/helix/send-to-helix-endtoendtests.targets b/tests/helix/send-to-helix-endtoendtests.targets index 2f8d9bb4c09..a2adbaf48ad 100644 --- a/tests/helix/send-to-helix-endtoendtests.targets +++ b/tests/helix/send-to-helix-endtoendtests.targets @@ -5,6 +5,11 @@ true + + + + + <_E2ETestsArchivePath>$(TestArchiveTestsDirForEndToEndTests)Aspire.EndToEnd.Tests.zip @@ -42,9 +47,6 @@ %(PreCommands) $(_ShellCommandSeparator) $(_EnvVarSetKeyword) "TEST_SCENARIO=%(Identity)" %(PreCommands) $(_ShellCommandSeparator) $(_EnvVarSetKeyword) "CODE_COV_FILE_SUFFIX=-%(Identity)" - cp $(_HelixLogsPath)/TestResults.trx $(_HelixLogsPath)/Aspire.EndToEnd.Tests-%(Identity).trx - copy "$(_HelixLogsPath)\TestResults.trx" "$(_HelixLogsPath)\Aspire.EndToEnd.Tests-%(Identity).trx" - $(_TestRunCommand) $(_workItemTimeout) diff --git a/tests/helix/send-to-helix-workloadtests.targets b/tests/helix/send-to-helix-workloadtests.targets index 3810d9a666f..ba8b7468ef0 100644 --- a/tests/helix/send-to-helix-workloadtests.targets +++ b/tests/helix/send-to-helix-workloadtests.targets @@ -12,6 +12,9 @@ + + + @@ -41,13 +44,11 @@ $(_EnvVarSetKeyword) "TEST_NAME=%(FileName)" %(PreCommands) $(_ShellCommandSeparator) $(_EnvVarSetKeyword) "CODE_COV_FILE_SUFFIX=-%(TestNameSuffix)" + %(PreCommands) $(_ShellCommandSeparator) $(_EnvVarSetKeyword) "TEST_NAME_SUFFIX=%(TestNameSuffix)" %(PreCommands) $(_ShellCommandSeparator) set "TEST_ARGS=--filter category^^!=failing^&FullyQualifiedName~%(Identity)" %(PreCommands) $(_ShellCommandSeparator) export "TEST_ARGS=--filter category!=failing&FullyQualifiedName~%(Identity)" - cp $(_HelixLogsPath)/TestResults.trx $(_HelixLogsPath)/$(TestProjectName)-%(TestNameSuffix).trx - copy "$(_HelixLogsPath)\TestResults.trx" "$(_HelixLogsPath)\$(TestProjectName)-%(TestNameSuffix).trx" - $(_TestRunCommand) $(_workItemTimeout)