|
@@ -72,8 +72,8 @@ async fn main() {
|
|
|
mod tests {
|
|
|
use super::*;
|
|
|
|
|
|
- use btlib::log::BuilderExt;
|
|
|
use btfproto::{client::FsClient, msg::*};
|
|
|
+ use btlib::{log::BuilderExt, BlockMetaSecrets, Epoch};
|
|
|
use btlib_tests::TpmCredStoreHarness;
|
|
|
use btmsg::Transmitter;
|
|
|
use std::{future::ready, net::Ipv4Addr};
|
|
@@ -199,7 +199,10 @@ mod tests {
|
|
|
client.flush(inode, handle).await.unwrap();
|
|
|
let case = existing_case(case).await;
|
|
|
let client = &case.client;
|
|
|
- let LookupReply { inode, .. } = client.lookup(SpecInodes::RootDir.into(), FILENAME).await.unwrap();
|
|
|
+ let LookupReply { inode, .. } = client
|
|
|
+ .lookup(SpecInodes::RootDir.into(), FILENAME)
|
|
|
+ .await
|
|
|
+ .unwrap();
|
|
|
let OpenReply { handle, .. } = client
|
|
|
.open(inode, FlagValue::ReadOnly.into())
|
|
|
.await
|
|
@@ -333,7 +336,10 @@ mod tests {
|
|
|
handle: root_handle,
|
|
|
..
|
|
|
} = client
|
|
|
- .open(SpecInodes::RootDir.into(), FlagValue::ReadOnly | FlagValue::Directory)
|
|
|
+ .open(
|
|
|
+ SpecInodes::RootDir.into(),
|
|
|
+ FlagValue::ReadOnly | FlagValue::Directory,
|
|
|
+ )
|
|
|
.await
|
|
|
.unwrap();
|
|
|
let ReadDirReply { entries, .. } = client
|
|
@@ -345,4 +351,169 @@ mod tests {
|
|
|
assert!(filenames.contains(&FIRSTNAME));
|
|
|
assert!(filenames.contains(&LASTNAME));
|
|
|
}
|
|
|
+
|
|
|
+ #[tokio::test]
|
|
|
+ async fn unlink() {
|
|
|
+ const FIRSTNAME: &str = "Jean-Luc";
|
|
|
+ const LASTNAME: &str = "Picard";
|
|
|
+ let case = new_case().await;
|
|
|
+ let client = &case.client;
|
|
|
+
|
|
|
+ let CreateReply { inode, .. } = client
|
|
|
+ .create(
|
|
|
+ SpecInodes::RootDir.into(),
|
|
|
+ FIRSTNAME,
|
|
|
+ Flags::default(),
|
|
|
+ 0o644,
|
|
|
+ 0,
|
|
|
+ )
|
|
|
+ .await
|
|
|
+ .unwrap();
|
|
|
+ client
|
|
|
+ .link(inode, SpecInodes::RootDir.into(), LASTNAME)
|
|
|
+ .await
|
|
|
+ .unwrap();
|
|
|
+ client
|
|
|
+ .unlink(SpecInodes::RootDir.into(), FIRSTNAME)
|
|
|
+ .await
|
|
|
+ .unwrap();
|
|
|
+ let OpenReply {
|
|
|
+ handle: root_handle,
|
|
|
+ ..
|
|
|
+ } = client
|
|
|
+ .open(
|
|
|
+ SpecInodes::RootDir.into(),
|
|
|
+ FlagValue::ReadOnly | FlagValue::Directory,
|
|
|
+ )
|
|
|
+ .await
|
|
|
+ .unwrap();
|
|
|
+ let ReadDirReply { entries, .. } = client
|
|
|
+ .read_dir(SpecInodes::RootDir.into(), root_handle, 0, 0)
|
|
|
+ .await
|
|
|
+ .unwrap();
|
|
|
+
|
|
|
+ let filenames: Vec<_> = entries.iter().map(|e| e.0.as_str()).collect();
|
|
|
+ assert!(filenames.contains(&LASTNAME));
|
|
|
+ assert!(!filenames.contains(&FIRSTNAME));
|
|
|
+ }
|
|
|
+
|
|
|
+ #[tokio::test]
|
|
|
+ async fn delete() {
|
|
|
+ const FILENAME: &str = "MANIFESTO.tex";
|
|
|
+ let case = new_case().await;
|
|
|
+ let client = &case.client;
|
|
|
+
|
|
|
+ client
|
|
|
+ .create(
|
|
|
+ SpecInodes::RootDir.into(),
|
|
|
+ FILENAME,
|
|
|
+ Flags::default(),
|
|
|
+ 0o644,
|
|
|
+ 0,
|
|
|
+ )
|
|
|
+ .await
|
|
|
+ .unwrap();
|
|
|
+ client
|
|
|
+ .unlink(SpecInodes::RootDir.into(), FILENAME)
|
|
|
+ .await
|
|
|
+ .unwrap();
|
|
|
+ let OpenReply {
|
|
|
+ handle: root_handle,
|
|
|
+ ..
|
|
|
+ } = client
|
|
|
+ .open(
|
|
|
+ SpecInodes::RootDir.into(),
|
|
|
+ FlagValue::ReadOnly | FlagValue::Directory,
|
|
|
+ )
|
|
|
+ .await
|
|
|
+ .unwrap();
|
|
|
+ let ReadDirReply { entries, .. } = client
|
|
|
+ .read_dir(SpecInodes::RootDir.into(), root_handle, 0, 0)
|
|
|
+ .await
|
|
|
+ .unwrap();
|
|
|
+
|
|
|
+ let filenames: Vec<_> = entries.iter().map(|e| e.0.as_str()).collect();
|
|
|
+ assert!(!filenames.contains(&FILENAME));
|
|
|
+ }
|
|
|
+
|
|
|
+ #[tokio::test]
|
|
|
+ async fn read_meta() {
|
|
|
+ const FILENAME: &str = "kibosh.txt";
|
|
|
+ const EXPECTED: u32 = 0o600;
|
|
|
+ let case = new_case().await;
|
|
|
+ let client = &case.client;
|
|
|
+
|
|
|
+ let before_create = Epoch::now();
|
|
|
+ let CreateReply { inode, handle, .. } = client
|
|
|
+ .create(
|
|
|
+ SpecInodes::RootDir.into(),
|
|
|
+ FILENAME,
|
|
|
+ FlagValue::ReadWrite.into(),
|
|
|
+ EXPECTED,
|
|
|
+ 0,
|
|
|
+ )
|
|
|
+ .await
|
|
|
+ .unwrap();
|
|
|
+ let before_read = Epoch::now();
|
|
|
+ let ReadMetaReply { attrs, .. } = client.read_meta(inode, Some(handle)).await.unwrap();
|
|
|
+ let after = Epoch::now();
|
|
|
+
|
|
|
+ let actual = attrs.mode;
|
|
|
+ assert_eq!(FileType::Reg | EXPECTED, actual);
|
|
|
+ assert!(before_create <= attrs.ctime && attrs.ctime <= before_read);
|
|
|
+ assert!(before_read <= attrs.mtime && attrs.mtime <= after);
|
|
|
+ assert!(before_read <= attrs.atime && attrs.atime <= after);
|
|
|
+ assert_eq!(attrs.block_id.inode, inode);
|
|
|
+ assert_eq!(attrs.size, 0);
|
|
|
+ assert!(attrs.tags.is_empty());
|
|
|
+ }
|
|
|
+
|
|
|
+ #[tokio::test]
|
|
|
+ async fn write_meta() {
|
|
|
+ fn check(expected: &Attrs, actual: &BlockMetaSecrets) {
|
|
|
+ assert_eq!(expected.mode, actual.mode);
|
|
|
+ assert_eq!(expected.uid, actual.uid);
|
|
|
+ assert_eq!(expected.gid, actual.gid);
|
|
|
+ assert_eq!(expected.atime, actual.atime);
|
|
|
+ assert_eq!(expected.mtime, actual.mtime);
|
|
|
+ assert_eq!(expected.ctime, actual.ctime);
|
|
|
+ assert_eq!(expected.tags.len(), actual.tags.len());
|
|
|
+ for (key, expected_value) in expected.tags.iter() {
|
|
|
+ let actual_value = actual.tags.get(key).unwrap();
|
|
|
+ assert_eq!(expected_value, actual_value);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const FILENAME: &str = "word_salad.docx";
|
|
|
+ let expected = Attrs {
|
|
|
+ mode: 0o600,
|
|
|
+ uid: 9290,
|
|
|
+ gid: 2190,
|
|
|
+ atime: 23193.into(),
|
|
|
+ mtime: 53432.into(),
|
|
|
+ ctime: 87239.into(),
|
|
|
+ tags: Vec::new(),
|
|
|
+ };
|
|
|
+ let case = new_case().await;
|
|
|
+ let client = &case.client;
|
|
|
+
|
|
|
+ let CreateReply { inode, handle, .. } = client
|
|
|
+ .create(
|
|
|
+ SpecInodes::RootDir.into(),
|
|
|
+ FILENAME,
|
|
|
+ FlagValue::ReadWrite.into(),
|
|
|
+ expected.mode | 0o011,
|
|
|
+ 0,
|
|
|
+ )
|
|
|
+ .await
|
|
|
+ .unwrap();
|
|
|
+ let WriteMetaReply { attrs, .. } = client
|
|
|
+ .write_meta(inode, Some(handle), expected.clone(), AttrsSet::ALL)
|
|
|
+ .await
|
|
|
+ .unwrap();
|
|
|
+ check(&expected, &attrs);
|
|
|
+ let ReadMetaReply { attrs, .. } = client.read_meta(inode, Some(handle)).await.unwrap();
|
|
|
+
|
|
|
+ check(&expected, &attrs);
|
|
|
+ }
|
|
|
}
|