2 * Copyright (c) 2020 Tilman Sauerbeck (tilman at code-monkey de)
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 use common::buffer::{Buffer, BufferUserData};
26 use common::storage::{Storage, Error};
27 use common::logger::{MEMORY_SIZE, Logger, Error as LoggerError};
35 fn new() -> FakeStorage {
37 expected: vec![0xff; MEMORY_SIZE].into_boxed_slice(),
38 actual: vec![0xff; MEMORY_SIZE].into_boxed_slice(),
43 impl Storage for FakeStorage {
44 fn size(&self) -> usize {
48 fn read(&self, address: usize, buffer: &mut [u8]) {
49 for i in 0..buffer.len() {
50 buffer[i] = self.actual[address + i];
54 fn write(&mut self, address: usize, buffer: &[u8; 4096]) -> Result<(), Error> {
55 if (address & 4095) != 0 {
56 return Err(Error::UnalignedAddress);
59 for i in 0..buffer.len() {
60 self.actual[address + i] = buffer[i];
67 self.actual = vec![0xff; MEMORY_SIZE].into_boxed_slice();
71 // Runs a couple of recordings on fully erased flash memory.
73 fn first_recording() {
74 let mut fake_storage = FakeStorage::new();
76 let mut logger = Logger::new(&mut fake_storage);
79 let tap = gps::TimeAndPos {
81 unix_time: 1478026311,
86 let recording_id = logger.start_recording(&tap);
87 assert_eq!(1, recording_id);
89 let sectors_written = logger.stop_recording(&tap);
90 assert_eq!(1, sectors_written);
94 0x01, 0x00, 0x01, 0x00,
95 0x47, 0xe4, 0x18, 0x58,
100 0x9c, 0x8d, 0x99, 0x07,
101 0x9e, 0x8d, 0x99, 0x07,
104 0xff, 0xff, 0xff, 0xff, 0x0f,
111 let end = start + expected.len();
112 fake_storage.expected[start..end].copy_from_slice(&expected);
114 assert_eq!(fake_storage.expected, fake_storage.actual);
118 fn second_recording() {
119 let mut fake_storage = FakeStorage::new();
121 // Mark first sector as in use.
124 0x01, 0x00, 0x01, 0x00,
127 fake_storage.expected[0..recording0.len()].copy_from_slice(&recording0);
128 fake_storage.actual[0..recording0.len()].copy_from_slice(&recording0);
130 let mut logger = Logger::new(&mut fake_storage);
133 let tap = gps::TimeAndPos {
135 unix_time: 1478026312,
140 let recording_id = logger.start_recording(&tap);
141 assert_eq!(2, recording_id);
143 let sectors_written = logger.stop_recording(&tap);
144 assert_eq!(1, sectors_written);
148 0x01, 0x00, 0x02, 0x00,
149 0x48, 0xe4, 0x18, 0x58,
154 0x9c, 0x8d, 0x99, 0x07,
155 0x9e, 0x8d, 0x99, 0x07,
158 0xff, 0xff, 0xff, 0xff, 0x0f,
165 let end = start + expected.len();
166 fake_storage.expected[start..end].copy_from_slice(&expected);
168 assert_eq!(fake_storage.expected, fake_storage.actual);
172 fn multi_sector_recording() {
173 let mut fake_storage = FakeStorage::new();
175 let mut logger = Logger::new(&mut fake_storage);
178 let tap = gps::TimeAndPos {
180 unix_time: 1578425250,
185 let recording_id = logger.start_recording(&tap);
186 assert_eq!(1, recording_id);
188 let mut prev_tap = tap;
191 let tap = gps::TimeAndPos {
193 unix_time: prev_tap.unix_time + 1,
194 latitude: prev_tap.latitude + 1,
195 longitude: prev_tap.longitude + 1,
198 logger.log(&prev_tap, &tap);
203 let sectors_written = logger.stop_recording(&tap);
204 assert_eq!(2, sectors_written);
207 0x01, 0x00, 0x01, 0x00,
211 0x03, 0x00, 0x01, 0x00,
214 assert_eq!(header0, fake_storage.actual[0..(0 + header0.len())]);
215 assert_eq!(header1, fake_storage.actual[4096..(4096 + header1.len())]);
218 extern "C" fn flush_write_buffer(user_data: *mut BufferUserData,
221 count: usize) -> isize {
222 let _final_buffer = user_data as *mut [u8; 8192];
223 let final_buffer = unsafe { &mut * _final_buffer };
226 core::ptr::copy_nonoverlapping(buf, final_buffer.as_mut_ptr(), count);
232 // Verifies that Logger::get_recording() detects unknown recording IDs.
234 fn get_recording_invalid() {
235 let mut final_buffer = [0u8; 8192];
237 let mut yenc_buffer_space = [0u8; 8192];
238 let mut yenc_buffer = Buffer::alloc();
240 let user_data = (&mut final_buffer as *mut [u8; 8192]) as *mut BufferUserData;
242 yenc_buffer.init(yenc_buffer_space.as_mut_ptr(),
243 yenc_buffer_space.len(),
246 let mut fake_storage = FakeStorage::new();
248 let mut logger = Logger::new(&mut fake_storage);
251 // Zero is never a valid recording id.
252 let result = logger.get_recording(0, &mut yenc_buffer);
253 assert_eq!(LoggerError::NoSuchRecording, result.unwrap_err());
255 let result = logger.get_recording(1, &mut yenc_buffer);
256 assert_eq!(LoggerError::NoSuchRecording, result.unwrap_err());
259 // Verifies that Logger::get_recording() can retrieve finished recordings.
261 fn get_recording_valid() {
262 let mut final_buffer = [0u8; 8192];
264 let mut yenc_buffer_space = [0u8; 8192];
265 let mut yenc_buffer = Buffer::alloc();
267 let user_data = (&mut final_buffer as *mut [u8; 8192]) as *mut BufferUserData;
269 yenc_buffer.init(yenc_buffer_space.as_mut_ptr(),
270 yenc_buffer_space.len(),
274 let mut fake_storage = FakeStorage::new();
276 let mut logger = Logger::new(&mut fake_storage);
279 let result = logger.get_recording(1, &mut yenc_buffer);
280 assert_eq!(LoggerError::NoSuchRecording, result.unwrap_err());
282 let tap0 = gps::TimeAndPos {
284 unix_time: 1478026311,
289 logger.start_recording(&tap0);
291 let tap1 = gps::TimeAndPos {
293 unix_time: 1478026311 + 1,
294 latitude: 0x73234e + 5,
295 longitude: 0x73234f + 5,
298 logger.log(&tap0, &tap1);
300 let tap2 = gps::TimeAndPos {
302 unix_time: 1478026311 + 2,
303 latitude: 0x73234e + 10,
304 longitude: 0x73234f + 10,
307 logger.log(&tap1, &tap2);
309 logger.stop_recording(&tap2);
311 assert!(logger.get_recording(1, &mut yenc_buffer).is_ok());