diff --git a/tests/test_fwrite.toml b/tests/test_fwrite.toml index 2341fe49..7060c41b 100644 --- a/tests/test_fwrite.toml +++ b/tests/test_fwrite.toml @@ -1690,6 +1690,172 @@ code = ''' lfsr_unmount(&lfs) => 0; ''' +# test that truncating to zero drops the bshrub/btree +[cases.test_fwrite_truncate_litmus_zero] +defines.N = [1, 2, 8] +defines.SIZE = 'N*BLOCK_SIZE' +defines.SYNC = [false, true] +in = 'lfs.c' +code = ''' + lfs_t lfs; + lfsr_format(&lfs, LFS_F_RDWR, CFG) => 0; + lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0; + + // create a file + lfsr_file_t file; + lfsr_file_open(&lfs, &file, "hello", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + uint8_t wbuf[SIZE]; + uint32_t prng = 42; + for (lfs_size_t i = 0; i < SIZE; i++) { + wbuf[i] = 'a' + (TEST_PRNG(&prng) % 26); + } + lfsr_file_write(&lfs, &file, wbuf, SIZE) => SIZE; + + // sync? + if (SYNC) { + lfsr_file_sync(&lfs, &file) => 0; + } + + // truncate down to zero, this should drop any bshrub/btree + lfsr_file_truncate(&lfs, &file, 0) => 0; + + lfsr_file_close(&lfs, &file) => 0; + + for (int remount = 0; remount < 2; remount++) { + // remount? + if (remount) { + lfsr_unmount(&lfs) => 0; + lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0; + } + + // check our file with stat + struct lfs_info info; + lfsr_stat(&lfs, "hello", &info) => 0; + assert(strcmp(info.name, "hello") == 0); + assert(info.type == LFS_TYPE_REG); + assert(info.size == 0); + + // and with dir read + lfsr_dir_t dir; + lfsr_dir_open(&lfs, &dir, "/") => 0; + lfsr_dir_read(&lfs, &dir, &info) => 0; + assert(strcmp(info.name, ".") == 0); + assert(info.type == LFS_TYPE_DIR); + assert(info.size == 0); + lfsr_dir_read(&lfs, &dir, &info) => 0; + assert(strcmp(info.name, "..") == 0); + assert(info.type == LFS_TYPE_DIR); + assert(info.size == 0); + lfsr_dir_read(&lfs, &dir, &info) => 0; + assert(strcmp(info.name, "hello") == 0); + assert(info.type == LFS_TYPE_REG); + assert(info.size == 0); + lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT; + lfsr_dir_close(&lfs, &dir) => 0; + + // try reading our file + lfsr_file_open(&lfs, &file, "hello", LFS_O_RDONLY) => 0; + // is size correct? + lfsr_file_size(&lfs, &file) => 0; + // try reading + uint8_t rbuf[2]; + memset(rbuf, 0xaa, 2); + lfsr_file_read(&lfs, &file, rbuf, 2) => 0; + lfsr_file_close(&lfs, &file) => 0; + + // here's our main test, did the file drop bshrubs/btrees? + lfsr_file_open(&lfs, &file, "hello", LFS_O_RDONLY) => 0; + assert(lfsr_bshrub_isbnull(&file.b)); + lfsr_file_close(&lfs, &file) => 0; + } + + lfsr_unmount(&lfs) => 0; +''' + +# test that fruncating to zero drops the bshrub/btree +[cases.test_fwrite_fruncate_litmus_zero] +defines.N = [1, 2, 8] +defines.SIZE = 'N*BLOCK_SIZE' +defines.SYNC = [false, true] +in = 'lfs.c' +code = ''' + lfs_t lfs; + lfsr_format(&lfs, LFS_F_RDWR, CFG) => 0; + lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0; + + // create a file + lfsr_file_t file; + lfsr_file_open(&lfs, &file, "hello", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + uint8_t wbuf[SIZE]; + uint32_t prng = 42; + for (lfs_size_t i = 0; i < SIZE; i++) { + wbuf[i] = 'a' + (TEST_PRNG(&prng) % 26); + } + lfsr_file_write(&lfs, &file, wbuf, SIZE) => SIZE; + + // sync? + if (SYNC) { + lfsr_file_sync(&lfs, &file) => 0; + } + + // fruncate down to zero, this should drop any bshrub/btree + lfsr_file_fruncate(&lfs, &file, 0) => 0; + + lfsr_file_close(&lfs, &file) => 0; + + for (int remount = 0; remount < 2; remount++) { + // remount? + if (remount) { + lfsr_unmount(&lfs) => 0; + lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0; + } + + // check our file with stat + struct lfs_info info; + lfsr_stat(&lfs, "hello", &info) => 0; + assert(strcmp(info.name, "hello") == 0); + assert(info.type == LFS_TYPE_REG); + assert(info.size == 0); + + // and with dir read + lfsr_dir_t dir; + lfsr_dir_open(&lfs, &dir, "/") => 0; + lfsr_dir_read(&lfs, &dir, &info) => 0; + assert(strcmp(info.name, ".") == 0); + assert(info.type == LFS_TYPE_DIR); + assert(info.size == 0); + lfsr_dir_read(&lfs, &dir, &info) => 0; + assert(strcmp(info.name, "..") == 0); + assert(info.type == LFS_TYPE_DIR); + assert(info.size == 0); + lfsr_dir_read(&lfs, &dir, &info) => 0; + assert(strcmp(info.name, "hello") == 0); + assert(info.type == LFS_TYPE_REG); + assert(info.size == 0); + lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT; + lfsr_dir_close(&lfs, &dir) => 0; + + // try reading our file + lfsr_file_open(&lfs, &file, "hello", LFS_O_RDONLY) => 0; + // is size correct? + lfsr_file_size(&lfs, &file) => 0; + // try reading + uint8_t rbuf[2]; + memset(rbuf, 0xaa, 2); + lfsr_file_read(&lfs, &file, rbuf, 2) => 0; + lfsr_file_close(&lfs, &file) => 0; + + // here's our main test, did the file drop bshrubs/btrees? + lfsr_file_open(&lfs, &file, "hello", LFS_O_RDONLY) => 0; + assert(lfsr_bshrub_isbnull(&file.b)); + lfsr_file_close(&lfs, &file) => 0; + } + + lfsr_unmount(&lfs) => 0; +''' + # test that carving below fragment_thresh breaks blocks into fragments [cases.test_fwrite_truncate_litmus_fragment] defines.N = [1, 2, 8]