use byteorder::{BigEndian, ByteOrder, LittleEndian};
use idb::binlog::correlate::{correlate_events, RowEventType};
use idb::binlog::BinlogFile;
use idb::innodb::tablespace::Tablespace;
fn make_minimal_tablespace() -> Vec<u8> {
let page_size = 16384usize;
let mut buf = vec![0u8; page_size];
BigEndian::write_u32(&mut buf[4..], 0); BigEndian::write_u16(&mut buf[24..], 8); BigEndian::write_u32(&mut buf[34..], 1);
BigEndian::write_u32(&mut buf[54..], 0);
BigEndian::write_u32(&mut buf[page_size - 4..], 0);
let crc1 = crc32c::crc32c(&buf[4..26]);
let crc2 = crc32c::crc32c(&buf[38..page_size - 8]);
let checksum = crc1 ^ crc2;
BigEndian::write_u32(&mut buf[0..], checksum);
buf
}
fn make_minimal_binlog() -> Vec<u8> {
let mut buf = Vec::new();
buf.extend_from_slice(&[0xfe, 0x62, 0x69, 0x6e]);
let fde_data_len = 57; let event_len = 19 + fde_data_len;
let mut header = vec![0u8; 19];
LittleEndian::write_u32(&mut header[0..], 1_700_000_000); header[4] = 15; LittleEndian::write_u32(&mut header[5..], 1); LittleEndian::write_u32(&mut header[9..], event_len as u32); LittleEndian::write_u32(&mut header[13..], (4 + event_len) as u32); LittleEndian::write_u16(&mut header[17..], 0); buf.extend_from_slice(&header);
let mut fde = vec![0u8; fde_data_len];
LittleEndian::write_u16(&mut fde[0..], 4); fde[2..8].copy_from_slice(b"8.0.35");
LittleEndian::write_u32(&mut fde[52..], 1_700_000_000); fde[56] = 19; buf.extend_from_slice(&fde);
buf
}
#[test]
fn correlate_events_returns_empty_for_no_sdi() {
let ts_data = make_minimal_tablespace();
let binlog_data = make_minimal_binlog();
let mut ts = Tablespace::from_bytes(ts_data).unwrap();
let mut binlog = BinlogFile::from_bytes(binlog_data).unwrap();
let result = correlate_events(&mut binlog, &mut ts).unwrap();
assert!(
result.is_empty(),
"Expected empty results for tablespace without SDI"
);
}
#[test]
fn row_event_type_variants() {
assert_eq!(RowEventType::from_type_code(30), Some(RowEventType::Insert));
assert_eq!(RowEventType::from_type_code(31), Some(RowEventType::Update));
assert_eq!(RowEventType::from_type_code(32), Some(RowEventType::Delete));
assert_eq!(RowEventType::from_type_code(15), None);
assert_eq!(format!("{}", RowEventType::Insert), "INSERT");
assert_eq!(format!("{}", RowEventType::Update), "UPDATE");
assert_eq!(format!("{}", RowEventType::Delete), "DELETE");
}