1use crate::*;
2
3cfg_if! {
4 if #[cfg(all(target_arch = "wasm32", target_os = "unknown"))] {
5 use js_sys::*;
6 } else {
7 use std::time::{Duration, SystemTime};
8 }
9}
10
11pub fn test_log() {
12 info!("testing log");
13}
14
15pub fn test_get_timestamp() {
16 info!("testing get_timestamp");
17 let t1 = get_timestamp();
18 let t2 = get_timestamp();
19 assert!(t2 >= t1);
20}
21
22pub async fn test_eventual() {
23 info!("testing Eventual");
24 {
25 let e1 = Eventual::new();
26 let i1 = e1.instance_clone(1u32);
27 let i2 = e1.instance_clone(2u32);
28 let i3 = e1.instance_clone(3u32);
29 drop(i3);
30 let i4 = e1.instance_clone(4u32);
31 drop(i2);
32
33 let jh = spawn("task", async move {
34 sleep(1000).await;
35 e1.resolve().await;
36 });
37
38 assert_eq!(i1.await, 1u32);
39 assert_eq!(i4.await, 4u32);
40
41 jh.await;
42 }
43 {
44 let e1 = Eventual::new();
45 let i1 = e1.instance_clone(1u32);
46 let i2 = e1.instance_clone(2u32);
47 let i3 = e1.instance_clone(3u32);
48 let i4 = e1.instance_clone(4u32);
49 let e1_c1 = e1.clone();
50 let jh = spawn("task", async move {
51 let i5 = e1.instance_clone(5u32);
52 let i6 = e1.instance_clone(6u32);
53 assert_eq!(i1.await, 1u32);
54 assert_eq!(i5.await, 5u32);
55 assert_eq!(i6.await, 6u32);
56 });
57 sleep(1000).await;
58 let resolved = e1_c1.resolve();
59 drop(i2);
60 drop(i3);
61 assert_eq!(i4.await, 4u32);
62 resolved.await;
63 jh.await;
64 }
65 {
66 let e1 = Eventual::new();
67 let i1 = e1.instance_clone(1u32);
68 let i2 = e1.instance_clone(2u32);
69 let e1_c1 = e1.clone();
70 let jh = spawn("task", async move {
71 assert_eq!(i1.await, 1u32);
72 assert_eq!(i2.await, 2u32);
73 });
74 sleep(1000).await;
75 e1_c1.resolve().await;
76
77 jh.await;
78
79 e1_c1.reset();
80 let j1 = e1.instance_clone(1u32);
82 let j2 = e1.instance_clone(2u32);
83 let jh = spawn("task", async move {
84 assert_eq!(j1.await, 1u32);
85 assert_eq!(j2.await, 2u32);
86 });
87 sleep(1000).await;
88 e1_c1.resolve().await;
89
90 jh.await;
91
92 e1_c1.reset();
93 }
94}
95
96pub async fn test_eventual_value() {
97 info!("testing Eventual Value");
98 {
99 let e1 = EventualValue::<u32>::new();
100 let i1 = e1.instance();
101 let i2 = e1.instance();
102 let i3 = e1.instance();
103 drop(i3);
104 let i4 = e1.instance();
105 drop(i2);
106
107 let e1_c1 = e1.clone();
108 let jh = spawn("task", async move {
109 sleep(1000).await;
110 e1_c1.resolve(3u32);
111 });
112
113 i1.await;
114 i4.await;
115 jh.await;
116 assert_eq!(e1.take_value(), Some(3u32));
117 }
118 {
119 let e1 = EventualValue::new();
120 let i1 = e1.instance();
121 let i2 = e1.instance();
122 let i3 = e1.instance();
123 let i4 = e1.instance();
124 let e1_c1 = e1.clone();
125 let jh = spawn("task", async move {
126 let i5 = e1.instance();
127 let i6 = e1.instance();
128 i1.await;
129 i5.await;
130 i6.await;
131 });
132 sleep(1000).await;
133 let resolved = e1_c1.resolve(4u16);
134 drop(i2);
135 drop(i3);
136 i4.await;
137 resolved.await;
138 jh.await;
139 assert_eq!(e1_c1.take_value(), Some(4u16));
140 }
141 {
142 let e1 = EventualValue::new();
143 assert_eq!(e1.take_value(), None);
144 let i1 = e1.instance();
145 let i2 = e1.instance();
146 let e1_c1 = e1.clone();
147 let jh = spawn("task", async move {
148 i1.await;
149 i2.await;
150 });
151 sleep(1000).await;
152 e1_c1.resolve(5u32).await;
153 jh.await;
154 assert_eq!(e1_c1.take_value(), Some(5u32));
155 e1_c1.reset();
156 assert_eq!(e1_c1.take_value(), None);
157 let j1 = e1.instance();
159 let j2 = e1.instance();
160 let jh = spawn("task", async move {
161 j1.await;
162 j2.await;
163 });
164 sleep(1000).await;
165 e1_c1.resolve(6u32).await;
166 jh.await;
167 assert_eq!(e1_c1.take_value(), Some(6u32));
168 e1_c1.reset();
169 assert_eq!(e1_c1.take_value(), None);
170 }
171}
172
173pub async fn test_eventual_value_clone() {
174 info!("testing Eventual Value Clone");
175 {
176 let e1 = EventualValueClone::<u32>::new();
177 let i1 = e1.instance();
178 let i2 = e1.instance();
179 let i3 = e1.instance();
180 drop(i3);
181 let i4 = e1.instance();
182 drop(i2);
183
184 let jh = spawn("task", async move {
185 sleep(1000).await;
186 e1.resolve(3u32);
187 });
188
189 assert_eq!(i1.await, 3);
190 assert_eq!(i4.await, 3);
191
192 jh.await;
193 }
194
195 {
196 let e1 = EventualValueClone::new();
197 let i1 = e1.instance();
198 let i2 = e1.instance();
199 let i3 = e1.instance();
200 let i4 = e1.instance();
201 let e1_c1 = e1.clone();
202 let jh = spawn("task", async move {
203 let i5 = e1.instance();
204 let i6 = e1.instance();
205 assert_eq!(i1.await, 4);
206 assert_eq!(i5.await, 4);
207 assert_eq!(i6.await, 4);
208 });
209 sleep(1000).await;
210 let resolved = e1_c1.resolve(4u16);
211 drop(i2);
212 drop(i3);
213 assert_eq!(i4.await, 4);
214 resolved.await;
215 jh.await;
216 }
217
218 {
219 let e1 = EventualValueClone::new();
220 let i1 = e1.instance();
221 let i2 = e1.instance();
222 let e1_c1 = e1.clone();
223 let jh = spawn("task", async move {
224 assert_eq!(i1.await, 5);
225 assert_eq!(i2.await, 5);
226 });
227 sleep(1000).await;
228 e1_c1.resolve(5u32).await;
229 jh.await;
230 e1_c1.reset();
231 let j1 = e1.instance();
233 let j2 = e1.instance();
234 let jh = spawn("task", async move {
235 assert_eq!(j1.await, 6);
236 assert_eq!(j2.await, 6);
237 });
238 sleep(1000).await;
239 e1_c1.resolve(6u32).await;
240 jh.await;
241 e1_c1.reset();
242 }
243}
244pub async fn test_interval() {
245 info!("testing interval");
246
247 let tick: Arc<Mutex<u32>> = Arc::new(Mutex::new(0u32));
248 let stopper = interval("interval", 1000, move || {
249 let tick = tick.clone();
250 async move {
251 let mut tick = tick.lock();
252 trace!("tick {}", tick);
253 *tick += 1;
254 }
255 });
256
257 sleep(5500).await;
258
259 stopper.await;
260}
261
262#[allow(clippy::await_holding_lock)]
263pub async fn test_timeout() {
264 info!("testing timeout");
265
266 let tick: Arc<Mutex<u32>> = Arc::new(Mutex::new(0u32));
267 let tick_1 = tick.clone();
268 assert!(
269 timeout(2500, async move {
270 let mut tick = tick_1.lock();
271 trace!("tick {}", tick);
272 sleep(1000).await;
273 *tick += 1;
274 trace!("tick {}", tick);
275 sleep(1000).await;
276 *tick += 1;
277 trace!("tick {}", tick);
278 sleep(1000).await;
279 *tick += 1;
280 trace!("tick {}", tick);
281 sleep(1000).await;
282 *tick += 1;
283 })
284 .await
285 .is_err(),
286 "should have timed out"
287 );
288
289 let ticks = *tick.lock();
290 assert!(ticks <= 2);
291}
292
293pub async fn test_sleep() {
294 info!("testing sleep");
295 cfg_if! {
296 if #[cfg(all(target_arch = "wasm32", target_os = "unknown"))] {
297
298 let t1 = Date::now();
299 sleep(1000).await;
300 let t2 = Date::now();
301 assert!((t2-t1) >= 1000.0);
302
303 } else {
304
305 let sys_time = SystemTime::now();
306 let one_sec = Duration::from_secs(1);
307
308 sleep(1000).await;
309 assert!(sys_time.elapsed().unwrap() >= one_sec);
310 }
311 }
312}
313
314macro_rules! assert_split_url {
315 ($url:expr, $scheme:expr, $host:expr) => {
316 assert_eq!(
317 SplitUrl::from_str($url),
318 Ok(SplitUrl::new($scheme, None, $host, None, None))
319 );
320 };
321 ($url:expr, $scheme:expr, $host:expr, $port:expr) => {
322 assert_eq!(
323 SplitUrl::from_str($url),
324 Ok(SplitUrl::new($scheme, None, $host, $port, None))
325 );
326 };
327 ($url:expr, $scheme:expr, $host:expr, $port:expr, $path:expr) => {
328 assert_eq!(
329 SplitUrl::from_str($url),
330 Ok(SplitUrl::new(
331 $scheme,
332 None,
333 $host,
334 $port,
335 Some(SplitUrlPath::new(
336 $path,
337 Option::<String>::None,
338 Option::<String>::None
339 ))
340 ))
341 );
342 };
343 ($url:expr, $scheme:expr, $host:expr, $port:expr, $path:expr, $frag:expr, $query:expr) => {
344 assert_eq!(
345 SplitUrl::from_str($url),
346 Ok(SplitUrl::new(
347 $scheme,
348 None,
349 $host,
350 $port,
351 Some(SplitUrlPath::new($path, $frag, $query))
352 ))
353 );
354 };
355}
356
357macro_rules! assert_split_url_parse {
358 ($url:expr) => {
359 let url = $url;
360 let su1 = SplitUrl::from_str(url).expect("should parse");
361 assert_eq!(su1.to_string(), url);
362 };
363}
364
365fn host<S: AsRef<str>>(s: S) -> SplitUrlHost {
366 SplitUrlHost::Hostname(s.as_ref().to_owned())
367}
368
369fn ip<S: AsRef<str>>(s: S) -> SplitUrlHost {
370 SplitUrlHost::IpAddr(IpAddr::from_str(s.as_ref()).unwrap())
371}
372
373pub fn test_split_url() {
374 info!("testing split_url");
375
376 assert_split_url!("http://foo", "http", host("foo"));
377 assert_split_url!("http://foo:1234", "http", host("foo"), Some(1234));
378 assert_split_url!("http://foo:1234/", "http", host("foo"), Some(1234), "");
379 assert_split_url!(
380 "http://foo:1234/asdf/qwer",
381 "http",
382 host("foo"),
383 Some(1234),
384 "asdf/qwer"
385 );
386 assert_split_url!("http://foo/", "http", host("foo"), None, "");
387 assert_split_url!("http://11.2.3.144/", "http", ip("11.2.3.144"), None, "");
388 assert_split_url!("http://[1111::2222]/", "http", ip("1111::2222"), None, "");
389 assert_split_url!(
390 "http://[1111::2222]:123/",
391 "http",
392 ip("1111::2222"),
393 Some(123),
394 ""
395 );
396
397 assert_split_url!(
398 "http://foo/asdf/qwer",
399 "http",
400 host("foo"),
401 None,
402 "asdf/qwer"
403 );
404 assert_split_url!(
405 "http://foo/asdf/qwer#3",
406 "http",
407 host("foo"),
408 None,
409 "asdf/qwer",
410 Some("3"),
411 Option::<String>::None
412 );
413 assert_split_url!(
414 "http://foo/asdf/qwer?xxx",
415 "http",
416 host("foo"),
417 None,
418 "asdf/qwer",
419 Option::<String>::None,
420 Some("xxx")
421 );
422 assert_split_url!(
423 "http://foo/asdf/qwer#yyy?xxx",
424 "http",
425 host("foo"),
426 None,
427 "asdf/qwer",
428 Some("yyy"),
429 Some("xxx")
430 );
431 assert_err!(SplitUrl::from_str("://asdf"));
432 assert_err!(SplitUrl::from_str(""));
433 assert_err!(SplitUrl::from_str("::"));
434 assert_err!(SplitUrl::from_str("://:"));
435 assert_err!(SplitUrl::from_str("a://:"));
436 assert_err!(SplitUrl::from_str("a://:1243"));
437 assert_err!(SplitUrl::from_str("a://:65536"));
438 assert_err!(SplitUrl::from_str("a://:-16"));
439 assert_err!(SplitUrl::from_str("a:///"));
440 assert_err!(SplitUrl::from_str("a:///qwer:"));
441 assert_err!(SplitUrl::from_str("a:///qwer://"));
442 assert_err!(SplitUrl::from_str("a://qwer://"));
443 assert_err!(SplitUrl::from_str("a://[1111::2222]:/"));
444 assert_err!(SplitUrl::from_str("a://[1111::2222]:"));
445
446 assert_split_url_parse!("sch://foo:bar@baz.com:1234/fnord#qux?zuz");
447 assert_split_url_parse!("sch://foo:bar@baz.com:1234/fnord#qux");
448 assert_split_url_parse!("sch://foo:bar@baz.com:1234/fnord?zuz");
449 assert_split_url_parse!("sch://foo:bar@baz.com:1234/fnord/");
450 assert_split_url_parse!("sch://foo:bar@baz.com:1234//");
451 assert_split_url_parse!("sch://foo:bar@baz.com:1234");
452 assert_split_url_parse!("sch://foo:bar@[1111::2222]:1234");
453 assert_split_url_parse!("sch://foo:bar@[::]:1234");
454 assert_split_url_parse!("sch://foo:bar@1.2.3.4:1234");
455 assert_split_url_parse!("sch://@baz.com:1234");
456 assert_split_url_parse!("sch://baz.com/asdf/asdf");
457 assert_split_url_parse!("sch://baz.com/");
458 assert_split_url_parse!("s://s");
459}
460
461pub fn test_get_random_u64() {
462 info!("testing random number generator for u64");
463 let t1 = get_timestamp();
464 let count = 10000;
465 for _ in 0..count {
466 let _ = get_random_u64();
467 }
468 let t2 = get_timestamp();
469 let tdiff = ((t2 - t1) as f64) / 1000000.0f64;
470 info!(
471 "running get_random_u64 with {} iterations took {} seconds",
472 count, tdiff
473 );
474}
475
476pub fn test_get_random_u32() {
477 info!("testing random number generator for u32");
478 let t1 = get_timestamp();
479 let count = 10000;
480 for _ in 0..count {
481 let _ = get_random_u32();
482 }
483 let t2 = get_timestamp();
484 let tdiff = ((t2 - t1) as f64) / 1000000.0f64;
485 info!(
486 "running get_random_u32 with {} iterations took {} seconds",
487 count, tdiff
488 );
489}
490
491pub async fn test_must_join_single_future() {
492 info!("testing must join single future");
493 let sf = MustJoinSingleFuture::<u32>::new();
494 assert_eq!(sf.check().await, Ok(None));
495 assert_eq!(
496 sf.single_spawn("t1", async {
497 sleep(2000).await;
498 69
499 })
500 .await,
501 Ok((None, true))
502 );
503 assert_eq!(sf.check().await, Ok(None));
504 assert_eq!(
505 sf.single_spawn("t2", async { panic!() }).await,
506 Ok((None, false))
507 );
508 assert_eq!(sf.join().await, Ok(Some(69)));
509 assert_eq!(
510 sf.single_spawn("t3", async {
511 sleep(1000).await;
512 37
513 })
514 .await,
515 Ok((None, true))
516 );
517 sleep(2000).await;
518 assert_eq!(
519 sf.single_spawn("t4", async {
520 sleep(1000).await;
521 27
522 })
523 .await,
524 Ok((Some(37), true))
525 );
526 sleep(2000).await;
527 assert_eq!(sf.join().await, Ok(Some(27)));
528 assert_eq!(sf.check().await, Ok(None));
529}
530
531pub fn test_tools() {
532 info!("testing retry_falloff_log");
533 let mut last_us = 0u64;
534 for x in 0..1024 {
535 let cur_us = x as u64 * 1000000u64;
536 if retry_falloff_log(last_us, cur_us, 10_000_000u64, 6_000_000_000u64, 2.0f64) {
537 info!(" retry at {} secs", timestamp_to_secs(cur_us));
538 last_us = cur_us;
539 }
540 }
541}
542
543pub async fn test_all() {
544 test_log();
545 test_get_timestamp();
546 test_tools();
547 test_split_url();
548 test_get_random_u64();
549 test_get_random_u32();
550 test_sleep().await;
551 #[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))]
552 test_must_join_single_future().await;
553 test_eventual().await;
554 test_eventual_value().await;
555 test_eventual_value_clone().await;
556 test_interval().await;
557 test_timeout().await;
558}