capsules_extra/test/
kv_system.rs1use crate::tickv::{KVSystem, KVSystemClient, KeyType};
34use core::cell::Cell;
35use core::marker::PhantomData;
36use kernel::debug;
37use kernel::utilities::cells::{MapCell, TakeCell};
38use kernel::utilities::leasable_buffer::SubSliceMut;
39use kernel::ErrorCode;
40
41#[derive(Clone, Copy, PartialEq)]
42enum CurrentState {
43 Normal,
44 ExpectGetValueFail,
45}
46
47pub struct KVSystemTest<'a, S: KVSystem<'static>, T: KeyType> {
48 kv_system: &'a S,
49 phantom: PhantomData<&'a T>,
50 value: MapCell<SubSliceMut<'static, u8>>,
51 ret_buffer: TakeCell<'static, [u8]>,
52 state: Cell<CurrentState>,
53}
54
55impl<'a, S: KVSystem<'static>, T: KeyType> KVSystemTest<'a, S, T> {
56 pub fn new(
57 kv_system: &'a S,
58 value: SubSliceMut<'static, u8>,
59 static_buf: &'static mut [u8; 4],
60 ) -> KVSystemTest<'a, S, T> {
61 debug!("---Starting TicKV Tests---");
62
63 Self {
64 kv_system,
65 phantom: PhantomData,
66 value: MapCell::new(value),
67 ret_buffer: TakeCell::new(static_buf),
68 state: Cell::new(CurrentState::Normal),
69 }
70 }
71}
72
73impl<S: KVSystem<'static, K = T>, T: KeyType + core::fmt::Debug> KVSystemClient<T>
74 for KVSystemTest<'_, S, T>
75{
76 fn generate_key_complete(
77 &self,
78 result: Result<(), ErrorCode>,
79 _unhashed_key: SubSliceMut<'static, u8>,
80 key_buf: &'static mut T,
81 ) {
82 match result {
83 Ok(()) => {
84 debug!("Generated key: {:?}", key_buf);
85 debug!("Now appending the key");
86 self.kv_system
87 .append_key(key_buf, self.value.take().unwrap())
88 .unwrap();
89 }
90 Err(e) => {
91 panic!("Error adding key: {:?}", e);
92 }
93 }
94 }
95
96 fn append_key_complete(
97 &self,
98 result: Result<(), ErrorCode>,
99 key: &'static mut T,
100 value: SubSliceMut<'static, u8>,
101 ) {
102 match result {
103 Ok(()) => {
104 debug!("Key: {:?} with value {:?} was added", key, value);
105 debug!("Now retrieving the key");
106 self.kv_system
107 .get_value(key, SubSliceMut::new(self.ret_buffer.take().unwrap()))
108 .unwrap();
109 }
110 Err(e) => {
111 panic!("Error adding key: {:?}", e);
112 }
113 }
114 }
115
116 fn get_value_complete(
117 &self,
118 result: Result<(), ErrorCode>,
119 key: &'static mut T,
120 ret_buf: SubSliceMut<'static, u8>,
121 ) {
122 match result {
123 Ok(()) => {
124 debug!("Key: {:?} with value {:?} was retrieved", key, ret_buf);
125 self.ret_buffer.replace(ret_buf.take());
126 self.kv_system.invalidate_key(key).unwrap();
127 }
128 Err(e) => {
129 if self.state.get() == CurrentState::ExpectGetValueFail {
130 debug!("Unable to find key: {:?}", key);
132 self.state.set(CurrentState::Normal);
133
134 debug!("Let's start a garbage collection");
135 self.kv_system.garbage_collect().unwrap();
136 } else {
137 panic!("Error finding key: {:?}", e);
138 }
139 }
140 }
141 }
142
143 fn invalidate_key_complete(&self, result: Result<(), ErrorCode>, key: &'static mut T) {
144 match result {
145 Ok(()) => {
146 debug!("Removed Key: {:?}", key);
147
148 debug!("Try to read removed key: {:?}", key);
149 self.state.set(CurrentState::ExpectGetValueFail);
150 self.kv_system
151 .get_value(key, SubSliceMut::new(self.ret_buffer.take().unwrap()))
152 .unwrap();
153 }
154 Err(e) => {
155 panic!("Error invalidating key: {:?}", e);
156 }
157 }
158 }
159
160 fn garbage_collect_complete(&self, result: Result<(), ErrorCode>) {
161 match result {
162 Ok(()) => {
163 debug!("Finished garbage collection");
164 debug!("---Finished TicKV Tests---");
165 }
166 Err(e) => {
167 panic!("Error running garbage collection: {:?}", e);
168 }
169 }
170 }
171}