private static void KpmPack(StartParameters startParameters) { startParameters.PackedApplicationRootPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); var parameters = string.Format("pack {0} -o {1}", startParameters.ApplicationPath, startParameters.PackedApplicationRootPath); Console.WriteLine(string.Format("Executing command kpm {0}", parameters)); var startInfo = new ProcessStartInfo { FileName = "kpm", Arguments = parameters, UseShellExecute = true, CreateNoWindow = true }; var hostProcess = Process.Start(startInfo); hostProcess.WaitForExit(60 * 1000); startParameters.ApplicationPath = (startParameters.ServerType == ServerType.Helios) ? Path.Combine(startParameters.PackedApplicationRootPath, "wwwroot") : Path.Combine(startParameters.PackedApplicationRootPath, "approot", "src", "MusicStore"); Console.WriteLine("kpm pack finished with exit code : {0}", hostProcess.ExitCode); }
private static Process StartSelfHost(StartParameters startParameters, string identityDbName, ILogger logger) { var commandName = startParameters.ServerType == ServerType.WebListener ? "web" : "kestrel"; logger.WriteInformation("Executing klr.exe --appbase {0} \"Microsoft.Framework.ApplicationHost\" {1}", startParameters.ApplicationPath, commandName); var startInfo = new ProcessStartInfo { FileName = "klr.exe", Arguments = string.Format("--appbase {0} \"Microsoft.Framework.ApplicationHost\" {1}", startParameters.ApplicationPath, commandName), UseShellExecute = true, CreateNoWindow = true }; var hostProcess = Process.Start(startInfo); //Sometimes reading MainModule returns null if called immediately after starting process. Thread.Sleep(1 * 1000); try { logger.WriteInformation("Started {0}. Process Id : {1}", hostProcess.MainModule.FileName, hostProcess.Id); } catch (Win32Exception win32Exception) { logger.WriteWarning("Cannot access 64 bit modules from a 32 bit process. Failed with following message.", win32Exception); } WaitTillDbCreated(identityDbName, logger); return(hostProcess); }
/// <summary> /// Copy klr.iis\[arch] to bin folder /// </summary> /// <param name="applicationPath"></param> private static void CopyKlrIIsBinFolder(StartParameters startParameters) { if (startParameters.ServerType == ServerType.HeliosNativeModule) { Console.WriteLine(@"Copying klr.iis\x86\* content to [ApplicationFolder]\bin\"); var archFolderName = startParameters.KreArchitecture.ToString(); var sourcePath = Path.Combine(Environment.CurrentDirectory, "NativeModule", "klr.iis", archFolderName); var targetPath = Path.Combine(startParameters.ApplicationPath, "bin", archFolderName); if (!Directory.Exists(targetPath)) { Directory.CreateDirectory(targetPath); } try { foreach (var sourceFile in Directory.EnumerateFiles(sourcePath, "*", SearchOption.AllDirectories)) { File.Copy(sourceFile, Path.Combine(targetPath, Path.GetFileName(sourceFile)), true); } } catch (Exception exception) { Console.WriteLine("Exception while copying assemblies", exception.Message); } } }
private static void DnuPublish(StartParameters startParameters, ILogger logger, string publishRoot = null) { startParameters.PublishedApplicationRootPath = Path.Combine(publishRoot ?? Path.GetTempPath(), Guid.NewGuid().ToString()); var parameters = string.Format( "publish {0} -o {1} --runtime {2} {3}", startParameters.ApplicationPath, startParameters.PublishedApplicationRootPath, startParameters.Runtime, startParameters.PublishWithNoSource ? "--no-source" : string.Empty); logger.LogInformation("Executing command dnu {args}", parameters); var startInfo = new ProcessStartInfo { FileName = "dnu", Arguments = parameters, UseShellExecute = true, CreateNoWindow = true }; var hostProcess = Process.Start(startInfo); hostProcess.WaitForExit(60 * 1000); startParameters.ApplicationPath = (startParameters.ServerType == ServerType.IISExpress || startParameters.ServerType == ServerType.IISNativeModule || startParameters.ServerType == ServerType.IIS) ? Path.Combine(startParameters.PublishedApplicationRootPath, "wwwroot") : Path.Combine(startParameters.PublishedApplicationRootPath, "approot", "src", "Hooli"); logger.LogInformation("dnu publish finished with exit code : {exitCode}", hostProcess.ExitCode); }
private static void KpmBundle(StartParameters startParameters, ILogger logger, string bundleRoot = null) { startParameters.BundledApplicationRootPath = Path.Combine(bundleRoot ?? Path.GetTempPath(), Guid.NewGuid().ToString()); var parameters = string.Format("bundle {0} -o {1} --runtime {2}", startParameters.ApplicationPath, startParameters.BundledApplicationRootPath, startParameters.Runtime); logger.WriteInformation("Executing command kpm {0}", parameters); var startInfo = new ProcessStartInfo { FileName = "kpm", Arguments = parameters, UseShellExecute = true, CreateNoWindow = true }; var hostProcess = Process.Start(startInfo); hostProcess.WaitForExit(60 * 1000); startParameters.ApplicationPath = (startParameters.ServerType == ServerType.IISExpress || startParameters.ServerType == ServerType.IISNativeModule || startParameters.ServerType == ServerType.IIS) ? Path.Combine(startParameters.BundledApplicationRootPath, "wwwroot") : Path.Combine(startParameters.BundledApplicationRootPath, "approot", "src", "MusicStore"); logger.WriteInformation("kpm bundle finished with exit code : {0}", hostProcess.ExitCode); }
private static Process StartHeliosHost(StartParameters startParameters) { CopyAspNetLoader(startParameters.ApplicationPath); if (!string.IsNullOrWhiteSpace(startParameters.ApplicationHostConfigTemplateContent)) { //Pass on the applicationhost.config to iis express. With this don't need to pass in the /path /port switches as they are in the applicationHost.config //We take a copy of the original specified applicationHost.Config to prevent modifying the one in the repo. var tempApplicationHostConfig = Path.GetTempFileName(); File.WriteAllText(tempApplicationHostConfig, startParameters.ApplicationHostConfigTemplateContent.Replace("[ApplicationPhysicalPath]", startParameters.ApplicationPath)); startParameters.ApplicationHostConfigLocation = tempApplicationHostConfig; } var parameters = string.IsNullOrWhiteSpace(startParameters.ApplicationHostConfigLocation) ? string.Format("/port:5001 /path:{0}", startParameters.ApplicationPath) : string.Format("/site:{0} /config:{1}", startParameters.SiteName, startParameters.ApplicationHostConfigLocation); var iisExpressPath = GetIISExpressPath(startParameters.KreArchitecture); Console.WriteLine("Executing command : {0} {1}", iisExpressPath, parameters); var startInfo = new ProcessStartInfo { FileName = iisExpressPath, Arguments = parameters, UseShellExecute = true, CreateNoWindow = true }; var hostProcess = Process.Start(startInfo); Console.WriteLine("Started iisexpress. Process Id : {0}", hostProcess.Id); return(hostProcess); }
private static Process StartSelfHost(StartParameters startParameters, string identityDbName) { Console.WriteLine(string.Format("Executing klr.exe --appbase {0} \"Microsoft.Framework.ApplicationHost\" {1}", startParameters.ApplicationPath, startParameters.ServerType.ToString())); var startInfo = new ProcessStartInfo { FileName = "klr.exe", Arguments = string.Format("--appbase {0} \"Microsoft.Framework.ApplicationHost\" {1}", startParameters.ApplicationPath, startParameters.ServerType.ToString()), UseShellExecute = true, CreateNoWindow = true }; var hostProcess = Process.Start(startInfo); //Sometimes reading MainModule returns null if called immediately after starting process. Thread.Sleep(1 * 1000); try { Console.WriteLine("Started {0}. Process Id : {1}", hostProcess.MainModule.FileName, hostProcess.Id); } catch (Win32Exception win32Exception) { Console.WriteLine("Cannot access 64 bit modules from a 32 bit process. Failed with following message : {0}", win32Exception.Message); } WaitTillDbCreated(identityDbName); return(hostProcess); }
public static void CleanUpApplication(StartParameters startParameters, Process hostProcess, string musicStoreDbName) { if (hostProcess != null && !hostProcess.HasExited) { //Shutdown the host process hostProcess.Kill(); hostProcess.WaitForExit(5 * 1000); if (!hostProcess.HasExited) { Console.WriteLine("Unable to terminate the host process with process Id '{0}", hostProcess.Id); } else { Console.WriteLine("Successfully terminated host process with process Id '{0}'", hostProcess.Id); } } else { Console.WriteLine("Host process already exited or never started successfully."); } if (!Helpers.RunningOnMono) { //Mono uses InMemoryStore DbUtils.DropDatabase(musicStoreDbName); } if (!string.IsNullOrWhiteSpace(startParameters.ApplicationHostConfigLocation)) { //Delete the temp applicationHostConfig that we created if (File.Exists(startParameters.ApplicationHostConfigLocation)) { try { File.Delete(startParameters.ApplicationHostConfigLocation); } catch (Exception exception) { //Ignore delete failures - just write a log Console.WriteLine("Failed to delete '{0}'. Exception : {1}", startParameters.ApplicationHostConfigLocation, exception.Message); } } } if (startParameters.PackApplicationBeforeStart) { try { //We've originally packed the application in a temp folder. We need to delete it. Directory.Delete(startParameters.PackedApplicationRootPath, true); } catch (Exception exception) { Console.WriteLine("Failed to delete directory '{0}'. Exception message: {1}", startParameters.PackedApplicationRootPath, exception.Message); } } }
private static Process StartHeliosHost(StartParameters startParameters, ILogger logger) { if (!string.IsNullOrWhiteSpace(startParameters.ApplicationHostConfigTemplateContent)) { startParameters.ApplicationHostConfigTemplateContent = startParameters.ApplicationHostConfigTemplateContent.Replace("[ApplicationPhysicalPath]", Path.Combine(startParameters.ApplicationPath, "wwwroot")); } if (!startParameters.PublishApplicationBeforeStart) { IISExpressHelper.CopyAspNetLoader(startParameters.ApplicationPath); } if (!string.IsNullOrWhiteSpace(startParameters.ApplicationHostConfigTemplateContent)) { //Pass on the applicationhost.config to iis express. With this don't need to pass in the /path /port switches as they are in the applicationHost.config //We take a copy of the original specified applicationHost.Config to prevent modifying the one in the repo. var tempApplicationHostConfig = Path.GetTempFileName(); File.WriteAllText(tempApplicationHostConfig, startParameters.ApplicationHostConfigTemplateContent.Replace("[ApplicationPhysicalPath]", startParameters.ApplicationPath)); startParameters.ApplicationHostConfigLocation = tempApplicationHostConfig; } var webroot = startParameters.ApplicationPath; if (!webroot.EndsWith("wwwroot")) { webroot = Path.Combine(webroot, "wwwroot"); } var parameters = string.IsNullOrWhiteSpace(startParameters.ApplicationHostConfigLocation) ? string.Format("/port:5001 /path:\"{0}\"", webroot) : string.Format("/site:{0} /config:{1}", startParameters.SiteName, startParameters.ApplicationHostConfigLocation); var iisExpressPath = IISExpressHelper.GetPath(startParameters.RuntimeArchitecture); logger.LogInformation("Executing command : {iisExpress} {args}", iisExpressPath, parameters); var startInfo = new ProcessStartInfo { FileName = iisExpressPath, Arguments = parameters, UseShellExecute = true, CreateNoWindow = true }; var hostProcess = Process.Start(startInfo); logger.LogInformation("Started iisexpress. Process Id : {processId}", hostProcess.Id); return(hostProcess); }
private static Process StartMonoHost(StartParameters startParameters, ILogger logger) { var path = Environment.GetEnvironmentVariable("PATH"); var runtimeBin = path.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries). Where(c => c.Contains("dnx-mono")).FirstOrDefault(); if (string.IsNullOrWhiteSpace(runtimeBin)) { throw new Exception("Runtime not detected on the machine."); } if (startParameters.PublishApplicationBeforeStart) { // We use full path to runtime to pack. startParameters.Runtime = new DirectoryInfo(runtimeBin).Parent.FullName; DnuPublish(startParameters, logger); } //Mono now supports --appbase logger.LogInformation("Setting the --appbase to {0}", startParameters.ApplicationPath); var bootstrapper = "dnx"; var commandName = startParameters.ServerType == ServerType.Kestrel ? "kestrel" : string.Empty; logger.LogInformation("Executing command: {dnx} \"{appPath}\" {command}", bootstrapper, startParameters.ApplicationPath, commandName); var startInfo = new ProcessStartInfo { FileName = bootstrapper, Arguments = string.Format("\"{0}\" {1}", startParameters.ApplicationPath, commandName), UseShellExecute = false, CreateNoWindow = true, RedirectStandardInput = true }; var hostProcess = Process.Start(startInfo); logger.LogInformation("Started {0}. Process Id : {1}", hostProcess.MainModule.FileName, hostProcess.Id); if (hostProcess.HasExited) { logger.LogError("Host process {processName} exited with code {exitCode} or failed to start.", startInfo.FileName, hostProcess.ExitCode); throw new Exception("Failed to start host"); } return(hostProcess); }
public static Process StartApplication(StartParameters startParameters, string identityDbName) { startParameters.ApplicationPath = Path.GetFullPath(Path.Combine(Environment.CurrentDirectory, APP_RELATIVE_PATH)); //To avoid the KRE_DEFAULT_LIB of the test process flowing into Helios, set it to empty var backupKreDefaultLibPath = Environment.GetEnvironmentVariable("KRE_DEFAULT_LIB"); Environment.SetEnvironmentVariable("KRE_DEFAULT_LIB", string.Empty); if (!string.IsNullOrWhiteSpace(startParameters.EnvironmentName)) { //To choose an environment based Startup Environment.SetEnvironmentVariable("KRE_ENV", startParameters.EnvironmentName); } Process hostProcess = null; if (startParameters.KreFlavor == KreFlavor.Mono) { hostProcess = StartMonoHost(startParameters); } else { //Tweak the %PATH% to the point to the right KREFLAVOR Environment.SetEnvironmentVariable("PATH", SwitchPathToKreFlavor(startParameters.KreFlavor, startParameters.KreArchitecture)); //Reason to do pack here instead of in a common place is use the right KRE to do the packing. Previous line switches to use the right KRE. if (startParameters.PackApplicationBeforeStart) { KpmPack(startParameters); } if (startParameters.ServerType == ServerType.Helios || startParameters.ServerType == ServerType.HeliosNativeModule) { hostProcess = StartHeliosHost(startParameters); } else { hostProcess = StartSelfHost(startParameters, identityDbName); } } //Restore the KRE_DEFAULT_LIB after starting the host process Environment.SetEnvironmentVariable("KRE_DEFAULT_LIB", backupKreDefaultLibPath); Environment.SetEnvironmentVariable("KRE_ENV", string.Empty); return(hostProcess); }
private static Process StartMonoHost(StartParameters startParameters, ILogger logger) { var path = Environment.GetEnvironmentVariable("PATH"); var runtimeBin = path.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries). Where(c => c.Contains("kre-mono")).FirstOrDefault(); if (string.IsNullOrWhiteSpace(runtimeBin)) { throw new Exception("Runtime not detected on the machine."); } if (startParameters.BundleApplicationBeforeStart) { // We use full path to runtime to pack. startParameters.Runtime = new DirectoryInfo(runtimeBin).Parent.FullName; KpmBundle(startParameters, logger); } //Mono now supports --appbase Environment.SetEnvironmentVariable("KRE_APPBASE", startParameters.ApplicationPath); logger.WriteInformation("Setting the --appbase to", startParameters.ApplicationPath); var bootstrapper = "klr"; var commandName = startParameters.ServerType == ServerType.Kestrel ? "kestrel" : string.Empty; logger.WriteInformation(string.Format("Executing command: {0} {1} {2}", bootstrapper, startParameters.ApplicationPath, commandName)); var startInfo = new ProcessStartInfo { FileName = bootstrapper, Arguments = string.Format("{0} {1}", startParameters.ApplicationPath, commandName), UseShellExecute = false, CreateNoWindow = true, RedirectStandardInput = true }; var hostProcess = Process.Start(startInfo); logger.WriteInformation("Started {0}. Process Id : {1}", hostProcess.MainModule.FileName, hostProcess.Id); Thread.Sleep(25 * 1000); return(hostProcess); }
private static Process StartMonoHost(StartParameters startParameters) { if (startParameters.PackApplicationBeforeStart) { KpmPack(startParameters); } //Mono does not have a way to pass in a --appbase switch. So it will be an environment variable. Environment.SetEnvironmentVariable("KRE_APPBASE", startParameters.ApplicationPath); Console.WriteLine("Setting the KRE_APPBASE to {0}", startParameters.ApplicationPath); var path = Environment.GetEnvironmentVariable("PATH"); var kreBin = path.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries).Where(c => c.Contains("KRE-Mono")).FirstOrDefault(); if (string.IsNullOrWhiteSpace(kreBin)) { throw new Exception("KRE not detected on the machine."); } var monoPath = Path.Combine(kreBin, "mono"); var klrMonoManaged = Path.Combine(kreBin, "klr.mono.managed.dll"); var applicationHost = Path.Combine(kreBin, "Microsoft.Framework.ApplicationHost"); Console.WriteLine(string.Format("Executing command: {0} {1} {3} {4}", monoPath, klrMonoManaged, startParameters.ApplicationPath, applicationHost, startParameters.ServerType.ToString())); var startInfo = new ProcessStartInfo { FileName = monoPath, Arguments = string.Format("{0} {1} {2}", klrMonoManaged, applicationHost, startParameters.ServerType.ToString()), UseShellExecute = true, CreateNoWindow = true }; var hostProcess = Process.Start(startInfo); Console.WriteLine("Started {0}. Process Id : {1}", hostProcess.MainModule.FileName, hostProcess.Id); Thread.Sleep(5 * 1000); //Clear the appbase so that it does not create issues with successive runs Environment.SetEnvironmentVariable("KRE_APPBASE", string.Empty); return(hostProcess); }
private static Process StartSelfHost(StartParameters startParameters, ILogger logger) { var commandName = startParameters.ServerType == ServerType.WebListener ? "web" : "kestrel"; logger.LogInformation("Executing dnx.exe --appbase {appPath} \"Microsoft.Framework.ApplicationHost\" {command}", startParameters.ApplicationPath, commandName); var startInfo = new ProcessStartInfo { FileName = "dnx.exe", Arguments = string.Format("--appbase \"{0}\" \"Microsoft.Framework.ApplicationHost\" {1}", startParameters.ApplicationPath, commandName), UseShellExecute = true, CreateNoWindow = true }; var hostProcess = Process.Start(startInfo); //Sometimes reading MainModule returns null if called immediately after starting process. Thread.Sleep(1 * 1000); if (hostProcess.HasExited) { logger.LogError("Host process {processName} exited with code {exitCode} or failed to start.", startInfo.FileName, hostProcess.ExitCode); throw new Exception("Failed to start host"); } try { logger.LogInformation("Started {fileName}. Process Id : {processId}", hostProcess.MainModule.FileName, hostProcess.Id); } catch (Win32Exception win32Exception) { logger.LogWarning("Cannot access 64 bit modules from a 32 bit process. Failed with following message.", win32Exception); } return(hostProcess); }
public IISApplication(StartParameters startParameters, ILogger logger) { _startParameters = startParameters; _logger = logger; }
private void SmokeTestSuite(ServerType serverType, RuntimeFlavor donetFlavor, RuntimeArchitecture architecture, string applicationBaseUrl) { using (_logger.BeginScope("SmokeTestSuite")) { _logger.LogInformation("Variation Details : HostType = {hostType}, DonetFlavor = {flavor}, Architecture = {arch}, applicationBaseUrl = {appBase}", serverType, donetFlavor, architecture, applicationBaseUrl); _startParameters = new StartParameters { ServerType = serverType, RuntimeFlavor = donetFlavor, RuntimeArchitecture = architecture, EnvironmentName = "SocialTesting" }; var stopwatch = Stopwatch.StartNew(); var musicStoreDbName = Guid.NewGuid().ToString().Replace("-", string.Empty); _logger.LogInformation("Pointing MusicStore DB to '{connString}'", string.Format(CONNECTION_STRING_FORMAT, musicStoreDbName)); //Override the connection strings using environment based configuration Environment.SetEnvironmentVariable("SQLAZURECONNSTR_DefaultConnection", string.Format(CONNECTION_STRING_FORMAT, musicStoreDbName)); _applicationBaseUrl = applicationBaseUrl; Process hostProcess = null; bool testSuccessful = false; try { hostProcess = DeploymentUtility.StartApplication(_startParameters, _logger); #if DNX451 if (serverType == ServerType.IISNativeModule || serverType == ServerType.IIS) { // Accomodate the vdir name. _applicationBaseUrl += _startParameters.IISApplication.VirtualDirectoryName + "/"; } #endif _httpClientHandler = new HttpClientHandler(); _httpClient = new HttpClient(_httpClientHandler) { BaseAddress = new Uri(_applicationBaseUrl) }; HttpResponseMessage response = null; string responseContent = null; //Request to base address and check if various parts of the body are rendered & measure the cold startup time. Helpers.Retry(() => { response = _httpClient.GetAsync(string.Empty).Result; responseContent = response.Content.ReadAsStringAsync().Result; _logger.LogInformation("[Time]: Approximate time taken for application initialization : '{t}' seconds", stopwatch.Elapsed.TotalSeconds); }, logger: _logger); VerifyHomePage(response, responseContent); //Verify the static file middleware can serve static content VerifyStaticContentServed(); //Making a request to a protected resource should automatically redirect to login page AccessStoreWithoutPermissions(); //Register a user - Negative scenario where the Password & ConfirmPassword do not match RegisterUserWithNonMatchingPasswords(); //Register a valid user var generatedEmail = RegisterValidUser(); SignInWithUser(generatedEmail, "Password~1"); //Register a user - Negative scenario : Trying to register a user name that's already registered. RegisterExistingUser(generatedEmail); //Logout from this user session - This should take back to the home page SignOutUser(generatedEmail); //Sign in scenarios: Invalid password - Expected an invalid user name password error. SignInWithInvalidPassword(generatedEmail, "InvalidPassword~1"); //Sign in scenarios: Valid user name & password. SignInWithUser(generatedEmail, "Password~1"); //Change password scenario ChangePassword(generatedEmail); //SignIn with old password and verify old password is not allowed and new password is allowed SignOutUser(generatedEmail); SignInWithInvalidPassword(generatedEmail, "Password~1"); SignInWithUser(generatedEmail, "Password~2"); //Making a request to a protected resource that this user does not have access to - should automatically redirect to login page again AccessStoreWithoutPermissions(generatedEmail); //Logout from this user session - This should take back to the home page SignOutUser(generatedEmail); //Login as an admin user SignInWithUser("*****@*****.**", "YouShouldChangeThisPassword1!"); //Now navigating to the store manager should work fine as this user has the necessary permission to administer the store. AccessStoreWithPermissions(); //Create an album var albumName = CreateAlbum(); var albumId = FetchAlbumIdFromName(albumName); //Get details of the album VerifyAlbumDetails(albumId, albumName); //Verify status code pages acts on non-existing items. VerifyStatusCodePages(); //Get the non-admin view of the album. GetAlbumDetailsFromStore(albumId, albumName); //Add an album to cart and checkout the same AddAlbumToCart(albumId, albumName); CheckOutCartItems(); //Delete the album from store DeleteAlbum(albumId, albumName); //Logout from this user session - This should take back to the home page SignOutUser("Administrator"); //Google login LoginWithGoogle(); //Facebook login LoginWithFacebook(); //Twitter login LoginWithTwitter(); //MicrosoftAccountLogin LoginWithMicrosoftAccount(); stopwatch.Stop(); _logger.LogInformation("[Time]: Total time taken for this test variation '{t}' seconds", stopwatch.Elapsed.TotalSeconds); testSuccessful = true; } finally { if (!testSuccessful) { _logger.LogError("Some tests failed. Proceeding with cleanup."); } DeploymentUtility.CleanUpApplication(_startParameters, hostProcess, musicStoreDbName, _logger); } } }
public void SmokeTestSuite(ServerType serverType, KreFlavor kreFlavor, KreArchitecture architecture, string applicationBaseUrl, bool RunTestOnMono = false) { Console.WriteLine("Variation Details : HostType = {0}, KreFlavor = {1}, Architecture = {2}, applicationBaseUrl = {3}", serverType, kreFlavor, architecture, applicationBaseUrl); if (Helpers.SkipTestOnCurrentConfiguration(RunTestOnMono, architecture)) { Assert.True(true); return; } var startParameters = new StartParameters { ServerType = serverType, KreFlavor = kreFlavor, KreArchitecture = architecture }; var testStartTime = DateTime.Now; var musicStoreDbName = Guid.NewGuid().ToString().Replace("-", string.Empty); Console.WriteLine("Pointing MusicStore DB to '{0}'", string.Format(Connection_string_Format, musicStoreDbName)); //Override the connection strings using environment based configuration Environment.SetEnvironmentVariable("SQLAZURECONNSTR_DefaultConnection", string.Format(Connection_string_Format, musicStoreDbName)); ApplicationBaseUrl = applicationBaseUrl; Process hostProcess = null; bool testSuccessful = false; try { hostProcess = DeploymentUtility.StartApplication(startParameters, musicStoreDbName); httpClientHandler = new HttpClientHandler(); httpClient = new HttpClient(httpClientHandler) { BaseAddress = new Uri(applicationBaseUrl) }; //Request to base address and check if various parts of the body are rendered & measure the cold startup time. var response = httpClient.GetAsync(string.Empty).Result; var responseContent = response.Content.ReadAsStringAsync().Result; var initializationCompleteTime = DateTime.Now; Console.WriteLine("[Time]: Approximate time taken for application initialization : '{0}' seconds", (initializationCompleteTime - testStartTime).TotalSeconds); VerifyHomePage(response, responseContent); //Verify the static file middleware can serve static content VerifyStaticContentServed(); //Making a request to a protected resource should automatically redirect to login page AccessStoreWithoutPermissions(); //Register a user - Negative scenario where the Password & ConfirmPassword do not match RegisterUserWithNonMatchingPasswords(); //Register a valid user var generatedEmail = RegisterValidUser(); //Register a user - Negative scenario : Trying to register a user name that's already registered. RegisterExistingUser(generatedEmail); //Logout from this user session - This should take back to the home page SignOutUser(generatedEmail); //Sign in scenarios: Invalid password - Expected an invalid user name password error. SignInWithInvalidPassword(generatedEmail, "InvalidPassword~1"); //Sign in scenarios: Valid user name & password. SignInWithUser(generatedEmail, "Password~1"); //Change password scenario ChangePassword(generatedEmail); //SignIn with old password and verify old password is not allowed and new password is allowed SignOutUser(generatedEmail); SignInWithInvalidPassword(generatedEmail, "Password~1"); SignInWithUser(generatedEmail, "Password~2"); //Making a request to a protected resource that this user does not have access to - should automatically redirect to login page again AccessStoreWithoutPermissions(generatedEmail); //Logout from this user session - This should take back to the home page SignOutUser(generatedEmail); //Login as an admin user SignInWithUser("*****@*****.**", "YouShouldChangeThisPassword1!"); //Now navigating to the store manager should work fine as this user has the necessary permission to administer the store. AccessStoreWithPermissions(); //Create an album var albumName = CreateAlbum(); var albumId = FetchAlbumIdFromName(albumName); //Get details of the album VerifyAlbumDetails(albumId, albumName); //Add an album to cart and checkout the same AddAlbumToCart(albumId, albumName); CheckOutCartItems(); //Delete the album from store DeleteAlbum(albumId, albumName); //Logout from this user session - This should take back to the home page SignOutUser("Administrator"); var testCompletionTime = DateTime.Now; Console.WriteLine("[Time]: All tests completed in '{0}' seconds", (testCompletionTime - initializationCompleteTime).TotalSeconds); Console.WriteLine("[Time]: Total time taken for this test variation '{0}' seconds", (testCompletionTime - testStartTime).TotalSeconds); testSuccessful = true; } finally { if (!testSuccessful) { Console.WriteLine("Some tests failed. Proceeding with cleanup."); } DeploymentUtility.CleanUpApplication(startParameters, hostProcess, musicStoreDbName); } }
public static void CleanUpApplication(StartParameters startParameters, Process hostProcess, string musicStoreDbName, ILogger logger) { if (startParameters.ServerType == ServerType.IISNativeModule || startParameters.ServerType == ServerType.IIS) { #if DNX451 // Stop & delete the application pool. if (startParameters.IISApplication != null) { startParameters.IISApplication.StopAndDeleteAppPool(); } #endif } else if (hostProcess != null && !hostProcess.HasExited) { //Shutdown the host process hostProcess.Kill(); hostProcess.WaitForExit(5 * 1000); if (!hostProcess.HasExited) { logger.LogWarning("Unable to terminate the host process with process Id '{processId}", hostProcess.Id); } else { logger.LogInformation("Successfully terminated host process with process Id '{processId}'", hostProcess.Id); } } else { logger.LogWarning("Host process already exited or never started successfully."); } if (!Helpers.RunningOnMono) { //Mono uses InMemoryStore DbUtils.DropDatabase(musicStoreDbName, logger); } if (!string.IsNullOrWhiteSpace(startParameters.ApplicationHostConfigLocation)) { //Delete the temp applicationHostConfig that we created if (File.Exists(startParameters.ApplicationHostConfigLocation)) { try { File.Delete(startParameters.ApplicationHostConfigLocation); } catch (Exception exception) { //Ignore delete failures - just write a log logger.LogWarning("Failed to delete '{config}'. Exception : {exception}", startParameters.ApplicationHostConfigLocation, exception.Message); } } } if (startParameters.PublishApplicationBeforeStart) { try { //We've originally published the application in a temp folder. We need to delete it. Directory.Delete(startParameters.PublishedApplicationRootPath, true); } catch (Exception exception) { logger.LogWarning("Failed to delete directory.", exception); } } }
public static Process StartApplication(StartParameters startParameters, ILogger logger) { startParameters.ApplicationPath = Path.GetFullPath(Path.Combine(Directory.GetCurrentDirectory(), APP_RELATIVE_PATH)); //To avoid the DNX_DEFAULT_LIB of the test process flowing into Helios, set it to empty var backupRuntimeDefaultLibPath = Environment.GetEnvironmentVariable("DNX_DEFAULT_LIB"); Environment.SetEnvironmentVariable("DNX_DEFAULT_LIB", string.Empty); if (!string.IsNullOrWhiteSpace(startParameters.EnvironmentName)) { if (startParameters.ServerType != ServerType.IISNativeModule && startParameters.ServerType != ServerType.IIS) { // To choose an environment based Startup. Environment.SetEnvironmentVariable("ASPNET_ENV", startParameters.EnvironmentName); } else { // Cannot override with environment in case of IIS. Publish and write a Microsoft.AspNet.Hosting.ini file. startParameters.PublishApplicationBeforeStart = true; } } Process hostProcess = null; if (startParameters.RuntimeFlavor == RuntimeFlavor.Mono) { hostProcess = StartMonoHost(startParameters, logger); } else { //Tweak the %PATH% to the point to the right RUNTIMEFLAVOR startParameters.Runtime = SwitchPathToRuntimeFlavor(startParameters.RuntimeFlavor, startParameters.RuntimeArchitecture, logger); //Reason to do pack here instead of in a common place is use the right runtime to do the packing. Previous line switches to use the right runtime. if (startParameters.PublishApplicationBeforeStart) { #if DNX451 if (startParameters.ServerType == ServerType.IISNativeModule || startParameters.ServerType == ServerType.IIS) { // Publish to IIS root\application folder. DnuPublish(startParameters, logger, Path.Combine(Environment.GetEnvironmentVariable("SystemDrive") + @"\", @"inetpub\wwwroot")); // Drop a Microsoft.AspNet.Hosting.ini with ASPNET_ENV information. logger.LogInformation("Creating Microsoft.AspNet.Hosting.ini file with ASPNET_ENV."); var iniFile = Path.Combine(startParameters.ApplicationPath, "Microsoft.AspNet.Hosting.ini"); File.WriteAllText(iniFile, string.Format("ASPNET_ENV={0}", startParameters.EnvironmentName)); // Can't use localdb with IIS. Setting an override to use InMemoryStore. logger.LogInformation("Creating configoverride.json file to override default config."); var overrideConfig = Path.Combine(startParameters.ApplicationPath, "..", "approot", "src", "Hooli", "configoverride.json"); overrideConfig = Path.GetFullPath(overrideConfig); File.WriteAllText(overrideConfig, "{\"UseInMemoryStore\": \"true\"}"); if (startParameters.ServerType == ServerType.IISNativeModule) { logger.LogInformation("Turning runAllManagedModulesForAllRequests=true in web.config."); // Set runAllManagedModulesForAllRequests=true var webConfig = Path.Combine(startParameters.ApplicationPath, "web.config"); var configuration = new XmlDocument(); configuration.LoadXml(File.ReadAllText(webConfig)); // https://github.com/aspnet/Helios/issues/77 var rammfarAttribute = configuration.CreateAttribute("runAllManagedModulesForAllRequests"); rammfarAttribute.Value = "true"; var modulesNode = configuration.CreateElement("modules"); modulesNode.Attributes.Append(rammfarAttribute); var systemWebServerNode = configuration.CreateElement("system.webServer"); systemWebServerNode.AppendChild(modulesNode); configuration.SelectSingleNode("//configuration").AppendChild(systemWebServerNode); configuration.Save(webConfig); } logger.LogInformation("Successfully finished IIS application directory setup."); Thread.Sleep(1 * 1000); } else #endif { DnuPublish(startParameters, logger); } } #if DNX451 if (startParameters.ServerType == ServerType.IISNativeModule || startParameters.ServerType == ServerType.IIS) { startParameters.IISApplication = new IISApplication(startParameters, logger); startParameters.IISApplication.SetupApplication(); } else #endif if (startParameters.ServerType == ServerType.IISExpress) { hostProcess = StartHeliosHost(startParameters, logger); } else { hostProcess = StartSelfHost(startParameters, logger); } } //Restore the DNX_DEFAULT_LIB after starting the host process Environment.SetEnvironmentVariable("DNX_DEFAULT_LIB", backupRuntimeDefaultLibPath); Environment.SetEnvironmentVariable("ASPNET_ENV", string.Empty); return(hostProcess); }
private static void DnuPublish(StartParameters startParameters, ILogger logger, string publishRoot = null) { startParameters.PublishedApplicationRootPath = Path.Combine(publishRoot ?? Path.GetTempPath(), Guid.NewGuid().ToString()); var parameters = string.Format( "publish {0} -o {1} --runtime {2} {3}", startParameters.ApplicationPath, startParameters.PublishedApplicationRootPath, startParameters.Runtime, startParameters.PublishWithNoSource ? "--no-source" : string.Empty); logger.LogInformation("Executing command dnu {args}", parameters); var startInfo = new ProcessStartInfo { FileName = "dnu", Arguments = parameters, UseShellExecute = true, CreateNoWindow = true }; var hostProcess = Process.Start(startInfo); hostProcess.WaitForExit(60 * 1000); startParameters.ApplicationPath = (startParameters.ServerType == ServerType.IISExpress || startParameters.ServerType == ServerType.IISNativeModule || startParameters.ServerType == ServerType.IIS) ? Path.Combine(startParameters.PublishedApplicationRootPath, "wwwroot") : Path.Combine(startParameters.PublishedApplicationRootPath, "approot", "src", "MusicStore"); logger.LogInformation("dnu publish finished with exit code : {exitCode}", hostProcess.ExitCode); }
//[InlineData(ServerType.WebListener, KreFlavor.DesktopClr, KreArchitecture.x86, "http://localhost:5002/", false)] //[InlineData(ServerType.Kestrel, KreFlavor.DesktopClr, KreArchitecture.x86, "http://localhost:5004/", true)] public void PublishAndRunTests(ServerType serverType, KreFlavor kreFlavor, KreArchitecture architecture, string applicationBaseUrl, bool RunTestOnMono = false) { Console.WriteLine("Variation Details : HostType = {0}, KreFlavor = {1}, Architecture = {2}, applicationBaseUrl = {3}", serverType, kreFlavor, architecture, applicationBaseUrl); if (Helpers.SkipTestOnCurrentConfiguration(RunTestOnMono, architecture)) { Assert.True(true); return; } var startParameters = new StartParameters { ServerType = serverType, KreFlavor = kreFlavor, KreArchitecture = architecture, PackApplicationBeforeStart = true }; var testStartTime = DateTime.Now; var musicStoreDbName = Guid.NewGuid().ToString().Replace("-", string.Empty); Console.WriteLine("Pointing MusicStore DB to '{0}'", string.Format(Connection_string_Format, musicStoreDbName)); //Override the connection strings using environment based configuration Environment.SetEnvironmentVariable("SQLAZURECONNSTR_DefaultConnection", string.Format(Connection_string_Format, musicStoreDbName)); ApplicationBaseUrl = applicationBaseUrl; Process hostProcess = null; bool testSuccessful = false; try { hostProcess = DeploymentUtility.StartApplication(startParameters, musicStoreDbName); httpClientHandler = new HttpClientHandler() { UseDefaultCredentials = true }; httpClient = new HttpClient(httpClientHandler) { BaseAddress = new Uri(applicationBaseUrl) }; //Request to base address and check if various parts of the body are rendered & measure the cold startup time. var response = httpClient.GetAsync(string.Empty).Result; var responseContent = response.Content.ReadAsStringAsync().Result; var initializationCompleteTime = DateTime.Now; Console.WriteLine("[Time]: Approximate time taken for application initialization : '{0}' seconds", (initializationCompleteTime - testStartTime).TotalSeconds); VerifyHomePage(response, responseContent, true); //Static files are served? VerifyStaticContentServed(); var testCompletionTime = DateTime.Now; Console.WriteLine("[Time]: All tests completed in '{0}' seconds", (testCompletionTime - initializationCompleteTime).TotalSeconds); Console.WriteLine("[Time]: Total time taken for this test variation '{0}' seconds", (testCompletionTime - testStartTime).TotalSeconds); testSuccessful = true; } finally { if (!testSuccessful) { Console.WriteLine("Some tests failed. Proceeding with cleanup."); } DeploymentUtility.CleanUpApplication(startParameters, hostProcess, musicStoreDbName); } }
public void PublishAndRunTests(ServerType serverType, KreFlavor kreFlavor, KreArchitecture architecture, string applicationBaseUrl, bool RunTestOnMono = false) { Console.WriteLine("Variation Details : HostType = {0}, KreFlavor = {1}, Architecture = {2}, applicationBaseUrl = {3}", serverType, kreFlavor, architecture, applicationBaseUrl); if (Helpers.SkipTestOnCurrentConfiguration(RunTestOnMono, architecture)) { Assert.True(true); return; } var startParameters = new StartParameters { ServerType = serverType, KreFlavor = kreFlavor, KreArchitecture = architecture, PackApplicationBeforeStart = true }; var testStartTime = DateTime.Now; var musicStoreDbName = Guid.NewGuid().ToString().Replace("-", string.Empty); Console.WriteLine("Pointing MusicStore DB to '{0}'", string.Format(Connection_string_Format, musicStoreDbName)); //Override the connection strings using environment based configuration Environment.SetEnvironmentVariable("SQLAZURECONNSTR_DefaultConnection", string.Format(Connection_string_Format, musicStoreDbName)); ApplicationBaseUrl = applicationBaseUrl; Process hostProcess = null; bool testSuccessful = false; try { hostProcess = DeploymentUtility.StartApplication(startParameters, musicStoreDbName); httpClientHandler = new HttpClientHandler() { UseDefaultCredentials = true }; httpClient = new HttpClient(httpClientHandler) { BaseAddress = new Uri(applicationBaseUrl) }; HttpResponseMessage response = null; string responseContent = null; var initializationCompleteTime = DateTime.MinValue; //Request to base address and check if various parts of the body are rendered & measure the cold startup time. //Add retry logic since tests are flaky on mono due to connection issues for (int retryCount = 0; retryCount < 3; retryCount++) { try { response = httpClient.GetAsync(string.Empty).Result; responseContent = response.Content.ReadAsStringAsync().Result; initializationCompleteTime = DateTime.Now; Console.WriteLine("[Time]: Approximate time taken for application initialization : '{0}' seconds", (initializationCompleteTime - testStartTime).TotalSeconds); break; //Went through successfully } catch (AggregateException exception) { // Both type exceptions thrown by Mono which are resolved by retry logic if (exception.InnerException is HttpRequestException || exception.InnerException is WebException) { Console.WriteLine("Failed to complete the request with error: {0}", exception.ToString()); Console.WriteLine("Retrying request.."); Thread.Sleep(1 * 1000); //Wait for a second before retry } } } VerifyHomePage(response, responseContent, true); //Static files are served? VerifyStaticContentServed(); if (serverType != ServerType.Helios) { if (Directory.GetFiles(startParameters.ApplicationPath, "*.cmd", SearchOption.TopDirectoryOnly).Length > 0) { throw new Exception("packExclude parameter values are not honored"); } } var testCompletionTime = DateTime.Now; Console.WriteLine("[Time]: All tests completed in '{0}' seconds", (testCompletionTime - initializationCompleteTime).TotalSeconds); Console.WriteLine("[Time]: Total time taken for this test variation '{0}' seconds", (testCompletionTime - testStartTime).TotalSeconds); testSuccessful = true; } finally { if (!testSuccessful) { Console.WriteLine("Some tests failed. Proceeding with cleanup."); } DeploymentUtility.CleanUpApplication(startParameters, hostProcess, musicStoreDbName); } }
private void OpenIdConnectTestSuite(ServerType serverType, RuntimeFlavor donetFlavor, RuntimeArchitecture architecture, string applicationBaseUrl) { using (_logger.BeginScope("OpenIdConnectTestSuite")) { _logger.LogInformation("Variation Details : HostType = {hostType}, DonetFlavor = {flavor}, Architecture = {arch}, applicationBaseUrl = {appBase}", serverType, donetFlavor, architecture, applicationBaseUrl); _startParameters = new StartParameters { ServerType = serverType, RuntimeFlavor = donetFlavor, RuntimeArchitecture = architecture, EnvironmentName = "OpenIdConnectTesting" }; var stopwatch = Stopwatch.StartNew(); var musicStoreDbName = Guid.NewGuid().ToString().Replace("-", string.Empty); _logger.LogInformation("Pointing MusicStore DB to '{connString}'", string.Format(CONNECTION_STRING_FORMAT, musicStoreDbName)); //Override the connection strings using environment based configuration Environment.SetEnvironmentVariable("SQLAZURECONNSTR_DefaultConnection", string.Format(CONNECTION_STRING_FORMAT, musicStoreDbName)); _applicationBaseUrl = applicationBaseUrl; Process hostProcess = null; bool testSuccessful = false; try { hostProcess = DeploymentUtility.StartApplication(_startParameters, _logger); #if DNX451 if (serverType == ServerType.IISNativeModule || serverType == ServerType.IIS) { // Accomodate the vdir name. _applicationBaseUrl += _startParameters.IISApplication.VirtualDirectoryName + "/"; } #endif _httpClientHandler = new HttpClientHandler(); _httpClient = new HttpClient(_httpClientHandler) { BaseAddress = new Uri(_applicationBaseUrl) }; HttpResponseMessage response = null; string responseContent = null; //Request to base address and check if various parts of the body are rendered & measure the cold startup time. Helpers.Retry(() => { response = _httpClient.GetAsync(string.Empty).Result; responseContent = response.Content.ReadAsStringAsync().Result; _logger.LogInformation("[Time]: Approximate time taken for application initialization : '{t}' seconds", stopwatch.Elapsed.TotalSeconds); }, logger: _logger); VerifyHomePage(response, responseContent); // OpenIdConnect login. LoginWithOpenIdConnect(); stopwatch.Stop(); _logger.LogInformation("[Time]: Total time taken for this test variation '{t}' seconds", stopwatch.Elapsed.TotalSeconds); testSuccessful = true; } finally { if (!testSuccessful) { _logger.LogError("Some tests failed. Proceeding with cleanup."); } DeploymentUtility.CleanUpApplication(_startParameters, hostProcess, musicStoreDbName, _logger); } } }
public void NtlmAuthenticationTest(ServerType serverType, RuntimeFlavor runtimeFlavor, RuntimeArchitecture architecture, string applicationBaseUrl) { using (_logger.BeginScope("NtlmAuthenticationTest")) { _logger.LogInformation("Variation Details : HostType = {hostType}, RuntimeFlavor = {flavor}, Architecture = {arch}, applicationBaseUrl = {appBase}", serverType, runtimeFlavor, architecture, applicationBaseUrl); _startParameters = new StartParameters { ServerType = serverType, RuntimeFlavor = runtimeFlavor, RuntimeArchitecture = architecture, EnvironmentName = "NtlmAuthentication", //Will pick the Start class named 'StartupNtlmAuthentication' ApplicationHostConfigTemplateContent = (serverType == ServerType.IISExpress) ? File.ReadAllText("NtlmAuthentation.config") : null, SiteName = "HooliNtlmAuthentication" //This is configured in the NtlmAuthentication.config }; var stopwatch = Stopwatch.StartNew(); var musicStoreDbName = Guid.NewGuid().ToString().Replace("-", string.Empty); _logger.LogInformation("Pointing Hooli DB to '{connString}'", string.Format(CONNECTION_STRING_FORMAT, musicStoreDbName)); //Override the connection strings using environment based configuration Environment.SetEnvironmentVariable("SQLAZURECONNSTR_DefaultConnection", string.Format(CONNECTION_STRING_FORMAT, musicStoreDbName)); _applicationBaseUrl = applicationBaseUrl; Process hostProcess = null; bool testSuccessful = false; try { hostProcess = DeploymentUtility.StartApplication(_startParameters, _logger); _httpClientHandler = new HttpClientHandler() { UseDefaultCredentials = true }; _httpClient = new HttpClient(_httpClientHandler) { BaseAddress = new Uri(applicationBaseUrl) }; HttpResponseMessage response = null; string responseContent = null; //Request to base address and check if various parts of the body are rendered & measure the cold startup time. Helpers.Retry(() => { response = _httpClient.GetAsync(string.Empty).Result; responseContent = response.Content.ReadAsStringAsync().Result; _logger.LogInformation("[Time]: Approximate time taken for application initialization : '{t}' seconds", stopwatch.Elapsed.TotalSeconds); }, logger: _logger); VerifyHomePage(response, responseContent, true); //Check if the user name appears in the page Assert.Contains( string.Format("{0}\\{1}", Environment.GetEnvironmentVariable("USERDOMAIN"), Environment.GetEnvironmentVariable("USERNAME")), responseContent, StringComparison.OrdinalIgnoreCase); //Should be able to access the store as the Startup adds necessary permissions for the current user AccessStoreWithPermissions(); stopwatch.Stop(); _logger.LogInformation("[Time]: Total time taken for this test variation '{t}' seconds", stopwatch.Elapsed.TotalSeconds); testSuccessful = true; } finally { if (!testSuccessful) { _logger.LogError("Some tests failed. Proceeding with cleanup."); } DeploymentUtility.CleanUpApplication(_startParameters, hostProcess, musicStoreDbName, _logger); } } }
private static Process StartSelfHost(StartParameters startParameters, ILogger logger) { var commandName = startParameters.ServerType == ServerType.WebListener ? "web" : "kestrel"; logger.LogInformation("Executing dnx.exe --appbase {appPath} \"Microsoft.Framework.ApplicationHost\" {command}", startParameters.ApplicationPath, commandName); var startInfo = new ProcessStartInfo { FileName = "dnx.exe", Arguments = string.Format("--appbase \"{0}\" \"Microsoft.Framework.ApplicationHost\" {1}", startParameters.ApplicationPath, commandName), UseShellExecute = true, CreateNoWindow = true }; var hostProcess = Process.Start(startInfo); //Sometimes reading MainModule returns null if called immediately after starting process. Thread.Sleep(1 * 1000); if (hostProcess.HasExited) { logger.LogError("Host process {processName} exited with code {exitCode} or failed to start.", startInfo.FileName, hostProcess.ExitCode); throw new Exception("Failed to start host"); } try { logger.LogInformation("Started {fileName}. Process Id : {processId}", hostProcess.MainModule.FileName, hostProcess.Id); } catch (Win32Exception win32Exception) { logger.LogWarning("Cannot access 64 bit modules from a 32 bit process. Failed with following message.", win32Exception); } return hostProcess; }
public static Process StartApplication(StartParameters startParameters, ILogger logger) { startParameters.ApplicationPath = Path.GetFullPath(Path.Combine(Directory.GetCurrentDirectory(), APP_RELATIVE_PATH)); //To avoid the DNX_DEFAULT_LIB of the test process flowing into Helios, set it to empty var backupRuntimeDefaultLibPath = Environment.GetEnvironmentVariable("DNX_DEFAULT_LIB"); Environment.SetEnvironmentVariable("DNX_DEFAULT_LIB", string.Empty); if (!string.IsNullOrWhiteSpace(startParameters.EnvironmentName)) { if (startParameters.ServerType != ServerType.IISNativeModule && startParameters.ServerType != ServerType.IIS) { // To choose an environment based Startup. Environment.SetEnvironmentVariable("ASPNET_ENV", startParameters.EnvironmentName); } else { // Cannot override with environment in case of IIS. Publish and write a Microsoft.AspNet.Hosting.ini file. startParameters.PublishApplicationBeforeStart = true; } } Process hostProcess = null; if (startParameters.RuntimeFlavor == RuntimeFlavor.Mono) { hostProcess = StartMonoHost(startParameters, logger); } else { //Tweak the %PATH% to the point to the right RUNTIMEFLAVOR startParameters.Runtime = SwitchPathToRuntimeFlavor(startParameters.RuntimeFlavor, startParameters.RuntimeArchitecture, logger); //Reason to do pack here instead of in a common place is use the right runtime to do the packing. Previous line switches to use the right runtime. if (startParameters.PublishApplicationBeforeStart) { #if DNX451 if (startParameters.ServerType == ServerType.IISNativeModule || startParameters.ServerType == ServerType.IIS) { // Publish to IIS root\application folder. DnuPublish(startParameters, logger, Path.Combine(Environment.GetEnvironmentVariable("SystemDrive") + @"\", @"inetpub\wwwroot")); // Drop a Microsoft.AspNet.Hosting.ini with ASPNET_ENV information. logger.LogInformation("Creating Microsoft.AspNet.Hosting.ini file with ASPNET_ENV."); var iniFile = Path.Combine(startParameters.ApplicationPath, "Microsoft.AspNet.Hosting.ini"); File.WriteAllText(iniFile, string.Format("ASPNET_ENV={0}", startParameters.EnvironmentName)); // Can't use localdb with IIS. Setting an override to use InMemoryStore. logger.LogInformation("Creating configoverride.json file to override default config."); var overrideConfig = Path.Combine(startParameters.ApplicationPath, "..", "approot", "src", "MusicStore", "configoverride.json"); overrideConfig = Path.GetFullPath(overrideConfig); File.WriteAllText(overrideConfig, "{\"UseInMemoryStore\": \"true\"}"); if (startParameters.ServerType == ServerType.IISNativeModule) { logger.LogInformation("Turning runAllManagedModulesForAllRequests=true in web.config."); // Set runAllManagedModulesForAllRequests=true var webConfig = Path.Combine(startParameters.ApplicationPath, "web.config"); var configuration = new XmlDocument(); configuration.LoadXml(File.ReadAllText(webConfig)); // https://github.com/aspnet/Helios/issues/77 var rammfarAttribute = configuration.CreateAttribute("runAllManagedModulesForAllRequests"); rammfarAttribute.Value = "true"; var modulesNode = configuration.CreateElement("modules"); modulesNode.Attributes.Append(rammfarAttribute); var systemWebServerNode = configuration.CreateElement("system.webServer"); systemWebServerNode.AppendChild(modulesNode); configuration.SelectSingleNode("//configuration").AppendChild(systemWebServerNode); configuration.Save(webConfig); } logger.LogInformation("Successfully finished IIS application directory setup."); Thread.Sleep(1 * 1000); } else #endif { DnuPublish(startParameters, logger); } } #if DNX451 if (startParameters.ServerType == ServerType.IISNativeModule || startParameters.ServerType == ServerType.IIS) { startParameters.IISApplication = new IISApplication(startParameters, logger); startParameters.IISApplication.SetupApplication(); } else #endif if (startParameters.ServerType == ServerType.IISExpress) { hostProcess = StartHeliosHost(startParameters, logger); } else { hostProcess = StartSelfHost(startParameters, logger); } } //Restore the DNX_DEFAULT_LIB after starting the host process Environment.SetEnvironmentVariable("DNX_DEFAULT_LIB", backupRuntimeDefaultLibPath); Environment.SetEnvironmentVariable("ASPNET_ENV", string.Empty); return hostProcess; }
private static Process StartHeliosHost(StartParameters startParameters, ILogger logger) { if (!string.IsNullOrWhiteSpace(startParameters.ApplicationHostConfigTemplateContent)) { startParameters.ApplicationHostConfigTemplateContent = startParameters.ApplicationHostConfigTemplateContent.Replace("[ApplicationPhysicalPath]", Path.Combine(startParameters.ApplicationPath, "wwwroot")); } if (!startParameters.PublishApplicationBeforeStart) { IISExpressHelper.CopyAspNetLoader(startParameters.ApplicationPath); } if (!string.IsNullOrWhiteSpace(startParameters.ApplicationHostConfigTemplateContent)) { //Pass on the applicationhost.config to iis express. With this don't need to pass in the /path /port switches as they are in the applicationHost.config //We take a copy of the original specified applicationHost.Config to prevent modifying the one in the repo. var tempApplicationHostConfig = Path.GetTempFileName(); File.WriteAllText(tempApplicationHostConfig, startParameters.ApplicationHostConfigTemplateContent.Replace("[ApplicationPhysicalPath]", startParameters.ApplicationPath)); startParameters.ApplicationHostConfigLocation = tempApplicationHostConfig; } var webroot = startParameters.ApplicationPath; if (!webroot.EndsWith("wwwroot")) { webroot = Path.Combine(webroot, "wwwroot"); } var parameters = string.IsNullOrWhiteSpace(startParameters.ApplicationHostConfigLocation) ? string.Format("/port:5001 /path:\"{0}\"", webroot) : string.Format("/site:{0} /config:{1}", startParameters.SiteName, startParameters.ApplicationHostConfigLocation); var iisExpressPath = IISExpressHelper.GetPath(startParameters.RuntimeArchitecture); logger.LogInformation("Executing command : {iisExpress} {args}", iisExpressPath, parameters); var startInfo = new ProcessStartInfo { FileName = iisExpressPath, Arguments = parameters, UseShellExecute = true, CreateNoWindow = true }; var hostProcess = Process.Start(startInfo); logger.LogInformation("Started iisexpress. Process Id : {processId}", hostProcess.Id); return hostProcess; }
private static Process StartMonoHost(StartParameters startParameters, ILogger logger) { var path = Environment.GetEnvironmentVariable("PATH"); var runtimeBin = path.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries). Where(c => c.Contains("dnx-mono")).FirstOrDefault(); if (string.IsNullOrWhiteSpace(runtimeBin)) { throw new Exception("Runtime not detected on the machine."); } if (startParameters.PublishApplicationBeforeStart) { // We use full path to runtime to pack. startParameters.Runtime = new DirectoryInfo(runtimeBin).Parent.FullName; DnuPublish(startParameters, logger); } //Mono now supports --appbase logger.LogInformation("Setting the --appbase to {0}", startParameters.ApplicationPath); var bootstrapper = "dnx"; var commandName = startParameters.ServerType == ServerType.Kestrel ? "kestrel" : string.Empty; logger.LogInformation("Executing command: {dnx} \"{appPath}\" {command}", bootstrapper, startParameters.ApplicationPath, commandName); var startInfo = new ProcessStartInfo { FileName = bootstrapper, Arguments = string.Format("\"{0}\" {1}", startParameters.ApplicationPath, commandName), UseShellExecute = false, CreateNoWindow = true, RedirectStandardInput = true }; var hostProcess = Process.Start(startInfo); logger.LogInformation("Started {0}. Process Id : {1}", hostProcess.MainModule.FileName, hostProcess.Id); if (hostProcess.HasExited) { logger.LogError("Host process {processName} exited with code {exitCode} or failed to start.", startInfo.FileName, hostProcess.ExitCode); throw new Exception("Failed to start host"); } return hostProcess; }
//WindowsIdentity not available on CoreCLR //[InlineData(ServerType.Helios, KreFlavor.CoreClr, KreArchitecture.x86, "http://localhost:5001/", false)] //[InlineData(ServerType.WebListener, KreFlavor.CoreClr, KreArchitecture.x86, "http://localhost:5002/", false)] public void NtlmAuthenticationTest(ServerType serverType, KreFlavor kreFlavor, KreArchitecture architecture, string applicationBaseUrl, bool RunTestOnMono = false) { Console.WriteLine("Variation Details : HostType = {0}, KreFlavor = {1}, Architecture = {2}, applicationBaseUrl = {3}", serverType, kreFlavor, architecture, applicationBaseUrl); if (Helpers.SkipTestOnCurrentConfiguration(RunTestOnMono, architecture)) { Assert.True(true); return; } var startParameters = new StartParameters { ServerType = serverType, KreFlavor = kreFlavor, KreArchitecture = architecture, EnvironmentName = "NtlmAuthentication", //Will pick the Start class named 'StartupNtlmAuthentication' ApplicationHostConfigTemplateContent = (serverType == ServerType.Helios) ? File.ReadAllText("NtlmAuthentation.config") : null, SiteName = "MusicStoreNtlmAuthentication" //This is configured in the NtlmAuthentication.config }; var testStartTime = DateTime.Now; var musicStoreDbName = Guid.NewGuid().ToString().Replace("-", string.Empty); Console.WriteLine("Pointing MusicStore DB to '{0}'", string.Format(Connection_string_Format, musicStoreDbName)); //Override the connection strings using environment based configuration Environment.SetEnvironmentVariable("SQLAZURECONNSTR_DefaultConnection", string.Format(Connection_string_Format, musicStoreDbName)); ApplicationBaseUrl = applicationBaseUrl; Process hostProcess = null; bool testSuccessful = false; try { hostProcess = DeploymentUtility.StartApplication(startParameters, musicStoreDbName); httpClientHandler = new HttpClientHandler() { UseDefaultCredentials = true }; httpClient = new HttpClient(httpClientHandler) { BaseAddress = new Uri(applicationBaseUrl) }; //Request to base address and check if various parts of the body are rendered & measure the cold startup time. var response = httpClient.GetAsync(string.Empty).Result; var responseContent = response.Content.ReadAsStringAsync().Result; var initializationCompleteTime = DateTime.Now; Console.WriteLine("[Time]: Approximate time taken for application initialization : '{0}' seconds", (initializationCompleteTime - testStartTime).TotalSeconds); VerifyHomePage(response, responseContent, true); //Check if the user name appears in the page Assert.Contains(string.Format("{0}\\{1}", Environment.UserDomainName, Environment.UserName), responseContent, StringComparison.OrdinalIgnoreCase); if (serverType != ServerType.Helios) { //https://github.com/aspnet/Helios/issues/53 //Should be able to access the store as the Startup adds necessary permissions for the current user AccessStoreWithPermissions(); } var testCompletionTime = DateTime.Now; Console.WriteLine("[Time]: All tests completed in '{0}' seconds", (testCompletionTime - initializationCompleteTime).TotalSeconds); Console.WriteLine("[Time]: Total time taken for this test variation '{0}' seconds", (testCompletionTime - testStartTime).TotalSeconds); testSuccessful = true; } finally { if (!testSuccessful) { Console.WriteLine("Some tests failed. Proceeding with cleanup."); } DeploymentUtility.CleanUpApplication(startParameters, hostProcess, musicStoreDbName); } }
private void Publish_And_Run_Tests(ServerType serverType, RuntimeFlavor runtimeFlavor, RuntimeArchitecture architecture, string applicationBaseUrl, bool noSource) { using (_logger.BeginScope("Publish_And_Run_Tests")) { _logger.LogInformation("Variation Details : HostType = {hostType}, RuntimeFlavor = {flavor}, Architecture = {arch}, applicationBaseUrl = {appBase}", serverType, runtimeFlavor, architecture, applicationBaseUrl); _startParameters = new StartParameters { ServerType = serverType, RuntimeFlavor = runtimeFlavor, RuntimeArchitecture = architecture, PublishApplicationBeforeStart = true, PublishWithNoSource = noSource }; var stopwatch = Stopwatch.StartNew(); var musicStoreDbName = Guid.NewGuid().ToString().Replace("-", string.Empty); _logger.LogInformation("Pointing MusicStore DB to '{connString}'", string.Format(CONNECTION_STRING_FORMAT, musicStoreDbName)); //Override the connection strings using environment based configuration Environment.SetEnvironmentVariable("SQLAZURECONNSTR_DefaultConnection", string.Format(CONNECTION_STRING_FORMAT, musicStoreDbName)); _applicationBaseUrl = applicationBaseUrl; Process hostProcess = null; bool testSuccessful = false; try { hostProcess = DeploymentUtility.StartApplication(_startParameters, _logger); _httpClientHandler = new HttpClientHandler() { UseDefaultCredentials = true }; _httpClient = new HttpClient(_httpClientHandler) { BaseAddress = new Uri(applicationBaseUrl) }; HttpResponseMessage response = null; string responseContent = null; //Request to base address and check if various parts of the body are rendered & measure the cold startup time. //Add retry logic since tests are flaky on mono due to connection issues Helpers.Retry(() => { response = _httpClient.GetAsync(string.Empty).Result; responseContent = response.Content.ReadAsStringAsync().Result; _logger.LogInformation("[Time]: Approximate time taken for application initialization : '{t}' seconds", stopwatch.Elapsed.TotalSeconds); }, logger: _logger); VerifyHomePage(response, responseContent, true); //Static files are served? VerifyStaticContentServed(); if (serverType != ServerType.IISExpress) { if (Directory.GetFiles(_startParameters.ApplicationPath, "*.cmd", SearchOption.TopDirectoryOnly).Length > 0) { throw new Exception("publishExclude parameter values are not honored."); } } stopwatch.Stop(); _logger.LogInformation("[Time]: Total time taken for this test variation '{t}' seconds.", stopwatch.Elapsed.TotalSeconds); testSuccessful = true; } finally { if (!testSuccessful) { _logger.LogError("Some tests failed. Proceeding with cleanup."); } DeploymentUtility.CleanUpApplication(_startParameters, hostProcess, musicStoreDbName, _logger); } } }