public void Dispose()
        {
            _referenceCount--;

            if (_referenceCount == 0)
            {
                TestUtility.LogInformation("InitializeTestMachine::Dispose() Start");
                TestUtility.ResetHelper(ResetHelperMode.KillIISExpress);

                if (InitializeTestMachine.UsePrivateAspNetCoreFile)
                {
                    if (IISConfigUtility.IsIISInstalled == true)
                    {
                        using (var iisConfig = new IISConfigUtility(ServerType.IIS))
                        {
                            try
                            {
                                iisConfig.AddModule("AspNetCoreModule", Aspnetcore_path_original, null);
                            }
                            catch
                            {
                                TestUtility.LogInformation("Failed to restore aspnetcore.dll path!!!");
                            }
                        }
                    }
                }
                TestUtility.LogInformation("InitializeTestMachine::Dispose() End");
            }
        }
        private void PreparePrivateANCMFiles()
        {
            var    solutionRoot = GetSolutionDirectory();
            string outputPath   = string.Empty;

            _setupScriptPath = Path.Combine(solutionRoot, "tools");

            // First try with release build
            outputPath = Path.Combine(solutionRoot, "artifacts", "build", "AspNetCore", "bin", "Release");

            // If release build is not available, try with debug build
            if (!File.Exists(Path.Combine(outputPath, "Win32", "aspnetcore.dll")) ||
                !File.Exists(Path.Combine(outputPath, "x64", "aspnetcore.dll")) ||
                !File.Exists(Path.Combine(outputPath, "x64", "aspnetcore_schema.xml")))
            {
                outputPath = Path.Combine(solutionRoot, "artifacts", "build", "AspNetCore", "bin", "Debug");
            }

            if (!File.Exists(Path.Combine(outputPath, "Win32", "aspnetcore.dll")) ||
                !File.Exists(Path.Combine(outputPath, "x64", "aspnetcore.dll")) ||
                !File.Exists(Path.Combine(outputPath, "x64", "aspnetcore_schema.xml")))
            {
                throw new ApplicationException("aspnetcore.dll is not available; check if there is any build issue!!!");
            }

            //
            // NOTE:
            // ANCM schema file can't be overwritten here
            // If there is any schema change, that should be updated with installing setup or manually copied with the new schema file.
            //

            if (TestFlags.Enabled(TestFlags.UseIISExpress))
            {
                //
                // Initialize 32 bit IisExpressAspnetcore_path
                //
                IisExpressAspnetcore_path     = Path.Combine(outputPath, "x64", "aspnetcore.dll");
                IisExpressAspnetcore_X86_path = Path.Combine(outputPath, "Win32", "aspnetcore.dll");
            }
            else  // if use Full IIS server
            {
                bool updateSuccess = false;
                for (int i = 0; i < 3; i++)
                {
                    updateSuccess = false;
                    try
                    {
                        TestUtility.ResetHelper(ResetHelperMode.KillWorkerProcess);
                        TestUtility.ResetHelper(ResetHelperMode.StopW3svcStartW3svc);
                        Thread.Sleep(1000);

                        // Copy private file on Inetsrv directory
                        TestUtility.FileCopy(Path.Combine(outputPath, "x64", "aspnetcore.dll"), FullIisAspnetcore_path, overWrite: true, ignoreExceptionWhileDeletingExistingFile: false);

                        if (TestUtility.IsOSAmd64)
                        {
                            // Copy 32bit private file on Inetsrv directory
                            TestUtility.FileCopy(Path.Combine(outputPath, "Win32", "aspnetcore.dll"), FullIisAspnetcore_X86_path, overWrite: true, ignoreExceptionWhileDeletingExistingFile: false);
                        }
                        updateSuccess = true;
                    }
                    catch
                    {
                        updateSuccess = false;
                    }
                    if (updateSuccess)
                    {
                        break;
                    }
                }
                if (!updateSuccess)
                {
                    throw new ApplicationException("Failed to update aspnetcore.dll");
                }

                // update applicationhost.config for IIS server with the new private ASPNET Core file name
                if (TestFlags.Enabled(TestFlags.UseFullIIS))
                {
                    using (var iisConfig = new IISConfigUtility(ServerType.IIS, null))
                    {
                        iisConfig.AddModule("AspNetCoreModule", FullIisAspnetcore_path, null);
                    }
                }
            }
        }
        public 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 InitializeTestMachine()
        {
            _referenceCount++;

            if (_referenceCount == 1)
            {
                TestUtility.LogInformation("InitializeTestMachine::InitializeTestMachine() Start");

                _InitializeTestMachineCompleted = false;

                TestUtility.LogInformation("InitializeTestMachine::Start");
                if (Environment.ExpandEnvironmentVariables("%ANCMDebug%").ToLower() == "true")
                {
                    System.Diagnostics.Debugger.Launch();
                }

                TestUtility.ResetHelper(ResetHelperMode.KillIISExpress);
                TestUtility.ResetHelper(ResetHelperMode.KillWorkerProcess);
                // cleanup before starting
                string siteRootPath = Path.Combine(Environment.ExpandEnvironmentVariables("%SystemDrive%") + @"\", "inetpub", "ANCMTest");
                try
                {
                    if (IISConfigUtility.IsIISInstalled == true)
                    {
                        IISConfigUtility.RestoreAppHostConfig();
                    }
                }
                catch
                {
                    TestUtility.LogInformation("Failed to restore applicationhost.config");
                }

                if (!Directory.Exists(siteRootPath))
                {
                    Directory.CreateDirectory(siteRootPath);
                }

                foreach (string directory in Directory.GetDirectories(siteRootPath))
                {
                    bool successDeleteChildDirectory = true;
                    try
                    {
                        TestUtility.DeleteDirectory(directory);
                    }
                    catch
                    {
                        successDeleteChildDirectory = false;
                        TestUtility.LogInformation("Failed to delete " + directory);
                    }
                    if (successDeleteChildDirectory)
                    {
                        try
                        {
                            TestUtility.DeleteDirectory(siteRootPath);
                        }
                        catch
                        {
                            TestUtility.LogInformation("Failed to delete " + siteRootPath);
                        }
                    }
                }

                if (InitializeTestMachine.UsePrivateAspNetCoreFile)
                {
                    PreparePrivateANCMFiles();

                    // update applicationhost.config for IIS server
                    if (IISConfigUtility.IsIISInstalled == true)
                    {
                        using (var iisConfig = new IISConfigUtility(ServerType.IIS))
                        {
                            iisConfig.AddModule("AspNetCoreModule", Aspnetcore_path, null);
                        }
                    }
                }

                _InitializeTestMachineCompleted = true;

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

            for (int i = 0; i < 120; i++)
            {
                if (_InitializeTestMachineCompleted)
                {
                    break;
                }
                else
                {
                    TestUtility.LogInformation("InitializeTestMachine::InitializeTestMachine() Waiting...");
                    Thread.Sleep(500);
                }
            }
            if (!_InitializeTestMachineCompleted)
            {
                throw new System.ApplicationException("InitializeTestMachine failed");
            }
        }
Exemple #6
0
        public InitializeTestMachine()
        {
            _referenceCount++;

            if (_referenceCount == 1)
            {
                CheckPerquisiteForANCMTest();

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

                _InitializeTestMachineCompleted = false;

                TestUtility.LogInformation("InitializeTestMachine::Start");
                if (Environment.ExpandEnvironmentVariables("%ANCMTEST_DEBUG%").ToLower() == "true")
                {
                    System.Diagnostics.Debugger.Launch();
                }

                // check Makecert.exe exists
                try
                {
                    string makecertExeFilePath = TestUtility.GetMakeCertPath();
                    TestUtility.RunCommand(makecertExeFilePath, null, true, true);
                    TestUtility.LogInformation("Verified makecert.exe is available : " + makecertExeFilePath);
                }
                catch (Exception ex)
                {
                    throw new System.ApplicationException("makecert.exe is not available : " + ex.Message);
                }

                TestUtility.ResetHelper(ResetHelperMode.KillIISExpress);

                // check if we can use IIS server instead of IISExpress
                try
                {
                    IISConfigUtility.IsIISReady = false;
                    if (IISConfigUtility.IsIISInstalled == true)
                    {
                        var envValue = Environment.ExpandEnvironmentVariables(ANCMTestFlagsEnvironmentVariable);
                        if (envValue.ToLower().Contains(ANCMTestFlagsUseIISExpressContext.ToLower()))
                        {
                            TestUtility.LogInformation("UseIISExpress is set");
                            throw new System.ApplicationException("'ANCMTestServerType' environment variable is set to 'true'");
                        }
                        else
                        {
                            TestUtility.LogInformation("UseIISExpress is not set");
                        }

                        // check websocket is installed
                        if (File.Exists(Path.Combine(IISConfigUtility.Strings.IIS64BitPath, "iiswsock.dll")))
                        {
                            TestUtility.LogInformation("Websocket is installed");
                        }
                        else
                        {
                            throw new System.ApplicationException("websocket module is not installed");
                        }

                        TestUtility.ResetHelper(ResetHelperMode.KillWorkerProcess);

                        // Reset applicationhost.config
                        TestUtility.LogInformation("Restoring applicationhost.config");
                        IISConfigUtility.RestoreAppHostConfig(restoreFromMasterBackupFile: true);
                        TestUtility.StartW3svc();

                        // check w3svc is running after resetting applicationhost.config
                        if (IISConfigUtility.GetServiceStatus("w3svc") == "Running")
                        {
                            TestUtility.LogInformation("W3SVC service is restarted after restoring applicationhost.config");
                        }
                        else
                        {
                            throw new System.ApplicationException("WWW service can't start");
                        }

                        // check URLRewrite module exists
                        if (File.Exists(Path.Combine(IISConfigUtility.Strings.IIS64BitPath, "rewrite.dll")))
                        {
                            TestUtility.LogInformation("Verified URL Rewrite module installed for IIS server");
                        }
                        else
                        {
                            throw new System.ApplicationException("URL Rewrite module is not installed");
                        }

                        if (IISConfigUtility.ApppHostTemporaryBackupFileExtention == null)
                        {
                            throw new System.ApplicationException("Failed to backup applicationhost.config");
                        }
                        IISConfigUtility.IsIISReady = true;
                    }
                }
                catch (Exception ex)
                {
                    RollbackIISApplicationhostConfigFile();
                    TestUtility.LogInformation("We will use IISExpress instead of IIS: " + ex.Message);
                }

                string siteRootPath = Path.Combine(Environment.ExpandEnvironmentVariables("%SystemDrive%") + @"\", "inetpub", "ANCMTest");
                if (!Directory.Exists(siteRootPath))
                {
                    Directory.CreateDirectory(siteRootPath);
                }

                foreach (string directory in Directory.GetDirectories(siteRootPath))
                {
                    bool successDeleteChildDirectory = true;
                    try
                    {
                        TestUtility.DeleteDirectory(directory);
                    }
                    catch
                    {
                        successDeleteChildDirectory = false;
                        TestUtility.LogInformation("Failed to delete " + directory);
                    }
                    if (successDeleteChildDirectory)
                    {
                        try
                        {
                            TestUtility.DeleteDirectory(siteRootPath);
                        }
                        catch
                        {
                            TestUtility.LogInformation("Failed to delete " + siteRootPath);
                        }
                    }
                }

                if (InitializeTestMachine.UsePrivateAspNetCoreFile == true)
                {
                    PreparePrivateANCMFiles();

                    // update applicationhost.config for IIS server
                    if (IISConfigUtility.IsIISReady)
                    {
                        using (var iisConfig = new IISConfigUtility(ServerType.IIS, null))
                        {
                            iisConfig.AddModule("AspNetCoreModule", FullIisAspnetcore_path, null);
                        }
                    }
                }

                _InitializeTestMachineCompleted = true;
                TestUtility.LogInformation("InitializeTestMachine::InitializeTestMachine() End");
            }

            for (int i = 0; i < 120; i++)
            {
                if (_InitializeTestMachineCompleted)
                {
                    break;
                }
                else
                {
                    TestUtility.LogInformation("InitializeTestMachine::InitializeTestMachine() Waiting...");
                    Thread.Sleep(500);
                }
            }
            if (!_InitializeTestMachineCompleted)
            {
                throw new System.ApplicationException("InitializeTestMachine failed");
            }
        }
        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");
        }