Skip to content

Commit

Permalink
add created time to file, address bytes written property check fail
Browse files Browse the repository at this point in the history
Signed-off-by: Brian L. Troutwine <brian.troutwine@datadoghq.com>
  • Loading branch information
blt committed Oct 29, 2024
1 parent 5959f3f commit 41d7d45
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 3 deletions.
3 changes: 2 additions & 1 deletion lading/src/generator/file_gen/logrotate_fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,12 +188,13 @@ fn getattr_helper(
let access_duration = Duration::from_secs(attr.access_tick);
let modified_duration = Duration::from_secs(attr.modified_tick);
let status_duration = Duration::from_secs(attr.status_tick);
let created_duration = Duration::from_secs(attr.created_tick);

// Calculate SystemTime instances
let atime = start_time_system + access_duration;
let mtime = start_time_system + modified_duration;
let ctime = start_time_system + status_duration;
let crtime = start_time_system; // Assume creation time is when the filesystem started
let crtime = start_time_system + created_duration;

FileAttr {
ino: attr.inode as u64,
Expand Down
42 changes: 40 additions & 2 deletions lading/src/generator/file_gen/logrotate_fs/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ pub(crate) struct File {
/// Property: `bytes_written` >= `bytes_read`.
bytes_read: u64,

/// The `Tick` on which the `File` was created.
created_tick: Tick,
/// The `Tick` on which the `File` was last accessed. Updated on reads,
/// opens for reading.
access_tick: Tick,
Expand All @@ -49,6 +51,9 @@ pub(crate) struct File {
/// happen -- or not.
read_only: bool,

/// When the file became read-only. Will only be Some if read_only is false.
read_only_since: Option<Tick>,

/// The peer of this file, the next in line in rotation. So, if this file is
/// foo.log the peer will be foo.log.1 and its peer foo.log.2 etc.
peer: Option<Inode>,
Expand Down Expand Up @@ -176,8 +181,9 @@ impl File {
///
/// This function flips the internal bool on this `File` stopping any future
/// byte accumulations.
pub(crate) fn set_read_only(&mut self) {
pub(crate) fn set_read_only(&mut self, now: Tick) {
self.read_only = true;
self.read_only_since = Some(now);
}

/// Return whether the file is read-only or not
Expand All @@ -204,6 +210,15 @@ impl File {
pub(crate) fn size(&self) -> u64 {
self.bytes_written
}

/// Calculate the expected bytes written based on writable duration.
#[cfg(test)]
pub(crate) fn expected_bytes_written(&self, now: Tick) -> u64 {
let start_tick = self.created_tick;
let end_tick = self.read_only_since.unwrap_or(now);
let writable_duration = end_tick.saturating_sub(start_tick);
self.bytes_per_tick.saturating_mul(writable_duration)
}
}

/// Model representation of a `Directory`. Contains children are `Directory`
Expand Down Expand Up @@ -279,6 +294,8 @@ pub(crate) struct NodeAttributes {
pub(crate) modified_tick: Tick,
/// The last status change time in ticks.
pub(crate) status_tick: Tick,
/// The tick on which the file was created.
pub(crate) created_tick: Tick,
}

/// Describe whether the Node is a File or Directory.
Expand Down Expand Up @@ -430,6 +447,7 @@ impl State {
access_tick: state.now,
modified_tick: state.now,
status_tick: state.now,
created_tick: state.now,
bytes_per_tick,
read_only: false,
ordinal: 0,
Expand All @@ -438,6 +456,7 @@ impl State {
open_handles: 0,
unlinked: false,
max_offset_observed: 0,
read_only_since: None,
};
state.nodes.insert(file_inode, Node::File { file });

Expand Down Expand Up @@ -514,7 +533,7 @@ impl State {
"Expected rotated file to be 0th ordinal, was {ordinal}",
ordinal = file.ordinal()
);
file.set_read_only();
file.set_read_only(now);
Some((
inode,
file.parent,
Expand Down Expand Up @@ -555,6 +574,7 @@ impl State {
access_tick: self.now,
modified_tick: self.now,
status_tick: self.now,
created_tick: self.now,
bytes_per_tick,
read_only: false,
ordinal: 0,
Expand All @@ -563,6 +583,7 @@ impl State {
open_handles: 0,
unlinked: false,
max_offset_observed: 0,
read_only_since: None,
};
new_file.advance_time(now);

Expand Down Expand Up @@ -720,6 +741,7 @@ impl State {
access_tick: file.access_tick,
modified_tick: file.modified_tick,
status_tick: file.status_tick,
created_tick: file.created_tick,
},
Node::Directory { .. } => NodeAttributes {
inode,
Expand All @@ -728,6 +750,7 @@ impl State {
access_tick: self.now,
modified_tick: self.now,
status_tick: self.now,
created_tick: self.now,
},
})
}
Expand Down Expand Up @@ -1112,6 +1135,21 @@ mod test {
}
}
}

// Property 7: bytes_written are tick accurate
for node in state.nodes.values() {
if let Node::File { file } = node {
let expected_bytes = file.expected_bytes_written(state.now);
assert_eq!(
file.bytes_written,
expected_bytes,
"bytes_written ({}) does not match expected_bytes_written ({}) for file with inode {}",
file.bytes_written,
expected_bytes,
file.parent
);
}
}
}

proptest! {
Expand Down

0 comments on commit 41d7d45

Please sign in to comment.