I'm trying to implement a test that compares the output of 2 algorithms for at least 10 seconds of running.
I'm just starting rust, so maybe is there something I didn't got with the timeout function.
How to get the output when timeout is finished and pass it inside my loop to break it ?
Thanks for your help,
#[cfg(test)]
mod tests {
use super::*;
use rand::Rng;
use std::time::Duration;
use tokio::sync::oneshot;
use tokio::time::timeout;
#[tokio::test]
async fn stress_test() {
timeout(Duration::from_secs(10), async move {
loop {
let n: i32 = rand::thread_rng().gen_range(2..100);
println!("Vector size : {} \n", n);
let mut vec1: Vec<i32> = vec![];
for _i in 0..n {
vec1.push(rand::thread_rng().gen_range(0..10000000));
}
println!("{:?} \n", vec1);
let res1: i128 = pairwise_product_by_loop(&vec1);
let res2: i128 = pairwise_product_by_max(&vec1);
if res1 != res2 {
panic!("Wrong answer : {} vs {}\n", res1, res2);
} else {
println!("OK");
}
// How do I stop the loop when we reach the end of the timeout ? Here I should put the break
}
})
.await
.unwrap();
}
}```
Your async block doesn't contain any await points, so it's useless. You never give the runtime a chance to re-acquire control – your code is 100% synchronous and blocking, forever. You have to insert some asynchrony somewhere (e.g. after each invocation of either algorithm to be tested) in order for the timeout to fire at all. However, unless your two functions are themselves async, this doesn't guarantee that they will run for at most 10 seconds.
When I said I want the two functions run for a least 10 seconds, I meant I'm executing them multiple times (probably millions) for 10 seconds(the reason why I use a loop inside a timeout), so the stress test can be valid if no error encountered in this time.
So I don't get where I can put an await inside the loop. I tried next to the the println!("OK").await but I got the error message ``() is not a future. I don't get cause if you look at the timeout method, it accepts only a Future as a second parameter.
You can't await random things – println() is not async. You have to await something that is async. For example, you can tokio::time::sleep() for a short (possibly zero) duration.
It means that it accepts the (pending) "result" of an async operation. No magic there.
What do you mean by "had to"? What happens if you simply add the sleep().await; call? Please provide more context – it's not clear what else you are trying to do.
panicked at 'called `Result::unwrap()` on an `Err` value: Elapsed(())'
I will try to explain with my words what I understood :
Timeout needs a future, so a pending "result" to start. As my function was synchronous and an infinite loop, I returned no pending..
By using sleep, my function could return a future, which is Sleep. So the timeout could start and return something.
Concerning unwrap :
timeout return an Error if the future not completes before the duration has elapsed, otherwise it will returns the value of the function (the future). As the function (future) couldn't complete before the duration was finished, timeout returns an Elapsed error and so unwrap throws it.
I can do something simply like this :
Don't hesitate to correct me if I'm wrong in my thinking. I really would like to understand.
#[tokio::test]
async fn stress_test() {
let _timer = timeout(Duration::from_secs(10), async move {
loop {
let n: i32 = rand::thread_rng().gen_range(2..100);
println!("Vector size : {} \n", n);
let mut vec1: Vec<i32> = vec![];
for _i in 0..n {
vec1.push(rand::thread_rng().gen_range(0..100));
}
println!("{:?} \n", vec1);
let res1: i128 = pairwise_product_by_loop(&vec1);
let res2: i128 = pairwise_product_by_max(&vec1);
if res1 != res2 {
panic!("Wrong answer : {} vs {}\n", res1, res2);
} else {
sleep(Duration::from_millis(0)).await;
println!("OK");
}
}
})
.await;
}