diff --git a/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.IntegrationTests/Amazon.Lambda.RuntimeSupport.IntegrationTests.csproj b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.IntegrationTests/Amazon.Lambda.RuntimeSupport.IntegrationTests.csproj index 1e37f5d9b..4a88a79dc 100644 --- a/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.IntegrationTests/Amazon.Lambda.RuntimeSupport.IntegrationTests.csproj +++ b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.IntegrationTests/Amazon.Lambda.RuntimeSupport.IntegrationTests.csproj @@ -23,13 +23,13 @@ - + - + all runtime; build; native; contentfiles; analyzers - + @@ -39,24 +39,4 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.IntegrationTests/CustomRuntimeAspNetCoreMinimalApiCustomSerializerTest.cs b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.IntegrationTests/CustomRuntimeAspNetCoreMinimalApiCustomSerializerTest.cs index 2d2a52b03..2b3826110 100644 --- a/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.IntegrationTests/CustomRuntimeAspNetCoreMinimalApiCustomSerializerTest.cs +++ b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.IntegrationTests/CustomRuntimeAspNetCoreMinimalApiCustomSerializerTest.cs @@ -14,15 +14,34 @@ using Xunit; using Amazon.Lambda.APIGatewayEvents; using System.Text.Json; +using Amazon.Lambda.RuntimeSupport.IntegrationTests.Helpers; +using Xunit.Abstractions; namespace Amazon.Lambda.RuntimeSupport.IntegrationTests { public class CustomRuntimeAspNetCoreMinimalApiCustomSerializerTest : BaseCustomRuntimeTest { - public CustomRuntimeAspNetCoreMinimalApiCustomSerializerTest() + public CustomRuntimeAspNetCoreMinimalApiCustomSerializerTest( + ITestOutputHelper output) : base("CustomRuntimeMinimalApiCustomSerializerTest-" + DateTime.Now.Ticks, "CustomRuntimeAspNetCoreMinimalApiCustomSerializerTest.zip", @"CustomRuntimeAspNetCoreMinimalApiCustomSerializerTest\bin\Release\net6.0\CustomRuntimeAspNetCoreMinimalApiCustomSerializerTest.zip", "bootstrap") { + string testAppPath = null; + string toolPath = null; + try + { + testAppPath = LambdaToolsHelper.GetTempTestAppDirectory( + "../../../../../../..", + "Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/CustomRuntimeAspNetCoreMinimalApiCustomSerializerTest"); + toolPath = LambdaToolsHelper.InstallLambdaTools(output); + LambdaToolsHelper.DotnetRestore(testAppPath, output); + LambdaToolsHelper.LambdaPackage(toolPath, "net6.0", testAppPath, output); + } + finally + { + LambdaToolsHelper.CleanUp(testAppPath); + LambdaToolsHelper.CleanUp(toolPath); + } } diff --git a/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.IntegrationTests/CustomRuntimeAspNetCoreMinimalApiTest.cs b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.IntegrationTests/CustomRuntimeAspNetCoreMinimalApiTest.cs index 0064568b9..62f9bb29a 100644 --- a/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.IntegrationTests/CustomRuntimeAspNetCoreMinimalApiTest.cs +++ b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.IntegrationTests/CustomRuntimeAspNetCoreMinimalApiTest.cs @@ -14,15 +14,34 @@ using Xunit; using Amazon.Lambda.APIGatewayEvents; using System.Text.Json; +using Amazon.Lambda.RuntimeSupport.IntegrationTests.Helpers; +using Xunit.Abstractions; namespace Amazon.Lambda.RuntimeSupport.IntegrationTests { public class CustomRuntimeAspNetCoreMinimalApiTest : BaseCustomRuntimeTest { - public CustomRuntimeAspNetCoreMinimalApiTest() + public CustomRuntimeAspNetCoreMinimalApiTest( + ITestOutputHelper output) : base("CustomRuntimeAspNetCoreMinimalApiTest-" + DateTime.Now.Ticks, "CustomRuntimeAspNetCoreMinimalApiTest.zip", @"CustomRuntimeAspNetCoreMinimalApiTest\bin\Release\net6.0\CustomRuntimeAspNetCoreMinimalApiTest.zip", "bootstrap") { + string testAppPath = null; + string toolPath = null; + try + { + testAppPath = LambdaToolsHelper.GetTempTestAppDirectory( + "../../../../../../..", + "Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/CustomRuntimeAspNetCoreMinimalApiTest"); + toolPath = LambdaToolsHelper.InstallLambdaTools(output); + LambdaToolsHelper.DotnetRestore(testAppPath, output); + LambdaToolsHelper.LambdaPackage(toolPath, "net6.0", testAppPath, output); + } + finally + { + LambdaToolsHelper.CleanUp(testAppPath); + LambdaToolsHelper.CleanUp(toolPath); + } } diff --git a/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.IntegrationTests/CustomRuntimeTests.cs b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.IntegrationTests/CustomRuntimeTests.cs index e4af2b9bc..049ddede6 100644 --- a/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.IntegrationTests/CustomRuntimeTests.cs +++ b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.IntegrationTests/CustomRuntimeTests.cs @@ -26,15 +26,23 @@ using System.Net; using System.Threading; using System.Threading.Tasks; +using Amazon.Lambda.RuntimeSupport.IntegrationTests.Helpers; using Xunit; +using Xunit.Abstractions; using static Amazon.Lambda.RuntimeSupport.IntegrationTests.CustomRuntimeTests; namespace Amazon.Lambda.RuntimeSupport.IntegrationTests { public class CustomRuntimeNET6Tests : CustomRuntimeTests { - public CustomRuntimeNET6Tests() - : base("CustomRuntimeNET6FunctionTest-" + DateTime.Now.Ticks, "CustomRuntimeFunctionTest.zip", @"CustomRuntimeFunctionTest\bin\Release\net6.0\CustomRuntimeFunctionTest.zip", "CustomRuntimeFunctionTest", TargetFramework.NET6) + public CustomRuntimeNET6Tests(ITestOutputHelper output) + : base( + output, + "CustomRuntimeNET6FunctionTest-" + DateTime.Now.Ticks, + "CustomRuntimeFunctionTest.zip", + @"CustomRuntimeFunctionTest\bin\Release\net6.0\CustomRuntimeFunctionTest.zip", + "CustomRuntimeFunctionTest", + TargetFramework.NET6) { } @@ -51,8 +59,14 @@ public async Task TestAllNET6HandlersAsync() public class CustomRuntimeNET8Tests : CustomRuntimeTests { - public CustomRuntimeNET8Tests() - : base("CustomRuntimeNET8FunctionTest-" + DateTime.Now.Ticks, "CustomRuntimeFunctionTest.zip", @"CustomRuntimeFunctionTest\bin\Release\net8.0\CustomRuntimeFunctionTest.zip", "CustomRuntimeFunctionTest", TargetFramework.NET8) + public CustomRuntimeNET8Tests(ITestOutputHelper output) + : base( + output, + "CustomRuntimeNET8FunctionTest-" + DateTime.Now.Ticks, + "CustomRuntimeFunctionTest.zip", + @"CustomRuntimeFunctionTest\bin\Release\net8.0\CustomRuntimeFunctionTest.zip", + "CustomRuntimeFunctionTest", + TargetFramework.NET8) { } @@ -73,12 +87,34 @@ public enum TargetFramework { NET6, NET8} private TargetFramework _targetFramework; - public CustomRuntimeTests(string functionName, string deploymentZipKey, string deploymentPackageZipRelativePath, string handler, TargetFramework targetFramework) + public CustomRuntimeTests( + ITestOutputHelper output, + string functionName, + string deploymentZipKey, + string deploymentPackageZipRelativePath, + string handler, + TargetFramework targetFramework) : base(functionName, deploymentZipKey, deploymentPackageZipRelativePath, handler) { _targetFramework = targetFramework; + string testAppPath = null; + string toolPath = null; + try + { + testAppPath = LambdaToolsHelper.GetTempTestAppDirectory( + "../../../../../../..", + "Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/CustomRuntimeFunctionTest"); + toolPath = LambdaToolsHelper.InstallLambdaTools(output); + LambdaToolsHelper.DotnetRestore(testAppPath, output); + LambdaToolsHelper.LambdaPackage(toolPath, _targetFramework == TargetFramework.NET8 ? "net8.0" : "net6.0", testAppPath, output); + } + finally + { + LambdaToolsHelper.CleanUp(testAppPath); + LambdaToolsHelper.CleanUp(toolPath); + } } - + protected virtual async Task TestAllHandlersAsync() { // run all test cases in one test to ensure they run serially diff --git a/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.IntegrationTests/Helpers/CommandLineWrapper.cs b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.IntegrationTests/Helpers/CommandLineWrapper.cs new file mode 100644 index 000000000..9c2883318 --- /dev/null +++ b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.IntegrationTests/Helpers/CommandLineWrapper.cs @@ -0,0 +1,60 @@ +using System; +using System.Diagnostics; +using System.IO; +using System.Runtime.InteropServices; +using Xunit; +using Xunit.Abstractions; + +namespace Amazon.Lambda.RuntimeSupport.IntegrationTests.Helpers; + +public static class CommandLineWrapper +{ + public static void Run(string command, string arguments, string workingDirectory, ITestOutputHelper outputHelper) + { + string tempOutputFile = Path.GetTempFileName(); + var startInfo = new ProcessStartInfo + { + FileName = GetSystemShell(), + Arguments = + RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? + $"/c {command} {arguments} > \"{tempOutputFile}\" 2>&1" : + $"-c \"{command} {arguments} > '{tempOutputFile}' 2>&1\"", + WorkingDirectory = workingDirectory, + UseShellExecute = true, + CreateNoWindow = true + }; + + using (var process = Process.Start(startInfo)) + { + if (process == null) + throw new Exception($"Unable to start process: {command} {arguments}"); + + process.WaitForExit(); + + string output = File.ReadAllText(tempOutputFile); + outputHelper.WriteLine(output); + + Assert.True(process.ExitCode == 0, $"Command '{command} {arguments}' failed."); + } + File.Delete(tempOutputFile); + } + + private static string GetSystemShell() + { + if (TryGetEnvironmentVariable("COMSPEC", out var comspec)) + return comspec!; + + if (TryGetEnvironmentVariable("SHELL", out var shell)) + return shell!; + + // fall back to defaults + return RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "cmd.exe" : "bash"; + } + + private static bool TryGetEnvironmentVariable(string variable, out string value) + { + value = Environment.GetEnvironmentVariable(variable); + + return !string.IsNullOrEmpty(value); + } +} \ No newline at end of file diff --git a/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.IntegrationTests/Helpers/LambdaToolsHelper.cs b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.IntegrationTests/Helpers/LambdaToolsHelper.cs new file mode 100644 index 000000000..f75181faf --- /dev/null +++ b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.IntegrationTests/Helpers/LambdaToolsHelper.cs @@ -0,0 +1,89 @@ +using System.IO; +using System.Runtime.InteropServices; +using Xunit.Abstractions; + +namespace Amazon.Lambda.RuntimeSupport.IntegrationTests.Helpers; + +public static class LambdaToolsHelper +{ + private static readonly string FunctionArchitecture = RuntimeInformation.OSArchitecture == System.Runtime.InteropServices.Architecture.Arm64 ? "arm64" : "x86_64"; + + public static string GetTempTestAppDirectory(string workingDirectory, string testAppPath) + { + var customTestAppPath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); + Directory.CreateDirectory(customTestAppPath); + + var currentDir = new DirectoryInfo(workingDirectory); + CopyDirectory(currentDir, customTestAppPath); + + return Path.Combine(customTestAppPath, testAppPath); + } + + public static string InstallLambdaTools(ITestOutputHelper output) + { + var customToolPath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); + Directory.CreateDirectory(customToolPath); + CommandLineWrapper.Run( + "dotnet", + $"tool install Amazon.Lambda.Tools --tool-path {customToolPath}", + Directory.GetCurrentDirectory(), + output); + return customToolPath; + } + + public static void DotnetRestore(string workingDirectory, ITestOutputHelper output) + { + CommandLineWrapper.Run( + "dotnet", + "restore", + workingDirectory, + output); + } + + public static void LambdaPackage(string toolPath, string framework, string workingDirectory, ITestOutputHelper output) + { + string lambdaToolPath = Path.Combine(toolPath, "dotnet-lambda"); + CommandLineWrapper.Run( + lambdaToolPath, + $"package -c Release --framework {framework} --function-architecture {FunctionArchitecture}", + workingDirectory, + output); + } + + public static void CleanUp(string toolPath) + { + if (!string.IsNullOrEmpty(toolPath) && Directory.Exists(toolPath)) + { + Directory.Delete(toolPath, true); + } + } + + /// + /// + /// + private static void CopyDirectory(DirectoryInfo dir, string destDirName) + { + if (!dir.Exists) + { + throw new DirectoryNotFoundException($"Source directory does not exist or could not be found: {dir.FullName}"); + } + + var dirs = dir.GetDirectories(); + + Directory.CreateDirectory(destDirName); + + var files = dir.GetFiles(); + foreach (var file in files) + { + var tempPath = Path.Combine(destDirName, file.Name); + file.CopyTo(tempPath, false); + } + + foreach (var subdir in dirs) + { + var tempPath = Path.Combine(destDirName, subdir.Name); + var subDir = new DirectoryInfo(subdir.FullName); + CopyDirectory(subDir, tempPath); + } + } +} \ No newline at end of file diff --git a/Libraries/test/TestServerlessApp.IntegrationTests/TestServerlessApp.IntegrationTests.csproj b/Libraries/test/TestServerlessApp.IntegrationTests/TestServerlessApp.IntegrationTests.csproj index 13d185a5b..77c3ddb54 100644 --- a/Libraries/test/TestServerlessApp.IntegrationTests/TestServerlessApp.IntegrationTests.csproj +++ b/Libraries/test/TestServerlessApp.IntegrationTests/TestServerlessApp.IntegrationTests.csproj @@ -12,9 +12,9 @@ - - - + + + all runtime; build; native; contentfiles; analyzers diff --git a/buildtools/build.proj b/buildtools/build.proj index f38fd1a07..a6aa29cea 100644 --- a/buildtools/build.proj +++ b/buildtools/build.proj @@ -194,12 +194,12 @@ - - + + - - + +