#[cfg(not(debug_assertions))]
use super::deflate::MAX_STORE_BLOCK_SIZE;
use crate::bytes;
use crate::compress::flate;
use crate::io as ggio;
#[cfg(not(debug_assertions))]
use crate::time;
use std::io::Write;
#[derive(Debug)]
struct ErrorWriter {
n: usize,
}
impl std::io::Write for ErrorWriter {
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
if self.n == 0 {
return Err(std::io::Error::new(
std::io::ErrorKind::BrokenPipe,
"intentional error",
));
}
self.n -= 1;
Ok(buf.len())
}
fn flush(&mut self) -> std::io::Result<()> {
Ok(())
}
}
#[test]
fn test_write_error() {
let mut buf = bytes::Buffer::new();
let n = 65536;
for i in 0..n {
let str = format!("asdasfasf{}{}fghfgujyut{}yutyu\n", i, i, i);
buf.write_string(&str).unwrap();
}
let input = buf.bytes();
let mut copy_buffer = vec![0; 128];
for l in 0..10 {
let mut fail = 1;
while fail <= 32 {
let mut ew = ErrorWriter { n: fail };
let mut eww: &mut dyn std::io::Write = &mut ew;
let mut w = flate::Writer::new(&mut eww, l).unwrap();
let mut reader = bytes::Reader::new(input);
let (_n, err) = ggio::copy_buffer(&mut w, &mut reader, Some(&mut copy_buffer));
assert!(
err.is_some(),
"Level {}: Expected an error, writer was {:?}",
l,
ew
);
let res = w.write(&[1, 2, 2, 3, 4, 5]);
assert!(res.is_err(), "Level {}, Expected an error", l);
let res = w.flush();
assert!(res.is_err(), "Level {}, Expected an error on flush", l);
let res = w.close();
assert!(res.is_err(), "Level {}, Expected an error on close", l);
let mut discard_writer = ggio::Discard::new();
let mut dw: &mut dyn std::io::Write = &mut discard_writer;
w.reset(&mut dw);
let res = w.write(&[1, 2, 3, 4, 5, 6]);
assert!(
res.as_ref().is_ok() && *res.as_ref().unwrap() == 6,
"Level {}, Got unexpected error after reset: {:?}",
l,
res
);
fail *= 2;
}
}
}
#[test]
#[cfg(not(debug_assertions))]
fn test_deterministic() {
for level in 0..=9 {
test_deterministic_int(level);
}
test_deterministic_int(-2);
}
#[cfg(not(debug_assertions))]
fn test_deterministic_int(level: isize) {
let length = MAX_STORE_BLOCK_SIZE * 30 + 500;
let mut t1 = vec![0; length];
for i in 0..length {
t1[i] = (time::now().nanosecond() / 100) as u8 & 7;
}
let mut b1 = bytes::Buffer::new();
{
let mut br = bytes::new_buffer(t1.clone());
let mut w = flate::Writer::new(&mut b1, level).unwrap();
let mut cbuf = vec![0; 787];
let (_, err) = ggio::copy_buffer(&mut w, &mut br, Some(&mut cbuf));
assert!(err.is_none());
w.close().unwrap();
}
let mut b2 = bytes::Buffer::new();
{
let mut br = bytes::new_buffer(t1.clone());
let mut w = flate::Writer::new(&mut b2, level).unwrap();
let mut cbuf = vec![0; 81761];
let (_, err) = ggio::copy_buffer(&mut w, &mut br, Some(&mut cbuf));
assert!(err.is_none());
w.close().unwrap();
}
let b1b = b1.bytes();
let b2b = b2.bytes();
if b1b != b2b {
assert!(
false,
"level {} did not produce deterministic result, result mismatch, len(a) = {}, b.len() = {}",
level,
b1b.len(),
b2b.len()
);
}
}