mod common; use common::{basic_flag, basic_segment, run_test, tombstone}; use test_case::test_case; use uuid::Uuid; use launchdarkly_server_sdk::{DataKind, PersistentDataStoreFactory, SerializedItem}; use launchdarkly_server_sdk_redis::RedisPersistentDataStoreFactory; #[test_case(1, 2, tombstone(2); "Newer versions replace older")] #[test_case(2, 1, basic_flag("test-item", 2); "Older versions do not replace newer versions")] #[test_case(1, 1, basic_flag("test-item", 1); "The same version does not replace existing version")] fn flag_upsert_a_deletion_handles_versions_appropriately( initial_version: u64, upserted_version: u64, expected_json_string: String, ) { let prefix = Uuid::new_v4().hyphenated().to_string(); run_test(&prefix, || { let mut factory = RedisPersistentDataStoreFactory::new(); factory.prefix(&prefix); let mut store = factory.create_persistent_data_store().expect("FAIL"); let initial_item = SerializedItem { version: initial_version, deleted: false, serialized_item: basic_flag("test-item", initial_version), }; assert!(store .upsert(DataKind::Flag, "test-item", initial_item) .is_ok()); let new_item = SerializedItem { version: upserted_version, deleted: true, serialized_item: tombstone(upserted_version), }; let result = store.upsert(DataKind::Flag, "test-item", new_item); assert!(result.is_ok()); let retrieved_item = store.flag("test-item").unwrap(); assert!(retrieved_item.is_some()); assert_eq!( retrieved_item.unwrap().serialized_item, expected_json_string ); }) } #[test_case(1, 2, basic_flag("test-item", 2); "Newer versions replace older")] #[test_case(2, 1, tombstone(2); "Older versions do not replace newer versions")] #[test_case(1, 1, tombstone(1); "The same version does not replace existing version")] fn flag_upsert_after_deletion_handles_versions_appropriately( initial_version: u64, upserted_version: u64, expected_json_string: String, ) { let prefix = Uuid::new_v4().hyphenated().to_string(); run_test(&prefix, || { let mut factory = RedisPersistentDataStoreFactory::new(); factory.prefix(&prefix); let mut store = factory.create_persistent_data_store().expect("FAIL"); let initial_item = SerializedItem { version: initial_version, deleted: true, serialized_item: tombstone(initial_version), }; assert!(store .upsert(DataKind::Flag, "test-item", initial_item) .is_ok()); let new_item = SerializedItem { version: upserted_version, deleted: false, serialized_item: basic_flag("test-item", upserted_version), }; let result = store.upsert(DataKind::Flag, "test-item", new_item); assert!(result.is_ok()); let retrieved_item = store.flag("test-item").unwrap(); assert!(retrieved_item.is_some()); assert_eq!( retrieved_item.unwrap().serialized_item, expected_json_string ); }) } #[test] fn delete_unknown_flag() { let prefix = Uuid::new_v4().hyphenated().to_string(); run_test(&prefix, || { let mut factory = RedisPersistentDataStoreFactory::new(); factory.prefix(&prefix); let mut store = factory.create_persistent_data_store().expect("FAIL"); let initial_item = SerializedItem { version: 1, deleted: true, serialized_item: tombstone(1), }; assert!(store .upsert(DataKind::Flag, "test-item", initial_item) .is_ok()); let retrieved_item = store.flag("test-item").unwrap(); assert!(retrieved_item.is_some()); assert_eq!(tombstone(1), retrieved_item.unwrap().serialized_item); }) } #[test_case(1, 2, tombstone(2); "Newer versions replace older")] #[test_case(2, 1, basic_segment("test-item", 2); "Older versions do not replace newer versions")] #[test_case(1, 1, basic_segment("test-item", 1); "The same version does not replace existing version")] fn segment_upsert_a_deletion_handles_versions_appropriately( initial_version: u64, upserted_version: u64, expected_json_string: String, ) { let prefix = Uuid::new_v4().hyphenated().to_string(); run_test(&prefix, || { let mut factory = RedisPersistentDataStoreFactory::new(); factory.prefix(&prefix); let mut store = factory.create_persistent_data_store().expect("FAIL"); let initial_item = SerializedItem { version: initial_version, deleted: false, serialized_item: basic_segment("test-item", initial_version), }; assert!(store .upsert(DataKind::Segment, "test-item", initial_item) .is_ok()); let new_item = SerializedItem { version: upserted_version, deleted: true, serialized_item: tombstone(upserted_version), }; let result = store.upsert(DataKind::Segment, "test-item", new_item); assert!(result.is_ok()); let retrieved_item = store.segment("test-item").unwrap(); assert!(retrieved_item.is_some()); assert_eq!( retrieved_item.unwrap().serialized_item, expected_json_string ); }) } #[test_case(1, 2, basic_segment("test-item", 2); "Newer versions replace older")] #[test_case(2, 1, tombstone(2); "Older versions do not replace newer versions")] #[test_case(1, 1, tombstone(1); "The same version does not replace existing version")] fn segment_upsert_after_deletion_handles_versions_appropriately( initial_version: u64, upserted_version: u64, expected_json_string: String, ) { let prefix = Uuid::new_v4().hyphenated().to_string(); run_test(&prefix, || { let mut factory = RedisPersistentDataStoreFactory::new(); factory.prefix(&prefix); let mut store = factory.create_persistent_data_store().expect("FAIL"); let initial_item = SerializedItem { version: initial_version, deleted: true, serialized_item: tombstone(initial_version), }; assert!(store .upsert(DataKind::Segment, "test-item", initial_item) .is_ok()); let new_item = SerializedItem { version: upserted_version, deleted: false, serialized_item: basic_segment("test-item", upserted_version), }; let result = store.upsert(DataKind::Segment, "test-item", new_item); assert!(result.is_ok()); let retrieved_item = store.segment("test-item").unwrap(); assert!(retrieved_item.is_some()); assert_eq!( retrieved_item.unwrap().serialized_item, expected_json_string ); }) } #[test] fn delete_unknown_segment() { let prefix = Uuid::new_v4().hyphenated().to_string(); run_test(&prefix, || { let mut factory = RedisPersistentDataStoreFactory::new(); factory.prefix(&prefix); let mut store = factory.create_persistent_data_store().expect("FAIL"); let initial_item = SerializedItem { version: 1, deleted: true, serialized_item: tombstone(1), }; assert!(store .upsert(DataKind::Segment, "test-item", initial_item) .is_ok()); let retrieved_item = store.segment("test-item").unwrap(); assert!(retrieved_item.is_some()); assert!(retrieved_item.is_some()); assert_eq!(tombstone(1), retrieved_item.unwrap().serialized_item); }) }