remove tests from ANCM as cyclic dependencies
This commit is contained in:
parent
b68d76417d
commit
90d5f124b6
|
|
@ -18,7 +18,6 @@ EndProject
|
|||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{EF30B533-D715-421A-92B7-92FEF460AC9C}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
test\Directory.Build.props = test\Directory.Build.props
|
||||
test\WebSocketClientEXE\WebSocketClientEXE.csproj = test\WebSocketClientEXE\WebSocketClientEXE.csproj
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{C74B8F36-FD2F-45C9-9B8A-00E7CF0126A9}"
|
||||
|
|
@ -54,10 +53,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CommonLib", "src\CommonLib\
|
|||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RequestHandler", "src\RequestHandler\RequestHandler.vcxproj", "{D57EA297-6DC2-4BC0-8C91-334863327863}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspNetCoreModule.Test", "test\AspNetCoreModule.Test\AspNetCoreModule.Test.csproj", "{5F31656B-4990-44FE-9090-00E32D933376}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspNetCoreModule.TestSites.Standard", "test\AspNetCoreModule.TestSites.Standard\AspNetCoreModule.TestSites.Standard.csproj", "{93ECA06C-767E-4A4D-AC59-21F250381297}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
|
@ -203,30 +198,6 @@ Global
|
|||
{D57EA297-6DC2-4BC0-8C91-334863327863}.Release|x64.Build.0 = Release|x64
|
||||
{D57EA297-6DC2-4BC0-8C91-334863327863}.Release|x86.ActiveCfg = Release|Win32
|
||||
{D57EA297-6DC2-4BC0-8C91-334863327863}.Release|x86.Build.0 = Release|Win32
|
||||
{5F31656B-4990-44FE-9090-00E32D933376}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{5F31656B-4990-44FE-9090-00E32D933376}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{5F31656B-4990-44FE-9090-00E32D933376}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{5F31656B-4990-44FE-9090-00E32D933376}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{5F31656B-4990-44FE-9090-00E32D933376}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{5F31656B-4990-44FE-9090-00E32D933376}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{5F31656B-4990-44FE-9090-00E32D933376}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{5F31656B-4990-44FE-9090-00E32D933376}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{5F31656B-4990-44FE-9090-00E32D933376}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{5F31656B-4990-44FE-9090-00E32D933376}.Release|x64.Build.0 = Release|Any CPU
|
||||
{5F31656B-4990-44FE-9090-00E32D933376}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{5F31656B-4990-44FE-9090-00E32D933376}.Release|x86.Build.0 = Release|Any CPU
|
||||
{93ECA06C-767E-4A4D-AC59-21F250381297}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{93ECA06C-767E-4A4D-AC59-21F250381297}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{93ECA06C-767E-4A4D-AC59-21F250381297}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{93ECA06C-767E-4A4D-AC59-21F250381297}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{93ECA06C-767E-4A4D-AC59-21F250381297}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{93ECA06C-767E-4A4D-AC59-21F250381297}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{93ECA06C-767E-4A4D-AC59-21F250381297}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{93ECA06C-767E-4A4D-AC59-21F250381297}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{93ECA06C-767E-4A4D-AC59-21F250381297}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{93ECA06C-767E-4A4D-AC59-21F250381297}.Release|x64.Build.0 = Release|Any CPU
|
||||
{93ECA06C-767E-4A4D-AC59-21F250381297}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{93ECA06C-767E-4A4D-AC59-21F250381297}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
@ -244,8 +215,6 @@ Global
|
|||
{4787A64F-9A3E-4867-A55A-70CB4B2B2FFE} = {04B1EDB6-E967-4D25-89B9-E6F8304038CD}
|
||||
{55494E58-E061-4C4C-A0A8-837008E72F85} = {04B1EDB6-E967-4D25-89B9-E6F8304038CD}
|
||||
{D57EA297-6DC2-4BC0-8C91-334863327863} = {04B1EDB6-E967-4D25-89B9-E6F8304038CD}
|
||||
{5F31656B-4990-44FE-9090-00E32D933376} = {EF30B533-D715-421A-92B7-92FEF460AC9C}
|
||||
{93ECA06C-767E-4A4D-AC59-21F250381297} = {EF30B533-D715-421A-92B7-92FEF460AC9C}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {DB4F868D-E1AE-4FD7-9333-69FA15B268C5}
|
||||
|
|
|
|||
|
|
@ -1,55 +0,0 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net461</TargetFramework>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
|
||||
<AssemblyName>AspNetCoreModule.Test</AssemblyName>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="_app._config" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="Http.config">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Testing" Version="$(MicrosoftAspNetCoreTestingPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(MicrosoftNETTestSdkPackageVersion)" />
|
||||
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="$(SystemRuntimeCompilerServicesUnsafePackageVersion)" />
|
||||
<PackageReference Include="xunit" Version="$(XunitPackageVersion)" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="$(XunitRunnerVisualstudioPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.Web.Administration" Version="$(MicrosoftWebAdministrationPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="$(MicrosoftExtensionsLoggingConsolePackageVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="$(MicrosoftExtensionsLoggingDebugPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="$(MicrosoftExtensionsLoggingPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.PlatformAbstractions" Version="$(MicrosoftExtensionsPlatformAbstractionsPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.Net.Http.Headers" Version="$(MicrosoftNetHttpHeadersPackageVersion)" />
|
||||
<PackageReference Include="System.Management.Automation" Version="$(SystemManagementAutomationPackageVersion)" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.IO.Compression.FileSystem" />
|
||||
<Reference Include="System.Management" />
|
||||
<Reference Include="System.Net.Http.WebRequest" />
|
||||
<Reference Include="System.Runtime" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Management" />
|
||||
<Reference Include="System.ServiceProcess" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Properties\" />
|
||||
<Folder Include="Properties\" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,513 +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 System.IO;
|
||||
using System.Threading;
|
||||
using Microsoft.Extensions.PlatformAbstractions;
|
||||
using System.Security.Principal;
|
||||
using System.Security.AccessControl;
|
||||
|
||||
namespace AspNetCoreModule.Test.Framework
|
||||
{
|
||||
public static class TestFlags
|
||||
{
|
||||
public const string SkipTest = "SkipTest";
|
||||
public const string UsePrivateANCM = "UsePrivateANCM";
|
||||
public const string UseIISExpress = "UseIISExpress";
|
||||
public const string UseFullIIS = "UseFullIIS";
|
||||
public const string RunAsAdministrator = "RunAsAdministrator";
|
||||
public const string MakeCertExeAvailable = "MakeCertExeAvailable";
|
||||
public const string WebSocketModuleAvailable = "WebSocketModuleAvailable";
|
||||
public const string UrlRewriteModuleAvailable = "UrlRewriteModuleAvailable";
|
||||
public const string X86Platform = "X86Platform";
|
||||
public const string Wow64BitMode = "Wow64BitMode";
|
||||
public const string RequireRunAsAdministrator = "RequireRunAsAdministrator";
|
||||
public const string Default = "Default";
|
||||
|
||||
public static bool Enabled(string flagValue)
|
||||
{
|
||||
return InitializeTestMachine.GlobalTestFlags.IndexOf(flagValue, StringComparison.OrdinalIgnoreCase) > -1;
|
||||
}
|
||||
}
|
||||
|
||||
public class InitializeTestMachine : IDisposable
|
||||
{
|
||||
public const string ANCMTestFlagsEnvironmentVariable = "%ANCMTestFlags%";
|
||||
|
||||
public static int SiteId = 40000;
|
||||
public const string PrivateFileName = "aspnetcore_private.dll";
|
||||
public static string FullIisAspnetcore_path = Path.Combine(Environment.ExpandEnvironmentVariables("%windir%"), "system32", "inetsrv", PrivateFileName);
|
||||
public static string FullIisAspnetcore_path_original = Path.Combine(Environment.ExpandEnvironmentVariables("%windir%"), "system32", "inetsrv", "aspnetcore.dll");
|
||||
public static string FullIisAspnetcore_X86_path = Path.Combine(Environment.ExpandEnvironmentVariables("%windir%"), "syswow64", "inetsrv", PrivateFileName);
|
||||
public static string IisExpressAspnetcore_path;
|
||||
public static string IisExpressAspnetcore_X86_path;
|
||||
|
||||
public static string IisExpressAspnetcoreSchema_path = Path.Combine(Environment.ExpandEnvironmentVariables("%ProgramFiles%"), "IIS Express", "config", "schema", "aspnetcore_schema.xml");
|
||||
public static string IisExpressAspnetcoreSchema_X86_path = Path.Combine(Environment.ExpandEnvironmentVariables("%ProgramFiles(x86)%"), "IIS Express", "config", "schema", "aspnetcore_schema.xml");
|
||||
public static string FullIisAspnetcoreSchema_path = Path.Combine(Environment.ExpandEnvironmentVariables("%windir%"), "system32", "inetsrv", "config", "schema", "aspnetcore_schema.xml");
|
||||
public static int _referenceCount = 0;
|
||||
private static bool _InitializeTestMachineCompleted = false;
|
||||
private string _setupScriptPath = null;
|
||||
|
||||
private static bool? _makeCertExeAvailable = null;
|
||||
public static bool MakeCertExeAvailable
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_makeCertExeAvailable == null)
|
||||
{
|
||||
_makeCertExeAvailable = false;
|
||||
try
|
||||
{
|
||||
string makecertExeFilePath = TestUtility.GetMakeCertPath();
|
||||
TestUtility.RunCommand(makecertExeFilePath, null, true, true);
|
||||
TestUtility.LogInformation("Verified makecert.exe is available : " + makecertExeFilePath);
|
||||
_makeCertExeAvailable = true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignore exception
|
||||
}
|
||||
}
|
||||
return (_makeCertExeAvailable == true);
|
||||
}
|
||||
}
|
||||
|
||||
public static string TestRootDirectory
|
||||
{
|
||||
get
|
||||
{
|
||||
return Path.Combine(Environment.ExpandEnvironmentVariables("%SystemDrive%") + @"\", "_ANCMTest");
|
||||
}
|
||||
}
|
||||
|
||||
private static string _globalTestFlags = null;
|
||||
public static string GlobalTestFlags
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_globalTestFlags == null)
|
||||
{
|
||||
WindowsPrincipal principal = new WindowsPrincipal(WindowsIdentity.GetCurrent());
|
||||
bool isElevated = principal.IsInRole(WindowsBuiltInRole.Administrator);
|
||||
|
||||
// check if this test process is started with the Run As Administrator start option
|
||||
_globalTestFlags = Environment.ExpandEnvironmentVariables(ANCMTestFlagsEnvironmentVariable);
|
||||
|
||||
//
|
||||
// Check if ANCMTestFlags environment is not defined and the test program was started
|
||||
// without using the Run As Administrator start option.
|
||||
// In that case, we have to use the default TestFlags of UseIISExpress and UsePrivateANCM
|
||||
//
|
||||
if (!isElevated)
|
||||
{
|
||||
if (_globalTestFlags.ToLower().Contains("%" + ANCMTestFlagsEnvironmentVariable.ToLower() + "%"))
|
||||
{
|
||||
_globalTestFlags = TestFlags.UsePrivateANCM + ";" + TestFlags.UseIISExpress;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// convert in lower case
|
||||
//
|
||||
_globalTestFlags = _globalTestFlags.ToLower();
|
||||
|
||||
//
|
||||
// error handling: UseIISExpress and UseFullIIS can be used together.
|
||||
//
|
||||
if (_globalTestFlags.Contains(TestFlags.UseIISExpress.ToLower()) && _globalTestFlags.Contains(TestFlags.UseFullIIS.ToLower()))
|
||||
{
|
||||
_globalTestFlags = _globalTestFlags.Replace(TestFlags.UseFullIIS.ToLower(), "");
|
||||
}
|
||||
|
||||
//
|
||||
// adjust the default test context in run time to figure out wrong test context values
|
||||
//
|
||||
if (isElevated)
|
||||
{
|
||||
// add RunAsAdministrator
|
||||
if (!_globalTestFlags.Contains(TestFlags.RunAsAdministrator.ToLower()))
|
||||
{
|
||||
TestUtility.LogInformation("Added test context of " + TestFlags.RunAsAdministrator);
|
||||
_globalTestFlags += ";" + TestFlags.RunAsAdministrator;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// add UseIISExpress
|
||||
if (!_globalTestFlags.Contains(TestFlags.UseIISExpress.ToLower()))
|
||||
{
|
||||
TestUtility.LogInformation("Added test context of " + TestFlags.UseIISExpress);
|
||||
_globalTestFlags += ";" + TestFlags.UseIISExpress;
|
||||
}
|
||||
|
||||
// remove UseFullIIS
|
||||
if (_globalTestFlags.Contains(TestFlags.UseFullIIS.ToLower()))
|
||||
{
|
||||
_globalTestFlags = _globalTestFlags.Replace(TestFlags.UseFullIIS.ToLower(), "");
|
||||
}
|
||||
|
||||
// remove RunAsAdmistrator
|
||||
if (_globalTestFlags.Contains(TestFlags.RunAsAdministrator.ToLower()))
|
||||
{
|
||||
_globalTestFlags = _globalTestFlags.Replace(TestFlags.RunAsAdministrator.ToLower(), "");
|
||||
}
|
||||
}
|
||||
|
||||
if (MakeCertExeAvailable)
|
||||
{
|
||||
// Add MakeCertExeAvailable
|
||||
if (!_globalTestFlags.Contains(TestFlags.MakeCertExeAvailable.ToLower()))
|
||||
{
|
||||
TestUtility.LogInformation("Added test context of " + TestFlags.MakeCertExeAvailable);
|
||||
_globalTestFlags += ";" + TestFlags.MakeCertExeAvailable;
|
||||
}
|
||||
}
|
||||
|
||||
if (!Environment.Is64BitOperatingSystem)
|
||||
{
|
||||
// Add X86Platform
|
||||
if (!_globalTestFlags.Contains(TestFlags.X86Platform.ToLower()))
|
||||
{
|
||||
TestUtility.LogInformation("Added test context of " + TestFlags.X86Platform);
|
||||
_globalTestFlags += ";" + TestFlags.X86Platform;
|
||||
}
|
||||
}
|
||||
|
||||
if (Environment.Is64BitOperatingSystem && !Environment.Is64BitProcess)
|
||||
{
|
||||
// Add Wow64bitMode
|
||||
if (!_globalTestFlags.Contains(TestFlags.Wow64BitMode.ToLower()))
|
||||
{
|
||||
TestUtility.LogInformation("Added test context of " + TestFlags.Wow64BitMode);
|
||||
_globalTestFlags += ";" + TestFlags.Wow64BitMode;
|
||||
}
|
||||
|
||||
// remove X86Platform
|
||||
if (_globalTestFlags.Contains(TestFlags.X86Platform.ToLower()))
|
||||
{
|
||||
_globalTestFlags = _globalTestFlags.Replace(TestFlags.X86Platform.ToLower(), "");
|
||||
}
|
||||
}
|
||||
|
||||
if (File.Exists(Path.Combine(IISConfigUtility.Strings.IIS64BitPath, "iiswsock.dll")))
|
||||
{
|
||||
// Add WebSocketModuleAvailable
|
||||
if (!_globalTestFlags.Contains(TestFlags.WebSocketModuleAvailable.ToLower()))
|
||||
{
|
||||
TestUtility.LogInformation("Added test context of " + TestFlags.WebSocketModuleAvailable);
|
||||
_globalTestFlags += ";" + TestFlags.WebSocketModuleAvailable;
|
||||
}
|
||||
}
|
||||
|
||||
if (File.Exists(Path.Combine(IISConfigUtility.Strings.IIS64BitPath, "rewrite.dll")))
|
||||
{
|
||||
// Add UrlRewriteModuleAvailable
|
||||
if (!_globalTestFlags.Contains(TestFlags.UrlRewriteModuleAvailable.ToLower()))
|
||||
{
|
||||
TestUtility.LogInformation("Added test context of " + TestFlags.UrlRewriteModuleAvailable);
|
||||
_globalTestFlags += ";" + TestFlags.UrlRewriteModuleAvailable;
|
||||
}
|
||||
}
|
||||
|
||||
_globalTestFlags = _globalTestFlags.ToLower();
|
||||
}
|
||||
|
||||
return _globalTestFlags;
|
||||
}
|
||||
}
|
||||
|
||||
public void InitializeIISServer()
|
||||
{
|
||||
// Check if IIS server is installed or not
|
||||
bool isIISInstalled = true;
|
||||
if (!File.Exists(Path.Combine(IISConfigUtility.Strings.IIS64BitPath, "iiscore.dll")))
|
||||
{
|
||||
isIISInstalled = false;
|
||||
}
|
||||
|
||||
if (!File.Exists(Path.Combine(IISConfigUtility.Strings.IIS64BitPath, "config", "applicationhost.config")))
|
||||
{
|
||||
isIISInstalled = false;
|
||||
}
|
||||
|
||||
if (!isIISInstalled)
|
||||
{
|
||||
throw new ApplicationException("IIS server is not installed");
|
||||
}
|
||||
|
||||
// Clean up IIS worker process
|
||||
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 ApplicationException("WWW service can't start");
|
||||
}
|
||||
|
||||
if (IISConfigUtility.ApppHostTemporaryBackupFileExtention == null)
|
||||
{
|
||||
throw new ApplicationException("Failed to backup applicationhost.config");
|
||||
}
|
||||
}
|
||||
|
||||
public InitializeTestMachine()
|
||||
{
|
||||
_referenceCount++;
|
||||
|
||||
// This method should be called only one time
|
||||
if (_referenceCount == 1)
|
||||
{
|
||||
TestUtility.LogInformation("InitializeTestMachine::InitializeTestMachine() Start");
|
||||
|
||||
_InitializeTestMachineCompleted = false;
|
||||
|
||||
TestUtility.LogInformation("InitializeTestMachine::Start");
|
||||
if (Environment.ExpandEnvironmentVariables("%ANCMTEST_DEBUG%").ToLower() == "true")
|
||||
{
|
||||
System.Diagnostics.Debugger.Launch();
|
||||
}
|
||||
|
||||
//
|
||||
// Clean up IISExpress processes
|
||||
//
|
||||
TestUtility.ResetHelper(ResetHelperMode.KillIISExpress);
|
||||
|
||||
//
|
||||
// Initalize IIS server
|
||||
//
|
||||
|
||||
if (TestFlags.Enabled(TestFlags.UseFullIIS))
|
||||
{
|
||||
InitializeIISServer();
|
||||
}
|
||||
|
||||
string siteRootPath = TestRootDirectory;
|
||||
if (!Directory.Exists(siteRootPath))
|
||||
{
|
||||
//
|
||||
// Create a new directory and set the write permission for the SID of AuthenticatedUser
|
||||
//
|
||||
Directory.CreateDirectory(siteRootPath);
|
||||
DirectorySecurity sec = Directory.GetAccessControl(siteRootPath);
|
||||
SecurityIdentifier authenticatedUser = new SecurityIdentifier(WellKnownSidType.AuthenticatedUserSid, null);
|
||||
sec.AddAccessRule(new FileSystemAccessRule(authenticatedUser, FileSystemRights.Modify | FileSystemRights.Synchronize, InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, PropagationFlags.None, AccessControlType.Allow));
|
||||
Directory.SetAccessControl(siteRootPath, sec);
|
||||
}
|
||||
|
||||
foreach (string directory in Directory.GetDirectories(siteRootPath))
|
||||
{
|
||||
bool successDeleteChildDirectory = true;
|
||||
try
|
||||
{
|
||||
TestUtility.DeleteDirectory(directory);
|
||||
}
|
||||
catch
|
||||
{
|
||||
successDeleteChildDirectory = false;
|
||||
TestUtility.LogInformation("Failed to delete " + directory);
|
||||
}
|
||||
if (successDeleteChildDirectory)
|
||||
{
|
||||
try
|
||||
{
|
||||
TestUtility.DeleteDirectory(siteRootPath);
|
||||
}
|
||||
catch
|
||||
{
|
||||
TestUtility.LogInformation("Failed to delete " + siteRootPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Intialize Private ANCM files for Full IIS server or IISExpress
|
||||
//
|
||||
if (TestFlags.Enabled(TestFlags.UsePrivateANCM))
|
||||
{
|
||||
PreparePrivateANCMFiles();
|
||||
}
|
||||
|
||||
_InitializeTestMachineCompleted = true;
|
||||
TestUtility.LogInformation("InitializeTestMachine::InitializeTestMachine() End");
|
||||
}
|
||||
|
||||
for (int i=0; i<120; i++)
|
||||
{
|
||||
if (_InitializeTestMachineCompleted)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
TestUtility.LogInformation("InitializeTestMachine::InitializeTestMachine() Waiting...");
|
||||
Thread.Sleep(500);
|
||||
}
|
||||
}
|
||||
if (!_InitializeTestMachineCompleted)
|
||||
{
|
||||
throw new ApplicationException("InitializeTestMachine failed");
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_referenceCount--;
|
||||
|
||||
if (_referenceCount == 0)
|
||||
{
|
||||
TestUtility.LogInformation("InitializeTestMachine::Dispose() Start");
|
||||
TestUtility.ResetHelper(ResetHelperMode.KillIISExpress);
|
||||
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 release build
|
||||
outputPath = Path.Combine(solutionRoot, "artifacts", "build", "AspNetCore", "bin", "Release");
|
||||
|
||||
// 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", "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; check if there is any build issue!!!");
|
||||
}
|
||||
|
||||
//
|
||||
// NOTE:
|
||||
// ANCM schema file can't be overwritten here
|
||||
// If there is any schema change, that should be updated with installing setup or manually copied with the new schema file.
|
||||
//
|
||||
|
||||
if (TestFlags.Enabled(TestFlags.UseIISExpress))
|
||||
{
|
||||
//
|
||||
// Initialize 32 bit IisExpressAspnetcore_path
|
||||
//
|
||||
IisExpressAspnetcore_path = Path.Combine(outputPath, "x64", "aspnetcore.dll");
|
||||
IisExpressAspnetcore_X86_path = Path.Combine(outputPath, "Win32", "aspnetcore.dll");
|
||||
}
|
||||
else // if use Full IIS server
|
||||
{
|
||||
bool updateSuccess = false;
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
updateSuccess = false;
|
||||
try
|
||||
{
|
||||
TestUtility.ResetHelper(ResetHelperMode.KillWorkerProcess);
|
||||
TestUtility.ResetHelper(ResetHelperMode.StopW3svcStartW3svc);
|
||||
Thread.Sleep(1000);
|
||||
|
||||
// Copy private file on Inetsrv directory
|
||||
TestUtility.FileCopy(Path.Combine(outputPath, "x64", "aspnetcore.dll"), FullIisAspnetcore_path, overWrite: true, ignoreExceptionWhileDeletingExistingFile: false);
|
||||
|
||||
if (TestUtility.IsOSAmd64)
|
||||
{
|
||||
|
||||
// Copy 32bit private file on Inetsrv directory
|
||||
TestUtility.FileCopy(Path.Combine(outputPath, "Win32", "aspnetcore.dll"), FullIisAspnetcore_X86_path, overWrite: true, ignoreExceptionWhileDeletingExistingFile: false);
|
||||
}
|
||||
updateSuccess = true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
updateSuccess = false;
|
||||
}
|
||||
if (updateSuccess)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!updateSuccess)
|
||||
{
|
||||
throw new ApplicationException("Failed to update aspnetcore.dll");
|
||||
}
|
||||
|
||||
// update applicationhost.config for IIS server with the new private ASPNET Core file name
|
||||
if (TestFlags.Enabled(TestFlags.UseFullIIS))
|
||||
{
|
||||
using (var iisConfig = new IISConfigUtility(ServerType.IIS, null))
|
||||
{
|
||||
iisConfig.AddModule("AspNetCoreModule", FullIisAspnetcore_path, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetSolutionDirectory()
|
||||
{
|
||||
var applicationBasePath = PlatformServices.Default.Application.ApplicationBasePath;
|
||||
var directoryInfo = new DirectoryInfo(applicationBasePath);
|
||||
do
|
||||
{
|
||||
var solutionFile = new FileInfo(Path.Combine(directoryInfo.FullName, "AspNetCoreModule.sln"));
|
||||
if (solutionFile.Exists)
|
||||
{
|
||||
return directoryInfo.FullName;
|
||||
}
|
||||
|
||||
directoryInfo = directoryInfo.Parent;
|
||||
}
|
||||
while (directoryInfo.Parent != null);
|
||||
|
||||
throw new Exception($"Solution root could not be located using application root {applicationBasePath}.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,966 +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 System.Text;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using System.Management;
|
||||
using System.Threading;
|
||||
using System.Diagnostics;
|
||||
using Microsoft.Extensions.PlatformAbstractions;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Principal;
|
||||
using System.Security.AccessControl;
|
||||
using System.Management.Automation.Runspaces;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using System.Net;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Management.Automation;
|
||||
|
||||
namespace AspNetCoreModule.Test.Framework
|
||||
{
|
||||
public enum ResetHelperMode
|
||||
{
|
||||
CallIISReset,
|
||||
StopHttpStartW3svc,
|
||||
StopWasStartW3svc,
|
||||
StopW3svcStartW3svc,
|
||||
KillWorkerProcess,
|
||||
KillVSJitDebugger,
|
||||
KillIISExpress
|
||||
}
|
||||
|
||||
public enum ServerType
|
||||
{
|
||||
IISExpress = 0,
|
||||
IIS = 1,
|
||||
}
|
||||
|
||||
public class TestUtility
|
||||
{
|
||||
public static ILogger _logger = null;
|
||||
|
||||
public static ILogger Logger
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_logger == null)
|
||||
{
|
||||
_logger = new LoggerFactory()
|
||||
.AddConsole()
|
||||
.CreateLogger("TestUtility");
|
||||
}
|
||||
return _logger;
|
||||
}
|
||||
}
|
||||
|
||||
public TestUtility(ILogger logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retries every 1 sec for 60 times by default.
|
||||
/// </summary>
|
||||
/// <param name="retryBlock"></param>
|
||||
/// <param name="logger"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <param name="retryCount"></param>
|
||||
public static async Task<HttpResponseMessage> RetryRequest(
|
||||
Func<Task<HttpResponseMessage>> retryBlock,
|
||||
ILogger logger,
|
||||
CancellationToken cancellationToken = default(CancellationToken),
|
||||
int retryCount = 60)
|
||||
{
|
||||
for (var retry = 0; retry < retryCount; retry++)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
logger.LogInformation("Failed to connect, retry canceled.");
|
||||
throw new OperationCanceledException("Failed to connect, retry canceled.", cancellationToken);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
logger.LogWarning("Retry count {retryCount}..", retry + 1);
|
||||
var response = await retryBlock().ConfigureAwait(false);
|
||||
|
||||
if (response.StatusCode == HttpStatusCode.ServiceUnavailable)
|
||||
{
|
||||
// Automatically retry on 503. May be application is still booting.
|
||||
logger.LogWarning("Retrying a service unavailable error.");
|
||||
continue;
|
||||
}
|
||||
|
||||
return response; // Went through successfully
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
if (retry == retryCount - 1)
|
||||
{
|
||||
logger.LogError(0, exception, "Failed to connect, retry limit exceeded.");
|
||||
throw;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (exception is HttpRequestException
|
||||
#if NET451
|
||||
|| exception is System.Net.WebException
|
||||
#endif
|
||||
)
|
||||
{
|
||||
logger.LogWarning("Failed to complete the request : {0}.", exception.Message);
|
||||
await Task.Delay(1 * 1000); //Wait for a while before retry.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
logger.LogInformation("Failed to connect, retry limit exceeded.");
|
||||
throw new OperationCanceledException("Failed to connect, retry limit exceeded.");
|
||||
}
|
||||
|
||||
public static void RetryOperation(
|
||||
Action retryBlock,
|
||||
Action<Exception> exceptionBlock,
|
||||
int retryCount = 3,
|
||||
int retryDelayMilliseconds = 0)
|
||||
{
|
||||
for (var retry = 0; retry < retryCount; ++retry)
|
||||
{
|
||||
try
|
||||
{
|
||||
retryBlock();
|
||||
break;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
exceptionBlock(exception);
|
||||
}
|
||||
|
||||
Thread.Sleep(retryDelayMilliseconds);
|
||||
}
|
||||
}
|
||||
|
||||
public static bool RetryHelper<T> (
|
||||
Func<T, bool> verifier,
|
||||
T arg,
|
||||
Action<Exception> exceptionBlock = null,
|
||||
int retryCount = 3,
|
||||
int retryDelayMilliseconds = 1000
|
||||
)
|
||||
{
|
||||
for (var retry = 0; retry < retryCount; ++retry)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (verifier(arg))
|
||||
return true;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
exceptionBlock?.Invoke(exception);
|
||||
}
|
||||
Thread.Sleep(retryDelayMilliseconds);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool RetryHelper<T1, T2>(
|
||||
Func<T1, T2, bool> verifier,
|
||||
T1 arg1,
|
||||
T2 arg2,
|
||||
Action<Exception> exceptionBlock = null,
|
||||
int retryCount = 3,
|
||||
int retryDelayMilliseconds = 1000
|
||||
)
|
||||
{
|
||||
for (var retry = 0; retry < retryCount; ++retry)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (verifier(arg1, arg2))
|
||||
return true;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
exceptionBlock?.Invoke(exception);
|
||||
}
|
||||
Thread.Sleep(retryDelayMilliseconds);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool RetryHelper<T1, T2, T3>(
|
||||
Func<T1, T2, T3, bool> verifier,
|
||||
T1 arg1,
|
||||
T2 arg2,
|
||||
T3 arg3,
|
||||
Action<Exception> exceptionBlock = null,
|
||||
int retryCount = 3,
|
||||
int retryDelayMilliseconds = 1000
|
||||
)
|
||||
{
|
||||
for (var retry = 0; retry < retryCount; ++retry)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (verifier(arg1, arg2, arg3))
|
||||
return true;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
exceptionBlock?.Invoke(exception);
|
||||
}
|
||||
LogInformation("ANCMTEST::RetryHelper Retrying " + retry);
|
||||
Thread.Sleep(retryDelayMilliseconds);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void GiveWritePermissionTo(string folder, SecurityIdentifier sid)
|
||||
{
|
||||
DirectorySecurity fsecurity = Directory.GetAccessControl(folder);
|
||||
FileSystemAccessRule writerule = new FileSystemAccessRule(sid, FileSystemRights.Write, AccessControlType.Allow);
|
||||
fsecurity.AddAccessRule(writerule);
|
||||
Directory.SetAccessControl(folder, fsecurity);
|
||||
Thread.Sleep(500);
|
||||
}
|
||||
|
||||
public static bool IsOSAmd64
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Environment.ExpandEnvironmentVariables("%PROCESSOR_ARCHITECTURE%") == "AMD64")
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void LogTrace(string format, params object[] parameters)
|
||||
{
|
||||
if (format != null)
|
||||
{
|
||||
Logger.LogTrace(format, parameters);
|
||||
}
|
||||
}
|
||||
public static void LogError(string format, params object[] parameters)
|
||||
{
|
||||
if (format != null)
|
||||
{
|
||||
Logger.LogError(format, parameters);
|
||||
}
|
||||
}
|
||||
public static void LogInformation(string format, params object[] parameters)
|
||||
{
|
||||
if (format != null)
|
||||
{
|
||||
Logger.LogInformation(format, parameters);
|
||||
}
|
||||
}
|
||||
|
||||
public static void DeleteFile(string filePath)
|
||||
{
|
||||
if (File.Exists(filePath))
|
||||
{
|
||||
RunCommand("cmd.exe", "/c del \"" + filePath + "\"");
|
||||
}
|
||||
if (File.Exists(filePath))
|
||||
{
|
||||
throw new ApplicationException("Failed to delete file: " + filePath);
|
||||
}
|
||||
}
|
||||
|
||||
public static void FileMove(string from, string to, bool overWrite = true)
|
||||
{
|
||||
if (overWrite)
|
||||
{
|
||||
DeleteFile(to);
|
||||
}
|
||||
if (File.Exists(from))
|
||||
{
|
||||
if (File.Exists(to) && !overWrite)
|
||||
{
|
||||
return;
|
||||
}
|
||||
File.Move(from, to);
|
||||
if (!File.Exists(to))
|
||||
{
|
||||
throw new ApplicationException("Failed to rename from : " + from + ", to : " + to);
|
||||
}
|
||||
if (File.Exists(from))
|
||||
{
|
||||
throw new ApplicationException("Failed to rename from : " + from + ", to : " + to);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ApplicationException("File not found " + from);
|
||||
}
|
||||
}
|
||||
|
||||
public static void FileCopy(string from, string to, bool overWrite = true, bool ignoreExceptionWhileDeletingExistingFile = false)
|
||||
{
|
||||
if (overWrite)
|
||||
{
|
||||
try
|
||||
{
|
||||
DeleteFile(to);
|
||||
}
|
||||
catch
|
||||
{
|
||||
if (!ignoreExceptionWhileDeletingExistingFile)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (File.Exists(from))
|
||||
{
|
||||
if (File.Exists(to) && !overWrite)
|
||||
{
|
||||
return;
|
||||
}
|
||||
RunCommand("cmd.exe", "/c copy /y \"" + from + "\" \"" + to + "\"");
|
||||
|
||||
if (!File.Exists(to))
|
||||
{
|
||||
throw new ApplicationException("Failed to move from : " + from + ", to : " + to);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LogError("File not found " + from);
|
||||
}
|
||||
}
|
||||
|
||||
public static void DeleteDirectory(string directoryPath)
|
||||
{
|
||||
if (Directory.Exists(directoryPath))
|
||||
{
|
||||
RunCommand("cmd.exe", "/c rd \"" + directoryPath + "\" /s /q");
|
||||
}
|
||||
if (Directory.Exists(directoryPath))
|
||||
{
|
||||
throw new ApplicationException("Failed to delete directory: " + directoryPath);
|
||||
}
|
||||
}
|
||||
|
||||
public static void CreateDirectory(string directoryPath)
|
||||
{
|
||||
if (!Directory.Exists(directoryPath))
|
||||
{
|
||||
RunCommand("cmd.exe", "/c md \"" + directoryPath + "\"");
|
||||
}
|
||||
if (!Directory.Exists(directoryPath))
|
||||
{
|
||||
throw new ApplicationException("Failed to create directory: " + directoryPath);
|
||||
}
|
||||
}
|
||||
|
||||
public static void DirectoryCopy(string from, string to)
|
||||
{
|
||||
if (Directory.Exists(to))
|
||||
{
|
||||
DeleteDirectory(to);
|
||||
}
|
||||
|
||||
if (!Directory.Exists(to))
|
||||
{
|
||||
CreateDirectory(to);
|
||||
}
|
||||
|
||||
if (Directory.Exists(from))
|
||||
{
|
||||
RunCommand("cmd.exe", "/c xcopy \"" + from + "\" \"" + to + "\" /s");
|
||||
}
|
||||
else
|
||||
{
|
||||
TestUtility.LogInformation("Directory not found " + from);
|
||||
}
|
||||
}
|
||||
|
||||
public static string FileReadAllText(string file)
|
||||
{
|
||||
string result = null;
|
||||
if (File.Exists(file))
|
||||
{
|
||||
result = File.ReadAllText(file);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void CreateFile(string file, string[] stringArray)
|
||||
{
|
||||
DeleteFile(file);
|
||||
using (StreamWriter sw = new StreamWriter(file))
|
||||
{
|
||||
foreach (string line in stringArray)
|
||||
{
|
||||
sw.WriteLine(line);
|
||||
}
|
||||
}
|
||||
|
||||
if (!File.Exists(file))
|
||||
{
|
||||
throw new ApplicationException("Failed to create " + file);
|
||||
}
|
||||
}
|
||||
|
||||
public static void KillProcess(string processFileName)
|
||||
{
|
||||
string query = "Select * from Win32_Process Where Name = \"" + processFileName + "\"";
|
||||
ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
|
||||
ManagementObjectCollection processList = searcher.Get();
|
||||
foreach (ManagementObject obj in processList)
|
||||
{
|
||||
obj.InvokeMethod("Terminate", null);
|
||||
}
|
||||
Thread.Sleep(1000);
|
||||
|
||||
processList = searcher.Get();
|
||||
if (processList.Count > 0)
|
||||
{
|
||||
TestUtility.LogInformation("Failed to kill process " + processFileName);
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetMakeCertPath()
|
||||
{
|
||||
string makecertExeFilePath = "makecert.exe";
|
||||
var makecertExeFilePaths = new Dictionary<string, string>();
|
||||
makecertExeFilePaths.Add("default", Path.Combine(Environment.ExpandEnvironmentVariables("%ProgramFiles%"), "Windows Kits"));
|
||||
if (IsOSAmd64)
|
||||
{
|
||||
makecertExeFilePaths.Add("wow64mode", Path.Combine(Environment.ExpandEnvironmentVariables("%ProgramFiles(x86)%"), "Windows Kits"));
|
||||
}
|
||||
|
||||
foreach (var item in makecertExeFilePaths)
|
||||
{
|
||||
string[] files = null;
|
||||
if (!Directory.Exists(item.Value))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
files = Directory.GetFiles(item.Value, "makecert.exe", SearchOption.AllDirectories);
|
||||
|
||||
foreach (string makecert in files)
|
||||
{
|
||||
if (makecert.Contains("arm"))
|
||||
{
|
||||
// arm process version is skipped here
|
||||
continue;
|
||||
}
|
||||
makecertExeFilePath = makecert;
|
||||
try
|
||||
{
|
||||
TestUtility.RunCommand(makecertExeFilePath, null, true, true);
|
||||
}
|
||||
catch
|
||||
{
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return makecertExeFilePath;
|
||||
}
|
||||
|
||||
public static int GetNumberOfProcess(string processFileName, int expectedNumber = 1, int retry = 0)
|
||||
{
|
||||
int result = 0;
|
||||
string query = "Select * from Win32_Process Where Name = \"" + processFileName + "\"";
|
||||
ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
|
||||
ManagementObjectCollection processList = searcher.Get();
|
||||
result = processList.Count;
|
||||
for (int i = 0; i < retry; i++)
|
||||
{
|
||||
if (result == expectedNumber)
|
||||
{
|
||||
break;
|
||||
}
|
||||
Thread.Sleep(1000);
|
||||
processList = searcher.Get();
|
||||
result = processList.Count;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static object GetProcessWMIAttributeValue(string processFileName, string attributeName, string owner = null)
|
||||
{
|
||||
string query = "Select * from Win32_Process Where Name = \"" + processFileName + "\"";
|
||||
ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
|
||||
ManagementObjectCollection processList = searcher.Get();
|
||||
object result = null;
|
||||
foreach (ManagementObject obj in processList)
|
||||
{
|
||||
string[] argList = new string[] { string.Empty, string.Empty };
|
||||
bool found = true;
|
||||
|
||||
if (owner != null)
|
||||
{
|
||||
found = false;
|
||||
int returnVal = Convert.ToInt32(obj.InvokeMethod("GetOwner", argList));
|
||||
if (returnVal == 0)
|
||||
{
|
||||
if (argList[0].ToUpper() == owner.ToUpper())
|
||||
{
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (found)
|
||||
{
|
||||
result = obj.GetPropertyValue(attributeName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static string GetHttpUri(string Url, TestWebSite siteContext)
|
||||
{
|
||||
string tempUrl = Url.TrimStart(new char[] { '/' });
|
||||
return "http://" + siteContext.HostName + ":" + siteContext.TcpPort + "/" + tempUrl;
|
||||
}
|
||||
|
||||
public static string XmlParser(string xmlFileContent, string elementName, string attributeName, string childkeyValue)
|
||||
{
|
||||
string result = string.Empty;
|
||||
|
||||
XmlDocument serviceStateXml = new XmlDocument();
|
||||
serviceStateXml.LoadXml(xmlFileContent);
|
||||
|
||||
XmlNodeList elements = serviceStateXml.GetElementsByTagName(elementName);
|
||||
foreach (XmlNode item in elements)
|
||||
{
|
||||
if (childkeyValue == null)
|
||||
{
|
||||
if (item.Attributes[attributeName].Value != null)
|
||||
{
|
||||
string newValueFound = item.Attributes[attributeName].Value;
|
||||
if (result != string.Empty)
|
||||
{
|
||||
newValueFound += "," + newValueFound; // make the result value in comma seperated format if there are multiple nodes
|
||||
}
|
||||
result += newValueFound;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//int groupIndex = 0;
|
||||
foreach (XmlNode groupNode in item.ChildNodes)
|
||||
{
|
||||
/*UrlGroup urlGroup = new UrlGroup();
|
||||
urlGroup._requestQueue = requestQueue._requestQueueName;
|
||||
urlGroup._urlGroupId = groupIndex.ToString();
|
||||
|
||||
foreach (XmlNode urlNode in groupNode)
|
||||
urlGroup._urls.Add(urlNode.InnerText.ToUpper());
|
||||
|
||||
requestQueue._urlGroupIds.Add(groupIndex);
|
||||
requestQueue._urlGroups.Add(urlGroup);
|
||||
groupIndex++; */
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static string RandomString(long size)
|
||||
{
|
||||
var random = new Random((int)DateTime.Now.Ticks);
|
||||
|
||||
var builder = new StringBuilder();
|
||||
char ch;
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65)));
|
||||
builder.Append(ch);
|
||||
}
|
||||
|
||||
return builder.ToString();
|
||||
}
|
||||
|
||||
public static bool ResetHelper(ResetHelperMode mode)
|
||||
{
|
||||
bool result = false;
|
||||
switch (mode)
|
||||
{
|
||||
case ResetHelperMode.CallIISReset:
|
||||
result = CallIISReset();
|
||||
break;
|
||||
case ResetHelperMode.StopHttpStartW3svc:
|
||||
StopHttp();
|
||||
result = StartW3svc();
|
||||
break;
|
||||
case ResetHelperMode.StopWasStartW3svc:
|
||||
StopWas();
|
||||
result = StartW3svc();
|
||||
break;
|
||||
case ResetHelperMode.StopW3svcStartW3svc:
|
||||
StopW3svc();
|
||||
result = StartW3svc();
|
||||
break;
|
||||
case ResetHelperMode.KillWorkerProcess:
|
||||
result = KillWorkerProcess();
|
||||
break;
|
||||
case ResetHelperMode.KillVSJitDebugger:
|
||||
result = KillVSJitDebugger();
|
||||
break;
|
||||
case ResetHelperMode.KillIISExpress:
|
||||
result = KillIISExpress();
|
||||
break;
|
||||
};
|
||||
return result;
|
||||
}
|
||||
|
||||
public static bool KillIISExpress()
|
||||
{
|
||||
bool result = false;
|
||||
string query = "Select * from Win32_Process Where Name = \"iisexpress.exe\"";
|
||||
ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
|
||||
ManagementObjectCollection processList = searcher.Get();
|
||||
|
||||
foreach (ManagementObject obj in processList)
|
||||
{
|
||||
string[] argList = new string[] { string.Empty, string.Empty };
|
||||
bool foundProcess = true;
|
||||
if (foundProcess)
|
||||
{
|
||||
obj.InvokeMethod("Terminate", null);
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static bool KillVSJitDebugger()
|
||||
{
|
||||
bool result = false;
|
||||
string query = "Select * from Win32_Process Where Name = \"vsjitdebugger.exe\"";
|
||||
ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
|
||||
ManagementObjectCollection processList = searcher.Get();
|
||||
|
||||
foreach (ManagementObject obj in processList)
|
||||
{
|
||||
string[] argList = new string[] { string.Empty, string.Empty };
|
||||
bool foundProcess = true;
|
||||
if (foundProcess)
|
||||
{
|
||||
LogError("Jit Debugger found");
|
||||
obj.InvokeMethod("Terminate", null);
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static bool KillWorkerProcess(string owner = null)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
string query = "Select * from Win32_Process Where Name = \"w3wp.exe\"";
|
||||
ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
|
||||
ManagementObjectCollection processList = searcher.Get();
|
||||
|
||||
foreach (ManagementObject obj in processList)
|
||||
{
|
||||
if (owner != null)
|
||||
{
|
||||
string[] argList = new string[] { string.Empty, string.Empty };
|
||||
int returnVal = Convert.ToInt32(obj.InvokeMethod("GetOwner", argList));
|
||||
if (returnVal == 0)
|
||||
{
|
||||
bool foundProcess = true;
|
||||
|
||||
if (String.Compare(argList[0], owner, true) != 0)
|
||||
{
|
||||
foundProcess = false;
|
||||
}
|
||||
if (foundProcess)
|
||||
{
|
||||
obj.InvokeMethod("Terminate", null);
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
obj.InvokeMethod("Terminate", null);
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static bool KillIISExpressProcess(string owner = null)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
string query = "Select * from Win32_Process Where Name = \"iisexpress.exe\"";
|
||||
ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
|
||||
ManagementObjectCollection processList = searcher.Get();
|
||||
|
||||
foreach (ManagementObject obj in processList)
|
||||
{
|
||||
if (owner != null)
|
||||
{
|
||||
string[] argList = new string[] { string.Empty, string.Empty };
|
||||
int returnVal = Convert.ToInt32(obj.InvokeMethod("GetOwner", argList));
|
||||
if (returnVal == 0)
|
||||
{
|
||||
bool foundProcess = true;
|
||||
|
||||
if (String.Compare(argList[0], owner, true) != 0)
|
||||
{
|
||||
foundProcess = false;
|
||||
}
|
||||
if (foundProcess)
|
||||
{
|
||||
obj.InvokeMethod("Terminate", null);
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
obj.InvokeMethod("Terminate", null);
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static string RunPowershellScript(string scriptText)
|
||||
{
|
||||
IPEndPoint a = new IPEndPoint(0, 443);
|
||||
|
||||
// create Powershell runspace
|
||||
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();
|
||||
|
||||
// create a pipeline and feed it the script text
|
||||
Pipeline pipeline = runspace.CreatePipeline();
|
||||
pipeline.Commands.AddScript(scriptText);
|
||||
|
||||
// add an extra command to transform the script output objects into nicely formatted strings
|
||||
// remove this line to get the actual objects that the script returns. For example, the script
|
||||
// "Get-Process" returns a collection of System.Diagnostics.Process instances.
|
||||
pipeline.Commands.Add("Out-String");
|
||||
Collection<PSObject> results = null;
|
||||
try
|
||||
{
|
||||
// execute the script
|
||||
results = pipeline.Invoke();
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
throw new Exception("Failed to run " + scriptText + " " + ex.ToString());
|
||||
}
|
||||
|
||||
// close the runspace
|
||||
runspace.Close();
|
||||
|
||||
// convert the script result into a single string
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
foreach (PSObject obj in results)
|
||||
{
|
||||
stringBuilder.AppendLine(obj.ToString());
|
||||
}
|
||||
|
||||
return stringBuilder.ToString().Trim(new char[] { ' ', '\r', '\n' });
|
||||
}
|
||||
|
||||
public static void RunPowershellScript(string scriptText, string expectedResult, int retryCount = 3)
|
||||
{
|
||||
bool isReady = false;
|
||||
string result = string.Empty;
|
||||
|
||||
for (int i = 0; i < retryCount; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
result = TestUtility.RunPowershellScript(scriptText);
|
||||
}
|
||||
catch
|
||||
{
|
||||
result = "ExceptionError";
|
||||
}
|
||||
|
||||
if (expectedResult != null)
|
||||
{
|
||||
if (expectedResult == result)
|
||||
{
|
||||
isReady = true;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.Threading.Thread.Sleep(1000);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
isReady = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isReady)
|
||||
{
|
||||
throw new ApplicationException("Failed to execute command: " + scriptText + ", expected result: " + expectedResult + ", actual result = " + result);
|
||||
}
|
||||
}
|
||||
|
||||
public static int RunCommand(string fileName, string arguments = null, bool checkStandardError = true, bool waitForExit=true)
|
||||
{
|
||||
int pid = -1;
|
||||
Process p = new Process();
|
||||
p.StartInfo.FileName = fileName;
|
||||
if (arguments != null)
|
||||
{
|
||||
p.StartInfo.Arguments = arguments;
|
||||
}
|
||||
|
||||
if (waitForExit)
|
||||
{
|
||||
p.StartInfo.RedirectStandardOutput = true;
|
||||
p.StartInfo.RedirectStandardError = true;
|
||||
}
|
||||
|
||||
p.StartInfo.UseShellExecute = false;
|
||||
p.StartInfo.CreateNoWindow = true;
|
||||
p.Start();
|
||||
pid = p.Id;
|
||||
string standardOutput = string.Empty;
|
||||
string standardError = string.Empty;
|
||||
if (waitForExit)
|
||||
{
|
||||
standardOutput = p.StandardOutput.ReadToEnd();
|
||||
standardError = p.StandardError.ReadToEnd();
|
||||
p.WaitForExit();
|
||||
}
|
||||
if (checkStandardError && standardError != string.Empty)
|
||||
{
|
||||
throw new Exception("Failed to run " + fileName + " " + arguments + ", Error: " + standardError + ", StandardOutput: " + standardOutput);
|
||||
}
|
||||
return pid;
|
||||
}
|
||||
|
||||
public static bool CallIISReset()
|
||||
{
|
||||
int result = RunCommand("iisreset", null, false);
|
||||
return (result != -1);
|
||||
}
|
||||
|
||||
public static bool StopHttp()
|
||||
{
|
||||
int result = RunCommand("net", "stop http /y", false);
|
||||
return (result != -1);
|
||||
}
|
||||
|
||||
public static bool StopWas()
|
||||
{
|
||||
int result = RunCommand("net", "stop was /y", false);
|
||||
return (result != -1);
|
||||
}
|
||||
|
||||
public static bool StartWas()
|
||||
{
|
||||
int result = RunCommand("net", "start was", false);
|
||||
return (result != -1);
|
||||
}
|
||||
|
||||
public static bool StopW3svc()
|
||||
{
|
||||
int result = RunCommand("net", "stop w3svc /y", false);
|
||||
return (result != -1);
|
||||
}
|
||||
|
||||
public static bool StartW3svc()
|
||||
{
|
||||
int result = RunCommand("net", "start w3svc", false);
|
||||
return (result != -1);
|
||||
}
|
||||
|
||||
public static string GetApplicationPath()
|
||||
{
|
||||
var applicationBasePath = PlatformServices.Default.Application.ApplicationBasePath;
|
||||
string solutionPath = InitializeTestMachine.GetSolutionDirectory();
|
||||
string applicationPath = string.Empty;
|
||||
applicationPath = Path.Combine(solutionPath, "test", "AspNetCoreModule.TestSites.Standard");
|
||||
return applicationPath;
|
||||
}
|
||||
|
||||
public static string GetConfigContent(ServerType serverType, string iisConfig)
|
||||
{
|
||||
string content = null;
|
||||
if (serverType == ServerType.IISExpress)
|
||||
{
|
||||
content = File.ReadAllText(iisConfig);
|
||||
}
|
||||
return content;
|
||||
}
|
||||
|
||||
public static void ClearApplicationEventLog()
|
||||
{
|
||||
using (EventLog eventLog = new EventLog("Application"))
|
||||
{
|
||||
eventLog.Clear();
|
||||
}
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
TestUtility.LogInformation("Waiting 1 seconds for eventlog to clear...");
|
||||
Thread.Sleep(1000);
|
||||
EventLog systemLog = new EventLog("Application");
|
||||
if (systemLog.Entries.Count == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static List<String> GetApplicationEvent(int id, DateTime startFrom)
|
||||
{
|
||||
var result = new List<String>();
|
||||
TestUtility.LogInformation("Waiting 1 seconds for eventlog to update...");
|
||||
Thread.Sleep(1000);
|
||||
EventLog systemLog = new EventLog("Application");
|
||||
foreach (EventLogEntry entry in systemLog.Entries)
|
||||
{
|
||||
if (entry.InstanceId == id && entry.TimeWritten >= startFrom)
|
||||
{
|
||||
result.Add(entry.ReplacementStrings[0]);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static string ConvertToPunycode(string domain)
|
||||
{
|
||||
Uri uri = new Uri("http://" + domain);
|
||||
return uri.DnsSafeHost;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,243 +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 System.IO;
|
||||
|
||||
namespace AspNetCoreModule.Test.Framework
|
||||
{
|
||||
public class TestWebApplication : IDisposable
|
||||
{
|
||||
private TestWebSite _testSite;
|
||||
public TestWebSite TestSite
|
||||
{
|
||||
get
|
||||
{
|
||||
return _testSite;
|
||||
}
|
||||
set
|
||||
{
|
||||
_testSite = value;
|
||||
}
|
||||
}
|
||||
|
||||
public TestWebApplication(string name, string physicalPath, string url = null)
|
||||
: this(name, physicalPath, null, url)
|
||||
{
|
||||
}
|
||||
|
||||
public TestWebApplication(string name, string physicalPath, TestWebSite siteContext, string url = null)
|
||||
{
|
||||
_testSite = siteContext;
|
||||
_name = name;
|
||||
string temp = physicalPath;
|
||||
if (physicalPath.Contains("%"))
|
||||
{
|
||||
temp = System.Environment.ExpandEnvironmentVariables(physicalPath);
|
||||
}
|
||||
_physicalPath = temp;
|
||||
|
||||
if (url != null)
|
||||
{
|
||||
_url = url;
|
||||
}
|
||||
else
|
||||
{
|
||||
string tempUrl = name.Trim();
|
||||
if (tempUrl[0] != '/')
|
||||
{
|
||||
_url = "/" + tempUrl;
|
||||
}
|
||||
else
|
||||
{
|
||||
_url = tempUrl;
|
||||
}
|
||||
}
|
||||
BackupFile("web.config");
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
DeleteFile("app_offline.htm");
|
||||
RestoreFile("web.config");
|
||||
}
|
||||
|
||||
private string _name = null;
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return _name;
|
||||
}
|
||||
set
|
||||
{
|
||||
_name = value;
|
||||
}
|
||||
}
|
||||
|
||||
private string _physicalPath = null;
|
||||
public string PhysicalPath
|
||||
{
|
||||
get
|
||||
{
|
||||
return _physicalPath;
|
||||
}
|
||||
set
|
||||
{
|
||||
_physicalPath = value;
|
||||
}
|
||||
}
|
||||
|
||||
private string _url = null;
|
||||
public string URL
|
||||
{
|
||||
get
|
||||
{
|
||||
return _url;
|
||||
}
|
||||
set
|
||||
{
|
||||
_url = value;
|
||||
}
|
||||
}
|
||||
|
||||
public Uri GetUri()
|
||||
{
|
||||
return new Uri("http://" + _testSite.HostName + ":" + _testSite.TcpPort.ToString() + URL);
|
||||
}
|
||||
|
||||
public Uri GetUri(string subPath, int port = -1, string protocol = "http")
|
||||
{
|
||||
if (port == -1)
|
||||
{
|
||||
port = _testSite.TcpPort;
|
||||
}
|
||||
|
||||
string tempSubPath = string.Empty;
|
||||
if (subPath != null)
|
||||
{
|
||||
tempSubPath = subPath;
|
||||
if (!tempSubPath.StartsWith("/"))
|
||||
{
|
||||
tempSubPath = "/" + tempSubPath;
|
||||
}
|
||||
}
|
||||
return new Uri(protocol + "://" + _testSite.HostName + ":" + port.ToString() + URL + tempSubPath);
|
||||
}
|
||||
|
||||
public string _appPoolName = null;
|
||||
public string AppPoolName
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_appPoolName == null)
|
||||
{
|
||||
_appPoolName = "DefaultAppPool";
|
||||
}
|
||||
return _appPoolName;
|
||||
}
|
||||
set
|
||||
{
|
||||
_appPoolName = value;
|
||||
}
|
||||
}
|
||||
|
||||
public string GetProcessFileName()
|
||||
{
|
||||
string filePath = Path.Combine(_physicalPath, "web.config");
|
||||
string result = null;
|
||||
|
||||
// read web.config
|
||||
string fileContent = TestUtility.FileReadAllText(filePath);
|
||||
|
||||
// get the value of processPath attribute of aspNetCore element
|
||||
if (fileContent != null)
|
||||
{
|
||||
result = TestUtility.XmlParser(fileContent, "aspNetCore", "processPath", null);
|
||||
}
|
||||
|
||||
// split fileName from full path
|
||||
result = Path.GetFileName(result);
|
||||
|
||||
// append .exe if it wasn't used
|
||||
if (!result.Contains(".exe"))
|
||||
{
|
||||
result = result + ".exe";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public string GetArgumentFileName()
|
||||
{
|
||||
string filePath = Path.Combine(_physicalPath, "web.config");
|
||||
string result = null;
|
||||
|
||||
// read web.config
|
||||
string fileContent = TestUtility.FileReadAllText(filePath);
|
||||
|
||||
// get the value of arguments attribute of aspNetCore element
|
||||
if (fileContent != null)
|
||||
{
|
||||
result = TestUtility.XmlParser(fileContent, "aspNetCore", "arguments", null);
|
||||
}
|
||||
|
||||
// split fileName from full path
|
||||
result = Path.GetFileName(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
public void BackupFile(string from)
|
||||
{
|
||||
string fromfile = Path.Combine(_physicalPath, from);
|
||||
string tofile = Path.Combine(_physicalPath, fromfile + ".bak");
|
||||
TestUtility.FileCopy(fromfile, tofile, overWrite: false);
|
||||
}
|
||||
|
||||
public void RestoreFile(string from)
|
||||
{
|
||||
string fromfile = Path.Combine(_physicalPath, from + ".bak");
|
||||
string tofile = Path.Combine(_physicalPath, from);
|
||||
if (!File.Exists(fromfile))
|
||||
{
|
||||
BackupFile(from);
|
||||
}
|
||||
TestUtility.FileCopy(fromfile, tofile);
|
||||
}
|
||||
|
||||
public string GetDirectoryPathWith(string subPath)
|
||||
{
|
||||
return Path.Combine(_physicalPath, subPath);
|
||||
}
|
||||
|
||||
public void DeleteFile(string file = "app_offline.htm")
|
||||
{
|
||||
string filePath = Path.Combine(_physicalPath, file);
|
||||
TestUtility.DeleteFile(filePath);
|
||||
}
|
||||
|
||||
public void CreateFile(string[] content, string file = "app_offline.htm")
|
||||
{
|
||||
string filePath = Path.Combine(_physicalPath, file);
|
||||
TestUtility.CreateFile(filePath, content);
|
||||
}
|
||||
|
||||
public void MoveFile(string from, string to)
|
||||
{
|
||||
string fromfile = Path.Combine(_physicalPath, from);
|
||||
string tofile = Path.Combine(_physicalPath, to);
|
||||
TestUtility.FileMove(fromfile, tofile);
|
||||
}
|
||||
|
||||
public void DeleteDirectory(string directory)
|
||||
{
|
||||
string directoryPath = Path.Combine(_physicalPath, directory);
|
||||
TestUtility.DeleteDirectory(directoryPath);
|
||||
}
|
||||
|
||||
public void CreateDirectory(string directory)
|
||||
{
|
||||
string directoryPath = Path.Combine(_physicalPath, directory);
|
||||
TestUtility.CreateDirectory(directoryPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,536 +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 System.IO;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace AspNetCoreModule.Test.Framework
|
||||
{
|
||||
public class TestWebSite : IDisposable
|
||||
{
|
||||
static private bool _publishedAspnetCoreApp = false;
|
||||
|
||||
public TestWebApplication RootAppContext;
|
||||
public TestWebApplication AspNetCoreApp;
|
||||
public TestWebApplication WebSocketApp;
|
||||
public TestWebApplication URLRewriteApp;
|
||||
public TestUtility testHelper;
|
||||
private ILogger _logger;
|
||||
private int _iisExpressPidBackup = -1;
|
||||
|
||||
private string postfix = string.Empty;
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
TestUtility.LogInformation("TestWebSite::Dispose() Start");
|
||||
|
||||
if (_iisExpressPidBackup != -1)
|
||||
{
|
||||
var iisExpressProcess = Process.GetProcessById(Convert.ToInt32(_iisExpressPidBackup));
|
||||
try
|
||||
{
|
||||
iisExpressProcess.Kill();
|
||||
iisExpressProcess.WaitForExit();
|
||||
iisExpressProcess.Close();
|
||||
}
|
||||
catch
|
||||
{
|
||||
TestUtility.RunPowershellScript("stop-process -id " + _iisExpressPidBackup);
|
||||
}
|
||||
}
|
||||
TestUtility.LogInformation("TestWebSite::Dispose() End");
|
||||
}
|
||||
|
||||
public string _hostName = null;
|
||||
public string HostName
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_hostName == null)
|
||||
{
|
||||
_hostName = "localhost";
|
||||
}
|
||||
return _hostName;
|
||||
}
|
||||
set
|
||||
{
|
||||
_hostName = value;
|
||||
}
|
||||
}
|
||||
|
||||
public string _siteName = null;
|
||||
public string SiteName
|
||||
{
|
||||
get
|
||||
{
|
||||
return _siteName;
|
||||
}
|
||||
set
|
||||
{
|
||||
_siteName = value;
|
||||
}
|
||||
}
|
||||
|
||||
public string _postFix = null;
|
||||
public string PostFix
|
||||
{
|
||||
get
|
||||
{
|
||||
return _postFix;
|
||||
}
|
||||
set
|
||||
{
|
||||
_postFix = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int _tcpPort = 8080;
|
||||
public int TcpPort
|
||||
{
|
||||
get
|
||||
{
|
||||
return _tcpPort;
|
||||
}
|
||||
set
|
||||
{
|
||||
_tcpPort = value;
|
||||
}
|
||||
}
|
||||
|
||||
private int _workerProcessID = 0;
|
||||
public int WorkerProcessID
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_workerProcessID == 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (IisServerType == ServerType.IISExpress)
|
||||
{
|
||||
_workerProcessID = Convert.ToInt32(TestUtility.GetProcessWMIAttributeValue("iisexpress.exe", "Handle", null));
|
||||
}
|
||||
else
|
||||
{
|
||||
_workerProcessID = Convert.ToInt32(TestUtility.GetProcessWMIAttributeValue("w3wp.exe", "Handle", null));
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
TestUtility.LogInformation("Failed to get process id of w3wp.exe");
|
||||
}
|
||||
}
|
||||
return _workerProcessID;
|
||||
}
|
||||
set
|
||||
{
|
||||
_workerProcessID = value;
|
||||
}
|
||||
}
|
||||
|
||||
public string HostNameBinding
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IisServerType == ServerType.IISExpress)
|
||||
{
|
||||
return "localhost";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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", bool startIISExpress = true, bool copyAllPublishedFiles = false, bool attachAppVerifier = false)
|
||||
{
|
||||
_appPoolBitness = appPoolBitness;
|
||||
|
||||
//
|
||||
// Initialize IisServerType
|
||||
//
|
||||
if (TestFlags.Enabled(TestFlags.UseFullIIS))
|
||||
{
|
||||
IisServerType = ServerType.IIS;
|
||||
}
|
||||
else
|
||||
{
|
||||
IisServerType = ServerType.IISExpress;
|
||||
}
|
||||
|
||||
//
|
||||
// Use localhost hostname for IISExpress
|
||||
//
|
||||
|
||||
|
||||
if (IisServerType == ServerType.IISExpress
|
||||
&& TestFlags.Enabled(TestFlags.Wow64BitMode))
|
||||
{
|
||||
//
|
||||
// In Wow64/IISExpress test context, always use 32 bit worker process
|
||||
//
|
||||
if (_appPoolBitness == IISConfigUtility.AppPoolBitness.noChange)
|
||||
{
|
||||
TestUtility.LogInformation("Warning!!! In Wow64, _appPoolBitness should be set with enable32bit");
|
||||
_appPoolBitness = IISConfigUtility.AppPoolBitness.enable32Bit;
|
||||
}
|
||||
}
|
||||
|
||||
TestUtility.LogInformation("TestWebSite::TestWebSite() Start");
|
||||
|
||||
string solutionPath = InitializeTestMachine.GetSolutionDirectory();
|
||||
|
||||
if (IisServerType == ServerType.IIS)
|
||||
{
|
||||
// check JitDebugger before continuing
|
||||
TestUtility.ResetHelper(ResetHelperMode.KillVSJitDebugger);
|
||||
}
|
||||
|
||||
// initialize logger for TestUtility
|
||||
_logger = new LoggerFactory()
|
||||
.AddConsole()
|
||||
.CreateLogger(string.Format(loggerPrefix));
|
||||
|
||||
testHelper = new TestUtility(_logger);
|
||||
|
||||
//
|
||||
// Initialize context variables
|
||||
//
|
||||
string siteRootPath = string.Empty;
|
||||
string siteName = string.Empty;
|
||||
string postfix = string.Empty;
|
||||
|
||||
// repeat three times until getting the valid temporary directory path
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
postfix = Path.GetRandomFileName();
|
||||
siteName = loggerPrefix.Replace(" ", "") + "_" + postfix;
|
||||
siteRootPath = Path.Combine(InitializeTestMachine.TestRootDirectory, siteName);
|
||||
if (!Directory.Exists(siteRootPath))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
TestUtility.DirectoryCopy(Path.Combine(solutionPath, "test", "WebRoot"), siteRootPath);
|
||||
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 DotnetCore v2.0
|
||||
//
|
||||
string publishPath = Path.Combine(srcPath, "bin", "Debug", "netcoreapp2.0", "publish");
|
||||
string publishPathOutput = Path.Combine(InitializeTestMachine.TestRootDirectory, "publishPathOutput");
|
||||
|
||||
//
|
||||
// Publish aspnetcore app
|
||||
//
|
||||
if (_publishedAspnetCoreApp != true)
|
||||
{
|
||||
string argumentForDotNet = "publish " + srcPath + " --framework netcoreapp2.0";
|
||||
TestUtility.LogInformation("TestWebSite::TestWebSite() StandardTestApp is not published, trying to publish on the fly: dotnet.exe " + argumentForDotNet);
|
||||
TestUtility.DeleteDirectory(publishPath);
|
||||
TestUtility.RunCommand("dotnet", argumentForDotNet);
|
||||
if (!File.Exists(Path.Combine(publishPath, "AspNetCoreModule.TestSites.Standard.dll")))
|
||||
{
|
||||
throw new Exception("Failed to publish");
|
||||
}
|
||||
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();
|
||||
if (string.IsNullOrEmpty(argumentFileName))
|
||||
{
|
||||
argumentFileName = "AspNetCoreModule.TestSites.Standard.dll";
|
||||
}
|
||||
iisConfig.CreateSite(tempSiteName, HostNameBinding, publishPathOutput, tempId, tempId);
|
||||
iisConfig.SetANCMConfig(tempSiteName, "/", "arguments", Path.Combine(publishPathOutput, argumentFileName));
|
||||
iisConfig.DeleteSite(tempSiteName);
|
||||
}
|
||||
_publishedAspnetCoreApp = true;
|
||||
}
|
||||
|
||||
if (copyAllPublishedFiles)
|
||||
{
|
||||
// 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"));
|
||||
}
|
||||
else
|
||||
{
|
||||
// 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"));
|
||||
}
|
||||
|
||||
int tcpPort = InitializeTestMachine.SiteId++;
|
||||
_siteId = tcpPort;
|
||||
|
||||
//
|
||||
// initialize class member variables
|
||||
//
|
||||
string appPoolName = null;
|
||||
if (IisServerType == ServerType.IIS)
|
||||
{
|
||||
appPoolName = "AspNetCoreModuleTestAppPool";
|
||||
}
|
||||
else if (IisServerType == ServerType.IISExpress)
|
||||
{
|
||||
appPoolName = "Clr4IntegratedAppPool";
|
||||
}
|
||||
|
||||
// Initialize member variables
|
||||
_hostName = "localhost";
|
||||
_siteName = siteName;
|
||||
_postFix = postfix;
|
||||
_tcpPort = tcpPort;
|
||||
|
||||
RootAppContext = new TestWebApplication("/", Path.Combine(siteRootPath, "WebSite1"), this);
|
||||
RootAppContext.RestoreFile("web.config");
|
||||
RootAppContext.DeleteFile("app_offline.htm");
|
||||
RootAppContext.AppPoolName = appPoolName;
|
||||
|
||||
AspNetCoreApp = new TestWebApplication("/AspNetCoreApp", aspnetCoreAppRootPath, this);
|
||||
AspNetCoreApp.AppPoolName = appPoolName;
|
||||
AspNetCoreApp.RestoreFile("web.config");
|
||||
AspNetCoreApp.DeleteFile("app_offline.htm");
|
||||
|
||||
WebSocketApp = new TestWebApplication("/WebSocketApp", Path.Combine(siteRootPath, "WebSocket"), this);
|
||||
WebSocketApp.AppPoolName = appPoolName;
|
||||
WebSocketApp.RestoreFile("web.config");
|
||||
WebSocketApp.DeleteFile("app_offline.htm");
|
||||
|
||||
URLRewriteApp = new TestWebApplication("/URLRewriteApp", Path.Combine(siteRootPath, "URLRewrite"), this);
|
||||
URLRewriteApp.AppPoolName = appPoolName;
|
||||
URLRewriteApp.RestoreFile("web.config");
|
||||
URLRewriteApp.DeleteFile("app_offline.htm");
|
||||
|
||||
//
|
||||
// Create site and apps
|
||||
//
|
||||
using (var iisConfig = new IISConfigUtility(IisServerType, IisExpressConfigPath))
|
||||
{
|
||||
// Create apppool
|
||||
if (IisServerType == ServerType.IIS)
|
||||
{
|
||||
iisConfig.CreateAppPool(appPoolName);
|
||||
|
||||
// Switch bitness
|
||||
if (TestUtility.IsOSAmd64 && appPoolBitness == IISConfigUtility.AppPoolBitness.enable32Bit)
|
||||
{
|
||||
iisConfig.SetAppPoolSetting(appPoolName, "enable32BitAppOnWin64", true);
|
||||
}
|
||||
}
|
||||
|
||||
if (TestFlags.Enabled(TestFlags.UsePrivateANCM) && IisServerType == ServerType.IISExpress)
|
||||
{
|
||||
if (TestUtility.IsOSAmd64)
|
||||
{
|
||||
if (_appPoolBitness == IISConfigUtility.AppPoolBitness.enable32Bit)
|
||||
{
|
||||
iisConfig.AddModule("AspNetCoreModule", (InitializeTestMachine.IisExpressAspnetcore_X86_path), null);
|
||||
}
|
||||
else
|
||||
{
|
||||
iisConfig.AddModule("AspNetCoreModule", (InitializeTestMachine.IisExpressAspnetcore_path), null);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
iisConfig.AddModule("AspNetCoreModule", (InitializeTestMachine.IisExpressAspnetcore_path), null);
|
||||
}
|
||||
}
|
||||
|
||||
iisConfig.CreateSite(siteName, HostNameBinding, 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 (startIISExpress)
|
||||
{
|
||||
// clean up IISExpress before starting a new instance
|
||||
TestUtility.KillIISExpressProcess();
|
||||
|
||||
StartIISExpress();
|
||||
|
||||
// send a startup request to IISExpress instance to make sure that it is fully ready to use before starting actual test scenarios
|
||||
TestUtility.RunPowershellScript("( invoke-webrequest http://localhost:" + TcpPort + " ).StatusCode", "200");
|
||||
}
|
||||
TestUtility.LogInformation("TestWebSite::TestWebSite() End");
|
||||
}
|
||||
|
||||
public void StartIISExpress()
|
||||
{
|
||||
if (IisServerType == ServerType.IIS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// reset workerProcessID
|
||||
this.WorkerProcessID = 0;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
public void AttachAppverifier()
|
||||
{
|
||||
string cmdline;
|
||||
string processName = "iisexpress.exe";
|
||||
if (IisServerType == ServerType.IIS)
|
||||
{
|
||||
processName = "w3wp.exe";
|
||||
}
|
||||
string argument = "-enable Heaps COM RPC Handles Locks Memory TLS Exceptions Threadpool Leak SRWLock -for " + processName;
|
||||
if (Directory.Exists(Environment.ExpandEnvironmentVariables("%ProgramFiles(x86)%")) && _appPoolBitness == IISConfigUtility.AppPoolBitness.enable32Bit)
|
||||
{
|
||||
cmdline = Path.Combine(Environment.ExpandEnvironmentVariables("%windir%"), "syswow64", "appverif.exe");
|
||||
if (!File.Exists(cmdline))
|
||||
{
|
||||
throw new ApplicationException("Not found :" + cmdline + "; this test requires appverif.exe.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cmdline = Path.Combine(Environment.ExpandEnvironmentVariables("%windir%"), "system32", "appverif.exe");
|
||||
if (!File.Exists(cmdline))
|
||||
{
|
||||
throw new ApplicationException("Not found :" + cmdline + "; this test requires appverif.exe.");
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
TestUtility.LogInformation("Configure Appverifier: " + cmdline + " " + argument);
|
||||
TestUtility.RunCommand(cmdline, argument, true, false);
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw new ApplicationException("Failed to configure Appverifier");
|
||||
}
|
||||
}
|
||||
|
||||
public void AttachWinDbg(int processIdOfWorkerProcess)
|
||||
{
|
||||
string processName = "iisexpress.exe";
|
||||
string debuggerCmdline;
|
||||
if (IisServerType == ServerType.IIS)
|
||||
{
|
||||
processName = "w3wp.exe";
|
||||
}
|
||||
string argument = "-enable Heaps COM RPC Handles Locks Memory TLS Exceptions Threadpool Leak SRWLock -for " + processName;
|
||||
if (Directory.Exists(Environment.ExpandEnvironmentVariables("%ProgramFiles(x86)%")) && _appPoolBitness == IISConfigUtility.AppPoolBitness.enable32Bit)
|
||||
{
|
||||
debuggerCmdline = Path.Combine(Environment.ExpandEnvironmentVariables("%ProgramFiles%"), "Debugging Tools for Windows (x64)", "wow64", "windbg.exe");
|
||||
if (!File.Exists(debuggerCmdline))
|
||||
{
|
||||
throw new ApplicationException("Not found :" + debuggerCmdline + "; this test requires windbg.exe.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Directory.Exists(Environment.ExpandEnvironmentVariables("%ProgramFiles(x86)%")))
|
||||
{
|
||||
debuggerCmdline = Path.Combine(Environment.ExpandEnvironmentVariables("%ProgramFiles%"), "Debugging Tools for Windows (x64)", "windbg.exe");
|
||||
}
|
||||
else
|
||||
{
|
||||
debuggerCmdline = Path.Combine(Environment.ExpandEnvironmentVariables("%ProgramFiles%"), "Debugging Tools for Windows (x86)", "windbg.exe");
|
||||
}
|
||||
if (!File.Exists(debuggerCmdline))
|
||||
{
|
||||
throw new ApplicationException("Not found :" + debuggerCmdline + "; this test requires windbg.exe.");
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
TestUtility.RunCommand(debuggerCmdline, " -g -G -p " + processIdOfWorkerProcess.ToString(), true, false);
|
||||
System.Threading.Thread.Sleep(3000);
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw new ApplicationException("Failed to attach debuger");
|
||||
}
|
||||
}
|
||||
|
||||
public void DetachAppverifier()
|
||||
{
|
||||
try
|
||||
{
|
||||
string cmdline;
|
||||
string processName = "iisexpress.exe";
|
||||
string debuggerCmdline;
|
||||
if (IisServerType == ServerType.IIS)
|
||||
{
|
||||
processName = "w3wp.exe";
|
||||
}
|
||||
|
||||
string argument = "-disable * -for " + processName;
|
||||
if (Directory.Exists(Environment.ExpandEnvironmentVariables("%ProgramFiles(x86)%")) && _appPoolBitness == IISConfigUtility.AppPoolBitness.enable32Bit)
|
||||
{
|
||||
cmdline = Path.Combine(Environment.ExpandEnvironmentVariables("%windir%"), "syswow64", "appverif.exe");
|
||||
if (!File.Exists(cmdline))
|
||||
{
|
||||
throw new ApplicationException("Not found :" + cmdline);
|
||||
}
|
||||
debuggerCmdline = Path.Combine(Environment.ExpandEnvironmentVariables("%ProgramFiles%"), "Debugging Tools for Windows (x64)", "wow64", "windbg.exe");
|
||||
if (!File.Exists(debuggerCmdline))
|
||||
{
|
||||
throw new ApplicationException("Not found :" + debuggerCmdline);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cmdline = Path.Combine(Environment.ExpandEnvironmentVariables("%windir%"), "system32", "appverif.exe");
|
||||
if (!File.Exists(cmdline))
|
||||
{
|
||||
throw new ApplicationException("Not found :" + cmdline);
|
||||
}
|
||||
debuggerCmdline = Path.Combine(Environment.ExpandEnvironmentVariables("%ProgramFiles%"), "Debugging Tools for Windows (x64)", "windbg.exe");
|
||||
if (!File.Exists(debuggerCmdline))
|
||||
{
|
||||
throw new ApplicationException("Not found :" + debuggerCmdline);
|
||||
}
|
||||
}
|
||||
TestUtility.RunCommand(cmdline, argument, true, false);
|
||||
}
|
||||
catch
|
||||
{
|
||||
TestUtility.LogInformation("Failed to detach Appverifier");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,370 +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 AspNetCoreModule.Test.Framework;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
|
||||
namespace AspNetCoreModule.Test
|
||||
{
|
||||
public class FunctionalTest : FunctionalTestHelper, IClassFixture<InitializeTestMachine>
|
||||
{
|
||||
private const string ANCMTestCondition = TestFlags.SkipTest;
|
||||
//private const string ANCMTestCondition = TestFlags.RunAsAdministrator;
|
||||
|
||||
[ConditionalTheory]
|
||||
[ANCMTestFlags(ANCMTestCondition)]
|
||||
[OSSkipCondition(OperatingSystems.Linux)]
|
||||
[OSSkipCondition(OperatingSystems.MacOSX)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.noChange)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit)]
|
||||
public async void BasicTest(IISConfigUtility.AppPoolBitness appPoolBitness)
|
||||
{
|
||||
await DoBasicTest(appPoolBitness);
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[ANCMTestFlags(ANCMTestCondition)]
|
||||
[OSSkipCondition(OperatingSystems.Linux)]
|
||||
[OSSkipCondition(OperatingSystems.MacOSX)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.noChange, 5)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit, 5)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.noChange, 1)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit, 0)]
|
||||
public Task RapidFailsPerMinuteTest(IISConfigUtility.AppPoolBitness appPoolBitness, int valueOfRapidFailsPerMinute)
|
||||
{
|
||||
return DoRapidFailsPerMinuteTest(appPoolBitness, valueOfRapidFailsPerMinute);
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[ANCMTestFlags(ANCMTestCondition)]
|
||||
[OSSkipCondition(OperatingSystems.Linux)]
|
||||
[OSSkipCondition(OperatingSystems.MacOSX)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit, 25, 19, false)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit, 25, 19, true)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.noChange, 25, 19, false)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.noChange, 25, 19, true)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit, 5, 4, true)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit, 5, 4, false)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.noChange, 5, 4, true)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.noChange, 5, 4, false)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit, 0, 0, false)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit, 0, 0, true)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.noChange, 0, 0, false)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.noChange, 0, 0, true)]
|
||||
public Task ShutdownTimeLimitTest(IISConfigUtility.AppPoolBitness appPoolBitness, int valueOfshutdownTimeLimit, int expectedClosingTime, bool isGraceFullShutdownEnabled)
|
||||
{
|
||||
return DoShutdownTimeLimitTest(appPoolBitness, valueOfshutdownTimeLimit, expectedClosingTime, isGraceFullShutdownEnabled);
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[ANCMTestFlags(ANCMTestCondition)]
|
||||
[OSSkipCondition(OperatingSystems.Linux)]
|
||||
[OSSkipCondition(OperatingSystems.MacOSX)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit, 10)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.noChange, 10)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit, 1)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.noChange, 1)]
|
||||
public Task StartupTimeLimitTest(IISConfigUtility.AppPoolBitness appPoolBitness, int starupTimeLimit)
|
||||
{
|
||||
return DoStartupTimeLimitTest(appPoolBitness, starupTimeLimit);
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[ANCMTestFlags(ANCMTestCondition)]
|
||||
[OSSkipCondition(OperatingSystems.Linux)]
|
||||
[OSSkipCondition(OperatingSystems.MacOSX)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.noChange)]
|
||||
public Task RecycleApplicationAfterBackendProcessBeingKilled(IISConfigUtility.AppPoolBitness appPoolBitness)
|
||||
{
|
||||
return DoRecycleApplicationAfterBackendProcessBeingKilled(appPoolBitness);
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[ANCMTestFlags(ANCMTestCondition)]
|
||||
[OSSkipCondition(OperatingSystems.Linux)]
|
||||
[OSSkipCondition(OperatingSystems.MacOSX)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.noChange)]
|
||||
public Task RecycleApplicationAfterW3WPProcessBeingKilled(IISConfigUtility.AppPoolBitness appPoolBitness)
|
||||
{
|
||||
return DoRecycleApplicationAfterW3WPProcessBeingKilled(appPoolBitness);
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[ANCMTestFlags(ANCMTestCondition)]
|
||||
[OSSkipCondition(OperatingSystems.Linux)]
|
||||
[OSSkipCondition(OperatingSystems.MacOSX)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.noChange)]
|
||||
public Task RecycleApplicationAfterWebConfigUpdated(IISConfigUtility.AppPoolBitness appPoolBitness)
|
||||
{
|
||||
return DoRecycleApplicationAfterWebConfigUpdated(appPoolBitness);
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[ANCMTestFlags(ANCMTestCondition)]
|
||||
[OSSkipCondition(OperatingSystems.Linux)]
|
||||
[OSSkipCondition(OperatingSystems.MacOSX)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.noChange)]
|
||||
public Task RecycleApplicationWithURLRewrite(IISConfigUtility.AppPoolBitness appPoolBitness)
|
||||
{
|
||||
return DoRecycleApplicationWithURLRewrite(appPoolBitness);
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[ANCMTestFlags(ANCMTestCondition)]
|
||||
[OSSkipCondition(OperatingSystems.Linux)]
|
||||
[OSSkipCondition(OperatingSystems.MacOSX)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.noChange)]
|
||||
public Task RecycleParentApplicationWithURLRewrite(IISConfigUtility.AppPoolBitness appPoolBitness)
|
||||
{
|
||||
return DoRecycleParentApplicationWithURLRewrite(appPoolBitness);
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[ANCMTestFlags(ANCMTestCondition)]
|
||||
[OSSkipCondition(OperatingSystems.Linux)]
|
||||
[OSSkipCondition(OperatingSystems.MacOSX)]
|
||||
[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(environmentVariableName, environmentVariableValue, expectedEnvironmentVariableValue, appPoolBitness);
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[ANCMTestFlags(ANCMTestCondition)]
|
||||
[OSSkipCondition(OperatingSystems.Linux)]
|
||||
[OSSkipCondition(OperatingSystems.MacOSX)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.noChange)]
|
||||
public Task AppOfflineTestWithRenaming(IISConfigUtility.AppPoolBitness appPoolBitness)
|
||||
{
|
||||
return DoAppOfflineTestWithRenaming(appPoolBitness);
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[ANCMTestFlags(ANCMTestCondition)]
|
||||
[OSSkipCondition(OperatingSystems.Linux)]
|
||||
[OSSkipCondition(OperatingSystems.MacOSX)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.noChange)]
|
||||
public Task AppOfflineTestWithUrlRewriteAndDeleting(IISConfigUtility.AppPoolBitness appPoolBitness)
|
||||
{
|
||||
return DoAppOfflineTestWithUrlRewriteAndDeleting(appPoolBitness);
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[ANCMTestFlags(ANCMTestCondition)]
|
||||
[OSSkipCondition(OperatingSystems.Linux)]
|
||||
[OSSkipCondition(OperatingSystems.MacOSX)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit, "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789")]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.noChange, "a")]
|
||||
public Task PostMethodTest(IISConfigUtility.AppPoolBitness appPoolBitness, string testData)
|
||||
{
|
||||
return DoPostMethodTest(appPoolBitness, testData);
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[ANCMTestFlags(ANCMTestCondition)]
|
||||
[OSSkipCondition(OperatingSystems.Linux)]
|
||||
[OSSkipCondition(OperatingSystems.MacOSX)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.noChange)]
|
||||
public Task DisableStartUpErrorPageTest(IISConfigUtility.AppPoolBitness appPoolBitness)
|
||||
{
|
||||
return DoDisableStartUpErrorPageTest(appPoolBitness);
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[ANCMTestFlags(ANCMTestCondition)]
|
||||
[OSSkipCondition(OperatingSystems.Linux)]
|
||||
[OSSkipCondition(OperatingSystems.MacOSX)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit, 10)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.noChange, 2)]
|
||||
public Task ProcessesPerApplicationTest(IISConfigUtility.AppPoolBitness appPoolBitness, int valueOfProcessesPerApplication)
|
||||
{
|
||||
return DoProcessesPerApplicationTest(appPoolBitness, valueOfProcessesPerApplication);
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[ANCMTestFlags(ANCMTestCondition)]
|
||||
[OSSkipCondition(OperatingSystems.Linux)]
|
||||
[OSSkipCondition(OperatingSystems.MacOSX)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit, "00:02:00")]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.noChange, "00:02:00")]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit, "00:01:00")]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.noChange, "00:01:00")]
|
||||
public Task RequestTimeoutTest(IISConfigUtility.AppPoolBitness appPoolBitness, string requestTimeout)
|
||||
{
|
||||
return DoRequestTimeoutTest(appPoolBitness, requestTimeout);
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[ANCMTestFlags(ANCMTestCondition)]
|
||||
[OSSkipCondition(OperatingSystems.Linux)]
|
||||
[OSSkipCondition(OperatingSystems.MacOSX)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.noChange)]
|
||||
public Task StdoutLogEnabledTest(IISConfigUtility.AppPoolBitness appPoolBitness)
|
||||
{
|
||||
return DoStdoutLogEnabledTest(appPoolBitness);
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[ANCMTestFlags(ANCMTestCondition)]
|
||||
[OSSkipCondition(OperatingSystems.Linux)]
|
||||
[OSSkipCondition(OperatingSystems.MacOSX)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit, "dotnet.exe", "./")]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.noChange, "dotnet", @".\")]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit, "$env", "")]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.noChange, "$env", "")]
|
||||
public Task ProcessPathAndArgumentsTest(IISConfigUtility.AppPoolBitness appPoolBitness, string processPath, string argumentsPrefix)
|
||||
{
|
||||
return DoProcessPathAndArgumentsTest(appPoolBitness, processPath, argumentsPrefix);
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[ANCMTestFlags(ANCMTestCondition)]
|
||||
[OSSkipCondition(OperatingSystems.Linux)]
|
||||
[OSSkipCondition(OperatingSystems.MacOSX)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit, true)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit, false)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.noChange, true)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.noChange, false)]
|
||||
public Task ForwardWindowsAuthTokenTest(IISConfigUtility.AppPoolBitness appPoolBitness, bool enabledForwardWindowsAuthToken)
|
||||
{
|
||||
return DoForwardWindowsAuthTokenTest(appPoolBitness, enabledForwardWindowsAuthToken);
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[ANCMTestFlags(ANCMTestCondition)]
|
||||
[OSSkipCondition(OperatingSystems.Linux)]
|
||||
[OSSkipCondition(OperatingSystems.MacOSX)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit, true, true)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit, false, false)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.noChange, true, false)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.noChange, false, true)]
|
||||
public Task CompressionTest(IISConfigUtility.AppPoolBitness appPoolBitness, bool useCompressionMiddleWare, bool enableIISCompression)
|
||||
{
|
||||
return DoCompressionTest(appPoolBitness, useCompressionMiddleWare, enableIISCompression);
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[ANCMTestFlags(ANCMTestCondition)]
|
||||
[OSSkipCondition(OperatingSystems.Linux)]
|
||||
[OSSkipCondition(OperatingSystems.MacOSX)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.noChange)]
|
||||
public Task CachingTest(IISConfigUtility.AppPoolBitness appPoolBitness)
|
||||
{
|
||||
return DoCachingTest(appPoolBitness);
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[ANCMTestFlags(ANCMTestCondition)]
|
||||
[OSSkipCondition(OperatingSystems.Linux)]
|
||||
[OSSkipCondition(OperatingSystems.MacOSX)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.noChange)]
|
||||
public Task SendHTTPSRequestTest(IISConfigUtility.AppPoolBitness appPoolBitness)
|
||||
{
|
||||
return DoSendHTTPSRequestTest(appPoolBitness);
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[ANCMTestFlags(ANCMTestCondition)]
|
||||
[OSSkipCondition(OperatingSystems.Linux)]
|
||||
[OSSkipCondition(OperatingSystems.MacOSX)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit, "MS-ASPNETCORE", "f")]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.noChange, "mS-ASPNETCORE", "fo")]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit, "MS-ASPNETCORE-", "foo")]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.noChange, "mS-ASPNETCORE-f", "fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo")]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit, "MS-ASPNETCORE-foo", "foo")]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.noChange, "MS-ASPNETCORE-foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", "bar")]
|
||||
public Task FilterOutMSRequestHeadersTest(IISConfigUtility.AppPoolBitness appPoolBitness, string requestHeader, string requestHeaderValue)
|
||||
{
|
||||
return DoFilterOutMSRequestHeadersTest(appPoolBitness, requestHeader, requestHeaderValue);
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[ANCMTestFlags(ANCMTestCondition)]
|
||||
[OSSkipCondition(OperatingSystems.Linux)]
|
||||
[OSSkipCondition(OperatingSystems.MacOSX)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit, true)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.noChange, true)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.noChange, false)]
|
||||
public Task ClientCertificateMappingTest(IISConfigUtility.AppPoolBitness appPoolBitness, bool useHTTPSMiddleWare)
|
||||
{
|
||||
return DoClientCertificateMappingTest(appPoolBitness, useHTTPSMiddleWare);
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[ANCMTestFlags(ANCMTestCondition)]
|
||||
[OSSkipCondition(OperatingSystems.Linux)]
|
||||
[OSSkipCondition(OperatingSystems.MacOSX)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.noChange, false, DoAppVerifierTest_StartUpMode.UseGracefulShutdown, DoAppVerifierTest_ShutDownMode.RecycleAppPool, 1)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.noChange, false, DoAppVerifierTest_StartUpMode.DontUseGracefulShutdown, DoAppVerifierTest_ShutDownMode.RecycleAppPool, 1)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.noChange, false, DoAppVerifierTest_StartUpMode.UseGracefulShutdown, DoAppVerifierTest_ShutDownMode.StopAndStartAppPool, 1)]
|
||||
public Task AppVerifierTest(IISConfigUtility.AppPoolBitness appPoolBitness, bool shutdownTimeout, DoAppVerifierTest_StartUpMode startUpMode, DoAppVerifierTest_ShutDownMode shutDownMode, int repeatCount)
|
||||
{
|
||||
return DoAppVerifierTest(appPoolBitness, shutdownTimeout, startUpMode, shutDownMode, repeatCount);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
// NOTE: below test scenarios are not valid for Win7 OS
|
||||
//////////////////////////////////////////////////////////
|
||||
|
||||
[ConditionalTheory]
|
||||
[ANCMTestFlags(ANCMTestCondition)]
|
||||
[OSSkipCondition(OperatingSystems.Linux)]
|
||||
[OSSkipCondition(OperatingSystems.MacOSX)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit)]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.noChange)]
|
||||
public Task WebSocketErrorhandlingTest(IISConfigUtility.AppPoolBitness appPoolBitness)
|
||||
{
|
||||
return DoWebSocketErrorhandlingTest(appPoolBitness);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
// NOTE: below test scenarios are not valid for Win7 OS
|
||||
//////////////////////////////////////////////////////////
|
||||
[ConditionalTheory]
|
||||
[ANCMTestFlags(ANCMTestCondition)]
|
||||
[OSSkipCondition(OperatingSystems.Linux)]
|
||||
[OSSkipCondition(OperatingSystems.MacOSX)]
|
||||
[OSSkipCondition(OperatingSystems.Windows, WindowsVersions.Win7, SkipReason = "IIS does not support Websocket on Win7")]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit, "abcdefghijklmnopqrstuvwxyz0123456789")]
|
||||
[InlineData(IISConfigUtility.AppPoolBitness.noChange, "a")]
|
||||
// Test reliablitiy issue with lenghty data; disabled until the reason of the test issue is figured out
|
||||
//[InlineData(IISConfigUtility.AppPoolBitness.enable32Bit, "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789")]
|
||||
public Task WebSocketTest(IISConfigUtility.AppPoolBitness appPoolBitness, string testData)
|
||||
{
|
||||
return DoWebSocketTest(appPoolBitness, testData);
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[ANCMTestFlags(ANCMTestCondition)]
|
||||
[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);
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -1,336 +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 AspNetCoreModule.Test.Framework;
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Net.Security;
|
||||
using System.Threading;
|
||||
using System.Net.Sockets;
|
||||
|
||||
namespace AspNetCoreModule.Test.HttpClientHelper
|
||||
{
|
||||
public class HttpClientHelper
|
||||
{
|
||||
private IPHostEntry _host = Dns.GetHostEntry(Dns.GetHostName());
|
||||
private string _ipv4Loopback = "127.0.0.1";
|
||||
private string _ipv4One = null;
|
||||
private string _ipv4Two = null;
|
||||
private string _ipv6Loopback = "[::1]";
|
||||
private string _ipv6One = null;
|
||||
private string _ipv6Two = null;
|
||||
|
||||
public HttpClientHelper()
|
||||
{
|
||||
ReadMachineIpAddressInfo();
|
||||
|
||||
_Ips = new string[] { _ipv4Loopback, _ipv4One, _ipv6Loopback, _ipv6One, _ipv6Two };
|
||||
|
||||
_Hosts = new string[] { "foo", "bar", "foobar", "barfoo" };
|
||||
|
||||
_unusedIp = _ipv6Two;
|
||||
}
|
||||
|
||||
// callback used to validate the certificate in an SSL conversation
|
||||
public static bool ValidateRemoteCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors policyErrors)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public static int sendRequest(string uri, string hostName, string expectedCN, bool useLegacy, bool displayContent, bool doLogging = true)
|
||||
{
|
||||
int status = -1;
|
||||
|
||||
if (doLogging)
|
||||
{
|
||||
if (hostName == null)
|
||||
TestUtility.LogInformation(String.Format("HttpClient::sendRequest() {0} with no hostname", uri));
|
||||
else
|
||||
TestUtility.LogInformation(String.Format("HttpClient::sendRequest() {0} with hostname {1}", uri, hostName));
|
||||
}
|
||||
|
||||
ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(ValidateRemoteCertificate);
|
||||
|
||||
if (useLegacy)
|
||||
{
|
||||
TestUtility.LogInformation(String.Format("Using SSL3"));
|
||||
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;
|
||||
}
|
||||
|
||||
HttpWebRequest myRequest;
|
||||
myRequest = (HttpWebRequest)WebRequest.Create(uri);
|
||||
myRequest.Proxy = null;
|
||||
myRequest.KeepAlive = false;
|
||||
if (hostName != null)
|
||||
myRequest.Host = hostName;
|
||||
|
||||
ServicePoint point = myRequest.ServicePoint;
|
||||
point.ConnectionLeaseTimeout = 0;
|
||||
|
||||
try
|
||||
{
|
||||
using (HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse())
|
||||
{
|
||||
using (Stream myStream = myResponse.GetResponseStream())
|
||||
{
|
||||
if (displayContent)
|
||||
{
|
||||
using (StreamReader myReader = new StreamReader(myStream))
|
||||
{
|
||||
string text = myReader.ReadToEnd();
|
||||
TestUtility.LogInformation("\n\n");
|
||||
TestUtility.LogInformation(text);
|
||||
TestUtility.LogInformation("\n\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
status = (int)myResponse.StatusCode;
|
||||
}
|
||||
}
|
||||
catch (WebException ex)
|
||||
{
|
||||
if ((HttpWebResponse)ex.Response == null)
|
||||
status = 0;
|
||||
else
|
||||
status = (int)((HttpWebResponse)ex.Response).StatusCode;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
public string IPv4Loopback
|
||||
{
|
||||
get { return _ipv4Loopback; }
|
||||
}
|
||||
public string IPv4One
|
||||
{
|
||||
get { return _ipv4One; }
|
||||
}
|
||||
public string IPv4Two
|
||||
{
|
||||
get { return _ipv4Two; }
|
||||
}
|
||||
public string IPv6Loopback
|
||||
{
|
||||
get { return _ipv6Loopback; }
|
||||
}
|
||||
public string IPv6One
|
||||
{
|
||||
get { return _ipv6One; }
|
||||
}
|
||||
public string IPv6Two
|
||||
{
|
||||
get { return _ipv6Two; }
|
||||
}
|
||||
|
||||
private string[] _Ips;
|
||||
|
||||
private string[] _Hosts = { "foo", "bar", "foobar", "barfoo" };
|
||||
|
||||
private string _unusedIp;
|
||||
|
||||
|
||||
private Thread _backgroundRequestThread = null;
|
||||
|
||||
public void ReadMachineIpAddressInfo()
|
||||
{
|
||||
foreach (IPAddress ip in _host.AddressList)
|
||||
{
|
||||
if (IPAddress.IsLoopback(ip))
|
||||
continue;
|
||||
|
||||
if (ip.AddressFamily == AddressFamily.InterNetwork)
|
||||
{
|
||||
if (_ipv4One == null)
|
||||
_ipv4One = ip.ToString();
|
||||
else if (_ipv4Two == null)
|
||||
_ipv4Two = ip.ToString();
|
||||
}
|
||||
else if (ip.AddressFamily == AddressFamily.InterNetworkV6)
|
||||
{
|
||||
if (!ip.ToString().Contains("%"))
|
||||
{
|
||||
if (_ipv6One == null)
|
||||
_ipv6One = "[" + ip.ToString() + "]";
|
||||
else if (_ipv6Two == null)
|
||||
_ipv6Two = "[" + ip.ToString() + "]";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int SendReceiveStatus(string path = "/", string protocol = "http", string ip = "127.0.0.1", int port = 8080, string host = "localhost", int expectedStatus = 200, int retryCount = 0)
|
||||
{
|
||||
string uri = protocol + "://" + ip + ":" + port + path;
|
||||
int status = HttpClientHelper.sendRequest(uri, host, "CN=NULL", false, false);
|
||||
for (int i = 0; i < retryCount; i++)
|
||||
{
|
||||
if (status == expectedStatus)
|
||||
{
|
||||
break;
|
||||
}
|
||||
DoSleep(1000);
|
||||
status = HttpClientHelper.sendRequest(uri, host, "CN=NULL", false, false);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
public void DoRequest(string uri, string host = null, string expectedCN = "CN=NULL", bool useLegacy = false, bool displayContent = false)
|
||||
{
|
||||
HttpClientHelper.sendRequest(uri, host, expectedCN, useLegacy, displayContent);
|
||||
}
|
||||
|
||||
private void BackgroundRequestLoop(object req)
|
||||
{
|
||||
String[] uriHost = (String[])req;
|
||||
|
||||
while (true)
|
||||
{
|
||||
HttpClientHelper.sendRequest(uriHost[0], uriHost[1], "CN=NULL", false, false, false);
|
||||
Thread.Sleep(5000);
|
||||
}
|
||||
}
|
||||
|
||||
public void StartBackgroundRequests(string uri, string host = null)
|
||||
{
|
||||
if (_backgroundRequestThread != null && _backgroundRequestThread.ThreadState == System.Threading.ThreadState.Running)
|
||||
_backgroundRequestThread.Abort();
|
||||
|
||||
if (host == null)
|
||||
TestUtility.LogInformation(String.Format("########## Starting background requests to {0} with no hostname ##########", uri));
|
||||
else
|
||||
TestUtility.LogInformation(String.Format("########## Starting background requests to {0} with hostname {1} ##########", uri, host));
|
||||
|
||||
|
||||
ParameterizedThreadStart threadStart = new ParameterizedThreadStart(BackgroundRequestLoop);
|
||||
_backgroundRequestThread = new Thread(threadStart);
|
||||
_backgroundRequestThread.IsBackground = true;
|
||||
_backgroundRequestThread.Start(new string[] { uri, host });
|
||||
}
|
||||
|
||||
public void StopBackgroundRequests()
|
||||
{
|
||||
TestUtility.LogInformation(String.Format("####################### Stopping background requests #######################"));
|
||||
|
||||
if (_backgroundRequestThread != null && _backgroundRequestThread.ThreadState == System.Threading.ThreadState.Running)
|
||||
_backgroundRequestThread.Abort();
|
||||
|
||||
_backgroundRequestThread = null;
|
||||
}
|
||||
|
||||
public void DoSleep(int sleepMs)
|
||||
{
|
||||
TestUtility.LogInformation(String.Format("################## Sleeping for {0} ms ##################", sleepMs));
|
||||
Thread.Sleep(sleepMs);
|
||||
}
|
||||
}
|
||||
|
||||
public class RequestInfo
|
||||
{
|
||||
public string ip;
|
||||
public int port;
|
||||
public string host;
|
||||
public int status;
|
||||
|
||||
public RequestInfo(string ipIn, int portIn, string hostIn, int statusIn)
|
||||
{
|
||||
ip = ipIn;
|
||||
port = portIn;
|
||||
host = hostIn;
|
||||
status = statusIn;
|
||||
}
|
||||
|
||||
public string ToUrlRegistration()
|
||||
{
|
||||
if ((ip == null || ip == "*") && (host == null || host == "*"))
|
||||
return String.Format("HTTP://*:{0}/", port).ToUpper();
|
||||
|
||||
if (ip == null || ip == "*")
|
||||
return String.Format("HTTP://{0}:{1}/", host, port).ToUpper();
|
||||
|
||||
if (host == null || host == "*")
|
||||
return String.Format("HTTP://{0}:{1}:{0}/", ip, port).ToUpper();
|
||||
|
||||
return String.Format("HTTP://{0}:{1}:{2}/", host, port, ip).ToUpper();
|
||||
}
|
||||
}
|
||||
|
||||
public class BindingInfo
|
||||
{
|
||||
public string ip;
|
||||
public int port;
|
||||
public string host;
|
||||
|
||||
public BindingInfo(string ip, int port, string host)
|
||||
{
|
||||
this.ip = ip;
|
||||
this.port = port;
|
||||
this.host = host;
|
||||
}
|
||||
|
||||
public int GetBindingType()
|
||||
{
|
||||
if (ip == null)
|
||||
{
|
||||
if (host == null)
|
||||
return 5;
|
||||
else
|
||||
return 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (host == null)
|
||||
return 4;
|
||||
else
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsSupportedForDynamic()
|
||||
{
|
||||
return GetBindingType() == 2 || GetBindingType() == 5;
|
||||
}
|
||||
|
||||
public bool Match(RequestInfo req)
|
||||
{
|
||||
if (ip != null && ip != req.ip)
|
||||
return false;
|
||||
if (port != req.port)
|
||||
return false;
|
||||
if (host != null && host != req.host)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public string ToBindingString()
|
||||
{
|
||||
string bindingInfoString = "";
|
||||
bindingInfoString += (ip == null) ? "*" : ip;
|
||||
bindingInfoString += ":";
|
||||
bindingInfoString += port;
|
||||
bindingInfoString += ":";
|
||||
if (host != null)
|
||||
bindingInfoString += host;
|
||||
|
||||
return bindingInfoString;
|
||||
}
|
||||
|
||||
public string ToUrlRegistration()
|
||||
{
|
||||
if ((ip == null || ip == "*") && (host == null || host == "*"))
|
||||
return String.Format("HTTP://*:{0}/", port).ToUpper();
|
||||
|
||||
if (ip == null || ip == "*")
|
||||
return String.Format("HTTP://{0}:{1}/", host, port).ToUpper();
|
||||
|
||||
if (host == null || host == "*")
|
||||
return String.Format("HTTP://{0}:{1}:{0}/", ip, port).ToUpper();
|
||||
|
||||
return String.Format("HTTP://{0}:{1}:{2}/", host, port, ip).ToUpper();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,59 +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.Text;
|
||||
|
||||
namespace AspNetCoreModule.Test.WebSocketClient
|
||||
{
|
||||
public class Frame
|
||||
{
|
||||
private int startingIndex; // This will be initialized as output parameter of GetFrameString()
|
||||
public int DataLength = 0; // This will be initialized as output parameter of GetFrameString()
|
||||
|
||||
public Frame(byte[] data)
|
||||
{
|
||||
Data = data;
|
||||
FrameType = WebSocketClientUtility.GetFrameType(Data);
|
||||
Content = WebSocketClientUtility.GetFrameString(Data, out startingIndex, out DataLength);
|
||||
IsMasked = WebSocketClientUtility.IsFrameMasked(Data);
|
||||
}
|
||||
|
||||
public FrameType FrameType { get; set; }
|
||||
public byte[] Data { get; private set; }
|
||||
|
||||
public string TextData
|
||||
{
|
||||
get
|
||||
{
|
||||
if (DataLength == 0)
|
||||
{
|
||||
throw new System.Exception("DataLength is zero");
|
||||
}
|
||||
return Encoding.ASCII.GetString(Data, startingIndex, DataLength);
|
||||
}
|
||||
}
|
||||
|
||||
public string Content { get; private set; }
|
||||
public bool IsMasked { get; private set; }
|
||||
|
||||
public int IndexOfNextFrame
|
||||
{
|
||||
get
|
||||
{
|
||||
if (startingIndex > 0 && Data.Length > Content.Length + startingIndex)
|
||||
{
|
||||
return Content.Length + startingIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override public string ToString()
|
||||
{
|
||||
return FrameType + ": " + Content;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
|
||||
namespace AspNetCoreModule.Test.WebSocketClient
|
||||
{
|
||||
//* %x0 denotes a continuation frame
|
||||
//* %x1 denotes a text frame
|
||||
//* %x2 denotes a binary frame
|
||||
//* %x3-7 are reserved for further non-control frames
|
||||
//* %x8 denotes a connection close
|
||||
//* %x9 denotes a ping
|
||||
//* %xA denotes a pong
|
||||
public enum FrameType
|
||||
{
|
||||
NonControlFrame,
|
||||
Ping,
|
||||
Pong,
|
||||
Text,
|
||||
SegmentedText,
|
||||
Binary,
|
||||
SegmentedBinary,
|
||||
Continuation,
|
||||
ContinuationControlled,
|
||||
ContinuationFrameEnd,
|
||||
Close,
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -1,445 +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 AspNetCoreModule.Test.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Collections;
|
||||
using System.Threading;
|
||||
|
||||
namespace AspNetCoreModule.Test.WebSocketClient
|
||||
{
|
||||
public class WebSocketClientHelper : IDisposable
|
||||
{
|
||||
public bool IsOpened { get; private set; }
|
||||
public WebSocketConnect Connection { get; set; }
|
||||
public bool StoreData { get; set; }
|
||||
public bool IsAlwaysReading { get; private set; }
|
||||
public Uri Address { get; set; }
|
||||
public byte[][] HandShakeRequest { get; set; }
|
||||
public WebSocketState WebSocketState { get; set; }
|
||||
|
||||
public WebSocketClientHelper()
|
||||
{
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (IsOpened)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
}
|
||||
|
||||
public bool WaitForWebSocketState(WebSocketState expectedState, int timeout = 3000)
|
||||
{
|
||||
bool result = false;
|
||||
int RETRYMAX = 300;
|
||||
int INTERVAL = 100; // ms
|
||||
if (timeout > RETRYMAX * INTERVAL)
|
||||
{
|
||||
throw new Exception("timeout should be less than " + 100 * 300);
|
||||
}
|
||||
for (int i=0; i<RETRYMAX; i++)
|
||||
{
|
||||
if (i*100 > timeout)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (this.WebSocketState == expectedState)
|
||||
{
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
Thread.Sleep(INTERVAL);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public Frame Connect(Uri address, bool storeData, bool isAlwaysReading, bool waitForConnectionOpen = true)
|
||||
{
|
||||
Address = address;
|
||||
StoreData = storeData;
|
||||
|
||||
Connection = new WebSocketConnect();
|
||||
if (isAlwaysReading)
|
||||
{
|
||||
InitiateWithAlwaysReading();
|
||||
}
|
||||
SendWebSocketRequest(WebSocketClientUtility.WebSocketVersion);
|
||||
|
||||
if (waitForConnectionOpen)
|
||||
{
|
||||
if (!WaitForWebSocketState(WebSocketState.ConnectionOpen))
|
||||
{
|
||||
throw new Exception("Failed to open a connection");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Thread.Sleep(3000);
|
||||
}
|
||||
|
||||
if (this.WebSocketState == WebSocketState.ConnectionOpen)
|
||||
{
|
||||
IsOpened = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
IsOpened = false;
|
||||
}
|
||||
|
||||
Frame openingFrame = null;
|
||||
|
||||
if (!IsAlwaysReading)
|
||||
openingFrame = ReadData();
|
||||
else
|
||||
openingFrame = Connection.DataReceived[0];
|
||||
|
||||
return openingFrame;
|
||||
}
|
||||
|
||||
public Frame Close()
|
||||
{
|
||||
CloseConnection();
|
||||
|
||||
Frame closeFrame = null;
|
||||
|
||||
if (!IsAlwaysReading)
|
||||
closeFrame = ReadData();
|
||||
else
|
||||
closeFrame = Connection.DataReceived[Connection.DataReceived.Count - 1];
|
||||
|
||||
IsOpened = false;
|
||||
return closeFrame;
|
||||
}
|
||||
|
||||
public void Initiate()
|
||||
{
|
||||
string host = Address.DnsSafeHost;
|
||||
int port = Address.Port;
|
||||
|
||||
Connection = new WebSocketConnect();
|
||||
TestUtility.LogInformation("Connecting to {0} on {1}", host, port);
|
||||
|
||||
Connection.TcpClient = new MyTcpClient(host, port);
|
||||
Connection.Stream = Connection.TcpClient.GetStream();
|
||||
IsAlwaysReading = false;
|
||||
|
||||
if (StoreData)
|
||||
{
|
||||
Connection.DataSent = new List<Frame>();
|
||||
Connection.DataReceived = new List<Frame>();
|
||||
}
|
||||
}
|
||||
|
||||
public void InitiateWithAlwaysReading()
|
||||
{
|
||||
Initiate();
|
||||
Connection.Stream.BeginRead(Connection.InputData, 0, Connection.InputData.Length, ReadDataCallback, Connection);
|
||||
IsAlwaysReading = true;
|
||||
}
|
||||
|
||||
public void SendWebSocketRequest(int websocketVersion)
|
||||
{
|
||||
HandShakeRequest = Frames.GetHandShakeFrame(Address.AbsoluteUri, websocketVersion);
|
||||
|
||||
byte[] outputData = null;
|
||||
int offset = 0;
|
||||
while (offset < HandShakeRequest.Length)
|
||||
{
|
||||
outputData = HandShakeRequest[offset++];
|
||||
|
||||
var result = Connection.Stream.BeginWrite(outputData, 0, outputData.Length, WriteCallback, Connection);
|
||||
|
||||
//jhkim debug
|
||||
//result.AsyncWaitHandle.WaitOne();
|
||||
|
||||
TestUtility.LogInformation("Client {0:D3}: Write {1} bytes: {2} ", Connection.Id, outputData.Length,
|
||||
Encoding.UTF8.GetString(outputData, 0, outputData.Length));
|
||||
|
||||
//result.AsyncWaitHandle.Close();
|
||||
}
|
||||
}
|
||||
|
||||
public void SendWebSocketRequest(int websocketVersion, string AffinityCookie)
|
||||
{
|
||||
HandShakeRequest = Frames.GetHandShakeFrameWithAffinityCookie(Address.AbsoluteUri, websocketVersion, AffinityCookie);
|
||||
|
||||
byte[] outputData = null;
|
||||
int offset = 0;
|
||||
while (offset < HandShakeRequest.Length)
|
||||
{
|
||||
outputData = HandShakeRequest[offset++];
|
||||
|
||||
Connection.Stream.BeginWrite(outputData, 0, outputData.Length, WriteCallback, Connection);
|
||||
TestUtility.LogInformation("Client {0:D3}: Write {1} bytes: {2} ", Connection.Id, outputData.Length,
|
||||
Encoding.UTF8.GetString(outputData, 0, outputData.Length));
|
||||
}
|
||||
}
|
||||
|
||||
public void ReadDataCallback(IAsyncResult result)
|
||||
{
|
||||
WebSocketConnect client = (WebSocketConnect) result.AsyncState;
|
||||
|
||||
if (client.IsDisposed)
|
||||
return;
|
||||
|
||||
int bytesRead = client.Stream.EndRead(result); // wait until the buffer is filled
|
||||
int bytesReadIntotal = bytesRead;
|
||||
ArrayList InputDataArray = new ArrayList();
|
||||
byte[] tempBuffer = null;
|
||||
|
||||
if (bytesRead > 0)
|
||||
{
|
||||
tempBuffer = WebSocketClientUtility.SubArray(Connection.InputData, 0, bytesRead);
|
||||
|
||||
Frame temp = new Frame(tempBuffer);
|
||||
|
||||
// start looping if there is still remaining data
|
||||
if (tempBuffer.Length < temp.DataLength)
|
||||
{
|
||||
if (client.TcpClient.GetStream().DataAvailable)
|
||||
{
|
||||
// add the first buffer to the arrayList
|
||||
InputDataArray.Add(tempBuffer);
|
||||
|
||||
// start looping appending to the arrayList
|
||||
while (client.TcpClient.GetStream().DataAvailable)
|
||||
{
|
||||
bytesRead = client.TcpClient.GetStream().Read(Connection.InputData, 0, Connection.InputData.Length);
|
||||
tempBuffer = WebSocketClientUtility.SubArray(Connection.InputData, 0, bytesRead);
|
||||
InputDataArray.Add(tempBuffer);
|
||||
bytesReadIntotal += bytesRead;
|
||||
TestUtility.LogInformation("ReadDataCallback: Looping: Client {0:D3}: bytesReadHere {1} ", Connection.Id, bytesRead);
|
||||
}
|
||||
|
||||
// create a single byte array with the arrayList
|
||||
tempBuffer = new byte[bytesReadIntotal];
|
||||
int arrayIndex = 0;
|
||||
foreach (byte[] item in InputDataArray.ToArray())
|
||||
{
|
||||
for (int i = 0; i < item.Length; i++)
|
||||
{
|
||||
tempBuffer[arrayIndex] = item[i];
|
||||
arrayIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create frame with the tempBuffer
|
||||
Frame frame = new Frame(tempBuffer);
|
||||
ProcessReceivedData(frame);
|
||||
int nextFrameIndex = frame.IndexOfNextFrame;
|
||||
|
||||
while (nextFrameIndex != -1)
|
||||
{
|
||||
tempBuffer = tempBuffer.SubArray(frame.IndexOfNextFrame, tempBuffer.Length - frame.IndexOfNextFrame);
|
||||
frame = new Frame(tempBuffer);
|
||||
ProcessReceivedData(frame);
|
||||
nextFrameIndex = frame.IndexOfNextFrame;
|
||||
}
|
||||
|
||||
if (client.IsDisposed)
|
||||
return;
|
||||
|
||||
// Start the Async Read to handle the next frame comming from server
|
||||
client.Stream.BeginRead(client.InputData, 0, client.InputData.Length, ReadDataCallback, client);
|
||||
}
|
||||
else
|
||||
{
|
||||
client.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public Frame ReadData()
|
||||
{
|
||||
Frame frame = new Frame(new byte[] { });
|
||||
|
||||
IAsyncResult result = Connection.Stream.BeginRead(Connection.InputData, 0, Connection.InputData.Length, null, Connection);
|
||||
|
||||
if (result != null)
|
||||
{
|
||||
int bytesRead = Connection.Stream.EndRead(result);
|
||||
if (bytesRead > 0)
|
||||
{
|
||||
frame = new Frame(WebSocketClientUtility.SubArray(Connection.InputData, 0, bytesRead));
|
||||
|
||||
ProcessReceivedData(frame);
|
||||
|
||||
TestUtility.LogInformation("Client {0:D3}: Read Type {1} : {2} ", Connection.Id, frame.FrameType, frame.Content.Length);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
public void SendTextData(string data)
|
||||
{
|
||||
Send(WebSocketClientUtility.GetFramedTextDataInBytes(data));
|
||||
}
|
||||
|
||||
public void SendTextData(string data, byte opCode)
|
||||
{
|
||||
Send(WebSocketClientUtility.GetFramedTextDataInBytes(data, opCode));
|
||||
}
|
||||
|
||||
public void SendHello()
|
||||
{
|
||||
Send(Frames.HELLO);
|
||||
}
|
||||
|
||||
public void SendPing()
|
||||
{
|
||||
Send(Frames.PING);
|
||||
}
|
||||
|
||||
public void SendPong()
|
||||
{
|
||||
Send(Frames.PONG);
|
||||
}
|
||||
public void SendClose()
|
||||
{
|
||||
Send(Frames.CLOSE_FRAME);
|
||||
}
|
||||
|
||||
public void SendPong(Frame receivedPing)
|
||||
{
|
||||
var pong = new byte[receivedPing.Data.Length+4];
|
||||
for (int i = 1; i < receivedPing.Data.Length; i++)
|
||||
{
|
||||
if(i<2)
|
||||
pong[i] = receivedPing.Data[i];
|
||||
else
|
||||
pong[i+4] = receivedPing.Data[i];
|
||||
}
|
||||
|
||||
pong[0] = 0x8A;
|
||||
pong[1] = (byte)((int)pong[1] | 128);
|
||||
|
||||
Send(pong);
|
||||
}
|
||||
|
||||
public void CloseConnection()
|
||||
{
|
||||
this.WebSocketState = WebSocketState.ClosingFromClientStarted;
|
||||
Send(Frames.CLOSE_FRAME);
|
||||
|
||||
if (!WaitForWebSocketState(WebSocketState.ConnectionClosed))
|
||||
{
|
||||
throw new Exception("Failed to close a connection");
|
||||
}
|
||||
}
|
||||
|
||||
public static void WriteCallback(IAsyncResult result)
|
||||
{
|
||||
var client = result.AsyncState as WebSocketConnect;
|
||||
if (client.IsDisposed)
|
||||
return;
|
||||
|
||||
client.Stream.EndWrite(result);
|
||||
}
|
||||
|
||||
override public string ToString()
|
||||
{
|
||||
return Connection.Id + ": " + WebSocketState.ToString();
|
||||
}
|
||||
|
||||
#region Private Methods
|
||||
|
||||
public Frame Send(byte[] outputData)
|
||||
{
|
||||
var frame = new Frame(outputData);
|
||||
ProcessSentData(frame);
|
||||
if (Connection.TcpClient.Connected)
|
||||
{
|
||||
var result = Connection.Stream.BeginWrite(outputData, 0, outputData.Length, WriteCallback, Connection);
|
||||
TestUtility.LogInformation("Client {0:D3}: Write Type {1} : {2} ", Connection.Id, frame.FrameType,
|
||||
frame.Content.Length);
|
||||
}
|
||||
else
|
||||
{
|
||||
TestUtility.LogInformation("Connection is disconnected");
|
||||
}
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
private void ProcessSentData(Frame frame)
|
||||
{
|
||||
ProcessData(frame, true);
|
||||
}
|
||||
|
||||
private void ProcessReceivedData(Frame frame)
|
||||
{
|
||||
TestUtility.LogInformation("ReadDataCallback: Client {0:D3}: Read Type {1} : {2} ", Connection.Id, frame.FrameType, frame.DataLength);
|
||||
if (frame.FrameType == FrameType.NonControlFrame)
|
||||
{
|
||||
string content = frame.Content.ToLower();
|
||||
if (content.Contains("connection: upgrade")
|
||||
&& content.Contains("upgrade: websocket")
|
||||
&& content.Contains("http/1.1 101 switching protocols"))
|
||||
{
|
||||
TestUtility.LogInformation("Connection opened...");
|
||||
TestUtility.LogInformation(frame.Content);
|
||||
WebSocketState = WebSocketState.ConnectionOpen;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Send Pong if the frame was Ping
|
||||
if (frame.FrameType == FrameType.Ping)
|
||||
SendPong(frame);
|
||||
|
||||
// Send Close if the frame was Close
|
||||
if (frame.FrameType == FrameType.Close)
|
||||
{
|
||||
if (WebSocketState == WebSocketState.ConnectionClosed)
|
||||
{
|
||||
throw new Exception("Connection was already closed");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (WebSocketState != WebSocketState.ClosingFromClientStarted)
|
||||
{
|
||||
TestUtility.LogInformation("Send back Close frame to responsd server closing...");
|
||||
SendClose();
|
||||
}
|
||||
TestUtility.LogInformation(frame.Content);
|
||||
WebSocketState = WebSocketState.ConnectionClosed;
|
||||
IsOpened = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
ProcessData(frame, false);
|
||||
}
|
||||
|
||||
private void ProcessData(Frame frame, bool isSentData)
|
||||
{
|
||||
if (isSentData && StoreData)
|
||||
StoreDataSent(frame);
|
||||
else if (StoreData)
|
||||
StoreDataReceived(frame);
|
||||
}
|
||||
|
||||
private void StoreDataReceived(Frame frame)
|
||||
{
|
||||
Connection.DataReceived.Add(frame);
|
||||
Connection.TotalDataReceived += frame.Content.Length;
|
||||
}
|
||||
|
||||
private void StoreDataSent(Frame frame)
|
||||
{
|
||||
Connection.DataSent.Add(frame);
|
||||
Connection.TotalDataSent += frame.Content.Length;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
@ -1,231 +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 System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace AspNetCoreModule.Test.WebSocketClient
|
||||
{
|
||||
public static class WebSocketClientUtility
|
||||
{
|
||||
public static FrameType GetFrameType(byte[] inputData)
|
||||
{
|
||||
if(inputData.Length==0)
|
||||
return FrameType.NonControlFrame;
|
||||
|
||||
byte firstByte = inputData[0];
|
||||
|
||||
switch (firstByte)
|
||||
{
|
||||
case 0x80:
|
||||
return FrameType.ContinuationFrameEnd;
|
||||
case 0:
|
||||
return FrameType.Continuation;
|
||||
case 0x81:
|
||||
return FrameType.Text;
|
||||
case 0x01:
|
||||
return FrameType.SegmentedText;
|
||||
case 0x82:
|
||||
return FrameType.Binary;
|
||||
case 0x02:
|
||||
return FrameType.SegmentedBinary;
|
||||
case 0x88:
|
||||
return FrameType.Close;
|
||||
case 0x89:
|
||||
return FrameType.Ping;
|
||||
case 0x8A:
|
||||
return FrameType.Pong;
|
||||
}
|
||||
return FrameType.NonControlFrame;
|
||||
}
|
||||
|
||||
public static string GetFrameString(byte[] inputData)
|
||||
{
|
||||
int frameStartingIndex;
|
||||
int dataLength;
|
||||
return GetFrameString(inputData, out frameStartingIndex, out dataLength);
|
||||
}
|
||||
|
||||
public static string GetFrameString(byte[] inputData, out int frameStartingIndex, out int frameDataLength)
|
||||
{
|
||||
string content;
|
||||
|
||||
FrameType frameType = GetFrameType(inputData);
|
||||
int startingIndex = 2;
|
||||
int dataLength = 0;
|
||||
|
||||
if (frameType != FrameType.NonControlFrame && frameType != FrameType.ContinuationControlled)
|
||||
{
|
||||
int frameLength = inputData[1];
|
||||
|
||||
if (IsFrameMasked(inputData))
|
||||
{
|
||||
frameLength = inputData[1] ^ 128;
|
||||
|
||||
if (frameLength < WebSocketConstants.SMALL_LENGTH_FLAG)
|
||||
{
|
||||
startingIndex = 6;
|
||||
dataLength = inputData[1] ^ 128;
|
||||
}
|
||||
else if (frameLength == WebSocketConstants.SMALL_LENGTH_FLAG)
|
||||
{
|
||||
startingIndex = 8;
|
||||
dataLength = (int)GetFrameSize(inputData, 2, 4);
|
||||
}
|
||||
else if (frameLength == WebSocketConstants.LARGE_LENGTH_FLAG)
|
||||
{
|
||||
startingIndex = 14;
|
||||
dataLength = (int)GetFrameSize(inputData, 2, 10);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (frameLength < WebSocketConstants.SMALL_LENGTH_FLAG)
|
||||
{
|
||||
startingIndex = 2;
|
||||
dataLength = inputData[1];
|
||||
}
|
||||
else if (frameLength == WebSocketConstants.SMALL_LENGTH_FLAG)
|
||||
{
|
||||
startingIndex = 4;
|
||||
dataLength = (int)GetFrameSize(inputData, 2, 4);
|
||||
}
|
||||
else if (frameLength == WebSocketConstants.LARGE_LENGTH_FLAG)
|
||||
{
|
||||
startingIndex = 10;
|
||||
dataLength = (int)GetFrameSize(inputData, 2, 10);
|
||||
}
|
||||
}
|
||||
|
||||
content = Encoding.UTF8.GetString(inputData, startingIndex, (inputData.Length - startingIndex < dataLength) ? inputData.Length - startingIndex : dataLength);
|
||||
}
|
||||
else
|
||||
{
|
||||
startingIndex = 0;
|
||||
dataLength = 0;
|
||||
content = Encoding.UTF8.GetString(inputData, 0, inputData.Length);
|
||||
}
|
||||
|
||||
frameStartingIndex = startingIndex;
|
||||
frameDataLength = dataLength;
|
||||
return content;
|
||||
}
|
||||
|
||||
public static uint GetFrameSize(byte[] inputData, int start, int length)
|
||||
{
|
||||
byte[] bytes = SubArray(inputData, 2, length - 2);
|
||||
|
||||
if (BitConverter.IsLittleEndian)
|
||||
Array.Reverse(bytes);
|
||||
|
||||
if (length > 4)
|
||||
return BitConverter.ToUInt32(bytes, 0);
|
||||
else
|
||||
return BitConverter.ToUInt16(bytes, 0);
|
||||
}
|
||||
|
||||
public static byte[] GetFramedTextDataInBytes(string data)
|
||||
{
|
||||
return GetFramedDataInBytes(0x81, data);
|
||||
}
|
||||
public static byte[] GetFramedTextDataInBytes(string data, byte opCode)
|
||||
{
|
||||
return GetFramedDataInBytes(opCode, data);
|
||||
}
|
||||
|
||||
public static byte[] GetFramedBinaryDataInBytes(string data)
|
||||
{
|
||||
return GetFramedDataInBytes(0x82, data);
|
||||
}
|
||||
|
||||
private static byte[] GetFramedDataInBytes(byte dataType, string data)
|
||||
{
|
||||
var a = BitConverter.GetBytes(data.Length);
|
||||
var framelist = GetByteArrayFromNumber(dataType, data.Length);
|
||||
|
||||
|
||||
byte[] datalist = Encoding.UTF8.GetBytes(data);
|
||||
|
||||
var frame = JoinTwoArrays(framelist, datalist);
|
||||
return frame;
|
||||
}
|
||||
|
||||
|
||||
public static byte[] GetByteArrayFromNumber(byte dataType, int number)
|
||||
{
|
||||
if (number < 126)
|
||||
{
|
||||
return new byte[] {dataType, (byte)(number | 128),0,0,0,0 };
|
||||
}
|
||||
else
|
||||
{
|
||||
byte lengthByte = WebSocketConstants.LARGE_LENGTH_BYTE;
|
||||
int lengthBits = 16;
|
||||
|
||||
if (number < 65536)
|
||||
{
|
||||
lengthByte = WebSocketConstants.SMALL_LENGTH_BYTE;
|
||||
lengthBits = 4;
|
||||
}
|
||||
|
||||
var framelist = new byte[] { dataType, lengthByte };
|
||||
string hexValue = (number).ToString("X");
|
||||
hexValue = PrependZeroes(hexValue, lengthBits - hexValue.Length);
|
||||
|
||||
var sizeArray = JoinTwoArrays(StringToByteArray(hexValue), new byte[]{0,0,0,0});
|
||||
|
||||
return JoinTwoArrays(framelist, sizeArray);
|
||||
}
|
||||
}
|
||||
|
||||
public static string PrependZeroes(string hex, int zeroes)
|
||||
{
|
||||
for (int i = 0; i < zeroes; i++)
|
||||
{
|
||||
hex = "0" + hex;
|
||||
}
|
||||
return hex;
|
||||
}
|
||||
|
||||
public static byte[] StringToByteArray(string hex)
|
||||
{
|
||||
return Enumerable.Range(0, hex.Length)
|
||||
.Where(x => x % 2 == 0)
|
||||
.Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
public static bool IsFrameMasked(byte[] inputData)
|
||||
{
|
||||
bool frameMasked = false;
|
||||
FrameType frameType = GetFrameType(inputData);
|
||||
|
||||
if (frameType != FrameType.NonControlFrame && inputData[1] > 127)
|
||||
frameMasked = true;
|
||||
|
||||
return frameMasked;
|
||||
}
|
||||
|
||||
public static byte[] JoinTwoArrays(byte[] aArray, byte[] bArray)
|
||||
{
|
||||
var concat = new byte[aArray.Length + bArray.Length];
|
||||
|
||||
Buffer.BlockCopy(aArray, 0, concat, 0, aArray.Length);
|
||||
Buffer.BlockCopy(bArray, 0, concat, aArray.Length, bArray.Length);
|
||||
|
||||
return concat;
|
||||
|
||||
}
|
||||
|
||||
public static T[] SubArray<T>(this T[] data, int index, int length)
|
||||
{
|
||||
T[] result = new T[length];
|
||||
Array.Copy(data, index, result, 0, length);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static string WebSocketUri = null;
|
||||
public static int WebSocketVersion { get { return 13; } }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,74 +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 System.Collections.Generic;
|
||||
using System.Net.Sockets;
|
||||
using System.IO;
|
||||
|
||||
namespace AspNetCoreModule.Test.WebSocketClient
|
||||
{
|
||||
public class MyTcpClient : TcpClient
|
||||
{
|
||||
public MyTcpClient(string hostname, int port) : base(hostname, port)
|
||||
{
|
||||
}
|
||||
|
||||
public bool IsDead { get; set; }
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
Console.WriteLine("MyClient is disposed");
|
||||
IsDead = true;
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
}
|
||||
|
||||
public class WebSocketConnect : IDisposable
|
||||
{
|
||||
private static int globalID;
|
||||
|
||||
public WebSocketConnect()
|
||||
{
|
||||
Id = ++globalID;
|
||||
InputData = new byte[10240];
|
||||
}
|
||||
|
||||
public byte[] InputData { get; set; }
|
||||
public bool IsDisposed { get; set; }
|
||||
|
||||
public int Id { get; set; }
|
||||
|
||||
public MyTcpClient TcpClient { get; set; }
|
||||
public Stream Stream { get; set; }
|
||||
|
||||
public List<Frame> DataSent { get; set; }
|
||||
public long TotalDataSent { get; set; }
|
||||
public List<Frame> DataReceived { get; set; }
|
||||
public long TotalDataReceived { get; set; }
|
||||
|
||||
override public string ToString()
|
||||
{
|
||||
return Id+"";
|
||||
|
||||
}
|
||||
|
||||
#region IDisposable Members
|
||||
|
||||
/// <summary>
|
||||
/// Dispose this instance.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
Console.WriteLine("Client object is disposed");
|
||||
|
||||
IsDisposed = true;
|
||||
if (Stream != null)
|
||||
Stream.Close();
|
||||
|
||||
if (TcpClient != null)
|
||||
TcpClient.Close();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
|
||||
namespace AspNetCoreModule.Test.WebSocketClient
|
||||
{
|
||||
public static class WebSocketConstants
|
||||
{
|
||||
public static int SMALL_LENGTH_FLAG = 126;
|
||||
public static int LARGE_LENGTH_FLAG = 127;
|
||||
|
||||
public static byte SMALL_LENGTH_BYTE = 0XFE;
|
||||
public static byte LARGE_LENGTH_BYTE = 0XFF;
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
|
||||
namespace AspNetCoreModule.Test.WebSocketClient
|
||||
{
|
||||
public enum WebSocketState
|
||||
{
|
||||
NonWebSocket,
|
||||
ConnectionOpen,
|
||||
ClosingFromClientStarted,
|
||||
ConnectionClosed
|
||||
}
|
||||
}
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Microsoft.Extensions.Primitives" publicKeyToken="adb9793829ddae60" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-1.2.0.0" newVersion="1.2.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Microsoft.Extensions.Logging.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-1.2.0.0" newVersion="1.2.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Microsoft.AspNetCore.Testing" publicKeyToken="adb9793829ddae60" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-1.2.0.0" newVersion="1.2.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Runtime.InteropServices.RuntimeInformation" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Microsoft.Extensions.FileProviders.Embedded" publicKeyToken="adb9793829ddae60" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-1.1.0.0" newVersion="1.1.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Microsoft.Extensions.FileProviders.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-1.1.0.0" newVersion="1.1.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Console" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Diagnostics.DiagnosticSource" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.1.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
</configuration>
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Hosting" Version="$(MicrosoftAspNetCoreTestingPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.ResponseCaching" Version="$(MicrosoftAspNetCoreTestingPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.ResponseCompression" Version="$(MicrosoftAspNetCoreTestingPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="$(MicrosoftAspNetCoreTestingPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Server.IISIntegration" Version="$(MicrosoftAspNetCoreTestingPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="$(MicrosoftAspNetCoreTestingPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.WebSockets" Version="$(MicrosoftAspNetCoreTestingPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.CommandLine" Version="$(MicrosoftAspNetCoreTestingPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="$(MicrosoftExtensionsLoggingPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="$(MicrosoftExtensionsLoggingConsolePackageVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="$(MicrosoftExtensionsLoggingDebugPackageVersion)" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
@ -1,31 +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.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Server.IISIntegration;
|
||||
|
||||
namespace AspnetCoreModule.TestSites.Standard
|
||||
{
|
||||
internal class IISSetupFilter : IStartupFilter
|
||||
{
|
||||
private readonly string _pairingToken;
|
||||
|
||||
internal IISSetupFilter(string pairingToken)
|
||||
{
|
||||
_pairingToken = pairingToken;
|
||||
}
|
||||
|
||||
public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
|
||||
{
|
||||
return app =>
|
||||
{
|
||||
app.UseMiddleware<TestMiddleWareBeforeIISMiddleWare>();
|
||||
app.UseMiddleware<IISMiddleware>(_pairingToken);
|
||||
next(app);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,36 +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 Microsoft.AspNetCore.Http;
|
||||
using System.Security.Principal;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AspnetCoreModule.TestSites.Standard
|
||||
{
|
||||
public class ImpersonateMiddleware
|
||||
{
|
||||
private readonly RequestDelegate next;
|
||||
public ImpersonateMiddleware(RequestDelegate next)
|
||||
{
|
||||
this.next = next;
|
||||
}
|
||||
|
||||
public async Task Invoke(HttpContext context)
|
||||
{
|
||||
var winIdent = context.User.Identity as WindowsIdentity;
|
||||
if (winIdent == null)
|
||||
{
|
||||
await context.Response.WriteAsync("ImpersonateMiddleware-UserName = NoAuthentication");
|
||||
await next.Invoke(context);
|
||||
}
|
||||
else
|
||||
{
|
||||
await WindowsIdentity.RunImpersonated(winIdent.AccessToken, async () => {
|
||||
string currentUserName = $"{ WindowsIdentity.GetCurrent().Name}";
|
||||
await context.Response.WriteAsync("ImpersonateMiddleware-UserName = " + currentUserName);
|
||||
await next.Invoke(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,170 +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 Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Threading;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace AspnetCoreModule.TestSites.Standard
|
||||
{
|
||||
public static class Program
|
||||
{
|
||||
public static IApplicationLifetime AappLifetime;
|
||||
public static bool AappLifetimeStopping = false;
|
||||
public static int GracefulShutdownDelayTime = 0;
|
||||
|
||||
private static X509Certificate2 _x509Certificate2;
|
||||
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
var config = new ConfigurationBuilder()
|
||||
.AddCommandLine(args)
|
||||
.Build();
|
||||
|
||||
string startUpClassString = Environment.GetEnvironmentVariable("ANCMTestStartupClassName");
|
||||
IWebHostBuilder builder = null;
|
||||
if (!string.IsNullOrEmpty(startUpClassString))
|
||||
{
|
||||
if (startUpClassString == "StartupHTTPS")
|
||||
{
|
||||
// load .\testresources\testcert.pfx
|
||||
string pfxPassword = "testPassword";
|
||||
if (File.Exists(@".\TestResources\testcert.pfx"))
|
||||
{
|
||||
_x509Certificate2 = new X509Certificate2(@".\TestResources\testcert.pfx", pfxPassword);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception(@"Certificate file not found: .\TestResources\testcert.pfx of which password should " + pfxPassword);
|
||||
}
|
||||
|
||||
builder = new WebHostBuilder()
|
||||
.UseConfiguration(config)
|
||||
.UseIISIntegration()
|
||||
.UseKestrel()
|
||||
.UseStartup<Startup>();
|
||||
}
|
||||
else if (startUpClassString == "StartupCompressionCaching")
|
||||
{
|
||||
builder = new WebHostBuilder()
|
||||
.UseConfiguration(config)
|
||||
.UseIISIntegration()
|
||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||
.UseStartup<StartupCompressionCaching>();
|
||||
}
|
||||
else if (startUpClassString == "StartupNoCompressionCaching")
|
||||
{
|
||||
StartupCompressionCaching.CompressionMode = false;
|
||||
builder = new WebHostBuilder()
|
||||
.UseConfiguration(config)
|
||||
.UseIISIntegration()
|
||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||
.UseStartup<StartupCompressionCaching>();
|
||||
}
|
||||
else if (startUpClassString == "StartupHelloWorld")
|
||||
{
|
||||
builder = new WebHostBuilder()
|
||||
.UseConfiguration(config)
|
||||
.UseIISIntegration()
|
||||
.UseStartup<StartupHelloWorld>();
|
||||
}
|
||||
else if (startUpClassString == "StartupNtlmAuthentication")
|
||||
{
|
||||
builder = new WebHostBuilder()
|
||||
.UseConfiguration(config)
|
||||
.UseIISIntegration()
|
||||
.UseStartup<StartupNtlmAuthentication>();
|
||||
}
|
||||
else if (startUpClassString == "StartupWithShutdownDisabled")
|
||||
{
|
||||
builder = new WebHostBuilder()
|
||||
.ConfigureServices(services =>
|
||||
{
|
||||
const string PairingToken = "TOKEN";
|
||||
string paringToken = builder.GetSetting(PairingToken) ?? Environment.GetEnvironmentVariable($"ASPNETCORE_{PairingToken}");
|
||||
services.AddSingleton<IStartupFilter>(
|
||||
new IISSetupFilter(paringToken)
|
||||
);
|
||||
})
|
||||
.UseConfiguration(config)
|
||||
.UseStartup<Startup>();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("Invalid startup class name : " + startUpClassString);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
builder = new WebHostBuilder()
|
||||
.UseConfiguration(config)
|
||||
.UseIISIntegration()
|
||||
.UseStartup<Startup>();
|
||||
}
|
||||
|
||||
string startupDelay = Environment.GetEnvironmentVariable("ANCMTestStartUpDelay");
|
||||
if (!string.IsNullOrEmpty(startupDelay))
|
||||
{
|
||||
Startup.SleeptimeWhileStarting = Convert.ToInt32(startupDelay);
|
||||
}
|
||||
|
||||
if (Startup.SleeptimeWhileStarting != 0)
|
||||
{
|
||||
Thread.Sleep(Startup.SleeptimeWhileStarting);
|
||||
}
|
||||
|
||||
string shutdownDelay = Environment.GetEnvironmentVariable("ANCMTestShutdownDelay");
|
||||
if (!string.IsNullOrEmpty(shutdownDelay))
|
||||
{
|
||||
Startup.SleeptimeWhileClosing = Convert.ToInt32(shutdownDelay);
|
||||
}
|
||||
|
||||
builder.UseKestrel();
|
||||
|
||||
var host = builder.Build();
|
||||
AappLifetime = (IApplicationLifetime)host.Services.GetService(typeof(IApplicationLifetime));
|
||||
|
||||
string gracefulShutdownDelay = Environment.GetEnvironmentVariable("GracefulShutdownDelayTime");
|
||||
if (!string.IsNullOrEmpty(gracefulShutdownDelay))
|
||||
{
|
||||
GracefulShutdownDelayTime = Convert.ToInt32(gracefulShutdownDelay);
|
||||
}
|
||||
AappLifetime.ApplicationStarted.Register(
|
||||
() => {
|
||||
Thread.Sleep(1000);
|
||||
}
|
||||
);
|
||||
AappLifetime.ApplicationStopping.Register(
|
||||
() => {
|
||||
AappLifetimeStopping = true;
|
||||
Thread.Sleep(Startup.SleeptimeWhileClosing / 2);
|
||||
}
|
||||
);
|
||||
AappLifetime.ApplicationStopped.Register(
|
||||
() => {
|
||||
Thread.Sleep(Startup.SleeptimeWhileClosing / 2);
|
||||
Startup.SleeptimeWhileClosing = 0; // All of SleeptimeWhileClosing is used now
|
||||
}
|
||||
);
|
||||
try
|
||||
{
|
||||
host.Run();
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignore
|
||||
}
|
||||
|
||||
if (Startup.SleeptimeWhileClosing != 0)
|
||||
{
|
||||
Thread.Sleep(Startup.SleeptimeWhileClosing);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
{
|
||||
"iisSettings": {
|
||||
"windowsAuthentication": true,
|
||||
"anonymousAuthentication": true,
|
||||
"iisExpress": {
|
||||
"applicationUrl": "http://localhost:39982/",
|
||||
"sslPort": 44375
|
||||
}
|
||||
},
|
||||
"profiles": {
|
||||
"IIS Express": {
|
||||
"commandName": "IISExpress",
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "https://localhost:44375/",
|
||||
"environmentVariables": {
|
||||
"ANCMTestStartupClassName": "StartupHTTPS",
|
||||
"ASPNET_ENVIRONMENT": "HelloWorld"
|
||||
}
|
||||
},
|
||||
"web": {
|
||||
"commandName": "web",
|
||||
"environmentVariables": {
|
||||
"ASPNET_ENVIRONMENT": "HelloWorld"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,351 +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 Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Net.WebSockets;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AspnetCoreModule.TestSites.Standard
|
||||
{
|
||||
public class Startup
|
||||
{
|
||||
public static int SleeptimeWhileClosing = 0;
|
||||
public static int SleeptimeWhileStarting = 0;
|
||||
public static List<byte[]> MemoryLeakList = new List<byte[]>();
|
||||
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.Configure<IISOptions>(options => {
|
||||
});
|
||||
}
|
||||
|
||||
private async Task Echo(WebSocket webSocket)
|
||||
{
|
||||
var buffer = new byte[1024 * 4];
|
||||
var result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
|
||||
bool closeFromServer = false;
|
||||
|
||||
while (!result.CloseStatus.HasValue)
|
||||
{
|
||||
if ((result.Count == "CloseFromServer".Length && System.Text.Encoding.ASCII.GetString(buffer).Substring(0, result.Count) == "CloseFromServer")
|
||||
|| Program.AappLifetimeStopping == true)
|
||||
{
|
||||
// start closing handshake from backend process
|
||||
await webSocket.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, "ClosingFromServer", CancellationToken.None);
|
||||
closeFromServer = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
await webSocket.SendAsync(new ArraySegment<byte>(buffer, 0, result.Count), result.MessageType, result.EndOfMessage, CancellationToken.None);
|
||||
}
|
||||
|
||||
result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
|
||||
}
|
||||
|
||||
if (closeFromServer)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
await webSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);
|
||||
}
|
||||
|
||||
public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
|
||||
{
|
||||
loggerFactory.AddConsole(minLevel: LogLevel.Warning);
|
||||
|
||||
app.Map("/websocketSubProtocol", subApp =>
|
||||
{
|
||||
app.UseWebSockets(new WebSocketOptions
|
||||
{
|
||||
});
|
||||
|
||||
subApp.Use(async (context, next) =>
|
||||
{
|
||||
if (context.WebSockets.IsWebSocketRequest)
|
||||
{
|
||||
var webSocket = await context.WebSockets.AcceptWebSocketAsync("mywebsocketsubprotocol");
|
||||
await Echo(webSocket);
|
||||
}
|
||||
else
|
||||
{
|
||||
var wsScheme = context.Request.IsHttps ? "wss" : "ws";
|
||||
var wsUrl = $"{wsScheme}://{context.Request.Host.Host}:{context.Request.Host.Port}{context.Request.Path}";
|
||||
await context.Response.WriteAsync($"Ready to accept a WebSocket request at: {wsUrl}");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
app.Map("/websocket", subApp =>
|
||||
{
|
||||
app.UseWebSockets(new WebSocketOptions
|
||||
{
|
||||
});
|
||||
|
||||
subApp.Use(async (context, next) =>
|
||||
{
|
||||
if (context.WebSockets.IsWebSocketRequest)
|
||||
{
|
||||
var webSocket = await context.WebSockets.AcceptWebSocketAsync("");
|
||||
await Echo(webSocket);
|
||||
}
|
||||
else
|
||||
{
|
||||
var wsScheme = context.Request.IsHttps ? "wss" : "ws";
|
||||
var wsUrl = $"{wsScheme}://{context.Request.Host.Host}:{context.Request.Host.Port}{context.Request.Path}";
|
||||
await context.Response.WriteAsync($"Ready to accept a WebSocket request at: {wsUrl}");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
app.Map("/GetProcessId", subApp =>
|
||||
{
|
||||
subApp.Run(context =>
|
||||
{
|
||||
var process = Process.GetCurrentProcess();
|
||||
return context.Response.WriteAsync(process.Id.ToString());
|
||||
});
|
||||
});
|
||||
|
||||
app.Map("/EchoPostData", subApp =>
|
||||
{
|
||||
subApp.Run(context =>
|
||||
{
|
||||
string responseBody = string.Empty;
|
||||
if (string.Equals(context.Request.Method, "POST", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var form = context.Request.ReadFormAsync().GetAwaiter().GetResult();
|
||||
int counter = 0;
|
||||
foreach (var key in form.Keys)
|
||||
{
|
||||
StringValues output;
|
||||
if (form.TryGetValue(key, out output))
|
||||
{
|
||||
responseBody += key + "=";
|
||||
foreach (var line in output)
|
||||
{
|
||||
responseBody += line;
|
||||
}
|
||||
if (++counter < form.Count)
|
||||
{
|
||||
responseBody += "&";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
responseBody = "NoAction";
|
||||
}
|
||||
return context.Response.WriteAsync(responseBody);
|
||||
});
|
||||
});
|
||||
|
||||
app.Map("/contentlength", subApp =>
|
||||
{
|
||||
subApp.Run(context =>
|
||||
{
|
||||
context.Response.ContentLength = 14;
|
||||
return context.Response.WriteAsync("Content Length");
|
||||
});
|
||||
});
|
||||
|
||||
app.Map("/connectionclose", subApp =>
|
||||
{
|
||||
subApp.Run(async context =>
|
||||
{
|
||||
context.Response.Headers[HeaderNames.Connection] = "close";
|
||||
await context.Response.WriteAsync("Connnection Close");
|
||||
await context.Response.Body.FlushAsync(); // Bypass IIS write-behind buffering
|
||||
});
|
||||
});
|
||||
|
||||
app.Map("/notchunked", subApp =>
|
||||
{
|
||||
subApp.Run(async context =>
|
||||
{
|
||||
var encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false);
|
||||
//context.Response.ContentLength = encoding.GetByteCount(document);
|
||||
context.Response.ContentType = "text/html;charset=UTF-8";
|
||||
await context.Response.WriteAsync("NotChunked", encoding, context.RequestAborted);
|
||||
await context.Response.Body.FlushAsync(); // Bypass IIS write-behind buffering
|
||||
});
|
||||
});
|
||||
|
||||
app.Map("/chunked", subApp =>
|
||||
{
|
||||
subApp.Run(async context =>
|
||||
{
|
||||
await context.Response.WriteAsync("Chunked");
|
||||
await context.Response.Body.FlushAsync(); // Bypass IIS write-behind buffering
|
||||
});
|
||||
});
|
||||
|
||||
app.Map("/manuallychunked", subApp =>
|
||||
{
|
||||
subApp.Run(context =>
|
||||
{
|
||||
context.Response.Headers[HeaderNames.TransferEncoding] = "chunked";
|
||||
return context.Response.WriteAsync("10\r\nManually Chunked\r\n0\r\n\r\n");
|
||||
});
|
||||
});
|
||||
|
||||
app.Map("/manuallychunkedandclose", subApp =>
|
||||
{
|
||||
subApp.Run(context =>
|
||||
{
|
||||
context.Response.Headers[HeaderNames.Connection] = "close";
|
||||
context.Response.Headers[HeaderNames.TransferEncoding] = "chunked";
|
||||
return context.Response.WriteAsync("1A\r\nManually Chunked and Close\r\n0\r\n\r\n");
|
||||
});
|
||||
});
|
||||
|
||||
app.Map("/ImpersonateMiddleware", subApp =>
|
||||
{
|
||||
subApp.UseMiddleware<ImpersonateMiddleware>();
|
||||
subApp.Run(context =>
|
||||
{
|
||||
return context.Response.WriteAsync("");
|
||||
});
|
||||
});
|
||||
|
||||
app.Run(context =>
|
||||
{
|
||||
string response = "Running";
|
||||
string[] paths = context.Request.Path.Value.Split(new char[] { '/', '\\' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
foreach (string item in paths)
|
||||
{
|
||||
string action = string.Empty;
|
||||
string parameter = string.Empty;
|
||||
|
||||
action = "DoSleep";
|
||||
if (item.StartsWith(action))
|
||||
{
|
||||
/*
|
||||
Process "DoSleep" command here.
|
||||
For example, if path contains "DoSleep" such as /DoSleep1000, run Thread.Sleep(1000)
|
||||
*/
|
||||
int sleepTime = 1000;
|
||||
if (item.Length > action.Length)
|
||||
{
|
||||
parameter = item.Substring(action.Length);
|
||||
sleepTime = Convert.ToInt32(parameter);
|
||||
}
|
||||
Thread.Sleep(sleepTime);
|
||||
}
|
||||
|
||||
action = "MemoryLeak";
|
||||
if (item.StartsWith(action))
|
||||
{
|
||||
parameter = "1024";
|
||||
if (item.Length > action.Length)
|
||||
{
|
||||
parameter = item.Substring(action.Length);
|
||||
}
|
||||
long size = Convert.ToInt32(parameter);
|
||||
var rnd = new Random();
|
||||
byte[] b = new byte[size * 1024];
|
||||
b[rnd.Next(0, b.Length)] = byte.MaxValue;
|
||||
MemoryLeakList.Add(b);
|
||||
response = "MemoryLeak, size:" + size.ToString() + " KB, total: " + MemoryLeakList.Count.ToString();
|
||||
}
|
||||
|
||||
action = "ExpandEnvironmentVariables";
|
||||
if (item.StartsWith(action))
|
||||
{
|
||||
if (item.Length > action.Length)
|
||||
{
|
||||
parameter = item.Substring(action.Length);
|
||||
response = Environment.ExpandEnvironmentVariables("%" + parameter + "%");
|
||||
}
|
||||
}
|
||||
|
||||
action = "GetEnvironmentVariables";
|
||||
if (item.StartsWith(action))
|
||||
{
|
||||
parameter = item.Substring(action.Length);
|
||||
response = Environment.GetEnvironmentVariables().Count.ToString();
|
||||
}
|
||||
|
||||
action = "DumpEnvironmentVariables";
|
||||
if (item.StartsWith(action))
|
||||
{
|
||||
response = String.Empty;
|
||||
|
||||
foreach (DictionaryEntry de in Environment.GetEnvironmentVariables())
|
||||
{
|
||||
response += de.Key + ":" + de.Value + "<br/>";
|
||||
}
|
||||
}
|
||||
|
||||
action = "GetRequestHeaderValue";
|
||||
if (item.StartsWith(action))
|
||||
{
|
||||
if (item.Length > action.Length)
|
||||
{
|
||||
parameter = item.Substring(action.Length);
|
||||
|
||||
if (context.Request.Headers.ContainsKey(parameter))
|
||||
{
|
||||
response = context.Request.Headers[parameter];
|
||||
}
|
||||
else
|
||||
{
|
||||
response = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
action = "DumpRequestHeaders";
|
||||
if (item.StartsWith(action))
|
||||
{
|
||||
response = String.Empty;
|
||||
|
||||
foreach (var de in context.Request.Headers)
|
||||
{
|
||||
response += de.Key + ":" + de.Value + "<br/>";
|
||||
}
|
||||
}
|
||||
|
||||
// This action can be used for testing invalid Transfer-Encoding response header
|
||||
action = "SetTransferEncoding";
|
||||
if (item.StartsWith(action))
|
||||
{
|
||||
if (item.Length > action.Length)
|
||||
{
|
||||
// this is the default response which is valid for chunked encoding
|
||||
response = "10\r\nManually Chunked\r\n0\r\n\r\n";
|
||||
parameter = item.Substring(action.Length);
|
||||
|
||||
// valid encoding value: "chunked" or "chunked,gzip"
|
||||
string encoding = parameter;
|
||||
var tokens = parameter.Split("_");
|
||||
|
||||
// if respons body value was also given after "_" delimeter, use the value as response data.
|
||||
if (tokens.Length == 2)
|
||||
{
|
||||
encoding = tokens[0];
|
||||
response = tokens[1];
|
||||
}
|
||||
context.Response.Headers[HeaderNames.TransferEncoding] = encoding;
|
||||
return context.Response.WriteAsync(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
return context.Response.WriteAsync(response);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,61 +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 Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
using System;
|
||||
|
||||
namespace AspnetCoreModule.TestSites.Standard
|
||||
{
|
||||
public class StartupCompressionCaching
|
||||
{
|
||||
public static bool CompressionMode = true;
|
||||
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
if (CompressionMode)
|
||||
{
|
||||
services.AddResponseCompression();
|
||||
}
|
||||
services.AddResponseCaching();
|
||||
}
|
||||
|
||||
public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
|
||||
{
|
||||
if (CompressionMode)
|
||||
{
|
||||
app.UseResponseCompression();
|
||||
}
|
||||
app.UseResponseCaching();
|
||||
app.UseDefaultFiles();
|
||||
app.UseStaticFiles(
|
||||
new StaticFileOptions()
|
||||
{
|
||||
OnPrepareResponse = context =>
|
||||
{
|
||||
//
|
||||
// FYI, below line can be simplified with
|
||||
// context.Context.Response.Headers[HeaderNames.CacheControl] = "public,max-age=10";
|
||||
//
|
||||
context.Context.Response.GetTypedHeaders().CacheControl = new CacheControlHeaderValue()
|
||||
{
|
||||
Public = true,
|
||||
MaxAge = TimeSpan.FromSeconds(10)
|
||||
};
|
||||
context.Context.Response.Headers.Append("MyCustomHeader", DateTime.Now.Second.ToString());
|
||||
var accept = context.Context.Request.Headers[HeaderNames.AcceptEncoding];
|
||||
if (!StringValues.IsNullOrEmpty(accept))
|
||||
{
|
||||
context.Context.Response.Headers.Append(HeaderNames.Vary, HeaderNames.AcceptEncoding);
|
||||
}
|
||||
context.Context.Response.ContentType = "text/plain";
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,22 +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 Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace AspnetCoreModule.TestSites.Standard
|
||||
{
|
||||
public class StartupHelloWorld
|
||||
{
|
||||
public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
|
||||
{
|
||||
loggerFactory.AddConsole(minLevel: LogLevel.Warning);
|
||||
|
||||
app.Run(ctx =>
|
||||
{
|
||||
return ctx.Response.WriteAsync("Hello World");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,94 +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.Authentication;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace AspnetCoreModule.TestSites.Standard
|
||||
{
|
||||
public class StartupNtlmAuthentication
|
||||
{
|
||||
public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
|
||||
{
|
||||
loggerFactory.AddConsole(minLevel: LogLevel.Warning);
|
||||
|
||||
app.Use(async (context, next) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
await next();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (context.Response.HasStarted)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
context.Response.Clear();
|
||||
context.Response.StatusCode = 500;
|
||||
await context.Response.WriteAsync(ex.ToString());
|
||||
}
|
||||
});
|
||||
|
||||
app.Use((context, next) =>
|
||||
{
|
||||
if (context.Request.Path.Equals("/Anonymous"))
|
||||
{
|
||||
return context.Response.WriteAsync("Anonymous?" + !context.User.Identity.IsAuthenticated);
|
||||
}
|
||||
|
||||
if (context.Request.Path.Equals("/Restricted"))
|
||||
{
|
||||
if (context.User.Identity.IsAuthenticated)
|
||||
{
|
||||
return context.Response.WriteAsync(context.User.Identity.AuthenticationType);
|
||||
}
|
||||
else
|
||||
{
|
||||
return context.ChallengeAsync();
|
||||
}
|
||||
}
|
||||
|
||||
if (context.Request.Path.Equals("/Forbidden"))
|
||||
{
|
||||
return context.ForbidAsync();
|
||||
|
||||
}
|
||||
|
||||
if (context.Request.Path.Equals("/AutoForbid"))
|
||||
{
|
||||
return context.ChallengeAsync();
|
||||
}
|
||||
|
||||
if (context.Request.Path.Equals("/RestrictedNegotiate"))
|
||||
{
|
||||
if (string.Equals("Negotiate", context.User.Identity.AuthenticationType, System.StringComparison.Ordinal))
|
||||
{
|
||||
return context.Response.WriteAsync("Negotiate");
|
||||
}
|
||||
else
|
||||
{
|
||||
return context.ChallengeAsync("Negotiate");
|
||||
}
|
||||
}
|
||||
|
||||
if (context.Request.Path.Equals("/RestrictedNTLM"))
|
||||
{
|
||||
if (string.Equals("NTLM", context.User.Identity.AuthenticationType, System.StringComparison.Ordinal))
|
||||
{
|
||||
return context.Response.WriteAsync("NTLM");
|
||||
}
|
||||
else
|
||||
{
|
||||
return context.ChallengeAsync("NTLM");
|
||||
}
|
||||
}
|
||||
|
||||
return context.Response.WriteAsync("Running NTLM");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,43 +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 Microsoft.AspNetCore.Http;
|
||||
using System;
|
||||
using System.Security.Principal;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
||||
namespace AspnetCoreModule.TestSites.Standard
|
||||
|
||||
{
|
||||
public class TestMiddleWareBeforeIISMiddleWare
|
||||
{
|
||||
private readonly RequestDelegate next;
|
||||
|
||||
public TestMiddleWareBeforeIISMiddleWare(RequestDelegate next)
|
||||
{
|
||||
this.next = next;
|
||||
}
|
||||
|
||||
public async Task Invoke(HttpContext context)
|
||||
{
|
||||
// if the given request is shutdown message from ANCM and the value of GracefulShutdown environment variable is set,
|
||||
// the shutdown message is handled by this middleware instead of IISMiddleware.
|
||||
|
||||
if (HttpMethods.IsPost(context.Request.Method) &&
|
||||
context.Request.Path.ToString().EndsWith("/iisintegration") &&
|
||||
string.Equals("shutdown", context.Request.Headers["MS-ASPNETCORE-EVENT"], StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
string shutdownMode = Environment.GetEnvironmentVariable("GracefulShutdown");
|
||||
if (!string.IsNullOrWhiteSpace(shutdownMode) && shutdownMode.ToLower().StartsWith("disabled"))
|
||||
{
|
||||
//ignore shutdown Message returning 200 instead of 202 because the gracefulshutdown is disabled
|
||||
context.Response.StatusCode = StatusCodes.Status200OK;
|
||||
await context.Response.WriteAsync("Called ShutdownMessage with disabled of GracefulShutdown");
|
||||
return;
|
||||
}
|
||||
}
|
||||
await next.Invoke(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
|
@ -1,9 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<system.webServer>
|
||||
<handlers>
|
||||
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
|
||||
</handlers>
|
||||
<aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" forwardWindowsAuthToken="true" />
|
||||
</system.webServer>
|
||||
</configuration>
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6" />
|
||||
</startup>
|
||||
</configuration>
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
using AspNetCoreModule.Test.Framework;
|
||||
using AspNetCoreModule.Test.WebSocketClient;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace WebSocketClientEXE
|
||||
{
|
||||
class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
using (WebSocketClientHelper websocketClient = new WebSocketClientHelper())
|
||||
{
|
||||
if (args.Length == 0)
|
||||
{
|
||||
TestUtility.LogInformation("Usage: WebSocketClientEXE http://localhost:40000/aspnetcoreapp/websocket");
|
||||
return;
|
||||
}
|
||||
string url = "http://localhost:40000/aspnetcoreapp/websocket";
|
||||
if (args[0].Contains("http:"))
|
||||
{
|
||||
url = args[0];
|
||||
}
|
||||
var frameReturned = websocketClient.Connect(new Uri(url), true, true);
|
||||
TestUtility.LogInformation(frameReturned.Content);
|
||||
TestUtility.LogInformation("Type any data and Enter key ('Q' to quit): ");
|
||||
|
||||
while (true)
|
||||
{
|
||||
Thread.Sleep(500);
|
||||
if (!websocketClient.IsOpened)
|
||||
{
|
||||
TestUtility.LogInformation("Connection closed...");
|
||||
break;
|
||||
}
|
||||
|
||||
string data = Console.ReadLine();
|
||||
if (data.Trim().ToLower() == "q")
|
||||
{
|
||||
frameReturned = websocketClient.Close();
|
||||
TestUtility.LogInformation(frameReturned.Content);
|
||||
break;
|
||||
}
|
||||
websocketClient.SendTextData(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("WebSocketClientEXE")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("WebSocketClientEXE")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2017")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("4062ea94-75f5-4691-86dc-c8594ba896de")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
|
|
@ -1,15 +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;
|
||||
|
||||
namespace AspNetCoreModule.Test.Framework
|
||||
{
|
||||
public class TestUtility
|
||||
{
|
||||
public static void LogInformation(string format, params object[] parameters)
|
||||
{
|
||||
Console.WriteLine(format, parameters);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="..\AspNetCoreModule.Test\WebSocketClientHelper\Frame.cs">
|
||||
<Link>Frame.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\AspNetCoreModule.Test\WebSocketClientHelper\Frames.cs">
|
||||
<Link>Frames.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\AspNetCoreModule.Test\WebSocketClientHelper\FrameType.cs">
|
||||
<Link>FrameType.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\AspNetCoreModule.Test\WebSocketClientHelper\WebSocketClientHelper.cs">
|
||||
<Link>WebSocketClientHelper.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\AspNetCoreModule.Test\WebSocketClientHelper\WebSocketClientUtility.cs">
|
||||
<Link>WebSocketClientUtility.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\AspNetCoreModule.Test\WebSocketClientHelper\WebSocketConnect.cs">
|
||||
<Link>WebSocketConnect.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\AspNetCoreModule.Test\WebSocketClientHelper\WebSocketConstants.cs">
|
||||
<Link>WebSocketConstants.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\AspNetCoreModule.Test\WebSocketClientHelper\WebSocketState.cs">
|
||||
<Link>WebSocketState.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="TestUtility.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
Loading…
Reference in New Issue