Nothing to see here, move along meow
0

Configure Feed

Select the types of activity you want to include in your feed.

at main 4.3 kB View raw
1use lancer_core::fs::BLOCK_SIZE_MIN; 2use lancer_lancerfs::test_helpers::setup_fs; 3use lancer_lancerfs::{dedup, integrity}; 4 5#[test] 6fn identical_blocks_deduped() { 7 let mut fs = setup_fs(4096); 8 let root = fs.root_block(); 9 10 let (_inode_a, block_a) = fs.create_file(root, b"file_a"); 11 let (_inode_b, block_b) = fs.create_file(root, b"file_b"); 12 13 let data = vec![0xABu8; BLOCK_SIZE_MIN as usize]; 14 15 fs.write_file(block_a, 0, &data); 16 fs.write_file(block_b, 0, &data); 17 18 let read_a = fs.read_file(block_a, 0, BLOCK_SIZE_MIN as usize); 19 let read_b = fs.read_file(block_b, 0, BLOCK_SIZE_MIN as usize); 20 21 assert_eq!(read_a, data); 22 assert_eq!(read_b, data); 23 24 let inode_a = fs.read_inode(block_a); 25 let inode_b = fs.read_inode(block_b); 26 assert_eq!( 27 inode_a.direct[0].physical_block_addr(), 28 inode_b.direct[0].physical_block_addr() 29 ); 30 31 let content_hash = integrity::xxhash128(&data); 32 let shard = dedup::dedup_shard(content_hash); 33 let dedup_result = dedup::dedup_check( 34 &mut fs.pool, 35 &mut fs.cache, 36 &mut fs.bio, 37 &fs.state.dedup_roots[shard], 38 content_hash, 39 ) 40 .unwrap(); 41 assert!( 42 matches!(dedup_result, dedup::DedupResult::Reused(_)), 43 "dedup index must contain an entry for the shared content hash" 44 ); 45} 46 47#[test] 48fn different_blocks_not_deduped() { 49 let mut fs = setup_fs(4096); 50 let root = fs.root_block(); 51 52 let (_inode_a, block_a) = fs.create_file(root, b"diff_a"); 53 let (_inode_b, block_b) = fs.create_file(root, b"diff_b"); 54 55 let data_a = vec![0x11u8; BLOCK_SIZE_MIN as usize]; 56 let data_b = vec![0x22u8; BLOCK_SIZE_MIN as usize]; 57 58 fs.write_file(block_a, 0, &data_a); 59 fs.write_file(block_b, 0, &data_b); 60 61 let inode_a = fs.read_inode(block_a); 62 let inode_b = fs.read_inode(block_b); 63 assert_ne!( 64 inode_a.direct[0].physical_block_addr(), 65 inode_b.direct[0].physical_block_addr() 66 ); 67} 68 69#[test] 70fn dedup_data_survives_one_file_delete() { 71 let mut fs = setup_fs(4096); 72 let root = fs.root_block(); 73 74 let (_inode_a, block_a) = fs.create_file(root, b"surv_a"); 75 let (_inode_b, block_b) = fs.create_file(root, b"surv_b"); 76 77 let data = vec![0xCDu8; BLOCK_SIZE_MIN as usize]; 78 fs.write_file(block_a, 0, &data); 79 fs.write_file(block_b, 0, &data); 80 fs.commit(); 81 82 fs.delete_file(root, b"surv_a").unwrap(); 83 fs.commit(); 84 85 let read_b = fs.read_file(block_b, 0, BLOCK_SIZE_MIN as usize); 86 assert_eq!(read_b, data); 87} 88 89#[test] 90fn dedup_across_multiple_writes() { 91 let mut fs = setup_fs(4096); 92 let root = fs.root_block(); 93 94 let (_inode, block) = fs.create_file(root, b"multi_dedup"); 95 96 let data = vec![0xEEu8; BLOCK_SIZE_MIN as usize]; 97 fs.write_file(block, 0, &data); 98 fs.write_file(block, BLOCK_SIZE_MIN as u64, &data); 99 100 let inode = fs.read_inode(block); 101 assert_eq!( 102 inode.direct[0].physical_block_addr(), 103 inode.direct[1].physical_block_addr() 104 ); 105 106 let read_first = fs.read_file(block, 0, BLOCK_SIZE_MIN as usize); 107 let read_second = fs.read_file(block, BLOCK_SIZE_MIN as u64, BLOCK_SIZE_MIN as usize); 108 assert_eq!(read_first, data); 109 assert_eq!(read_second, data); 110} 111 112#[test] 113fn dedup_both_deleted_bulkfree_reclaims() { 114 let mut fs = setup_fs(4096); 115 let root = fs.root_block(); 116 117 let (_inode_a, block_a) = fs.create_file(root, b"dup_a"); 118 let (_inode_b, block_b) = fs.create_file(root, b"dup_b"); 119 120 let data = vec![0xFFu8; BLOCK_SIZE_MIN as usize]; 121 fs.write_file(block_a, 0, &data); 122 fs.write_file(block_b, 0, &data); 123 fs.commit(); 124 125 let inode_a = fs.read_inode(block_a); 126 let inode_b = fs.read_inode(block_b); 127 assert_eq!( 128 inode_a.direct[0].physical_block_addr(), 129 inode_b.direct[0].physical_block_addr(), 130 "both files must share the same physical block" 131 ); 132 133 let alloc_before = fs.count_allocated_blocks(); 134 135 fs.delete_file(root, b"dup_a").unwrap(); 136 fs.delete_file(root, b"dup_b").unwrap(); 137 fs.commit(); 138 fs.run_bulkfree(); 139 140 let alloc_after = fs.count_allocated_blocks(); 141 assert!( 142 alloc_after < alloc_before, 143 "bulkfree must reclaim blocks after deleting both dedup references: before={alloc_before}, after={alloc_after}" 144 ); 145}