Updated to support IISExpress and add new test cases for the additional environment variables (#93)

This commit is contained in:
jhkimnew 2017-04-24 18:17:33 -07:00 коммит произвёл GitHub
Родитель 5854e03ddc
Коммит 2c5132251b
19 изменённых файлов: 1151 добавлений и 425 удалений

Просмотреть файл

@ -12,12 +12,18 @@
<VersionSuffix Condition="'$(VersionSuffix)'!='' AND '$(BuildNumber)' != ''">$(VersionSuffix)-$(BuildNumber)</VersionSuffix>
</PropertyGroup>
<PropertyGroup>
<VSTestCLIRunSettings>RunConfiguration.TargetPlatform=x64</VSTestCLIRunSettings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Internal.AspNetCore.Sdk" Version="$(InternalAspNetCoreSdkVersion)" PrivateAssets="All" />
</ItemGroup>
<!--
<ItemGroup Condition="'$(TargetFrameworkIdentifier)'=='.NETFramework' AND '$(OutputType)'=='library'">
<PackageReference Include="NETStandard.Library" Version="$(NetStandardImplicitPackageVersion)" />
</ItemGroup>
</ItemGroup>
-->
</Project>

Просмотреть файл

@ -3,4 +3,8 @@
<ExcludeFromTest Include="$(RepositoryRoot)test\AspNetCoreModule.TestSites.Standard\*.csproj" />
<ExcludeFromTest Include="$(RepositoryRoot)test\AspNetCoreModule.Test\*.csproj" Condition="'$(OS)' != 'Windows_NT'" />
</ItemGroup>
<PropertyGroup>
<VSTestCLIRunSettings>RunConfiguration.TargetPlatform=x64</VSTestCLIRunSettings>
</PropertyGroup>
</Project>

59
Build/repo.targets Normal file
Просмотреть файл

@ -0,0 +1,59 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<MicrosoftCommonTargetsImported>true</MicrosoftCommonTargetsImported>
<VerifyDependsOn>$(VerifyDependsOn);PublishPackage</VerifyDependsOn>
<PublishFeed>https://dotnet.myget.org/F/aspnetcoremodule/api/v2/package</PublishFeed>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="PackagePublisher" Version="1.0.1-*" />
</ItemGroup>
<Target Name="_LocateMSBuildExe">
<ItemGroup>
<MSBuild15ExePaths Include="$(MSBuildProgramFiles32)\Microsoft Visual Studio\**\MSBuild\15.0\Bin\MSBuild.exe" />
</ItemGroup>
<Error
Text="Unable to locate MSBuild 15.0 under $(MSBuildProgramFiles32)\Microsoft Visual Studio"
Condition="'@(MSBuild15ExePaths)'==''"/>
<PropertyGroup Condition="'@(MSBuild15ExePaths)'!=''">
<MSBuildExePath>%(MSBuild15ExePaths.FullPath)</MSBuildExePath>
</PropertyGroup>
</Target>
<Target Name="BuildNativeAssets" DependsOnTargets="_LocateMSBuildExe" BeforeTargets="Compile">
<ItemGroup>
<BuildConfigurations Include="/p:Configuration=Release /p:platform=Win32" />
<BuildConfigurations Include="/p:Configuration=Release /p:platform=x64" />
</ItemGroup>
<Exec Command="&quot;$(MSBuildExePath)&quot; &quot;$(RepositoryRoot)src\AspNetCore\AspNetCore.vcxproj&quot; %(BuildConfigurations.Identity)" />
</Target>
<Target Name="PackageProjects">
<PropertyGroup>
<NuGetExePath>$(RepositoryRoot).build\nuget.exe</NuGetExePath>
<NuspecPath>$(RepositoryRoot)nuget\AspNetCore.nuspec</NuspecPath>
</PropertyGroup>
<Exec Command="&quot;$(NuGetExePath)&quot; pack &quot;$(NuspecPath)&quot; -OutputDirectory &quot;$(ArtifactsDir) &quot; -prop Version=1.0.0-$(BuildNumber)" />
</Target>
<Target Name="_ResolvePackagePublisherPath" DependsOnTargets="RunResolvePackageDependencies">
<ItemGroup>
<PackagePublisherPath Include="%(PackageDefinitions.ResolvedPath)" Condition="'%(PackageDefinitions.Name)'=='PackagePublisher'" />
</ItemGroup>
<PropertyGroup>
<_PackagePublisherPath>@(PackagePublisherPath)\PackagePublisher.exe</_PackagePublisherPath>
</PropertyGroup>
</Target>
<Target Name="PublishPackage"
DependsOnTargets="_ResolvePackagePublisherPath"
Condition="'$(PublishPackage)'=='true'">
<Exec Command="&quot;$(PackagePublisherPath)&quot; -d &quot;$(ArtifactsDir) &quot; -f $(PublishFeed)" />
</Target>
</Project>

Просмотреть файл

@ -1,20 +0,0 @@
default BASE_DIR_LOCAL='${Directory.GetCurrentDirectory()}'
default BUILD_DIR_LOCAL='${Path.Combine(BASE_DIR_LOCAL, "artifacts", "build")}'
var VERSION='0.1'
var FULL_VERSION='0.1'
use-standard-lifecycle
k-standard-goals
#make-nupkg target='package'
log info='Make nuget package containing ASP.NET Core Module'
@{
var nugetExePath = Environment.GetEnvironmentVariable("KOREBUILD_NUGET_EXE");
if (string.IsNullOrEmpty(nugetExePath))
{
nugetExePath = Path.Combine(BASE_DIR_LOCAL, ".build", "nuget.exe");
}
var nuspecPath = Path.Combine(BASE_DIR_LOCAL, "nuget", "AspNetCore.nuspec");
ExecClr(nugetExePath, "pack " + nuspecPath + " -OutputDirectory " + BUILD_DIR_LOCAL + " -prop VERSION=1.0.0-" + BuildNumber);
}

Просмотреть файл

@ -71,6 +71,9 @@
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)'=='Release'">
<OutDir>$(SolutionDir)artifacts\build\$(ProjectName)\bin\$(Configuration)\$(Platform)</OutDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>

Просмотреть файл

@ -1,41 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
using System;
using Microsoft.AspNetCore.Testing.xunit;
namespace AspNetCoreModule.Test.Framework
{
/// <summary>
/// Skip test if a given environment variable is not enabled. To enable the test, set environment variable
/// to "true" for the test process.
/// </summary>
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class EnvironmentVariableTestConditionAttribute : Attribute, ITestCondition
{
private readonly string _environmentVariableName;
public EnvironmentVariableTestConditionAttribute(string environmentVariableName)
{
_environmentVariableName = environmentVariableName;
}
public bool IsMet
{
get
{
return string.Compare(Environment.GetEnvironmentVariable(_environmentVariableName), "true", ignoreCase: true) == 0;
}
}
public string SkipReason
{
get
{
return $"To run this test, set the environment variable {_environmentVariableName}=\"true\". {AdditionalInfo}";
}
}
public string AdditionalInfo { get; set; }
}
}

Просмотреть файл

