1 extern crate futures;
2 extern crate tokio;
3 extern crate tokio_timer;
4 extern crate tokio_retry;
5 
6 use std::sync::Arc;
7 use std::sync::atomic::{AtomicUsize, Ordering};
8 
9 use futures::Future;
10 use futures::sync::oneshot::spawn;
11 use tokio::runtime::Runtime;
12 use tokio_retry::{Error, Retry, RetryIf};
13 
14 #[test]
attempts_just_once()15 fn attempts_just_once() {
16     use std::iter::empty;
17     let runtime = Runtime::new().unwrap();
18     let counter = Arc::new(AtomicUsize::new(0));
19     let cloned_counter = counter.clone();
20     let future = Retry::spawn(empty(), move || {
21         cloned_counter.fetch_add(1, Ordering::SeqCst);
22         Err::<(), u64>(42)
23     });
24     let res = spawn(future, &runtime.executor()).wait();
25 
26     assert_eq!(res, Err(Error::OperationError(42)));
27     assert_eq!(counter.load(Ordering::SeqCst), 1);
28 }
29 
30 #[test]
attempts_until_max_retries_exceeded()31 fn attempts_until_max_retries_exceeded() {
32     use tokio_retry::strategy::FixedInterval;
33     let s = FixedInterval::from_millis(100).take(2);
34     let runtime = Runtime::new().unwrap();
35     let counter = Arc::new(AtomicUsize::new(0));
36     let cloned_counter = counter.clone();
37     let future = Retry::spawn(s, move || {
38         cloned_counter.fetch_add(1, Ordering::SeqCst);
39         Err::<(), u64>(42)
40     });
41     let res = spawn(future, &runtime.executor()).wait();
42 
43     assert_eq!(res, Err(Error::OperationError(42)));
44     assert_eq!(counter.load(Ordering::SeqCst), 3);
45 }
46 
47 #[test]
attempts_until_success()48 fn attempts_until_success() {
49     use tokio_retry::strategy::FixedInterval;
50     let s = FixedInterval::from_millis(100);
51     let runtime = Runtime::new().unwrap();
52     let counter = Arc::new(AtomicUsize::new(0));
53     let cloned_counter = counter.clone();
54     let future = Retry::spawn(s, move || {
55         let previous = cloned_counter.fetch_add(1, Ordering::SeqCst);
56         if previous < 3 {
57             Err::<(), u64>(42)
58         } else {
59             Ok::<(), u64>(())
60         }
61     });
62     let res = spawn(future, &runtime.executor()).wait();
63 
64     assert_eq!(res, Ok(()));
65     assert_eq!(counter.load(Ordering::SeqCst), 4);
66 }
67 
68 #[test]
attempts_retry_only_if_given_condition_is_true()69 fn attempts_retry_only_if_given_condition_is_true() {
70     use tokio_retry::strategy::FixedInterval;
71     let s = FixedInterval::from_millis(100).take(5);
72     let runtime = Runtime::new().unwrap();
73     let counter = Arc::new(AtomicUsize::new(0));
74     let cloned_counter = counter.clone();
75     let future = RetryIf::spawn(s, move || {
76         let previous  = cloned_counter.fetch_add(1, Ordering::SeqCst);
77         Err::<(), usize>(previous + 1)
78     }, |e: &usize| *e < 3);
79     let res = spawn(future, &runtime.executor()).wait();
80 
81     assert_eq!(res, Err(Error::OperationError(3)));
82     assert_eq!(counter.load(Ordering::SeqCst), 3);
83 }
84