From 67bf35be5f2a99cd3c2bd46853ed946fbb882137 Mon Sep 17 00:00:00 2001 From: Tarek Date: Wed, 12 Jun 2024 19:27:46 +0300 Subject: [PATCH] add delay Signed-off-by: Tarek --- .github/workflows/build.yml | 13 ------ fs-storage/src/file_storage.rs | 72 ++++++++++++++++++++++++++++++++-- 2 files changed, 68 insertions(+), 17 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index cddbfab4..009dda9e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -21,19 +21,6 @@ jobs: - name: Install Rust uses: dtolnay/rust-toolchain@stable - with: - components: rustfmt, clippy - - - name: Check - run: cargo check - - - name: Format - run: | - cargo fmt --all -- --check - cargo clippy --workspace --bins -- -D warnings - - - name: Build Debug - run: cargo build --verbose - name: Run tests run: cargo test --verbose diff --git a/fs-storage/src/file_storage.rs b/fs-storage/src/file_storage.rs index 276c808c..8fe0dd06 100644 --- a/fs-storage/src/file_storage.rs +++ b/fs-storage/src/file_storage.rs @@ -46,7 +46,7 @@ where /// /// /// This is the data that is serialized and deserialized to and from disk. -#[derive(Serialize, Deserialize)] +#[derive(Serialize, Deserialize, Debug)] pub struct FileStorageData where K: Ord, @@ -254,6 +254,9 @@ where let mut file = File::create(&self.path)?; file.write_all(serde_json::to_string_pretty(&self.data)?.as_bytes())?; file.flush()?; + // Sync the file to disk to ensure metadata is updated + file.sync_all()?; + drop(file); let new_timestamp = fs::metadata(&self.path)?.modified()?; if new_timestamp == self.modified { @@ -374,6 +377,7 @@ mod tests { .unwrap() .modified() .unwrap(); + std::thread::sleep(std::time::Duration::from_secs(1)); file_storage.write_fs().unwrap(); let after_write = fs::metadata(&storage_path) .unwrap() @@ -385,6 +389,47 @@ mod tests { ); assert!(before_write < after_write); } + use std::io::Write; + /* + A debugging test for checking metadata timestamps + + steps: + - create a temp file + - get metadata timestamp + - write to the file (using `write_fs()`, `flush()`, `sync_all()`) + - get metadata timestamp + - check if the timestamp has been updated + */ + #[test] + fn test_file_metadata_timestamp() { + let temp_dir = + TempDir::new("tmp").expect("Failed to create temporary directory"); + let storage_path = temp_dir.path().join("teststorage.txt"); + + let _file = fs::File::create(&storage_path).unwrap(); + let before_write = fs::metadata(&storage_path) + .unwrap() + .modified() + .unwrap(); + + // 1 second sleep to ensure the timestamp is updated + std::thread::sleep(std::time::Duration::from_secs(1)); + + let mut file = fs::File::create(&storage_path).unwrap(); + file.write_all(b"test").unwrap(); + file.flush().unwrap(); + file.sync_all().unwrap(); + + let after_write = fs::metadata(&storage_path) + .unwrap() + .modified() + .unwrap(); + println!( + "before_write: {:?}, after_write: {:?}", + before_write, after_write + ); + assert!(before_write < after_write); + } #[test] fn test_file_storage_is_storage_updated() { @@ -398,27 +443,46 @@ mod tests { assert_eq!(file_storage.sync_status().unwrap(), SyncStatus::InSync); file_storage.set("key1".to_string(), "value1".to_string()); + // We updated the in-memory storage but not the storage on disk + // so the storage is stale assert_eq!( file_storage.sync_status().unwrap(), SyncStatus::StorageStale ); + std::thread::sleep(std::time::Duration::from_secs(1)); file_storage.write_fs().unwrap(); + // `write_fs()` updates the storage on disk, so the storage is in sync assert_eq!(file_storage.sync_status().unwrap(), SyncStatus::InSync); // External data manipulation + // mirror_storage simulates external data manipulation let mut mirror_storage = FileStorage::new("MirrorTestStorage".to_string(), &storage_path) .unwrap(); - assert_eq!(mirror_storage.sync_status().unwrap(), SyncStatus::InSync); + println!("{:?}", mirror_storage.data); + assert_eq!( + mirror_storage.sync_status().unwrap(), + SyncStatus::InSync, + "{:?}", + mirror_storage.data + ); mirror_storage.set("key1".to_string(), "value3".to_string()); assert_eq!( mirror_storage.sync_status().unwrap(), - SyncStatus::StorageStale + SyncStatus::StorageStale, + "{:?}", + mirror_storage.data ); + std::thread::sleep(std::time::Duration::from_secs(1)); mirror_storage.write_fs().unwrap(); - assert_eq!(mirror_storage.sync_status().unwrap(), SyncStatus::InSync); + assert_eq!( + mirror_storage.sync_status().unwrap(), + SyncStatus::InSync, + "{:?}", + mirror_storage.data + ); // receive updates from external data manipulation assert_eq!(