@ -22,9 +22,10 @@ namespace AspNetCoreModule.Test.Framework
public static string DefaultAppPool = "DefaultAppPool";
}
public static string ApppHostTemporaryBackupFileExtention = null;
private ServerType _serverType = ServerType.IIS;
private string _iisExpressConfigPath = null;
public enum AppPoolBitness
{
enable32Bit,
@ -53,63 +54,167 @@ namespace AspNetCoreModule.Test.Framework
}
}
public IISConfigUtility(ServerType type, string iisExpressConfigPath = null)
public IISConfigUtility(ServerType type, string iisExpressConfigPath)
{
_serverType = type;
_iisExpressConfigPath = iisExpressConfigPath;
}
public static void BackupAppHostConfig()
public static bool BackupAppHostConfig(string fileExtenstion, bool overWriteMode)
{
bool result = true;
string fromfile = Strings.AppHostConfigPath;
string tofile = Strings.AppHostConfigPath + ".ancmtest.bak";
string tofile = Strings.AppHostConfigPath + fileExtenstion;
if (File.Exists(fromfile))
{
TestUtility.FileCopy(fromfile, tofile, overWrite: false);
try
{
TestUtility.FileCopy(fromfile, tofile, overWrite: overWriteMode);
}
catch
{
result = false;
}
}
return result;
}
public static void RestoreAppHostConfig(bool restoreFromMasterBackupFile = true)
{
string masterBackupFileExtension = ".ancmtest.mastebackup";
string masterBackupFilePath = Strings.AppHostConfigPath + masterBackupFileExtension;
string temporaryBackupFileExtenstion = null;
string temporaryBackupFilePath = null;
string tofile = Strings.AppHostConfigPath;
string backupFileExentsionForDebug = ".ancmtest.debug";
string backupFilePathForDebug = Strings.AppHostConfigPath + backupFileExentsionForDebug;
TestUtility.DeleteFile(backupFilePathForDebug);
// Create a master backup file
if (restoreFromMasterBackupFile)
{
// Create a master backup file if it does not exist
if (!File.Exists(masterBackupFilePath))
{
if (!File.Exists(tofile))
{
throw new ApplicationException("Can't find " + tofile);
}
BackupAppHostConfig(masterBackupFileExtension, overWriteMode: false);
}
if (!File.Exists(masterBackupFilePath))
{
throw new ApplicationException("Not found master backup file " + masterBackupFilePath);
}
}
// if applicationhost.config does not exist but master backup file is available, create a new applicationhost.config from the master backup file first
if (!File.Exists(tofile))
{
CopyAppHostConfig(masterBackupFilePath, tofile);
}
// Create a temporary backup file with the current applicationhost.config to rollback after test is completed.
if (ApppHostTemporaryBackupFileExtention == null)
{
// retry 10 times until it really creates the temporary backup file
for (int i = 0; i < 10; i++)
{
temporaryBackupFileExtenstion = "." + TestUtility.RandomString(5);
string tempFile = Strings.AppHostConfigPath + temporaryBackupFileExtenstion;
if (File.Exists(tempFile))
{
// file already exists, try with a different file name
continue;
}
bool backupSuccess = BackupAppHostConfig(temporaryBackupFileExtenstion, overWriteMode: false);
if (backupSuccess && File.Exists(tempFile))
{
if (File.Exists(tempFile))
{
ApppHostTemporaryBackupFileExtention = temporaryBackupFileExtenstion;
break;
}
}
}
if (ApppHostTemporaryBackupFileExtention == null)
{
throw new ApplicationException("Can't make a temporary backup file");
}
}
if (restoreFromMasterBackupFile)
{
// restoring applicationhost.config from the master backup file
CopyAppHostConfig(masterBackupFilePath, tofile);
}
else
{
// Create a temporary backup file to preserve the last state for debugging purpose before rolling back from the temporary backup file
try
{
BackupAppHostConfig(backupFileExentsionForDebug, overWriteMode: true);
}
catch
{
TestUtility.LogInformation("Failed to create a backup file for debugging");
}
// restoring applicationhost.config from the temporary backup file
temporaryBackupFilePath = Strings.AppHostConfigPath + ApppHostTemporaryBackupFileExtention;
CopyAppHostConfig(temporaryBackupFilePath, tofile);
// delete the temporary backup file because it is not used anymore
try
{
TestUtility.DeleteFile(temporaryBackupFilePath);
}
catch
{
TestUtility.LogInformation("Failed to cleanup temporary backup file : " + temporaryBackupFilePath);
}
}
}
public static void RestoreAppHostConfig()
private static void CopyAppHostConfig(string fromfile, string tofile)
{
string fromfile = Strings.AppHostConfigPath + ".ancmtest.bak";
string tofile = Strings.AppHostConfigPath;
if (!File.Exists(fromfile) && !File.Exists(tofile))
{
// IIS is not installed, don't do anything here
return;
}
// backup first if the backup file is not available
if (!File.Exists(fromfile))
{
BackupAppHostConfig();
throw new System.ApplicationException("Failed to backup " + tofile);
}
// try again after the ininial clean up
if (File.Exists(fromfile))
// try restoring applicationhost.config again after the ininial clean up for better reliability
try
{
try
{
TestUtility.FileCopy(fromfile, tofile, true, true);
}
catch
{
// ignore
}
TestUtility.FileCopy(fromfile, tofile, true, true);
}
catch
{
// ignore
}
// try again
if (!File.Exists(tofile) || File.ReadAllBytes(fromfile).Length != File.ReadAllBytes(tofile).Length)
{
// try again
TestUtility.ResetHelper(ResetHelperMode.KillWorkerProcess);
TestUtility.FileCopy(fromfile, tofile, true, true);
}
// try again
if (!File.Exists(tofile) || File.ReadAllBytes(fromfile).Length != File.ReadAllBytes(tofile).Length)
{
// try again
TestUtility.ResetHelper(ResetHelperMode.KillWorkerProcess);
TestUtility.FileCopy(fromfile, tofile, true, true);
}
if (File.ReadAllBytes(fromfile).Length != File.ReadAllBytes(tofile).Length)
{
throw new System.ApplicationException("Failed to restore applicationhost.config");
}
// verify restoration is done successfully
if (File.ReadAllBytes(fromfile).Length != File.ReadAllBytes(tofile).Length)
{
throw new System.ApplicationException("Failed to restore applicationhost.config from " + fromfile + " to " + tofile);
}
}
@ -243,7 +348,7 @@ namespace AspNetCoreModule.Test.Framework
}
}
public void EnableWindowsAuthentication(string siteName)
public void EnableIISAuthentication(string siteName, bool windows, bool basic, bool anonymous)
{
TestUtility.LogInformation("Enable Windows authentication : " + siteName);
using (ServerManager serverManager = GetServerManager())
@ -251,9 +356,11 @@ namespace AspNetCoreModule.Test.Framework
Configuration config = serverManager.GetApplicationHostConfiguration();
ConfigurationSection anonymousAuthenticationSection = config.GetSection("system.webServer/security/authentication/anonymousAuthentication", siteName);
anonymousAuthenticationSection["enabled"] = false;
anonymousAuthenticationSection["enabled"] = anonymous;
ConfigurationSection basicAuthenticationSection = config.GetSection("system.webServer/security/authentication/basicAuthentication", siteName);
basicAuthenticationSection["enabled"] = basic;
ConfigurationSection windowsAuthenticationSection = config.GetSection("system.webServer/security/authentication/windowsAuthentication", siteName);
windowsAuthenticationSection["enabled"] = true;
windowsAuthenticationSection["enabled"] = windows;
serverManager.CommitChanges();
}
@ -265,7 +372,7 @@ namespace AspNetCoreModule.Test.Framework
using (ServerManager serverManager = GetServerManager())
{
Configuration config = serverManager.GetApplicationHostConfiguration();
ConfigurationSection iisClientCertificateMappingAuthenticationSection = config.GetSection("system.webServer/security/authentication/iisClientCertificateMappingAuthentication", siteName);
// enable iisClientCertificateMappingAuthentication
@ -275,7 +382,10 @@ namespace AspNetCoreModule.Test.Framework
// add a new oneToOne mapping collection item
ConfigurationElement addElement = oneToOneMappingsCollection.CreateElement("add");
addElement["userName"] = userName;
addElement["password"] = password;
if (password != null)
{
addElement["password"] = password;
}
addElement["certificate"] = publicKey;
oneToOneMappingsCollection.Add(addElement);
@ -326,32 +436,39 @@ namespace AspNetCoreModule.Test.Framework
public void SetANCMConfig(string siteName, string appName, string attributeName, object attributeValue)
{
using (ServerManager serverManager = GetServerManager())
try
{
Configuration config = serverManager.GetWebConfiguration(siteName, appName);
ConfigurationSection aspNetCoreSection = config.GetSection("system.webServer/aspNetCore");
if (attributeName == "environmentVariable")
using (ServerManager serverManager = GetServerManager())
{
string name = ((string[])attributeValue)[0];
string value = ((string[])attributeValue)[1];
ConfigurationElementCollection environmentVariablesCollection = aspNetCoreSection.GetCollection("environmentVariables");
ConfigurationElement environmentVariableElement = environmentVariablesCollection.CreateElement("environmentVariable");
environmentVariableElement["name"] = name;
environmentVariableElement["value"] = value;
var element = FindElement(environmentVariablesCollection, "add", "name", value);
if (element != null)
Configuration config = serverManager.GetWebConfiguration(siteName, appName);
ConfigurationSection aspNetCoreSection = config.GetSection("system.webServer/aspNetCore");
if (attributeName == "environmentVariable")
{
throw new System.ApplicationException("duplicated collection item");
string name = ((string[])attributeValue)[0];
string value = ((string[])attributeValue)[1];
ConfigurationElementCollection environmentVariablesCollection = aspNetCoreSection.GetCollection("environmentVariables");
ConfigurationElement environmentVariableElement = environmentVariablesCollection.CreateElement("environmentVariable");
environmentVariableElement["name"] = name;
environmentVariableElement["value"] = value;
var element = FindElement(environmentVariablesCollection, "add", "name", value);
if (element != null)
{
throw new System.ApplicationException("duplicated collection item");
}
environmentVariablesCollection.Add(environmentVariableElement);
}
else
{
aspNetCoreSection[attributeName] = attributeValue;
}
environmentVariablesCollection.Add(environmentVariableElement);
}
else
{
aspNetCoreSection[attributeName] = attributeValue;
}
serverManager.CommitChanges();
}
serverManager.CommitChanges();
}
}
catch (Exception ex)
{
throw ex;
}
}
public void ConfigureCustomLogging(string siteName, string appName, int statusCode, int subStatusCode, string path)
@ -387,21 +504,29 @@ namespace AspNetCoreModule.Test.Framework
{
if (_isIISInstalled == null)
{
bool result = true;
if (!File.Exists(Path.Combine(Strings.IIS64BitPath, "iiscore.dll")))
_isIISInstalled = true;
if (_isIISInstalled == true && !File.Exists(Path.Combine(Strings.IIS64BitPath, "iiscore.dll")))
{
result = false;
_isIISInstalled = false;
}
if (!File.Exists(Path.Combine(Strings.IIS64BitPath, "config", "applicationhost.config")))
if (_isIISInstalled == true && !File.Exists(Path.Combine(Strings.IIS64BitPath, "config", "applicationhost.config")))
{
result = false;
_isIISInstalled = false;
}
_isIISInstalled = result;
}
return _isIISInstalled;
}
set
{
_isIISInstalled = value;
}
}
public static bool IsIISReady {
get;
set;
}
public bool IsAncmInstalled(ServerType servertype)
{
bool result = true;
@ -422,7 +547,7 @@ namespace AspNetCoreModule.Test.Framework
return result;
}
public string GetServiceStatus(string serviceName)
public static string GetServiceStatus(string serviceName)
{
ServiceController sc = new ServiceController(serviceName);
@ -959,26 +1084,8 @@ namespace AspNetCoreModule.Test.Framework
public string CreateSelfSignedCertificateWithMakeCert(string subjectName, string issuerName = null, string extendedKeyUsage = null)
{
string makecertExeFilePath = "makecert.exe";
var makecertExeFilePaths = new string[]
{
Path.Combine(Environment.ExpandEnvironmentVariables("%ProgramFiles(x86)%"), "Windows Kits", "8.1", "bin", "x64", "makecert.exe"),
Path.Combine(Environment.ExpandEnvironmentVariables("%ProgramFiles%"), "Windows Kits", "8.1", "bin", "x86", "makecert.exe"),
Path.Combine(Environment.ExpandEnvironmentVariables("%ProgramFiles(x86)%"), "Windows Kits", "8.0", "bin", "x64", "makecert.exe"),
Path.Combine(Environment.ExpandEnvironmentVariables("%ProgramFiles%"), "Windows Kits", "8.0", "bin", "x86", "makecert.exe"),
Path.Combine(Environment.ExpandEnvironmentVariables("%ProgramFiles(x86)%"), "Windows SKDs", "Windows", "v7.1A", "bin", "x64", "makecert.exe"),
Path.Combine(Environment.ExpandEnvironmentVariables("%ProgramFiles%"), "Windows SKDs", "Windows", "v7.1A", "bin", "makecert.exe")
};
string makecertExeFilePath = TestUtility.GetMakeCertPath();
foreach (string item in makecertExeFilePaths)
{
if (File.Exists(item))
{
makecertExeFilePath = item;
break;
}
}
string parameter;
string targetSSLStore = string.Empty;
if (issuerName == null)

Просмотреть файл

@ -11,14 +11,18 @@ namespace AspNetCoreModule.Test.Framework
public class InitializeTestMachine : IDisposable
{
//
// By default, we don't use the private AspNetCoreFile
// By default, we use the private AspNetCoreFile which were created from this solution
//
public static bool UsePrivateAspNetCoreFile = false;
public static bool UsePrivateAspNetCoreFile = true;
public static int SiteId = 40000;
public static string Aspnetcore_path = Path.Combine(Environment.ExpandEnvironmentVariables("%windir%"), "system32", "inetsrv", "aspnetcore_private.dll");
public const string PrivateFileName = "aspnetcore_private.dll";
public static string Aspnetcore_path = Path.Combine(Environment.ExpandEnvironmentVariables("%windir%"), "system32", "inetsrv", PrivateFileName);
public static string Aspnetcore_path_original = Path.Combine(Environment.ExpandEnvironmentVariables("%windir%"), "system32", "inetsrv", "aspnetcore.dll");
public static string Aspnetcore_X86_path = Path.Combine(Environment.ExpandEnvironmentVariables("%windir%"), "syswow64", "inetsrv", "aspnetcore_private.dll");
public static string Aspnetcore_X86_path = Path.Combine(Environment.ExpandEnvironmentVariables("%windir%"), "syswow64", "inetsrv", PrivateFileName);
public static string IISExpressAspnetcore_path = Path.Combine(Environment.ExpandEnvironmentVariables("%ProgramFiles%"), "IIS Express", PrivateFileName);
public static string IISExpressAspnetcore_X86_path = Path.Combine(Environment.ExpandEnvironmentVariables("%ProgramFiles(x86)%"), "IIS Express", PrivateFileName);
public static string IISExpressAspnetcoreSchema_path = Path.Combine(Environment.ExpandEnvironmentVariables("%ProgramFiles%"), "IIS Express", "config", "schema", "aspnetcore_schema.xml");
public static string IISAspnetcoreSchema_path = Path.Combine(Environment.ExpandEnvironmentVariables("%windir%"), "system32", "inetsrv", "config", "schema", "aspnetcore_schema.xml");
public static int _referenceCount = 0;
@ -27,11 +31,6 @@ namespace AspNetCoreModule.Test.Framework
public InitializeTestMachine()
{
if (Environment.Is64BitOperatingSystem && !Environment.Is64BitProcess)
{
TestUtility.LogInformation("Error!!! Skipping to run InitializeTestMachine::InitializeTestMachine() because the test process is started on syswow mode");
return;
}
_referenceCount++;
if (_referenceCount == 1)
@ -41,27 +40,87 @@ namespace AspNetCoreModule.Test.Framework
_InitializeTestMachineCompleted = false;
TestUtility.LogInformation("InitializeTestMachine::Start");
if (Environment.ExpandEnvironmentVariables("%ANCMDebug%").ToLower() == "true")
if (Environment.ExpandEnvironmentVariables("%ANCMTEST_DEBUG%").ToLower() == "true")
{
System.Diagnostics.Debugger.Launch();
}
TestUtility.ResetHelper(ResetHelperMode.KillIISExpress);
TestUtility.ResetHelper(ResetHelperMode.KillWorkerProcess);
// cleanup before starting
string siteRootPath = Path.Combine(Environment.ExpandEnvironmentVariables("%SystemDrive%") + @"\", "inetpub", "ANCMTest");
// check Makecert.exe exists
try
{
if (IISConfigUtility.IsIISInstalled == true)
{
IISConfigUtility.RestoreAppHostConfig();
}
string makecertExeFilePath = TestUtility.GetMakeCertPath();
TestUtility.RunCommand(makecertExeFilePath, null, true, true);
TestUtility.LogInformation("Verified makecert.exe is available : " + makecertExeFilePath);
}
catch
catch (Exception ex)
{
TestUtility.LogInformation("Failed to restore applicationhost.config");
throw new System.ApplicationException("makecert.exe is not available : " + ex.Message);
}
TestUtility.ResetHelper(ResetHelperMode.KillIISExpress);
// check if we can use IIS server instead of IISExpress
try
{
IISConfigUtility.IsIISReady = false;
if (IISConfigUtility.IsIISInstalled == true)
{
if (Environment.GetEnvironmentVariable("ANCMTEST_USE_IISEXPRESS") != null && Environment.GetEnvironmentVariable("ANCMTEST_USE_IISEXPRESS").Equals("true", StringComparison.InvariantCultureIgnoreCase))
{
throw new System.ApplicationException("'ANCMTestServerType' environment variable is set to 'true'");
}
// check websocket is installed
if (File.Exists(Path.Combine(IISConfigUtility.Strings.IIS64BitPath, "iiswsock.dll")))
{
TestUtility.LogInformation("Websocket is installed");
}
else
{
throw new System.ApplicationException("websocket module is not installed");
}
TestUtility.ResetHelper(ResetHelperMode.KillWorkerProcess);
// Reset applicationhost.config
TestUtility.LogInformation("Restoring applicationhost.config");
IISConfigUtility.RestoreAppHostConfig(restoreFromMasterBackupFile:true);
TestUtility.StartW3svc();
// check w3svc is running after resetting applicationhost.config
if (IISConfigUtility.GetServiceStatus("w3svc") == "Running")
{
TestUtility.LogInformation("W3SVC service is restarted after restoring applicationhost.config");
}
else
{
throw new System.ApplicationException("WWW service can't start");
}
// check URLRewrite module exists
if (File.Exists(Path.Combine(IISConfigUtility.Strings.IIS64BitPath, "rewrite.dll")))
{
TestUtility.LogInformation("Verified URL Rewrite module installed for IIS server");
}
else
{
throw new System.ApplicationException("URL Rewrite module is not installed");
}
if (IISConfigUtility.ApppHostTemporaryBackupFileExtention == null)
{
throw new System.ApplicationException("Failed to backup applicationhost.config");
}
IISConfigUtility.IsIISReady = true;
}
}
catch (Exception ex)
{
RollbackIISApplicationhostConfigFile();
TestUtility.LogInformation("We will use IISExpress instead of IIS: " + ex.Message);
}
string siteRootPath = Path.Combine(Environment.ExpandEnvironmentVariables("%SystemDrive%") + @"\", "inetpub", "ANCMTest");
if (!Directory.Exists(siteRootPath))
{
Directory.CreateDirectory(siteRootPath);
@ -97,18 +156,16 @@ namespace AspNetCoreModule.Test.Framework
PreparePrivateANCMFiles();
// update applicationhost.config for IIS server
if (IISConfigUtility.IsIISInstalled == true)
if (IISConfigUtility.IsIISReady)
{
using (var iisConfig = new IISConfigUtility(ServerType.IIS))
using (var iisConfig = new IISConfigUtility(ServerType.IIS, null))
{
iisConfig.AddModule("AspNetCoreModule", Aspnetcore_path, null);
}
}
}
_InitializeTestMachineCompleted = true;
_InitializeTestMachineCompleted = true;
TestUtility.LogInformation("InitializeTestMachine::InitializeTestMachine() End");
}
@ -122,7 +179,7 @@ namespace AspNetCoreModule.Test.Framework
{
TestUtility.LogInformation("InitializeTestMachine::InitializeTestMachine() Waiting...");
Thread.Sleep(500);
}
}
}
if (!_InitializeTestMachineCompleted)
{
@ -138,60 +195,68 @@ namespace AspNetCoreModule.Test.Framework
{
TestUtility.LogInformation("InitializeTestMachine::Dispose() Start");
TestUtility.ResetHelper(ResetHelperMode.KillIISExpress);
if (InitializeTestMachine.UsePrivateAspNetCoreFile)
{
if (IISConfigUtility.IsIISInstalled == true)
{
using (var iisConfig = new IISConfigUtility(ServerType.IIS))
{
try
{
iisConfig.AddModule("AspNetCoreModule", Aspnetcore_path_original, null);
}
catch
{
TestUtility.LogInformation("Failed to restore aspnetcore.dll path!!!");
}
}
}
}
RollbackIISApplicationhostConfigFile();
TestUtility.LogInformation("InitializeTestMachine::Dispose() End");
}
}
private void RollbackIISApplicationhostConfigFile()
{
if (IISConfigUtility.ApppHostTemporaryBackupFileExtention != null)
{
try
{
TestUtility.ResetHelper(ResetHelperMode.KillWorkerProcess);
}
catch
{
TestUtility.LogInformation("Failed to stop IIS worker processes");
}
try
{
IISConfigUtility.RestoreAppHostConfig(restoreFromMasterBackupFile: false);
}
catch
{
TestUtility.LogInformation("Failed to rollback applicationhost.config");
}
try
{
TestUtility.StartW3svc();
}
catch
{
TestUtility.LogInformation("Failed to start w3svc");
}
IISConfigUtility.ApppHostTemporaryBackupFileExtention = null;
}
}
private void PreparePrivateANCMFiles()
{
var solutionRoot = GetSolutionDirectory();
string outputPath = string.Empty;
_setupScriptPath = Path.Combine(solutionRoot, "tools");
// First try with debug build
outputPath = Path.Combine(solutionRoot, "artifacts", "build", "AspNetCore", "bin", "Debug");
// First try with release build
outputPath = Path.Combine(solutionRoot, "artifacts", "build", "AspNetCore", "bin", "Release");
// If debug build does is not available, try with release build
// If release build is not available, try with debug build
if (!File.Exists(Path.Combine(outputPath, "Win32", "aspnetcore.dll"))
|| !File.Exists(Path.Combine(outputPath, "x64", "aspnetcore.dll"))
|| !File.Exists(Path.Combine(outputPath, "x64", "aspnetcore_schema.xml")))
{
outputPath = Path.Combine(solutionRoot, "artifacts", "build", "AspNetCore", "bin", "Release");
}
if (!File.Exists(Path.Combine(outputPath, "Win32", "aspnetcore.dll"))
|| !File.Exists(Path.Combine(outputPath, "x64", "aspnetcore.dll"))
|| !File.Exists(Path.Combine(outputPath, "x64", "aspnetcore_schema.xml")))
{
outputPath = Path.Combine(solutionRoot, "src", "AspNetCore", "bin", "Debug");
}
if (!File.Exists(Path.Combine(outputPath, "Win32", "aspnetcore.dll"))
|| !File.Exists(Path.Combine(outputPath, "x64", "aspnetcore.dll"))
|| !File.Exists(Path.Combine(outputPath, "x64", "aspnetcore_schema.xml")))
{
throw new ApplicationException("aspnetcore.dll is not available; build aspnetcore.dll for both x86 and x64 and then try again!!!");
outputPath = Path.Combine(solutionRoot, "artifacts", "build", "AspNetCore", "bin", "Debug");
}
// create an extra private copy of the private file on IISExpress directory
if (!File.Exists(Path.Combine(outputPath, "Win32", "aspnetcore.dll"))
|| !File.Exists(Path.Combine(outputPath, "x64", "aspnetcore.dll"))
|| !File.Exists(Path.Combine(outputPath, "x64", "aspnetcore_schema.xml")))
{
throw new ApplicationException("aspnetcore.dll is not available; check if there is any build issue!!!");
}
// create an extra private copy of the private file on IIS directory
if (InitializeTestMachine.UsePrivateAspNetCoreFile)
{
bool updateSuccess = false;
@ -204,10 +269,15 @@ namespace AspNetCoreModule.Test.Framework
TestUtility.ResetHelper(ResetHelperMode.KillWorkerProcess);
TestUtility.ResetHelper(ResetHelperMode.StopW3svcStartW3svc);
Thread.Sleep(1000);
TestUtility.FileCopy(Path.Combine(outputPath, "x64", "aspnetcore.dll"), Aspnetcore_path);
string from = Path.Combine(outputPath, "x64", "aspnetcore.dll");
TestUtility.FileCopy(from, Aspnetcore_path, overWrite:true, ignoreExceptionWhileDeletingExistingFile:false);
TestUtility.FileCopy(from, IISExpressAspnetcore_path, overWrite: true, ignoreExceptionWhileDeletingExistingFile: false);
if (TestUtility.IsOSAmd64)
{
TestUtility.FileCopy(Path.Combine(outputPath, "Win32", "aspnetcore.dll"), Aspnetcore_X86_path);
from = Path.Combine(outputPath, "Win32", "aspnetcore.dll");
TestUtility.FileCopy(from, Aspnetcore_X86_path, overWrite: true, ignoreExceptionWhileDeletingExistingFile: false);
TestUtility.FileCopy(from, IISExpressAspnetcore_X86_path, overWrite: true, ignoreExceptionWhileDeletingExistingFile: false);
}
updateSuccess = true;
}

Просмотреть файл

@ -215,6 +215,7 @@ namespace AspNetCoreModule.Test.Framework
{
exceptionBlock?.Invoke(exception);
}
LogInformation("ANCMTEST::RetryHelper Retrying " + retry);
Thread.Sleep(retryDelayMilliseconds);
}
return false;
@ -248,21 +249,21 @@ namespace AspNetCoreModule.Test.Framework
{
if (format != null)
{
Logger.LogTrace(format);
Logger.LogTrace(format, parameters);
}
}
public static void LogError(string format, params object[] parameters)
{
if (format != null)
{
Logger.LogError(format);
Logger.LogError(format, parameters);
}
}
public static void LogInformation(string format, params object[] parameters)
{
if (format != null)
{
Logger.LogInformation(format);
Logger.LogInformation(format, parameters);
}
}
@ -433,6 +434,31 @@ namespace AspNetCoreModule.Test.Framework
}
}
public static string GetMakeCertPath()
{
string makecertExeFilePath = "makecert.exe";
var makecertExeFilePaths = new string[]
{
Path.Combine(Environment.ExpandEnvironmentVariables("%ProgramFiles(x86)%"), "Windows Kits", "8.1", "bin", "x64", "makecert.exe"),
Path.Combine(Environment.ExpandEnvironmentVariables("%ProgramFiles%"), "Windows Kits", "8.1", "bin", "x86", "makecert.exe"),
Path.Combine(Environment.ExpandEnvironmentVariables("%ProgramFiles(x86)%"), "Windows Kits", "8.0", "bin", "x64", "makecert.exe"),
Path.Combine(Environment.ExpandEnvironmentVariables("%ProgramFiles%"), "Windows Kits", "8.0", "bin", "x86", "makecert.exe"),
Path.Combine(Environment.ExpandEnvironmentVariables("%ProgramFiles(x86)%"), "Windows SKDs", "Windows", "v7.1A", "bin", "x64", "makecert.exe"),
Path.Combine(Environment.ExpandEnvironmentVariables("%ProgramFiles%"), "Windows SKDs", "Windows", "v7.1A", "bin", "makecert.exe")
};
foreach (string item in makecertExeFilePaths)
{
if (File.Exists(item))
{
makecertExeFilePath = item;
break;
}
}
return makecertExeFilePath;
}
public static int GetNumberOfProcess(string processFileName, int expectedNumber = 1, int retry = 0)
{
int result = 0;
@ -704,7 +730,16 @@ namespace AspNetCoreModule.Test.Framework
IPEndPoint a = new IPEndPoint(0, 443);
// create Powershell runspace
Runspace runspace = RunspaceFactory.CreateRunspace();
Runspace runspace = null;
try
{
runspace = RunspaceFactory.CreateRunspace();
}
catch
{
LogInformation("Failed to instantiate powershell Runspace; if this is Win7, install Powershell 4.0 to fix this problem");
throw new ApplicationException("Failed to instantiate powershell Runspace");
}
// open it
runspace.Open();
@ -759,7 +794,7 @@ namespace AspNetCoreModule.Test.Framework
p.StartInfo.UseShellExecute = false;
p.StartInfo.CreateNoWindow = true;
p.Start();
p.Start();
pid = p.Id;
string standardOutput = string.Empty;
string standardError = string.Empty;

Просмотреть файл

@ -175,7 +175,7 @@ namespace AspNetCoreModule.Test.Framework
// read web.config
string fileContent = TestUtility.FileReadAllText(filePath);
// get the value of processPath attribute of aspNetCore element
// get the value of arguments attribute of aspNetCore element
if (fileContent != null)
{
result = TestUtility.XmlParser(fileContent, "aspNetCore", "arguments", null);
@ -197,7 +197,7 @@ namespace AspNetCoreModule.Test.Framework
{
string fromfile = Path.Combine(_physicalPath, from + ".bak");
string tofile = Path.Combine(_physicalPath, from);
if (!File.Exists(tofile))
if (!File.Exists(fromfile))
{
BackupFile(from);
}

Просмотреть файл

@ -19,7 +19,7 @@ namespace AspNetCoreModule.Test.Framework
public TestUtility testHelper;
private ILogger _logger;
private int _iisExpressPidBackup = -1;
private string postfix = string.Empty;
public void Dispose()
@ -29,10 +29,17 @@ namespace AspNetCoreModule.Test.Framework
if (_iisExpressPidBackup != -1)
{
var iisExpressProcess = Process.GetProcessById(Convert.ToInt32(_iisExpressPidBackup));
iisExpressProcess.Kill();
iisExpressProcess.WaitForExit();
try
{
iisExpressProcess.Kill();
iisExpressProcess.WaitForExit();
iisExpressProcess.Close();
}
catch
{
TestUtility.RunPowershellScript("stop-process -id " + _iisExpressPidBackup);
}
}
TestUtility.LogInformation("TestWebSite::Dispose() End");
}
@ -91,14 +98,30 @@ namespace AspNetCoreModule.Test.Framework
_tcpPort = value;
}
}
public ServerType IisServerType { get; set; }
public string IisExpressConfigPath { get; set; }
private int _siteId { get; set; }
private IISConfigUtility.AppPoolBitness _appPoolBitness { get; set; }
public TestWebSite(IISConfigUtility.AppPoolBitness appPoolBitness, string loggerPrefix = "ANCMTest", ServerType serverType = ServerType.IIS)
public TestWebSite(IISConfigUtility.AppPoolBitness appPoolBitness, string loggerPrefix = "ANCMTest", bool startIISExpress = true, bool copyAllPublishedFiles = false)
{
_appPoolBitness = appPoolBitness;
//
// Default server type is IISExpress. we, however, should use IIS server instead if IIS server is ready to use.
//
IisServerType = ServerType.IISExpress;
if (IISConfigUtility.IsIISReady)
{
IisServerType = ServerType.IIS;
}
TestUtility.LogInformation("TestWebSite::TestWebSite() Start");
string solutionPath = InitializeTestMachine.GetSolutionDirectory();
if (serverType == ServerType.IIS)
if (IisServerType == ServerType.IIS)
{
// check JitDebugger before continuing
TestUtility.ResetHelper(ResetHelperMode.KillVSJitDebugger);
@ -134,11 +157,19 @@ namespace AspNetCoreModule.Test.Framework
string aspnetCoreAppRootPath = Path.Combine(siteRootPath, "AspNetCoreApp");
string srcPath = TestUtility.GetApplicationPath();
// copy http.config to the test site root directory and initialize iisExpressConfigPath with the path
if (IisServerType == ServerType.IISExpress)
{
IisExpressConfigPath = Path.Combine(siteRootPath, "http.config");
TestUtility.FileCopy(Path.Combine(solutionPath, "test", "AspNetCoreModule.Test", "http.config"), IisExpressConfigPath);
}
//
// Currently we use only DotnetCore v1.1
//
string publishPath = Path.Combine(srcPath, "bin", "Debug", "netcoreapp1.1", "publish");
string publishPathOutput = Path.Combine(Environment.ExpandEnvironmentVariables("%SystemDrive%") + @"\", "inetpub", "ANCMTest", "publishPathOutput");
//
// Publish aspnetcore app
//
@ -147,44 +178,51 @@ namespace AspNetCoreModule.Test.Framework
string argumentForDotNet = "publish " + srcPath;
TestUtility.LogInformation("TestWebSite::TestWebSite() StandardTestApp is not published, trying to publish on the fly: dotnet.exe " + argumentForDotNet);
TestUtility.RunCommand("dotnet", argumentForDotNet);
TestUtility.DirectoryCopy(publishPath, publishPathOutput);
TestUtility.FileCopy(Path.Combine(publishPathOutput, "web.config"), Path.Combine(publishPathOutput, "web.config.bak"));
// Adjust the arguments attribute value with IISConfigUtility from a temporary site
using (var iisConfig = new IISConfigUtility(IisServerType, IisExpressConfigPath))
{
string tempSiteName = "ANCMTest_Temp";
int tempId = InitializeTestMachine.SiteId - 1;
string argumentFileName = (new TestWebApplication("/", publishPathOutput, null)).GetArgumentFileName();
iisConfig.CreateSite(tempSiteName, publishPathOutput, tempId, tempId);
iisConfig.SetANCMConfig(tempSiteName, "/", "arguments", Path.Combine(publishPathOutput, argumentFileName));
iisConfig.DeleteSite(tempSiteName);
}
_publishedAspnetCoreApp = true;
}
// check published files
bool checkPublishedFiles = false;
string[] publishedFiles = Directory.GetFiles(publishPath);
foreach (var item in publishedFiles)
if (copyAllPublishedFiles)
{
if (Path.GetFileName(item) == "web.config")
{
checkPublishedFiles = true;
}
// Copy all the files in the pubishpath to the standardAppRootPath
TestUtility.DirectoryCopy(publishPath, aspnetCoreAppRootPath);
TestUtility.FileCopy(Path.Combine(publishPathOutput, "web.config.bak"), Path.Combine(aspnetCoreAppRootPath, "web.config"));
}
if (!checkPublishedFiles)
else
{
throw new System.ApplicationException("web.config is not available in " + publishPath);
// Copy only web.config file, which points to the shared publishPathOutput, to the standardAppRootPath
TestUtility.CreateDirectory(aspnetCoreAppRootPath);
TestUtility.FileCopy(Path.Combine(publishPathOutput, "web.config"), Path.Combine(aspnetCoreAppRootPath, "web.config"));
}
// Copy the pubishpath to standardAppRootPath
TestUtility.DirectoryCopy(publishPath, aspnetCoreAppRootPath);
int tcpPort = InitializeTestMachine.SiteId++;
int siteId = tcpPort;
_siteId = tcpPort;
//
// initialize class member variables
//
string appPoolName = null;
if (serverType == ServerType.IIS)
if (IisServerType == ServerType.IIS)
{
appPoolName = siteName;
}
else if (serverType == ServerType.IISExpress)
else if (IisServerType == ServerType.IISExpress)
{
appPoolName = "Clr4IntegratedAppPool";
}
// Initialize member variables
_hostName = "localhost";
_siteName = siteName;
@ -211,49 +249,99 @@ namespace AspNetCoreModule.Test.Framework
URLRewriteApp.RestoreFile("web.config");
URLRewriteApp.DeleteFile("app_offline.htm");
// copy http.config to the test site root directory and initialize iisExpressConfigPath with the path
string iisExpressConfigPath = null;
if (serverType == ServerType.IISExpress)
{
iisExpressConfigPath = Path.Combine(siteRootPath, "http.config");
TestUtility.FileCopy(Path.Combine(solutionPath, "test", "AspNetCoreModule.Test", "http.config"), iisExpressConfigPath);
}
//
// Create site and apps
//
using (var iisConfig = new IISConfigUtility(serverType, iisExpressConfigPath))
using (var iisConfig = new IISConfigUtility(IisServerType, IisExpressConfigPath))
{
if (serverType == ServerType.IIS)
// Create apppool
if (IisServerType == ServerType.IIS)
{
iisConfig.CreateAppPool(appPoolName);
bool is32bit = (appPoolBitness == IISConfigUtility.AppPoolBitness.enable32Bit);
iisConfig.SetAppPoolSetting(appPoolName, "enable32BitAppOnWin64", is32bit);
// Switch bitness
if (TestUtility.IsOSAmd64 && appPoolBitness == IISConfigUtility.AppPoolBitness.enable32Bit)
{
iisConfig.SetAppPoolSetting(appPoolName, "enable32BitAppOnWin64", true);
}
}
iisConfig.CreateSite(siteName, RootAppContext.PhysicalPath, siteId, this.TcpPort, appPoolName);
if (InitializeTestMachine.UsePrivateAspNetCoreFile && IisServerType == ServerType.IISExpress)
{
iisConfig.AddModule("AspNetCoreModule", ("%IIS_BIN%\\" + InitializeTestMachine.PrivateFileName), null);
}
iisConfig.CreateSite(siteName, RootAppContext.PhysicalPath, _siteId, TcpPort, appPoolName);
iisConfig.CreateApp(siteName, AspNetCoreApp.Name, AspNetCoreApp.PhysicalPath, appPoolName);
iisConfig.CreateApp(siteName, WebSocketApp.Name, WebSocketApp.PhysicalPath, appPoolName);
iisConfig.CreateApp(siteName, URLRewriteApp.Name, URLRewriteApp.PhysicalPath, appPoolName);
}
if (serverType == ServerType.IISExpress)
{
string cmdline;
string argument = "/siteid:" + siteId + " /config:" + iisExpressConfigPath;
if (Directory.Exists(Environment.ExpandEnvironmentVariables("%ProgramFiles(x86)%")) && appPoolBitness == IISConfigUtility.AppPoolBitness.enable32Bit)
{
cmdline = Path.Combine(Environment.ExpandEnvironmentVariables("%ProgramFiles(x86)%"), "IIS Express", "iisexpress.exe");
}
else
{
cmdline = Path.Combine(Environment.ExpandEnvironmentVariables("%ProgramFiles%"), "IIS Express", "iisexpress.exe");
}
TestUtility.LogInformation("TestWebSite::TestWebSite() Start IISExpress: " + cmdline + " " + argument);
_iisExpressPidBackup = TestUtility.RunCommand(cmdline, argument, false, false);
if (startIISExpress)
{
StartIISExpress();
}
TestUtility.LogInformation("TestWebSite::TestWebSite() End");
}
public void StartIISExpress(string verificationCommand = null)
{
if (IisServerType == ServerType.IIS)
{
return;
}
string cmdline;
string argument = "/siteid:" + _siteId + " /config:" + IisExpressConfigPath;
if (Directory.Exists(Environment.ExpandEnvironmentVariables("%ProgramFiles(x86)%")) && _appPoolBitness == IISConfigUtility.AppPoolBitness.enable32Bit)
{
cmdline = Path.Combine(Environment.ExpandEnvironmentVariables("%ProgramFiles(x86)%"), "IIS Express", "iisexpress.exe");
}
else
{
cmdline = Path.Combine(Environment.ExpandEnvironmentVariables("%ProgramFiles%"), "IIS Express", "iisexpress.exe");
}
TestUtility.LogInformation("TestWebSite::TestWebSite() Start IISExpress: " + cmdline + " " + argument);
_iisExpressPidBackup = TestUtility.RunCommand(cmdline, argument, false, false);
bool isIISExpressReady = false;
int timeout = 3;
for (int i = 0; i < timeout * 5; i++)
{
string statusCode = string.Empty;
try
{
if (verificationCommand == null)
{
verificationCommand = "( invoke-webrequest http://localhost:" + TcpPort + " ).StatusCode";
}
statusCode = TestUtility.RunPowershellScript(verificationCommand);
}
catch
{
statusCode = "ExceptionError";
}
if ("200" == statusCode)
{
isIISExpressReady = true;
break;
}
else
{
System.Threading.Thread.Sleep(200);
}
}
if (isIISExpressReady)
{
TestUtility.LogInformation("IISExpress is ready to use");
}
else
{
throw new ApplicationException("IISExpress is not responding within " + timeout + " seconds");
}
}
}
}

Просмотреть файл

@ -3,6 +3,7 @@
using AspNetCoreModule.Test.Framework;
using Microsoft.AspNetCore.Testing.xunit;
using System;
using System.Threading.Tasks;
using Xunit;
@ -10,30 +11,19 @@ namespace AspNetCoreModule.Test
{
public class FunctionalTest : FunctionalTestHelper, IClassFixture<InitializeTestMachine>
{
[EnvironmentVariableTestCondition("IIS_VARIATIONS_ENABLED")]
[ConditionalTheory]
[ANCMTestSkipCondition("RunAsAdministratorAndX64Bitness")]
[OSSkipCondition(OperatingSystems.Linux)]
[OSSkipCondition(OperatingSystems.MacOSX)]
[InlineData(ServerType.IISExpress, IISConfigUtility.AppPoolBitness.noChange)]
[InlineData(ServerType.IISExpress, IISConfigUtility.AppPoolBitness.enable32Bit)]
public Task BasicTestOnIISExpress(ServerType serverType, IISConfigUtility.AppPoolBitness appPoolBitness)
[InlineData(IISConfigUtility.AppPoolBitness.noChange)]
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit)]
public async void BasicTest(IISConfigUtility.AppPoolBitness appPoolBitness)
{
return DoBasicTest(serverType, appPoolBitness);
await DoBasicTest(appPoolBitness);
}
[EnvironmentVariableTestCondition("IIS_VARIATIONS_ENABLED")]
[ConditionalTheory]
[OSSkipCondition(OperatingSystems.Linux)]
[OSSkipCondition(OperatingSystems.MacOSX)]
[InlineData(ServerType.IIS, IISConfigUtility.AppPoolBitness.noChange)]
[InlineData(ServerType.IIS, IISConfigUtility.AppPoolBitness.enable32Bit)]
public Task BasicTestOnIIS(ServerType serverType, IISConfigUtility.AppPoolBitness appPoolBitness)
{
return DoBasicTest(serverType, appPoolBitness);
}
[EnvironmentVariableTestCondition("IIS_VARIATIONS_ENABLED")]
[ConditionalTheory]
[ANCMTestSkipCondition("RunAsAdministratorAndX64Bitness")]
[OSSkipCondition(OperatingSystems.Linux)]
[OSSkipCondition(OperatingSystems.MacOSX)]
[InlineData(IISConfigUtility.AppPoolBitness.noChange, 5)]
@ -44,9 +34,9 @@ namespace AspNetCoreModule.Test
{
return DoRapidFailsPerMinuteTest(appPoolBitness, valueOfRapidFailsPerMinute);
}
[EnvironmentVariableTestCondition("IIS_VARIATIONS_ENABLED")]
[ConditionalTheory]
[ANCMTestSkipCondition("RunAsAdministratorAndX64Bitness")]
[OSSkipCondition(OperatingSystems.Linux)]
[OSSkipCondition(OperatingSystems.MacOSX)]
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit, 25, 19)]
@ -59,9 +49,9 @@ namespace AspNetCoreModule.Test
{
return DoShutdownTimeLimitTest(appPoolBitness, valueOfshutdownTimeLimit, expectedClosingTime);
}
[EnvironmentVariableTestCondition("IIS_VARIATIONS_ENABLED")]
[ConditionalTheory]
[ANCMTestSkipCondition("RunAsAdministratorAndX64Bitness")]
[OSSkipCondition(OperatingSystems.Linux)]
[OSSkipCondition(OperatingSystems.MacOSX)]
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit, 10)]
@ -72,20 +62,9 @@ namespace AspNetCoreModule.Test
{
return DoStartupTimeLimitTest(appPoolBitness, starupTimeLimit);
}
[EnvironmentVariableTestCondition("IIS_VARIATIONS_ENABLED")]
[ConditionalTheory]
[OSSkipCondition(OperatingSystems.Linux)]
[OSSkipCondition(OperatingSystems.MacOSX)]
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit, "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789")]
[InlineData(IISConfigUtility.AppPoolBitness.noChange, "a")]
public Task WebSocketTest(IISConfigUtility.AppPoolBitness appPoolBitness, string testData)
{
return DoWebSocketTest(appPoolBitness, testData);
}
[EnvironmentVariableTestCondition("IIS_VARIATIONS_ENABLED")]
[ConditionalTheory]
[ANCMTestSkipCondition("RunAsAdministratorAndX64Bitness")]
[OSSkipCondition(OperatingSystems.Linux)]
[OSSkipCondition(OperatingSystems.MacOSX)]
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit)]
@ -94,9 +73,9 @@ namespace AspNetCoreModule.Test
{
return DoRecycleApplicationAfterBackendProcessBeingKilled(appPoolBitness);
}
[EnvironmentVariableTestCondition("IIS_VARIATIONS_ENABLED")]
[ConditionalTheory]
[ANCMTestSkipCondition("RunAsAdministratorAndX64Bitness")]
[OSSkipCondition(OperatingSystems.Linux)]
[OSSkipCondition(OperatingSystems.MacOSX)]
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit)]
@ -105,9 +84,9 @@ namespace AspNetCoreModule.Test
{
return DoRecycleApplicationAfterW3WPProcessBeingKilled(appPoolBitness);
}
[EnvironmentVariableTestCondition("IIS_VARIATIONS_ENABLED")]
[ConditionalTheory]
[ANCMTestSkipCondition("RunAsAdministratorAndX64Bitness")]
[OSSkipCondition(OperatingSystems.Linux)]
[OSSkipCondition(OperatingSystems.MacOSX)]
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit)]
@ -117,8 +96,8 @@ namespace AspNetCoreModule.Test
return DoRecycleApplicationAfterWebConfigUpdated(appPoolBitness);
}
[EnvironmentVariableTestCondition("IIS_VARIATIONS_ENABLED")]
[ConditionalTheory]
[ANCMTestSkipCondition("RunAsAdministratorAndX64Bitness")]
[OSSkipCondition(OperatingSystems.Linux)]
[OSSkipCondition(OperatingSystems.MacOSX)]
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit)]
@ -127,9 +106,9 @@ namespace AspNetCoreModule.Test
{
return DoRecycleApplicationWithURLRewrite(appPoolBitness);
}
[EnvironmentVariableTestCondition("IIS_VARIATIONS_ENABLED")]
[ConditionalTheory]
[ANCMTestSkipCondition("RunAsAdministratorAndX64Bitness")]
[OSSkipCondition(OperatingSystems.Linux)]
[OSSkipCondition(OperatingSystems.MacOSX)]
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit)]
@ -138,20 +117,26 @@ namespace AspNetCoreModule.Test
{
return DoRecycleParentApplicationWithURLRewrite(appPoolBitness);
}
[EnvironmentVariableTestCondition("IIS_VARIATIONS_ENABLED")]
[ConditionalTheory]
[ANCMTestSkipCondition("RunAsAdministratorAndX64Bitness")]
[OSSkipCondition(OperatingSystems.Linux)]
[OSSkipCondition(OperatingSystems.MacOSX)]
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit)]
[InlineData(IISConfigUtility.AppPoolBitness.noChange)]
public Task EnvironmentVariablesTest(IISConfigUtility.AppPoolBitness appPoolBitness)
[InlineData("ANCMTestBar", "bar", "bar", IISConfigUtility.AppPoolBitness.enable32Bit)]
[InlineData("ASPNETCORE_HOSTINGSTARTUPASSEMBLIES", "NA", "Microsoft.AspNetCore.Server.IISIntegration", IISConfigUtility.AppPoolBitness.noChange)]
[InlineData("ASPNETCORE_HOSTINGSTARTUPASSEMBLIES", "newValue", "newValue", IISConfigUtility.AppPoolBitness.enable32Bit)]
[InlineData("ASPNETCORE_IIS_HTTPAUTH", "anonymous;", "anonymous;", IISConfigUtility.AppPoolBitness.noChange)]
[InlineData("ASPNETCORE_IIS_HTTPAUTH", "basic;anonymous;", "basic;anonymous;", IISConfigUtility.AppPoolBitness.enable32Bit)]
[InlineData("ASPNETCORE_IIS_HTTPAUTH", "windows;anonymous;", "windows;anonymous;", IISConfigUtility.AppPoolBitness.noChange)]
[InlineData("ASPNETCORE_IIS_HTTPAUTH", "windows;basic;anonymous;", "windows;basic;anonymous;", IISConfigUtility.AppPoolBitness.enable32Bit)]
[InlineData("ASPNETCORE_IIS_HTTPAUTH", "ignoredValue", "anonymous;", IISConfigUtility.AppPoolBitness.noChange)]
public Task EnvironmentVariablesTest(string environmentVariableName, string environmentVariableValue, string expectedEnvironmentVariableValue, IISConfigUtility.AppPoolBitness appPoolBitness)
{
return DoEnvironmentVariablesTest(appPoolBitness);
return DoEnvironmentVariablesTest(environmentVariableName, environmentVariableValue, expectedEnvironmentVariableValue, appPoolBitness);
}
[EnvironmentVariableTestCondition("IIS_VARIATIONS_ENABLED")]
[ConditionalTheory]
[ANCMTestSkipCondition("RunAsAdministratorAndX64Bitness")]
[OSSkipCondition(OperatingSystems.Linux)]
[OSSkipCondition(OperatingSystems.MacOSX)]
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit)]
@ -160,9 +145,9 @@ namespace AspNetCoreModule.Test
{
return DoAppOfflineTestWithRenaming(appPoolBitness);
}
[EnvironmentVariableTestCondition("IIS_VARIATIONS_ENABLED")]
[ConditionalTheory]
[ANCMTestSkipCondition("RunAsAdministratorAndX64Bitness")]
[OSSkipCondition(OperatingSystems.Linux)]
[OSSkipCondition(OperatingSystems.MacOSX)]
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit)]
@ -171,9 +156,9 @@ namespace AspNetCoreModule.Test
{
return DoAppOfflineTestWithUrlRewriteAndDeleting(appPoolBitness);
}
[EnvironmentVariableTestCondition("IIS_VARIATIONS_ENABLED")]
[ConditionalTheory]
[ANCMTestSkipCondition("RunAsAdministratorAndX64Bitness")]
[OSSkipCondition(OperatingSystems.Linux)]
[OSSkipCondition(OperatingSystems.MacOSX)]
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit, "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789")]
@ -182,9 +167,9 @@ namespace AspNetCoreModule.Test
{
return DoPostMethodTest(appPoolBitness, testData);
}
[EnvironmentVariableTestCondition("IIS_VARIATIONS_ENABLED")]
[ConditionalTheory]
[ANCMTestSkipCondition("RunAsAdministratorAndX64Bitness")]
[OSSkipCondition(OperatingSystems.Linux)]
[OSSkipCondition(OperatingSystems.MacOSX)]
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit)]
@ -194,8 +179,8 @@ namespace AspNetCoreModule.Test
return DoDisableStartUpErrorPageTest(appPoolBitness);
}
[EnvironmentVariableTestCondition("IIS_VARIATIONS_ENABLED")]
[ConditionalTheory]
[ANCMTestSkipCondition("RunAsAdministratorAndX64Bitness")]
[OSSkipCondition(OperatingSystems.Linux)]
[OSSkipCondition(OperatingSystems.MacOSX)]
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit, 10)]
@ -205,8 +190,8 @@ namespace AspNetCoreModule.Test
return DoProcessesPerApplicationTest(appPoolBitness, valueOfProcessesPerApplication);
}
[EnvironmentVariableTestCondition("IIS_VARIATIONS_ENABLED")]
[ConditionalTheory]
[ANCMTestSkipCondition("RunAsAdministratorAndX64Bitness")]
[OSSkipCondition(OperatingSystems.Linux)]
[OSSkipCondition(OperatingSystems.MacOSX)]
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit, "00:02:00")]
@ -218,8 +203,8 @@ namespace AspNetCoreModule.Test
return DoRequestTimeoutTest(appPoolBitness, requestTimeout);
}
[EnvironmentVariableTestCondition("IIS_VARIATIONS_ENABLED")]
[ConditionalTheory]
[ANCMTestSkipCondition("RunAsAdministratorAndX64Bitness")]
[OSSkipCondition(OperatingSystems.Linux)]
[OSSkipCondition(OperatingSystems.MacOSX)]
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit)]
@ -229,8 +214,8 @@ namespace AspNetCoreModule.Test
return DoStdoutLogEnabledTest(appPoolBitness);
}
[EnvironmentVariableTestCondition("IIS_VARIATIONS_ENABLED")]
[ConditionalTheory]
[ANCMTestSkipCondition("RunAsAdministratorAndX64Bitness")]
[OSSkipCondition(OperatingSystems.Linux)]
[OSSkipCondition(OperatingSystems.MacOSX)]
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit, "dotnet.exe", "./")]
@ -241,9 +226,9 @@ namespace AspNetCoreModule.Test
{
return DoProcessPathAndArgumentsTest(appPoolBitness, processPath, argumentsPrefix);
}
[EnvironmentVariableTestCondition("IIS_VARIATIONS_ENABLED")]
[ConditionalTheory]
[ANCMTestSkipCondition("RunAsAdministratorAndX64Bitness")]
[OSSkipCondition(OperatingSystems.Linux)]
[OSSkipCondition(OperatingSystems.MacOSX)]
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit, true)]
@ -255,19 +240,8 @@ namespace AspNetCoreModule.Test
return DoForwardWindowsAuthTokenTest(appPoolBitness, enabledForwardWindowsAuthToken);
}
[EnvironmentVariableTestCondition("IIS_VARIATIONS_ENABLED")]
[ConditionalTheory]
[OSSkipCondition(OperatingSystems.Linux)]
[OSSkipCondition(OperatingSystems.MacOSX)]
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit)]
[InlineData(IISConfigUtility.AppPoolBitness.noChange)]
public Task RecylingAppPoolTest(IISConfigUtility.AppPoolBitness appPoolBitness)
{
return DoRecylingAppPoolTest(appPoolBitness);
}
[EnvironmentVariableTestCondition("IIS_VARIATIONS_ENABLED")]
[ConditionalTheory]
[ANCMTestSkipCondition("RunAsAdministratorAndX64Bitness")]
[OSSkipCondition(OperatingSystems.Linux)]
[OSSkipCondition(OperatingSystems.MacOSX)]
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit, true, true)]
@ -278,9 +252,9 @@ namespace AspNetCoreModule.Test
{
return DoCompressionTest(appPoolBitness, useCompressionMiddleWare, enableIISCompression);
}
[EnvironmentVariableTestCondition("IIS_VARIATIONS_ENABLED")]
[ConditionalTheory]
[ANCMTestSkipCondition("RunAsAdministratorAndX64Bitness")]
[OSSkipCondition(OperatingSystems.Linux)]
[OSSkipCondition(OperatingSystems.MacOSX)]
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit)]
@ -289,9 +263,9 @@ namespace AspNetCoreModule.Test
{
return DoCachingTest(appPoolBitness);
}
[EnvironmentVariableTestCondition("IIS_VARIATIONS_ENABLED")]
[ConditionalTheory]
[ANCMTestSkipCondition("RunAsAdministratorAndX64Bitness")]
[OSSkipCondition(OperatingSystems.Linux)]
[OSSkipCondition(OperatingSystems.MacOSX)]
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit)]
@ -300,9 +274,9 @@ namespace AspNetCoreModule.Test
{
return DoSendHTTPSRequestTest(appPoolBitness);
}
[EnvironmentVariableTestCondition("IIS_VARIATIONS_ENABLED")]
[ConditionalTheory]
[ANCMTestSkipCondition("RunAsAdministratorAndX64Bitness")]
[OSSkipCondition(OperatingSystems.Linux)]
[OSSkipCondition(OperatingSystems.MacOSX)]
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit, true)]
@ -312,5 +286,32 @@ namespace AspNetCoreModule.Test
{
return DoClientCertificateMappingTest(appPoolBitness, useHTTPSMiddleWare);
}
//////////////////////////////////////////////////////////
// NOTE: below test scenarios are not valid for Win7 OS
//////////////////////////////////////////////////////////
[ConditionalTheory]
[ANCMTestSkipCondition("RunAsAdministratorAndX64Bitness")]
[OSSkipCondition(OperatingSystems.Linux)]
[OSSkipCondition(OperatingSystems.MacOSX)]
[OSSkipCondition(OperatingSystems.Windows, WindowsVersions.Win7, SkipReason = "IIS does not support Websocket on Win7")]
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit, "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789")]
[InlineData(IISConfigUtility.AppPoolBitness.noChange, "a")]
public Task WebSocketTest(IISConfigUtility.AppPoolBitness appPoolBitness, string testData)
{
return DoWebSocketTest(appPoolBitness, testData);
}
[ConditionalTheory]
[ANCMTestSkipCondition("RunAsAdministratorAndX64Bitness")]
[OSSkipCondition(OperatingSystems.Linux)]
[OSSkipCondition(OperatingSystems.MacOSX)]
[OSSkipCondition(OperatingSystems.Windows, WindowsVersions.Win7, SkipReason = "WAS does not handle private memory limitation with Job object on Win7")]
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit)]
[InlineData(IISConfigUtility.AppPoolBitness.noChange)]
public Task RecylingAppPoolTest(IISConfigUtility.AppPoolBitness appPoolBitness)
{
return DoRecylingAppPoolTest(appPoolBitness);
}
}
}

