Skip to content

Commit b6a73b4

Browse files
committed
mem: add kani proof for growing queue
1 parent 4d0996e commit b6a73b4

File tree

1 file changed

+76
-0
lines changed

1 file changed

+76
-0
lines changed

Diff for: kernel/src/mem/queue.rs

+76
Original file line numberDiff line numberDiff line change
@@ -265,3 +265,79 @@ mod tests {
265265
}
266266
}
267267
// END TESTING
268+
269+
// VERIFICATION -------------------------------------------------------------------------------------------------------
270+
#[cfg(kani)]
271+
mod verification {
272+
use super::*;
273+
use core::cmp::max;
274+
use std::cmp::min;
275+
use std::vec::Vec;
276+
277+
#[test]
278+
fn kani_concrete_playback_growing_retains_queue_state_with_wrapping_7154119071478699851() {
279+
let concrete_vals: Vec<Vec<u8>> = vec![
280+
// 99968ul
281+
vec![128, 134, 1, 0, 0, 0, 0, 0],
282+
];
283+
kani::concrete_playback_run(concrete_vals, growing_retains_queue_state_with_wrapping);
284+
}
285+
286+
#[kani::proof]
287+
#[kani::unwind(30)]
288+
fn growing_retains_queue_state_with_wrapping() {
289+
let mut queue = Queue::<usize, 10>::new();
290+
for i in 0..10 {
291+
assert_eq!(queue.push_back(i), Ok(()));
292+
}
293+
// sanity check that queue really is full
294+
assert_eq!(queue.push_back(1), Err(KernelError::OutOfMemory));
295+
assert_eq!(queue.len(), 10);
296+
297+
// pop and subsequently push more elements to make queue wrap
298+
for i in 0..5 {
299+
assert_eq!(queue.pop_front(), Some(i));
300+
}
301+
302+
assert_eq!(*queue.front().unwrap(), 5);
303+
assert_eq!(*queue.back().unwrap(), 9);
304+
assert_eq!(queue.len(), 5);
305+
306+
for i in 10..15 {
307+
assert_eq!(queue.push_back(i), Ok(()));
308+
}
309+
310+
assert_eq!(queue.len(), 10);
311+
assert_eq!(*queue.front().unwrap(), 5);
312+
assert_eq!(*queue.back().unwrap(), 14);
313+
let new_cap = kani::any();
314+
let res = queue.grow_capacity(new_cap);
315+
316+
if res == Ok(()) && new_cap > 10 {
317+
for i in 0..(new_cap - 10) {
318+
// add some more elements for good measure
319+
assert_eq!(queue.push_back(i), Ok(()));
320+
}
321+
}
322+
323+
for i in 5..15 {
324+
assert_eq!(queue.pop_front(), Some(i));
325+
}
326+
327+
while !queue.is_empty() {
328+
let _ = queue.pop_front();
329+
}
330+
331+
// now add and remove elements again to show queue still works as expected
332+
if res == Ok(()) && new_cap > 10 {
333+
for i in 0..new_cap {
334+
assert_eq!(queue.push_back(i), Ok(()));
335+
}
336+
337+
for i in 0..new_cap {
338+
assert_eq!(queue.pop_front(), Some(i));
339+
}
340+
}
341+
}
342+
}
343+
// END VERIFICATION

0 commit comments

Comments
 (0)