1.0, 1.1 template tests (#100)

This commit is contained in:
Pavel Krymets 2017-08-31 15:49:14 -07:00 committed by GitHub
parent dbb9262d68
commit 305ab1fa4c
19 changed files with 691 additions and 54 deletions

View File

@ -11,6 +11,7 @@
<ItemGroup>
<DotNetCoreSdk Include="2.0.0" InstallDir="$(TestDotNetPath)2.0\" Condition="'$(AntaresTests)' != ''"/>
<DotNetCoreSdk Include="1.0.4" InstallDir="$(TestDotNetPath)1.1\" Condition="'$(AntaresTests)' != ''"/>
<DotNetCoreSdk Include="coherent" Channel="master" InstallDir="$(TestDotNetPath)latest\" Condition="'$(AntaresTests)' != ''"/>
</ItemGroup>

View File

@ -22,6 +22,7 @@
<ItemGroup>
<Content Include="applicationHost.xdt" />
<Content Include="install.cmd" />
<Content Include="dotnet.cmd" />
<Content Include="$(OutputPath)\Microsoft.Web.Xdt.Extensions.dll" PackagePath="content" />
<Content Include="$(DotnetHomeDirectory)**\*.*" Exclude="$(DotnetHomeDirectory)**\nuGetPackagesArchive.lzma" Condition="$(DotnetHomeDirectory) != ''" PackagePath="content\%(RecursiveDir)%(FileName)%(Extension)" />
</ItemGroup>

View File

@ -0,0 +1 @@
D:\home\SiteExtensions\AspNetCoreTestBundle\dotnet.exe %*

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,19 @@
<Project ToolsVersion="15.0" Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp1.0</TargetFramework>
<PreserveCompilationContext>true</PreserveCompilationContext>
</PropertyGroup>
<PropertyGroup>
<PackageTargetFallback>$(PackageTargetFallback);portable-net45+win8+wp8+wpa81;</PackageTargetFallback>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore" Version="1.0.5" />
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="1.0.4" />
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="1.0.3" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="1.0.2" />
<PackageReference Include="Microsoft.VisualStudio.Web.BrowserLink" Version="1.0.1" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,15 @@
<Project ToolsVersion="15.0" Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp1.0</TargetFramework>
<PreserveCompilationContext>true</PreserveCompilationContext>
</PropertyGroup>
<PropertyGroup>
<PackageTargetFallback>$(PackageTargetFallback);portable-net45+win8+wp8+wpa81;</PackageTargetFallback>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore" Version="1.0.5" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp1.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore" Version="1.1.2" />
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="1.1.3" />
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="1.1.2" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="1.1.2" />
<PackageReference Include="Microsoft.VisualStudio.Web.BrowserLink" Version="1.1.2" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp1.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Folder Include="wwwroot\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore" Version="1.1.2" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<clear />
<add key="AspNetCore" value="https://dotnet.myget.org/F/aspnetcore-ci-dev/api/v3/index.json" />
<add key="NuGet" value="https://api.nuget.org/v3/index.json" />
</packageSources>
</configuration>

View File

@ -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 { }

View File

@ -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<string, List<Task<IWebApp>>> _deploymentCache = new Dictionary<string, List<Task<IWebApp>>>();
private int _predeploymentId;
public async Task<IWebApp> Deploy(string template, IDictionary<string, string> additionalArguments = null, [CallerMemberName] string baseName = null)
{
List<Task<IWebApp>> deployments;
void DeployBatch()
{
var maxId = _predeploymentId + 5;
for (; _predeploymentId < maxId; _predeploymentId++)
{
deployments.Add(DeployImpl(template, additionalArguments, "PreDeploy" + _predeploymentId));
}
}
var deploymentKeyParts = new List<string>();
deploymentKeyParts.Add(template);
if (additionalArguments != null)
{
deploymentKeyParts.AddRange(additionalArguments.Select(a => a.Key + "=" + a.Value));
}
var deploymentKey = string.Join(Environment.NewLine, deploymentKeyParts);
Task<IWebApp> deployment;
if (!_deploymentCache.TryGetValue(deploymentKey, out deployments))
{
deployments = new List<Task<IWebApp>>();
DeployBatch();
_deploymentCache[deploymentKey] = deployments;
}
deployment = await Task.WhenAny(deployments);
deployments.Remove(deployment);
if (deployments.Count == 2)
{
DeployBatch();
}
return await deployment;
}
private async Task<IWebApp> DeployImpl(string template, IDictionary<string, string> additionalArguments = null, [CallerMemberName] string baseName = null)
{
var siteName = GetTimestampedName(baseName);
var parameters = new Dictionary<string, string>

View File

@ -6,7 +6,7 @@
</PropertyGroup>
<ItemGroup>
<None Include="Templates\*.*" CopyToOutputDirectory="PreserveNewest" />
<None Include="Assets\*.*" CopyToOutputDirectory="PreserveNewest" />
<ContentWithTargetPath Include="NuGet.config.template" CopyToOutputDirectory="PreserveNewest" TargetPath="NuGet.config" />
<ContentWithTargetPath Include="global.json.template" CopyToOutputDirectory="PreserveNewest" TargetPath="global.json" />
<ContentWithTargetPath Include="Directory.Build.props.template" CopyToOutputDirectory="PreserveNewest" TargetPath="Directory.Build.props" />

View File

@ -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();
}
}
}

View File

@ -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<string, string>
{
{ "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<RuntimeInfo>(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<string>(File.ReadAllLines(Asset($"DotNetCache.{expectedRuntime}.txt")), StringComparer.InvariantCultureIgnoreCase);
var runtimeModules = PathUtilities.GetLatestSharedRuntimeAssemblies(dotnetPath, out _);
var modulesNotInCache = new List<string>();
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<RuntimeInfo>(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<string, string> GetSiteExtensionArguments()
{
return new Dictionary<string, string>
{
{ "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<AssemblyInformationalVersionAttribute>();
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;
}
}
}

View File

@ -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
}
}

View File

@ -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(