Просмотреть файл

@ -18,11 +18,71 @@ using System.Text;
using System.IO;
using System.Security.Principal;
using System.IO.Compression;
using Microsoft.AspNetCore.Testing.xunit;
namespace AspNetCoreModule.Test
{
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class ANCMTestSkipCondition : Attribute, ITestCondition
{
private readonly string _environmentVariableName;
public ANCMTestSkipCondition(string environmentVariableName)
{
_environmentVariableName = environmentVariableName;
}
public bool IsMet
{
get
{
bool result = true;
if (_environmentVariableName == "RunAsAdministratorAndX64Bitness")
{
try
{
if (Environment.Is64BitOperatingSystem && !Environment.Is64BitProcess)
{
throw new System.InvalidOperationException("this should be started with x64 process mode on 64 bit machine");
}
bool isElevated;
WindowsIdentity identity = WindowsIdentity.GetCurrent();
WindowsPrincipal principal = new WindowsPrincipal(identity);
isElevated = principal.IsInRole(WindowsBuiltInRole.Administrator);
if (!isElevated)
{
throw new System.ApplicationException("this should be started as an administrator");
}
}
catch (Exception ex)
{
AdditionalInfo = ex.Message;
result = false;
}
}
return result;
}
}
public string SkipReason
{
get
{
return $"Skip condition: {_environmentVariableName}: this test case is skipped becauset {AdditionalInfo}.";
}
}
public string AdditionalInfo { get; set; }
}
public class FunctionalTestHelper
{
public FunctionalTestHelper()
{
}
private const int _repeatCount = 3;
public enum ReturnValueType
@ -33,18 +93,20 @@ namespace AspNetCoreModule.Test
None
}
public static async Task DoBasicTest(ServerType serverType, IISConfigUtility.AppPoolBitness appPoolBitness)
public static async Task DoBasicTest(IISConfigUtility.AppPoolBitness appPoolBitness)
{
using (var testSite = new TestWebSite(appPoolBitness, "DoBasicTest", serverType))
using (var testSite = new TestWebSite(appPoolBitness, "DoBasicTest"))
{
string backendProcessId_old = null;
DateTime startTime = DateTime.Now;
Thread.Sleep(3000);
string backendProcessId = await GetResponse(testSite.AspNetCoreApp.GetUri("GetProcessId"), HttpStatusCode.OK);
Assert.NotEqual(backendProcessId_old, backendProcessId);
var backendProcess = Process.GetProcessById(Convert.ToInt32(backendProcessId));
Assert.Equal(backendProcess.ProcessName.ToLower().Replace(".exe", ""), testSite.AspNetCoreApp.GetProcessFileName().ToLower().Replace(".exe", ""));
Assert.True(TestUtility.RetryHelper((arg1, arg2) => VerifyANCMStartEvent(arg1, arg2), startTime, backendProcessId));
var httpClientHandler = new HttpClientHandler();
@ -78,6 +140,7 @@ namespace AspNetCoreModule.Test
backendProcessId_old = backendProcessId;
var backendProcess = Process.GetProcessById(Convert.ToInt32(backendProcessId));
Assert.Equal(backendProcess.ProcessName.ToLower().Replace(".exe", ""), testSite.AspNetCoreApp.GetProcessFileName().ToLower().Replace(".exe", ""));
Assert.True(TestUtility.RetryHelper((arg1, arg2) => VerifyANCMStartEvent(arg1, arg2), startTime, backendProcessId));
backendProcess.Kill();
Thread.Sleep(500);
@ -89,6 +152,12 @@ namespace AspNetCoreModule.Test
{
using (var testSite = new TestWebSite(appPoolBitness, "DoRecycleApplicationAfterW3WPProcessBeingKilled"))
{
if (testSite.IisServerType == ServerType.IISExpress)
{
TestUtility.LogInformation("This test is not valid for IISExpress server type");
return;
}
string backendProcessId_old = null;
const int repeatCount = 3;
for (int i = 0; i < repeatCount; i++)
@ -212,11 +281,15 @@ namespace AspNetCoreModule.Test
}
}
public static async Task DoEnvironmentVariablesTest(IISConfigUtility.AppPoolBitness appPoolBitness)
public static async Task DoEnvironmentVariablesTest(string environmentVariableName, string environmentVariableValue, string expectedEnvironmentVariableValue, IISConfigUtility.AppPoolBitness appPoolBitness)
{
if (environmentVariableName == null)
{
throw new InvalidDataException("envrionmentVarialbeName is null");
}
using (var testSite = new TestWebSite(appPoolBitness, "DoEnvironmentVariablesTest"))
{
using (var iisConfig = new IISConfigUtility(ServerType.IIS))
using (var iisConfig = new IISConfigUtility(testSite.IisServerType, testSite.IisExpressConfigPath))
{
DateTime startTime = DateTime.Now;
Thread.Sleep(500);
@ -237,22 +310,78 @@ namespace AspNetCoreModule.Test
TestUtility.ResetHelper(ResetHelperMode.KillVSJitDebugger);
int expectedValue = Convert.ToInt32(totalNumber) + 1;
string totalResult = (await GetResponse(testSite.AspNetCoreApp.GetUri("GetEnvironmentVariables"), HttpStatusCode.OK));
Assert.True(expectedValue.ToString() == (await GetResponse(testSite.AspNetCoreApp.GetUri("GetEnvironmentVariables"), HttpStatusCode.OK)));
iisConfig.SetANCMConfig(testSite.SiteName, testSite.AspNetCoreApp.Name, "environmentVariable", new string[] { "ANCMTestBar", "bar" });
Thread.Sleep(500);
bool setEnvironmentVariableConfiguration = true;
// Set authentication for ASPNETCORE_IIS_HTTPAUTH test scenarios
if (environmentVariableName == "ASPNETCORE_IIS_HTTPAUTH" && environmentVariableValue != "ignoredValue")
{
setEnvironmentVariableConfiguration = false;
bool windows = false;
bool basic = false;
bool anonymous = false;
if (environmentVariableValue.Contains("windows;"))
{
windows = true;
}
if (environmentVariableValue.Contains("basic;"))
{
basic = true;
}
if (environmentVariableValue.Contains("anonymous;"))
{
anonymous = true;
}
iisConfig.EnableIISAuthentication(testSite.SiteName, windows, basic, anonymous);
}
if (environmentVariableValue == "NA" || environmentVariableValue == null)
{
setEnvironmentVariableConfiguration = false;
}
// Add a new environment variable
if (setEnvironmentVariableConfiguration)
{
iisConfig.SetANCMConfig(testSite.SiteName, testSite.AspNetCoreApp.Name, "environmentVariable", new string[] { environmentVariableName, environmentVariableValue });
// Adjust the new expected total number of environment variables
if (environmentVariableName != "ASPNETCORE_HOSTINGSTARTUPASSEMBLIES" &&
environmentVariableName != "ASPNETCORE_IIS_HTTPAUTH")
{
expectedValue++;
}
}
Thread.Sleep(500);
// check JitDebugger before continuing
TestUtility.ResetHelper(ResetHelperMode.KillVSJitDebugger);
expectedValue++;
totalResult = (await GetResponse(testSite.AspNetCoreApp.GetUri("GetEnvironmentVariables"), HttpStatusCode.OK));
Assert.True(expectedValue.ToString() == totalResult);
Assert.True("foo" == (await GetResponse(testSite.AspNetCoreApp.GetUri("ExpandEnvironmentVariablesANCMTestFoo"), HttpStatusCode.OK)));
Assert.True("bar" == (await GetResponse(testSite.AspNetCoreApp.GetUri("ExpandEnvironmentVariablesANCMTestBar"), HttpStatusCode.OK)));
Assert.True(expectedEnvironmentVariableValue == (await GetResponse(testSite.AspNetCoreApp.GetUri("ExpandEnvironmentVariables" + environmentVariableName), HttpStatusCode.OK)));
// Verify other common environment variables
string temp = (await GetResponse(testSite.AspNetCoreApp.GetUri("DumpEnvironmentVariables"), HttpStatusCode.OK));
Assert.True(temp.Contains("ASPNETCORE_PORT"));
Assert.True(temp.Contains("ASPNETCORE_APPL_PATH"));
Assert.True(temp.Contains("ASPNETCORE_IIS_HTTPAUTH"));
Assert.True(temp.Contains("ASPNETCORE_TOKEN"));
Assert.True(temp.Contains("ASPNETCORE_HOSTINGSTARTUPASSEMBLIES"));
// Verify other inherited environment variables
Assert.True(temp.Contains("PROCESSOR_ARCHITECTURE"));
Assert.True(temp.Contains("USERNAME"));
Assert.True(temp.Contains("USERDOMAIN"));
Assert.True(temp.Contains("USERPROFILE"));
}
testSite.AspNetCoreApp.RestoreFile("web.config");
}
}
public static async Task DoAppOfflineTestWithRenaming(IISConfigUtility.AppPoolBitness appPoolBitness)
{
using (var testSite = new TestWebSite(appPoolBitness, "DoAppOfflineTestWithRenaming"))
@ -350,7 +479,7 @@ namespace AspNetCoreModule.Test
Thread.Sleep(500);
using (var iisConfig = new IISConfigUtility(ServerType.IIS))
using (var iisConfig = new IISConfigUtility(testSite.IisServerType, testSite.IisExpressConfigPath))
{
DateTime startTime = DateTime.Now;
Thread.Sleep(500);
@ -390,7 +519,7 @@ namespace AspNetCoreModule.Test
{
using (var testSite = new TestWebSite(appPoolBitness, "DoRapidFailsPerMinuteTest"))
{
using (var iisConfig = new IISConfigUtility(ServerType.IIS))
using (var iisConfig = new IISConfigUtility(testSite.IisServerType, testSite.IisExpressConfigPath))
{
bool rapidFailsTriggered = false;
iisConfig.SetANCMConfig(testSite.SiteName, testSite.AspNetCoreApp.Name, "rapidFailsPerMinute", valueOfRapidFailsPerMinute);
@ -446,9 +575,10 @@ namespace AspNetCoreModule.Test
{
using (var testSite = new TestWebSite(appPoolBitness, "DoProcessesPerApplicationTest"))
{
using (var iisConfig = new IISConfigUtility(ServerType.IIS))
using (var iisConfig = new IISConfigUtility(testSite.IisServerType, testSite.IisExpressConfigPath))
{
DateTime startTime = DateTime.Now;
Thread.Sleep(3000);
iisConfig.SetANCMConfig(testSite.SiteName, testSite.AspNetCoreApp.Name, "processesPerApplication", valueOfProcessesPerApplication);
HashSet<int> processIDs = new HashSet<int>();
@ -469,6 +599,7 @@ namespace AspNetCoreModule.Test
}
Assert.Equal(valueOfProcessesPerApplication, processIDs.Count);
foreach (var id in processIDs)
{
var backendProcess = Process.GetProcessById(id);
@ -505,7 +636,7 @@ namespace AspNetCoreModule.Test
{
using (var testSite = new TestWebSite(appPoolBitness, "DoStartupTimeLimitTest"))
{
using (var iisConfig = new IISConfigUtility(ServerType.IIS))
using (var iisConfig = new IISConfigUtility(testSite.IisServerType, testSite.IisExpressConfigPath))
{
int startupDelay = 3; //3 seconds
iisConfig.SetANCMConfig(
@ -536,7 +667,7 @@ namespace AspNetCoreModule.Test
{
using (var testSite = new TestWebSite(appPoolBitness, "DoRequestTimeoutTest"))
{
using (var iisConfig = new IISConfigUtility(ServerType.IIS))
using (var iisConfig = new IISConfigUtility(testSite.IisServerType, testSite.IisExpressConfigPath))
{
iisConfig.SetANCMConfig(testSite.SiteName, testSite.AspNetCoreApp.Name, "requestTimeout", TimeSpan.Parse(requestTimeout));
Thread.Sleep(500);
@ -562,7 +693,7 @@ namespace AspNetCoreModule.Test
{
using (var testSite = new TestWebSite(appPoolBitness, "DoShutdownTimeLimitTest"))
{
using (var iisConfig = new IISConfigUtility(ServerType.IIS))
using (var iisConfig = new IISConfigUtility(testSite.IisServerType, testSite.IisExpressConfigPath))
{
// Set new value (10 second) to make the backend process get the Ctrl-C signal and measure when the recycle happens
iisConfig.SetANCMConfig(testSite.SiteName, testSite.AspNetCoreApp.Name, "shutdownTimeLimit", valueOfshutdownTimeLimit);
@ -598,16 +729,18 @@ namespace AspNetCoreModule.Test
{
testSite.AspNetCoreApp.DeleteDirectory("logs");
using (var iisConfig = new IISConfigUtility(ServerType.IIS))
using (var iisConfig = new IISConfigUtility(testSite.IisServerType, testSite.IisExpressConfigPath))
{
DateTime startTime = DateTime.Now;
Thread.Sleep(500);
Thread.Sleep(3000);
iisConfig.SetANCMConfig(testSite.SiteName, testSite.AspNetCoreApp.Name, "stdoutLogEnabled", true);
iisConfig.SetANCMConfig(testSite.SiteName, testSite.AspNetCoreApp.Name, "stdoutLogFile", @".\logs\stdout");
string backendProcessId = await GetResponse(testSite.AspNetCoreApp.GetUri("GetProcessId"), HttpStatusCode.OK);
string logPath = testSite.AspNetCoreApp.GetDirectoryPathWith("logs");
Assert.False(Directory.Exists(logPath));
Assert.True(TestUtility.RetryHelper((arg1, arg2, arg3) => VerifyApplicationEventLog(arg1, arg2, arg3), 1004, startTime, @"logs\stdout"));
Assert.True(TestUtility.RetryHelper((arg1, arg2) => VerifyANCMStartEvent(arg1, arg2), startTime, backendProcessId));
@ -642,9 +775,9 @@ namespace AspNetCoreModule.Test
public static async Task DoProcessPathAndArgumentsTest(IISConfigUtility.AppPoolBitness appPoolBitness, string processPath, string argumentsPrefix)
{
using (var testSite = new TestWebSite(appPoolBitness, "DoProcessPathAndArgumentsTest"))
using (var testSite = new TestWebSite(appPoolBitness, "DoProcessPathAndArgumentsTest", copyAllPublishedFiles:true))
{
using (var iisConfig = new IISConfigUtility(ServerType.IIS))
using (var iisConfig = new IISConfigUtility(testSite.IisServerType, testSite.IisExpressConfigPath))
{
string arguments = argumentsPrefix + testSite.AspNetCoreApp.GetArgumentFileName();
string tempProcessId = await GetResponse(testSite.AspNetCoreApp.GetUri("GetProcessId"), HttpStatusCode.OK);
@ -681,15 +814,14 @@ namespace AspNetCoreModule.Test
{
using (var testSite = new TestWebSite(appPoolBitness, "DoForwardWindowsAuthTokenTest"))
{
using (var iisConfig = new IISConfigUtility(ServerType.IIS))
using (var iisConfig = new IISConfigUtility(testSite.IisServerType, testSite.IisExpressConfigPath))
{
string result = string.Empty;
iisConfig.SetANCMConfig(testSite.SiteName, testSite.AspNetCoreApp.Name, "forwardWindowsAuthToken", enabledForwardWindowsAuthToken);
string requestHeaders = await GetResponse(testSite.AspNetCoreApp.GetUri("DumpRequestHeaders"), HttpStatusCode.OK);
Assert.False(requestHeaders.ToUpper().Contains("MS-ASPNETCORE-WINAUTHTOKEN"));
iisConfig.EnableWindowsAuthentication(testSite.SiteName);
iisConfig.EnableIISAuthentication(testSite.SiteName, windows:true, basic:false, anonymous:false);
Thread.Sleep(500);
// check JitDebugger before continuing
@ -736,7 +868,13 @@ namespace AspNetCoreModule.Test
{
using (var testSite = new TestWebSite(appPoolBitness, "DoRecylingAppPoolTest"))
{
using (var iisConfig = new IISConfigUtility(ServerType.IIS))
if (testSite.IisServerType == ServerType.IISExpress)
{
TestUtility.LogInformation("This test is not valid for IISExpress server type");
return;
}
using (var iisConfig = new IISConfigUtility(testSite.IisServerType, testSite.IisExpressConfigPath))
{
// allocating 1024,000 KB
@ -845,7 +983,7 @@ namespace AspNetCoreModule.Test
{
using (var testSite = new TestWebSite(appPoolBitness, "DoCompressionTest"))
{
using (var iisConfig = new IISConfigUtility(ServerType.IIS))
using (var iisConfig = new IISConfigUtility(testSite.IisServerType, testSite.IisExpressConfigPath))
{
string startupClass = "StartupCompressionCaching";
if (!useCompressionMiddleWare)
@ -911,7 +1049,7 @@ namespace AspNetCoreModule.Test
{
using (var testSite = new TestWebSite(appPoolBitness, "DoCachingTest"))
{
using (var iisConfig = new IISConfigUtility(ServerType.IIS))
using (var iisConfig = new IISConfigUtility(testSite.IisServerType, testSite.IisExpressConfigPath))
{
string startupClass = "StartupCompressionCaching";
@ -937,16 +1075,26 @@ namespace AspNetCoreModule.Test
string result = string.Empty;
result = await GetResponseAndHeaders(testSite.AspNetCoreApp.GetUri("foo.htm"), new string[] { "Accept-Encoding", "gzip" }, HttpStatusCode.OK);
string headerValue = GetHeaderValue(result, "MyCustomHeader");
Assert.True(result.Contains("foohtm"), "verify response body");
Assert.Equal("gzip", GetHeaderValue(result, "Content-Encoding"));
Thread.Sleep(2000);
const int retryCount = 3;
string headerValue = string.Empty;
string headerValue2 = string.Empty;
for (int i = 0; i < retryCount; i++)
{
result = await GetResponseAndHeaders(testSite.AspNetCoreApp.GetUri("foo.htm"), new string[] { "Accept-Encoding", "gzip" }, HttpStatusCode.OK);
headerValue = GetHeaderValue(result, "MyCustomHeader");
Assert.True(result.Contains("foohtm"), "verify response body");
Assert.Equal("gzip", GetHeaderValue(result, "Content-Encoding"));
Thread.Sleep(1500);
result = await GetResponseAndHeaders(testSite.AspNetCoreApp.GetUri("foo.htm"), new string[] { "Accept-Encoding", "gzip" }, HttpStatusCode.OK);
string headerValue2 = GetHeaderValue(result, "MyCustomHeader");
Assert.True(result.Contains("foohtm"), "verify response body");
Assert.Equal("gzip", GetHeaderValue(result, "Content-Encoding"));
result = await GetResponseAndHeaders(testSite.AspNetCoreApp.GetUri("foo.htm"), new string[] { "Accept-Encoding", "gzip" }, HttpStatusCode.OK);
headerValue2 = GetHeaderValue(result, "MyCustomHeader");
Assert.True(result.Contains("foohtm"), "verify response body");
Assert.Equal("gzip", GetHeaderValue(result, "Content-Encoding"));
if (headerValue == headerValue2)
{
break;
}
}
Assert.Equal(headerValue, headerValue2);
Thread.Sleep(12000);
@ -962,15 +1110,15 @@ namespace AspNetCoreModule.Test
public static async Task DoSendHTTPSRequestTest(IISConfigUtility.AppPoolBitness appPoolBitness)
{
using (var testSite = new TestWebSite(appPoolBitness, "DoSendHTTPSRequestTest"))
using (var testSite = new TestWebSite(appPoolBitness, "DoSendHTTPSRequestTest", startIISExpress:false))
{
using (var iisConfig = new IISConfigUtility(ServerType.IIS))
using (var iisConfig = new IISConfigUtility(testSite.IisServerType, testSite.IisExpressConfigPath))
{
string hostName = "";
string subjectName = "localhost";
string ipAddress = "*";
string hexIPAddress = "0x00";
int sslPort = 46300;
int sslPort = InitializeTestMachine.SiteId + 6300;
// Add https binding and get https uri information
iisConfig.AddBindingToSite(testSite.SiteName, ipAddress, sslPort, hostName, "https");
@ -984,6 +1132,9 @@ namespace AspNetCoreModule.Test
// Configure http.sys ssl certificate mapping to IP:Port endpoint with the newly created self signed certificage
iisConfig.SetSSLCertificate(sslPort, hexIPAddress, thumbPrint);
// starting IISExpress was deffered after creating test applications and now it is ready to start it
testSite.StartIISExpress();
// Verify http request
string result = string.Empty;
result = await GetResponseAndHeaders(testSite.AspNetCoreApp.GetUri(), new string[] { "Accept-Encoding", "gzip" }, HttpStatusCode.OK);
@ -1009,9 +1160,9 @@ namespace AspNetCoreModule.Test
public static async Task DoClientCertificateMappingTest(IISConfigUtility.AppPoolBitness appPoolBitness, bool useHTTPSMiddleWare)
{
using (var testSite = new TestWebSite(appPoolBitness, "DoClientCertificateMappingTest"))
using (var testSite = new TestWebSite(appPoolBitness, "DoClientCertificateMappingTest", startIISExpress: false))
{
using (var iisConfig = new IISConfigUtility(ServerType.IIS))
using (var iisConfig = new IISConfigUtility(testSite.IisServerType, testSite.IisExpressConfigPath))
{
string hostName = "";
string rootCN = "ANCMTest" + testSite.PostFix;
@ -1021,7 +1172,7 @@ namespace AspNetCoreModule.Test
string ipAddress = "*";
string hexIPAddress = "0x00";
int sslPort = 46300;
int sslPort = InitializeTestMachine.SiteId + 6300;
// Add https binding and get https uri information
iisConfig.AddBindingToSite(testSite.SiteName, ipAddress, sslPort, hostName, "https");
@ -1050,7 +1201,27 @@ namespace AspNetCoreModule.Test
// Get public key of the client certificate and Configure OnetToOneClientCertificateMapping the public key and disable anonymous authentication and set SSL flags for Client certificate authentication
string publicKey = iisConfig.GetCertificatePublicKey(thumbPrintForClientAuthentication, @"Cert:\CurrentUser\My");
iisConfig.EnableOneToOneClientCertificateMapping(testSite.SiteName, ".\\" + userName, password, publicKey);
bool setPasswordSeperately = false;
if (testSite.IisServerType == ServerType.IISExpress && IISConfigUtility.IsIISInstalled == true)
{
setPasswordSeperately = true;
iisConfig.EnableOneToOneClientCertificateMapping(testSite.SiteName, ".\\" + userName, null, publicKey);
}
else
{
iisConfig.EnableOneToOneClientCertificateMapping(testSite.SiteName, ".\\" + userName, password, publicKey);
}
// IISExpress uses a differnt encryption from full IIS version's and it is not easy to override the encryption methong with MWA.
// As a work-around, password is set with updating the config file directly.
if (setPasswordSeperately)
{
// Search userName property and replace it with userName + password
string text = File.ReadAllText(testSite.IisExpressConfigPath);
text = text.Replace(userName + "\"", userName + "\"" + " " + "password=" + "\"" + password + "\"");
File.WriteAllText(testSite.IisExpressConfigPath, text);
}
// Configure kestrel SSL test environment
if (useHTTPSMiddleWare)
@ -1073,9 +1244,13 @@ namespace AspNetCoreModule.Test
Assert.True(File.Exists(pfxFilePath));
}
// starting IISExpress was deffered after creating test applications and now it is ready to start it
Uri rootHttpsUri = testSite.RootAppContext.GetUri(null, sslPort, protocol: "https");
testSite.StartIISExpress("( invoke-webrequest " + rootHttpsUri.OriginalString + " -CertificateThumbprint " + thumbPrintForClientAuthentication + ").StatusCode");
// Verify http request with using client certificate
Uri targetHttpsUri = testSite.AspNetCoreApp.GetUri(null, sslPort, protocol: "https");
string statusCode = TestUtility.RunPowershellScript("( invoke-webrequest " + targetHttpsUri.OriginalString + " -CertificateThumbprint " + thumbPrintForClientAuthentication + ").StatusCode");
string statusCode = TestUtility.RunPowershellScript("( invoke-webrequest " + targetHttpsUri.OriginalString + " -CertificateThumbprint " + thumbPrintForClientAuthentication + ").StatusCode");
Assert.Equal("200", statusCode);
// Verify https request with client certificate includes the certificate header "MS-ASPNETCORE-CLIENTCERT"
@ -1134,10 +1309,7 @@ namespace AspNetCoreModule.Test
// Verify WebSocket subprotocol
await VerifyResponseBodyContain(testSite.WebSocketApp.GetUri("echoSubProtocol.aspx"), new string[] { "Socket Open", "mywebsocketsubprotocol" }, HttpStatusCode.OK); // echoSubProtocol.aspx has hard coded path for the websocket server
// Verify process creation ANCM event log
Assert.True(TestUtility.RetryHelper((arg1, arg2) => VerifyANCMStartEvent(arg1, arg2), startTime, backendProcessId));
// Verify websocket
using (WebSocketClientHelper websocketClient = new WebSocketClientHelper())
{
@ -1386,10 +1558,30 @@ namespace AspNetCoreModule.Test
if (unZipContent)
{
var inputStream = await response.Content.ReadAsStreamAsync();
var outputStream = new MemoryStream();
// for debugging purpose
//byte[] temp = new byte[inputStream.Length];
//inputStream.Read(temp, 0, (int) inputStream.Length);
//inputStream.Position = 0;
using (var gzip = new GZipStream(inputStream, CompressionMode.Decompress))
{
await gzip.CopyToAsync(outputStream);
var outputStream = new MemoryStream();
try
{
await gzip.CopyToAsync(outputStream);
}
catch (Exception ex)
{
// Even though "Vary" response header exists, the content is not actually compressed.
// We should ignore this execption until we find a proper way to determine if the body is compressed or not.
if (ex.Message.IndexOf("gzip", StringComparison.InvariantCultureIgnoreCase) >= 0)
{
result = await response.Content.ReadAsStringAsync();
return result;
}
throw ex;
}
gzip.Close();
inputStream.Close();
outputStream.Position = 0;
@ -1414,7 +1606,8 @@ namespace AspNetCoreModule.Test
string responseStatus = "NotInitialized";
var httpClientHandler = new HttpClientHandler();
httpClientHandler.UseDefaultCredentials = true;
httpClientHandler.UseDefaultCredentials = true;
httpClientHandler.AutomaticDecompression = DecompressionMethods.None;
var httpClient = new HttpClient(httpClientHandler)
{

Просмотреть файл

@ -26,6 +26,14 @@
<assemblyIdentity name="Microsoft.Extensions.FileProviders.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.1.0.0" newVersion="1.1.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Console" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Diagnostics.DiagnosticSource" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.1.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.1" /></startup></configuration>
</configuration>

Просмотреть файл

@ -6,12 +6,15 @@
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
</PropertyGroup>
<ItemGroup>
<None Remove="_app._config" />
</ItemGroup>
<ItemGroup>
<None Update="Http.config">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
@ -32,7 +35,6 @@
<Reference Include="System.Data" />
<Reference Include="System.IO.Compression.FileSystem" />
<Reference Include="System.Management" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Net.Http.WebRequest" />
<Reference Include="System.Runtime" />
<Reference Include="System.Xml" />
@ -41,6 +43,10 @@
<Reference Include="System.ServiceProcess" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'net451' ">
<Reference Include="System.Management.Automation" />
</ItemGroup>
<ItemGroup>
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
</ItemGroup>

Просмотреть файл

@ -0,0 +1 @@
test

Просмотреть файл

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="dotnet.exe" arguments="C:\gitroot\AspNetCoreModule\test\AspNetCoreModule.TestSites.Standard\bin\Debug\netcoreapp1.1\publish\AspNetCoreModule.TestSites.Standard.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" forwardWindowsAuthToken="true" />
</system.webServer>
</configuration>

Просмотреть файл

@ -26,7 +26,7 @@
("Result: $thumbPrint2")
.\certificate.ps1 -Command Export-CertificateTo -TargetThumbPrint $thumbPrint2 -TargetSSLStore "Cert:\LocalMachine\My" -ExportToSSLStore "Cert:\CurrentUser\My"
.\certificate.ps1 -Command Export-CertificateTo -TargetThumbPrint F97AB75DCF1C62547E4B5E7025D60001892A6A60 -ExportToSSLStore C:\gitroot\AspNetCoreModule\tools\test.pfx -PfxPassword test
.\certificate.ps1 -Command Export-CertificateTo -TargetThumbPrint $thumbPrint2 -TargetSSLStore "Cert:\LocalMachine\My" -ExportToSSLStore C:\gitroot\AspNetCoreModule\tools\test.pfx -PfxPassword test
# Clean up
@ -238,6 +238,17 @@ function Export-CertificateTo($_targetThumbPrint, $_exportToSSLStore, $_password
Remove-Item $tempExportFile -Force -Confirm:$false
}
$isThisWin7 = $false
$exportToSSLStoreName = $null
$exportToSSLStoreLocation = $null
$targetSSLStoreName = $null
$targetSSLStoreLocation = $null
if ((Get-Command Export-Certificate 2> out-null) -eq $null)
{
$isThisWin7 = $true
}
# if _exportToSSLStore points to a .pfx file
if ($exportToSSLStore.ToLower().EndsWith(".pfx"))
{
@ -246,33 +257,123 @@ function Export-CertificateTo($_targetThumbPrint, $_exportToSSLStore, $_password
return ("Error!!! _password is required")
}
$securedPassword = ConvertTo-SecureString -String $_password -Force AsPlainText
$exportedPfxFile = Export-PfxCertificate -FilePath $_exportToSSLStore -Cert $TargetSSLStore\$_targetThumbPrint -Password $securedPassword
if ( ($exportedPfxFile -ne $null) -and (Test-Path $exportedPfxFile.FullName) )
{
# Succeeded to export to .pfx file
return
if ($isThisWin7)
{
if ($TargetSSLStore.ToLower().Contains("my"))
{
$targetSSLStoreName = "My"
}
elseif ($_exportToSSLStore.ToLower().Contains("root"))
{
$targetSSLStoreName = "Root"
}
else
{
throw ("Unsupported store name " + $TargetSSLStore)
}
if ($TargetSSLStore.ToLower().Contains("localmachine"))
{
$targetSSLStoreLocation = "LocalMachine"
}
else
{
throw ("Unsupported store location name " + $TargetSSLStore)
}
&certutil.exe @('-exportpfx', '-p', $_password, $targetSSLStoreName, $_targetThumbPrint, $_exportToSSLStore) | out-null
if ( Test-Path $_exportToSSLStore )
{
# Succeeded to export to .pfx file
return
}
else
{
return ("Error!!! Can't export $TargetSSLStore\$_targetThumbPrint to $tempExportFile")
}
}
else
{
$securedPassword = ConvertTo-SecureString -String $_password -Force AsPlainText
$exportedPfxFile = Export-PfxCertificate -FilePath $_exportToSSLStore -Cert $TargetSSLStore\$_targetThumbPrint -Password $securedPassword
if ( ($exportedPfxFile -ne $null) -and (Test-Path $exportedPfxFile.FullName) )
{
# Succeeded to export to .pfx file
return
}
else
{
return ("Error!!! Can't export $TargetSSLStore\$_targetThumbPrint to $tempExportFile")
}
}
}
if ($isThisWin7)
{
# Initialize variables for Win7
if ($_exportToSSLStore.ToLower().Contains("my"))
{
$exportToSSLStoreName = [System.Security.Cryptography.X509Certificates.StoreName]::My
}
elseif ($_exportToSSLStore.ToLower().Contains("root"))
{
$exportToSSLStoreName = [System.Security.Cryptography.X509Certificates.StoreName]::Root
}
else
{
throw ("Unsupported store name " + $_exportToSSLStore)
}
if ($_exportToSSLStore.ToLower().Contains("localmachine"))
{
$exportToSSLStoreLocation = [System.Security.Cryptography.X509Certificates.StoreLocation]::LocalMachine
}
elseif ($_exportToSSLStore.ToLower().Contains("currentuser"))
{
$exportToSSLStoreLocation = [System.Security.Cryptography.X509Certificates.StoreLocation]::CurrentUser
}
else
{
throw ("Unsupported store location name " + $_exportToSSLStore)
}
# Export-Certificate is not available.
$isThisWin7 = $true
$certificate = Get-Item "$TargetSSLStore\$_targetThumbPrint"
$base64certificate = @"
-----BEGIN CERTIFICATE-----
$([Convert]::ToBase64String($certificate.Export('Cert'), [System.Base64FormattingOptions]::InsertLineBreaks)))
-----END CERTIFICATE-----
"@
Set-Content -Path $tempExportFile -Value $base64certificate | Out-Null
}
else
{
Export-Certificate -Cert $cert -FilePath $tempExportFile | Out-Null
if (-not (Test-Path $tempExportFile))
{
return ("Error!!! Can't export $TargetSSLStore\$_targetThumbPrint to $tempExportFile")
}
}
Export-Certificate -Cert $cert -FilePath $tempExportFile | Out-Null
if (-not (Test-Path $tempExportFile))
if ($isThisWin7)
{
return ("Error!!! Can't export $TargetSSLStore\$_targetThumbPrint to $tempExportFile")
[Reflection.Assembly]::Load("System.Security, Version=2.0.0.0, Culture=Neutral, PublicKeyToken=b03f5f7f11d50a3a") | Out-Null
$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($tempExportFile)
$store = New-Object System.Security.Cryptography.X509Certificates.X509Store($exportToSSLStoreName,$exportToSSLStoreLocation)
$store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite) | Out-Null
$store.Add($cert) | Out-Null
}
else
{
# clean up destination SSL store
Delete-Certificate $_targetThumbPrint $_exportToSSLStore
if (Test-Path "$_exportToSSLStore\$_targetThumbPrint")
{
return ("Error!!! Can't delete already existing one $_exportToSSLStore\$_targetThumbPrint")
}
Import-Certificate -CertStoreLocation $_exportToSSLStore -FilePath $tempExportFile | Out-Null
}
# clean up destination SSL store
Delete-Certificate $_targetThumbPrint $_exportToSSLStore
if (Test-Path "$_exportToSSLStore\$_targetThumbPrint")
{
return ("Error!!! Can't delete already existing one $_exportToSSLStore\$_targetThumbPrint")
}
Import-Certificate -CertStoreLocation $_exportToSSLStore -FilePath $tempExportFile | Out-Null
if (-not (Test-Path "$_exportToSSLStore\$_targetThumbPrint"))
{
return ("Error!!! Can't copy $TargetSSLStore\$_targetThumbPrint to $_exportToSSLStore")

96
tools/stresstest.ps1 Normal file
Просмотреть файл

@ -0,0 +1,96 @@
##########################################################
# NOTE:
# For running test automation, following prerequisite required:
#
# 1. On Win7, powershell should be upgraded to 4.0
# https://social.technet.microsoft.com/wiki/contents/articles/21016.how-to-install-windows-powershell-4-0.aspx
# 2. url-rewrite should be installed
# 3. makecert.exe tools should be available
##########################################################
# Replace aspnetcore.dll with the latest version
copy C:\gitroot\AspNetCoreModule\artifacts\build\AspNetCore\bin\Release\x64\aspnetcore.dll "C:\Program Files\IIS Express"
copy C:\gitroot\AspNetCoreModule\artifacts\build\AspNetCore\bin\Release\x64\aspnetcore.pdb "C:\Program Files\IIS Express"
# Enable appverif for IISExpress.exe
appverif /verify iisexpress.exe
# Set the AspNetCoreModuleTest environment variable with the following command
cd C:\gitroot\AspNetCoreModule\test\AspNetCoreModule.Test
dotnet restore
dotnet build
$aspNetCoreModuleTest="C:\gitroot\AspNetCoreModule\test\AspNetCoreModule.Test\bin\Debug\net46"
if (Test-Path (Join-Path $aspNetCoreModuleTest aspnetcoremodule.test.dll))
{
# Clean up applicationhost.config of IISExpress
del $env:userprofile\documents\iisexpress\config\applicationhost.config -Confirm:$false -Force
Start-Process "C:\Program Files\IIS Express\iisexpress.exe"
Sleep 3
Stop-Process -Name iisexpress
# Create sites
(1..50) | foreach { md ("C:\inetpub\wwwroot\AspnetCoreHandler_HelloWeb\foo" + $_ ) 2> out-null }
(1..50) | foreach { copy C:\gitroot\AspNetCoreModule\test\StressTestWebRoot\web.config ("C:\inetpub\wwwroot\AspnetCoreHandler_HelloWeb\foo" + $_ ) }
(1..50) | foreach {
$path = ("C:\inetpub\wwwroot\AspnetCoreHandler_HelloWeb\foo" + $_ )
$appPath = "/foo"+$_
& "C:\Program Files\IIS Express\appcmd.exe" add app /site.name:"WebSite1" /path:$appPath /physicalPath:$path
}
<#(1..50) | foreach {
$configpath = ("WebSite1/foo" + $_)
$value = "C:\inetpub\wwwroot\AspnetCoreHandler_HelloWeb\foo" + $_ + ".exe"
& "C:\Program Files\IIS Express\appcmd.exe" set config $configpath -section:system.webServer/aspNetCore /processPath:$value
}
(1..50) | foreach { copy C:\inetpub\wwwroot\AspnetCoreHandler_HelloWeb\foo.exe ("C:\inetpub\wwwroot\AspnetCoreHandler_HelloWeb\foo" + $_ +".exe") }
(1..50) | foreach {
$configpath = ("WebSite1/foo" + $_)
$value = "%AspNetCoreModuleTest%\AspnetCoreApp_HelloWeb\foo" + $_ + ".exe"
& "C:\Program Files\IIS Express\appcmd.exe" set config $configpath -section:system.webServer/aspNetCore /processPath:$value /apphostconfig:%AspNetCoreModuleTest%\config\applicationhost.config
$value = "%AspNetCoreModuleTest%\AspnetCoreApp_HelloWeb\AutobahnTestServer.dll"
& "C:\Program Files\IIS Express\appcmd.exe" set config $configpath -section:system.webServer/aspNetCore /arguments:$value /apphostconfig:%AspNetCoreModuleTest%\config\applicationhost.config
}
#>
# Start IISExpress with running the below command
&"C:\Program Files\Debugging Tools for Windows (x64)\windbg.exe" /g /G "C:\Program Files\IIS Express\iisexpress.exe"
# 6. Start stress testing
(1..10000) | foreach {
if ($_ % 2 -eq 0)
{
("Recycling backend only")
stop-process -name dotnet
(1..50) | foreach { del ("C:\inetpub\wwwroot\AspnetCoreHandler_HelloWeb\foo" + $_ + "\app_offline.htm") -confirm:$false -Force 2> out-null }
stop-process -name dotnet
}
else
{
("Recycling backedn + enabling appoffline ....")
stop-process -name dotnet
(1..50) | foreach { copy C:\gitroot\AspNetCoreModule\test\StressTestWebRoot\app_offline.htm ("C:\inetpub\wwwroot\AspnetCoreHandler_HelloWeb\foo" + $_ ) }
}
Sleep 1
(1..10) | foreach {
(1..50) | foreach {
invoke-webrequest ("http://localhost:8080/foo"+$_) > $null
}
}
}
# Stress test idea
# 1. Use Web Stress Tester
# 2. Run stop-process -name dotnet
# 3. Hit Q command to IISExpress console window
# 4. Use app_offline.htm
# 5. Save dummy web.config
}
// bp aspnetcore!FORWARDING_HANDLER::FORWARDING_HANDLER
// bp aspnetcore!FORWARDING_HANDLER::~FORWARDING_HANDLER