diff --git a/.gitignore b/.gitignore
index 216e8d9c58..be311a1f7d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -23,4 +23,5 @@ nuget.exe
*DS_Store
*.ncrunchsolution
*.*sdf
-*.ipch
\ No newline at end of file
+*.ipch
+project.lock.json
\ No newline at end of file
diff --git a/ServerTests.sln b/ServerTests.sln
new file mode 100644
index 0000000000..7a7cebf0a7
--- /dev/null
+++ b/ServerTests.sln
@@ -0,0 +1,41 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+VisualStudioVersion = 14.0.22807.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{5B0A1907-2525-4081-AE14-255D3CE65B62}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{49AB8AAA-8160-48DF-A18B-78F51E54E02A}"
+ ProjectSection(SolutionItems) = preProject
+ global.json = global.json
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{FA91F388-F4AF-4850-9D68-D4D128E6B1A6}"
+EndProject
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "ServerComparison.FunctionalTests", "test\ServerComparison.FunctionalTests\ServerComparison.FunctionalTests.xproj", "{A319ACCE-060B-4385-9534-9F2202F6180E}"
+EndProject
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "ServerComparison.TestSites", "test\ServerComparison.TestSites\ServerComparison.TestSites.xproj", "{030225D8-4EE8-47E5-B692-2A96B3B51A38}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {A319ACCE-060B-4385-9534-9F2202F6180E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A319ACCE-060B-4385-9534-9F2202F6180E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A319ACCE-060B-4385-9534-9F2202F6180E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A319ACCE-060B-4385-9534-9F2202F6180E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {030225D8-4EE8-47E5-B692-2A96B3B51A38}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {030225D8-4EE8-47E5-B692-2A96B3B51A38}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {030225D8-4EE8-47E5-B692-2A96B3B51A38}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {030225D8-4EE8-47E5-B692-2A96B3B51A38}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {A319ACCE-060B-4385-9534-9F2202F6180E} = {FA91F388-F4AF-4850-9D68-D4D128E6B1A6}
+ {030225D8-4EE8-47E5-B692-2A96B3B51A38} = {FA91F388-F4AF-4850-9D68-D4D128E6B1A6}
+ EndGlobalSection
+EndGlobal
diff --git a/src/Placeholder/project.json b/src/Placeholder/project.json
new file mode 100644
index 0000000000..2c63c08510
--- /dev/null
+++ b/src/Placeholder/project.json
@@ -0,0 +1,2 @@
+{
+}
diff --git a/test/ServerComparison.FunctionalTests/HelloWorldTest.cs b/test/ServerComparison.FunctionalTests/HelloWorldTest.cs
new file mode 100644
index 0000000000..77f9c631b1
--- /dev/null
+++ b/test/ServerComparison.FunctionalTests/HelloWorldTest.cs
@@ -0,0 +1,123 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Diagnostics;
+using System.Net.Http;
+using System.Threading.Tasks;
+using DeploymentHelpers;
+using Microsoft.AspNet.Testing.xunit;
+using Microsoft.Framework.Logging;
+using Xunit;
+
+namespace ServerComparison.FunctionalTests
+{
+ // Uses ports ranging 5061 - 5069.
+ public class HelloWorldTests
+ {
+ [ConditionalTheory]
+ [OSSkipCondition(OperatingSystems.Unix | OperatingSystems.MacOSX)]
+ [InlineData(ServerType.IISExpress, RuntimeFlavor.coreclr, RuntimeArchitecture.x86, "http://localhost:5061/")]
+ [InlineData(ServerType.IISExpress, RuntimeFlavor.clr, RuntimeArchitecture.x64, "http://localhost:5062/")]
+ [InlineData(ServerType.WebListener, RuntimeFlavor.clr, RuntimeArchitecture.x86, "http://localhost:5063/")]
+ [InlineData(ServerType.WebListener, RuntimeFlavor.coreclr, RuntimeArchitecture.x64, "http://localhost:5064/")]
+ public Task HelloWorld_Windows(ServerType serverType, RuntimeFlavor runtimeFlavor, RuntimeArchitecture architecture, string applicationBaseUrl)
+ {
+ return HelloWorld(serverType, runtimeFlavor, architecture, applicationBaseUrl);
+ }
+
+ [Theory]
+ [InlineData(ServerType.Kestrel, RuntimeFlavor.coreclr, RuntimeArchitecture.x86, "http://localhost:5065/")]
+ [InlineData(ServerType.Kestrel, RuntimeFlavor.clr, RuntimeArchitecture.x64, "http://localhost:5066/")]
+ public Task HelloWorld_Kestrel(ServerType serverType, RuntimeFlavor runtimeFlavor, RuntimeArchitecture architecture, string applicationBaseUrl)
+ {
+ return HelloWorld(serverType, runtimeFlavor, architecture, applicationBaseUrl);
+ }
+
+ [ConditionalTheory]
+ [FrameworkSkipCondition(RuntimeFrameworks.DotNet)]
+ [InlineData(ServerType.Kestrel, RuntimeFlavor.mono, RuntimeArchitecture.x86, "http://localhost:5067/")]
+ [InlineData(ServerType.Kestrel, RuntimeFlavor.mono, RuntimeArchitecture.x64, "http://localhost:5068/")]
+ public Task HelloWorld_Mono(ServerType serverType, RuntimeFlavor runtimeFlavor, RuntimeArchitecture architecture, string applicationBaseUrl)
+ {
+ return HelloWorld(serverType, runtimeFlavor, architecture, applicationBaseUrl);
+ }
+
+ [ConditionalTheory]
+ [SkipIfIISVariationsNotEnabled]
+ [OSSkipCondition(OperatingSystems.MacOSX | OperatingSystems.Unix)]
+ [SkipIfCurrentRuntimeIsCoreClr]
+ [InlineData(ServerType.IIS, RuntimeFlavor.clr, RuntimeArchitecture.x64, "http://localhost:5069/")]
+ [InlineData(ServerType.IIS, RuntimeFlavor.coreclr, RuntimeArchitecture.x86, "http://localhost:5070/")]
+ public Task HelloWorld_IIS_X86(ServerType serverType, RuntimeFlavor runtimeFlavor, RuntimeArchitecture architecture, string applicationBaseUrl)
+ {
+ return HelloWorld(serverType, runtimeFlavor, architecture, applicationBaseUrl);
+ }
+
+ [ConditionalTheory]
+ [SkipIfIISNativeVariationsNotEnabled]
+ [OSSkipCondition(OperatingSystems.Win7And2008R2 | OperatingSystems.MacOSX | OperatingSystems.Unix)]
+ [SkipIfCurrentRuntimeIsCoreClr]
+ [InlineData(ServerType.IISNativeModule, RuntimeFlavor.coreclr, RuntimeArchitecture.x86, "http://localhost:5071/")]
+ public Task HelloWorld_NativeModule_X86(ServerType serverType, RuntimeFlavor runtimeFlavor, RuntimeArchitecture architecture, string applicationBaseUrl)
+ {
+ return HelloWorld(serverType, runtimeFlavor, architecture, applicationBaseUrl);
+ }
+
+ [ConditionalTheory]
+ [SkipIfIISNativeVariationsNotEnabled]
+ [OSSkipCondition(OperatingSystems.Win7And2008R2 | OperatingSystems.MacOSX | OperatingSystems.Unix)]
+ [SkipOn32BitOS]
+ [SkipIfCurrentRuntimeIsCoreClr]
+ [InlineData(ServerType.IISNativeModule, RuntimeFlavor.coreclr, RuntimeArchitecture.x64, "http://localhost:5072/")]
+ public Task HelloWorld_NativeModule_AMD64(ServerType serverType, RuntimeFlavor runtimeFlavor, RuntimeArchitecture architecture, string applicationBaseUrl)
+ {
+ return HelloWorld(serverType, runtimeFlavor, architecture, applicationBaseUrl);
+ }
+
+ public async Task HelloWorld(ServerType serverType, RuntimeFlavor runtimeFlavor, RuntimeArchitecture architecture, string applicationBaseUrl)
+ {
+ var logger = new LoggerFactory()
+ .AddConsole()
+ .CreateLogger(string.Format("HelloWorld:{0}:{1}:{2}", serverType, runtimeFlavor, architecture));
+
+ using (logger.BeginScope("HelloWorldTest"))
+ {
+ var stopwatch = Stopwatch.StartNew();
+
+ logger.LogInformation("Variation Details : HostType = {hostType}, RuntimeFlavor = {flavor}, Architecture = {arch}, applicationBaseUrl = {appBase}",
+ serverType, runtimeFlavor, architecture, applicationBaseUrl);
+
+ var deploymentParameters = new DeploymentParameters(Helpers.GetApplicationPath(), serverType, runtimeFlavor, architecture)
+ {
+ ApplicationBaseUriHint = applicationBaseUrl,
+ EnvironmentName = "HelloWorld", // Will pick the Start class named 'StartupHelloWorld'
+ };
+
+ using (var deployer = ApplicationDeployerFactory.Create(deploymentParameters, logger))
+ {
+ var deploymentResult = deployer.Deploy();
+ var httpClientHandler = new HttpClientHandler();
+ var httpClient = new HttpClient(httpClientHandler) { BaseAddress = new Uri(deploymentResult.ApplicationBaseUri) };
+
+ HttpResponseMessage response = null;
+
+ // Request to base address and check if various parts of the body are rendered & measure the cold startup time.
+ RetryHelper.RetryRequest(() =>
+ {
+ response = httpClient.GetAsync(string.Empty).Result;
+ return response;
+ }, logger: logger);
+
+ logger.LogInformation("[Time]: Approximate time taken for application initialization : '{t}' seconds", stopwatch.Elapsed.TotalSeconds);
+
+ var responseText = await response.Content.ReadAsStringAsync();
+ Assert.Equal("Hello World", responseText);
+
+ stopwatch.Stop();
+ logger.LogInformation("[Time]: Total time taken for this test variation '{t}' seconds", stopwatch.Elapsed.TotalSeconds);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/ServerComparison.FunctionalTests/Helpers.cs b/test/ServerComparison.FunctionalTests/Helpers.cs
new file mode 100644
index 0000000000..f2900bec3f
--- /dev/null
+++ b/test/ServerComparison.FunctionalTests/Helpers.cs
@@ -0,0 +1,24 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.IO;
+
+namespace ServerComparison.FunctionalTests
+{
+ public class Helpers
+ {
+ public static bool RunningOnMono
+ {
+ get
+ {
+ return Type.GetType("Mono.Runtime") != null;
+ }
+ }
+
+ public static string GetApplicationPath()
+ {
+ return Path.GetFullPath(Path.Combine("..", "ServerComparison.TestSites"));
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/ServerComparison.FunctionalTests/NtlmAuthentation.config b/test/ServerComparison.FunctionalTests/NtlmAuthentation.config
new file mode 100644
index 0000000000..b639cc4091
--- /dev/null
+++ b/test/ServerComparison.FunctionalTests/NtlmAuthentation.config
@@ -0,0 +1,1038 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/ServerComparison.FunctionalTests/NtlmAuthentationTest.cs b/test/ServerComparison.FunctionalTests/NtlmAuthentationTest.cs
new file mode 100644
index 0000000000..01b1d67629
--- /dev/null
+++ b/test/ServerComparison.FunctionalTests/NtlmAuthentationTest.cs
@@ -0,0 +1,85 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Diagnostics;
+using System.IO;
+using System.Net;
+using System.Net.Http;
+using System.Threading.Tasks;
+using DeploymentHelpers;
+using Microsoft.AspNet.Testing.xunit;
+using Microsoft.Framework.Logging;
+using Xunit;
+
+namespace ServerComparison.FunctionalTests
+{
+ // Uses ports ranging 5050 - 5060.
+ public class NtlmAuthenticationTests
+ {
+ [ConditionalTheory, Trait("ServerComparison.FunctionalTests", "ServerComparison.FunctionalTests")]
+ [OSSkipCondition(OperatingSystems.Unix | OperatingSystems.MacOSX)]
+ [InlineData(ServerType.IISExpress, RuntimeFlavor.coreclr, RuntimeArchitecture.x86, "http://localhost:5050/")]
+ [InlineData(ServerType.IISExpress, RuntimeFlavor.clr, RuntimeArchitecture.x64, "http://localhost:5051/")]
+ [InlineData(ServerType.WebListener, RuntimeFlavor.clr, RuntimeArchitecture.x86, "http://localhost:5052/")]
+ [InlineData(ServerType.WebListener, RuntimeFlavor.coreclr, RuntimeArchitecture.x64, "http://localhost:5052/")]
+ public async Task NtlmAuthentication(ServerType serverType, RuntimeFlavor runtimeFlavor, RuntimeArchitecture architecture, string applicationBaseUrl)
+ {
+ var logger = new LoggerFactory()
+ .AddConsole()
+ .CreateLogger(string.Format("Ntlm:{0}:{1}:{2}", serverType, runtimeFlavor, architecture));
+
+ using (logger.BeginScope("NtlmAuthenticationTest"))
+ {
+ var stopwatch = Stopwatch.StartNew();
+
+ logger.LogInformation("Variation Details : HostType = {hostType}, RuntimeFlavor = {flavor}, Architecture = {arch}, applicationBaseUrl = {appBase}",
+ serverType, runtimeFlavor, architecture, applicationBaseUrl);
+
+ var deploymentParameters = new DeploymentParameters(Helpers.GetApplicationPath(), serverType, runtimeFlavor, architecture)
+ {
+ ApplicationBaseUriHint = applicationBaseUrl,
+ EnvironmentName = "NtlmAuthentication", // Will pick the Start class named 'StartupNtlmAuthentication'
+ ApplicationHostConfigTemplateContent = (serverType == ServerType.IISExpress) ? File.ReadAllText("NtlmAuthentation.config") : null,
+ SiteName = "NtlmAuthenticationTestSite", // This is configured in the NtlmAuthentication.config
+ };
+
+ using (var deployer = ApplicationDeployerFactory.Create(deploymentParameters, logger))
+ {
+ var deploymentResult = deployer.Deploy();
+ var httpClientHandler = new HttpClientHandler();
+ var httpClient = new HttpClient(httpClientHandler) { BaseAddress = new Uri(deploymentResult.ApplicationBaseUri) };
+
+ HttpResponseMessage response = null;
+
+ // Request to base address and check if various parts of the body are rendered & measure the cold startup time.
+ RetryHelper.RetryRequest(() =>
+ {
+ response = httpClient.GetAsync(string.Empty).Result;
+ return response;
+ }, logger: logger);
+
+ logger.LogInformation("[Time]: Approximate time taken for application initialization : '{t}' seconds", stopwatch.Elapsed.TotalSeconds);
+
+ var responseText = await response.Content.ReadAsStringAsync();
+ Assert.Equal("Hello World", responseText);
+
+ responseText = await httpClient.GetStringAsync("/Anonymous");
+ Assert.Equal("Anonymous?True", responseText);
+
+ response = await httpClient.GetAsync("/Restricted");
+ Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
+ Assert.Contains("NTLM", response.Headers.WwwAuthenticate.ToString());
+
+ httpClientHandler = new HttpClientHandler() { UseDefaultCredentials = true };
+ httpClient = new HttpClient(httpClientHandler) { BaseAddress = new Uri(deploymentResult.ApplicationBaseUri) };
+ responseText = await httpClient.GetStringAsync("/Restricted");
+ Assert.Equal("NotAnonymous", responseText);
+
+ stopwatch.Stop();
+ logger.LogInformation("[Time]: Total time taken for this test variation '{t}' seconds", stopwatch.Elapsed.TotalSeconds);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/ServerComparison.FunctionalTests/ServerComparison.FunctionalTests.xproj b/test/ServerComparison.FunctionalTests/ServerComparison.FunctionalTests.xproj
new file mode 100644
index 0000000000..9474f8e79c
--- /dev/null
+++ b/test/ServerComparison.FunctionalTests/ServerComparison.FunctionalTests.xproj
@@ -0,0 +1,20 @@
+
+
+
+ 14.0
+ $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
+
+
+
+ a319acce-060b-4385-9534-9f2202f6180e
+ ..\..\artifacts\obj\$(MSBuildProjectName)
+ ..\..\artifacts\bin\$(MSBuildProjectName)\
+
+
+ 2.0
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/ServerComparison.FunctionalTests/project.json b/test/ServerComparison.FunctionalTests/project.json
new file mode 100644
index 0000000000..274a0fd662
--- /dev/null
+++ b/test/ServerComparison.FunctionalTests/project.json
@@ -0,0 +1,23 @@
+{
+ "compilationOptions": {
+ "warningsAsErrors": "true"
+ },
+ "commands": {
+ "test": "xunit.runner.aspnet"
+ },
+ "dependencies": {
+ "DeploymentHelpers": "1.0.0-*",
+ "Microsoft.AspNet.Server.IIS": "1.0.0-*",
+ "Microsoft.Framework.Logging.Console": "1.0.0-*",
+ "xunit.runner.aspnet": "2.0.0-aspnet-*"
+ },
+ "frameworks": {
+ "dnx451": {
+ "frameworkAssemblies": {
+ "System.Data": "",
+ "System.Net.Http": "",
+ "System.Xml": ""
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/ServerComparison.TestSites/Properties/launchSettings.json b/test/ServerComparison.TestSites/Properties/launchSettings.json
new file mode 100644
index 0000000000..b111483280
--- /dev/null
+++ b/test/ServerComparison.TestSites/Properties/launchSettings.json
@@ -0,0 +1,11 @@
+{
+ "profiles": {
+ "IIS Express": {
+ "commandName": "IISExpress",
+ "launchBrowser": true,
+ "environmentVariables": {
+ "ASPNET_ENV": "HelloWorld"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/ServerComparison.TestSites/ServerComparison.TestSites.xproj b/test/ServerComparison.TestSites/ServerComparison.TestSites.xproj
new file mode 100644
index 0000000000..be51354920
--- /dev/null
+++ b/test/ServerComparison.TestSites/ServerComparison.TestSites.xproj
@@ -0,0 +1,19 @@
+
+
+
+ 14.0
+ $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
+
+
+
+ 030225d8-4ee8-47e5-b692-2a96b3b51a38
+ ServerComparison.TestSites
+ ..\..\artifacts\obj\$(MSBuildProjectName)
+ ..\..\artifacts\bin\$(MSBuildProjectName)\
+
+
+ 2.0
+ 49212
+
+
+
\ No newline at end of file
diff --git a/test/ServerComparison.TestSites/StartupHelloWorld.cs b/test/ServerComparison.TestSites/StartupHelloWorld.cs
new file mode 100644
index 0000000000..ba97b49cb0
--- /dev/null
+++ b/test/ServerComparison.TestSites/StartupHelloWorld.cs
@@ -0,0 +1,67 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Microsoft.AspNet.Builder;
+using Microsoft.AspNet.Diagnostics;
+using Microsoft.AspNet.Http;
+using Microsoft.Framework.ConfigurationModel;
+using Microsoft.Framework.DependencyInjection;
+using Microsoft.Framework.Logging;
+using Microsoft.Framework.Runtime;
+
+namespace ServerComparison.TestSites
+{
+ ///
+ /// To make runtime to load an environment based startup class, specify the environment by the following ways:
+ /// 1. Drop a Microsoft.AspNet.Hosting.ini file in the wwwroot folder
+ /// 2. Add a setting in the ini file named 'ASPNET_ENV' with value of the format 'Startup[EnvironmentName]'. For example: To load a Startup class named
+ /// 'StartupHelloWorld' the value of the env should be 'NtlmAuthentication' (eg. ASPNET_ENV=HelloWorld). Runtime adds a 'Startup' prefix to this and loads 'StartupHelloWorld'.
+ /// If no environment name is specified the default startup class loaded is 'Startup'.
+ /// Alternative ways to specify environment are:
+ /// 1. Set the environment variable named SET ASPNET_ENV=HelloWorld
+ /// 2. For selfhost based servers pass in a command line variable named --env with this value. Eg:
+ /// "commands": {
+ /// "web": "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.WebListener --server.urls http://localhost:5002 --ASPNET_ENV HelloWorld",
+ /// },
+ ///
+ public class StartupHelloWorld
+ {
+ public StartupHelloWorld(IApplicationEnvironment env)
+ {
+ //Below code demonstrates usage of multiple configuration sources. For instance a setting say 'setting1' is found in both the registered sources,
+ //then the later source will win. By this way a Local config can be overridden by a different setting while deployed remotely.
+ Configuration = new Configuration(env.ApplicationBasePath)
+ .AddJsonFile("config.json")
+ .AddEnvironmentVariables(); //All environment variables in the process's context flow in as configuration values.
+ }
+
+ public IConfiguration Configuration { get; private set; }
+
+ public void ConfigureServices(IServiceCollection services)
+ {
+ // services.Configure(Configuration.GetSubKey("AppSettings"));
+ }
+
+ public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
+ {
+ loggerFactory.AddConsole(minLevel: LogLevel.Warning);
+
+ // Error page middleware displays a nice formatted HTML page for any unhandled exceptions in the request pipeline.
+ // Note: ErrorPageOptions.ShowAll to be used only at development time. Not recommended for production.
+ app.UseErrorPage(ErrorPageOptions.ShowAll);
+
+ // Add the runtime information page that can be used by developers
+ // to see what packages are used by the application
+ // default path is: /runtimeinfo
+ app.UseRuntimeInfoPage();
+
+ // Add static files to the request pipeline
+ // app.UseStaticFiles();
+
+ app.Run(ctx =>
+ {
+ return ctx.Response.WriteAsync("Hello World");
+ });
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/ServerComparison.TestSites/StartupNtlmAuthentication.cs b/test/ServerComparison.TestSites/StartupNtlmAuthentication.cs
new file mode 100644
index 0000000000..7c82dd74a1
--- /dev/null
+++ b/test/ServerComparison.TestSites/StartupNtlmAuthentication.cs
@@ -0,0 +1,85 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System.Threading.Tasks;
+using Microsoft.AspNet.Builder;
+using Microsoft.AspNet.Diagnostics;
+using Microsoft.AspNet.Http;
+using Microsoft.AspNet.Server.WebListener;
+using Microsoft.Framework.ConfigurationModel;
+using Microsoft.Framework.DependencyInjection;
+using Microsoft.Framework.Logging;
+using Microsoft.Framework.Runtime;
+using Microsoft.Net.Http.Server;
+
+namespace ServerComparison.TestSites
+{
+ ///
+ /// To make runtime to load an environment based startup class, specify the environment by the following ways:
+ /// 1. Drop a Microsoft.AspNet.Hosting.ini file in the wwwroot folder
+ /// 2. Add a setting in the ini file named 'ASPNET_ENV' with value of the format 'Startup[EnvironmentName]'. For example: To load a Startup class named
+ /// 'StartupNtlmAuthentication' the value of the env should be 'NtlmAuthentication' (eg. ASPNET_ENV=NtlmAuthentication). Runtime adds a 'Startup' prefix to this and loads 'StartupNtlmAuthentication'.
+ /// If no environment name is specified the default startup class loaded is 'Startup'.
+ /// Alternative ways to specify environment are:
+ /// 1. Set the environment variable named SET ASPNET_ENV=NtlmAuthentication
+ /// 2. For selfhost based servers pass in a command line variable named --env with this value. Eg:
+ /// "commands": {
+ /// "web": "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.WebListener --server.urls http://localhost:5002 --ASPNET_ENV NtlmAuthentication",
+ /// },
+ ///
+ public class StartupNtlmAuthentication
+ {
+ public StartupNtlmAuthentication(IApplicationEnvironment env)
+ {
+ //Below code demonstrates usage of multiple configuration sources. For instance a setting say 'setting1' is found in both the registered sources,
+ //then the later source will win. By this way a Local config can be overridden by a different setting while deployed remotely.
+ Configuration = new Configuration(env.ApplicationBasePath)
+ .AddJsonFile("config.json")
+ .AddEnvironmentVariables(); //All environment variables in the process's context flow in as configuration values.
+ }
+
+ public IConfiguration Configuration { get; private set; }
+
+ public void ConfigureServices(IServiceCollection services)
+ {
+ }
+
+ public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
+ {
+ loggerFactory.AddConsole(minLevel: LogLevel.Warning);
+
+ app.UseErrorPage(ErrorPageOptions.ShowAll);
+
+ // Set up NTLM authentication for WebListener like below.
+ // For IIS and IISExpress: Use inetmgr to setup NTLM authentication on the application vDir or modify the applicationHost.config to enable NTLM.
+ if ((app.Server as ServerInformation) != null)
+ {
+ var serverInformation = (ServerInformation)app.Server;
+ serverInformation.Listener.AuthenticationManager.AuthenticationSchemes = AuthenticationSchemes.NTLM | AuthenticationSchemes.AllowAnonymous;
+ }
+
+ app.Use((context, next) =>
+ {
+ if (context.Request.Path.Equals(new PathString("/Anonymous")))
+ {
+ return context.Response.WriteAsync("Anonymous?" + !context.User.Identity.IsAuthenticated);
+ }
+
+ if (context.Request.Path.Equals(new PathString("/Restricted")))
+ {
+ if (context.User.Identity.IsAuthenticated)
+ {
+ return context.Response.WriteAsync("NotAnonymous");
+ }
+ else
+ {
+ context.Response.Challenge();
+ return Task.FromResult(0);
+ }
+ }
+
+ return context.Response.WriteAsync("Hello World");
+ });
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/ServerComparison.TestSites/config.json b/test/ServerComparison.TestSites/config.json
new file mode 100644
index 0000000000..d177980a92
--- /dev/null
+++ b/test/ServerComparison.TestSites/config.json
@@ -0,0 +1,3 @@
+{
+
+}
diff --git a/test/ServerComparison.TestSites/project.json b/test/ServerComparison.TestSites/project.json
new file mode 100644
index 0000000000..ea0420a18c
--- /dev/null
+++ b/test/ServerComparison.TestSites/project.json
@@ -0,0 +1,38 @@
+{
+ "webroot": "wwwroot",
+ "version": "1.0.0-*",
+
+ "dependencies": {
+ "Kestrel": "1.0.0-*",
+ "Microsoft.AspNet.Diagnostics": "1.0.0-*",
+ "Microsoft.AspNet.Http.Core": "1.0.0-*",
+ "Microsoft.AspNet.Server.IIS": "1.0.0-*",
+ "Microsoft.AspNet.Server.WebListener": "1.0.0-*",
+ "Microsoft.AspNet.WebUtilities": "1.0.0-*",
+ "Microsoft.Framework.ConfigurationModel.Json": "1.0.0-*",
+ "Microsoft.Framework.Logging.Console": "1.0.0-*"
+ },
+
+ "commands": {
+ "web": "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.WebListener",
+ "kestrel": "Microsoft.AspNet.Hosting --server Kestrel"
+ },
+
+ "frameworks": {
+ "dnx451": { },
+ "dnxcore50": { }
+ },
+
+ "publishExclude": [
+ "node_modules",
+ "bower_components",
+ "**.xproj",
+ "**.user",
+ "**.vspscc"
+ ],
+ "exclude": [
+ "wwwroot",
+ "node_modules",
+ "bower_components"
+ ]
+}