|
| 1 | +use super::super::testing::crash_test::{CrashTest, Panic}; |
1 | 2 | use super::super::testing::ord_chaos::{Cyclic3, Governed, Governor};
|
2 | 3 | use super::super::testing::rng::DeterministicRng;
|
3 | 4 | use super::Entry::{Occupied, Vacant};
|
@@ -1134,103 +1135,60 @@ mod test_drain_filter {
|
1134 | 1135 |
|
1135 | 1136 | #[test]
|
1136 | 1137 | fn drop_panic_leak() {
|
1137 |
| - static PREDS: AtomicUsize = AtomicUsize::new(0); |
1138 |
| - static DROPS: AtomicUsize = AtomicUsize::new(0); |
1139 |
| - |
1140 |
| - struct D; |
1141 |
| - impl Drop for D { |
1142 |
| - fn drop(&mut self) { |
1143 |
| - if DROPS.fetch_add(1, SeqCst) == 1 { |
1144 |
| - panic!("panic in `drop`"); |
1145 |
| - } |
1146 |
| - } |
1147 |
| - } |
| 1138 | + let test = CrashTest::new(); |
| 1139 | + let mut map = BTreeMap::new(); |
| 1140 | + map.insert(test.dummy(0, Panic::Never), ()); |
| 1141 | + map.insert(test.dummy(1, Panic::InDrop), ()); |
| 1142 | + map.insert(test.dummy(2, Panic::Never), ()); |
1148 | 1143 |
|
1149 |
| - // Keys are multiples of 4, so that each key is counted by a hexadecimal digit. |
1150 |
| - let mut map = (0..3).map(|i| (i * 4, D)).collect::<BTreeMap<_, _>>(); |
| 1144 | + catch_unwind(move || drop(map.drain_filter(|dummy, _| dummy.query(true)))).unwrap_err(); |
1151 | 1145 |
|
1152 |
| - catch_unwind(move || { |
1153 |
| - drop(map.drain_filter(|i, _| { |
1154 |
| - PREDS.fetch_add(1usize << i, SeqCst); |
1155 |
| - true |
1156 |
| - })) |
1157 |
| - }) |
1158 |
| - .unwrap_err(); |
1159 |
| - |
1160 |
| - assert_eq!(PREDS.load(SeqCst), 0x011); |
1161 |
| - assert_eq!(DROPS.load(SeqCst), 3); |
| 1146 | + assert_eq!(test.queried(), 0x011); |
| 1147 | + assert_eq!(test.dropped(), 0x111); |
1162 | 1148 | }
|
1163 | 1149 |
|
1164 | 1150 | #[test]
|
1165 | 1151 | fn pred_panic_leak() {
|
1166 |
| - static PREDS: AtomicUsize = AtomicUsize::new(0); |
1167 |
| - static DROPS: AtomicUsize = AtomicUsize::new(0); |
1168 |
| - |
1169 |
| - struct D; |
1170 |
| - impl Drop for D { |
1171 |
| - fn drop(&mut self) { |
1172 |
| - DROPS.fetch_add(1, SeqCst); |
1173 |
| - } |
1174 |
| - } |
1175 |
| - |
1176 |
| - // Keys are multiples of 4, so that each key is counted by a hexadecimal digit. |
1177 |
| - let mut map = (0..3).map(|i| (i * 4, D)).collect::<BTreeMap<_, _>>(); |
| 1152 | + let test = CrashTest::new(); |
| 1153 | + let mut map = BTreeMap::new(); |
| 1154 | + map.insert(test.dummy(0, Panic::Never), ()); |
| 1155 | + map.insert(test.dummy(1, Panic::InQuery), ()); |
| 1156 | + map.insert(test.dummy(2, Panic::InQuery), ()); |
1178 | 1157 |
|
1179 |
| - catch_unwind(AssertUnwindSafe(|| { |
1180 |
| - drop(map.drain_filter(|i, _| { |
1181 |
| - PREDS.fetch_add(1usize << i, SeqCst); |
1182 |
| - match i { |
1183 |
| - 0 => true, |
1184 |
| - _ => panic!(), |
1185 |
| - } |
1186 |
| - })) |
1187 |
| - })) |
1188 |
| - .unwrap_err(); |
| 1158 | + catch_unwind(AssertUnwindSafe(|| drop(map.drain_filter(|dummy, _| dummy.query(true))))) |
| 1159 | + .unwrap_err(); |
1189 | 1160 |
|
1190 |
| - assert_eq!(PREDS.load(SeqCst), 0x011); |
1191 |
| - assert_eq!(DROPS.load(SeqCst), 1); |
| 1161 | + assert_eq!(test.queried(), 0x011); |
| 1162 | + assert_eq!(test.dropped(), 0x001); |
1192 | 1163 | assert_eq!(map.len(), 2);
|
1193 |
| - assert_eq!(map.first_entry().unwrap().key(), &4); |
1194 |
| - assert_eq!(map.last_entry().unwrap().key(), &8); |
| 1164 | + assert_eq!(map.first_entry().unwrap().key().id, 1); |
| 1165 | + assert_eq!(map.last_entry().unwrap().key().id, 2); |
1195 | 1166 | map.check();
|
1196 | 1167 | }
|
1197 | 1168 |
|
1198 | 1169 | // Same as above, but attempt to use the iterator again after the panic in the predicate
|
1199 | 1170 | #[test]
|
1200 | 1171 | fn pred_panic_reuse() {
|
1201 |
| - static PREDS: AtomicUsize = AtomicUsize::new(0); |
1202 |
| - static DROPS: AtomicUsize = AtomicUsize::new(0); |
1203 |
| - |
1204 |
| - struct D; |
1205 |
| - impl Drop for D { |
1206 |
| - fn drop(&mut self) { |
1207 |
| - DROPS.fetch_add(1, SeqCst); |
1208 |
| - } |
1209 |
| - } |
1210 |
| - |
1211 |
| - // Keys are multiples of 4, so that each key is counted by a hexadecimal digit. |
1212 |
| - let mut map = (0..3).map(|i| (i * 4, D)).collect::<BTreeMap<_, _>>(); |
| 1172 | + let test = CrashTest::new(); |
| 1173 | + let mut map = BTreeMap::new(); |
| 1174 | + map.insert(test.dummy(0, Panic::Never), ()); |
| 1175 | + map.insert(test.dummy(1, Panic::InQuery), ()); |
| 1176 | + map.insert(test.dummy(2, Panic::InQuery), ()); |
1213 | 1177 |
|
1214 | 1178 | {
|
1215 |
| - let mut it = map.drain_filter(|i, _| { |
1216 |
| - PREDS.fetch_add(1usize << i, SeqCst); |
1217 |
| - match i { |
1218 |
| - 0 => true, |
1219 |
| - _ => panic!(), |
1220 |
| - } |
1221 |
| - }); |
| 1179 | + let mut it = map.drain_filter(|dummy, _| dummy.query(true)); |
1222 | 1180 | catch_unwind(AssertUnwindSafe(|| while it.next().is_some() {})).unwrap_err();
|
1223 | 1181 | // Iterator behaviour after a panic is explicitly unspecified,
|
1224 | 1182 | // so this is just the current implementation:
|
1225 | 1183 | let result = catch_unwind(AssertUnwindSafe(|| it.next()));
|
1226 | 1184 | assert!(matches!(result, Ok(None)));
|
1227 | 1185 | }
|
1228 | 1186 |
|
1229 |
| - assert_eq!(PREDS.load(SeqCst), 0x011); |
1230 |
| - assert_eq!(DROPS.load(SeqCst), 1); |
| 1187 | + assert_eq!(test.queried(), 0x011); |
| 1188 | + assert_eq!(test.dropped(), 0x001); |
1231 | 1189 | assert_eq!(map.len(), 2);
|
1232 |
| - assert_eq!(map.first_entry().unwrap().key(), &4); |
1233 |
| - assert_eq!(map.last_entry().unwrap().key(), &8); |
| 1190 | + assert_eq!(map.first_entry().unwrap().key().id, 1); |
| 1191 | + assert_eq!(map.last_entry().unwrap().key().id, 2); |
1234 | 1192 | map.check();
|
1235 | 1193 | }
|
1236 | 1194 | }
|
@@ -1482,6 +1440,25 @@ fn test_clone() {
|
1482 | 1440 | map.check();
|
1483 | 1441 | }
|
1484 | 1442 |
|
| 1443 | +#[test] |
| 1444 | +fn test_clone_panic_leak() { |
| 1445 | + let test = CrashTest::new(); |
| 1446 | + |
| 1447 | + let mut map = BTreeMap::new(); |
| 1448 | + map.insert(test.dummy(0, Panic::Never), ()); |
| 1449 | + map.insert(test.dummy(1, Panic::InClone), ()); |
| 1450 | + map.insert(test.dummy(2, Panic::Never), ()); |
| 1451 | + |
| 1452 | + catch_unwind(|| map.clone()).unwrap_err(); |
| 1453 | + assert_eq!(test.cloned(), 0x011); |
| 1454 | + assert_eq!(test.dropped(), 0x001); |
| 1455 | + assert_eq!(map.len(), 3); |
| 1456 | + |
| 1457 | + drop(map); |
| 1458 | + assert_eq!(test.cloned(), 0x011); |
| 1459 | + assert_eq!(test.dropped(), 0x112); |
| 1460 | +} |
| 1461 | + |
1485 | 1462 | #[test]
|
1486 | 1463 | fn test_clone_from() {
|
1487 | 1464 | let mut map1 = BTreeMap::new();
|
@@ -1858,29 +1835,18 @@ create_append_test!(test_append_1700, 1700);
|
1858 | 1835 |
|
1859 | 1836 | #[test]
|
1860 | 1837 | fn test_append_drop_leak() {
|
1861 |
| - static DROPS: AtomicUsize = AtomicUsize::new(0); |
1862 |
| - |
1863 |
| - struct D; |
1864 |
| - |
1865 |
| - impl Drop for D { |
1866 |
| - fn drop(&mut self) { |
1867 |
| - if DROPS.fetch_add(1, SeqCst) == 0 { |
1868 |
| - panic!("panic in `drop`"); |
1869 |
| - } |
1870 |
| - } |
1871 |
| - } |
1872 |
| - |
| 1838 | + let test = CrashTest::new(); |
1873 | 1839 | let mut left = BTreeMap::new();
|
1874 | 1840 | let mut right = BTreeMap::new();
|
1875 |
| - left.insert(0, D); |
1876 |
| - left.insert(1, D); // first to be dropped during append |
1877 |
| - left.insert(2, D); |
1878 |
| - right.insert(1, D); |
1879 |
| - right.insert(2, D); |
| 1841 | + left.insert(test.dummy(0, Panic::Never), ()); |
| 1842 | + left.insert(test.dummy(1, Panic::InDrop), ()); // first duplicate key, dropped during append |
| 1843 | + left.insert(test.dummy(2, Panic::Never), ()); |
| 1844 | + right.insert(test.dummy(1, Panic::Never), ()); |
| 1845 | + right.insert(test.dummy(2, Panic::Never), ()); |
1880 | 1846 |
|
1881 | 1847 | catch_unwind(move || left.append(&mut right)).unwrap_err();
|
1882 | 1848 |
|
1883 |
| - assert_eq!(DROPS.load(SeqCst), 5); |
| 1849 | + assert_eq!(test.dropped(), 0x221); |
1884 | 1850 | }
|
1885 | 1851 |
|
1886 | 1852 | #[test]
|
@@ -2007,51 +1973,32 @@ fn test_split_off_large_random_sorted() {
|
2007 | 1973 |
|
2008 | 1974 | #[test]
|
2009 | 1975 | fn test_into_iter_drop_leak_height_0() {
|
2010 |
| - static DROPS: AtomicUsize = AtomicUsize::new(0); |
2011 |
| - |
2012 |
| - struct D; |
2013 |
| - |
2014 |
| - impl Drop for D { |
2015 |
| - fn drop(&mut self) { |
2016 |
| - if DROPS.fetch_add(1, SeqCst) == 3 { |
2017 |
| - panic!("panic in `drop`"); |
2018 |
| - } |
2019 |
| - } |
2020 |
| - } |
2021 |
| - |
| 1976 | + let test = CrashTest::new(); |
2022 | 1977 | let mut map = BTreeMap::new();
|
2023 |
| - map.insert("a", D); |
2024 |
| - map.insert("b", D); |
2025 |
| - map.insert("c", D); |
2026 |
| - map.insert("d", D); |
2027 |
| - map.insert("e", D); |
| 1978 | + map.insert("a", test.dummy(0, Panic::Never)); |
| 1979 | + map.insert("b", test.dummy(1, Panic::Never)); |
| 1980 | + map.insert("c", test.dummy(2, Panic::Never)); |
| 1981 | + map.insert("d", test.dummy(3, Panic::InDrop)); |
| 1982 | + map.insert("e", test.dummy(4, Panic::Never)); |
2028 | 1983 |
|
2029 | 1984 | catch_unwind(move || drop(map.into_iter())).unwrap_err();
|
2030 | 1985 |
|
2031 |
| - assert_eq!(DROPS.load(SeqCst), 5); |
| 1986 | + assert_eq!(test.dropped(), 0x11111); |
2032 | 1987 | }
|
2033 | 1988 |
|
2034 | 1989 | #[test]
|
2035 | 1990 | fn test_into_iter_drop_leak_height_1() {
|
2036 | 1991 | let size = MIN_INSERTS_HEIGHT_1;
|
2037 |
| - static DROPS: AtomicUsize = AtomicUsize::new(0); |
2038 |
| - static PANIC_POINT: AtomicUsize = AtomicUsize::new(0); |
2039 |
| - |
2040 |
| - struct D; |
2041 |
| - impl Drop for D { |
2042 |
| - fn drop(&mut self) { |
2043 |
| - if DROPS.fetch_add(1, SeqCst) == PANIC_POINT.load(SeqCst) { |
2044 |
| - panic!("panic in `drop`"); |
2045 |
| - } |
2046 |
| - } |
2047 |
| - } |
2048 |
| - |
2049 | 1992 | for panic_point in vec![0, 1, size - 2, size - 1] {
|
2050 |
| - DROPS.store(0, SeqCst); |
2051 |
| - PANIC_POINT.store(panic_point, SeqCst); |
2052 |
| - let map: BTreeMap<_, _> = (0..size).map(|i| (i, D)).collect(); |
| 1993 | + let test = CrashTest::new_totaling(); |
| 1994 | + let map: BTreeMap<_, _> = (0..size) |
| 1995 | + .map(|i| { |
| 1996 | + let panic = if i == panic_point { Panic::InDrop } else { Panic::Never }; |
| 1997 | + (test.dummy(i, Panic::Never), test.dummy(i, panic)) |
| 1998 | + }) |
| 1999 | + .collect(); |
2053 | 2000 | catch_unwind(move || drop(map.into_iter())).unwrap_err();
|
2054 |
| - assert_eq!(DROPS.load(SeqCst), size); |
| 2001 | + assert_eq!(test.dropped(), size as u64 * 2); |
2055 | 2002 | }
|
2056 | 2003 | }
|
2057 | 2004 |
|
|
0 commit comments