Skip to content

Commit 4ccfe2e

Browse files
author
Roderick Bovee
committed
Improve error messaging and move tests into their own modules
1 parent 1742586 commit 4ccfe2e

File tree

2 files changed

+187
-174
lines changed

2 files changed

+187
-174
lines changed

src/bloom.rs

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -98,17 +98,19 @@ impl BloomFilter {
9898
}
9999
}
100100

101+
#[cfg(test)]
102+
mod test {
103+
#[test]
104+
fn test_bloom_filter() {
105+
use std::fs::remove_file;
106+
let mut filter = BloomFilter::new(Some("./test_bloom"), 100, 2).unwrap();
107+
let (a, b) = (1, 2);
108+
assert!(!filter.contains(a));
109+
assert!(!filter.contains(b));
110+
filter.insert(b);
111+
assert!(!filter.contains(a));
112+
assert!(filter.contains(b));
101113

102-
#[test]
103-
fn test_bloom_filter() {
104-
use std::fs::remove_file;
105-
let mut filter = BloomFilter::new(Some("./test_bloom"), 100, 2).unwrap();
106-
let (a, b) = (1, 2);
107-
assert!(!filter.contains(a));
108-
assert!(!filter.contains(b));
109-
filter.insert(b);
110-
assert!(!filter.contains(a));
111-
assert!(filter.contains(b));
112-
113-
remove_file("./test_bloom").unwrap();
114+
remove_file("./test_bloom").unwrap();
115+
}
114116
}

src/mmap_bitvec.rs

Lines changed: 173 additions & 162 deletions
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,10 @@ impl MmapBitVec {
8383
where
8484
P: AsRef<Path>,
8585
{
86-
// TODO: at some point remove `readonly` from the interface (since we use
87-
// MmapMut for everything)
88-
let mut file = OpenOptions::new().read(true).write(true).open(filename)?;
86+
let mut file = OpenOptions::new()
87+
.read(true)
88+
.write(!readonly)
89+
.open(filename)?;
8990

9091
// read the magic bytes and (optionally) check if it matches
9192
let mut file_magic = [0; 2];
@@ -94,7 +95,10 @@ impl MmapBitVec {
9495
if &file_magic != m {
9596
return Err(io::Error::new(
9697
io::ErrorKind::InvalidData,
97-
"file not long enough",
98+
format!(
99+
"file has wrong magic bytes {:x?} (expected {:x?})",
100+
file_magic, m
101+
),
98102
));
99103
}
100104
}
@@ -117,7 +121,12 @@ impl MmapBitVec {
117121
if file.metadata()?.len() != total_header_size as u64 + byte_size {
118122
return Err(io::Error::new(
119123
io::ErrorKind::InvalidData,
120-
"file not long enough",
124+
format!(
125+
"file should be {} bytes (with {} header), but file is {} bytes",
126+
byte_size + total_header_size as u64,
127+
total_header_size,
128+
file.metadata()?.len(),
129+
),
121130
));
122131
}
123132

@@ -600,166 +609,168 @@ fn order_byte(b: u8) -> u8 {
600609
BACKWARDS[b as usize]
601610
}
602611

612+
#[cfg(test)]
613+
mod test {
614+
#[test]
615+
fn test_bitvec() {
616+
use std::fs::remove_file;
617+
618+
let header = vec![];
619+
let mut b = MmapBitVec::create("./test", 100, b"!!", &header).unwrap();
620+
b.set(2, true);
621+
assert!(!b.get(1));
622+
assert!(b.get(2));
623+
assert!(!b.get(100));
624+
drop(b);
625+
assert!(Path::new("./test").exists());
626+
627+
let b = MmapBitVec::open("./test", Some(b"!!"), true).unwrap();
628+
assert!(!b.get(1));
629+
assert!(b.get(2));
630+
assert!(!b.get(100));
631+
632+
remove_file("./test").unwrap();
633+
}
603634

604-
#[test]
605-
fn test_bitvec() {
606-
use std::fs::remove_file;
607-
608-
let header = vec![];
609-
let mut b = MmapBitVec::create("./test", 100, b"!!", &header).unwrap();
610-
b.set(2, true);
611-
assert!(!b.get(1));
612-
assert!(b.get(2));
613-
assert!(!b.get(100));
614-
drop(b);
615-
assert!(Path::new("./test").exists());
616-
617-
let b = MmapBitVec::open("./test", Some(b"!!"), true).unwrap();
618-
assert!(!b.get(1));
619-
assert!(b.get(2));
620-
assert!(!b.get(100));
621-
622-
remove_file("./test").unwrap();
623-
}
624-
625-
#[test]
626-
fn test_open_no_header() {
627-
use std::fs::remove_file;
628-
629-
let header = vec![];
630-
// the bitvector has to be a size with a multiple of 8 because the
631-
// no_header code always opens to the end of the last byte
632-
let _ = MmapBitVec::create("./test_headerless", 80, b"!!", &header).unwrap();
633-
assert!(Path::new("./test_headerless").exists());
634-
let b = MmapBitVec::open_no_header("./test_headerless", 12).unwrap();
635-
assert_eq!(b.size(), 80);
636-
remove_file("./test_headerless").unwrap();
637-
}
635+
#[test]
636+
fn test_open_no_header() {
637+
use std::fs::remove_file;
638+
639+
let header = vec![];
640+
// the bitvector has to be a size with a multiple of 8 because the
641+
// no_header code always opens to the end of the last byte
642+
let _ = MmapBitVec::create("./test_headerless", 80, b"!!", &header).unwrap();
643+
assert!(Path::new("./test_headerless").exists());
644+
let b = MmapBitVec::open_no_header("./test_headerless", 12).unwrap();
645+
assert_eq!(b.size(), 80);
646+
remove_file("./test_headerless").unwrap();
647+
}
638648

639-
#[test]
640-
fn test_bitvec_get_range() {
641-
let mut b = MmapBitVec::from_memory(128).unwrap();
642-
b.set(2, true);
643-
b.set(3, true);
644-
b.set(5, true);
645-
assert_eq!(b.get_range(0..8), 52, "indexing within a single byte");
646-
assert_eq!(b.get_range(0..16), 13312, "indexing multiple bytes");
647-
assert_eq!(
648-
b.get_range(0..64),
649-
3_746_994_889_972_252_672,
650-
"indexing the maximum # of bytes"
651-
);
652-
assert_eq!(
653-
b.get_range(64..128),
654-
0,
655-
"indexing the maximum # of bytes to the end"
656-
);
657-
assert_eq!(b.get_range(2..10), 208, "indexing across bytes");
658-
assert_eq!(
659-
b.get_range(2..66),
660-
14_987_979_559_889_010_688,
661-
"indexing the maximum # of bytes across bytes"
662-
);
663-
assert_eq!(b.get_range(115..128), 0, "indexing across bytes to the end");
664-
}
649+
#[test]
650+
fn test_bitvec_get_range() {
651+
let mut b = MmapBitVec::from_memory(128).unwrap();
652+
b.set(2, true);
653+
b.set(3, true);
654+
b.set(5, true);
655+
assert_eq!(b.get_range(0..8), 52, "indexing within a single byte");
656+
assert_eq!(b.get_range(0..16), 13312, "indexing multiple bytes");
657+
assert_eq!(
658+
b.get_range(0..64),
659+
3_746_994_889_972_252_672,
660+
"indexing the maximum # of bytes"
661+
);
662+
assert_eq!(
663+
b.get_range(64..128),
664+
0,
665+
"indexing the maximum # of bytes to the end"
666+
);
667+
assert_eq!(b.get_range(2..10), 208, "indexing across bytes");
668+
assert_eq!(
669+
b.get_range(2..66),
670+
14_987_979_559_889_010_688,
671+
"indexing the maximum # of bytes across bytes"
672+
);
673+
assert_eq!(b.get_range(115..128), 0, "indexing across bytes to the end");
674+
}
665675

666-
#[test]
667-
fn test_bitvec_get_range_bytes() {
668-
let mut b = MmapBitVec::from_memory(128).unwrap();
669-
b.set(2, true);
670-
b.set(3, true);
671-
b.set(5, true);
672-
assert_eq!(
673-
b.get_range_bytes(0..8),
674-
&[0x34],
675-
"indexing within a single byte"
676-
);
677-
assert_eq!(
678-
b.get_range_bytes(0..16),
679-
&[0x34, 0x00],
680-
"indexing multiple bytes"
681-
);
682-
assert_eq!(
683-
b.get_range_bytes(0..64),
684-
&[0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
685-
"indexing the maximum # of bytes"
686-
);
687-
assert_eq!(
688-
b.get_range_bytes(64..128),
689-
&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
690-
"indexing the maximum # of bytes to the end"
691-
);
692-
assert_eq!(b.get_range_bytes(2..10), &[0xD0], "indexing across bytes");
693-
assert_eq!(
694-
b.get_range_bytes(2..66),
695-
&[0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
696-
"indexing the maximum # of bytes across bytes"
697-
);
698-
assert_eq!(
699-
b.get_range_bytes(115..128),
700-
&[0x00, 0x00],
701-
"indexing across bytes to the end"
702-
);
703-
}
676+
#[test]
677+
fn test_bitvec_get_range_bytes() {
678+
let mut b = MmapBitVec::from_memory(128).unwrap();
679+
b.set(2, true);
680+
b.set(3, true);
681+
b.set(5, true);
682+
assert_eq!(
683+
b.get_range_bytes(0..8),
684+
&[0x34],
685+
"indexing within a single byte"
686+
);
687+
assert_eq!(
688+
b.get_range_bytes(0..16),
689+
&[0x34, 0x00],
690+
"indexing multiple bytes"
691+
);
692+
assert_eq!(
693+
b.get_range_bytes(0..64),
694+
&[0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
695+
"indexing the maximum # of bytes"
696+
);
697+
assert_eq!(
698+
b.get_range_bytes(64..128),
699+
&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
700+
"indexing the maximum # of bytes to the end"
701+
);
702+
assert_eq!(b.get_range_bytes(2..10), &[0xD0], "indexing across bytes");
703+
assert_eq!(
704+
b.get_range_bytes(2..66),
705+
&[0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
706+
"indexing the maximum # of bytes across bytes"
707+
);
708+
assert_eq!(
709+
b.get_range_bytes(115..128),
710+
&[0x00, 0x00],
711+
"indexing across bytes to the end"
712+
);
713+
}
704714

705-
#[test]
706-
fn test_bitvec_set_range() {
707-
let mut b = MmapBitVec::from_memory(128).unwrap();
708-
b.set_range(0..4, 0b0101);
709-
assert_eq!(b.get_range(0..4), 0b0101);
710-
b.set_range(5..8, 0b0101);
711-
assert_eq!(b.get_range(5..8), 0b0101);
712-
b.set_range(123..127, 0b0101);
713-
assert_eq!(b.get_range(123..127), 0b0101);
714-
715-
// test across a byte boundary
716-
b.set_range(6..9, 0b111);
717-
assert_eq!(b.get_range(6..9), 0b111);
718-
719-
// test zeroing works on both sides of a byte boundary
720-
b.set_range(0..16, 0xFFFF);
721-
assert_eq!(b.get_range(0..16), 0xFFFF);
722-
b.clear_range(4..12);
723-
assert_eq!(b.get_range(0..16), 0xF00F);
724-
725-
// test setting multiple bytes (and that overflow doesn't happen)
726-
b.set_range(20..36, 0xFFFF);
727-
assert_eq!(b.get_range(16..20), 0x0);
728-
assert_eq!(b.get_range(20..36), 0xFFFF);
729-
assert_eq!(b.get_range(36..44), 0x0);
730-
731-
// set an entire range
732-
assert_eq!(b.get_range(39..103), 0x0);
733-
b.set_range(39..103, 0xABCD1234);
734-
assert_eq!(b.get_range(39..103), 0xABCD1234);
735-
}
715+
#[test]
716+
fn test_bitvec_set_range() {
717+
let mut b = MmapBitVec::from_memory(128).unwrap();
718+
b.set_range(0..4, 0b0101);
719+
assert_eq!(b.get_range(0..4), 0b0101);
720+
b.set_range(5..8, 0b0101);
721+
assert_eq!(b.get_range(5..8), 0b0101);
722+
b.set_range(123..127, 0b0101);
723+
assert_eq!(b.get_range(123..127), 0b0101);
724+
725+
// test across a byte boundary
726+
b.set_range(6..9, 0b111);
727+
assert_eq!(b.get_range(6..9), 0b111);
728+
729+
// test zeroing works on both sides of a byte boundary
730+
b.set_range(0..16, 0xFFFF);
731+
assert_eq!(b.get_range(0..16), 0xFFFF);
732+
b.clear_range(4..12);
733+
assert_eq!(b.get_range(0..16), 0xF00F);
734+
735+
// test setting multiple bytes (and that overflow doesn't happen)
736+
b.set_range(20..36, 0xFFFF);
737+
assert_eq!(b.get_range(16..20), 0x0);
738+
assert_eq!(b.get_range(20..36), 0xFFFF);
739+
assert_eq!(b.get_range(36..44), 0x0);
740+
741+
// set an entire range
742+
assert_eq!(b.get_range(39..103), 0x0);
743+
b.set_range(39..103, 0xABCD1234);
744+
assert_eq!(b.get_range(39..103), 0xABCD1234);
745+
}
736746

737-
#[test]
738-
fn test_bitvec_set_range_bytes() {
739-
let mut b = MmapBitVec::from_memory(128).unwrap();
740-
b.set_range_bytes(0..4, &[0x05]);
741-
assert_eq!(b.get_range(0..4), 0b0101);
742-
b.set_range_bytes(5..8, &[0x05]);
743-
assert_eq!(b.get_range(5..8), 0b0101);
744-
745-
// clear the first part
746-
b.clear_range(0..16);
747-
748-
// test across a byte boundary
749-
b.set_range_bytes(6..10, &[0x0D]);
750-
assert_eq!(b.get_range(6..10), 0x0D);
751-
752-
// test setting multiple bytes
753-
b.set_range_bytes(0..16, &[0xFF, 0xFF]);
754-
assert_eq!(b.get_range(0..16), 0xFFFF);
755-
756-
// test setting multiple bytes across boundaries
757-
b.set_range_bytes(20..36, &[0xFF, 0xFF]);
758-
assert_eq!(b.get_range(20..36), 0xFFFF);
759-
760-
// testing ORing works
761-
b.set_range_bytes(64..80, &[0xA0, 0x0A]);
762-
assert_eq!(b.get_range(64..80), 0xA00A);
763-
b.set_range_bytes(64..80, &[0x0B, 0xB0]);
764-
assert_eq!(b.get_range(64..80), 0xABBA);
747+
#[test]
748+
fn test_bitvec_set_range_bytes() {
749+
let mut b = MmapBitVec::from_memory(128).unwrap();
750+
b.set_range_bytes(0..4, &[0x05]);
751+
assert_eq!(b.get_range(0..4), 0b0101);
752+
b.set_range_bytes(5..8, &[0x05]);
753+
assert_eq!(b.get_range(5..8), 0b0101);
754+
755+
// clear the first part
756+
b.clear_range(0..16);
757+
758+
// test across a byte boundary
759+
b.set_range_bytes(6..10, &[0x0D]);
760+
assert_eq!(b.get_range(6..10), 0x0D);
761+
762+
// test setting multiple bytes
763+
b.set_range_bytes(0..16, &[0xFF, 0xFF]);
764+
assert_eq!(b.get_range(0..16), 0xFFFF);
765+
766+
// test setting multiple bytes across boundaries
767+
b.set_range_bytes(20..36, &[0xFF, 0xFF]);
768+
assert_eq!(b.get_range(20..36), 0xFFFF);
769+
770+
// testing ORing works
771+
b.set_range_bytes(64..80, &[0xA0, 0x0A]);
772+
assert_eq!(b.get_range(64..80), 0xA00A);
773+
b.set_range_bytes(64..80, &[0x0B, 0xB0]);
774+
assert_eq!(b.get_range(64..80), 0xABBA);
775+
}
765776
}

0 commit comments

Comments
 (0)