changeset 286:900210e7d0b0

log: Implement LogWriter::new_with_off() and add tests.
author Lewin Bormann <lbo@spheniscida.de>
date Mon, 25 Sep 2017 20:32:47 +0200
parents b176afa0f765
children b71f43585267
files src/log.rs
diffstat 1 files changed, 49 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/src/log.rs	Mon Sep 25 20:32:16 2017 +0200
+++ b/src/log.rs	Mon Sep 25 20:32:47 2017 +0200
@@ -40,6 +40,14 @@
         }
     }
 
+    /// new_with_off opens a writer starting at some offset of an existing log file. The file must
+    /// have the default block size.
+    pub fn new_with_off(writer: W, off: usize) -> LogWriter<W> {
+        let mut w = LogWriter::new(writer);
+        w.current_block_offset = off % BLOCK_SIZE;
+        w
+    }
+
     pub fn add_record(&mut self, r: &[u8]) -> Result<usize> {
         let mut record = &r[..];
         let mut first_frag = true;
@@ -118,10 +126,10 @@
 }
 
 impl<R: Read> LogReader<R> {
-    pub fn new(src: R, chksum: bool, offset: usize) -> LogReader<R> {
+    pub fn new(src: R, chksum: bool) -> LogReader<R> {
         LogReader {
             src: src,
-            blk_off: offset,
+            blk_off: 0,
             blocksize: BLOCK_SIZE,
             checksums: chksum,
             head_scratch: [0; 7],
@@ -165,7 +173,7 @@
 
             if self.checksums &&
                !self.check_integrity(typ, &dst[dst_offset..dst_offset + bytes_read], checksum) {
-                return err(StatusCode::InvalidData, "Invalid Checksum");
+                return err(StatusCode::Corruption, "Invalid Checksum");
             }
 
             dst_offset += length as usize;
@@ -193,16 +201,49 @@
 #[cfg(test)]
 mod tests {
     use super::*;
+    use std::io::Cursor;
 
     #[test]
     fn test_writer() {
-        let data = &"hello world. My first log entry.".as_bytes().to_vec();
+        let data = &["hello world. My first log entry.", "and my second", "and my third"];
         let mut lw = LogWriter::new(Vec::new());
+        let total_len = data.iter().fold(0, |l, d| l + d.len());
+
+        for d in data {
+            let _ = lw.add_record(d.as_bytes());
+        }
+
+        assert_eq!(lw.current_block_offset, total_len + 3 * super::HEADER_SIZE);
+    }
+
+    #[test]
+    fn test_writer_append() {
+        let data = &["hello world. My first log entry.", "and my second", "and my third"];
+
+        let mut dst = Vec::new();
+        dst.resize(1024, 0 as u8);
 
-        let _ = lw.add_record(&data);
+        {
+            let mut lw = LogWriter::new(Cursor::new(dst.as_mut_slice()));
+            for d in data {
+                let _ = lw.add_record(d.as_bytes());
+            }
+        }
+
+        let old = dst.clone();
 
-        assert_eq!(lw.current_block_offset, data.len() + super::HEADER_SIZE);
-        assert_eq!(&lw.dst[super::HEADER_SIZE..], data.as_slice());
+        // Ensure that new_with_off positions the writer correctly. Some ugly mucking about with
+        // cursors and stuff is required.
+        {
+            let offset = data[0].len() + super::HEADER_SIZE;
+            let mut lw = LogWriter::new_with_off(Cursor::new(&mut dst.as_mut_slice()[offset..]),
+                                                 offset);
+            for d in &data[1..] {
+                let _ = lw.add_record(d.as_bytes());
+            }
+        }
+        assert_eq!(old, dst);
+
     }
 
     #[test]
@@ -219,7 +260,7 @@
 
         assert_eq!(lw.dst.len(), 93);
 
-        let mut lr = LogReader::new(lw.dst.as_slice(), true, 0);
+        let mut lr = LogReader::new(lw.dst.as_slice(), true);
         lr.blocksize = super::HEADER_SIZE + 10;
         let mut dst = Vec::with_capacity(128);
         let mut i = 0;