-
Notifications
You must be signed in to change notification settings - Fork 66
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Engines now return FileMeta with correct millisecond timestamps #565
Changes from 1 commit
c7d41a8
dcc2d49
b3bde76
97e61a6
7103d27
dd71d00
c765eae
64b174f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -51,19 +51,19 @@ impl FileSystemClient for SyncFilesystemClient { | |
.sorted_by_key(|ent| ent.path()) | ||
.map(|ent| { | ||
ent.metadata().map_err(Error::IOError).and_then(|metadata| { | ||
let last_modified: u64 = metadata | ||
let last_modified = metadata | ||
.modified() | ||
.map( | ||
|modified| match modified.duration_since(SystemTime::UNIX_EPOCH) { | ||
Ok(d) => d.as_secs(), | ||
Err(_) => 0, | ||
}, | ||
) | ||
.ok() | ||
.and_then(|modified| { | ||
modified.duration_since(SystemTime::UNIX_EPOCH).ok() | ||
}) | ||
.and_then(|modified| modified.as_millis().try_into().ok()) | ||
.unwrap_or(0); | ||
|
||
Url::from_file_path(ent.path()) | ||
.map(|location| FileMeta { | ||
location, | ||
last_modified: last_modified as i64, | ||
last_modified, | ||
size: metadata.len() as usize, | ||
}) | ||
.map_err(|_| Error::Generic(format!("Invalid path: {:?}", ent.path()))) | ||
|
@@ -97,20 +97,53 @@ impl FileSystemClient for SyncFilesystemClient { | |
|
||
#[cfg(test)] | ||
mod tests { | ||
use std::fs::File; | ||
use std::io::Write; | ||
use std::os::unix::fs::MetadataExt; | ||
use std::{fs::File, time::UNIX_EPOCH}; | ||
|
||
use bytes::{BufMut, BytesMut}; | ||
use itertools::Itertools; | ||
use url::Url; | ||
|
||
use super::SyncFilesystemClient; | ||
use crate::FileSystemClient; | ||
use crate::{FileMeta, FileSystemClient}; | ||
|
||
/// generate json filenames that follow the spec (numbered padded to 20 chars) | ||
fn get_json_filename(index: usize) -> String { | ||
format!("{index:020}.json") | ||
} | ||
|
||
#[test] | ||
fn test_file_meta_is_correct() -> Result<(), Box<dyn std::error::Error>> { | ||
let client = SyncFilesystemClient; | ||
let tmp_dir = tempfile::tempdir().unwrap(); | ||
|
||
let path = tmp_dir.path().join(get_json_filename(1)); | ||
let mut f = File::create(path)?; | ||
writeln!(f, "null")?; | ||
|
||
let url_path = tmp_dir.path().join(get_json_filename(1)); | ||
let url = Url::from_file_path(url_path).unwrap(); | ||
let list: Vec<_> = client.list_from(&url)?.try_collect()?; | ||
|
||
let metadata = f.metadata()?; | ||
// We assert that the timestamp is in milliseconds | ||
let expected_timestamp = metadata | ||
.modified()? | ||
.duration_since(UNIX_EPOCH)? | ||
.as_millis() | ||
.try_into()?; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the exact same code the iterator uses... so it's not actually testing for correctness but rather testing that the code is equivalent. Not sure what the better test would be? Maybe we write a file and manually set its mtime, then verify the FileMeta has the same timestamp? (same criticism applies to the default client test) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maybe create the file then just assert that the timestamp we get back is within 10s or 60s or something? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Implemented a test that checks that the filemeta is from the last minute. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. seems good for now :) |
||
let expected_size = metadata.size().try_into()?; | ||
let expected_file_meta = FileMeta { | ||
location: url, | ||
last_modified: expected_timestamp, | ||
size: expected_size, | ||
}; | ||
|
||
assert_eq!(list, vec![expected_file_meta]); | ||
Ok(()) | ||
} | ||
|
||
#[test] | ||
fn test_list_from() -> Result<(), Box<dyn std::error::Error>> { | ||
let client = SyncFilesystemClient; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are we converting Result to Option three times here? Why is that needed?
Or do types not match in some annoying way?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Honestly, all this monadic chaining feels like a poor substitute for a missing helper method...
and then
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Woah that's clean 👌 I'm doing a lot of map_err, and I'm wondering if we should do
From
conversions for common things likeUrl::from_*
andTryInto
🤔There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yea seems reasonable? make an issue for us to think about?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We already have the
From
conversion forurl::ParseError
, so?
should Just Work? The problem withTryInto
is the error type is parametrized, so there's no way to know in advance what might be needed. We'd have to go case by case (when in doubt, try?
and hopefully there's already animpl From
for it to use).