/// <summary> /// Formats the login url based on the specified application, church code and environment. /// </summary> /// <param name="application">The application under test.</param> /// <param name="churchCode">The church code targeted.</param> /// <param name="environment">The environment targeted.</param> /// <returns>A string url representing the entry point for the test.</returns> public static string FormatLoginURL(Enums.Applications application, string churchCode, Enums.Environments environment) { string targetURL = string.Empty; if (application == Enums.Applications.INFELLOWSHIP) { switch (environment) { case Enums.Environments.DEV1: case Enums.Environments.DEV2: case Enums.Environments.DEV3: targetURL = string.Format("http://{0}.infellowship.{1}.dev.corp.local/UserLogin/Attempt", churchCode, environment); break; case Enums.Environments.INTEGRATION: targetURL = string.Format("http://{0}.infellowship.integration.corp.local/UserLogin/Attempt", churchCode); break; case Enums.Environments.DEV: case Enums.Environments.QA: targetURL = string.Format("http://{0}.infellowship{1}.dev.corp.local/UserLogin/Attempt", churchCode, environment); break; case Enums.Environments.STAGING: targetURL = string.Format("https://{0}.staging.infellowship.com/UserLogin/Attempt", churchCode); break; default: throw new Exception("Not a valid option!"); } } else if (application == Enums.Applications.PORTAL) { switch (environment) { case Enums.Environments.LOCAL: targetURL = "http://portal.local/login.aspx/"; break; case Enums.Environments.DEV1: case Enums.Environments.DEV2: case Enums.Environments.DEV3: targetURL = string.Format("http://portal.{0}.dev.corp.local/login.aspx/", environment.ToString().ToLower()); break; case Enums.Environments.INTEGRATION: targetURL = "http://portal.integration.corp.local/login.aspx/"; break; case Enums.Environments.DEV: case Enums.Environments.QA: targetURL = string.Format("http://portal{0}.dev.corp.local/login.aspx", environment); break; case Enums.Environments.STAGING: targetURL = "https://staging-www.fellowshipone.com/login.aspx"; break; default: throw new Exception("Not a valid option!"); } } else if (application == Enums.Applications.REPORTLIBRARY) { switch (environment) { case Enums.Environments.LOCAL: targetURL = "http://portal.local/login.aspx/"; break; case Enums.Environments.DEV1: case Enums.Environments.DEV2: case Enums.Environments.DEV3: targetURL = string.Format("http://portal.{0}.dev.corp.local/login.aspx/", environment.ToString().ToLower()); break; case Enums.Environments.INTEGRATION: targetURL = "http://portal.integration.corp.local/login.aspx/"; break; case Enums.Environments.DEV: case Enums.Environments.QA: targetURL = string.Format("http://reportlibrary{0}.dev.corp.local/ReportLibrary/Login/Index.aspx", environment); break; case Enums.Environments.STAGING: targetURL = "https://staging-reportlibrary.fellowshipone.com/ReportLibrary/Login/Index.aspx"; break; default: throw new Exception("Not a valid option!"); } } else { throw new Exception("Application not available!"); } return(targetURL); }
// possible args: duration, threads, target url, postdata, etc. static void Main(string[] args) { Console.WriteLine("QA Load Testing App"); Console.Write("Enter the test xml file name: "); string xmlFile = Console.ReadLine(); // Attempt to open the xml file specified by the user XmlDocument test = new XmlDocument(); try { test.Load(string.Format("../../../{0}", xmlFile)); } catch (FileNotFoundException e) { Console.WriteLine(e.Message); Console.ReadKey(); Environment.Exit(2); } // Extract the configuration and test details Enums.Applications app = (Enums.Applications)Enum.Parse(typeof(Enums.Applications), test.SelectSingleNode("//configuration/application").InnerText.ToUpper()); Enums.Environments environment = (Enums.Environments)Enum.Parse(typeof(Enums.Environments), test.SelectSingleNode("//configuration/environment").InnerText.ToUpper()); string churchCode = test.SelectSingleNode("//configuration/churchCode").InnerText; int maxThreads = Convert.ToInt16(test.SelectSingleNode("//configuration/threads").InnerText); int rampUp = Convert.ToInt16(test.SelectSingleNode("//configuration/rampUp").InnerText); int duration = int.MinValue; bool isTimedRun = int.TryParse(test.SelectSingleNode("//configuration/duration").InnerText, out duration); string URL = test.SelectSingleNode("//configuration/targetURL").InnerText; string requestType = test.SelectSingleNode("//configuration/requestType").InnerText; XmlNode credentials = test.SelectSingleNode("//credentials"); XmlNodeList pData = test.SelectNodes("//postData/dataItem"); // Configure the test engine ThreadPool.SetMaxThreads(maxThreads, maxThreads); ThreadPool.SetMinThreads(maxThreads, maxThreads); Actions action = new Actions(); DateTime stopTime = DateTime.Now.AddSeconds(duration); // If the request is a post generate the data, if not, set to null string targetReqData = requestType == "POST" ? Helpers.GenerateTargetRequestData(pData) : null; if (isTimedRun) { while (DateTime.Now < stopTime) { int workerThreads; int portThreads; ThreadPool.GetAvailableThreads(out workerThreads, out portThreads); if (workerThreads > 0) { ThreadPool.QueueUserWorkItem(new WaitCallback(action.MakeRequests), new TestInfo() { application = app, loginURL = Helpers.FormatLoginURL(app, churchCode, environment), loginRequestData = Helpers.GenerateLoginRequestData(app, credentials, churchCode), targetURL = URL, targetRequestData = targetReqData }); Thread.Sleep(250); } else { var timeLeft = (stopTime - DateTime.Now); Console.WriteLine("Queue is full... time left {0:0}:{1:00}", timeLeft.Minutes, timeLeft.Seconds); Thread.Sleep(1000); } } } else { for (int i = 0; i < maxThreads; i++) { ThreadPool.QueueUserWorkItem(new WaitCallback(action.MakeRequests), new TestInfo() { application = app, loginURL = Helpers.FormatLoginURL(app, churchCode, environment), loginRequestData = Helpers.GenerateLoginRequestData(app, credentials, churchCode), targetURL = URL, targetRequestData = targetReqData }); Thread.Sleep(250); } } // Allow the existing requests to burnoff before exiting the application int threadsLeft = 1; int portThreadsLeft = 1; DateTime burnoff = DateTime.Now.AddSeconds(180); Console.WriteLine("Finished making requests, entering the burnoff period."); while (DateTime.Now < burnoff && threadsLeft < maxThreads) { ThreadPool.GetAvailableThreads(out threadsLeft, out portThreadsLeft); Console.WriteLine("Waiting for {0} thread(s) to finish...", maxThreads - threadsLeft); Thread.Sleep(1000); } Console.WriteLine("Test run completed. Press any key to close the application."); Console.ReadKey(); }