From f323ea1bdac29234f7fba31ddbb55d0169822671 Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Thu, 25 Jan 2024 12:14:23 -0600 Subject: [PATCH] Made mkdir tests a bit more paranoid Unfortunately the current dir+bookmark+grm design has a high risk of the system becoming out-of-sync and losing bookmarks. In theory this should cause test failures, but the previous grm-mid-off-by-one bug has left me a bit paranoid. So when dbglfs.py starting flashing bookmark errors, I started investigating. But just I can't reproduce these errors in a controlled way, and they cause no test failures... My current setup involves this script to copy the disk file "atomically", so even though dbglfs.py is slow, we shouldn't be reading blocks from different filesystem states. Uh, beauty is in the eye of the beholder and all that jazz?: ./scripts/watch.py -b -Kdisk bash -c "cp disk disk_ \ && ./scripts/dbglfs.py disk_ -B4096 \ --color=always -s -a -T -f -g 2>&1 \ | head -n32" But some brief investigation suggests cp is not atomic. After all, how could it be? My guess is we occasionaly catch blocks from different filesystem states when a write occurs during a cp operation. So a false positive. Still, might as well keep these extra asserts for a bit of extra confidence we're not losing bookmarks during heavy mkdir operations. --- tests/test_dirs.toml | 257 ++++++++++++++++++++++++++++++++----------- 1 file changed, 194 insertions(+), 63 deletions(-) diff --git a/tests/test_dirs.toml b/tests/test_dirs.toml index 56f38ec5..1d9af561 100644 --- a/tests/test_dirs.toml +++ b/tests/test_dirs.toml @@ -52,12 +52,23 @@ code = ''' lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT; lfsr_dir_close(&lfs, &dir) => 0; + lfsr_dir_open(&lfs, &dir, "ardvark") => 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) => LFS_ERR_NOENT; + lfsr_dir_close(&lfs, &dir) => 0; + lfsr_unmount(&lfs) => 0; ''' # test that noent errors work [cases.test_dirs_noent] -defines.REMOUNT = [false, true] code = ''' lfs_t lfs; lfsr_format(&lfs, CFG) => 0; @@ -73,42 +84,11 @@ code = ''' lfsr_dir_t dir; lfsr_dir_open(&lfs, &dir, "no") => LFS_ERR_NOENT; - // remount? - if (REMOUNT) { - lfsr_unmount(&lfs) => 0; - lfsr_mount(&lfs, CFG) => 0; - // grm should be zero here - assert(lfs.grm_g[0] == 0); - } - - // and check that this didn't interfere with our original directory - lfsr_stat(&lfs, "ardvark", &info) => 0; - assert(strcmp(info.name, "ardvark") == 0); - assert(info.type == LFS_TYPE_DIR); - assert(info.size == 0); - - 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, "ardvark") == 0); - assert(info.type == LFS_TYPE_DIR); - assert(info.size == 0); - lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT; - lfsr_dir_close(&lfs, &dir) => 0; - lfsr_unmount(&lfs) => 0; ''' # test that stat on root works [cases.test_dirs_stat_root] -defines.REMOUNT = [false, true] code = ''' lfs_t lfs; lfsr_format(&lfs, CFG) => 0; @@ -124,37 +104,6 @@ code = ''' assert(info.type == LFS_TYPE_DIR); assert(info.size == 0); - // remount? - if (REMOUNT) { - lfsr_unmount(&lfs) => 0; - lfsr_mount(&lfs, CFG) => 0; - // grm should be zero here - assert(lfs.grm_g[0] == 0); - } - - // and check that this didn't interfere with our original directory - lfsr_stat(&lfs, "ardvark", &info) => 0; - assert(strcmp(info.name, "ardvark") == 0); - assert(info.type == LFS_TYPE_DIR); - assert(info.size == 0); - - 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, "ardvark") == 0); - assert(info.type == LFS_TYPE_DIR); - assert(info.size == 0); - lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT; - lfsr_dir_close(&lfs, &dir) => 0; - lfsr_unmount(&lfs) => 0; ''' @@ -210,6 +159,18 @@ code = ''' lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT; lfsr_dir_close(&lfs, &dir) => 0; + lfsr_dir_open(&lfs, &dir, "ardvark") => 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) => LFS_ERR_NOENT; + lfsr_dir_close(&lfs, &dir) => 0; + lfsr_unmount(&lfs) => 0; ''' @@ -288,6 +249,18 @@ code = ''' lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT; lfsr_dir_close(&lfs, &dir) => 0; + lfsr_dir_open(&lfs, &dir, "ardvark") => 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) => LFS_ERR_NOENT; + lfsr_dir_close(&lfs, &dir) => 0; + lfsr_unmount(&lfs) => 0; ''' @@ -346,6 +319,18 @@ code = ''' lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT; lfsr_dir_close(&lfs, &dir) => 0; + lfsr_dir_open(&lfs, &dir, "ardvark") => 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) => LFS_ERR_NOENT; + lfsr_dir_close(&lfs, &dir) => 0; + lfsr_unmount(&lfs) => 0; ''' @@ -404,6 +389,18 @@ code = ''' lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT; lfsr_dir_close(&lfs, &dir) => 0; + lfsr_dir_open(&lfs, &dir, "ardvark") => 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) => LFS_ERR_NOENT; + lfsr_dir_close(&lfs, &dir) => 0; + lfsr_unmount(&lfs) => 0; ''' @@ -519,6 +516,42 @@ code = ''' lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT; lfsr_dir_close(&lfs, &dir) => 0; + lfsr_dir_open(&lfs, &dir, "ardvark") => 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) => LFS_ERR_NOENT; + lfsr_dir_close(&lfs, &dir) => 0; + + lfsr_dir_open(&lfs, &dir, "banana") => 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) => LFS_ERR_NOENT; + lfsr_dir_close(&lfs, &dir) => 0; + + lfsr_dir_open(&lfs, &dir, "cat") => 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) => LFS_ERR_NOENT; + lfsr_dir_close(&lfs, &dir) => 0; + lfsr_unmount(&lfs) => 0; ''' @@ -690,6 +723,18 @@ code = ''' lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT; lfsr_dir_close(&lfs, &dir) => 0; + lfsr_dir_open(&lfs, &dir, "/ardvark/banana/cat") => 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) => LFS_ERR_NOENT; + lfsr_dir_close(&lfs, &dir) => 0; + lfsr_unmount(&lfs) => 0; ''' @@ -757,6 +802,22 @@ code = ''' lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT; lfsr_dir_close(&lfs, &dir) => 0; + for (lfs_size_t i = 0; i < N; i++) { + char name[256]; + sprintf(name, "dir%04d", i); + lfsr_dir_open(&lfs, &dir, name) => 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) => LFS_ERR_NOENT; + lfsr_dir_close(&lfs, &dir) => 0; + } + lfsr_unmount(&lfs) => 0; ''' @@ -824,6 +885,22 @@ code = ''' lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT; lfsr_dir_close(&lfs, &dir) => 0; + for (lfs_size_t i = 0; i < N; i++) { + char name[256]; + sprintf(name, "dir%04d", i); + lfsr_dir_open(&lfs, &dir, name) => 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) => LFS_ERR_NOENT; + lfsr_dir_close(&lfs, &dir) => 0; + } + lfsr_unmount(&lfs) => 0; ''' @@ -933,6 +1010,24 @@ code = ''' lfsr_dir_close(&lfs, &dir) => 0; } + for (lfs_size_t i = 0; i < N; i++) { + for (lfs_size_t j = 0; j < N; j++) { + char name[256]; + sprintf(name, "dir%04d/child%04d", i, j); + lfsr_dir_open(&lfs, &dir, name) => 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) => LFS_ERR_NOENT; + lfsr_dir_close(&lfs, &dir) => 0; + } + } + lfsr_unmount(&lfs) => 0; ''' @@ -1084,6 +1179,26 @@ code = ''' } } + for (lfs_size_t i = 0; i < N; i++) { + for (lfs_size_t j = 0; j < N; j++) { + for (lfs_size_t k = 0; k < N; k++) { + char name[256]; + sprintf(name, "dir%04d/child%04d/grandchild%04d", i, j, k); + lfsr_dir_open(&lfs, &dir, name) => 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) => LFS_ERR_NOENT; + lfsr_dir_close(&lfs, &dir) => 0; + } + } + } + lfsr_unmount(&lfs) => 0; ''' @@ -1259,6 +1374,22 @@ code = ''' lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT; lfsr_dir_close(&lfs, &dir) => 0; + for (lfs_size_t j = 0; j < sim_size; j++) { + char name[256]; + sprintf(name, "%s/dir%04d", ((PARENT) ? "pricklypear" : ""), sim[j]); + lfsr_dir_open(&lfs, &dir, name) => 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) => LFS_ERR_NOENT; + lfsr_dir_close(&lfs, &dir) => 0; + } + // clean up sim/lfs free(sim); lfsr_unmount(&lfs) => 0;