Skip to content

Commit deacbd4

Browse files
authored
Simulate all ticks, not just some (#1075)
### What does this PR do? This commit adjusts the model to simulate every tick between the previous moment time was advanced and the current moment. This avoids errors where files grow well past the size they should -- demonstrated now with an additional model property.
1 parent 063881b commit deacbd4

File tree

1 file changed

+34
-1
lines changed
  • lading/src/generator/file_gen/logrotate_fs

1 file changed

+34
-1
lines changed

lading/src/generator/file_gen/logrotate_fs/model.rs

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -521,8 +521,22 @@ impl State {
521521
/// advance.
522522
pub(crate) fn advance_time(&mut self, now: Tick) {
523523
assert!(now >= self.now);
524-
let mut inodes: Vec<Inode> = self.nodes.keys().copied().collect();
524+
// We have to simulate all ticks that happen between self.now and now,
525+
// else an observer will detect a sudden shift in the model. This is
526+
// still possible by careful observation of the metadata for files
527+
// updating only on tick boundaries, but it's better than shifts only
528+
// when observation happens.
529+
while self.now < now {
530+
self.now += 1;
531+
self.advance_time_inner(self.now);
532+
}
533+
}
525534

535+
#[inline]
536+
fn advance_time_inner(&mut self, now: Tick) {
537+
assert!(now >= self.now);
538+
539+
let mut inodes: Vec<Inode> = self.nodes.keys().copied().collect();
526540
for inode in inodes.drain(..) {
527541
let (rotated_inode, parent_inode, bytes_per_tick, group_id, ordinal) = {
528542
// If the node pointed to by inode doesn't exist, that's a
@@ -1143,6 +1157,25 @@ mod test {
11431157
);
11441158
}
11451159
}
1160+
1161+
// Property 8: max(bytes_written) <= max_bytes_per_file + bytes_per_second
1162+
//
1163+
// If just prior to a rollover the file is within bytes_per_second of
1164+
// max_bytes_per_file on the next tick that the rollover happens the
1165+
// file will be larger than max_bytes_per_file but to a limited degree.
1166+
for node in state.nodes.values() {
1167+
if let Node::File { file } = node {
1168+
if file.unlinked {
1169+
continue;
1170+
}
1171+
let max_size = state.max_bytes_per_file + file.bytes_per_tick;
1172+
assert!(
1173+
file.size() <= max_size,
1174+
"File size {sz} exceeds max allowed size {max_size}",
1175+
sz = file.size()
1176+
);
1177+
}
1178+
}
11461179
}
11471180

11481181
proptest! {

0 commit comments

Comments
 (0)