use crate::disk::block::{DataBlock, DoubleIndirectBlock, IndirectBlock}; use crate::disk::inode::InodeMode; use crate::tests::common; #[test] fn test_basic_lru() { let mut fs = common::setup(); let v: Vec = (1..=256) .map(|_| { let index = fs.data_bitmap.allocate().unwrap(); fs.get_block::(index).unwrap(); index }) .collect(); assert!(fs.peek_block::(v[0]).is_some()); for i in 0..256 { let index = fs.data_bitmap.allocate().unwrap(); fs.get_block::(index).unwrap(); assert!(fs.peek_block::(v[i]).is_none()); } } #[test] fn test_inode_allocation() { let mut fs = common::setup(); let (inode_index, inode) = fs.create_directory(0o755, 0, 0, 0, None).unwrap(); let mut inode = inode.clone(); const DIRECT_NUMBER: u32 = 15; const INDIRECT_NUMBER: u32 = 1024; // const DOUBLE_INDIRECT_NUMBER: u32 = 1024 * 1024; for i in 0..DIRECT_NUMBER { fs.allocate_block_for(&mut inode).unwrap(); assert!(fs.data_bitmap.query(inode.direct[i as usize] as usize)) } for _i in 0..INDIRECT_NUMBER { fs.allocate_block_for(&mut inode).unwrap(); } println!("single indirect is {}", inode.single_indirect); println!("double indirect is {}", inode.double_indirect); println!("triple indirect is {}", inode.triple_indirect); let indirect_block = fs .peek_block::(inode.single_indirect as usize) .unwrap(); for entry in indirect_block.block.entries { assert_ne!(entry, 0); assert!(fs.data_bitmap.query(entry as usize)); } assert_eq!(fs.data_bitmap.query(inode.double_indirect as usize), false); assert_eq!(fs.data_bitmap.query(inode.triple_indirect as usize), false); for _i in 0..INDIRECT_NUMBER { fs.allocate_block_for(&mut inode).unwrap(); } let double_indirect = inode.double_indirect; println!( "double indirect is {} after allocation", inode.double_indirect ); fs.update_inode(inode_index, inode); assert!(fs.data_bitmap.query(double_indirect as usize)); } #[test] fn test_inode_deallocation() { let mut fs = common::setup(); let (inode_index, inode) = fs.create_directory(0o755, 0, 0, 0, None).unwrap(); let mut inode = inode.clone(); const DIRECT_NUMBER: u32 = 15; const INDIRECT_NUMBER: u32 = 1024; // const DOUBLE_INDIRECT_NUMBER: u32 = 1024 * 1024; for i in 0..DIRECT_NUMBER { println!("Allocated {:?}", fs.allocate_block_for(&mut inode).unwrap()); assert!(fs.data_bitmap.query(inode.direct[i as usize] as usize)) } for _i in 0..2 * INDIRECT_NUMBER { println!("Allocated {:?}", fs.allocate_block_for(&mut inode).unwrap()); } println!("single indirect is {}", inode.single_indirect); println!("double indirect is {}", inode.double_indirect); println!("triple indirect is {}", inode.triple_indirect); assert!(fs.data_bitmap.query(inode.double_indirect as usize)); for i in 0..INDIRECT_NUMBER + 5 { println!( "Deallocated {}", fs.deallocate_block_for(&mut inode).unwrap() ); } println!("single indirect is {}", inode.single_indirect); println!("double indirect is {}", inode.double_indirect); println!("triple indirect is {}", inode.triple_indirect); assert_eq!(fs.data_bitmap.query(inode.double_indirect as usize), false); fs.update_inode(inode_index, inode); } #[test] fn test_multiple_inode_allocation() { let mut fs = common::setup(); let (inode_index_1, inode_1) = fs.create_directory(0o755, 0, 0, 0, None).unwrap(); let mut inode_1 = inode_1.clone(); let (inode_index_2, inode_2) = fs.create_file(0o755, 0, 0, 0).unwrap(); let mut inode_2 = inode_2.clone(); // let mut inode_1 = fs.get_inode(inode_index_1).unwrap().clone(); // let mut inode_2 = fs.get_inode(inode_index_2).unwrap().clone(); const DIRECT_NUMBER: u32 = 15; const INDIRECT_NUMBER: u32 = 1024; for i in 0..DIRECT_NUMBER + INDIRECT_NUMBER { println!( "Allocated {:?} in inode {}", fs.allocate_block_for(&mut inode_1).unwrap(), inode_index_1 ); println!( "Allocated {:?} in inode {}", fs.allocate_block_for(&mut inode_2).unwrap(), inode_index_2 ); } let (inode_index_3, inode_3) = fs.create_directory(0o755, 0, 0, 0, None).unwrap(); let mut inode_3 = inode_3.clone(); // let mut inode_3 = fs.get_inode(inode_index_3).unwrap().clone(); for _i in 0..INDIRECT_NUMBER { println!( "Deallocated {} in inode {}", fs.deallocate_block_for(&mut inode_1).unwrap(), inode_index_1 ); println!( "Allocated {:?} in inode {}", fs.allocate_block_for(&mut inode_3).unwrap(), inode_index_3 ); } for _i in 0..DIRECT_NUMBER { println!( "Deallocated {} in inode {}", fs.deallocate_block_for(&mut inode_1).unwrap(), inode_index_1 ); } assert!(fs.deallocate_block_for(&mut inode_1).is_none()); println!( "single indirect is {} for {}", inode_1.single_indirect, inode_index_1 ); println!( "double indirect is {} for {}", inode_1.double_indirect, inode_index_1 ); println!( "single indirect is {} for {}", inode_2.single_indirect, inode_index_2 ); println!( "double indirect is {} for {}", inode_2.double_indirect, inode_index_2 ); println!( "single indirect is {} for {}", inode_3.single_indirect, inode_index_3 ); println!( "double indirect is {} for {}", inode_3.double_indirect, inode_index_3 ); assert_eq!( fs.data_bitmap.query(inode_1.single_indirect as usize), false ); assert!(fs.data_bitmap.query(inode_2.single_indirect as usize)); assert_eq!( fs.data_bitmap.query(inode_2.double_indirect as usize), false ); assert!(fs.data_bitmap.query(inode_3.single_indirect as usize)); assert_eq!( fs.data_bitmap.query(inode_3.double_indirect as usize), false ); fs.allocate_block_for(&mut inode_2).unwrap(); println!("-----------------"); println!( "double indirect is {} for {}", inode_2.double_indirect, inode_index_2 ); assert!(fs.data_bitmap.query(inode_2.double_indirect as usize)); for _i in 0..DIRECT_NUMBER { fs.allocate_block_for(&mut inode_3).unwrap(); } println!("-----------------"); println!( "double indirect is {} for {}", inode_3.double_indirect, inode_index_3 ); assert_eq!( fs.data_bitmap.query(inode_3.double_indirect as usize), false ); fs.allocate_block_for(&mut inode_3).unwrap(); println!("-----------------"); println!( "double indirect is {} for {}", inode_3.double_indirect, inode_index_3 ); assert!(fs.data_bitmap.query(inode_3.double_indirect as usize)); fs.update_inode(inode_index_1, inode_1); fs.update_inode(inode_index_2, inode_2); fs.update_inode(inode_index_3, inode_3); }