123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230 |
- use generational_box::{GenerationalBox, Storage, SyncStorage, UnsyncStorage};
- /// # Example
- ///
- /// ```compile_fail
- /// let data = String::from("hello world");
- /// let owner = UnsyncStorage::owner();
- /// let key = owner.insert(&data);
- /// drop(data);
- /// assert_eq!(*key.read(), "hello world");
- /// ```
- #[allow(unused)]
- fn compile_fail() {}
- #[test]
- fn leaking_is_ok() {
- fn leaking_is_ok_test<S: Storage<String>>() {
- let data = String::from("hello world");
- let key;
- {
- // create an owner
- let owner = S::owner();
- // insert data into the store
- key = owner.insert(data);
- // don't drop the owner
- std::mem::forget(owner);
- }
- assert_eq!(
- key.try_read().as_deref().unwrap(),
- &"hello world".to_string()
- );
- }
- leaking_is_ok_test::<UnsyncStorage>();
- leaking_is_ok_test::<SyncStorage>();
- }
- #[test]
- fn drops() {
- fn drops_test<S: Storage<String>>() {
- let data = String::from("hello world");
- let key;
- {
- // create an owner
- let owner = S::owner();
- // insert data into the store
- key = owner.insert(data);
- // drop the owner
- }
- assert!(key.try_read().is_err());
- }
- drops_test::<UnsyncStorage>();
- drops_test::<SyncStorage>();
- }
- #[test]
- fn works() {
- fn works_test<S: Storage<i32>>() {
- let owner = S::owner();
- let key = owner.insert(1);
- assert_eq!(*key.read(), 1);
- }
- works_test::<UnsyncStorage>();
- works_test::<SyncStorage>();
- }
- #[test]
- fn insert_while_reading() {
- fn insert_while_reading_test<S: Storage<String> + Storage<&'static i32>>() {
- let owner = S::owner();
- let key;
- {
- let data: String = "hello world".to_string();
- key = owner.insert(data);
- }
- let value = key.read();
- owner.insert(&1);
- assert_eq!(*value, "hello world");
- }
- insert_while_reading_test::<UnsyncStorage>();
- insert_while_reading_test::<SyncStorage>();
- }
- #[test]
- #[should_panic]
- fn panics() {
- fn panics_test<S: Storage<i32>>() {
- let owner = S::owner();
- let key = owner.insert(1);
- drop(owner);
- assert_eq!(*key.read(), 1);
- }
- panics_test::<UnsyncStorage>();
- panics_test::<SyncStorage>();
- }
- #[test]
- fn fuzz() {
- fn maybe_owner_scope<S: Storage<String>>(
- valid_keys: &mut Vec<GenerationalBox<String, S>>,
- invalid_keys: &mut Vec<GenerationalBox<String, S>>,
- path: &mut Vec<u8>,
- ) {
- let branch_cutoff = 5;
- let children = if path.len() < branch_cutoff {
- rand::random::<u8>() % 4
- } else {
- rand::random::<u8>() % 2
- };
- for i in 0..children {
- let owner = S::owner();
- let value = format!("hello world {path:?}");
- let key = owner.insert(value.clone());
- println!("created new box {key:?}");
- valid_keys.push(key);
- path.push(i);
- // read all keys
- println!("{:?}", path);
- for key in valid_keys.iter() {
- println!("reading {key:?}");
- let value = key.read();
- println!("{:?}", &*value);
- assert!(value.starts_with("hello world"));
- }
- for key in invalid_keys.iter() {
- println!("reading invalid {key:?}");
- assert!(key.try_read().is_err());
- }
- maybe_owner_scope(valid_keys, invalid_keys, path);
- // After all the children run, we should still have our data
- let key_value = &*key.read();
- println!("{:?}", key_value);
- assert_eq!(key_value, &value);
- let invalid = valid_keys.pop().unwrap();
- println!("popping {invalid:?}");
- invalid_keys.push(invalid);
- path.pop();
- }
- }
- for _ in 0..10 {
- maybe_owner_scope::<UnsyncStorage>(&mut Vec::new(), &mut Vec::new(), &mut Vec::new());
- }
- for _ in 0..10 {
- maybe_owner_scope::<SyncStorage>(&mut Vec::new(), &mut Vec::new(), &mut Vec::new());
- }
- }
- #[test]
- fn fuzz_rc() {
- fn maybe_owner_scope<S: Storage<String>>(
- valid_keys: &mut Vec<Vec<GenerationalBox<String, S>>>,
- invalid_keys: &mut Vec<GenerationalBox<String, S>>,
- path: &mut Vec<u8>,
- ) {
- let branch_cutoff = 5;
- let children = if path.len() < branch_cutoff {
- rand::random::<u8>() % 4
- } else {
- rand::random::<u8>() % 2
- };
- for i in 0..children {
- let owner = S::owner();
- let value = format!("hello world {path:?}");
- let key = owner.insert_rc(value.clone());
- println!("created new box {key:?}");
- let mut keys = vec![key];
- for _ in 0..rand::random::<u8>() % 10 {
- if rand::random::<u8>() % 2 == 0 {
- let owner = S::owner();
- let key = owner.insert_reference(key).unwrap();
- println!("created new reference {key:?}");
- invalid_keys.push(key);
- }
- let key = owner.insert_reference(key).unwrap();
- println!("created new reference {key:?}");
- keys.push(key);
- }
- valid_keys.push(keys.clone());
- path.push(i);
- // read all keys
- println!("{:?}", path);
- for keys in valid_keys.iter() {
- for key in keys {
- println!("reading {key:?}");
- let value = key.read();
- println!("{:?}", &*value);
- assert!(value.starts_with("hello world"));
- }
- }
- for key in invalid_keys.iter() {
- println!("reading invalid {key:?}");
- assert!(key.try_read().is_err());
- }
- maybe_owner_scope(valid_keys, invalid_keys, path);
- // After all the children run, we should still have our data
- for key in keys {
- let key_value = &*key.read();
- println!("{:?}", key_value);
- assert_eq!(key_value, &value);
- }
- let invalid = valid_keys.pop().unwrap();
- println!("popping {invalid:?}");
- invalid_keys.extend(invalid);
- path.pop();
- }
- }
- for _ in 0..10 {
- maybe_owner_scope::<UnsyncStorage>(&mut Vec::new(), &mut Vec::new(), &mut Vec::new());
- }
- for _ in 0..10 {
- maybe_owner_scope::<SyncStorage>(&mut Vec::new(), &mut Vec::new(), &mut Vec::new());
- }
- }
|