use super::*;
#[test]
fn a_build_from_sealed_entries_serves_the_bytes_of_one_from_scratch() {
let mut fixture = fixture("sha1");
let source = CobSource::new(&fixture);
let (alice, bob) = (account("alice"), account("bob"));
let cobs = source.cobs(&fixture.signer);
let (ticket, mut version) = cobs.open_ticket("3lubrptx57d22", &alice, "one");
for n in 0..105 {
version = cobs.edit_ticket(ticket, &alice, version, &format!("edit {n}"), 20 + n);
}
for n in 0..60 {
cobs.open_ticket(&format!("3lubrptx58{n:03}"), &alice, &format!("t{n}"));
}
let comment = knot_cobs::Comment {
subject: RecordCid::new(knot_types::dag_cbor_cid(b"subject")).unwrap(),
reply: None,
};
let (erased, version) = cobs.open("3lubrptx57d33", &alice, 1, comment, "gone", 30);
cobs.erase::<knot_cobs::Comment>(erased, &alice, version, 40);
cobs.add_collaborator(&bob, &alice, 50);
let (cold, cold_dir) = build(&mut fixture, &source, "warm", "cold");
let pooled = served_tree(&cold_dir).len();
let (warm, warm_dir) = build(&mut fixture, &source, "warm", "warm");
assert_eq!(
served_tree(&cold_dir).len(),
pooled,
"the warm build pooled nothing new"
);
let (_, scratch_dir) = build(&mut fixture, &source, "scratch", "scratch");
assert_eq!(
warm.entry_key, cold.entry_key,
"the second build takes the first's seal"
);
let mount = warm_dir.join(ATPROTO_DIR).join(warm.dir_name());
assert!(std::fs::symlink_metadata(&mount).unwrap().is_symlink());
let scratch = served_tree(&scratch_dir);
assert!(scratch.len() > 100, "{} files", scratch.len());
assert!(scratch.keys().any(|path| path.contains("/versions/")));
assert!(scratch.keys().any(|path| path.ends_with("62_records.conf")));
assert!(served_tree(&cold_dir) == scratch);
assert!(served_tree(&warm_dir) == scratch);
assert!(
warm.blobs == cold.blobs,
"the records blobs are linked from"
);
}
#[test]
fn a_rebuild_pools_only_what_moved_and_serves_the_bytes_of_one_from_scratch() {
let mut fixture = fixture("sha1");
let source = CobSource::new(&fixture);
let alice = account("alice");
let cobs = source.cobs(&fixture.signer);
let (moved, mut version) = cobs.open_ticket("3lubrptx57d22", &alice, "one");
for n in 0..4 {
version = cobs.edit_ticket(moved, &alice, version, &format!("edit {n}"), 20 + n);
}
cobs.open_ticket("3lubrptx57d33", &alice, "kept");
cobs.open_ticket("3lubrptx57d44", &alice, "other");
let (first, _) = build(&mut fixture, &source, "warm", "first");
let (records, versions) = (
pooled_files(&first, "records"),
pooled_files(&first, "versions"),
);
source
.cobs(&fixture.signer)
.edit_ticket(moved, &alice, version, "moved", 40);
std::fs::write(fixture.work.join("a"), "two").unwrap();
git(&fixture.work, &["commit", "-q", "-am", "two"]);
git(
&fixture.source.export_dir,
&[
"fetch",
"-q",
fixture.work.to_str().unwrap(),
"+refs/heads/main:refs/heads/main",
],
);
let (second, second_dir) = build(&mut fixture, &source, "warm", "second");
let (_, scratch_dir) = build(&mut fixture, &source, "scratch", "scratch");
assert_ne!(second.entry_key, first.entry_key);
assert_serves_like(&second_dir, &scratch_dir);
assert_eq!(
pooled_files(&second, "records") - records,
2,
"the moved ticket and the refs record"
);
assert_eq!(
pooled_files(&second, "versions") - versions,
2,
"the moved ticket's pages, oldest and newest first"
);
}
#[test]
fn a_seal_keeps_the_blobs_its_records_cite_not_the_records() {
let mut fixture = fixture("sha1");
let source = CobSource::new(&fixture);
source
.cobs(&fixture.signer)
.open_ticket("3lubrptx57d22", &account("alice"), "one");
let (settled, _) = build(&mut fixture, &source, "warm", "first");
let sealed: serde_json::Value = fixture
.source
.served
.read_file(SEAL_KIND, &settled.entry_key)
.unwrap();
assert!(sealed.get("records").is_none());
assert!(sealed["blobs"].is_array());
let rows = sealed["rows"].as_object().unwrap();
assert!(!rows.contains_key("record_page") && !rows.contains_key("version_page"));
assert!(!rows["record"].as_array().unwrap().is_empty());
}
#[test]
fn a_pooled_file_cut_short_by_a_crash_is_written_again() {
let mut fixture = fixture("sha1");
let source = CobSource::new(&fixture);
let alice = account("alice");
let cobs = source.cobs(&fixture.signer);
let (ticket, version) = cobs.open_ticket("3lubrptx57d22", &alice, "one");
cobs.edit_ticket(ticket, &alice, version, "two", 20);
let (other, other_version) = cobs.open_ticket("3lubrptx57d33", &alice, "other");
let (first, _) = build(&mut fixture, &source, "warm", "first");
crate::cas::sealed::assert_sealed(&first.pool);
let record = a_pooled(&first, "records");
cut_short(&record, b"");
let (_, again) = build(&mut fixture, &source, "warm", "again");
let (_, scratch) = build(&mut fixture, &source, "scratch", "scratch");
assert_serves_like(&again, &scratch);
crate::cas::sealed::assert_sealed(&first.pool);
let row = format!(
"at://{}/org.tangled.track.ticket/3lubrptx57d22|100a|0",
first.did
);
let (_, file) = first.rows.version.iter().find(|(r, _)| *r == row).unwrap();
let page = first.pooled(file);
let bytes = std::fs::read(&page).unwrap();
cut_short(&page, &bytes[..bytes.len() / 2]);
source
.cobs(&fixture.signer)
.edit_ticket(other, &alice, other_version, "moved", 30);
let (_, moved) = build(&mut fixture, &source, "warm", "moved");
let (_, scratch) = build(&mut fixture, &source, "scratch", "scratch-moved");
assert_serves_like(&moved, &scratch);
}
#[test]
fn a_rebuild_after_a_crash_compares_what_the_pool_holds() {
let mut fixture = fixture("sha1");
let source = CobSource::new(&fixture);
source
.cobs(&fixture.signer)
.open_ticket("3lubrptx57d22", &account("alice"), "one");
let (first, _) = build(&mut fixture, &source, "warm", "first");
let record = a_pooled(&first, "records");
let len = std::fs::metadata(&record).unwrap().len() as usize;
cut_short(&record, &vec![b' '; len]);
fixture.source.verify = true;
let (_, again) = build(&mut fixture, &source, "warm", "again");
let (_, scratch) = build(&mut fixture, &source, "scratch", "scratch");
assert_serves_like(&again, &scratch);
}
#[test]
fn a_version_that_keeps_the_record_and_the_rev_reseals_its_pages() {
let mut fixture = fixture("sha1");
let source = CobSource::new(&fixture);
let alice = account("alice");
let (ticket, version) =
source
.cobs(&fixture.signer)
.open_ticket("3lubrptx57d22", &alice, "one");
let key = "org.tangled.track.ticket/3lubrptx57d22";
let first = source.settle(&mut fixture);
assert_eq!(first.served_versions(key).len(), 1);
source
.cobs(&fixture.signer)
.edit_ticket(ticket, &alice, version, "one", 20);
let again = source.settle(&mut fixture);
assert_eq!(again.commit, first.commit, "the record didn't change");
assert_eq!(again.served_versions(key).len(), 2);
}