diff --git a/DotNetWorker.Extensions.sln b/DotNetWorker.Extensions.sln index b87fefd58..0d08d2f21 100644 --- a/DotNetWorker.Extensions.sln +++ b/DotNetWorker.Extensions.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.1.32228.430 +# Visual Studio Version 18 +VisualStudioVersion = 18.1.11312.151 d18.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{FD7243E4-BF18-43F8-8744-BA1D17ACF378}" EndProject @@ -82,6 +82,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Worker.Extensions.Timer.Tes EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Worker.Extensions.Http.AspNetCore.Analyzers", "extensions\Worker.Extensions.Http.AspNetCore.Analyzers\src\Worker.Extensions.Http.AspNetCore.Analyzers.csproj", "{914B3E60-DE19-4827-956F-22080C817820}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "E2EAspNetCoreApp", "test\E2ETests\E2EApps\E2EAspNetCoreApp\E2EAspNetCoreApp.csproj", "{2A48230E-525D-9ECE-0B98-67417F8AC4F5}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -204,6 +206,10 @@ Global {914B3E60-DE19-4827-956F-22080C817820}.Debug|Any CPU.Build.0 = Debug|Any CPU {914B3E60-DE19-4827-956F-22080C817820}.Release|Any CPU.ActiveCfg = Release|Any CPU {914B3E60-DE19-4827-956F-22080C817820}.Release|Any CPU.Build.0 = Release|Any CPU + {2A48230E-525D-9ECE-0B98-67417F8AC4F5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2A48230E-525D-9ECE-0B98-67417F8AC4F5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2A48230E-525D-9ECE-0B98-67417F8AC4F5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2A48230E-525D-9ECE-0B98-67417F8AC4F5}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -239,6 +245,7 @@ Global {B6342174-5436-4846-B43C-39D8E34AE5CF} = {FD7243E4-BF18-43F8-8744-BA1D17ACF378} {6947034E-C97F-4F78-940F-B6A398E23C9C} = {FD7243E4-BF18-43F8-8744-BA1D17ACF378} {914B3E60-DE19-4827-956F-22080C817820} = {A7B4FF1E-3DF7-4F28-9333-D0961CDDF702} + {2A48230E-525D-9ECE-0B98-67417F8AC4F5} = {0EA6A975-2934-4837-9932-2328EFE23BFD} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {497D2ED4-A13E-4BCA-8D29-F30CA7D0EA4A} diff --git a/eng/ci/templates/steps/install-core-tools.yml b/eng/ci/templates/steps/install-core-tools.yml new file mode 100644 index 000000000..e9ac1c91e --- /dev/null +++ b/eng/ci/templates/steps/install-core-tools.yml @@ -0,0 +1,52 @@ +steps: +- pwsh: | + $ErrorActionPreference = 'Stop' + $arch = [System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture.ToString().ToLowerInvariant() + + if ($IsWindows) { + $os = "win" + } + elseif ($IsMacOS) { + $os = "osx" + } + else { + $os = "linux" + } + + # GitHub API call for latest release + $releaseInfo = Invoke-RestMethod -Uri "https://api.github.com/repos/Azure/azure-functions-core-tools/releases/latest" -Headers @{ "User-Agent" = "PowerShell" } + + $version = $releaseInfo.tag_name + Write-Host "Latest Core Tools version: $version" + + # Look for zip file matching os and arch + $pattern = "Azure\.Functions\.Cli\.$os-$arch\..*\.zip$" + $asset = $releaseInfo.assets | Where-Object { $_.name -match $pattern } + + if (-not $asset) { + Write-Error "Could not find a Core Tools .zip for OS '$os' and arch '$arch'" + exit 1 + } + + $coreToolsUrl = $asset.browser_download_url + Write-Host "Downloading Azure Functions Core Tools from $coreToolsUrl" + + $zipPath = "$(Agent.TempDirectory)/Azure.Functions.Cli.zip" + Invoke-WebRequest -Uri $coreToolsUrl -OutFile $zipPath + + $installPath = "$(Agent.ToolsDirectory)/Azure.Functions.Cli/$version" + New-Item -ItemType Directory -Path $installPath -Force | Out-Null + + Write-Host "Extracting to $installPath" + Expand-Archive -Path $zipPath -DestinationPath $installPath -Force + + if ($IsMacOS -or $IsLinux) + { + & "chmod" "a+x" "$installPath/func" + } + + Write-Host "Azure Functions Core Tools installed to $installPath" + + # Make Core Tools available on PATH for subsequent steps + Write-Host "##vso[task.prependpath]$installPath" + displayName: 'Install Azure Functions Core Tools' \ No newline at end of file diff --git a/eng/ci/templates/steps/setup-e2e-tests.yml b/eng/ci/templates/steps/setup-e2e-tests.yml index e250237ff..de8ab4d5e 100644 --- a/eng/ci/templates/steps/setup-e2e-tests.yml +++ b/eng/ci/templates/steps/setup-e2e-tests.yml @@ -20,6 +20,9 @@ parameters: steps: +- ${{ if not(parameters.SkipCoreTools) }}: + - template: /eng/ci/templates/steps/install-core-tools.yml@self + - task: PowerShell@2 displayName: 'Setup E2E tests' inputs: @@ -29,7 +32,7 @@ steps: -DotnetVersion ${{ parameters.DotnetVersion }} -SkipStorageEmulator:$${{ parameters.SkipStorageEmulator }} -SkipCosmosDBEmulator:$${{ parameters.SkipCosmosDBEmulator }} - -SkipCoreTools:$${{ parameters.SkipCoreTools }} -UseCoreToolsBuildFromIntegrationTests:$${{ parameters.UseCoreToolsBuild }} -SkipBuildOnPack:$${{ parameters.SkipBuildOnPack }} + -SkipCoreTools pwsh: true diff --git a/setup-e2e-tests.ps1 b/setup-e2e-tests.ps1 index c9cb60358..7945b3aab 100644 --- a/setup-e2e-tests.ps1 +++ b/setup-e2e-tests.ps1 @@ -106,12 +106,12 @@ else & "chmod" "a+x" "$FUNC_CLI_DIRECTORY/func" } - Write-Host "------" -} + if (Test-Path $output) + { + Remove-Item $output -Recurse -Force -ErrorAction Ignore + } -if (Test-Path $output) -{ - Remove-Item $output -Recurse -Force -ErrorAction Ignore + Write-Host "------" } Write-Host "----- Executing tests for Dotnet version $DotnetVersion -----" diff --git a/test/E2ETests/E2EApps/E2EApp/E2EApp.csproj b/test/E2ETests/E2EApps/E2EApp/E2EApp.csproj index 3409c286f..4dcbdf357 100644 --- a/test/E2ETests/E2EApps/E2EApp/E2EApp.csproj +++ b/test/E2ETests/E2EApps/E2EApp/E2EApp.csproj @@ -45,8 +45,8 @@ - - + + \ No newline at end of file diff --git a/test/E2ETests/E2EApps/E2EAspNetCoreApp/E2EAspNetCoreApp.csproj b/test/E2ETests/E2EApps/E2EAspNetCoreApp/E2EAspNetCoreApp.csproj index 5c2fd1e8c..84f07b338 100644 --- a/test/E2ETests/E2EApps/E2EAspNetCoreApp/E2EAspNetCoreApp.csproj +++ b/test/E2ETests/E2EApps/E2EAspNetCoreApp/E2EAspNetCoreApp.csproj @@ -27,7 +27,8 @@ - - + + + \ No newline at end of file diff --git a/test/E2ETests/E2ETests.slnf b/test/E2ETests/E2ETests.slnf index 1cd8d2420..d9db51af4 100644 --- a/test/E2ETests/E2ETests.slnf +++ b/test/E2ETests/E2ETests.slnf @@ -1,17 +1,15 @@ { "solution": { - "path": "..\\..\\DotNetWorker.sln", + "path": "..\\..\\DotNetWorker.Extensions.sln", "projects": [ - "extensions\\Worker.Extensions.Abstractions\\Worker.Extensions.Abstractions.csproj", - "extensions\\Worker.Extensions.CosmosDB\\Worker.Extensions.CosmosDB.csproj", - "extensions\\Worker.Extensions.EventHubs\\Worker.Extensions.EventHubs.csproj", - "extensions\\Worker.Extensions.Http\\Worker.Extensions.Http.csproj", - "extensions\\Worker.Extensions.Storage\\Worker.Extensions.Storage.csproj", - "extensions\\Worker.Extensions.Timer\\Worker.Extensions.Timer.csproj", - "src\\DotNetWorker.Core\\DotNetWorker.Core.csproj", - "src\\DotNetWorker.Grpc\\DotNetWorker.Grpc.csproj", - "src\\DotNetWorker\\DotNetWorker.csproj", + "extensions\\Worker.Extensions.Abstractions\\src\\Worker.Extensions.Abstractions.csproj", + "extensions\\Worker.Extensions.CosmosDB\\src\\Worker.Extensions.CosmosDB.csproj", + "extensions\\Worker.Extensions.EventHubs\\src\\Worker.Extensions.EventHubs.csproj", + "extensions\\Worker.Extensions.Http\\src\\Worker.Extensions.Http.csproj", + "extensions\\Worker.Extensions.Storage\\src\\Worker.Extensions.Storage.csproj", + "extensions\\Worker.Extensions.Timer\\src\\Worker.Extensions.Timer.csproj", "test\\E2ETests\\E2EApps\\E2EApp\\E2EApp.csproj", + "test\\E2ETests\\E2EApps\\E2EAspNetCoreApp\\E2EAspNetCoreApp.csproj", "test\\E2ETests\\E2ETests\\E2ETests.csproj", "test\\TestUtility\\TestUtility.csproj" ] diff --git a/test/E2ETests/E2ETests/Fixtures/FixtureHelpers.cs b/test/E2ETests/E2ETests/Fixtures/FixtureHelpers.cs index 3b31026b4..245cb9260 100644 --- a/test/E2ETests/E2ETests/Fixtures/FixtureHelpers.cs +++ b/test/E2ETests/E2ETests/Fixtures/FixtureHelpers.cs @@ -1,11 +1,8 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the MIT License. See License.txt in the project root for license information. -using System; using System.Diagnostics; using System.IO; -using System.Linq; -using System.Runtime.InteropServices; using Microsoft.Extensions.Logging; namespace Microsoft.Azure.Functions.Tests.E2ETests @@ -15,41 +12,22 @@ public static class FixtureHelpers { public static Process GetFuncHostProcess(bool enableAuth = false, string testAppName = null) { - var funcProcess = new Process(); - var rootDir = Path.GetFullPath(@"../../../../../.."); - var e2eAppBinPath = Path.Combine(rootDir, "test", "E2ETests", "E2EApps", testAppName, "bin"); - string e2eHostJson = Directory.GetFiles(e2eAppBinPath, "host.json", SearchOption.AllDirectories).FirstOrDefault(); - - if (e2eHostJson == null) - { - throw new InvalidOperationException($"Could not find a built worker app under '{e2eAppBinPath}'"); - } - - var e2eAppPath = Path.GetDirectoryName(e2eHostJson); - - var cliPath = Path.Combine(rootDir, "Azure.Functions.Cli", "func"); - - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - cliPath += ".exe"; - } - - if (!File.Exists(cliPath)) - { - throw new InvalidOperationException($"Could not find '{cliPath}'. Try running '{Path.Combine(rootDir, "setup-e2e-tests.ps1")}' to install it."); - } + Process funcProcess = new(); + string e2eAppPath = Path.Combine(TestUtility.RepoRoot, "test", "E2ETests", "E2EApps", testAppName); funcProcess.StartInfo.UseShellExecute = false; funcProcess.StartInfo.RedirectStandardError = true; funcProcess.StartInfo.RedirectStandardOutput = true; funcProcess.StartInfo.CreateNoWindow = true; funcProcess.StartInfo.WorkingDirectory = e2eAppPath; - funcProcess.StartInfo.FileName = cliPath; - funcProcess.StartInfo.ArgumentList.Add("start"); - funcProcess.StartInfo.ArgumentList.Add("--verbose"); + funcProcess.StartInfo.FileName = "dotnet"; + funcProcess.StartInfo.ArgumentList.Add("run"); + funcProcess.StartInfo.ArgumentList.Add("--no-build"); if (enableAuth) { + // '--' to pass args to func host + funcProcess.StartInfo.ArgumentList.Add("--"); funcProcess.StartInfo.ArgumentList.Add("--enableAuth"); } diff --git a/test/Sdk.E2ETests/TestUtility.cs b/test/Sdk.E2ETests/TestUtility.cs index b1217ad3f..4432636c8 100644 --- a/test/Sdk.E2ETests/TestUtility.cs +++ b/test/Sdk.E2ETests/TestUtility.cs @@ -64,20 +64,13 @@ public static void ValidateFunctionsMetadata(string actualFilePath, string embed { JToken functionsMetadataContents = JToken.Parse(File.ReadAllText(actualFilePath)); var assembly = Assembly.GetExecutingAssembly(); - string resourceName = assembly.GetManifestResourceNames() - .Single(str => str.EndsWith(embeddedResourceName)); - using (Stream stream = assembly.GetManifestResourceStream(resourceName)) - { - using (StreamReader reader = new StreamReader(stream)) - { - using (var jsonReader = new JsonTextReader(reader)) - { - JsonSerializer serializer = new JsonSerializer(); - var expected = serializer.Deserialize(jsonReader); - Assert.True(JToken.DeepEquals(functionsMetadataContents, expected), $"Actual: {functionsMetadataContents}{Environment.NewLine}Expected: {expected}"); - } - } - } + string resourceName = assembly.GetManifestResourceNames().Single(str => str.EndsWith(embeddedResourceName)); + using Stream stream = assembly.GetManifestResourceStream(resourceName); + using StreamReader reader = new(stream); + using JsonTextReader jsonReader = new(reader); + JsonSerializer serializer = new(); + var expected = serializer.Deserialize(jsonReader); + Assert.True(JToken.DeepEquals(functionsMetadataContents, expected), $"Actual: {functionsMetadataContents}{Environment.NewLine}Expected: {expected}"); } public static async Task RestoreAndBuildProjectAsync(string fullPathToProjFile, string outputDir, string additionalParams, ITestOutputHelper outputHelper)