diff --git a/Build/common.props b/Build/common.props
index c87cc995fa..7eb2e446b7 100644
--- a/Build/common.props
+++ b/Build/common.props
@@ -12,12 +12,18 @@
$(VersionSuffix)-$(BuildNumber)
+
+ RunConfiguration.TargetPlatform=x64
+
+
+
\ No newline at end of file
diff --git a/Build/repo.props b/Build/repo.props
index a56e75519b..1d5d44d0dd 100644
--- a/Build/repo.props
+++ b/Build/repo.props
@@ -3,4 +3,8 @@
+
+
+ RunConfiguration.TargetPlatform=x64
+
\ No newline at end of file
diff --git a/Build/repo.targets b/Build/repo.targets
new file mode 100644
index 0000000000..2138b46789
--- /dev/null
+++ b/Build/repo.targets
@@ -0,0 +1,59 @@
+
+
+ true
+ $(VerifyDependsOn);PublishPackage
+ https://dotnet.myget.org/F/aspnetcoremodule/api/v2/package
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ %(MSBuild15ExePaths.FullPath)
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $(RepositoryRoot).build\nuget.exe
+ $(RepositoryRoot)nuget\AspNetCore.nuspec
+
+
+
+
+
+
+
+
+
+
+
+ <_PackagePublisherPath>@(PackagePublisherPath)\PackagePublisher.exe
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/makefile.shade b/makefile.shade
deleted file mode 100644
index 6be672789f..0000000000
--- a/makefile.shade
+++ /dev/null
@@ -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);
- }
diff --git a/src/AspNetCore/AspNetCore.vcxproj b/src/AspNetCore/AspNetCore.vcxproj
index 423cf6e188..c795aed3da 100644
--- a/src/AspNetCore/AspNetCore.vcxproj
+++ b/src/AspNetCore/AspNetCore.vcxproj
@@ -71,6 +71,9 @@
+
+ $(SolutionDir)artifacts\build\$(ProjectName)\bin\$(Configuration)\$(Platform)
+
NotUsing
diff --git a/test/AspNetCoreModule.Test/Framework/EnvironmentVariableTestConditionAttribute.cs b/test/AspNetCoreModule.Test/Framework/EnvironmentVariableTestConditionAttribute.cs
deleted file mode 100644
index 8e17664271..0000000000
--- a/test/AspNetCoreModule.Test/Framework/EnvironmentVariableTestConditionAttribute.cs
+++ /dev/null
@@ -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
-{
- ///
- /// Skip test if a given environment variable is not enabled. To enable the test, set environment variable
- /// to "true" for the test process.
- ///
- [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; }
- }
-}
\ No newline at end of file
diff --git a/test/AspNetCoreModule.Test/Framework/IISConfigUtility.cs b/test/AspNetCoreModule.Test/Framework/IISConfigUtility.cs
index 0a77d73e57..5e122c900b 100644
--- a/test/AspNetCoreModule.Test/Framework/IISConfigUtility.cs
+++ b/test/AspNetCoreModule.Test/Framework/IISConfigUtility.cs
@@ -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)
diff --git a/test/AspNetCoreModule.Test/Framework/InitializeTestMachine.cs b/test/AspNetCoreModule.Test/Framework/InitializeTestMachine.cs
index 0bf79b4e25..12df0ca755 100644
--- a/test/AspNetCoreModule.Test/Framework/InitializeTestMachine.cs
+++ b/test/AspNetCoreModule.Test/Framework/InitializeTestMachine.cs
@@ -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;
}
diff --git a/test/AspNetCoreModule.Test/Framework/TestUtility.cs b/test/AspNetCoreModule.Test/Framework/TestUtility.cs
index 9e7d6d67fd..e7373e2299 100644
--- a/test/AspNetCoreModule.Test/Framework/TestUtility.cs
+++ b/test/AspNetCoreModule.Test/Framework/TestUtility.cs
@@ -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;
diff --git a/test/AspNetCoreModule.Test/Framework/TestWebApplication.cs b/test/AspNetCoreModule.Test/Framework/TestWebApplication.cs
index 3e6498e6dc..83f0b03e32 100644
--- a/test/AspNetCoreModule.Test/Framework/TestWebApplication.cs
+++ b/test/AspNetCoreModule.Test/Framework/TestWebApplication.cs
@@ -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);
}
diff --git a/test/AspNetCoreModule.Test/Framework/TestWebSite.cs b/test/AspNetCoreModule.Test/Framework/TestWebSite.cs
index a946fc49d3..cf062ef1e9 100644
--- a/test/AspNetCoreModule.Test/Framework/TestWebSite.cs
+++ b/test/AspNetCoreModule.Test/Framework/TestWebSite.cs
@@ -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");
+ }
+ }
}
}
diff --git a/test/AspNetCoreModule.Test/FunctionalTest.cs b/test/AspNetCoreModule.Test/FunctionalTest.cs
index 52f5fa72ad..1ef8474b08 100644
--- a/test/AspNetCoreModule.Test/FunctionalTest.cs
+++ b/test/AspNetCoreModule.Test/FunctionalTest.cs
@@ -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
{
- [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);
+ }
}
}
diff --git a/test/AspNetCoreModule.Test/FunctionalTestHelper.cs b/test/AspNetCoreModule.Test/FunctionalTestHelper.cs
index 97bf2d92d8..8c206a7dfd 100644
--- a/test/AspNetCoreModule.Test/FunctionalTestHelper.cs
+++ b/test/AspNetCoreModule.Test/FunctionalTestHelper.cs
@@ -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 processIDs = new HashSet();
@@ -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)
{
diff --git a/test/AspNetCoreModule.Test/app.config b/test/AspNetCoreModule.Test/app.config
index d36d43e498..49e0f8825c 100644
--- a/test/AspNetCoreModule.Test/app.config
+++ b/test/AspNetCoreModule.Test/app.config
@@ -26,6 +26,14 @@
+
+
+
+
+
+
+
+
-
+
diff --git a/test/AspNetCoreModule.Test/aspnetcoremodule.test.csproj b/test/AspNetCoreModule.Test/aspnetcoremodule.test.csproj
index 9da583a52b..4545c18afb 100644
--- a/test/AspNetCoreModule.Test/aspnetcoremodule.test.csproj
+++ b/test/AspNetCoreModule.Test/aspnetcoremodule.test.csproj
@@ -6,12 +6,15 @@
true
true
+
+
+
+
PreserveNewest
-
@@ -32,7 +35,6 @@
-
@@ -41,6 +43,10 @@
+
+
+
+
diff --git a/test/stresstestwebroot/app_offline.htm b/test/stresstestwebroot/app_offline.htm
new file mode 100644
index 0000000000..30d74d2584
--- /dev/null
+++ b/test/stresstestwebroot/app_offline.htm
@@ -0,0 +1 @@
+test
\ No newline at end of file
diff --git a/test/stresstestwebroot/web.config b/test/stresstestwebroot/web.config
new file mode 100644
index 0000000000..a6fc3cdcf5
--- /dev/null
+++ b/test/stresstestwebroot/web.config
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tools/certificate.ps1 b/tools/certificate.ps1
index 1a19029ad9..c5a6fce639 100644
--- a/tools/certificate.ps1
+++ b/tools/certificate.ps1
@@ -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")
diff --git a/tools/stresstest.ps1 b/tools/stresstest.ps1
new file mode 100644
index 0000000000..981c6fcf44
--- /dev/null
+++ b/tools/stresstest.ps1
@@ -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
\ No newline at end of file