Skip to content

Commit 8d462b0

Browse files
committed
Tests: validate dual-write + fastest-read fallback and collections.
- Ensure both dashmap and sled OpenDAL stores receive resource blobs on save - Verify fallback to sled when fastest store entry is missing - Assert collections API still paginates, sorts, and counts correctly
1 parent 4d7e844 commit 8d462b0

File tree

1 file changed

+84
-0
lines changed

1 file changed

+84
-0
lines changed

lib/src/db/test.rs

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,90 @@ fn test_db_resources_all() {
422422
);
423423
}
424424

425+
#[test]
426+
fn persistable_multi_store_dual_write_and_fallback() {
427+
// New isolated store
428+
let store = Db::init_temp("persistable_dual_write").unwrap();
429+
430+
// Create and save a resource
431+
let mut r = crate::Resource::new_generate_subject(&store);
432+
r.set_propval_string(crate::urls::SHORTNAME.into(), "dual", &store)
433+
.unwrap();
434+
r.save(&store).unwrap();
435+
let subject = r.get_subject().to_string();
436+
437+
// Both OpenDAL operators should have the blob
438+
let dash = store.dal_ops.get("dashmap").expect("dashmap op");
439+
let sled = store.dal_ops.get("sled").expect("sled op");
440+
let dash_bytes = store
441+
.runtime
442+
.block_on(async { dash.read(&subject).await.expect("dash read") });
443+
let sled_bytes = store
444+
.runtime
445+
.block_on(async { sled.read(&subject).await.expect("sled read") });
446+
assert!(dash_bytes.len() > 0);
447+
assert_eq!(dash_bytes, sled_bytes, "stores should contain same bytes");
448+
449+
// Delete from the fastest store, ensure fallback (sled tree) still serves resource
450+
store
451+
.runtime
452+
.block_on(async { store.dal_fastest.delete(&subject).await })
453+
.ok();
454+
// Should still be able to fetch via sled resources fallback
455+
let fetched = store.get_resource(&subject).expect("fallback should work");
456+
assert_eq!(fetched.get_subject(), subject);
457+
458+
// Remove from sled resources tree and ensure not found now
459+
store
460+
.resources
461+
.remove(subject.as_bytes())
462+
.expect("sled remove");
463+
assert!(store.get_resource(&subject).is_err(), "should be gone now");
464+
}
465+
466+
#[test]
467+
fn persistable_collections_still_work() {
468+
let store = Db::init_temp("persistable_collections").unwrap();
469+
let filter_prop = crate::urls::DESTINATION;
470+
let sort_by = crate::urls::DESCRIPTION;
471+
472+
// Create a few resources that match collection filters
473+
for _ in 0..8 {
474+
let mut res = crate::Resource::new_generate_subject(&store);
475+
res.set_propval(
476+
filter_prop.into(),
477+
crate::Value::AtomicUrl(crate::urls::PARAGRAPH.into()),
478+
&store,
479+
)
480+
.unwrap();
481+
res.set_propval(
482+
sort_by.into(),
483+
crate::Value::Markdown(crate::utils::random_string(10)),
484+
&store,
485+
)
486+
.unwrap();
487+
res.save(&store).unwrap();
488+
}
489+
490+
// Build a collection via Query and check pagination + sorting paths remain valid
491+
let q = crate::storelike::Query {
492+
property: Some(filter_prop.into()),
493+
value: Some(crate::Value::AtomicUrl(crate::urls::PARAGRAPH.into())),
494+
limit: Some(5),
495+
start_val: None,
496+
end_val: None,
497+
offset: 0,
498+
sort_by: Some(sort_by.into()),
499+
sort_desc: false,
500+
include_external: true,
501+
include_nested: true,
502+
for_agent: ForAgent::Sudo,
503+
};
504+
let res = store.query(&q).unwrap();
505+
assert_eq!(res.resources.len(), 5, "limit respected");
506+
assert!(res.count >= 8, "count should include all members");
507+
}
508+
425509
#[test]
426510
/// Changing these values actually correctly updates the index.
427511
fn index_invalidate_cache() {

0 commit comments

Comments
 (0)