public void Basic3SiteValidatorTest()
        {
            var requestList = new List<HttpRequestData>()
            {

                // should work because it's local loopback
                new HttpRequestData
                {
                    Url = "http://rasxps/WebLog"
                },
                              new HttpRequestData
                {
                    Url = "http://rasxps/WebLog/posts"
                }

            };
            var stress = new StressTester();

            var validator = new SiteValidator(stress);
            bool result = validator.CheckAllServers(requestList);

            Console.WriteLine(validator.ErrorMessage);
            Assert.IsTrue(result);
        }
        /// <summary>
        /// This is the main Session processing routine. This routine creates the
        /// new threads to run each session on. It monitors for shutdown/cancel operation
        /// and then shuts down the worker threads and summarizes the results.
        ///
        /// The worker method call for each Session request processing is
        /// SessionThreadRunner().
        /// </summary>
        /// <param name="requests"></param>
        /// <param name="threadCount"></param>
        /// <param name="seconds"></param>
        /// <returns></returns>
        public List <HttpRequestData> CheckAllSites(IEnumerable <HttpRequestData> requests,
                                                    int threadCount = 2,
                                                    int seconds     = 60,
                                                    bool runOnce    = false)
        {
            ThreadsUsed = threadCount;

            //if (UnlockKey.RegType == RegTypes.Free &&
            //    (threadCount > UnlockKey.FreeThreadLimit ||
            //    requests.Count() > UnlockKey.FreeSitesLimit))
            //{
            //    Running = false;
            //    SetError("The free version is limited to " + UnlockKey.FreeSitesLimit + " urls to check and " + UnlockKey.FreeThreadLimit + " simultaneous threads.\r\n\r\n" +
            //            "Please reduce the URL or thread counts, or consider purchasing the Professional version that includes unlimited sites and threads.");
            //    return null;
            //}

            if (!runOnce)
            {
                var validator = new SiteValidator(this);
                if (!validator.CheckAllServers(requests))
                {
                    SetError(validator.ErrorMessage);
                    Running = false;
                    return(null);
                }
            }


            Results  = new List <HttpRequestData>();
            requests = requests.Where(req => req.IsActive).ToList();


            foreach (var plugin in App.Plugins)
            {
                try
                {
                    if (!plugin.OnLoadTestStarted(requests as List <HttpRequestData>))
                    {
                        return(null);
                    }
                }
                catch (Exception ex)
                {
                    App.Log(plugin.GetType().Name + " failed in OnLoadTestStarted(): " + ex.Message);
                }
            }

            Running = true;

            var threads = new List <Thread>();

            CancelThreads     = false;
            RequestsProcessed = 0;
            RequestsFailed    = 0;

            // add warmup seconds to the request
            seconds += Options.WarmupSeconds;

            StartTime = DateTime.UtcNow;
            for (int i = 0; i < threadCount; i++)
            {
                var thread = new Thread(RunSessions);
                thread.Start(requests);
                threads.Add(thread);
            }

            var lastProgress = DateTime.UtcNow.AddSeconds(-10);

            while (!CancelThreads)
            {
                if (DateTime.UtcNow.Subtract(StartTime).TotalSeconds > seconds + 1)
                {
                    TimeTakenForLastRunMs = (int)DateTime.UtcNow.Subtract(StartTime).TotalMilliseconds;

                    CancelThreads = true;

                    Thread.Sleep(3000);
                    foreach (var thread in threads)
                    {
                        thread.Abort();
                    }
                    Thread.Sleep(1000);

                    break;
                }
                Thread.Sleep(100);

                if (DateTime.UtcNow.Subtract(lastProgress).TotalMilliseconds > 950)
                {
                    lastProgress = DateTime.UtcNow;

                    OnProgress(new ProgressInfo()
                    {
                        SecondsProcessed        = (int)DateTime.UtcNow.Subtract(StartTime).TotalSeconds,
                        TotalSecondsToProcessed = seconds,
                        RequestsProcessed       = RequestsProcessed,
                        RequestsFailed          = RequestsFailed,
                    });
                }
            }

            Running = false;

            seconds = seconds - Options.WarmupSeconds;

            // strip off WarmupSeconds
            var results = Results.Where(res => !res.IsWarmupRequest);

            var result = results.FirstOrDefault();
            var min    = StartTime;

            if (result != null)
            {
                min = result.Timestamp;
                min = TimeUtils.Truncate(min, DateTimeResolution.Second);
            }
            var max = min.AddSeconds(seconds + 1).AddMilliseconds(-1);

            Results = results.Where(res => res.Timestamp > min && res.Timestamp < max).ToList();

            if (Results.Count > 0)
            {
                max = Results.Max(res => res.Timestamp);
                TimeTakenForLastRunMs = (int)TimeUtils.Truncate(max).Subtract(min).TotalMilliseconds;
            }
            else
            {
                TimeTakenForLastRunMs = (int)TimeUtils.Truncate(DateTime.UtcNow).Subtract(min).TotalMilliseconds;
            }

            foreach (var plugin in App.Plugins)
            {
                try
                {
                    plugin.OnLoadTestCompleted(Results, TimeTakenForLastRunMs);
                }
                catch (Exception ex)
                {
                    App.Log(plugin.GetType().Name + " failed in OnLoadTestCompleted(): " + ex.Message);
                }
            }

            return(Results);
        }
        /// <summary>
        /// This is the main Session processing routine. This routine creates the
        /// new threads to run each session on. It monitors for shutdown/cancel operation
        /// and then shuts down the worker threads and summarizes the results.
        /// 
        /// The worker method call for each Session request processing is 
        /// SessionThreadRunner().
        /// </summary>
        /// <param name="requests"></param>
        /// <param name="threadCount"></param>
        /// <param name="seconds"></param>
        /// <returns></returns>
        public List<HttpRequestData> CheckAllSites(IEnumerable<HttpRequestData> requests, 
                                                   int threadCount = 2, 
                                                   int seconds = 60,
                                                   bool runOnce = false)
        {
     

            
            ThreadsUsed = threadCount;

            //if (UnlockKey.RegType == RegTypes.Free &&
            //    (threadCount > UnlockKey.FreeThreadLimit ||
            //    requests.Count() > UnlockKey.FreeSitesLimit))
            //{
            //    Running = false;
            //    SetError("The free version is limited to " + UnlockKey.FreeSitesLimit + " urls to check and " + UnlockKey.FreeThreadLimit + " simultaneous threads.\r\n\r\n" +
            //            "Please reduce the URL or thread counts, or consider purchasing the Professional version that includes unlimited sites and threads.");                    
            //    return null;
            //}

            if (!runOnce)
            {
                var validator = new SiteValidator(this);
                if (!validator.CheckAllServers(requests))
                {
                    SetError(validator.ErrorMessage);
                    Running = false;
                    return null;
                }
            }


            Results = new List<HttpRequestData>();
            requests = requests.Where(req => req.IsActive).ToList();


            foreach (var plugin in App.Plugins)
            {
                try
                {
                    if (!plugin.OnLoadTestStarted(requests as List<HttpRequestData>))
                        return null;
                }
                catch (Exception ex)
                {
                    App.Log(plugin.GetType().Name + " failed in OnLoadTestStarted(): " + ex.Message);
                }
            }

            Running = true;
             
            var threads = new List<Thread>();
            CancelThreads = false;
            RequestsProcessed = 0;
            RequestsFailed = 0;

            // add warmup seconds to the request
            seconds += Options.WarmupSeconds;

            StartTime = DateTime.UtcNow;
            for (int i = 0; i < threadCount; i++)
            {
                var thread = new Thread(RunSessions);
                thread.Start(requests);
                threads.Add(thread);
            }            

            var lastProgress = DateTime.UtcNow.AddSeconds(-10);            
            while (!CancelThreads)
            {
                if (DateTime.UtcNow.Subtract(StartTime).TotalSeconds  > seconds + 1)
                {
                    TimeTakenForLastRunMs = (int) DateTime.UtcNow.Subtract(StartTime).TotalMilliseconds;
                    
                    CancelThreads = true;

                    Thread.Sleep(3000);                    
                    foreach (var thread in threads)
                        thread.Abort();
                    Thread.Sleep(1000);

                    break;
                }
                Thread.Sleep(100);

                if (DateTime.UtcNow.Subtract(lastProgress).TotalMilliseconds > 950)
                {
                    lastProgress = DateTime.UtcNow;
                    
                    OnProgress(new ProgressInfo() 
                    {
                         SecondsProcessed = (int) DateTime.UtcNow.Subtract(StartTime).TotalSeconds,
                         TotalSecondsToProcessed = seconds,
                         RequestsProcessed = RequestsProcessed,
                         RequestsFailed = RequestsFailed,                         
                    });
                    
                }
            }

            Running = false;

            seconds = seconds - Options.WarmupSeconds;

            // strip off WarmupSeconds
            var results = Results.Where(res => !res.IsWarmupRequest);

            var result = results.FirstOrDefault();
            var min =  StartTime;
            if (result != null)
            {
                min = result.Timestamp;                
                min = TimeUtils.Truncate(min, DateTimeResolution.Second);
            }
            var max = min.AddSeconds(seconds + 1).AddMilliseconds(-1);

            Results = results.Where(res => res.Timestamp > min && res.Timestamp < max).ToList();

            if (Results.Count > 0)
            {
                max = Results.Max(res => res.Timestamp);
                TimeTakenForLastRunMs = (int) TimeUtils.Truncate(max).Subtract(min).TotalMilliseconds;
            }
            else
                TimeTakenForLastRunMs = (int) TimeUtils.Truncate(DateTime.UtcNow).Subtract(min).TotalMilliseconds;

            foreach (var plugin in App.Plugins)
            {
                try
                {
                    plugin.OnLoadTestCompleted(Results, TimeTakenForLastRunMs);
                }
                catch (Exception ex)
                {
                    App.Log(plugin.GetType().Name + " failed in OnLoadTestCompleted(): " + ex.Message);
                }
            }

            return Results;   
        }
        public void BasicSiteValidatorTest()
        {
            var requestList = new List<HttpRequestData>()
            {
                new HttpRequestData
                {
                    Url = "http://www.microsoft.com/en-us/default.aspx"
                },
                new HttpRequestData
                {
                    Url = "http://localhost/WebLog"
                },
                              new HttpRequestData
                {
                    Url = "http://localhost/WebLog/posts"
                }

            };
            var stress = new StressTester();

            var validator = new SiteValidator(stress);
            bool result= validator.CheckAllServers(requestList);

            Assert.IsFalse(result);
            Console.WriteLine(validator.ErrorMessage);
        }