basic.rs 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. use generational_box::{GenerationalBox, Storage, SyncStorage, UnsyncStorage};
  2. /// # Example
  3. ///
  4. /// ```compile_fail
  5. /// let data = String::from("hello world");
  6. /// let owner = UnsyncStorage::owner();
  7. /// let key = owner.insert(&data);
  8. /// drop(data);
  9. /// assert_eq!(*key.read(), "hello world");
  10. /// ```
  11. #[allow(unused)]
  12. fn compile_fail() {}
  13. #[test]
  14. fn leaking_is_ok() {
  15. fn leaking_is_ok_test<S: Storage<String>>() {
  16. let data = String::from("hello world");
  17. let key;
  18. {
  19. // create an owner
  20. let owner = S::owner();
  21. // insert data into the store
  22. key = owner.insert(data);
  23. // don't drop the owner
  24. std::mem::forget(owner);
  25. }
  26. assert_eq!(
  27. key.try_read().as_deref().unwrap(),
  28. &"hello world".to_string()
  29. );
  30. }
  31. leaking_is_ok_test::<UnsyncStorage>();
  32. leaking_is_ok_test::<SyncStorage>();
  33. }
  34. #[test]
  35. fn drops() {
  36. fn drops_test<S: Storage<String>>() {
  37. let data = String::from("hello world");
  38. let key;
  39. {
  40. // create an owner
  41. let owner = S::owner();
  42. // insert data into the store
  43. key = owner.insert(data);
  44. // drop the owner
  45. }
  46. assert!(key.try_read().is_err());
  47. }
  48. drops_test::<UnsyncStorage>();
  49. drops_test::<SyncStorage>();
  50. }
  51. #[test]
  52. fn works() {
  53. fn works_test<S: Storage<i32>>() {
  54. let owner = S::owner();
  55. let key = owner.insert(1);
  56. assert_eq!(*key.read(), 1);
  57. }
  58. works_test::<UnsyncStorage>();
  59. works_test::<SyncStorage>();
  60. }
  61. #[test]
  62. fn insert_while_reading() {
  63. fn insert_while_reading_test<S: Storage<String> + Storage<&'static i32>>() {
  64. let owner = S::owner();
  65. let key;
  66. {
  67. let data: String = "hello world".to_string();
  68. key = owner.insert(data);
  69. }
  70. let value = key.read();
  71. owner.insert(&1);
  72. assert_eq!(*value, "hello world");
  73. }
  74. insert_while_reading_test::<UnsyncStorage>();
  75. insert_while_reading_test::<SyncStorage>();
  76. }
  77. #[test]
  78. #[should_panic]
  79. fn panics() {
  80. fn panics_test<S: Storage<i32>>() {
  81. let owner = S::owner();
  82. let key = owner.insert(1);
  83. drop(owner);
  84. assert_eq!(*key.read(), 1);
  85. }
  86. panics_test::<UnsyncStorage>();
  87. panics_test::<SyncStorage>();
  88. }
  89. #[test]
  90. fn fuzz() {
  91. fn maybe_owner_scope<S: Storage<String>>(
  92. valid_keys: &mut Vec<GenerationalBox<String, S>>,
  93. invalid_keys: &mut Vec<GenerationalBox<String, S>>,
  94. path: &mut Vec<u8>,
  95. ) {
  96. let branch_cutoff = 5;
  97. let children = if path.len() < branch_cutoff {
  98. rand::random::<u8>() % 4
  99. } else {
  100. rand::random::<u8>() % 2
  101. };
  102. for i in 0..children {
  103. let owner = S::owner();
  104. let value = format!("hello world {path:?}");
  105. let key = owner.insert(value.clone());
  106. println!("created new box {key:?}");
  107. valid_keys.push(key);
  108. path.push(i);
  109. // read all keys
  110. println!("{:?}", path);
  111. for key in valid_keys.iter() {
  112. println!("reading {key:?}");
  113. let value = key.read();
  114. println!("{:?}", &*value);
  115. assert!(value.starts_with("hello world"));
  116. }
  117. for key in invalid_keys.iter() {
  118. println!("reading invalid {key:?}");
  119. assert!(key.try_read().is_err());
  120. }
  121. maybe_owner_scope(valid_keys, invalid_keys, path);
  122. // After all the children run, we should still have our data
  123. let key_value = &*key.read();
  124. println!("{:?}", key_value);
  125. assert_eq!(key_value, &value);
  126. let invalid = valid_keys.pop().unwrap();
  127. println!("popping {invalid:?}");
  128. invalid_keys.push(invalid);
  129. path.pop();
  130. }
  131. }
  132. for _ in 0..10 {
  133. maybe_owner_scope::<UnsyncStorage>(&mut Vec::new(), &mut Vec::new(), &mut Vec::new());
  134. }
  135. for _ in 0..10 {
  136. maybe_owner_scope::<SyncStorage>(&mut Vec::new(), &mut Vec::new(), &mut Vec::new());
  137. }
  138. }
  139. #[test]
  140. fn fuzz_rc() {
  141. fn maybe_owner_scope<S: Storage<String>>(
  142. valid_keys: &mut Vec<Vec<GenerationalBox<String, S>>>,
  143. invalid_keys: &mut Vec<GenerationalBox<String, S>>,
  144. path: &mut Vec<u8>,
  145. ) {
  146. let branch_cutoff = 5;
  147. let children = if path.len() < branch_cutoff {
  148. rand::random::<u8>() % 4
  149. } else {
  150. rand::random::<u8>() % 2
  151. };
  152. for i in 0..children {
  153. let owner = S::owner();
  154. let value = format!("hello world {path:?}");
  155. let key = owner.insert_rc(value.clone());
  156. println!("created new box {key:?}");
  157. let mut keys = vec![key];
  158. for _ in 0..rand::random::<u8>() % 10 {
  159. if rand::random::<u8>() % 2 == 0 {
  160. let owner = S::owner();
  161. let key = owner.insert_reference(key).unwrap();
  162. println!("created new reference {key:?}");
  163. invalid_keys.push(key);
  164. }
  165. let key = owner.insert_reference(key).unwrap();
  166. println!("created new reference {key:?}");
  167. keys.push(key);
  168. }
  169. valid_keys.push(keys.clone());
  170. path.push(i);
  171. // read all keys
  172. println!("{:?}", path);
  173. for keys in valid_keys.iter() {
  174. for key in keys {
  175. println!("reading {key:?}");
  176. let value = key.read();
  177. println!("{:?}", &*value);
  178. assert!(value.starts_with("hello world"));
  179. }
  180. }
  181. for key in invalid_keys.iter() {
  182. println!("reading invalid {key:?}");
  183. assert!(key.try_read().is_err());
  184. }
  185. maybe_owner_scope(valid_keys, invalid_keys, path);
  186. // After all the children run, we should still have our data
  187. for key in keys {
  188. let key_value = &*key.read();
  189. println!("{:?}", key_value);
  190. assert_eq!(key_value, &value);
  191. }
  192. let invalid = valid_keys.pop().unwrap();
  193. println!("popping {invalid:?}");
  194. invalid_keys.extend(invalid);
  195. path.pop();
  196. }
  197. }
  198. for _ in 0..10 {
  199. maybe_owner_scope::<UnsyncStorage>(&mut Vec::new(), &mut Vec::new(), &mut Vec::new());
  200. }
  201. for _ in 0..10 {
  202. maybe_owner_scope::<SyncStorage>(&mut Vec::new(), &mut Vec::new(), &mut Vec::new());
  203. }
  204. }