use super::*;
use rand::{thread_rng, Rng};
use std::{collections::BTreeMap, fs, io::prelude::*, time};
const DATA: &[u8] = b"some_ssidthe_password";
const ENCODED: &[u8] =
b"some_ssidthe_password\x00\x00\x00\x00]\xd8\x94\xea\x91\x1bGU\xff+\x882[\xa6\xd3";
#[test]
fn encoder_5_8_test() {
encoder_test(5, 8);
}
fn encoder_test(k: usize, m: usize) {
let fec = Fec::new(k, m).unwrap();
let (mut encoded_chunks, _) = fec.encode(&DATA.to_vec()).unwrap();
let mut encoded = vec![];
for chunk in &mut encoded_chunks {
encoded.append(&mut chunk.data);
}
assert_eq!(encoded, ENCODED);
}
#[test]
fn decoder_5_8_test() {
decoder_test(5, 8);
}
#[test]
fn decoder_extensive() {
for m in 2..20 {
for k in 1..m - 1 {
decoder_test(k, m);
}
}
}
fn decoder_test(k: usize, m: usize) {
let mut fec = Fec::new(k, m).unwrap();
let (chunks, padding) = fec.encode(&DATA).unwrap();
let decoded = fec.decode(&chunks, padding).unwrap();
assert_eq!(
decoded,
DATA.to_vec(),
"Failed to decode from complete k: {}, m: {} encoded message",
k,
m
);
for i in 0..m {
let mut broken_enc = chunks.clone();
broken_enc.remove(i);
let decoded = fec.decode(&broken_enc, padding).unwrap();
assert_eq!(
decoded,
DATA.to_vec(),
"Failed to decode while missing {}th block",
i,
);
}
let max_missing = m - k;
let mut rng = rand::thread_rng();
for _ in 0..20 {
for n in 1..=max_missing {
let mut broken_enc = chunks.clone();
for _ in 0..n {
let keys = &broken_enc
.iter()
.map(|chunk| chunk.index)
.collect::<Vec<usize>>()[..];
let index = rng.gen_range(0..keys.len());
let _ = broken_enc.remove(index);
}
let decoded = fec.decode(&broken_enc, padding).unwrap();
assert_eq!(
decoded,
DATA.to_vec(),
"Failed to decode from k: {}, m: {} encoded message with {} missing chunks",
k,
m,
n
);
}
}
}