X-Git-Url: http://git.code-monkey.de/?a=blobdiff_plain;f=test%2Flogger_test.rs;h=bbf8dd56b2254448275e030b613b5d49b932a86d;hb=4b82362597c3908db091615b403663b8f39b67fa;hp=ee0b30b92b749fbb61ea73dd3918b1613143baa5;hpb=3582479d2c11b4969514e321086acf7d6d8d503f;p=gps-watch.git diff --git a/test/logger_test.rs b/test/logger_test.rs index ee0b30b..bbf8dd5 100644 --- a/test/logger_test.rs +++ b/test/logger_test.rs @@ -21,9 +21,12 @@ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +use std::io::{Read, Write}; +use std::os::unix::io::FromRawFd; +use common::buffer::{Buffer, BufferUserData}; use common::gps; use common::storage::{Storage, Error}; -use common::logger::*; +use common::logger::{MEMORY_SIZE, Logger, Error as LoggerError}; struct FakeStorage { expected: Box<[u8]>, @@ -67,6 +70,38 @@ impl Storage for FakeStorage { } } +struct Pipe { + pipe_fd: [i32; 2], +} + +impl Pipe { + fn new() -> Pipe { + let mut pipe_fd = [-1i32; 2]; + + unsafe { + extern { + fn pipe2(pipefd: *mut i32, flags: i32) -> i32; + } + + const O_NONBLOCK : i32 = 0x800; + + pipe2(pipe_fd.as_mut_ptr(), O_NONBLOCK); + } + + Pipe { + pipe_fd: pipe_fd, + } + } + + fn read_fd(&self) -> i32 { + self.pipe_fd[0] + } + + fn write_fd(&self) -> i32 { + self.pipe_fd[1] + } +} + // Runs a couple of recordings on fully erased flash memory. #[test] fn first_recording() { @@ -213,3 +248,185 @@ fn multi_sector_recording() { assert_eq!(header0, fake_storage.actual[0..(0 + header0.len())]); assert_eq!(header1, fake_storage.actual[4096..(4096 + header1.len())]); } + +extern "C" fn flush_write_buffer(user_data: *mut BufferUserData, + buf: *const u8, + _bufsiz: usize, + count: usize) -> isize { + let _file = user_data as *mut std::fs::File; + + unsafe { + let file = &mut * _file; + + file.write_all(std::slice::from_raw_parts(buf, count)).unwrap(); + } + + count as isize +} + +// Verifies that Logger::get_recording() detects unknown recording IDs. +#[test] +fn get_recording_invalid() { + let pipe = Pipe::new(); + + let mut file = unsafe { std::fs::File::from_raw_fd(pipe.write_fd()) }; + + let mut yenc_buffer_space = [0u8; 8192]; + let mut yenc_buffer = Buffer::alloc(); + + let user_data = (&mut file as *mut std::fs::File) as *mut BufferUserData; + + yenc_buffer.init(yenc_buffer_space.as_mut_ptr(), + yenc_buffer_space.len(), + flush_write_buffer, + user_data); + + let mut fake_storage = FakeStorage::new(); + + let mut logger = Logger::new(&mut fake_storage); + logger.init(); + + // Zero is never a valid recording id. + let result = logger.get_recording(0, &mut yenc_buffer); + assert_eq!(LoggerError::NoSuchRecording, result.unwrap_err()); + + let result = logger.get_recording(1, &mut yenc_buffer); + assert_eq!(LoggerError::NoSuchRecording, result.unwrap_err()); +} + +// Verifies that Logger::get_recording() can retrieve finished recordings. +#[test] +fn get_recording_valid() { + let pipe = Pipe::new(); + + let mut file = unsafe { std::fs::File::from_raw_fd(pipe.write_fd()) }; + + let mut yenc_buffer_space = [0u8; 8192]; + let mut yenc_buffer = Buffer::alloc(); + + let user_data = (&mut file as *mut std::fs::File) as *mut BufferUserData; + + yenc_buffer.init(yenc_buffer_space.as_mut_ptr(), + yenc_buffer_space.len(), + flush_write_buffer, + user_data); + + let mut fake_storage = FakeStorage::new(); + + let mut logger = Logger::new(&mut fake_storage); + logger.init(); + + let result = logger.get_recording(1, &mut yenc_buffer); + assert_eq!(LoggerError::NoSuchRecording, result.unwrap_err()); + + let tap0 = gps::TimeAndPos { + system_time: 0, + unix_time: 1478026311, + latitude: 0x73234e, + longitude: 0x73234f, + }; + + logger.start_recording(&tap0); + + let tap1 = gps::TimeAndPos { + system_time: 0, + unix_time: 1478026311 + 1, + latitude: 0x73234e + 5, + longitude: 0x73234f + 5, + }; + + logger.log(&tap0, &tap1); + + let tap2 = gps::TimeAndPos { + system_time: 0, + unix_time: 1478026311 + 2, + latitude: 0x73234e + 10, + longitude: 0x73234f + 10, + }; + + logger.log(&tap1, &tap2); + + logger.stop_recording(&tap2); + + assert!(logger.get_recording(1, &mut yenc_buffer).is_ok()); +} + +// Verifies that Logger::list_recordings() shows an empty listing +// if there are no recordings. +#[test] +fn list_recordings0() { + let pipe = Pipe::new(); + + let mut file = unsafe { std::fs::File::from_raw_fd(pipe.write_fd()) }; + + let mut ls_buffer_space = [0u8; 4096]; + let mut ls_buffer = Buffer::alloc(); + + let user_data = (&mut file as *mut std::fs::File) as *mut BufferUserData; + + ls_buffer.init(ls_buffer_space.as_mut_ptr(), + ls_buffer_space.len(), + flush_write_buffer, + user_data); + + let mut fake_storage = FakeStorage::new(); + + let mut logger = Logger::new(&mut fake_storage); + logger.init(); + + logger.list_recordings(&mut ls_buffer); + + let mut file = unsafe { std::fs::File::from_raw_fd(pipe.read_fd()) }; + + let mut listing_raw = [0u8; 256]; + + // There are no recordings, so there's no data in the pipe either. + assert!(file.read(&mut listing_raw).is_err()); +} + +// Verifies that Logger::list_recordings() shows a listing +// of a single recording in the very first sector. +#[test] +fn list_recordings1() { + let pipe = Pipe::new(); + + let mut file = unsafe { std::fs::File::from_raw_fd(pipe.write_fd()) }; + + let mut ls_buffer_space = [0u8; 4096]; + let mut ls_buffer = Buffer::alloc(); + + let user_data = (&mut file as *mut std::fs::File) as *mut BufferUserData; + + ls_buffer.init(ls_buffer_space.as_mut_ptr(), + ls_buffer_space.len(), + flush_write_buffer, + user_data); + + let mut fake_storage = FakeStorage::new(); + + // Mark first sector as in use. + let recording0 = [ + // Header: + 0x01, 0x00, 0x01, 0x00, + 0xa2, 0xdb, 0x14, 0x5e, + ]; + + fake_storage.expected[0..recording0.len()].copy_from_slice(&recording0); + fake_storage.actual[0..recording0.len()].copy_from_slice(&recording0); + + let mut logger = Logger::new(&mut fake_storage); + logger.init(); + + logger.list_recordings(&mut ls_buffer); + + let mut file = unsafe { std::fs::File::from_raw_fd(pipe.read_fd()) }; + + let mut listing_raw = [0u8; 256]; + let num_bytes_read = file.read(&mut listing_raw).unwrap(); + + let expected_bytes = b"\ +2020-01-07 19:27:30 1\n"; + + assert_eq!(String::from_utf8(expected_bytes.to_vec()).unwrap(), + String::from_utf8(listing_raw[0..num_bytes_read].to_vec()).unwrap()); +}