How do I assert that an async task should complete within a minimum and maximum time? - c#

I can assert that a task should complete within a specified maximum time like this:
await obj.Awaiting( o => o.DoSomethingAsync() ).Should().CompleteWithinAsync( 1.Second() );
But how can I also require that the task also takes at least a certain amount of time to complete? For example, I want to assert that the task should take between 1 and 2 seconds to complete, such that taking less than 1 second or more than 2 seconds indicates failure?
I'm aware of NotCompleteWithinAsync, but I can't work out how to combine both CompleteWithinAsync and NotCompleteWithinAsync in one assertion.

You could use the ExecutionTime extension method and combine it with BeCloseTo. Something like
Awaiting(() => DoSomethingAsync()).ExecutionTime().Should().BeCloseTo(1.Minutes(), 5.Seconds());

Related

How to cause a delay with ReactiveUI.Validation in a ValidationRule

I am doing the following:
this.ValidationRule(vm => vm.UserEntry, this.WhenAnyValue(vm => vm.UserEntry, IsEntryValidOrEmpty).Delay(TimeSpan.FromSeconds(5)), "Invalid entry.")
Expecting this
but the Delay() acts almost like a Throttle() - causing each change in validation status (true/false) to be delayed 5 seconds.
I would expect that the observable sequence would only be shifted once at the start by 5 seconds as this is how Delay() is supposed to work as I understand it.
but getting this
What I'd really like to do in the end is actually to introduce a 5 second delay between the first and second element of the sequence, not before the the first, but that's the next step.
this is what I really want
I have tried various variations on the the theme, but they all behave as if the sequence is restarted between each change in validation status. There's definitely something I'm not getting here.

Increase in time taken to run LINQ query .asparallel when creating new separate tasks in C#

