use super::*;
const MAX: u64 = u32::MAX as u64;
fn restored_log(family: LogFamily, total: u32, values: &[u64], added: &[u64]) -> ObjectDatabase {
let mut db = ObjectDatabase::new();
match family {
LogFamily::Trend => {
let mut log = TrendLogObject::new(1, "TL-1", 10).unwrap();
log.restore_log_buffer(total, values.iter().copied().map(record))
.unwrap();
for &value in added {
log.add_record(record(value)).unwrap();
}
db.add(Box::new(log)).unwrap();
}
LogFamily::Event => {
let mut log = EventLogObject::new(1, "EL-1", 10).unwrap();
log.restore_log_buffer(total, values.iter().copied().map(event_record))
.unwrap();
for &value in added {
log.add_record(event_record(value)).unwrap();
}
db.add(Box::new(log)).unwrap();
}
LogFamily::TrendMultiple => {
let mut log = TrendLogMultipleObject::new(1, "TLM-1", 10).unwrap();
log.restore_log_buffer(total, values.iter().copied().map(multiple_record))
.unwrap();
for &value in added {
log.add_record(multiple_record(value)).unwrap();
}
db.add(Box::new(log)).unwrap();
}
}
db
}
fn oid(family: LogFamily) -> ObjectIdentifier {
let object_type = match family {
LogFamily::Trend => ObjectType::TREND_LOG,
LogFamily::Event => ObjectType::EVENT_LOG,
LogFamily::TrendMultiple => ObjectType::TREND_LOG_MULTIPLE,
};
ObjectIdentifier::new(object_type, 1).unwrap()
}
fn read(db: &ObjectDatabase, family: LogFamily, range: RangeSpec) -> ReadRangeAck {
call(db, oid(family), PropertyIdentifier::LOG_BUFFER, Some(range)).unwrap()
}
fn by_sequence(reference_seq: u64, count: i32) -> RangeSpec {
RangeSpec::BySequenceNumber {
reference_seq,
count,
}
}
fn items(family: LogFamily, values: &[u64]) -> Vec<PropertyValue> {
values
.iter()
.map(|&value| projected(family, value))
.collect()
}
const FAMILIES: [LogFamily; 3] = [LogFamily::Trend, LogFamily::Event, LogFamily::TrendMultiple];
#[test]
fn a_count_seeded_near_the_wrap_pages_across_it_by_sequence() {
for family in FAMILIES {
let db = restored_log(family, u32::MAX - 2, &[], &[1, 2, 3, 4, 5]);
let ack = read(&db, family, by_sequence(MAX, 3));
assert_ack(
&ack,
&items(family, &[2, 3, 4]),
(false, false, false),
Some(MAX),
);
let back = read(&db, family, by_sequence(2, -3));
assert_ack(
&back,
&items(family, &[2, 3, 4]),
(false, false, false),
Some(MAX),
);
let all = read(&db, family, by_sequence(MAX - 1, 10));
assert_ack(
&all,
&items(family, &[1, 2, 3, 4, 5]),
(true, true, false),
Some(MAX - 1),
);
let next = read(&db, family, by_sequence(1, 2));
assert_ack(
&next,
&items(family, &[3, 4]),
(false, false, false),
Some(1),
);
let by_time = read(
&db,
family,
RangeSpec::ByTime {
reference_time: (DATE, time(2)),
count: 2,
},
);
assert_ack(
&by_time,
&items(family, &[3, 4]),
(false, false, false),
Some(1),
);
}
}
#[test]
fn restored_records_that_straddle_the_wrap_page_by_sequence() {
for family in FAMILIES {
let db = restored_log(family, 1, &[1, 2, 3], &[4]);
let ack = read(&db, family, by_sequence(MAX, -2));
assert_ack(
&ack,
&items(family, &[1, 2]),
(true, false, false),
Some(MAX - 1),
);
let tail = read(&db, family, by_sequence(1, 5));
assert_ack(
&tail,
&items(family, &[3, 4]),
(false, true, false),
Some(1),
);
let gone = read(&db, family, by_sequence(MAX - 2, 1));
assert_ack(&gone, &[], (false, false, false), None);
}
}