diff --git a/.gitignore b/.gitignore index 1096b27..0f0e72d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ /target Cargo.lock -test.db \ No newline at end of file +*test.db \ No newline at end of file diff --git a/patch-db/Cargo.toml b/patch-db/Cargo.toml index 8d9d7b1..0085fd3 100644 --- a/patch-db/Cargo.toml +++ b/patch-db/Cargo.toml @@ -22,4 +22,6 @@ tokio = { version = "1.0.1", features = ["sync", "fs", "rt", "io-util", "macros" patch-db-macro = { path = "../patch-db-macro" } [dev-dependencies] +proptest = "1.0.0" serde = { version = "1.0.118", features = ["rc", "derive"] } +tokio = { version = "1.0.1", features = ["sync", "fs", "rt", "rt-multi-thread", "io-util", "macros"] } diff --git a/patch-db/src/test.rs b/patch-db/src/test.rs index ea00620..6e3c147 100644 --- a/patch-db/src/test.rs +++ b/patch-db/src/test.rs @@ -1,26 +1,80 @@ use super::*; use crate as patch_db; +use proptest::prelude::*; +use tokio::{fs, runtime::Builder}; use patch_db_macro::HasModel; -#[tokio::test] -async fn basic() { - let db = PatchDb::open("test.db").await.unwrap(); +async fn init_db(db_name: String) -> PatchDb { + cleanup_db(&db_name).await; + let db = PatchDb::open(db_name).await.unwrap(); db.put( &JsonPointer::<&'static str>::default(), &Sample { a: "test1".to_string(), b: Child { a: "test2".to_string(), - b: 4, + b: 1, }, }, ) - .await - .unwrap(); + .await.unwrap(); + db +} + +async fn cleanup_db(db_name: &String) { + fs::remove_file(db_name).await.ok(); +} + +async fn put_string_into_root(db: PatchDb, s: String) -> Arc { + println!("trying string: {}", s); + db.put( + &JsonPointer::<&'static str>::default(), + &s + ) + .await.unwrap() +} + + +#[tokio::test] +async fn basic() { + let db = init_db("basic.test.db".to_string()).await; let ptr: JsonPointer = "/b/b".parse().unwrap(); + let mut get_res: Value = db.get(&ptr).await.unwrap(); + assert_eq!(get_res, 1); db.put(&ptr, &"hello").await.unwrap(); - let get_res: Value = db.get(&ptr).await.unwrap(); + get_res = db.get(&ptr).await.unwrap(); assert_eq!(get_res, "hello"); + cleanup_db(&"basic.test.db".to_string()).await; +} + +#[tokio::test] +async fn transaction() { + let db = init_db("transaction.test.db".to_string()).await; + let mut tx = db.begin(); + let ptr: JsonPointer = "/b/b".parse().unwrap(); + tx.put(&ptr, &(2 as usize)).await.unwrap(); + tx.put(&ptr, &(1 as usize)).await.unwrap(); + let _res = tx.commit().await.unwrap(); + println!("res = {:?}", _res); + cleanup_db(&"transaction.test.db".to_string()).await; +} + +proptest! { + #[test] + fn doesnt_crash(s in "\\PC*") { + // build runtime + let runtime = Builder::new_multi_thread() + .worker_threads(4) + .thread_name("test-doesnt-crash") + .thread_stack_size(3 * 1024 * 1024) + .build() + .unwrap(); + let db = runtime.block_on(init_db("doesnt_crash.test.db".to_string())); + let put_future = put_string_into_root(db, s); + runtime.block_on(put_future); + runtime.block_on(cleanup_db(&"doesnt_crash.test.db".to_string())); + + } } #[derive(Debug, serde::Deserialize, serde::Serialize, HasModel)]