From f400550b5b5b71be4e9afa653bbc76d9cde52590 Mon Sep 17 00:00:00 2001 From: Praburaj Date: Mon, 15 Sep 2014 17:10:06 -0700 Subject: [PATCH] Adding a variation that does a kpm pack and starts the application Currently adding only for Helios & X86 desktop CLR. Will add a few more interesting variations in future. --- test/E2ETests/DeploymentUtility.cs | 53 +++++++++++++++++-- test/E2ETests/PublishAndRunTests.cs | 80 +++++++++++++++++++++++++++++ test/E2ETests/StartParameters.cs | 4 ++ 3 files changed, 133 insertions(+), 4 deletions(-) create mode 100644 test/E2ETests/PublishAndRunTests.cs diff --git a/test/E2ETests/DeploymentUtility.cs b/test/E2ETests/DeploymentUtility.cs index 1848b1274c..8dfd21c889 100644 --- a/test/E2ETests/DeploymentUtility.cs +++ b/test/E2ETests/DeploymentUtility.cs @@ -53,7 +53,7 @@ namespace E2ETests } } - private const string APP_RELATIVE_PATH = @"..\..\src\MusicStore\"; + private static string APP_RELATIVE_PATH = Path.Combine("..", "..", "src", "MusicStore"); public static Process StartApplication(StartParameters startParameters, string identityDbName) { @@ -80,6 +80,12 @@ namespace E2ETests //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) { hostProcess = StartHeliosHost(startParameters); @@ -98,8 +104,10 @@ namespace E2ETests private static Process StartMonoHost(StartParameters startParameters) { - //Mono needs this as GetFullPath does not work if it has \ - startParameters.ApplicationPath = Path.GetFullPath(startParameters.ApplicationPath.Replace('\\', '/')); + 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); @@ -173,7 +181,6 @@ namespace E2ETests private static Process StartSelfHost(StartParameters startParameters, string identityDbName) { - //ServerType hostType, string applicationPath, string identityDbName Console.WriteLine(string.Format("Executing klr.exe --appbase {0} \"Microsoft.Framework.ApplicationHost\" {1}", startParameters.ApplicationPath, startParameters.ServerType.ToString())); var startInfo = new ProcessStartInfo @@ -220,6 +227,31 @@ namespace E2ETests return pathValue; } + 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); + } + //In case of self-host application activation happens immediately unlike iis where activation happens on first request. //So in self-host case, we need a way to block the first request until the application is initialized. In MusicStore application's case, //identity DB creation is pretty much the last step of application setup. So waiting on this event will help us wait efficiently. @@ -307,6 +339,19 @@ namespace E2ETests } } } + + 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); + } + } } } } \ No newline at end of file diff --git a/test/E2ETests/PublishAndRunTests.cs b/test/E2ETests/PublishAndRunTests.cs new file mode 100644 index 0000000000..878dfef8a5 --- /dev/null +++ b/test/E2ETests/PublishAndRunTests.cs @@ -0,0 +1,80 @@ +using System; +using System.Diagnostics; +using System.Net.Http; +using Xunit; + +namespace E2ETests +{ + /// + /// Summary description for PublishAndRunTests + /// + public partial class SmokeTests + { + [Theory] + [InlineData(ServerType.Helios, KreFlavor.DesktopClr, KreArchitecture.x86, "http://localhost:5001/", false)] + //[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); + } + } + } +} \ No newline at end of file diff --git a/test/E2ETests/StartParameters.cs b/test/E2ETests/StartParameters.cs index aed59c2882..c8707d670e 100644 --- a/test/E2ETests/StartParameters.cs +++ b/test/E2ETests/StartParameters.cs @@ -20,5 +20,9 @@ public string SiteName { get; set; } public string ApplicationPath { get; set; } + + public bool PackApplicationBeforeStart { get; set; } + + public string PackedApplicationRootPath { get; set; } } } \ No newline at end of file