In a LINQ Query, I have used .AsParallel as follows:
var completeReservationItems = from rBase in reservation.AsParallel()
join rRel in relationship.AsParallel() on rBase.GroupCode equals rRel.SourceGroupCode
join rTarget in reservation.AsParallel() on rRel.TargetCode equals rTarget.GroupCode
where rRel.ProgramCode == programCode && rBase.StartDate <= rTarget.StartDate && rBase.EndDate >= rTarget.EndDate
select new Object
{
//Initialize based on the query
};
Then, I have created two separate Tasks and was running them in parallel, passing the same Lists to both the methods as follows:
Task getS1Status = Task.Factory.StartNew(
() =>
{
RunLinqQuery(params);
});
Task getS2Status = Task.Factory.StartNew(
() =>
{
RunLinqQuery(params);
});
Task.WaitAll(getS1Status, getS2Status);
I was capturing the timings and was surprised to see that the timings were as follows:
Above scenario: 6 sec (6000 ms)
Same code, running sequentially instead of 2 Tasks: 50 ms
Same code, but without .AsParallel() in the LINQ: 50 ms
I wanted to understand why this is taking so long in the above scenario.
Posting this as answer only because I have some code to show.
Firstly, I dont know how many threads will be created with AsParallel(). Documentation dont say anything about it https://msdn.microsoft.com/en-us/library/dd413237(v=vs.110).aspx
Imagine following code
void RunMe()
{
foreach (var threadId in Enumerable.Range(0, 100)
.AsParallel()
.Select(x => Thread.CurrentThread.ManagedThreadId)
.Distinct())
Console.WriteLine(threadId);
}
How much thread's ids we will see? For me each time will see different number of threads, example output:
30 // only one thread!
Next time
27 // several threads
13
38
10
43
30
I think, number of threads depends of current scheduler. We can always define maximum number of threads by calling WithDegreeOfParallelism (https://msdn.microsoft.com/en-us/library/dd383719(v=vs.110).aspx) method, example
void RunMe()
{
foreach (var threadId in Enumerable.Range(0, 100)
.AsParallel()
.WithDegreeOfParallelism(2)
.Select(x => Thread.CurrentThread.ManagedThreadId)
.Distinct())
Console.WriteLine(threadId);
}
Now, output will contains maximum 2 threads.
7
40
Why this important? As I said, number of threads can directly influence on performance.
But, this is not all problems. In your 1 scenario, you are creating new tasks (which will perform inside thread pool and can add additional overhead), and then, you are calling Task.WaitAll. Take a look on source code for it https://referencesource.microsoft.com/#mscorlib/system/threading/Tasks/Task.cs,72b6b3fa5eb35695 , Im sure that those for loop by task will add additional overhead, and, in situation when AsParallel will take too much threads inside first task, next task can start continiously. Moreover, this CAN be happen, so, if you will run your 1 scenario 1000 times, probably, you will get very different results.
So, my last argument that you try to measure parallel code, but it is very hard to do it right. Im not recommend to use parallel stuff as much as you can, because it can raise performance degradation, if you dont know exactly, what are you doing.

Best fit formula to estimate the task execution duration

I am trying to figure out a best estimation calculation for my newly creating tasks running parallel on the same time..
As a first step of my calculation my formula will be Duration(D) = Count(c)/networkthroughput(T). So for the given starting time I can find the duration for 1 task easily and for the next task with the same time, Am doing some calculation myself and I am expecting some idea or relevant formula for the same for the attached image.
And here i need to calculate the duration for each task separately..Idea's / Solutions are welcomed.
Thank you.
Why don't you create a function that you pass in your function to time as an argument, then wrap the function call in a couple of date variables?
//Assuming functionToTime is marked async Task
public async Task<TimeSpan>(Action functionToTime){
DateTime startTime = DateTime.Now;
await functionToTime;
return (DateTime.Now - startTime);
}
If functionToTime in not async, you would want to call the function by:
await Task.Run(() => functionToTime);
You can change it to meet your needs, but I think this should be a good starting point.

C# delay in Parallel.ForEach

I use 2 Parallel.ForEach nested loops to retrieve information quickly from a url. This is the code:
while (searches.Count > 0)
{
Parallel.ForEach(searches, (search, loopState) =>
{
Parallel.ForEach(search.items, item =>
{
RetrieveInfo(item);
}
);
}
);
}
The outer ForEach has a list of, for example 10, whilst the inner ForEach has a list of 5. This means that I'm going to query the url 50 times, however I query it 5 times simultaneously (inner ForEach).
I need to add a delay for the inner loop so that after it queries the url, it waits for x seconds - the time taken for the inner loop to complete the 5 requests.
Using Thread.Sleep is not a good idea because it will block the complete thread and possibly the other parallel tasks.
Is there an alternative that might work?
To my understanding, you have 50 tasks and you wish to process 5 of them at a time.
If so, you should look into ParallelOptions.MaxDegreeOfParallelism to process 50 tasks with a maximum degree of parallelism at 5. When one task stops, another task is permitted to start.
If you wish to have tasks processed in chunks of five, followed by another chunk of five (as in, you wish to process chunks in serial), then you would want code similar to
for(...)
{
Parallel.ForEach(
[paralleloptions,]
set of 5, action
)
}

What's the alternative to use Thread.Sleep when working with Selenium in system testing?

I have a TestMethod using Selenium as below:
[TestMethod]
public void ShouldSendPasswordReminder()
{
// go to loginregister url
_fireFoxWebDriver.Navigate().GoToUrl(UkPaBaseUrl + "loginregister.aspx");
Thread.Sleep(1000);
// click the forgotten password
_fireFoxWebDriver.FindElement(By.LinkText("Forgotten your password?")).Click();
Thread.Sleep(1000);
// enter your email address
_fireFoxWebDriver.FindElement(By.Id("PasswordResetRequest1_PasswordResetRequest_Username"))
.SendKeys("username.lastname#domain.com");
Thread.Sleep(1000);
// click submit
_fireFoxWebDriver.FindElement(By.Id("PasswordResetRequest1_PasswordResetRequest_PasswordResetRequestSubmit")).Click();
Thread.Sleep(5000);
// assert
Assert.IsTrue(_fireFoxWebDriver.Url.Contains("ThankYou"));
}
As you can see, I'd have to call Thread.Sleep many times (because the page might take some time to finish what it does due to javascript, etc) almost after each action because Selenium doesn't seem to be able to handle page loads and delays unlike WatiN.
This makes the code rather ugly and not very much reliable.
What's the better way to handle such scenarios? Do you write frequent Thread.Sleep calls in your tests as well?
Thanks,
You could use the manage functionality to set the base line time you want FindElement() to wait for before failing:
_fireFoxWebDriver.Manage()
.Timeouts()
.ImplicitlyWait(TimeSpan.FromSeconds(1000));
Explicit wait.
According to official documentation (http://www.seleniumhq.org/docs/0...), Thread.sleep() is the worst case of explicit wait.
In explicit wait, without waiting for the maximum time to get over, it proceeds as soon as the condition occurs, if that condition occurs before the specified maximum time gets over. Hence having to wait till the maximum time (because the condition did not occur during the specified maximum time) is the worst case of explicit wait.
I think Thread.sleep() is considered as the worst case of explicit wait because, for Thread.sleep(), it has to wait for the full time specified as the argument of Thread.sleep(), before proceeding further.
You may think why Thread.sleep() isn't implicit wait. I think that is because effect of Thread.sleep() is only at the place where it is written, like explicit wait. Effect of implicit wait however, is for the entire lifetime of the driver instance.
**JAVA**
WebDriver driver = new FirefoxDriver();
driver.get("http://somedomain/url_that_delays_loading");
WebElement myDynamicElement = (new WebDriverWait(driver, 10)).until(ExpectedConditions.presenceOfElementLocated(By.id("myDynamicElement")));
**C#**
using (IWebDriver driver = new FirefoxDriver())
{
driver.Url = "http://somedomain/url_that_delays_loading";
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
IWebElement myDynamicElement = wait.Until<IWebElement>(d => d.FindElement(By.Id("someDynamicElement")));
}
This waits up to 10 seconds before throwing a TimeoutException or if it finds the element will return it in 0 - 10 seconds.
My sample code, my test case wanted me to wait for a maximum of 10 seconds, earlier I was waiting for 10 seconds before finding my next element using Thread.Sleep. Now I use the the WebDriverWait so if the element is found it proceeds, this speeds up my day to day activities and also saves time.
using (IWebDriver driver = new ChromeDriver(options))
{
TimeSpan t = TimeSpan.FromSeconds(10);
WebDriverWait wait = new WebDriverWait(driver,t);
try
{
driver.Navigate().GoToUrl("URL");
//IWebElement username = driver.FindElement(By.Name("loginfmt"));
IWebElement username = wait.Until(ExpectedConditions.ElementIsVisible(By.Name("loginfmt")));
username.SendKeys(dictionaryItem);
//Thread.Sleep(10000); Removed my Thread.Sleep and tested my wait.Until and vola it works awesome.
IWebElement next = wait.Until(ExpectedConditions.ElementIsVisible(By.Id("idSIButton9")));
//IWebElement nextdriver.FindElement(By.Id("idSIButton9"));
next.Click();
My general heuristic on introducing delays when my script gets faster than my app is to really think about what I'm waiting for. In my opinion, sleep type calls are really only appropriate in cases where I'm actually waiting for time to elapse. A case where I was testing an automatic timeout might make sense to have a Thread.sleep type call in it, because I'm actually waiting for a specific amount of time to elapse. Usually, however, I'm waiting for other things to occur - pages to load, javascript to execute, etc. In these cases, waiting for a set period of time is an easy way to seem to get past the potentially greater complexity of checking for what I'm actually waiting for. This has multiple pitfalls though - you may be slowing down your tests too much (what if each of your waits above only needed to be 200ms, for example - now even the brief snippet above takes an extra 2.5 seconds (and that's without adjusting the 5 second wait at the end). That may not seem like much by itself but it adds up as your suite gets bigger.) Another pitfall happens when you move to a slower machine or environmental things slow down your app - what if it took 1.5 seconds before you could click the Forgotten your password? link on one machine. Your test would fail, but that may still be within acceptable performance thresholds for your app, so you now have a false failure. This is often dealt with by simply increasing the wait time, but that leads back to the first pitfall I mentioned again.
To break out of this cycle, I find it's very important to be as specific as possible when I'm waiting for things. Selenium provides a Wait class that can be used to wait until a particular condition is met. I don't know if the .Net bindings include it, but i would go into using them expecting it. In the Ruby version, we give Wait a block of code - it can look for the presence of an element or whatever else we need to check. The wait method takes a timeout value and an interval value, and then runs the block every interval seconds until either the block returns true or the timeout period has elapsed. Setting up a class like this allows you to set your timeout values high enough to handle the low end of the performance scale but not to incur the penalty of waiting a lot longer than you really need to in a given run.

Categories