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}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{EF30B533-D715-421A-92B7-92FEF460AC9C}"
|
||||||
ProjectSection(SolutionItems) = preProject
|
ProjectSection(SolutionItems) = preProject
|
||||||
test\Directory.Build.props = test\Directory.Build.props
|
test\Directory.Build.props = test\Directory.Build.props
|
||||||
test\WebSocketClientEXE\WebSocketClientEXE.csproj = test\WebSocketClientEXE\WebSocketClientEXE.csproj
|
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{C74B8F36-FD2F-45C9-9B8A-00E7CF0126A9}"
|
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
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RequestHandler", "src\RequestHandler\RequestHandler.vcxproj", "{D57EA297-6DC2-4BC0-8C91-334863327863}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RequestHandler", "src\RequestHandler\RequestHandler.vcxproj", "{D57EA297-6DC2-4BC0-8C91-334863327863}"
|
||||||
EndProject
|
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
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
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|x64.Build.0 = Release|x64
|
||||||
{D57EA297-6DC2-4BC0-8C91-334863327863}.Release|x86.ActiveCfg = Release|Win32
|
{D57EA297-6DC2-4BC0-8C91-334863327863}.Release|x86.ActiveCfg = Release|Win32
|
||||||
{D57EA297-6DC2-4BC0-8C91-334863327863}.Release|x86.Build.0 = 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
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|
@ -244,8 +215,6 @@ Global
|
||||||
{4787A64F-9A3E-4867-A55A-70CB4B2B2FFE} = {04B1EDB6-E967-4D25-89B9-E6F8304038CD}
|
{4787A64F-9A3E-4867-A55A-70CB4B2B2FFE} = {04B1EDB6-E967-4D25-89B9-E6F8304038CD}
|
||||||
{55494E58-E061-4C4C-A0A8-837008E72F85} = {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}
|
{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
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
SolutionGuid = {DB4F868D-E1AE-4FD7-9333-69FA15B268C5}
|
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