1 use std::iter;
2 use wasmtime::Result;
3 use wasmtime_environ::collections::{TryCollect, TryVec, try_vec};
4 use wasmtime_fuzzing::oom::OomTest;
5 
6 #[test]
try_vec_with_capacity() -> Result<()>7 fn try_vec_with_capacity() -> Result<()> {
8     OomTest::new().test(|| {
9         let _v = wasmtime_environ::collections::TryVec::<usize>::with_capacity(100)?;
10         Ok(())
11     })
12 }
13 
14 #[test]
try_vec_reserve() -> Result<()>15 fn try_vec_reserve() -> Result<()> {
16     OomTest::new().test(|| {
17         let mut v = wasmtime_environ::collections::TryVec::<usize>::new();
18         v.reserve(10)?;
19         Ok(())
20     })
21 }
22 
23 #[test]
try_vec_reserve_exact() -> Result<()>24 fn try_vec_reserve_exact() -> Result<()> {
25     OomTest::new().test(|| {
26         let mut v = wasmtime_environ::collections::TryVec::<usize>::new();
27         v.reserve_exact(3)?;
28         Ok(())
29     })
30 }
31 
32 #[test]
try_vec_push() -> Result<()>33 fn try_vec_push() -> Result<()> {
34     OomTest::new().test(|| {
35         let mut v = wasmtime_environ::collections::TryVec::new();
36         v.push(42)?;
37         Ok(())
38     })
39 }
40 
41 #[test]
try_vec_and_boxed_slice() -> Result<()>42 fn try_vec_and_boxed_slice() -> Result<()> {
43     use wasmtime_core::alloc::TryVec;
44 
45     OomTest::new().test(|| {
46         // Nonzero-sized type.
47         let mut vec = TryVec::new();
48         vec.push(1)?;
49         let slice = vec.into_boxed_slice()?; // len > 0, cap > 0
50 
51         let mut vec = TryVec::from(slice);
52         vec.pop();
53         let slice = vec.into_boxed_slice()?; // len = 0, cap > 0
54 
55         let vec = TryVec::from(slice);
56         let _slice = vec.into_boxed_slice()?; // len = 0, cap = 0
57 
58         let mut vec = TryVec::new();
59         vec.reserve_exact(3)?;
60         vec.push(2)?;
61         vec.push(2)?;
62         vec.push(2)?;
63         let _slice = vec.into_boxed_slice()?; // len = cap, len > 0
64 
65         for i in 0..12 {
66             let mut vec = TryVec::new();
67             for j in 0..i {
68                 vec.push(j)?;
69             }
70             let _slice = vec.into_boxed_slice()?; // len ?= cap
71         }
72 
73         // Zero-sized type.
74         let mut vec = TryVec::new();
75         vec.push(())?;
76         let slice = vec.into_boxed_slice()?; // len > 0, cap > 0
77         let mut vec = TryVec::from(slice);
78         vec.pop();
79         let slice = vec.into_boxed_slice()?; // len = 0, cap > 0
80         let vec = TryVec::from(slice);
81         let _ = vec.into_boxed_slice()?; // len = 0, cap = 0
82 
83         Ok(())
84     })
85 }
86 
87 #[test]
try_vec_shrink_to_fit() -> Result<()>88 fn try_vec_shrink_to_fit() -> Result<()> {
89     use wasmtime_core::alloc::TryVec;
90 
91     #[derive(Default)]
92     struct ZeroSized;
93 
94     #[derive(Default)]
95     struct NonZeroSized {
96         _unused: usize,
97     }
98 
99     fn do_test<T: Default>() -> Result<()> {
100         // len == cap == 0
101         let mut v = TryVec::<T>::new();
102         v.shrink_to_fit()?;
103 
104         // len == 0 < cap
105         let mut v = TryVec::<T>::with_capacity(4)?;
106         v.shrink_to_fit()?;
107 
108         // 0 < len < cap
109         let mut v = TryVec::with_capacity(4)?;
110         v.push(T::default())?;
111         v.shrink_to_fit()?;
112 
113         // 0 < len == cap
114         let mut v = TryVec::new();
115         v.reserve_exact(2)?;
116         v.push(T::default())?;
117         v.push(T::default())?;
118         v.shrink_to_fit()?;
119 
120         Ok(())
121     }
122 
123     OomTest::new().test(|| do_test::<ZeroSized>())?;
124     OomTest::new().test(|| do_test::<NonZeroSized>())?;
125     Ok(())
126 }
127 
128 #[test]
try_vec_resize() -> Result<()>129 fn try_vec_resize() -> Result<()> {
130     OomTest::new().test(|| {
131         let mut v = TryVec::new();
132         v.resize(10, 'a')?; // Grow.
133         v.resize(1, 'b')?; // Truncate.
134         v.resize(1, 'c')?; // Same length.
135         v.resize(3, 'd')?; // Grow again.
136         assert_eq!(&*v, &['a', 'd', 'd']);
137         Ok(())
138     })
139 }
140 
141 #[test]
try_vec_try_collect() -> Result<()>142 fn try_vec_try_collect() -> Result<()> {
143     OomTest::new().test(|| {
144         iter::repeat(1).take(0).try_collect::<TryVec<_>, _>()?;
145         iter::repeat(1).take(1).try_collect::<TryVec<_>, _>()?;
146         iter::repeat(1).take(100).try_collect::<TryVec<_>, _>()?;
147         iter::repeat(()).take(100).try_collect::<TryVec<_>, _>()?;
148         Ok(())
149     })
150 }
151 
152 #[test]
try_vec_extend() -> Result<()>153 fn try_vec_extend() -> Result<()> {
154     use wasmtime_core::alloc::{TryExtend, TryVec};
155     OomTest::new().test(|| {
156         let mut vec = TryVec::new();
157         vec.try_extend([])?;
158         vec.try_extend([1])?;
159         vec.try_extend([1, 2, 3, 4])?;
160 
161         let mut vec = TryVec::new();
162         vec.try_extend([])?;
163         vec.try_extend([()])?;
164         vec.try_extend([(), (), ()])?;
165         Ok(())
166     })
167 }
168 
169 #[test]
try_vec_macro_elems() -> Result<()>170 fn try_vec_macro_elems() -> Result<()> {
171     OomTest::new().test(|| {
172         let v = try_vec![100, 200, 300, 400]?;
173         assert_eq!(&*v, &[100, 200, 300, 400]);
174         Ok(())
175     })
176 }
177 
178 #[test]
try_vec_macro_elem_len() -> Result<()>179 fn try_vec_macro_elem_len() -> Result<()> {
180     OomTest::new().test(|| {
181         let v = try_vec![100; 3]?;
182         assert_eq!(&*v, &[100, 100, 100]);
183         Ok(())
184     })
185 }
186