From 305ab1fa4c2e2c1c1509d982fd574995d61750cd Mon Sep 17 00:00:00 2001 From: Pavel Krymets Date: Thu, 31 Aug 2017 15:49:14 -0700 Subject: [PATCH] 1.0, 1.1 template tests (#100) --- build/repo.targets | 1 + ...NetCore.AzureAppServices.TestBundle.csproj | 1 + .../dotnet.cmd | 1 + .../install.cmd | 2 + .../AppServicesWithSiteExtensions.json | 0 .../Assets/DotNetCache.1.0.5.txt | 155 ++++++++++++++ .../Assets/DotNetCache.1.1.2.txt | 155 ++++++++++++++ .../Assets/Legacy.1.0.5.mvc.csproj | 19 ++ .../Assets/Legacy.1.0.5.web.csproj | 15 ++ .../Assets/Legacy.1.1.2.mvc.csproj | 17 ++ .../Assets/Legacy.1.1.2.web.csproj | 15 ++ .../Assets/NuGet.latest.config | 8 + .../RuntimeInformationMiddleware.cs | 2 +- .../AzureFixture.cs | 45 +++- ...re.AzureAppServices.FunctionalTests.csproj | 2 +- .../PathUtilities.cs | 18 +- .../TemplateFunctionalTests.cs | 200 +++++++++++++++--- .../WebAppDeploymentKind.cs | 12 ++ .../WebAppExtensions.cs | 77 ++++++- 19 files changed, 691 insertions(+), 54 deletions(-) create mode 100644 src/Microsoft.AspNetCore.AzureAppServices.TestBundle/dotnet.cmd rename test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/{Templates => Assets}/AppServicesWithSiteExtensions.json (100%) create mode 100644 test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/Assets/DotNetCache.1.0.5.txt create mode 100644 test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/Assets/DotNetCache.1.1.2.txt create mode 100644 test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/Assets/Legacy.1.0.5.mvc.csproj create mode 100644 test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/Assets/Legacy.1.0.5.web.csproj create mode 100644 test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/Assets/Legacy.1.1.2.mvc.csproj create mode 100644 test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/Assets/Legacy.1.1.2.web.csproj create mode 100644 test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/Assets/NuGet.latest.config rename test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/{Templates => Assets}/RuntimeInformationMiddleware.cs (95%) create mode 100644 test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/WebAppDeploymentKind.cs diff --git a/build/repo.targets b/build/repo.targets index 85ba1a8fe5..aa8ed89a8d 100644 --- a/build/repo.targets +++ b/build/repo.targets @@ -11,6 +11,7 @@ + diff --git a/src/Microsoft.AspNetCore.AzureAppServices.TestBundle/Microsoft.AspNetCore.AzureAppServices.TestBundle.csproj b/src/Microsoft.AspNetCore.AzureAppServices.TestBundle/Microsoft.AspNetCore.AzureAppServices.TestBundle.csproj index 8dfc194aea..8d8949b8bf 100644 --- a/src/Microsoft.AspNetCore.AzureAppServices.TestBundle/Microsoft.AspNetCore.AzureAppServices.TestBundle.csproj +++ b/src/Microsoft.AspNetCore.AzureAppServices.TestBundle/Microsoft.AspNetCore.AzureAppServices.TestBundle.csproj @@ -22,6 +22,7 @@ + diff --git a/src/Microsoft.AspNetCore.AzureAppServices.TestBundle/dotnet.cmd b/src/Microsoft.AspNetCore.AzureAppServices.TestBundle/dotnet.cmd new file mode 100644 index 0000000000..b1f5d0c075 --- /dev/null +++ b/src/Microsoft.AspNetCore.AzureAppServices.TestBundle/dotnet.cmd @@ -0,0 +1 @@ +D:\home\SiteExtensions\AspNetCoreTestBundle\dotnet.exe %* \ No newline at end of file diff --git a/src/Microsoft.AspNetCore.AzureAppServices.TestBundle/install.cmd b/src/Microsoft.AspNetCore.AzureAppServices.TestBundle/install.cmd index ee3f1ff9cf..bac2756d10 100644 --- a/src/Microsoft.AspNetCore.AzureAppServices.TestBundle/install.cmd +++ b/src/Microsoft.AspNetCore.AzureAppServices.TestBundle/install.cmd @@ -10,5 +10,7 @@ robocopy "%DOTNET%" "." /E /XC /XN /XO /NFL /NDL ^ /XD "%RUNTIMES%\2.0.0-preview1-002111-00" ^ /XD "%RUNTIMES%\2.0.0-preview2-25407-01" +copy /y dotnet.cmd D:\home\site\deployments\tools + if %errorlevel% geq 8 exit /b 1 exit /b 0 \ No newline at end of file diff --git a/test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/Templates/AppServicesWithSiteExtensions.json b/test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/Assets/AppServicesWithSiteExtensions.json similarity index 100% rename from test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/Templates/AppServicesWithSiteExtensions.json rename to test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/Assets/AppServicesWithSiteExtensions.json diff --git a/test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/Assets/DotNetCache.1.0.5.txt b/test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/Assets/DotNetCache.1.0.5.txt new file mode 100644 index 0000000000..8da4b73745 --- /dev/null +++ b/test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/Assets/DotNetCache.1.0.5.txt @@ -0,0 +1,155 @@ +Microsoft.AspNetCore.Antiforgery +Microsoft.AspNetCore.Authentication +Microsoft.AspNetCore.Authentication.Cookies +Microsoft.AspNetCore.Authentication.Facebook +Microsoft.AspNetCore.Authentication.Google +Microsoft.AspNetCore.Authentication.JwtBearer +Microsoft.AspNetCore.Authentication.MicrosoftAccount +Microsoft.AspNetCore.Authentication.OAuth +Microsoft.AspNetCore.Authentication.OpenIdConnect +Microsoft.AspNetCore.Authentication.Twitter +Microsoft.AspNetCore.Authorization +microsoft.aspnetcore.azureappservicesintegration +Microsoft.AspNetCore.Buffering +Microsoft.AspNetCore.CookiePolicy +Microsoft.AspNetCore.Cors +Microsoft.AspNetCore.Cryptography.Internal +Microsoft.AspNetCore.Cryptography.KeyDerivation +Microsoft.AspNetCore.DataProtection +Microsoft.AspNetCore.DataProtection.Abstractions +microsoft.aspnetcore.dataprotection.azurestorage +Microsoft.AspNetCore.DataProtection.Extensions +microsoft.aspnetcore.dataprotection.redis +Microsoft.AspNetCore.Diagnostics +Microsoft.AspNetCore.Diagnostics.Abstractions +Microsoft.AspNetCore.Diagnostics.Elm +Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore +Microsoft.AspNetCore.Hosting +Microsoft.AspNetCore.Hosting.Abstractions +Microsoft.AspNetCore.Hosting.Server.Abstractions +Microsoft.AspNetCore.Html.Abstractions +Microsoft.AspNetCore.Http +Microsoft.AspNetCore.Http.Abstractions +Microsoft.AspNetCore.Http.Extensions +Microsoft.AspNetCore.Http.Features +Microsoft.AspNetCore.HttpOverrides +Microsoft.AspNetCore.Identity +Microsoft.AspNetCore.Identity.EntityFrameworkCore +Microsoft.AspNetCore.JsonPatch +Microsoft.AspNetCore.Localization +microsoft.aspnetcore.localization.routing +Microsoft.AspNetCore.MiddlewareAnalysis +Microsoft.AspNetCore.Mvc +Microsoft.AspNetCore.Mvc.Abstractions +Microsoft.AspNetCore.Mvc.ApiExplorer +Microsoft.AspNetCore.Mvc.Core +Microsoft.AspNetCore.Mvc.Cors +Microsoft.AspNetCore.Mvc.DataAnnotations +Microsoft.AspNetCore.Mvc.Formatters.Json +Microsoft.AspNetCore.Mvc.Formatters.Xml +Microsoft.AspNetCore.Mvc.Localization +Microsoft.AspNetCore.Mvc.Razor +Microsoft.AspNetCore.Mvc.Razor.Host +Microsoft.AspNetCore.Mvc.TagHelpers +Microsoft.AspNetCore.Mvc.ViewFeatures +Microsoft.AspNetCore.Mvc.WebApiCompatShim +Microsoft.AspNetCore.Owin +Microsoft.AspNetCore.Proxy +Microsoft.AspNetCore.Razor +Microsoft.AspNetCore.Razor.Runtime +microsoft.aspnetcore.responsecaching +microsoft.aspnetcore.responsecaching.abstractions +microsoft.aspnetcore.responsecompression +microsoft.aspnetcore.rewrite +Microsoft.AspNetCore.Routing +Microsoft.AspNetCore.Routing.Abstractions +Microsoft.AspNetCore.Server.IISIntegration +Microsoft.AspNetCore.Server.Kestrel +Microsoft.AspNetCore.Server.Kestrel.Https +Microsoft.AspNetCore.Server.WebListener +Microsoft.AspNetCore.Session +Microsoft.AspNetCore.StaticFiles +microsoft.aspnetcore.websockets +Microsoft.AspNetCore.WebSockets.Protocol +Microsoft.AspNetCore.WebSockets.Server +Microsoft.AspNetCore.WebUtilities +Microsoft.Data.Sqlite +microsoft.dotnet.internalabstractions +Microsoft.EntityFrameworkCore +Microsoft.EntityFrameworkCore.InMemory +Microsoft.EntityFrameworkCore.Relational +Microsoft.EntityFrameworkCore.Relational.Design +Microsoft.EntityFrameworkCore.Relational.Design.Specification.Tests +Microsoft.EntityFrameworkCore.Relational.Specification.Tests +Microsoft.EntityFrameworkCore.Specification.Tests +Microsoft.EntityFrameworkCore.Sqlite +Microsoft.EntityFrameworkCore.Sqlite.Design +Microsoft.EntityFrameworkCore.SqlServer +Microsoft.EntityFrameworkCore.SqlServer.Design +Microsoft.Extensions.Caching.Abstractions +Microsoft.Extensions.Caching.Memory +Microsoft.Extensions.Caching.SqlServer +Microsoft.Extensions.Configuration +Microsoft.Extensions.Configuration.Abstractions +microsoft.extensions.configuration.azurekeyvault +Microsoft.Extensions.Configuration.Binder +Microsoft.Extensions.Configuration.CommandLine +Microsoft.Extensions.Configuration.EnvironmentVariables +Microsoft.Extensions.Configuration.FileExtensions +Microsoft.Extensions.Configuration.Ini +Microsoft.Extensions.Configuration.Json +Microsoft.Extensions.Configuration.UserSecrets +Microsoft.Extensions.Configuration.Xml +Microsoft.Extensions.DependencyInjection +Microsoft.Extensions.DependencyInjection.Abstractions +microsoft.extensions.dependencymodel +Microsoft.Extensions.DiagnosticAdapter +Microsoft.Extensions.FileProviders.Abstractions +Microsoft.Extensions.FileProviders.Composite +Microsoft.Extensions.FileProviders.Embedded +Microsoft.Extensions.FileProviders.Physical +Microsoft.Extensions.FileSystemGlobbing +Microsoft.Extensions.Globalization.CultureInfoCache +Microsoft.Extensions.Localization +Microsoft.Extensions.Localization.Abstractions +Microsoft.Extensions.Logging +Microsoft.Extensions.Logging.Abstractions +microsoft.extensions.logging.azureappservices +Microsoft.Extensions.Logging.Console +Microsoft.Extensions.Logging.Debug +microsoft.extensions.logging.eventsource +Microsoft.Extensions.Logging.Filter +Microsoft.Extensions.Logging.TraceSource +Microsoft.Extensions.ObjectPool +Microsoft.Extensions.Options +Microsoft.Extensions.Options.ConfigurationExtensions +// Microsoft.Extensions.PlatformAbstractions - sha mismatch +Microsoft.Extensions.Primitives +Microsoft.Extensions.WebEncoders +microsoft.identitymodel.logging +microsoft.identitymodel.protocols +microsoft.identitymodel.protocols.openidconnect +microsoft.identitymodel.tokens +microsoft.net.http +Microsoft.Net.Http.Headers +Microsoft.Net.Http.Server +Microsoft.Net.WebSockets.Servern +newtonsoft.json +remotion.linq +system.collections.nongeneric +system.collections.specialized +system.componentmodel.primitives +system.componentmodel.typeconverter +system.data.common +system.data.sqlclient +system.diagnostics.contracts +system.diagnostics.tracesource +system.identitymodel.tokens.jwt +system.interactive.async +system.io.pipes +system.net.websockets +system.private.datacontractserialization +system.runtime.serialization.primitives +system.runtime.serialization.xml +//system.text.encodings.web - sha mismatch +system.xml.xmlserializer \ No newline at end of file diff --git a/test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/Assets/DotNetCache.1.1.2.txt b/test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/Assets/DotNetCache.1.1.2.txt new file mode 100644 index 0000000000..caff5f16b5 --- /dev/null +++ b/test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/Assets/DotNetCache.1.1.2.txt @@ -0,0 +1,155 @@ +Microsoft.AspNetCore.Antiforgery +Microsoft.AspNetCore.Authentication +Microsoft.AspNetCore.Authentication.Cookies +Microsoft.AspNetCore.Authentication.Facebook +Microsoft.AspNetCore.Authentication.Google +Microsoft.AspNetCore.Authentication.JwtBearer +Microsoft.AspNetCore.Authentication.MicrosoftAccount +Microsoft.AspNetCore.Authentication.OAuth +Microsoft.AspNetCore.Authentication.OpenIdConnect +Microsoft.AspNetCore.Authentication.Twitter +Microsoft.AspNetCore.Authorization +microsoft.aspnetcore.azureappservicesintegration +Microsoft.AspNetCore.Buffering +Microsoft.AspNetCore.CookiePolicy +Microsoft.AspNetCore.Cors +Microsoft.AspNetCore.Cryptography.Internal +Microsoft.AspNetCore.Cryptography.KeyDerivation +Microsoft.AspNetCore.DataProtection +Microsoft.AspNetCore.DataProtection.Abstractions +microsoft.aspnetcore.dataprotection.azurestorage +Microsoft.AspNetCore.DataProtection.Extensions +microsoft.aspnetcore.dataprotection.redis +Microsoft.AspNetCore.Diagnostics +Microsoft.AspNetCore.Diagnostics.Abstractions +Microsoft.AspNetCore.Diagnostics.Elm +Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore +Microsoft.AspNetCore.Hosting +Microsoft.AspNetCore.Hosting.Abstractions +Microsoft.AspNetCore.Hosting.Server.Abstractions +Microsoft.AspNetCore.Html.Abstractions +Microsoft.AspNetCore.Http +Microsoft.AspNetCore.Http.Abstractions +Microsoft.AspNetCore.Http.Extensions +Microsoft.AspNetCore.Http.Features +Microsoft.AspNetCore.HttpOverrides +Microsoft.AspNetCore.Identity +Microsoft.AspNetCore.Identity.EntityFrameworkCore +Microsoft.AspNetCore.JsonPatch +Microsoft.AspNetCore.Localization +microsoft.aspnetcore.localization.routing +Microsoft.AspNetCore.MiddlewareAnalysis +Microsoft.AspNetCore.Mvc +Microsoft.AspNetCore.Mvc.Abstractions +Microsoft.AspNetCore.Mvc.ApiExplorer +Microsoft.AspNetCore.Mvc.Core +Microsoft.AspNetCore.Mvc.Cors +Microsoft.AspNetCore.Mvc.DataAnnotations +Microsoft.AspNetCore.Mvc.Formatters.Json +Microsoft.AspNetCore.Mvc.Formatters.Xml +Microsoft.AspNetCore.Mvc.Localization +Microsoft.AspNetCore.Mvc.Razor +Microsoft.AspNetCore.Mvc.Razor.Host +Microsoft.AspNetCore.Mvc.TagHelpers +Microsoft.AspNetCore.Mvc.ViewFeatures +Microsoft.AspNetCore.Mvc.WebApiCompatShim +Microsoft.AspNetCore.Owin +Microsoft.AspNetCore.Proxy +Microsoft.AspNetCore.Razor +Microsoft.AspNetCore.Razor.Runtime +microsoft.aspnetcore.responsecaching +microsoft.aspnetcore.responsecaching.abstractions +microsoft.aspnetcore.responsecompression +microsoft.aspnetcore.rewrite +Microsoft.AspNetCore.Routing +Microsoft.AspNetCore.Routing.Abstractions +Microsoft.AspNetCore.Server.IISIntegration +Microsoft.AspNetCore.Server.Kestrel +Microsoft.AspNetCore.Server.Kestrel.Https +Microsoft.AspNetCore.Server.WebListener +Microsoft.AspNetCore.Session +Microsoft.AspNetCore.StaticFiles +microsoft.aspnetcore.websockets +Microsoft.AspNetCore.WebSockets.Protocol +Microsoft.AspNetCore.WebSockets.Server +Microsoft.AspNetCore.WebUtilities +Microsoft.Data.Sqlite +microsoft.dotnet.internalabstractions +Microsoft.EntityFrameworkCore +Microsoft.EntityFrameworkCore.InMemory +Microsoft.EntityFrameworkCore.Relational +Microsoft.EntityFrameworkCore.Relational.Design +Microsoft.EntityFrameworkCore.Relational.Design.Specification.Tests +Microsoft.EntityFrameworkCore.Relational.Specification.Tests +Microsoft.EntityFrameworkCore.Specification.Tests +Microsoft.EntityFrameworkCore.Sqlite +Microsoft.EntityFrameworkCore.Sqlite.Design +Microsoft.EntityFrameworkCore.SqlServer +Microsoft.EntityFrameworkCore.SqlServer.Design +Microsoft.Extensions.Caching.Abstractions +Microsoft.Extensions.Caching.Memory +Microsoft.Extensions.Caching.SqlServer +Microsoft.Extensions.Configuration +Microsoft.Extensions.Configuration.Abstractions +microsoft.extensions.configuration.azurekeyvault +Microsoft.Extensions.Configuration.Binder +Microsoft.Extensions.Configuration.CommandLine +Microsoft.Extensions.Configuration.EnvironmentVariables +Microsoft.Extensions.Configuration.FileExtensions +Microsoft.Extensions.Configuration.Ini +Microsoft.Extensions.Configuration.Json +Microsoft.Extensions.Configuration.UserSecrets +Microsoft.Extensions.Configuration.Xml +Microsoft.Extensions.DependencyInjection +Microsoft.Extensions.DependencyInjection.Abstractions +//microsoft.extensions.dependencymodel - sha mismatch +Microsoft.Extensions.DiagnosticAdapter +Microsoft.Extensions.FileProviders.Abstractions +Microsoft.Extensions.FileProviders.Composite +Microsoft.Extensions.FileProviders.Embedded +Microsoft.Extensions.FileProviders.Physical +Microsoft.Extensions.FileSystemGlobbing +Microsoft.Extensions.Globalization.CultureInfoCache +Microsoft.Extensions.Localization +Microsoft.Extensions.Localization.Abstractions +Microsoft.Extensions.Logging +Microsoft.Extensions.Logging.Abstractions +microsoft.extensions.logging.azureappservices +Microsoft.Extensions.Logging.Console +Microsoft.Extensions.Logging.Debug +microsoft.extensions.logging.eventsource +Microsoft.Extensions.Logging.Filter +Microsoft.Extensions.Logging.TraceSource +Microsoft.Extensions.ObjectPool +Microsoft.Extensions.Options +Microsoft.Extensions.Options.ConfigurationExtensions +Microsoft.Extensions.PlatformAbstractions +Microsoft.Extensions.Primitives +Microsoft.Extensions.WebEncoders +microsoft.identitymodel.logging +microsoft.identitymodel.protocols +microsoft.identitymodel.protocols.openidconnect +microsoft.identitymodel.tokens +microsoft.net.http +Microsoft.Net.Http.Headers +Microsoft.Net.Http.Server +Microsoft.Net.WebSockets.Servern +newtonsoft.json +remotion.linq +// system.collections.nongeneric - sha mismatch +// system.collections.specialized - sha mismatch +// system.componentmodel.primitives - sha mismatch +// system.componentmodel.typeconverter - sha mismatch +system.data.common +system.data.sqlclient +system.diagnostics.contracts +system.diagnostics.tracesource +system.identitymodel.tokens.jwt +system.interactive.async +system.io.pipes +system.net.websockets +system.private.datacontractserialization +// system.runtime.serialization.primitives - sha mismatch +system.runtime.serialization.xml +//system.text.encodings.web - sha mismatch +system.xml.xmlserializer \ No newline at end of file diff --git a/test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/Assets/Legacy.1.0.5.mvc.csproj b/test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/Assets/Legacy.1.0.5.mvc.csproj new file mode 100644 index 0000000000..bbad0448ac --- /dev/null +++ b/test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/Assets/Legacy.1.0.5.mvc.csproj @@ -0,0 +1,19 @@ + + + Exe + netcoreapp1.0 + true + + + + $(PackageTargetFallback);portable-net45+win8+wp8+wpa81; + + + + + + + + + + diff --git a/test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/Assets/Legacy.1.0.5.web.csproj b/test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/Assets/Legacy.1.0.5.web.csproj new file mode 100644 index 0000000000..9920de4da0 --- /dev/null +++ b/test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/Assets/Legacy.1.0.5.web.csproj @@ -0,0 +1,15 @@ + + + Exe + netcoreapp1.0 + true + + + + $(PackageTargetFallback);portable-net45+win8+wp8+wpa81; + + + + + + diff --git a/test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/Assets/Legacy.1.1.2.mvc.csproj b/test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/Assets/Legacy.1.1.2.mvc.csproj new file mode 100644 index 0000000000..0d78be3aed --- /dev/null +++ b/test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/Assets/Legacy.1.1.2.mvc.csproj @@ -0,0 +1,17 @@ + + + + netcoreapp1.1 + + + + + + + + + + + + + diff --git a/test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/Assets/Legacy.1.1.2.web.csproj b/test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/Assets/Legacy.1.1.2.web.csproj new file mode 100644 index 0000000000..d30aff10a1 --- /dev/null +++ b/test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/Assets/Legacy.1.1.2.web.csproj @@ -0,0 +1,15 @@ + + + + netcoreapp1.1 + + + + + + + + + + + diff --git a/test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/Assets/NuGet.latest.config b/test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/Assets/NuGet.latest.config new file mode 100644 index 0000000000..4a06556f1c --- /dev/null +++ b/test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/Assets/NuGet.latest.config @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/Templates/RuntimeInformationMiddleware.cs b/test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/Assets/RuntimeInformationMiddleware.cs similarity index 95% rename from test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/Templates/RuntimeInformationMiddleware.cs rename to test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/Assets/RuntimeInformationMiddleware.cs index 2850f0a77f..1aa6ad74e7 100644 --- a/test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/Templates/RuntimeInformationMiddleware.cs +++ b/test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/Assets/RuntimeInformationMiddleware.cs @@ -51,7 +51,7 @@ namespace Microsoft.AspNetCore.AzureAppServices.FunctionalTests Assembly assembly = null; try { - assembly = Assembly.Load(Path.GetFileNameWithoutExtension(m.ModuleName)); + assembly = Assembly.Load(new AssemblyName(Path.GetFileNameWithoutExtension(m.ModuleName))); } catch { } diff --git a/test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/AzureFixture.cs b/test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/AzureFixture.cs index 007ebd8daf..c8f5954212 100644 --- a/test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/AzureFixture.cs +++ b/test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/AzureFixture.cs @@ -65,7 +65,7 @@ namespace Microsoft.AspNetCore.AzureAppServices.FunctionalTests Plan = Azure.AppServices.AppServicePlans.Define(servicePlanName) .WithRegion(Region.USWest2) .WithExistingResourceGroup(ResourceGroup) - .WithPricingTier(PricingTier.BasicB1) + .WithPricingTier(PricingTier.StandardS1) .WithOperatingSystem(OperatingSystem.Windows) .Create(); } @@ -98,7 +98,50 @@ namespace Microsoft.AspNetCore.AzureAppServices.FunctionalTests return name + Timestamp; } + private Dictionary>> _deploymentCache = new Dictionary>>(); + private int _predeploymentId; + public async Task Deploy(string template, IDictionary additionalArguments = null, [CallerMemberName] string baseName = null) + { + List> deployments; + + void DeployBatch() + { + var maxId = _predeploymentId + 5; + for (; _predeploymentId < maxId; _predeploymentId++) + { + deployments.Add(DeployImpl(template, additionalArguments, "PreDeploy" + _predeploymentId)); + } + } + + var deploymentKeyParts = new List(); + deploymentKeyParts.Add(template); + if (additionalArguments != null) + { + deploymentKeyParts.AddRange(additionalArguments.Select(a => a.Key + "=" + a.Value)); + } + var deploymentKey = string.Join(Environment.NewLine, deploymentKeyParts); + + Task deployment; + if (!_deploymentCache.TryGetValue(deploymentKey, out deployments)) + { + deployments = new List>(); + DeployBatch(); + _deploymentCache[deploymentKey] = deployments; + } + + deployment = await Task.WhenAny(deployments); + deployments.Remove(deployment); + + if (deployments.Count == 2) + { + DeployBatch(); + } + + return await deployment; + } + + private async Task DeployImpl(string template, IDictionary additionalArguments = null, [CallerMemberName] string baseName = null) { var siteName = GetTimestampedName(baseName); var parameters = new Dictionary diff --git a/test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/Microsoft.AspNetCore.AzureAppServices.FunctionalTests.csproj b/test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/Microsoft.AspNetCore.AzureAppServices.FunctionalTests.csproj index 1ae218e17d..b5ffd418c4 100644 --- a/test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/Microsoft.AspNetCore.AzureAppServices.FunctionalTests.csproj +++ b/test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/Microsoft.AspNetCore.AzureAppServices.FunctionalTests.csproj @@ -6,7 +6,7 @@ - + diff --git a/test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/PathUtilities.cs b/test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/PathUtilities.cs index e685152da4..f43ee9163a 100644 --- a/test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/PathUtilities.cs +++ b/test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/PathUtilities.cs @@ -21,19 +21,17 @@ namespace Microsoft.AspNetCore.AzureAppServices.FunctionalTests .ToArray(); } - public static string[] GetSharedRuntimeAssemblies(string dotnetPath, out string runtimeVersion) + public static string[] GetLatestSharedRuntimeAssemblies(string dotnetPath, out string runtimeVersion) { var dotnetHome = Path.GetDirectoryName(dotnetPath); var runtimeDirectory = new DirectoryInfo(Path.Combine(dotnetHome, "shared", "Microsoft.NETCore.App")) .GetDirectories() - .Single(); + .OrderByDescending(d => d.Name) + .First(); runtimeVersion = runtimeDirectory.Name; - return runtimeDirectory - .GetFiles("*.dll") - .Select(GetName) - .ToArray(); + return GetAllModules(runtimeDirectory); } public static string GetBundledAspNetCoreVersion(string dotnetPath) @@ -52,5 +50,13 @@ namespace Microsoft.AspNetCore.AzureAppServices.FunctionalTests public string Name { get; set; } public string[] Versions { get; set; } } + + public static string[] GetAllModules(DirectoryInfo publishPath) + { + return publishPath + .GetFiles("*.dll") + .Select(GetName) + .ToArray(); + } } } \ No newline at end of file diff --git a/test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/TemplateFunctionalTests.cs b/test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/TemplateFunctionalTests.cs index d3dfa3a0fe..66a29bb27c 100644 --- a/test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/TemplateFunctionalTests.cs +++ b/test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/TemplateFunctionalTests.cs @@ -19,9 +19,11 @@ namespace Microsoft.AspNetCore.AzureAppServices.FunctionalTests [Collection("Azure")] public class TemplateFunctionalTests { - private const string RuntimeInformationMiddlewareType = "Microsoft.AspNetCore.AzureAppServices.FunctionalTests.RuntimeInformationMiddleware"; + private static readonly string RuntimeInformationMiddlewareType = "Microsoft.AspNetCore.AzureAppServices.FunctionalTests.RuntimeInformationMiddleware"; - private const string RuntimeInformationMiddlewareFile = "Templates\\RuntimeInformationMiddleware.cs"; + private static readonly string RuntimeInformationMiddlewareFile = Asset("RuntimeInformationMiddleware.cs"); + + private static readonly string AppServicesWithSiteExtensionsTemplate = Asset("AppServicesWithSiteExtensions.json"); readonly AzureFixture _fixture; @@ -34,39 +36,34 @@ namespace Microsoft.AspNetCore.AzureAppServices.FunctionalTests } [Theory] - [InlineData("2.0", "web", "Hello World!")] - [InlineData("2.0", "razor", "Learn how to build ASP.NET apps that can run anywhere.")] - [InlineData("2.0", "mvc", "Learn how to build ASP.NET apps that can run anywhere.")] - [InlineData("latest", "web", "Hello World!")] - [InlineData("latest", "razor", "Learn how to build ASP.NET apps that can run anywhere.")] - [InlineData("latest", "mvc", "Learn how to build ASP.NET apps that can run anywhere.")] - public async Task TemplateRuns(string dotnetVersion, string template, string expected) + [InlineData(WebAppDeploymentKind.Git, "1.0.5", "web", "Hello World!")] + [InlineData(WebAppDeploymentKind.Git, "1.0.5", "mvc", "Learn how to build ASP.NET apps that can run anywhere")] + [InlineData(WebAppDeploymentKind.Git, "1.1.2", "web", "Hello World!")] + [InlineData(WebAppDeploymentKind.Git, "1.1.2", "mvc", "Learn how to build ASP.NET apps that can run anywhere")] + [InlineData(WebAppDeploymentKind.Ftp, "1.0.5", "web", "Hello World!")] + [InlineData(WebAppDeploymentKind.Ftp, "1.0.5", "mvc", "Learn how to build ASP.NET apps that can run anywhere")] + [InlineData(WebAppDeploymentKind.Ftp, "1.1.2", "web", "Hello World!")] + [InlineData(WebAppDeploymentKind.Ftp, "1.1.2", "mvc", "Learn how to build ASP.NET apps that can run anywhere")] + public async Task LegacyTemplateRuns(WebAppDeploymentKind deploymentKind, string expectedRuntime, string template, string expected) { - var testId = nameof(TemplateRuns) + template + dotnetVersion.Replace(".", string.Empty); + var testId = ToFriendlyName(nameof(LegacyTemplateRuns), deploymentKind, template, expectedRuntime); using (var logger = GetLogger(testId)) { - var site = await _fixture.Deploy("Templates\\AppServicesWithSiteExtensions.json", - baseName: testId, - additionalArguments: new Dictionary - { - { "extensionFeed", AzureFixture.GetRequiredEnvironmentVariable("SiteExtensionFeed") }, - { "extensionName", "AspNetCoreTestBundle" }, - { "extensionVersion", GetAssemblyInformationalVersion() }, - }); + var siteTask = _fixture.Deploy(AppServicesWithSiteExtensionsTemplate, GetSiteExtensionArguments(), testId); var testDirectory = GetTestDirectory(testId); - var dotnet = DotNet(logger, testDirectory, dotnetVersion); - await dotnet.ExecuteAndAssertAsync("new " + template); + var dotnet = DotNet(logger, testDirectory, "1.1"); + + await dotnet.ExecuteAndAssertAsync($"new {template}"); + + UpdateCSProj(testDirectory, Asset($"Legacy.{expectedRuntime}.{template}.csproj")); InjectMiddlware(testDirectory, RuntimeInformationMiddlewareType, RuntimeInformationMiddlewareFile); - FixAspNetCoreVersion(testDirectory, dotnet.Command); - - await site.BuildPublishProfileAsync(testDirectory.FullName); - - await dotnet.ExecuteAndAssertAsync("publish /p:PublishProfile=Profile"); + var site = await siteTask; + await site.Deploy(deploymentKind, testDirectory, dotnet, logger); using (var httpClient = site.CreateClient()) { @@ -78,18 +75,115 @@ namespace Microsoft.AspNetCore.AzureAppServices.FunctionalTests getResult.EnsureSuccessStatusCode(); var runtimeInfo = JsonConvert.DeserializeObject(await getResult.Content.ReadAsStringAsync()); - ValidateRuntimeInfo(runtimeInfo, dotnet.Command); + ValidateLegacyRuntimeInfo(runtimeInfo, expectedRuntime, dotnet.Command); } } } - private void ValidateRuntimeInfo(RuntimeInfo runtimeInfo, string dotnetPath) + private void ValidateLegacyRuntimeInfo(RuntimeInfo runtimeInfo, string expectedRuntime, string dotnetPath) { - var storeModules = PathUtilities.GetStoreModules(dotnetPath); - var runtimeModules = PathUtilities.GetSharedRuntimeAssemblies(dotnetPath, out var runtimeVersion); + var cacheAssemblies = new HashSet(File.ReadAllLines(Asset($"DotNetCache.{expectedRuntime}.txt")), StringComparer.InvariantCultureIgnoreCase); + var runtimeModules = PathUtilities.GetLatestSharedRuntimeAssemblies(dotnetPath, out _); + var modulesNotInCache = new List(); foreach (var runtimeInfoModule in runtimeInfo.Modules) { + // Skip native + if (runtimeInfoModule.Version == null) + { + continue; + } + + // Verify that modules that we expect to come from runtime actually come from there + if (runtimeModules.Any(rutimeModule => runtimeInfoModule.ModuleName.Equals(rutimeModule, StringComparison.InvariantCultureIgnoreCase))) + { + Assert.Contains($"shared\\Microsoft.NETCore.App\\{expectedRuntime}", runtimeInfoModule.FileName); + continue; + } + + // Check if assembly that is in the cache is loaded from it + if (cacheAssemblies.Contains(Path.GetFileNameWithoutExtension(runtimeInfoModule.ModuleName))) + { + if (runtimeInfoModule.FileName.IndexOf("D:\\DotNetCache\\x86\\", StringComparison.CurrentCultureIgnoreCase) == -1) + { + modulesNotInCache.Add(runtimeInfoModule.FileName); + } + continue; + } + + Assert.Contains("wwwroot\\", runtimeInfoModule.FileName); + } + + Assert.Empty(modulesNotInCache); + } + + [Theory] + [InlineData(WebAppDeploymentKind.Git, "2.0", "web", "Hello World!")] + [InlineData(WebAppDeploymentKind.Git, "2.0", "razor", "Learn how to build ASP.NET apps that can run anywhere.")] + [InlineData(WebAppDeploymentKind.Git, "2.0", "mvc", "Learn how to build ASP.NET apps that can run anywhere.")] + [InlineData(WebAppDeploymentKind.Git, "latest", "web", "Hello World!")] + [InlineData(WebAppDeploymentKind.Git, "latest", "razor", "Learn how to build ASP.NET apps that can run anywhere.")] + [InlineData(WebAppDeploymentKind.Git, "latest", "mvc", "Learn how to build ASP.NET apps that can run anywhere.")] + [InlineData(WebAppDeploymentKind.WebDeploy, "2.0", "web", "Hello World!")] + [InlineData(WebAppDeploymentKind.WebDeploy, "2.0", "razor", "Learn how to build ASP.NET apps that can run anywhere.")] + [InlineData(WebAppDeploymentKind.WebDeploy, "2.0", "mvc", "Learn how to build ASP.NET apps that can run anywhere.")] + [InlineData(WebAppDeploymentKind.WebDeploy, "latest", "web", "Hello World!")] + [InlineData(WebAppDeploymentKind.WebDeploy, "latest", "razor", "Learn how to build ASP.NET apps that can run anywhere.")] + [InlineData(WebAppDeploymentKind.WebDeploy, "latest", "mvc", "Learn how to build ASP.NET apps that can run anywhere.")] + public async Task TemplateRuns(WebAppDeploymentKind deploymentKind, string dotnetVersion, string template, string expected) + { + var testId = ToFriendlyName(nameof(TemplateRuns), deploymentKind, template, dotnetVersion); + + using (var logger = GetLogger(testId)) + { + var siteTask = _fixture.Deploy(AppServicesWithSiteExtensionsTemplate, GetSiteExtensionArguments(), testId); + + var testDirectory = GetTestDirectory(testId); + var dotnet = DotNet(logger, testDirectory, dotnetVersion); + + await dotnet.ExecuteAndAssertAsync("new " + template); + + // We don't ship offline cache in site extension so we need to provider a feed to + // restore from when doing kudu git deploy for version not published to Nuget + if (deploymentKind == WebAppDeploymentKind.Git && dotnetVersion == "latest") + { + CopyToProjectDirectory(testDirectory, Asset("Nuget.latest.config"), "NuGet.config"); + } + + InjectMiddlware(testDirectory, RuntimeInformationMiddlewareType, RuntimeInformationMiddlewareFile); + FixAspNetCoreVersion(testDirectory, dotnet.Command); + + var site = await siteTask; + await site.Deploy(deploymentKind, testDirectory, dotnet, logger); + + using (var httpClient = site.CreateClient()) + { + var getResult = await httpClient.GetAsync("/"); + getResult.EnsureSuccessStatusCode(); + Assert.Contains(expected, await getResult.Content.ReadAsStringAsync()); + + getResult = await httpClient.GetAsync("/runtimeInfo"); + getResult.EnsureSuccessStatusCode(); + + var runtimeInfo = JsonConvert.DeserializeObject(await getResult.Content.ReadAsStringAsync()); + ValidateStoreRuntimeInfo(runtimeInfo, dotnet.Command); + } + } + } + + private void ValidateStoreRuntimeInfo(RuntimeInfo runtimeInfo, string dotnetPath) + { + var storeModules = PathUtilities.GetStoreModules(dotnetPath); + var runtimeModules = PathUtilities.GetLatestSharedRuntimeAssemblies(dotnetPath, out var runtimeVersion); + + foreach (var runtimeInfoModule in runtimeInfo.Modules) + { + // Skip native + if (runtimeInfoModule.Version == null) + { + continue; + } + var moduleName = Path.GetFileNameWithoutExtension(runtimeInfoModule.ModuleName); // Check if module should come from the store, verify that one of the expected versions is loaded @@ -113,14 +207,44 @@ namespace Microsoft.AspNetCore.AzureAppServices.FunctionalTests // Verify that modules that we expect to come from runtime actually come from there // Native modules would prefer to be loaded from windows folder, skip them - if (runtimeModules.Any(rutimeModule => runtimeInfoModule.ModuleName.Equals(rutimeModule, StringComparison.InvariantCultureIgnoreCase)) && - runtimeInfoModule.FileName.IndexOf("windows\\system32", StringComparison.InvariantCultureIgnoreCase) == -1) + if (runtimeModules.Any(rutimeModule => runtimeInfoModule.ModuleName.Equals(rutimeModule, StringComparison.InvariantCultureIgnoreCase))) { Assert.Contains($"shared\\Microsoft.NETCore.App\\{runtimeVersion}", runtimeInfoModule.FileName); } } } + private string ToFriendlyName(params object[] parts) + { + return new string(string.Join(string.Empty, parts).Where(char.IsLetterOrDigit).ToArray()); + } + + private static Dictionary GetSiteExtensionArguments() + { + return new Dictionary + { + { "extensionFeed", AzureFixture.GetRequiredEnvironmentVariable("SiteExtensionFeed") }, + { "extensionName", "AspNetCoreTestBundle" }, + { "extensionVersion", GetAssemblyInformationalVersion() }, + }; + } + + private static void UpdateCSProj(DirectoryInfo projectRoot, string fileName) + { + var csproj = projectRoot.GetFiles("*.csproj").Single().FullName; + + // Copy implementation file to project directory + var implementationFile = Path.Combine(Directory.GetCurrentDirectory(), fileName); + File.Copy(implementationFile, csproj, true); + } + + private static void CopyToProjectDirectory(DirectoryInfo projectRoot, string fileName, string desinationFileName = null) + { + // Copy implementation file to project directory + var implementationFile = Path.Combine(Directory.GetCurrentDirectory(), fileName); + File.Copy(implementationFile, Path.Combine(projectRoot.FullName, desinationFileName ?? Path.GetFileName(fileName)), true); + } + private static void InjectMiddlware(DirectoryInfo projectRoot, string typeName, string fileName) { // Copy implementation file to project directory @@ -162,7 +286,7 @@ namespace Microsoft.AspNetCore.AzureAppServices.FunctionalTests projectContents.Save(csproj); } - private string GetAssemblyInformationalVersion() + private static string GetAssemblyInformationalVersion() { var assemblyInformationalVersionAttribute = typeof(TemplateFunctionalTests).Assembly.GetCustomAttribute(); if (assemblyInformationalVersionAttribute == null) @@ -208,14 +332,22 @@ namespace Microsoft.AspNetCore.AzureAppServices.FunctionalTests throw new InvalidOperationException("dotnet executable was not found"); } - private DirectoryInfo GetTestDirectory([CallerMemberName] string callerName = null) { if (Directory.Exists(callerName)) { - Directory.Delete(callerName, recursive:true); + try + { + Directory.Delete(callerName, recursive: true); + } + catch { } } return Directory.CreateDirectory(callerName); } + + private static string Asset(string name) + { + return "Assets\\" + name; + } } } \ No newline at end of file diff --git a/test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/WebAppDeploymentKind.cs b/test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/WebAppDeploymentKind.cs new file mode 100644 index 0000000000..36b5915f22 --- /dev/null +++ b/test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/WebAppDeploymentKind.cs @@ -0,0 +1,12 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +namespace Microsoft.AspNetCore.AzureAppServices.FunctionalTests +{ + public enum WebAppDeploymentKind + { + Git, + WebDeploy, + Ftp + } +} \ No newline at end of file diff --git a/test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/WebAppExtensions.cs b/test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/WebAppExtensions.cs index c53a3ca77d..b7888d7bfa 100644 --- a/test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/WebAppExtensions.cs +++ b/test/Microsoft.AspNetCore.AzureAppServices.FunctionalTests/WebAppExtensions.cs @@ -6,12 +6,12 @@ using System.IO; using System.Linq; using System.Net; using System.Net.Http; -using System.Threading; using System.Threading.Tasks; using System.Xml.Linq; using Microsoft.Azure.Management.AppService.Fluent; using Microsoft.Azure.Management.AppService.Fluent.Models; using Microsoft.Extensions.Logging; +using Xunit; namespace Microsoft.AspNetCore.AzureAppServices.FunctionalTests { @@ -26,21 +26,16 @@ namespace Microsoft.AspNetCore.AzureAppServices.FunctionalTests public static async Task UploadFilesAsync(this IWebApp site, DirectoryInfo from, string to, IPublishingProfile publishingProfile, ILogger logger) { - foreach (var info in from.GetFileSystemInfos("*", SearchOption.AllDirectories)) + foreach (var info in from.GetFileSystemInfos("*")) { + var address = new Uri( + "ftp://" + publishingProfile.FtpUrl + to + info.FullName.Substring(from.FullName.Length + 1).Replace('\\', '/')); + if (info is FileInfo file) { - var address = new Uri( - "ftp://" + publishingProfile.FtpUrl + to + file.FullName.Substring(from.FullName.Length).Replace('\\', '/')); logger.LogInformation($"Uploading {file.FullName} to {address}"); - var request = (FtpWebRequest)WebRequest.Create(address); - request.Method = WebRequestMethods.Ftp.UploadFile; - request.KeepAlive = true; - request.UseBinary = true; - request.UsePassive = false; - request.Credentials = new NetworkCredential(publishingProfile.FtpUsername, publishingProfile.FtpPassword); - request.ConnectionGroupName = "group"; + var request = CreateRequest(publishingProfile, address, WebRequestMethods.Ftp.UploadFile); using (var fileStream = File.OpenRead(file.FullName)) { using (var requestStream = await request.GetRequestStreamAsync()) @@ -50,9 +45,69 @@ namespace Microsoft.AspNetCore.AzureAppServices.FunctionalTests } await request.GetResponseAsync(); } + if (info is DirectoryInfo directory) + { + var request = CreateRequest(publishingProfile, address, WebRequestMethods.Ftp.MakeDirectory); + await request.GetResponseAsync(); + await UploadFilesAsync(site, directory, to + directory.Name + '/', publishingProfile, logger); + } } } + private static FtpWebRequest CreateRequest(IPublishingProfile publishingProfile, Uri address, string method) + { + var request = (FtpWebRequest) WebRequest.Create(address); + request.Method = method; + request.KeepAlive = true; + request.UseBinary = true; + request.UsePassive = false; + request.Credentials = new NetworkCredential(publishingProfile.FtpUsername, publishingProfile.FtpPassword); + request.ConnectionGroupName = "group"; + return request; + } + + + public static async Task Deploy(this IWebApp site, WebAppDeploymentKind kind, DirectoryInfo from, TestCommand dotnet, ILogger logger) + { + switch (kind) + { + case WebAppDeploymentKind.Git: + await site.GitDeploy(from, logger); + break; + case WebAppDeploymentKind.WebDeploy: + await site.BuildPublishProfileAsync(from.FullName); + await dotnet.ExecuteAndAssertAsync("publish /p:PublishProfile=Profile"); + break; + case WebAppDeploymentKind.Ftp: + var publishDirectory = from.CreateSubdirectory("publish"); + await dotnet.ExecuteAndAssertAsync("restore"); + await dotnet.ExecuteAndAssertAsync("publish -o " + publishDirectory.FullName); + await site.UploadFilesAsync(publishDirectory, "/", await site.GetPublishingProfileAsync(), logger); + break; + default: + throw new ArgumentOutOfRangeException(nameof(kind), kind, null); + } + } + + public static async Task GitDeploy(this IWebApp site, DirectoryInfo workingDirectory, ILogger logger) + { + var git = new TestCommand("git") + { + Logger = logger, + WorkingDirectory = workingDirectory.FullName + }; + + var publishingProfile = await site.GetPublishingProfileAsync(); + + await git.ExecuteAndAssertAsync("init"); + await git.ExecuteAndAssertAsync($"remote add origin https://{publishingProfile.GitUsername}:{publishingProfile.GitPassword}@{publishingProfile.GitUrl}"); + await git.ExecuteAndAssertAsync("add ."); + await git.ExecuteAndAssertAsync("commit -am Initial"); + var result = await git.ExecuteAndAssertAsync("push origin master"); + + Assert.DoesNotContain("An error has occurred during web site deployment", result.StdErr); + } + public static async Task BuildPublishProfileAsync(this IWebApp site, string projectDirectory) { var result = await site.Manager.WebApps.Inner.ListPublishingProfileXmlWithSecretsAsync(