diff --git a/test/FunctionalTests/Linker/Helpers/DotNetProcess.cs b/test/FunctionalTests/Linker/Helpers/DotNetProcess.cs index 40ab06572..fc9c4a5e7 100644 --- a/test/FunctionalTests/Linker/Helpers/DotNetProcess.cs +++ b/test/FunctionalTests/Linker/Helpers/DotNetProcess.cs @@ -1,4 +1,4 @@ -#region Copyright notice and license +#region Copyright notice and license // Copyright 2019 The gRPC Authors // @@ -54,9 +54,10 @@ public DotNetProcess() public int ExitCode => Process.ExitCode; public bool HasExited => Process.HasExited; - public void Start(string arguments) + public void Start(string fileName, string? arguments) { - Process.StartInfo.Arguments = arguments; + Process.StartInfo.FileName = fileName; + Process.StartInfo.Arguments = arguments ?? string.Empty; Process.Start(); Process.BeginOutputReadLine(); diff --git a/test/FunctionalTests/Linker/LinkerTests.cs b/test/FunctionalTests/Linker/LinkerTests.cs index 8e26122bf..7a78c909a 100644 --- a/test/FunctionalTests/Linker/LinkerTests.cs +++ b/test/FunctionalTests/Linker/LinkerTests.cs @@ -33,8 +33,21 @@ public class LinkerTests { private static readonly TimeSpan Timeout = TimeSpan.FromSeconds(120); +#if NET8_0_OR_GREATER [Test] - public async Task RunWebsiteAndCallWithClient_Success() + public async Task RunWebsiteAndCallWithClient_Aot_Success() + { + await RunWebsiteAndCallWithClient(publishAot: true); + } +#endif + + [Test] + public async Task RunWebsiteAndCallWithClient_Trimming_Success() + { + await RunWebsiteAndCallWithClient(publishAot: false); + } + + private async Task RunWebsiteAndCallWithClient(bool publishAot) { var projectDirectory = typeof(LinkerTests).Assembly .GetCustomAttributes() @@ -51,13 +64,11 @@ public async Task RunWebsiteAndCallWithClient_Success() try { using var cts = new CancellationTokenSource(); - using var websiteProcess = new WebsiteProcess(); - using var clientProcess = new DotNetProcess(); try { - var publishWebsiteTask = PublishAppAsync(projectDirectory + @"\..\..\testassets\LinkerTestsWebsite\LinkerTestsWebsite.csproj", linkerTestsWebsitePath, cts.Token); - var publishClientTask = PublishAppAsync(projectDirectory + @"\..\..\testassets\LinkerTestsClient\LinkerTestsClient.csproj", linkerTestsClientPath, cts.Token); + var publishWebsiteTask = PublishAppAsync(projectDirectory + @"\..\..\testassets\LinkerTestsWebsite\LinkerTestsWebsite.csproj", linkerTestsWebsitePath, publishAot, cts.Token); + var publishClientTask = PublishAppAsync(projectDirectory + @"\..\..\testassets\LinkerTestsClient\LinkerTestsClient.csproj", linkerTestsClientPath, publishAot, cts.Token); await Task.WhenAll(publishWebsiteTask, publishClientTask).TimeoutAfter(Timeout); Console.WriteLine("Successfully published app."); @@ -67,12 +78,15 @@ public async Task RunWebsiteAndCallWithClient_Success() cts.Dispose(); } + using var websiteProcess = new WebsiteProcess(); + using var clientProcess = new DotNetProcess(); + try { - websiteProcess.Start(Path.Combine(linkerTestsWebsitePath, "LinkerTestsWebsite.dll")); + websiteProcess.Start(BuildStartPath(linkerTestsWebsitePath, "LinkerTestsWebsite"), arguments: null); await websiteProcess.WaitForReadyAsync().TimeoutAfter(Timeout); - clientProcess.Start(Path.Combine(linkerTestsClientPath, $"LinkerTestsClient.dll {websiteProcess.ServerPort}")); + clientProcess.Start(BuildStartPath(linkerTestsClientPath, "LinkerTestsClient"), arguments: websiteProcess.ServerPort!.ToString()); await clientProcess.WaitForExitAsync().TimeoutAfter(Timeout); } finally @@ -92,6 +106,13 @@ public async Task RunWebsiteAndCallWithClient_Success() } } + private static string BuildStartPath(string path, string projectName) + { + // Executable on Windows has an *.exe extension. + // We don't need to add it to the start path because *.exe is in the PATHEXT env var. + return Path.Combine(path, projectName); + } + private static void EnsureDeleted(string path) { if (Directory.Exists(path)) @@ -100,7 +121,7 @@ private static void EnsureDeleted(string path) } } - private static async Task PublishAppAsync(string path, string outputPath, CancellationToken cancellationToken) + private static async Task PublishAppAsync(string path, string outputPath, bool publishAot, CancellationToken cancellationToken) { var resolvedPath = Path.GetFullPath(path); Console.WriteLine($"Publishing {resolvedPath}"); @@ -110,7 +131,9 @@ private static async Task PublishAppAsync(string path, string outputPath, Cancel try { - process.Start($"publish {resolvedPath} -r {GetRuntimeIdentifier()} -c Release -o {outputPath} --self-contained"); + // The AppPublishAot parameter is used to tell the compiler to publish as AOT. + // AppPublishAot is used instead of PublishAot because dependency projects have non-AOT targets. Setting "PublishAot=true" causes build errors. + process.Start("dotnet", $"publish {resolvedPath} -r {GetRuntimeIdentifier()} -c Release -o {outputPath} -p:AppPublishAot={publishAot} --self-contained"); await process.WaitForExitAsync().TimeoutAfter(Timeout); } catch (Exception ex) diff --git a/testassets/LinkerTestsClient/LinkerTestsClient.csproj b/testassets/LinkerTestsClient/LinkerTestsClient.csproj index 46c1308c3..4834024ce 100644 --- a/testassets/LinkerTestsClient/LinkerTestsClient.csproj +++ b/testassets/LinkerTestsClient/LinkerTestsClient.csproj @@ -4,6 +4,7 @@ net8.0 Exe true + $(AppPublishAot) diff --git a/testassets/LinkerTestsWebsite/LinkerTestsWebsite.csproj b/testassets/LinkerTestsWebsite/LinkerTestsWebsite.csproj index ed6d46389..5d4cc37f0 100644 --- a/testassets/LinkerTestsWebsite/LinkerTestsWebsite.csproj +++ b/testassets/LinkerTestsWebsite/LinkerTestsWebsite.csproj @@ -4,6 +4,7 @@ net8.0 Exe true + $(AppPublishAot)