Enable x86 testing #949
This commit is contained in:
parent
5906740cdb
commit
09d3b32fe5
|
|
@ -65,11 +65,6 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting
|
|||
throw new DirectoryNotFoundException(string.Format("Application path {0} does not exist.", applicationPath));
|
||||
}
|
||||
|
||||
if (runtimeArchitecture == RuntimeArchitecture.x86 && runtimeFlavor == RuntimeFlavor.CoreClr)
|
||||
{
|
||||
throw new NotSupportedException("32 bit deployment is not yet supported for CoreCLR. Don't remove the tests, just disable them for now.");
|
||||
}
|
||||
|
||||
ApplicationPath = applicationPath;
|
||||
ApplicationName = new DirectoryInfo(ApplicationPath).Name;
|
||||
ServerType = serverType;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,71 @@
|
|||
// 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.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IntegrationTesting.Common
|
||||
{
|
||||
internal static class DotNetCommands
|
||||
{
|
||||
private const string _dotnetFolderName = ".dotnet";
|
||||
|
||||
internal static string DotNetHome { get; } = GetDotNetHome();
|
||||
|
||||
// Compare to https://github.com/aspnet/BuildTools/blob/314c98e4533217a841ff9767bb38e144eb6c93e4/tools/KoreBuild.Console/Commands/CommandContext.cs#L76
|
||||
private static string GetDotNetHome()
|
||||
{
|
||||
var dotnetHome = Environment.GetEnvironmentVariable("DOTNET_HOME");
|
||||
var userProfile = Environment.GetEnvironmentVariable("USERPROFILE");
|
||||
var home = Environment.GetEnvironmentVariable("HOME");
|
||||
|
||||
var result = Path.Combine(Directory.GetCurrentDirectory(), _dotnetFolderName);
|
||||
if (!string.IsNullOrEmpty(dotnetHome))
|
||||
{
|
||||
result = dotnetHome;
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(userProfile))
|
||||
{
|
||||
result = Path.Combine(userProfile, _dotnetFolderName);
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(home))
|
||||
{
|
||||
result = home;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static string GetDotNetInstallDir(RuntimeArchitecture arch)
|
||||
{
|
||||
var dotnetDir = DotNetHome;
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
dotnetDir = Path.Combine(dotnetDir, arch.ToString());
|
||||
}
|
||||
|
||||
return dotnetDir;
|
||||
}
|
||||
|
||||
internal static string GetDotNetExecutable(RuntimeArchitecture arch)
|
||||
{
|
||||
var dotnetDir = GetDotNetInstallDir(arch);
|
||||
|
||||
var dotnetFile = "dotnet";
|
||||
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
dotnetFile += ".exe";
|
||||
}
|
||||
|
||||
return Path.Combine(dotnetDir, dotnetFile);
|
||||
}
|
||||
|
||||
internal static bool IsRunningX86OnX64(RuntimeArchitecture arch)
|
||||
{
|
||||
return (RuntimeInformation.OSArchitecture == Architecture.X64 || RuntimeInformation.OSArchitecture == Architecture.Arm64)
|
||||
&& arch == RuntimeArchitecture.x86;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -47,11 +47,6 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting
|
|||
DeploymentParameters.RuntimeFlavor = GetRuntimeFlavor(DeploymentParameters.TargetFramework);
|
||||
}
|
||||
|
||||
if (DeploymentParameters.RuntimeArchitecture == RuntimeArchitecture.x86 && DeploymentParameters.RuntimeFlavor == RuntimeFlavor.CoreClr)
|
||||
{
|
||||
throw new NotSupportedException("32 bit deployment is not yet supported for CoreCLR. Don't remove the tests, just disable them for now.");
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(DeploymentParameters.ApplicationPath))
|
||||
{
|
||||
throw new ArgumentException("ApplicationPath cannot be null.");
|
||||
|
|
|
|||
|
|
@ -35,14 +35,6 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting
|
|||
{
|
||||
}
|
||||
|
||||
public bool Is64BitHost
|
||||
{
|
||||
get
|
||||
{
|
||||
return Environment.Is64BitOperatingSystem;
|
||||
}
|
||||
}
|
||||
|
||||
public override async Task<DeploymentResult> DeployAsync()
|
||||
{
|
||||
using (Logger.BeginScope("Deployment"))
|
||||
|
|
@ -128,6 +120,7 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting
|
|||
}
|
||||
|
||||
ModifyHandlerSectionInWebConfig(key: "modules", value: DeploymentParameters.AncmVersion.ToString());
|
||||
ModifyDotNetExePathInWebConfig();
|
||||
|
||||
var parameters = string.IsNullOrWhiteSpace(DeploymentParameters.ServerConfigLocation) ?
|
||||
string.Format("/port:{0} /path:\"{1}\" /trace:error", uri.Port, contentRoot) :
|
||||
|
|
@ -228,7 +221,8 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting
|
|||
{
|
||||
if (serverConfig.Contains(replaceFlag))
|
||||
{
|
||||
var ancmFile = Path.Combine(contentRoot, Is64BitHost ? $@"x64\{dllName}" : $@"x86\{dllName}");
|
||||
var arch = DeploymentParameters.RuntimeArchitecture == RuntimeArchitecture.x64 ? $@"x64\{dllName}" : $@"x86\{dllName}";
|
||||
var ancmFile = Path.Combine(contentRoot, arch);
|
||||
if (!File.Exists(Environment.ExpandEnvironmentVariables(ancmFile)))
|
||||
{
|
||||
ancmFile = Path.Combine(contentRoot, dllName);
|
||||
|
|
@ -246,8 +240,14 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting
|
|||
|
||||
private string GetIISExpressPath()
|
||||
{
|
||||
var programFiles = "Program Files";
|
||||
if (DotNetCommands.IsRunningX86OnX64(DeploymentParameters.RuntimeArchitecture))
|
||||
{
|
||||
programFiles = "Program Files (x86)";
|
||||
}
|
||||
|
||||
// Get path to program files
|
||||
var iisExpressPath = Path.Combine(Environment.GetEnvironmentVariable("SystemDrive") + "\\", "Program Files", "IIS Express", "iisexpress.exe");
|
||||
var iisExpressPath = Path.Combine(Environment.GetEnvironmentVariable("SystemDrive") + "\\", programFiles, "IIS Express", "iisexpress.exe");
|
||||
|
||||
if (!File.Exists(iisExpressPath))
|
||||
{
|
||||
|
|
@ -297,8 +297,24 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting
|
|||
}
|
||||
}
|
||||
|
||||
// Transforms the web.config file to include the hostingModel="inprocess" element
|
||||
// and adds the server type = Microsoft.AspNetServer.IIS such that Kestrel isn't added again in ServerTests
|
||||
private void ModifyDotNetExePathInWebConfig()
|
||||
{
|
||||
// We assume the x64 dotnet.exe is on the path so we need to provide an absolute path for x86 scenarios.
|
||||
// Only do it for scenarios that rely on dotnet.exe (Core, portable, etc.).
|
||||
if (DeploymentParameters.RuntimeFlavor == RuntimeFlavor.CoreClr
|
||||
&& DeploymentParameters.ApplicationType == ApplicationType.Portable
|
||||
&& DotNetCommands.IsRunningX86OnX64(DeploymentParameters.RuntimeArchitecture))
|
||||
{
|
||||
var executableName = DotNetCommands.GetDotNetExecutable(DeploymentParameters.RuntimeArchitecture);
|
||||
if (!File.Exists(executableName))
|
||||
{
|
||||
throw new Exception($"Unable to find '{executableName}'.'");
|
||||
}
|
||||
ModifyAspNetCoreSectionInWebConfig("processPath", executableName);
|
||||
}
|
||||
}
|
||||
|
||||
// Transforms the web.config file to set attributes like hostingModel="inprocess" element
|
||||
private void ModifyAspNetCoreSectionInWebConfig(string key, string value)
|
||||
{
|
||||
var webConfigFile = $"{DeploymentParameters.PublishedApplicationRootPath}/web.config";
|
||||
|
|
|
|||
|
|
@ -35,6 +35,13 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting
|
|||
|
||||
var redirectUri = TestUriHelper.BuildTestUri(ServerType.Nginx);
|
||||
|
||||
if (DeploymentParameters.RuntimeFlavor == RuntimeFlavor.CoreClr
|
||||
&& DeploymentParameters.ApplicationType == ApplicationType.Standalone)
|
||||
{
|
||||
// Publish is required to get the correct files in the output directory
|
||||
DeploymentParameters.PublishApplicationBeforeDeployment = true;
|
||||
}
|
||||
|
||||
if (DeploymentParameters.PublishApplicationBeforeDeployment)
|
||||
{
|
||||
DotnetPublish();
|
||||
|
|
|
|||
|
|
@ -36,6 +36,20 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting
|
|||
// Start timer
|
||||
StartTimer();
|
||||
|
||||
if (DeploymentParameters.RuntimeFlavor == RuntimeFlavor.Clr
|
||||
&& DeploymentParameters.RuntimeArchitecture == RuntimeArchitecture.x86)
|
||||
{
|
||||
// Publish is required to rebuild for the right bitness
|
||||
DeploymentParameters.PublishApplicationBeforeDeployment = true;
|
||||
}
|
||||
|
||||
if (DeploymentParameters.RuntimeFlavor == RuntimeFlavor.CoreClr
|
||||
&& DeploymentParameters.ApplicationType == ApplicationType.Standalone)
|
||||
{
|
||||
// Publish is required to get the correct files in the output directory
|
||||
DeploymentParameters.PublishApplicationBeforeDeployment = true;
|
||||
}
|
||||
|
||||
if (DeploymentParameters.PublishApplicationBeforeDeployment)
|
||||
{
|
||||
DotnetPublish();
|
||||
|
|
@ -65,37 +79,42 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting
|
|||
{
|
||||
using (Logger.BeginScope("StartSelfHost"))
|
||||
{
|
||||
string executableName;
|
||||
string executableArgs = string.Empty;
|
||||
string workingDirectory = string.Empty;
|
||||
var executableName = string.Empty;
|
||||
var executableArgs = string.Empty;
|
||||
var workingDirectory = string.Empty;
|
||||
var executableExtension = DeploymentParameters.ApplicationType == ApplicationType.Portable ? ".dll"
|
||||
: (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ".exe" : "");
|
||||
|
||||
if (DeploymentParameters.PublishApplicationBeforeDeployment)
|
||||
{
|
||||
workingDirectory = DeploymentParameters.PublishedApplicationRootPath;
|
||||
var executableExtension =
|
||||
DeploymentParameters.RuntimeFlavor == RuntimeFlavor.Clr ? ".exe" :
|
||||
DeploymentParameters.ApplicationType == ApplicationType.Portable ? ".dll" : "";
|
||||
var executable = Path.Combine(DeploymentParameters.PublishedApplicationRootPath, DeploymentParameters.ApplicationName + executableExtension);
|
||||
|
||||
if (DeploymentParameters.RuntimeFlavor == RuntimeFlavor.CoreClr && DeploymentParameters.ApplicationType == ApplicationType.Portable)
|
||||
{
|
||||
executableName = "dotnet";
|
||||
executableArgs = executable;
|
||||
}
|
||||
else
|
||||
{
|
||||
executableName = executable;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
workingDirectory = DeploymentParameters.ApplicationPath;
|
||||
var targetFramework = DeploymentParameters.TargetFramework ?? (DeploymentParameters.RuntimeFlavor == RuntimeFlavor.Clr ? Tfm.Net461 : Tfm.NetCoreApp22);
|
||||
executableName = DotnetCommandName;
|
||||
executableArgs = $"run --no-build -c {DeploymentParameters.Configuration} --framework {targetFramework} {DotnetArgumentSeparator}";
|
||||
// Core+Standalone always publishes. This must be Clr+Standalone or Core+Portable.
|
||||
// Run from the pre-built bin/{config}/{tfm} directory.
|
||||
var targetFramework = DeploymentParameters.TargetFramework
|
||||
?? (DeploymentParameters.RuntimeFlavor == RuntimeFlavor.Clr ? Tfm.Net461 : Tfm.NetCoreApp22);
|
||||
workingDirectory = Path.Combine(DeploymentParameters.ApplicationPath, "bin", DeploymentParameters.Configuration, targetFramework);
|
||||
// CurrentDirectory will point to bin/{config}/{tfm}, but the config and static files aren't copied, point to the app base instead.
|
||||
DeploymentParameters.EnvironmentVariables["ASPNETCORE_CONTENTROOT"] = DeploymentParameters.ApplicationPath;
|
||||
}
|
||||
|
||||
executableArgs += $" --urls {hintUrl} "
|
||||
+ $" --server {(DeploymentParameters.ServerType == ServerType.HttpSys ? "Microsoft.AspNetCore.Server.HttpSys" : "Microsoft.AspNetCore.Server.Kestrel")}";
|
||||
var executable = Path.Combine(workingDirectory, DeploymentParameters.ApplicationName + executableExtension);
|
||||
|
||||
if (DeploymentParameters.RuntimeFlavor == RuntimeFlavor.CoreClr && DeploymentParameters.ApplicationType == ApplicationType.Portable)
|
||||
{
|
||||
executableName = GetDotNetExeForArchitecture();
|
||||
executableArgs = executable;
|
||||
}
|
||||
else
|
||||
{
|
||||
executableName = executable;
|
||||
}
|
||||
|
||||
var server = DeploymentParameters.ServerType == ServerType.HttpSys
|
||||
? "Microsoft.AspNetCore.Server.HttpSys" : "Microsoft.AspNetCore.Server.Kestrel";
|
||||
executableArgs += $" --urls {hintUrl} --server {server}";
|
||||
|
||||
Logger.LogInformation($"Executing {executableName} {executableArgs}");
|
||||
|
||||
|
|
@ -175,6 +194,22 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting
|
|||
}
|
||||
}
|
||||
|
||||
private string GetDotNetExeForArchitecture()
|
||||
{
|
||||
var executableName = DotnetCommandName;
|
||||
// We expect x64 dotnet.exe to be on the path but we have to go searching for the x86 version.
|
||||
if (DotNetCommands.IsRunningX86OnX64(DeploymentParameters.RuntimeArchitecture))
|
||||
{
|
||||
executableName = DotNetCommands.GetDotNetExecutable(DeploymentParameters.RuntimeArchitecture);
|
||||
if (!File.Exists(executableName))
|
||||
{
|
||||
throw new Exception($"Unable to find '{executableName}'.'");
|
||||
}
|
||||
}
|
||||
|
||||
return executableName;
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
using (Logger.BeginScope("SelfHost.Dispose"))
|
||||
|
|
|
|||
|
|
@ -246,9 +246,15 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting
|
|||
{
|
||||
foreach (var arch in Architectures)
|
||||
{
|
||||
if (!IsArchitectureSupportedOnServer(arch, server))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
var archSkip = skip ?? SkipIfArchitectureNotSupportedOnCurrentSystem(arch);
|
||||
|
||||
if (server == ServerType.IISExpress)
|
||||
{
|
||||
VaryByAncmVersion(variants, server, tfm, type, arch, skip);
|
||||
VaryByAncmVersion(variants, server, tfm, type, arch, archSkip);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -258,12 +264,31 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting
|
|||
Tfm = tfm,
|
||||
ApplicationType = type,
|
||||
Architecture = arch,
|
||||
Skip = skip,
|
||||
Skip = archSkip,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private string SkipIfArchitectureNotSupportedOnCurrentSystem(RuntimeArchitecture arch)
|
||||
{
|
||||
if (arch == RuntimeArchitecture.x64)
|
||||
{
|
||||
// Can't run x64 on a x86 OS.
|
||||
return (RuntimeInformation.OSArchitecture == Architecture.Arm || RuntimeInformation.OSArchitecture == Architecture.X86)
|
||||
? $"Cannot run {arch} on your current system." : null;
|
||||
}
|
||||
|
||||
// No x86 runtimes available on MacOS or Linux.
|
||||
return RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? null : $"No {arch} available for non-Windows systems.";
|
||||
}
|
||||
|
||||
private bool IsArchitectureSupportedOnServer(RuntimeArchitecture arch, ServerType server)
|
||||
{
|
||||
// No x86 Mac/Linux runtime, don't generate a test variation that will always be skipped.
|
||||
return !(arch == RuntimeArchitecture.x86 && ServerType.Nginx == server);
|
||||
}
|
||||
|
||||
private void VaryByAncmVersion(IList<TestVariant> variants, ServerType server, string tfm, ApplicationType type, RuntimeArchitecture arch, string skip)
|
||||
{
|
||||
foreach (var version in AncmVersions)
|
||||
|
|
|
|||
|
|
@ -21,7 +21,13 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting
|
|||
public override string ToString()
|
||||
{
|
||||
// For debug and test explorer view
|
||||
return $"Server: {Server}, TFM: {Tfm}, Type: {ApplicationType}, Host: {HostingModel}, ANCM: {AncmVersion}, Arch: {Architecture}";
|
||||
var description = $"Server: {Server}, TFM: {Tfm}, Type: {ApplicationType}, Arch: {Architecture}";
|
||||
if (Server == ServerType.IISExpress)
|
||||
{
|
||||
var version = AncmVersion == AncmVersion.AspNetCoreModule ? "V1" : "V2";
|
||||
description += $", ANCM: {version}, Host: {HostingModel}";
|
||||
}
|
||||
return description;
|
||||
}
|
||||
|
||||
public void Serialize(IXunitSerializationInfo info)
|
||||
|
|
|
|||
|
|
@ -2,32 +2,21 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IntegrationTesting
|
||||
{
|
||||
/// <summary>
|
||||
/// Skips a 64 bit test if the current Windows OS is 32-bit.
|
||||
/// Skips a 64 bit test if the current OS is 32-bit.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
|
||||
public class SkipOn32BitOSAttribute : Attribute, ITestCondition
|
||||
{
|
||||
public bool IsMet
|
||||
{
|
||||
get
|
||||
{
|
||||
// Directory found only on 64-bit OS.
|
||||
return Directory.Exists(Path.Combine(Environment.GetEnvironmentVariable("SystemRoot"), "SysWOW64"));
|
||||
}
|
||||
}
|
||||
public bool IsMet =>
|
||||
RuntimeInformation.OSArchitecture == Architecture.Arm64
|
||||
|| RuntimeInformation.OSArchitecture == Architecture.X64;
|
||||
|
||||
public string SkipReason
|
||||
{
|
||||
get
|
||||
{
|
||||
return "Skipping the x64 test since Windows is 32-bit";
|
||||
}
|
||||
}
|
||||
public string SkipReason => "Skipping the x64 test since Windows is 32-bit";
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue