Update test code (#298)
This commit is contained in:
Родитель
fd2f5524e9
Коммит
191b5128ba
|
@ -460,6 +460,85 @@ namespace AspNetCoreModule.Test.Framework
|
|||
}
|
||||
}
|
||||
|
||||
public void SetSiteRooAppConfig(string siteName, string attributeName, object attributeValue)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (ServerManager serverManager = GetServerManager())
|
||||
{
|
||||
Configuration config = serverManager.GetApplicationHostConfiguration();
|
||||
ConfigurationSection sitesSection = config.GetSection("system.applicationHost/sites");
|
||||
ConfigurationElementCollection sitesCollection = sitesSection.GetCollection();
|
||||
ConfigurationElement siteElement = FindElement(sitesCollection, "site", "name", siteName);
|
||||
if (siteElement == null)
|
||||
{
|
||||
throw new Exception("SetSiteConfig::Site Not Found");
|
||||
}
|
||||
ConfigurationElementCollection applicationCollection = siteElement.GetCollection();
|
||||
ConfigurationElement applicationElement = FindElement(applicationCollection, "application", "path", @"/");
|
||||
|
||||
applicationElement[attributeName] = attributeValue;
|
||||
serverManager.CommitChanges();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetWarmUpConfig(string siteName, string appName, string attributeName, object attributeValue, bool removeExisting = false)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (ServerManager serverManager = GetServerManager())
|
||||
{
|
||||
Configuration config = serverManager.GetWebConfiguration(siteName, appName);
|
||||
ConfigurationSection appInitializationSection = config.GetSection("system.webServer/applicationInitialization");
|
||||
if (attributeName == "initializationPage" || attributeName == "hostName")
|
||||
{
|
||||
string initializationPage = (string) attributeValue;
|
||||
string hostName = null;
|
||||
if (attributeName == "hostName")
|
||||
{
|
||||
initializationPage = ((string[])attributeValue)[0];
|
||||
hostName = ((string[])attributeValue)[1];
|
||||
}
|
||||
ConfigurationElementCollection intializationPagesCollection = appInitializationSection.GetCollection();
|
||||
ConfigurationElement environmentVariableElement = intializationPagesCollection.CreateElement();
|
||||
environmentVariableElement["initializationPage"] = initializationPage;
|
||||
if (hostName != null)
|
||||
{
|
||||
environmentVariableElement["hostName"] = hostName;
|
||||
}
|
||||
var element = FindElement(intializationPagesCollection, "add", "initializationPage", initializationPage);
|
||||
if (element != null)
|
||||
{
|
||||
if (removeExisting)
|
||||
{
|
||||
intializationPagesCollection.Remove(element);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ApplicationException("duplicated collection item");
|
||||
}
|
||||
}
|
||||
intializationPagesCollection.Add(environmentVariableElement);
|
||||
}
|
||||
else
|
||||
{
|
||||
appInitializationSection[attributeName] = attributeValue;
|
||||
}
|
||||
|
||||
serverManager.CommitChanges();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetANCMConfig(string siteName, string appName, string attributeName, object attributeValue, bool removeExisting = false)
|
||||
{
|
||||
try
|
||||
|
@ -494,7 +573,7 @@ namespace AspNetCoreModule.Test.Framework
|
|||
{
|
||||
if (attributeName == "hostingModel")
|
||||
{
|
||||
if (attributeValue.ToString().ToLower().Trim() == "inprocess")
|
||||
if (attributeValue.ToString().ToLower().Trim() == TestWebApplication.HostingModelValue.Inprocess)
|
||||
{
|
||||
ANCMInprocessMode = true;
|
||||
}
|
||||
|
@ -1271,11 +1350,13 @@ namespace AspNetCoreModule.Test.Framework
|
|||
}
|
||||
}
|
||||
|
||||
public void AddBindingToSite(string siteName, string ipAddress, int port, string host, string protocol = "http")
|
||||
public void AddBindingToSite(string siteName, string ipAddress, int port, string host, string protocol = "http")
|
||||
{
|
||||
string bindingInfo = "";
|
||||
if (ipAddress == null)
|
||||
{
|
||||
ipAddress = "*";
|
||||
}
|
||||
bindingInfo += ipAddress;
|
||||
bindingInfo += ":";
|
||||
bindingInfo += port;
|
||||
|
|
|
@ -305,7 +305,11 @@ namespace AspNetCoreModule.Test.Framework
|
|||
{
|
||||
InitializeIISServer();
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
TestUtility.ResetHelper(ResetHelperMode.KillIISExpress);
|
||||
}
|
||||
|
||||
string siteRootPath = TestRootDirectory;
|
||||
if (!Directory.Exists(siteRootPath))
|
||||
{
|
||||
|
@ -381,7 +385,14 @@ namespace AspNetCoreModule.Test.Framework
|
|||
if (_referenceCount == 0)
|
||||
{
|
||||
TestUtility.LogInformation("InitializeTestMachine::Dispose() Start");
|
||||
TestUtility.ResetHelper(ResetHelperMode.KillIISExpress);
|
||||
try
|
||||
{
|
||||
TestUtility.ResetHelper(ResetHelperMode.KillIISExpress);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignore
|
||||
}
|
||||
RollbackIISApplicationhostConfigFile();
|
||||
TestUtility.LogInformation("InitializeTestMachine::Dispose() End");
|
||||
}
|
||||
|
|
|
@ -642,6 +642,22 @@ namespace AspNetCoreModule.Test.Framework
|
|||
result = true;
|
||||
}
|
||||
}
|
||||
|
||||
query = "Select * from Win32_Process Where Name = \"iisexpresstray.exe\"";
|
||||
searcher = new ManagementObjectSearcher(query);
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -114,6 +114,12 @@ namespace AspNetCoreModule.Test.Framework
|
|||
}
|
||||
}
|
||||
|
||||
public static class HostingModelValue
|
||||
{
|
||||
public static string Inprocess = "inprocess";
|
||||
public static string Outofprocess = "outofprocess";
|
||||
}
|
||||
|
||||
private string _hostingModel = null;
|
||||
public string HostingModel
|
||||
{
|
||||
|
@ -171,7 +177,7 @@ namespace AspNetCoreModule.Test.Framework
|
|||
public string GetProcessFileName()
|
||||
{
|
||||
string result = null;
|
||||
if (this.HostingModel == "inprocess")
|
||||
if (this.HostingModel == TestWebApplication.HostingModelValue.Inprocess)
|
||||
{
|
||||
if (this.IisServerType == ServerType.IIS)
|
||||
{
|
||||
|
|
|
@ -37,7 +37,7 @@ namespace AspNetCoreModule.Test.Framework
|
|||
}
|
||||
catch
|
||||
{
|
||||
if (this.AspNetCoreApp.HostingModel == "inprocess")
|
||||
if (this.AspNetCoreApp.HostingModel == TestWebApplication.HostingModelValue.Inprocess)
|
||||
{
|
||||
// IISExpress seems to be already recycled under Inprocess mode.
|
||||
}
|
||||
|
@ -67,6 +67,8 @@ namespace AspNetCoreModule.Test.Framework
|
|||
}
|
||||
}
|
||||
|
||||
public string ThumbPrint { get; set; }
|
||||
|
||||
public string _siteName = null;
|
||||
public string SiteName
|
||||
{
|
||||
|
@ -156,8 +158,8 @@ namespace AspNetCoreModule.Test.Framework
|
|||
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)
|
||||
|
||||
public TestWebSite(IISConfigUtility.AppPoolBitness appPoolBitness, string loggerPrefix = "ANCMTest", bool startIISExpress = true, bool copyAllPublishedFiles = false, bool attachAppVerifier = false, bool publishing = true, int tcpPort = -1)
|
||||
{
|
||||
_appPoolBitness = appPoolBitness;
|
||||
|
||||
|
@ -253,10 +255,18 @@ namespace AspNetCoreModule.Test.Framework
|
|||
//
|
||||
if (_publishedAspnetCoreApp != true)
|
||||
{
|
||||
string argumentForDotNet = "publish " + srcPath + " --framework " + SDKVersion;
|
||||
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 (publishing == false && File.Exists(Path.Combine(publishPath, "AspNetCoreModule.TestSites.Standard.dll")))
|
||||
{
|
||||
// skip publishing
|
||||
}
|
||||
else
|
||||
{
|
||||
string argumentForDotNet = "publish " + srcPath + " --framework " + SDKVersion;
|
||||
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");
|
||||
|
@ -294,9 +304,6 @@ namespace AspNetCoreModule.Test.Framework
|
|||
TestUtility.FileCopy(Path.Combine(publishPathOutput, "web.config"), Path.Combine(aspnetCoreAppRootPath, "web.config"));
|
||||
}
|
||||
|
||||
int tcpPort = InitializeTestMachine.SiteId++;
|
||||
_siteId = tcpPort;
|
||||
|
||||
//
|
||||
// initialize class member variables
|
||||
//
|
||||
|
@ -314,7 +321,16 @@ namespace AspNetCoreModule.Test.Framework
|
|||
_hostName = "localhost";
|
||||
_siteName = siteName;
|
||||
_postFix = postfix;
|
||||
_tcpPort = tcpPort;
|
||||
if (tcpPort != -1)
|
||||
{
|
||||
_tcpPort = tcpPort;
|
||||
}
|
||||
else
|
||||
{
|
||||
_tcpPort = InitializeTestMachine.SiteId++;
|
||||
InitializeTestMachine.SiteId++;
|
||||
}
|
||||
_siteId = _tcpPort;
|
||||
|
||||
RootAppContext = new TestWebApplication("/", Path.Combine(siteRootPath, "WebSite1"), this);
|
||||
RootAppContext.RestoreFile("web.config");
|
||||
|
@ -385,8 +401,8 @@ namespace AspNetCoreModule.Test.Framework
|
|||
// Configure hostingModel for aspnetcore app
|
||||
if (TestFlags.Enabled(TestFlags.InprocessMode))
|
||||
{
|
||||
AspNetCoreApp.HostingModel = "inprocess";
|
||||
iisConfig.SetANCMConfig(siteName, AspNetCoreApp.Name, "hostingModel", "inprocess");
|
||||
AspNetCoreApp.HostingModel = TestWebApplication.HostingModelValue.Inprocess;
|
||||
iisConfig.SetANCMConfig(siteName, AspNetCoreApp.Name, "hostingModel", TestWebApplication.HostingModelValue.Inprocess);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -405,30 +421,58 @@ namespace AspNetCoreModule.Test.Framework
|
|||
|
||||
public void VerifyWorkerProcessRecycledUnderInprocessMode(string backendProcessId, int timeout = 5000)
|
||||
{
|
||||
if (AspNetCoreApp.HostingModel == "inprocess")
|
||||
if (AspNetCoreApp.HostingModel != TestWebApplication.HostingModelValue.Inprocess)
|
||||
{
|
||||
if (backendProcessId == null)
|
||||
{
|
||||
System.Threading.Thread.Sleep(3000);
|
||||
return; // do nothing for outofprocess
|
||||
}
|
||||
|
||||
bool succeeded = false;
|
||||
for (int i = 0; i < (timeout / 1000); i++)
|
||||
{
|
||||
Process backendProcess = null;
|
||||
try
|
||||
{
|
||||
backendProcess = Process.GetProcessById(Convert.ToInt32(backendProcessId));
|
||||
}
|
||||
else
|
||||
catch
|
||||
{
|
||||
try
|
||||
{
|
||||
var backendProcess = Process.GetProcessById(Convert.ToInt32(backendProcessId));
|
||||
backendProcess.WaitForExit(timeout);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// IISExpress process is already recycled.
|
||||
}
|
||||
succeeded = true;
|
||||
TestUtility.LogInformation("Process not found.");
|
||||
break;
|
||||
}
|
||||
|
||||
if (IisServerType == ServerType.IISExpress)
|
||||
if (backendProcess == null)
|
||||
{
|
||||
// restart IISExpress
|
||||
StartIISExpress();
|
||||
succeeded = true;
|
||||
break;
|
||||
}
|
||||
backendProcess.WaitForExit(1000);
|
||||
|
||||
if (this.IisServerType == ServerType.IISExpress && i == 3)
|
||||
{
|
||||
// exit after 3 seconds for IISExpress case
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (succeeded == false)
|
||||
{
|
||||
if (this.IisServerType == ServerType.IIS)
|
||||
{
|
||||
throw new Exception("Failed to recycle IIS worker process");
|
||||
}
|
||||
else
|
||||
{
|
||||
// IISExpress should be killed if it can't be recycled
|
||||
TestUtility.LogInformation("BugBug: Restart IISExpress...");
|
||||
TestUtility.ResetHelper(ResetHelperMode.KillIISExpress);
|
||||
}
|
||||
}
|
||||
|
||||
if (IisServerType == ServerType.IISExpress)
|
||||
{
|
||||
// restart IISExpress
|
||||
StartIISExpress();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -457,15 +501,9 @@ namespace AspNetCoreModule.Test.Framework
|
|||
_iisExpressPidBackup = TestUtility.RunCommand(cmdline, argument, false, false);
|
||||
}
|
||||
|
||||
public void AttachAppverifier()
|
||||
public string GetAppVerifierPath()
|
||||
{
|
||||
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;
|
||||
string cmdline = null;
|
||||
if (Directory.Exists(Environment.ExpandEnvironmentVariables("%ProgramFiles(x86)%")) && _appPoolBitness == IISConfigUtility.AppPoolBitness.enable32Bit)
|
||||
{
|
||||
cmdline = Path.Combine(Environment.ExpandEnvironmentVariables("%windir%"), "syswow64", "appverif.exe");
|
||||
|
@ -482,6 +520,18 @@ namespace AspNetCoreModule.Test.Framework
|
|||
throw new ApplicationException("Not found :" + cmdline + "; this test requires appverif.exe.");
|
||||
}
|
||||
}
|
||||
return cmdline;
|
||||
}
|
||||
|
||||
public void AttachAppverifier()
|
||||
{
|
||||
string cmdline = GetAppVerifierPath();
|
||||
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;
|
||||
|
||||
try
|
||||
{
|
||||
|
|
|
@ -368,6 +368,16 @@ namespace AspNetCoreModule.Test
|
|||
return DoAppVerifierTest(appPoolBitness, shutdownTimeout, startUpMode, shutDownMode, repeatCount);
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[ANCMTestFlags(ANCMTestCondition)]
|
||||
[OSSkipCondition(OperatingSystems.Linux)]
|
||||
[OSSkipCondition(OperatingSystems.MacOSX)]
|
||||
[InlineData(false)]
|
||||
public Task V21_StressTest(bool enableAppVerifier)
|
||||
{
|
||||
return DoStressTest(enableAppVerifier);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
// NOTE: below test scenarios are not valid for Win7 OS
|
||||
//////////////////////////////////////////////////////////
|
||||
|
|
|
@ -89,7 +89,7 @@ namespace AspNetCoreModule.Test
|
|||
Thread.Sleep(3000);
|
||||
|
||||
string backendProcessId = (await SendReceive(testSite.AspNetCoreApp.GetUri("GetProcessId"))).ResponseBody;
|
||||
if (testSite.AspNetCoreApp.HostingModel == "inprocess" && backendProcessId_old != null)
|
||||
if (testSite.AspNetCoreApp.HostingModel == TestWebApplication.HostingModelValue.Inprocess && backendProcessId_old != null)
|
||||
{
|
||||
Assert.Equal(backendProcessId_old, backendProcessId);
|
||||
}
|
||||
|
@ -370,6 +370,8 @@ namespace AspNetCoreModule.Test
|
|||
bool setEnvironmentVariableConfiguration = true;
|
||||
|
||||
// Set authentication for ASPNETCORE_IIS_HTTPAUTH test scenarios
|
||||
recycledProcessId = (await SendReceive(testSite.AspNetCoreApp.GetUri("GetProcessId"))).ResponseBody;
|
||||
|
||||
if (environmentVariableName == "ASPNETCORE_IIS_HTTPAUTH" && environmentVariableValue != "ignoredValue")
|
||||
{
|
||||
setEnvironmentVariableConfiguration = false;
|
||||
|
@ -408,9 +410,9 @@ namespace AspNetCoreModule.Test
|
|||
expectedValue++;
|
||||
}
|
||||
}
|
||||
Thread.Sleep(500);
|
||||
testSite.VerifyWorkerProcessRecycledUnderInprocessMode(recycledProcessId);
|
||||
|
||||
testSite.VerifyWorkerProcessRecycledUnderInprocessMode(null);
|
||||
Thread.Sleep(500);
|
||||
|
||||
// check JitDebugger before continuing
|
||||
CleanupVSJitDebuggerWindow();
|
||||
|
@ -420,7 +422,7 @@ namespace AspNetCoreModule.Test
|
|||
Assert.True(expectedEnvironmentVariableValue == (await SendReceive(testSite.AspNetCoreApp.GetUri("ExpandEnvironmentVariables" + environmentVariableName))).ResponseBody);
|
||||
|
||||
// verify environment variables passed to backend process
|
||||
if (testSite.AspNetCoreApp.HostingModel != "inprocess")
|
||||
if (testSite.AspNetCoreApp.HostingModel != TestWebApplication.HostingModelValue.Inprocess)
|
||||
{
|
||||
// Verify other common environment variables
|
||||
string temp = (await SendReceive(testSite.AspNetCoreApp.GetUri("DumpEnvironmentVariables"))).ResponseBody;
|
||||
|
@ -453,7 +455,7 @@ namespace AspNetCoreModule.Test
|
|||
string appDllFileName = testSite.AspNetCoreApp.GetArgumentFileName();
|
||||
|
||||
testSite.AspNetCoreApp.CreateFile(new string[] { fileContent }, "App_Offline.Htm");
|
||||
|
||||
|
||||
for (int i = 0; i < _repeatCount; i++)
|
||||
{
|
||||
// check JitDebugger before continuing
|
||||
|
@ -601,7 +603,7 @@ namespace AspNetCoreModule.Test
|
|||
{
|
||||
using (var testSite = new TestWebSite(appPoolBitness, "DoRapidFailsPerMinuteTest"))
|
||||
{
|
||||
if (testSite.AspNetCoreApp.HostingModel == "inprocess")
|
||||
if (testSite.AspNetCoreApp.HostingModel == TestWebApplication.HostingModelValue.Inprocess)
|
||||
{
|
||||
TestUtility.LogInformation("This test is not valid for Inprocess mode");
|
||||
return;
|
||||
|
@ -665,7 +667,7 @@ namespace AspNetCoreModule.Test
|
|||
{
|
||||
using (var testSite = new TestWebSite(appPoolBitness, "DoProcessesPerApplicationTest"))
|
||||
{
|
||||
if (testSite.AspNetCoreApp.HostingModel == "inprocess")
|
||||
if (testSite.AspNetCoreApp.HostingModel == TestWebApplication.HostingModelValue.Inprocess)
|
||||
{
|
||||
TestUtility.LogInformation("This test is not valid for Inprocess mode");
|
||||
return;
|
||||
|
@ -870,7 +872,7 @@ namespace AspNetCoreModule.Test
|
|||
|
||||
public static async Task DoShutdownTimeLimitAndAppOfflineTest(IISConfigUtility.AppPoolBitness appPoolBitness, int valueOfshutdownTimeLimit, int expectedClosingTime, bool isGraceFullShutdownEnabled)
|
||||
{
|
||||
using (var testSite = new TestWebSite(appPoolBitness, "DoShutdownTimeLimitTest", startIISExpress: false))
|
||||
using (var testSite = new TestWebSite(appPoolBitness, "DoShutdownTimeLimitAndAppOfflineTest", startIISExpress: false))
|
||||
{
|
||||
using (var iisConfig = new IISConfigUtility(testSite.IisServerType, testSite.IisExpressConfigPath))
|
||||
{
|
||||
|
@ -1000,6 +1002,13 @@ namespace AspNetCoreModule.Test
|
|||
|
||||
testSite.VerifyWorkerProcessRecycledUnderInprocessMode(backendProcessId);
|
||||
|
||||
//if (testSite.IisServerType == ServerType.IISExpress && testSite.AspNetCoreApp.HostingModel == TestWebApplication.HostingModelValue.Inprocess)
|
||||
//{
|
||||
// // for IISExpress/Inprocess mode, we need to put app_offline to close logfile handle
|
||||
// testSite.AspNetCoreApp.CreateFile(new string[] { "test" }, "App_Offline.Htm");
|
||||
// Thread.Sleep(1000)
|
||||
//}
|
||||
|
||||
Thread.Sleep(2000);
|
||||
startTime = DateTime.Now;
|
||||
Thread.Sleep(1000);
|
||||
|
@ -1037,16 +1046,17 @@ namespace AspNetCoreModule.Test
|
|||
SecurityIdentifier sid = new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null);
|
||||
TestUtility.GiveWritePermissionTo(logPath, sid);
|
||||
|
||||
backendProcessId = (await SendReceive(testSite.AspNetCoreApp.GetUri("GetProcessId"))).ResponseBody;
|
||||
|
||||
startTime = DateTime.Now;
|
||||
Thread.Sleep(500);
|
||||
iisConfig.SetANCMConfig(testSite.SiteName, testSite.AspNetCoreApp.Name, "stdoutLogEnabled", false);
|
||||
|
||||
|
||||
// check JitDebugger before continuing
|
||||
CleanupVSJitDebuggerWindow();
|
||||
iisConfig.SetANCMConfig(testSite.SiteName, testSite.AspNetCoreApp.Name, "stdoutLogEnabled", true);
|
||||
|
||||
testSite.VerifyWorkerProcessRecycledUnderInprocessMode(null);
|
||||
testSite.VerifyWorkerProcessRecycledUnderInprocessMode(backendProcessId);
|
||||
|
||||
Assert.True(backendProcessId != (await SendReceive(testSite.AspNetCoreApp.GetUri("GetProcessId"))).ResponseBody);
|
||||
|
||||
|
@ -1106,7 +1116,7 @@ namespace AspNetCoreModule.Test
|
|||
{
|
||||
using (var testSite = new TestWebSite(appPoolBitness, "DoForwardWindowsAuthTokenTest", startIISExpress: false))
|
||||
{
|
||||
if (testSite.AspNetCoreApp.HostingModel == "inprocess")
|
||||
if (testSite.AspNetCoreApp.HostingModel == TestWebApplication.HostingModelValue.Inprocess)
|
||||
{
|
||||
TestUtility.LogInformation("This test is not valid for Inprocess mode");
|
||||
return;
|
||||
|
@ -1281,8 +1291,6 @@ namespace AspNetCoreModule.Test
|
|||
{
|
||||
using (var testSite = new TestWebSite(appPoolBitness, "DoCompressionTest", startIISExpress: false))
|
||||
{
|
||||
string recycledProcessId = (await SendReceive(testSite.AspNetCoreApp.GetUri("GetProcessId"))).ResponseBody;
|
||||
|
||||
using (var iisConfig = new IISConfigUtility(testSite.IisServerType, testSite.IisExpressConfigPath))
|
||||
{
|
||||
string startupClass = "StartupCompressionCaching";
|
||||
|
@ -1312,6 +1320,7 @@ namespace AspNetCoreModule.Test
|
|||
testSite.AspNetCoreApp.CreateFile(new string[] { "defaulthtm" }, @"wwwroot\default.htm");
|
||||
|
||||
testSite.StartIISExpress();
|
||||
Thread.Sleep(1000);
|
||||
|
||||
SendReceiveContext result = null;
|
||||
if (!useCompressionMiddleWare && !enableIISCompression)
|
||||
|
@ -1351,8 +1360,6 @@ namespace AspNetCoreModule.Test
|
|||
{
|
||||
using (var testSite = new TestWebSite(appPoolBitness, "DoCachingTest", startIISExpress: false))
|
||||
{
|
||||
string recycledProcessId = (await SendReceive(testSite.AspNetCoreApp.GetUri("GetProcessId"))).ResponseBody;
|
||||
|
||||
using (var iisConfig = new IISConfigUtility(testSite.IisServerType, testSite.IisExpressConfigPath))
|
||||
{
|
||||
string startupClass = "StartupCompressionCaching";
|
||||
|
@ -1650,19 +1657,18 @@ namespace AspNetCoreModule.Test
|
|||
|
||||
public static async Task DoWebSocketTest(IISConfigUtility.AppPoolBitness appPoolBitness, string testData)
|
||||
{
|
||||
using (var testSite = new TestWebSite(appPoolBitness, "DoWebSocketTest"))
|
||||
using (var testSite = new TestWebSite(appPoolBitness, "DoWebSocketTest", startIISExpress: false))
|
||||
{
|
||||
string recycledProcessId = (await SendReceive(testSite.AspNetCoreApp.GetUri("GetProcessId"))).ResponseBody;
|
||||
|
||||
string appDllFileName = testSite.AspNetCoreApp.GetArgumentFileName();
|
||||
|
||||
using (var iisConfig = new IISConfigUtility(testSite.IisServerType, testSite.IisExpressConfigPath))
|
||||
{
|
||||
iisConfig.SetANCMConfig(testSite.SiteName, testSite.AspNetCoreApp.Name, "shutdownTimeLimit", 10);
|
||||
|
||||
testSite.VerifyWorkerProcessRecycledUnderInprocessMode(recycledProcessId);
|
||||
}
|
||||
|
||||
testSite.StartIISExpress();
|
||||
|
||||
DateTime startTime = DateTime.Now;
|
||||
|
||||
await SendReceive(testSite.AspNetCoreApp.GetUri(), expectedResponseBody: "Running");
|
||||
|
@ -1744,19 +1750,17 @@ namespace AspNetCoreModule.Test
|
|||
|
||||
public static async Task DoWebSocketAppOfflineTest(IISConfigUtility.AppPoolBitness appPoolBitness, string testData)
|
||||
{
|
||||
using (var testSite = new TestWebSite(appPoolBitness, "DoWebSocketTest"))
|
||||
using (var testSite = new TestWebSite(appPoolBitness, "DoWebSocketAppOfflineTest", startIISExpress: false))
|
||||
{
|
||||
string recycledProcessId = (await SendReceive(testSite.AspNetCoreApp.GetUri("GetProcessId"))).ResponseBody;
|
||||
|
||||
string appDllFileName = testSite.AspNetCoreApp.GetArgumentFileName();
|
||||
|
||||
using (var iisConfig = new IISConfigUtility(testSite.IisServerType, testSite.IisExpressConfigPath))
|
||||
{
|
||||
iisConfig.SetANCMConfig(testSite.SiteName, testSite.AspNetCoreApp.Name, "shutdownTimeLimit", 10);
|
||||
|
||||
testSite.VerifyWorkerProcessRecycledUnderInprocessMode(recycledProcessId);
|
||||
}
|
||||
|
||||
testSite.StartIISExpress();
|
||||
|
||||
DateTime startTime = DateTime.Now;
|
||||
|
||||
// Get Process ID
|
||||
|
@ -1787,6 +1791,8 @@ namespace AspNetCoreModule.Test
|
|||
|
||||
// put app_offline
|
||||
testSite.AspNetCoreApp.CreateFile(new string[] { fileContent }, "App_Offline.Htm");
|
||||
|
||||
//websocketClient.ExpectedDisposedConnection = true;
|
||||
bool connectionClosedFromServer = websocketClient.WaitForWebSocketState(WebSocketState.ConnectionClosed);
|
||||
|
||||
//if (connectionClosedFromServer)
|
||||
|
@ -1830,7 +1836,7 @@ namespace AspNetCoreModule.Test
|
|||
|
||||
public static async Task DoWebSocketRecycledWithConfigChangeTest(IISConfigUtility.AppPoolBitness appPoolBitness, string testData)
|
||||
{
|
||||
using (var testSite = new TestWebSite(appPoolBitness, "DoWebSocketTest"))
|
||||
using (var testSite = new TestWebSite(appPoolBitness, "DoWebSocketRecycledWithConfigChangeTest"))
|
||||
{
|
||||
string recycledProcessId = (await SendReceive(testSite.AspNetCoreApp.GetUri("GetProcessId"))).ResponseBody;
|
||||
|
||||
|
@ -2115,7 +2121,7 @@ namespace AspNetCoreModule.Test
|
|||
// Set Shutdown delay time to give more time for the backend program to do the gracefulshutdown
|
||||
int shutdownDelayTime = 5000;
|
||||
iisConfig.SetANCMConfig(testSite.SiteName, testSite.AspNetCoreApp.Name, "environmentVariable", new string[] { "ANCMTestShutdownDelay", shutdownDelayTime.ToString() });
|
||||
|
||||
|
||||
if (startUpMode != DoAppVerifierTest_StartUpMode.DontUseGracefulShutdown)
|
||||
{
|
||||
// Verify websocket with app_offline.htm
|
||||
|
@ -2143,12 +2149,12 @@ namespace AspNetCoreModule.Test
|
|||
// put app_offline
|
||||
testSite.AspNetCoreApp.CreateFile(new string[] { "test" }, "App_Offline.Htm");
|
||||
Thread.Sleep(1000);
|
||||
|
||||
|
||||
// wait for the gracefulshutdown finished
|
||||
Thread.Sleep(shutdownDelayTime);
|
||||
|
||||
bool connectionClosedFromServer = websocketClient.WaitForWebSocketState(WebSocketState.ConnectionClosed);
|
||||
|
||||
|
||||
// Verify server side connection closing is done successfully
|
||||
Assert.True(connectionClosedFromServer, "Closing Handshake initiated from Server");
|
||||
|
||||
|
@ -2164,10 +2170,10 @@ namespace AspNetCoreModule.Test
|
|||
// reset shutdownDelayTime
|
||||
shutdownDelayTime = 0;
|
||||
iisConfig.SetANCMConfig(
|
||||
testSite.SiteName,
|
||||
testSite.AspNetCoreApp.Name,
|
||||
"environmentVariable",
|
||||
new string[] { "ANCMTestShutdownDelay", shutdownDelayTime.ToString() },
|
||||
testSite.SiteName,
|
||||
testSite.AspNetCoreApp.Name,
|
||||
"environmentVariable",
|
||||
new string[] { "ANCMTestShutdownDelay", shutdownDelayTime.ToString() },
|
||||
removeExisting: true); // reset existing correction item
|
||||
|
||||
// Verify websocket again
|
||||
|
@ -2272,6 +2278,245 @@ namespace AspNetCoreModule.Test
|
|||
}
|
||||
}
|
||||
|
||||
public static async Task DoStressTest(bool enableAppVerifier)
|
||||
{
|
||||
if (!File.Exists(Environment.ExpandEnvironmentVariables("%systemdrive%\\ANCMStressTest.TXT")))
|
||||
{
|
||||
TestUtility.LogInformation("Skipping stress test");
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// While running this test, start stressing with running below command in a seperate powershell window
|
||||
//
|
||||
// (1..1000) | foreach { (Invoke-WebRequest http://localhost:1234/aspnetcoreapp/getprocessid).StatusCode; }
|
||||
//
|
||||
|
||||
int timeoutValue = 5;
|
||||
int numberOfSite = 0;
|
||||
|
||||
int tcpPort = 1234 + numberOfSite;
|
||||
TestWebSite testSite = new TestWebSite(IISConfigUtility.AppPoolBitness.noChange, "DoStressTest", startIISExpress: false, publishing: false, tcpPort: tcpPort);
|
||||
InitializeSite(testSite, timeoutValue : timeoutValue);
|
||||
numberOfSite++;
|
||||
|
||||
tcpPort = 1234 + numberOfSite;
|
||||
TestWebSite testSite2 = new TestWebSite(IISConfigUtility.AppPoolBitness.noChange, "DoStressTest2", startIISExpress: false, publishing: false, tcpPort: 1234 + numberOfSite);
|
||||
InitializeSite(testSite2, timeoutValue: timeoutValue, disableGracefulShutdown: true);
|
||||
numberOfSite++;
|
||||
|
||||
tcpPort = 1234 + numberOfSite;
|
||||
TestWebSite testSite3 = new TestWebSite(IISConfigUtility.AppPoolBitness.enable32Bit, "DoStressTest3", startIISExpress: false, publishing: false, tcpPort: 1234 + numberOfSite);
|
||||
InitializeSite(testSite3, timeoutValue: timeoutValue, disableGracefulShutdown: true);
|
||||
numberOfSite++;
|
||||
|
||||
if (enableAppVerifier)
|
||||
{
|
||||
// enable AppVerifier
|
||||
testSite.AttachAppverifier();
|
||||
}
|
||||
|
||||
// reset existing worker process process
|
||||
TestUtility.ResetHelper(ResetHelperMode.KillWorkerProcess);
|
||||
Thread.Sleep(1000);
|
||||
|
||||
try
|
||||
{
|
||||
///////////////////////////////////
|
||||
// Start test sceanrio
|
||||
///////////////////////////////////
|
||||
using (var iisConfig = new IISConfigUtility(testSite.IisServerType, testSite.IisExpressConfigPath))
|
||||
{
|
||||
bool attachDebugger = true;
|
||||
for (int i=0; i<10; i++)
|
||||
{
|
||||
if (enableAppVerifier)
|
||||
{
|
||||
if (attachDebugger)
|
||||
{
|
||||
// send a startup request to start a new worker process
|
||||
TestUtility.RunPowershellScript("( invoke-webrequest http://localhost:" + testSite.TcpPort + " ).StatusCode", "200", retryCount: 5);
|
||||
Thread.Sleep(1000);
|
||||
|
||||
// attach debugger to the worker process
|
||||
testSite.WorkerProcessID = 0;
|
||||
|
||||
// attach debugger
|
||||
testSite.AttachWinDbg(testSite.WorkerProcessID, "sxi 80000003;g");
|
||||
|
||||
// verify windbg process is started
|
||||
await SendReceive(testSite.AspNetCoreApp.GetUri(), expectedResponseBody: "Running", timeout: 10);
|
||||
TestUtility.RunPowershellScript("(get-process -name windbg 2> $null).count", "1", retryCount: 5);
|
||||
|
||||
attachDebugger = false;
|
||||
}
|
||||
|
||||
// verify debugger is running
|
||||
TestUtility.RunPowershellScript("(get-process -name windbg 2> $null).count", "1", retryCount: 1);
|
||||
}
|
||||
|
||||
// put delay time for each iteration
|
||||
Thread.Sleep(3000);
|
||||
|
||||
// reset worker process id to refresh
|
||||
testSite.WorkerProcessID = 0;
|
||||
|
||||
switch (i % 7)
|
||||
{
|
||||
case 0:
|
||||
|
||||
// StopAndStartAppPool:
|
||||
iisConfig.StopAppPool(testSite.AspNetCoreApp.AppPoolName);
|
||||
Thread.Sleep((timeoutValue + 1) * 1000);
|
||||
iisConfig.StartAppPool(testSite.AspNetCoreApp.AppPoolName);
|
||||
Thread.Sleep((timeoutValue + 1) * 1000);
|
||||
|
||||
attachDebugger = true;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
|
||||
// CreateAppOfflineHtm
|
||||
testSite.AspNetCoreApp.DeleteFile("App_Offline.Htm");
|
||||
testSite.AspNetCoreApp.CreateFile(new string[] { "test" }, "App_Offline.Htm");
|
||||
break;
|
||||
|
||||
case 2:
|
||||
|
||||
// Re-create AppOfflineHtm
|
||||
testSite.AspNetCoreApp.DeleteFile("App_Offline.Htm");
|
||||
testSite.AspNetCoreApp.CreateFile(new string[] { "test" }, "App_Offline.Htm");
|
||||
break;
|
||||
|
||||
case 3:
|
||||
|
||||
// Rename appOfflineHtm
|
||||
testSite.AspNetCoreApp.MoveFile("App_Offline.Htm", "_App_Offline.Htm");
|
||||
break;
|
||||
|
||||
case 4:
|
||||
|
||||
// ConfigurationChangeNotification
|
||||
iisConfig.SetANCMConfig(testSite.SiteName, testSite.AspNetCoreApp.Name, "shutdownTimeLimit", timeoutValue + 1);
|
||||
Thread.Sleep(1000);
|
||||
iisConfig.SetANCMConfig(testSite.SiteName, testSite.AspNetCoreApp.Name, "shutdownTimeLimit", timeoutValue - 1);
|
||||
Thread.Sleep(1000);
|
||||
|
||||
if (testSite.AspNetCoreApp.HostingModel == TestWebApplication.HostingModelValue.Inprocess)
|
||||
{
|
||||
attachDebugger = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case 5:
|
||||
iisConfig.SetAppPoolSetting(testSite.AspNetCoreApp.AppPoolName, "enable32BitAppOnWin64", true);
|
||||
break;
|
||||
|
||||
case 6:
|
||||
iisConfig.SetAppPoolSetting(testSite.AspNetCoreApp.AppPoolName, "enable32BitAppOnWin64", false);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Exception("Not supported value");
|
||||
}
|
||||
}
|
||||
|
||||
InitializeSite(testSite, cleanup: true);
|
||||
InitializeSite(testSite2, cleanup: true);
|
||||
InitializeSite(testSite3, cleanup: true);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (enableAppVerifier)
|
||||
{
|
||||
// cleanup Appverifier
|
||||
if (testSite != null)
|
||||
{
|
||||
testSite.DetachAppverifier();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TestUtility.ResetHelper(ResetHelperMode.KillWorkerProcess);
|
||||
|
||||
if (enableAppVerifier)
|
||||
{
|
||||
// cleanup windbg process incase it is still running
|
||||
TestUtility.RunPowershellScript("stop-process -Name windbg -Force -Confirm:$false 2> $null");
|
||||
}
|
||||
}
|
||||
|
||||
private static void InitializeSite(TestWebSite testSite, int timeoutValue = 0, bool disableGracefulShutdown = false, bool cleanup = false)
|
||||
{
|
||||
using (var iisConfig = new IISConfigUtility(testSite.IisServerType, testSite.IisExpressConfigPath))
|
||||
{
|
||||
string hexIPAddress = "0x00";
|
||||
int sslPort = testSite.TcpPort + 6300;
|
||||
|
||||
if (cleanup)
|
||||
{
|
||||
// Remove the SSL Certificate mapping
|
||||
iisConfig.RemoveSSLCertificate(sslPort, hexIPAddress);
|
||||
|
||||
// Remove the newly created self signed certificate
|
||||
iisConfig.DeleteCertificate(testSite.ThumbPrint);
|
||||
|
||||
// Remove the exported self signed certificate on rootCA
|
||||
iisConfig.DeleteCertificate(testSite.ThumbPrint, @"Cert:\LocalMachine\Root");
|
||||
return;
|
||||
}
|
||||
|
||||
string hostName = "";
|
||||
string subjectName = "localhost";
|
||||
string ipAddress = "*";
|
||||
string thumbPrint = null;
|
||||
if (disableGracefulShutdown)
|
||||
{
|
||||
// disable graceful shutdown for the second site
|
||||
iisConfig.SetANCMConfig(testSite.SiteName, testSite.AspNetCoreApp.Name, "environmentVariable", new string[] { "GracefulShutdown", "disabled" });
|
||||
}
|
||||
|
||||
// Add https binding and get https uri information
|
||||
iisConfig.AddBindingToSite(testSite.SiteName, ipAddress, sslPort, hostName, "https");
|
||||
|
||||
// Create a self signed certificate
|
||||
thumbPrint = iisConfig.CreateSelfSignedCertificate(subjectName);
|
||||
|
||||
// Export the self signed certificate to rootCA
|
||||
iisConfig.ExportCertificateTo(thumbPrint, sslStoreTo: @"Cert:\LocalMachine\Root");
|
||||
|
||||
// Configure http.sys ssl certificate mapping to IP:Port endpoint with the newly created self signed certificage
|
||||
iisConfig.SetSSLCertificate(sslPort, hexIPAddress, thumbPrint);
|
||||
testSite.ThumbPrint = thumbPrint;
|
||||
|
||||
// enable preloadEnabled for the site
|
||||
iisConfig.SetSiteRooAppConfig(testSite.SiteName, "preloadEnabled", true);
|
||||
iisConfig.SetWarmUpConfig(testSite.SiteName, testSite.AspNetCoreApp.Name, "skipManagedModules", true);
|
||||
iisConfig.SetWarmUpConfig(testSite.SiteName, testSite.AspNetCoreApp.Name, "doAppInitAfterRestart", true);
|
||||
iisConfig.SetWarmUpConfig(testSite.SiteName, testSite.AspNetCoreApp.Name, "initializationPage", "DoSleep1000");
|
||||
|
||||
// Set shutdownTimeLimit with 3 seconds and use 5 seconds for delay time to make the shutdownTimeout happen
|
||||
iisConfig.SetANCMConfig(testSite.SiteName, testSite.AspNetCoreApp.Name, "shutdownTimeLimit", timeoutValue);
|
||||
|
||||
// set requestTimeout
|
||||
iisConfig.SetANCMConfig(testSite.SiteName, testSite.AspNetCoreApp.Name, "requestTimeout", TimeSpan.Parse("00:00:5")); // 5 seconds
|
||||
|
||||
// set startupTimeout
|
||||
iisConfig.SetANCMConfig(testSite.SiteName, testSite.AspNetCoreApp.Name, "startupTimeLimit", timeoutValue);
|
||||
|
||||
// Set shutdownTimeLimit
|
||||
iisConfig.SetANCMConfig(testSite.SiteName, testSite.AspNetCoreApp.Name, "shutdownTimeLimit", timeoutValue);
|
||||
|
||||
// Set starupTimeLimit and shutdownTimeLimit for test app
|
||||
iisConfig.SetANCMConfig(testSite.SiteName, testSite.AspNetCoreApp.Name, "environmentVariable", new string[] { "ANCMTestShutdownDelay", "1000" });
|
||||
iisConfig.SetANCMConfig(testSite.SiteName, testSite.AspNetCoreApp.Name, "environmentVariable", new string[] { "ANCMTestStartupDelay", "1000" });
|
||||
|
||||
// starting IISExpress was deffered after creating test applications and now it is ready to start.
|
||||
testSite.StartIISExpress();
|
||||
}
|
||||
}
|
||||
|
||||
private static bool CleanupVSJitDebuggerWindow()
|
||||
{
|
||||
bool result = TestUtility.ResetHelper(ResetHelperMode.KillVSJitDebugger);
|
||||
|
|
|
@ -16,5 +16,8 @@
|
|||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.1.0-preview1-28291" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="wwwroot\" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -88,7 +88,8 @@ namespace AspnetCoreModule.TestSites.Standard
|
|||
}
|
||||
host = WebHost.CreateDefaultBuilder(args)
|
||||
.UseConfiguration(config)
|
||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||
// BUGBUG below line is commented out because it causes 404 error with inprocess mode
|
||||
//.UseContentRoot(Directory.GetCurrentDirectory())
|
||||
.UseStartup<StartupCompressionCaching>()
|
||||
.Build();
|
||||
}
|
||||
|
|
|
@ -390,10 +390,11 @@ namespace AspnetCoreModule.TestSites.Standard
|
|||
// Sleep before starting
|
||||
if (Startup.SleeptimeWhileStarting > 0)
|
||||
{
|
||||
Console.WriteLine("Begin: SleeptimeWhileStarting " + Startup.SleeptimeWhileStarting);
|
||||
Thread.Sleep(Startup.SleeptimeWhileStarting);
|
||||
Console.WriteLine("End: SleeptimeWhileStarting");
|
||||
int temp = Startup.SleeptimeWhileStarting;
|
||||
Startup.SleeptimeWhileStarting = 0;
|
||||
Console.WriteLine("Begin: SleeptimeWhileStarting " + temp);
|
||||
Thread.Sleep(temp);
|
||||
Console.WriteLine("End: SleeptimeWhileStarting");
|
||||
}
|
||||
|
||||
return context.Response.WriteAsync(response);
|
||||
|
|
|
@ -55,7 +55,8 @@ namespace AspnetCoreModule.TestSites.Standard
|
|||
context.Context.Response.ContentType = "text/plain";
|
||||
}
|
||||
}
|
||||
);
|
||||
);
|
||||
app.UseStaticFiles();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,366 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title></title>
|
||||
<style>
|
||||
table {
|
||||
border: 0
|
||||
}
|
||||
|
||||
.commslog-data {
|
||||
font-family: Consolas, Courier New, Courier, monospace;
|
||||
}
|
||||
|
||||
.commslog-server {
|
||||
background-color: red;
|
||||
color: white
|
||||
}
|
||||
|
||||
.commslog-client {
|
||||
background-color: green;
|
||||
color: white
|
||||
}
|
||||
</style>
|
||||
|
||||
<style type="text/css">
|
||||
body {
|
||||
background-repeat: no-repeat;
|
||||
padding-top: 85px;
|
||||
font-family: Trebuchet MS, Lucida Sans Unicode, Arial, sans-serif;
|
||||
font-size: 0.9em;
|
||||
line-height: 130%;
|
||||
}
|
||||
|
||||
.selectBoxArrow {
|
||||
margin-top: 1px;
|
||||
float: left;
|
||||
position: absolute;
|
||||
right: 1px;
|
||||
}
|
||||
|
||||
.selectBoxInput {
|
||||
border: 0px;
|
||||
padding-left: 1px;
|
||||
height: 16px;
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
width: 600px;
|
||||
}
|
||||
|
||||
.selectBox {
|
||||
border: 1px solid #7f9db9;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.selectBoxOptionContainer {
|
||||
position: absolute;
|
||||
border: 1px solid #7f9db9;
|
||||
height: 100px;
|
||||
background-color: #FFF;
|
||||
left: -1px;
|
||||
top: 20px;
|
||||
visibility: hidden;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.selectBoxAnOption {
|
||||
font-family: arial;
|
||||
font-size: 12px;
|
||||
cursor: default;
|
||||
margin: 1px;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.selectBoxIframe {
|
||||
position: absolute;
|
||||
background-color: #FFF;
|
||||
border: 0px;
|
||||
z-index: 999;
|
||||
}
|
||||
</style>
|
||||
<script type="text/javascript">
|
||||
|
||||
// Path to arrow images
|
||||
var arrowImage = './images/select_arrow.gif'; // Regular arrow
|
||||
var arrowImageOver = './images/select_arrow_over.gif'; // Mouse over
|
||||
var arrowImageDown = './images/select_arrow_down.gif'; // Mouse down
|
||||
|
||||
var selectBoxIds = 0;
|
||||
var currentlyOpenedOptionBox = false;
|
||||
var editableSelect_activeArrow = false;
|
||||
|
||||
function selectBox_switchImageUrl() {
|
||||
if (this.src.indexOf(arrowImage) >= 0) {
|
||||
this.src = this.src.replace(arrowImage, arrowImageOver);
|
||||
} else {
|
||||
this.src = this.src.replace(arrowImageOver, arrowImage);
|
||||
}
|
||||
}
|
||||
|
||||
function selectBox_showOptions() {
|
||||
if (editableSelect_activeArrow && editableSelect_activeArrow != this) {
|
||||
editableSelect_activeArrow.src = arrowImage;
|
||||
}
|
||||
editableSelect_activeArrow = this;
|
||||
|
||||
var numId = this.id.replace(/[^\d]/g, '');
|
||||
var optionDiv = document.getElementById('selectBoxOptions' + numId);
|
||||
if (optionDiv.style.display == 'block') {
|
||||
optionDiv.style.display = 'none';
|
||||
if (navigator.userAgent.indexOf('MSIE') >= 0) document.getElementById('selectBoxIframe' + numId).style.display = 'none';
|
||||
this.src = arrowImageOver;
|
||||
} else {
|
||||
optionDiv.style.display = 'block';
|
||||
if (navigator.userAgent.indexOf('MSIE') >= 0) document.getElementById('selectBoxIframe' + numId).style.display = 'block';
|
||||
this.src = arrowImageDown;
|
||||
if (currentlyOpenedOptionBox && currentlyOpenedOptionBox != optionDiv) currentlyOpenedOptionBox.style.display = 'none';
|
||||
currentlyOpenedOptionBox = optionDiv;
|
||||
}
|
||||
}
|
||||
|
||||
function selectOptionValue() {
|
||||
var parentNode = this.parentNode.parentNode;
|
||||
var textInput = parentNode.getElementsByTagName('INPUT')[0];
|
||||
textInput.value = this.innerHTML;
|
||||
this.parentNode.style.display = 'none';
|
||||
document.getElementById('arrowSelectBox' + parentNode.id.replace(/[^\d]/g, '')).src = arrowImageOver;
|
||||
|
||||
if (navigator.userAgent.indexOf('MSIE') >= 0) document.getElementById('selectBoxIframe' + parentNode.id.replace(/[^\d]/g, '')).style.display = 'none';
|
||||
|
||||
}
|
||||
|
||||
var activeOption;
|
||||
function highlightSelectBoxOption() {
|
||||
if (this.style.backgroundColor == '#316AC5') {
|
||||
this.style.backgroundColor = '';
|
||||
this.style.color = '';
|
||||
} else {
|
||||
this.style.backgroundColor = '#316AC5';
|
||||
this.style.color = '#FFF';
|
||||
}
|
||||
|
||||
if (activeOption) {
|
||||
activeOption.style.backgroundColor = '';
|
||||
activeOption.style.color = '';
|
||||
}
|
||||
activeOption = this;
|
||||
}
|
||||
|
||||
function createEditableSelect(dest) {
|
||||
dest.className = 'selectBoxInput';
|
||||
var div = document.createElement('DIV');
|
||||
div.style.styleFloat = 'left';
|
||||
div.style.width = dest.offsetWidth + 16 + 'px';
|
||||
div.style.position = 'relative';
|
||||
div.id = 'selectBox' + selectBoxIds;
|
||||
var parent = dest.parentNode;
|
||||
parent.insertBefore(div, dest);
|
||||
div.appendChild(dest);
|
||||
div.className = 'selectBox';
|
||||
div.style.zIndex = 10000 - selectBoxIds;
|
||||
|
||||
var img = document.createElement('IMG');
|
||||
img.src = arrowImage;
|
||||
img.className = 'selectBoxArrow';
|
||||
|
||||
img.onmouseover = selectBox_switchImageUrl;
|
||||
img.onmouseout = selectBox_switchImageUrl;
|
||||
img.onclick = selectBox_showOptions;
|
||||
img.id = 'arrowSelectBox' + selectBoxIds;
|
||||
|
||||
div.appendChild(img);
|
||||
|
||||
var optionDiv = document.createElement('DIV');
|
||||
optionDiv.id = 'selectBoxOptions' + selectBoxIds;
|
||||
optionDiv.className = 'selectBoxOptionContainer';
|
||||
optionDiv.style.width = div.offsetWidth - 2 + 'px';
|
||||
div.appendChild(optionDiv);
|
||||
|
||||
if (navigator.userAgent.indexOf('MSIE') >= 0) {
|
||||
var iframe = document.createElement('<IFRAME src="about:blank" frameborder=0>');
|
||||
iframe.style.width = optionDiv.style.width;
|
||||
iframe.style.height = optionDiv.offsetHeight + 'px';
|
||||
iframe.style.display = 'none';
|
||||
iframe.id = 'selectBoxIframe' + selectBoxIds;
|
||||
div.appendChild(iframe);
|
||||
}
|
||||
|
||||
if (dest.getAttribute('selectBoxOptions')) {
|
||||
var options = dest.getAttribute('selectBoxOptions').split(';');
|
||||
var optionsTotalHeight = 0;
|
||||
var optionArray = new Array();
|
||||
for (var no = 0; no < options.length; no++) {
|
||||
var anOption = document.createElement('DIV');
|
||||
anOption.innerHTML = options[no];
|
||||
anOption.className = 'selectBoxAnOption';
|
||||
anOption.onclick = selectOptionValue;
|
||||
anOption.style.width = optionDiv.style.width.replace('px', '') - 2 + 'px';
|
||||
anOption.onmouseover = highlightSelectBoxOption;
|
||||
optionDiv.appendChild(anOption);
|
||||
optionsTotalHeight = optionsTotalHeight + anOption.offsetHeight;
|
||||
optionArray.push(anOption);
|
||||
}
|
||||
if (optionsTotalHeight > optionDiv.offsetHeight) {
|
||||
for (var no = 0; no < optionArray.length; no++) {
|
||||
optionArray[no].style.width = optionDiv.style.width.replace('px', '') - 22 + 'px';
|
||||
}
|
||||
}
|
||||
optionDiv.style.display = 'none';
|
||||
optionDiv.style.visibility = 'visible';
|
||||
}
|
||||
selectBoxIds = selectBoxIds + 1;
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1>WebSocket Sample Application</h1>
|
||||
<p id="stateLabel">Ready to connect...</p>
|
||||
<div>
|
||||
<label for="connectionUrl">WebSocket Server URL:</label>
|
||||
<input id="connectionUrl" />
|
||||
<button id="connectButton" type="submit">Connect</button>
|
||||
</div>
|
||||
<p></p>
|
||||
<div>
|
||||
<label for="sendMessage">Message to send:</label>
|
||||
<input id="sendMessage" disabled selectBoxOptions="CloseFromServerBugRepro;CloseFromServerWithIgnoringExceptionError" />
|
||||
<button id="sendButton" type="submit" disabled>Send</button>
|
||||
<button id="closeButton" disabled>Close Socket</button>
|
||||
<button id="clearButton">Clear Log</button>
|
||||
</div>
|
||||
<h2>Communication Log</h2>
|
||||
<table style="width: 800px">
|
||||
<thead>
|
||||
<tr>
|
||||
<td style="width: 100px">From</td>
|
||||
<td style="width: 100px">To</td>
|
||||
<td>Data</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="commsLog"></tbody>
|
||||
</table>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
createEditableSelect(document.getElementById("sendMessage"));
|
||||
|
||||
</script>
|
||||
|
||||
<script>
|
||||
var connectionForm = document.getElementById("connectionForm");
|
||||
var connectionUrl = document.getElementById("connectionUrl");
|
||||
var connectButton = document.getElementById("connectButton");
|
||||
var stateLabel = document.getElementById("stateLabel");
|
||||
var sendMessage = document.getElementById("sendMessage");
|
||||
var sendButton = document.getElementById("sendButton");
|
||||
var sendForm = document.getElementById("sendForm");
|
||||
var commsLog = document.getElementById("commsLog");
|
||||
|
||||
var socket;
|
||||
|
||||
var scheme = document.location.protocol == "https:" ? "wss" : "ws";
|
||||
var port = document.location.port ? (":" + document.location.port) : "";
|
||||
|
||||
connectionUrl.value = scheme + "://" + document.location.hostname + port + "/ws";
|
||||
|
||||
function updateState() {
|
||||
function disable() {
|
||||
sendMessage.disabled = true;
|
||||
sendButton.disabled = true;
|
||||
closeButton.disabled = true;
|
||||
}
|
||||
function enable() {
|
||||
sendMessage.disabled = false;
|
||||
sendButton.disabled = false;
|
||||
closeButton.disabled = false;
|
||||
}
|
||||
|
||||
connectionUrl.disabled = true;
|
||||
connectButton.disabled = true;
|
||||
|
||||
if (!socket) {
|
||||
disable();
|
||||
} else {
|
||||
switch (socket.readyState) {
|
||||
case WebSocket.CLOSED:
|
||||
stateLabel.innerHTML = "Closed";
|
||||
disable();
|
||||
connectionUrl.disabled = false;
|
||||
connectButton.disabled = false;
|
||||
break;
|
||||
case WebSocket.CLOSING:
|
||||
stateLabel.innerHTML = "Closing...";
|
||||
disable();
|
||||
break;
|
||||
case WebSocket.CONNECTING:
|
||||
stateLabel.innerHTML = "Connecting...";
|
||||
disable();
|
||||
break;
|
||||
case WebSocket.OPEN:
|
||||
stateLabel.innerHTML = "Open";
|
||||
enable();
|
||||
break;
|
||||
default:
|
||||
stateLabel.innerHTML = "Unknown WebSocket State: " + socket.readyState;
|
||||
disable();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
closeButton.onclick = function () {
|
||||
if (!socket || socket.readyState != WebSocket.OPEN) {
|
||||
alert("socket not connected");
|
||||
}
|
||||
socket.close(1000, "Closing from client");
|
||||
}
|
||||
|
||||
clearButton.onclick = function () {
|
||||
var table = document.getElementById("commsLog");
|
||||
table.innerHTML = "";
|
||||
}
|
||||
|
||||
sendButton.onclick = function () {
|
||||
if (!socket || socket.readyState != WebSocket.OPEN) {
|
||||
alert("socket not connected");
|
||||
}
|
||||
var data = sendMessage.value;
|
||||
socket.send(data);
|
||||
//document.getElementById("sendMessage").value = "";
|
||||
commsLog.innerHTML += '<tr>' +
|
||||
'<td class="commslog-client">Client</td>' +
|
||||
'<td class="commslog-server">Server</td>' +
|
||||
'<td class="commslog-data">' + data + '</td>'
|
||||
'</tr>';
|
||||
}
|
||||
|
||||
connectButton.onclick = function () {
|
||||
stateLabel.innerHTML = "Connecting";
|
||||
socket = new WebSocket(connectionUrl.value);
|
||||
socket.onopen = function (event) {
|
||||
updateState();
|
||||
commsLog.innerHTML += '<tr>' +
|
||||
'<td colspan="3" class="commslog-data">Connection opened</td>' +
|
||||
'</tr>';
|
||||
};
|
||||
socket.onclose = function (event) {
|
||||
updateState();
|
||||
commsLog.innerHTML += '<tr>' +
|
||||
'<td colspan="3" class="commslog-data">Connection closed. Code: ' + event.code + '. Reason: ' + event.reason + '</td>' +
|
||||
'</tr>';
|
||||
};
|
||||
socket.onerror = updateState;
|
||||
socket.onmessage = function (event) {
|
||||
commsLog.innerHTML += '<tr>' +
|
||||
'<td class="commslog-server">Server</td>' +
|
||||
'<td class="commslog-client">Client</td>' +
|
||||
'<td class="commslog-data">' + event.data + '</td>'
|
||||
'</tr>';
|
||||
};
|
||||
};
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1 @@
|
|||
test.htm
|
Загрузка…
Ссылка в новой задаче