forked from mirrors/gecko-dev
		
	
		
			
				
	
	
		
			150 lines
		
	
	
	
		
			3.8 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			150 lines
		
	
	
	
		
			3.8 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
| #![cfg(feature = "sync")]
 | |
| 
 | |
| #[cfg(tokio_wasm_not_wasi)]
 | |
| use wasm_bindgen_test::wasm_bindgen_test as test;
 | |
| 
 | |
| use std::sync::Arc;
 | |
| use tokio::sync::Semaphore;
 | |
| 
 | |
| #[test]
 | |
| fn no_permits() {
 | |
|     // this should not panic
 | |
|     Semaphore::new(0);
 | |
| }
 | |
| 
 | |
| #[test]
 | |
| fn try_acquire() {
 | |
|     let sem = Semaphore::new(1);
 | |
|     {
 | |
|         let p1 = sem.try_acquire();
 | |
|         assert!(p1.is_ok());
 | |
|         let p2 = sem.try_acquire();
 | |
|         assert!(p2.is_err());
 | |
|     }
 | |
|     let p3 = sem.try_acquire();
 | |
|     assert!(p3.is_ok());
 | |
| }
 | |
| 
 | |
| #[tokio::test]
 | |
| #[cfg(feature = "full")]
 | |
| async fn acquire() {
 | |
|     let sem = Arc::new(Semaphore::new(1));
 | |
|     let p1 = sem.try_acquire().unwrap();
 | |
|     let sem_clone = sem.clone();
 | |
|     let j = tokio::spawn(async move {
 | |
|         let _p2 = sem_clone.acquire().await;
 | |
|     });
 | |
|     drop(p1);
 | |
|     j.await.unwrap();
 | |
| }
 | |
| 
 | |
| #[tokio::test]
 | |
| #[cfg(feature = "full")]
 | |
| async fn add_permits() {
 | |
|     let sem = Arc::new(Semaphore::new(0));
 | |
|     let sem_clone = sem.clone();
 | |
|     let j = tokio::spawn(async move {
 | |
|         let _p2 = sem_clone.acquire().await;
 | |
|     });
 | |
|     sem.add_permits(1);
 | |
|     j.await.unwrap();
 | |
| }
 | |
| 
 | |
| #[test]
 | |
| fn forget() {
 | |
|     let sem = Arc::new(Semaphore::new(1));
 | |
|     {
 | |
|         let p = sem.try_acquire().unwrap();
 | |
|         assert_eq!(sem.available_permits(), 0);
 | |
|         p.forget();
 | |
|         assert_eq!(sem.available_permits(), 0);
 | |
|     }
 | |
|     assert_eq!(sem.available_permits(), 0);
 | |
|     assert!(sem.try_acquire().is_err());
 | |
| }
 | |
| 
 | |
| #[test]
 | |
| fn merge() {
 | |
|     let sem = Arc::new(Semaphore::new(3));
 | |
|     {
 | |
|         let mut p1 = sem.try_acquire().unwrap();
 | |
|         assert_eq!(sem.available_permits(), 2);
 | |
|         let p2 = sem.try_acquire_many(2).unwrap();
 | |
|         assert_eq!(sem.available_permits(), 0);
 | |
|         p1.merge(p2);
 | |
|         assert_eq!(sem.available_permits(), 0);
 | |
|     }
 | |
|     assert_eq!(sem.available_permits(), 3);
 | |
| }
 | |
| 
 | |
| #[test]
 | |
| #[cfg(not(tokio_wasm))] // No stack unwinding on wasm targets
 | |
| #[should_panic]
 | |
| fn merge_unrelated_permits() {
 | |
|     let sem1 = Arc::new(Semaphore::new(3));
 | |
|     let sem2 = Arc::new(Semaphore::new(3));
 | |
|     let mut p1 = sem1.try_acquire().unwrap();
 | |
|     let p2 = sem2.try_acquire().unwrap();
 | |
|     p1.merge(p2);
 | |
| }
 | |
| 
 | |
| #[tokio::test]
 | |
| #[cfg(feature = "full")]
 | |
| async fn stress_test() {
 | |
|     let sem = Arc::new(Semaphore::new(5));
 | |
|     let mut join_handles = Vec::new();
 | |
|     for _ in 0..1000 {
 | |
|         let sem_clone = sem.clone();
 | |
|         join_handles.push(tokio::spawn(async move {
 | |
|             let _p = sem_clone.acquire().await;
 | |
|         }));
 | |
|     }
 | |
|     for j in join_handles {
 | |
|         j.await.unwrap();
 | |
|     }
 | |
|     // there should be exactly 5 semaphores available now
 | |
|     let _p1 = sem.try_acquire().unwrap();
 | |
|     let _p2 = sem.try_acquire().unwrap();
 | |
|     let _p3 = sem.try_acquire().unwrap();
 | |
|     let _p4 = sem.try_acquire().unwrap();
 | |
|     let _p5 = sem.try_acquire().unwrap();
 | |
|     assert!(sem.try_acquire().is_err());
 | |
| }
 | |
| 
 | |
| #[test]
 | |
| fn add_max_amount_permits() {
 | |
|     let s = tokio::sync::Semaphore::new(0);
 | |
|     s.add_permits(tokio::sync::Semaphore::MAX_PERMITS);
 | |
|     assert_eq!(s.available_permits(), tokio::sync::Semaphore::MAX_PERMITS);
 | |
| }
 | |
| 
 | |
| #[cfg(not(tokio_wasm))] // wasm currently doesn't support unwinding
 | |
| #[test]
 | |
| #[should_panic]
 | |
| fn add_more_than_max_amount_permits1() {
 | |
|     let s = tokio::sync::Semaphore::new(1);
 | |
|     s.add_permits(tokio::sync::Semaphore::MAX_PERMITS);
 | |
| }
 | |
| 
 | |
| #[cfg(not(tokio_wasm))] // wasm currently doesn't support unwinding
 | |
| #[test]
 | |
| #[should_panic]
 | |
| fn add_more_than_max_amount_permits2() {
 | |
|     let s = Semaphore::new(Semaphore::MAX_PERMITS - 1);
 | |
|     s.add_permits(1);
 | |
|     s.add_permits(1);
 | |
| }
 | |
| 
 | |
| #[cfg(not(tokio_wasm))] // wasm currently doesn't support unwinding
 | |
| #[test]
 | |
| #[should_panic]
 | |
| fn panic_when_exceeds_maxpermits() {
 | |
|     let _ = Semaphore::new(Semaphore::MAX_PERMITS + 1);
 | |
| }
 | |
| 
 | |
| #[test]
 | |
| fn no_panic_at_maxpermits() {
 | |
|     let _ = Semaphore::new(Semaphore::MAX_PERMITS);
 | |
|     let s = Semaphore::new(Semaphore::MAX_PERMITS - 1);
 | |
|     s.add_permits(1);
 | |
| }
 | 
