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 TestWebSite(IISConfigUtility.AppPoolBitness appPoolBitness, string loggerPrefix = "ANCMTest", bool copyAllPublishedFiles = false, bool attachAppVerifier = false, bool publishing = true, int tcpPort = -1)
        {
            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);
            }

            //
            // By default we use DotnetCore v2.0
            //
            string SDKVersion = "netcoreapp2.0";

            if (TestFlags.Enabled(TestFlags.UseDotNetCore21))
            {
                SDKVersion = "netcoreapp2.1";
            }
            else if (TestFlags.Enabled(TestFlags.UseDotNetCore22))
            {
                SDKVersion = "netcoreapp2.2";
            }

            string publishPath       = Path.Combine(srcPath, "bin", "Debug", SDKVersion, "publish");
            string publishPathOutput = Path.Combine(InitializeTestMachine.TestRootDirectory, "publishPathOutput");

            //
            // Publish aspnetcore app
            //
            if (_publishedAspnetCoreApp != true)
            {
                if ((publishing == false && File.Exists(Path.Combine(publishPath, "AspNetCoreModule.TestSites.Standard.dll"))) ||
                    Debugger.IsAttached && 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);

                    try
                    {
                        if (TestFlags.Enabled(TestFlags.UseDotNetCore22))
                        {
                            TestUtility.FileCopy(Path.Combine(srcPath, "AspNetCoreModule.TestSites.Standard.csproj.UseDotNetCore22"), Path.Combine(srcPath, "AspNetCoreModule.TestSites.Standard.csproj"));
                        }
                        else if (TestFlags.Enabled(TestFlags.UseDotNetCore21))
                        {
                            TestUtility.FileCopy(Path.Combine(srcPath, "AspNetCoreModule.TestSites.Standard.csproj.UseDotNetCore21"), Path.Combine(srcPath, "AspNetCoreModule.TestSites.Standard.csproj"));
                        }
                        else
                        {
                            TestUtility.FileCopy(Path.Combine(srcPath, "AspNetCoreModule.TestSites.Standard.csproj.UseDotNetCore20"), Path.Combine(srcPath, "AspNetCoreModule.TestSites.Standard.csproj"));
                        }
                    }
                    catch
                    {
                        TestUtility.LogInformation("Failed to overwrite project file, update the project file manually");
                    }


                    if (TestFlags.Enabled(TestFlags.UseDotNetCore22))
                    {
                        var aspNetCoreModuleHostingModel = TestFlags.Enabled(TestFlags.InprocessMode) ? "inprocess" : "OutOfProcess";
                        argumentForDotNet += $" /p:AspNetCoreModuleHostingModel={aspNetCoreModuleHostingModel}";
                    }

                    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"));
            }

            //
            // 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;
            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");
            RootAppContext.DeleteFile("app_offline.htm");
            RootAppContext.AppPoolName   = appPoolName;
            RootAppContext.IisServerType = IisServerType;

            AspNetCoreApp             = new TestWebApplication("/AspNetCoreApp", aspnetCoreAppRootPath, this);
            AspNetCoreApp.AppPoolName = appPoolName;
            AspNetCoreApp.RestoreFile("web.config");
            AspNetCoreApp.DeleteFile("app_offline.htm");
            AspNetCoreApp.IisServerType = IisServerType;

            WebSocketApp             = new TestWebApplication("/WebSocketApp", Path.Combine(siteRootPath, "WebSocket"), this);
            WebSocketApp.AppPoolName = appPoolName;
            WebSocketApp.RestoreFile("web.config");
            WebSocketApp.DeleteFile("app_offline.htm");
            WebSocketApp.IisServerType = IisServerType;

            URLRewriteApp             = new TestWebApplication("/URLRewriteApp", Path.Combine(siteRootPath, "URLRewrite"), this);
            URLRewriteApp.AppPoolName = appPoolName;
            URLRewriteApp.RestoreFile("web.config");
            URLRewriteApp.DeleteFile("app_offline.htm");
            URLRewriteApp.IisServerType = IisServerType;

            //
            // Create site and apps
            //
            using (var iisConfig = new IISConfigUtility(IisServerType, IisExpressConfigPath))
            {
                // Create apppool
                if (IisServerType == ServerType.IIS)
                {
                    iisConfig.DeleteAppPool(appPoolName);
                    iisConfig.CreateAppPool(appPoolName);
                    iisConfig.SetAppPoolSetting(appPoolName, "rapidFailProtectionMaxCrashes", 100);

                    // 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 (TestFlags.Enabled(TestFlags.UseANCMV2))
                {
                    iisConfig.SetHandler(siteName, AspNetCoreApp.Name, "aspNetCore", "modules", "AspNetCoreModuleV2");
                }

                // Configure hostingModel for aspnetcore app
                if (TestFlags.Enabled(TestFlags.InprocessMode))
                {
                    AspNetCoreApp.HostingModel = TestWebApplication.HostingModelValue.Inprocess;
                    iisConfig.SetANCMConfig(siteName, AspNetCoreApp.Name, "hostingModel", TestWebApplication.HostingModelValue.Inprocess);
                    AspNetCoreApp.DeleteFile("web.config.bak");
                    AspNetCoreApp.BackupFile("web.config");
                }
            }

            TestUtility.LogInformation("TestWebSite::TestWebSite() End");
        }
        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 = siteName;
            }
            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 TestWebSite(IISConfigUtility.AppPoolBitness appPoolBitness, string loggerPrefix = "ANCMTest", ServerType serverType = ServerType.IIS)
        {
            TestUtility.LogInformation("TestWebSite::TestWebSite() Start");

            string solutionPath = InitializeTestMachine.GetSolutionDirectory();

            if (serverType == 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;

            // repeat three times until getting the valid temporary directory path
            for (int i = 0; i < 3; i++)
            {
                string postfix = Path.GetRandomFileName();
                siteName     = loggerPrefix.Replace(" ", "") + "_" + postfix;
                siteRootPath = Path.Combine(Environment.ExpandEnvironmentVariables("%SystemDrive%") + @"\", "inetpub", "ANCMTest", siteName);
                if (!Directory.Exists(siteRootPath))
                {
                    break;
                }
            }

            TestUtility.DirectoryCopy(Path.Combine(solutionPath, "test", "WebRoot"), siteRootPath);
            string aspnetCoreAppRootPath = Path.Combine(siteRootPath, "AspNetCoreApp");
            string srcPath = TestUtility.GetApplicationPath();

            //
            // Currently we use only DotnetCore v1.1
            //
            string publishPath = Path.Combine(srcPath, "bin", "Debug", "netcoreapp1.1", "publish");

            //
            // Publish aspnetcore app
            //
            if (_publishedAspnetCoreApp != true)
            {
                string argumentForDotNet = "publish " + srcPath;
                TestUtility.LogInformation("TestWebSite::TestWebSite() StandardTestApp is not published, trying to publish on the fly: dotnet.exe " + argumentForDotNet);
                TestUtility.RunCommand("dotnet", argumentForDotNet);
                _publishedAspnetCoreApp = true;
            }

            // check published files
            bool checkPublishedFiles = false;

            string[] publishedFiles = Directory.GetFiles(publishPath);
            foreach (var item in publishedFiles)
            {
                if (Path.GetFileName(item) == "web.config")
                {
                    checkPublishedFiles = true;
                }
            }

            if (!checkPublishedFiles)
            {
                throw new System.ApplicationException("web.config is not available in " + publishPath);
            }

            // Copy the pubishpath to standardAppRootPath
            TestUtility.DirectoryCopy(publishPath, aspnetCoreAppRootPath);

            int tcpPort = InitializeTestMachine.SiteId++;
            int siteId  = tcpPort;

            //
            // initialize class member variables
            //
            string appPoolName = null;

            if (serverType == ServerType.IIS)
            {
                appPoolName = siteName;
            }
            else if (serverType == ServerType.IISExpress)
            {
                appPoolName = "Clr4IntegratedAppPool";
            }

            // Initialize member variables
            _hostName = "localhost";
            _siteName = siteName;
            _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");

            // copy http.config to the test site root directory and initialize iisExpressConfigPath with the path
            string iisExpressConfigPath = null;

            if (serverType == ServerType.IISExpress)
            {
                iisExpressConfigPath = Path.Combine(siteRootPath, "http.config");
                TestUtility.FileCopy(Path.Combine(solutionPath, "test", "AspNetCoreModule.Test", "http.config"), iisExpressConfigPath);
            }

            //
            // Create site and apps
            //
            using (var iisConfig = new IISConfigUtility(serverType, iisExpressConfigPath))
            {
                if (serverType == ServerType.IIS)
                {
                    iisConfig.CreateAppPool(appPoolName);
                    bool is32bit = (appPoolBitness == IISConfigUtility.AppPoolBitness.enable32Bit);
                    iisConfig.SetAppPoolSetting(appPoolName, "enable32BitAppOnWin64", is32bit);
                }
                iisConfig.CreateSite(siteName, RootAppContext.PhysicalPath, siteId, this.TcpPort, appPoolName);
                iisConfig.CreateApp(siteName, AspNetCoreApp.Name, AspNetCoreApp.PhysicalPath, appPoolName);
                iisConfig.CreateApp(siteName, WebSocketApp.Name, WebSocketApp.PhysicalPath, appPoolName);
                iisConfig.CreateApp(siteName, URLRewriteApp.Name, URLRewriteApp.PhysicalPath, appPoolName);
            }

            if (serverType == ServerType.IISExpress)
            {
                string cmdline;
                string argument = "/siteid:" + siteId + " /config:" + iisExpressConfigPath;

                if (Directory.Exists(Environment.ExpandEnvironmentVariables("%ProgramFiles(x86)%")) && appPoolBitness == IISConfigUtility.AppPoolBitness.enable32Bit)
                {
                    cmdline = Path.Combine(Environment.ExpandEnvironmentVariables("%ProgramFiles(x86)%"), "IIS Express", "iisexpress.exe");
                }
                else
                {
                    cmdline = Path.Combine(Environment.ExpandEnvironmentVariables("%ProgramFiles%"), "IIS Express", "iisexpress.exe");
                }
                TestUtility.LogInformation("TestWebSite::TestWebSite() Start IISExpress: " + cmdline + " " + argument);
                _iisExpressPidBackup = TestUtility.RunCommand(cmdline, argument, false, false);
            }

            TestUtility.LogInformation("TestWebSite::TestWebSite() End");
        }
        public TestWebSite(IISConfigUtility.AppPoolBitness appPoolBitness, string loggerPrefix = "ANCMTest", bool startIISExpress = true, bool copyAllPublishedFiles = false)
        {
            _appPoolBitness = appPoolBitness;

            //
            // Default server type is IISExpress. we, however, should use IIS server instead if IIS server is ready to use.
            //
            IisServerType = ServerType.IISExpress;
            if (IISConfigUtility.IsIISReady)
            {
                IisServerType = ServerType.IIS;
            }

            TestUtility.LogInformation("TestWebSite::TestWebSite() Start");

            string solutionPath = InitializeTestMachine.GetSolutionDirectory();

            if (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(Environment.ExpandEnvironmentVariables("%SystemDrive%") + @"\", "inetpub", "ANCMTest", 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 only DotnetCore v1.1
            //
            string publishPath       = Path.Combine(srcPath, "bin", "Debug", "netcoreapp1.1", "publish");
            string publishPathOutput = Path.Combine(Environment.ExpandEnvironmentVariables("%SystemDrive%") + @"\", "inetpub", "ANCMTest", "publishPathOutput");

            //
            // Publish aspnetcore app
            //
            if (_publishedAspnetCoreApp != true)
            {
                string argumentForDotNet = "publish " + srcPath;
                TestUtility.LogInformation("TestWebSite::TestWebSite() StandardTestApp is not published, trying to publish on the fly: dotnet.exe " + argumentForDotNet);
                TestUtility.RunCommand("dotnet", argumentForDotNet);
                TestUtility.DirectoryCopy(publishPath, publishPathOutput);
                TestUtility.FileCopy(Path.Combine(publishPathOutput, "web.config"), Path.Combine(publishPathOutput, "web.config.bak"));

                // Adjust the arguments attribute value with IISConfigUtility from a temporary site
                using (var iisConfig = new IISConfigUtility(IisServerType, IisExpressConfigPath))
                {
                    string tempSiteName     = "ANCMTest_Temp";
                    int    tempId           = InitializeTestMachine.SiteId - 1;
                    string argumentFileName = (new TestWebApplication("/", publishPathOutput, null)).GetArgumentFileName();
                    if (string.IsNullOrEmpty(argumentFileName))
                    {
                        argumentFileName = "AspNetCoreModule.TestSites.Standard.dll";
                    }
                    iisConfig.CreateSite(tempSiteName, 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 = siteName;
            }
            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 (InitializeTestMachine.UsePrivateAspNetCoreFile == true && IisServerType == ServerType.IISExpress)
                {
                    iisConfig.AddModule("AspNetCoreModule", ("%IIS_BIN%\\" + InitializeTestMachine.PrivateFileName), null);
                }

                iisConfig.CreateSite(siteName, RootAppContext.PhysicalPath, _siteId, TcpPort, appPoolName);
                iisConfig.CreateApp(siteName, AspNetCoreApp.Name, AspNetCoreApp.PhysicalPath, appPoolName);
                iisConfig.CreateApp(siteName, WebSocketApp.Name, WebSocketApp.PhysicalPath, appPoolName);
                iisConfig.CreateApp(siteName, URLRewriteApp.Name, URLRewriteApp.PhysicalPath, appPoolName);
            }

            if (startIISExpress)
            {
                StartIISExpress();
            }

            TestUtility.LogInformation("TestWebSite::TestWebSite() End");
        }