From d1fa6af7befd5dd9557a2feeb0beefb12eb18d2a Mon Sep 17 00:00:00 2001 From: Brendan Allan Date: Tue, 12 Mar 2024 08:39:57 +0800 Subject: [PATCH] Add tests for CompressedCRDTOperation (#2189) --- Cargo.toml | 3 +- core/Cargo.toml | 46 +++++----- crates/sync/Cargo.toml | 2 +- crates/sync/src/compressed.rs | 158 +++++++++++++++++++++++++++++++++- 4 files changed, 182 insertions(+), 27 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 46c721a93..20b9dbff0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,13 +23,12 @@ repository = "https://github.com/spacedriveapp/spacedrive" [workspace.dependencies] # First party dependencies prisma-client-rust = { git = "https://github.com/spacedriveapp/prisma-client-rust", rev = "f99d6f5566570f3ab1edecb7a172ad25b03d95af", features = [ - "rspc", "sqlite-create-many", "migrations", "sqlite", ], default-features = false } prisma-client-rust-cli = { git = "https://github.com/spacedriveapp/prisma-client-rust", rev = "f99d6f5566570f3ab1edecb7a172ad25b03d95af", features = [ - "rspc", + "specta", "sqlite-create-many", "migrations", "sqlite", diff --git a/core/Cargo.toml b/core/Cargo.toml index ff3a1c8f1..0bd343b76 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -25,15 +25,15 @@ sd-core-sync = { path = "./crates/sync" } # sd-cloud-api = { path = "../crates/cloud-api" } sd-file-path-helper = { path = "../crates/file-path-helper" } sd-crypto = { path = "../crates/crypto", features = [ - "sys", - "tokio", + "sys", + "tokio", ], optional = true } sd-ffmpeg = { path = "../crates/ffmpeg", optional = true } sd-file-ext = { path = "../crates/file-ext" } sd-images = { path = "../crates/images", features = [ - "rspc", - "serde", - "specta", + "rspc", + "serde", + "specta", ] } sd-media-metadata = { path = "../crates/media-metadata" } sd-p2p2 = { path = "../crates/p2p2", features = ["specta"] } @@ -59,17 +59,17 @@ image = { workspace = true } normpath = { workspace = true, features = ["localization"] } once_cell = { workspace = true } pin-project-lite = { workspace = true } -prisma-client-rust = { workspace = true } +prisma-client-rust = { workspace = true, features = ["rspc"] } regex = { workspace = true } reqwest = { workspace = true, features = ["json", "native-tls-vendored"] } rmp-serde = { workspace = true } rspc = { workspace = true, features = [ - "axum", - "uuid", - "chrono", - "tracing", - "alpha", - "unstable", + "axum", + "uuid", + "chrono", + "tracing", + "alpha", + "unstable", ] } serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } @@ -79,12 +79,12 @@ strum_macros = { workspace = true } tempfile = { workspace = true } thiserror = { workspace = true } tokio = { workspace = true, features = [ - "sync", - "rt-multi-thread", - "io-util", - "macros", - "time", - "process", + "sync", + "rt-multi-thread", + "io-util", + "macros", + "time", + "process", ] } tokio-stream = { workspace = true, features = ["fs"] } tokio-util = { workspace = true, features = ["io"] } @@ -111,7 +111,7 @@ itertools = "0.12.0" libc = "0.2.153" mini-moka = "0.10.2" notify = { git = "https://github.com/notify-rs/notify.git", rev = "c3929ed114fbb0bc7457a9a498260461596b00ca", default-features = false, features = [ - "macos_fsevent", + "macos_fsevent", ] } rmpv = { workspace = true } serde-hashkey = "0.4.5" @@ -144,10 +144,10 @@ plist = "1" [target.'cfg(target_os = "ios")'.dependencies] icrate = { version = "0.1.0", features = [ - "Foundation", - "Foundation_NSFileManager", - "Foundation_NSString", - "Foundation_NSNumber", + "Foundation", + "Foundation_NSFileManager", + "Foundation_NSString", + "Foundation_NSNumber", ] } [dev-dependencies] diff --git a/crates/sync/Cargo.toml b/crates/sync/Cargo.toml index f734df205..860e6fa40 100644 --- a/crates/sync/Cargo.toml +++ b/crates/sync/Cargo.toml @@ -12,6 +12,6 @@ rmp-serde = "1.1.2" rmpv = { workspace = true } serde = { workspace = true } serde_json = { workspace = true } -specta = { workspace = true, features = ["uuid", "uhlc"] } +specta = { workspace = true, features = ["uuid", "uhlc", "serde_json"] } uhlc = { workspace = true } uuid = { workspace = true, features = ["serde", "v4"] } diff --git a/crates/sync/src/compressed.rs b/crates/sync/src/compressed.rs index e81288a88..edd8249a5 100644 --- a/crates/sync/src/compressed.rs +++ b/crates/sync/src/compressed.rs @@ -8,7 +8,9 @@ pub type CompressedCRDTOperationsForModel = Vec<(rmpv::Value, Vec)>); +pub struct CompressedCRDTOperations( + pub(self) Vec<(Uuid, Vec<(String, CompressedCRDTOperationsForModel)>)>, +); impl CompressedCRDTOperations { pub fn new(ops: Vec) -> Self { @@ -109,3 +111,157 @@ impl From for CompressedCRDTOperation { } } } + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn compress() { + let instance = Uuid::new_v4(); + + let uncompressed = vec![ + CRDTOperation { + instance, + timestamp: NTP64(0), + id: Uuid::new_v4(), + model: "FilePath".to_string(), + record_id: rmpv::Value::Nil, + data: CRDTOperationData::Create, + }, + CRDTOperation { + instance, + timestamp: NTP64(0), + id: Uuid::new_v4(), + model: "FilePath".to_string(), + record_id: rmpv::Value::Nil, + data: CRDTOperationData::Create, + }, + CRDTOperation { + instance, + timestamp: NTP64(0), + id: Uuid::new_v4(), + model: "FilePath".to_string(), + record_id: rmpv::Value::Nil, + data: CRDTOperationData::Create, + }, + CRDTOperation { + instance, + timestamp: NTP64(0), + id: Uuid::new_v4(), + model: "Object".to_string(), + record_id: rmpv::Value::Nil, + data: CRDTOperationData::Create, + }, + CRDTOperation { + instance, + timestamp: NTP64(0), + id: Uuid::new_v4(), + model: "Object".to_string(), + record_id: rmpv::Value::Nil, + data: CRDTOperationData::Create, + }, + CRDTOperation { + instance, + timestamp: NTP64(0), + id: Uuid::new_v4(), + model: "FilePath".to_string(), + record_id: rmpv::Value::Nil, + data: CRDTOperationData::Create, + }, + CRDTOperation { + instance, + timestamp: NTP64(0), + id: Uuid::new_v4(), + model: "FilePath".to_string(), + record_id: rmpv::Value::Nil, + data: CRDTOperationData::Create, + }, + ]; + + let CompressedCRDTOperations(compressed) = CompressedCRDTOperations::new(uncompressed); + + assert_eq!(&compressed[0].1[0].0, "FilePath"); + assert_eq!(&compressed[0].1[1].0, "Object"); + assert_eq!(&compressed[0].1[2].0, "FilePath"); + + assert_eq!(compressed[0].1[0].1[0].1.len(), 3); + assert_eq!(compressed[0].1[1].1[0].1.len(), 2); + assert_eq!(compressed[0].1[2].1[0].1.len(), 2); + } + + #[test] + fn into_ops() { + let compressed = CompressedCRDTOperations(vec![( + Uuid::new_v4(), + vec![ + ( + "FilePath".to_string(), + vec![( + rmpv::Value::Nil, + vec![ + CompressedCRDTOperation { + id: Uuid::new_v4(), + timestamp: NTP64(0), + data: CRDTOperationData::Create, + }, + CompressedCRDTOperation { + id: Uuid::new_v4(), + timestamp: NTP64(0), + data: CRDTOperationData::Create, + }, + CompressedCRDTOperation { + id: Uuid::new_v4(), + timestamp: NTP64(0), + data: CRDTOperationData::Create, + }, + ], + )], + ), + ( + "Object".to_string(), + vec![( + rmpv::Value::Nil, + vec![ + CompressedCRDTOperation { + id: Uuid::new_v4(), + timestamp: NTP64(0), + data: CRDTOperationData::Create, + }, + CompressedCRDTOperation { + id: Uuid::new_v4(), + timestamp: NTP64(0), + data: CRDTOperationData::Create, + }, + ], + )], + ), + ( + "FilePath".to_string(), + vec![( + rmpv::Value::Nil, + vec![ + CompressedCRDTOperation { + id: Uuid::new_v4(), + timestamp: NTP64(0), + data: CRDTOperationData::Create, + }, + CompressedCRDTOperation { + id: Uuid::new_v4(), + timestamp: NTP64(0), + data: CRDTOperationData::Create, + }, + ], + )], + ), + ], + )]); + + let uncompressed = compressed.into_ops(); + + assert_eq!(uncompressed.len(), 7); + assert_eq!(uncompressed[2].model, "FilePath"); + assert_eq!(uncompressed[4].model, "Object"); + assert_eq!(uncompressed[6].model, "FilePath"); + } +}