Browse Source

Fixed testing issues introduced by expanding superblocks

This was mostly tweaking test cases to be accommodating for variable
sized superblock-lists. Though there were a few bugs that needed fixing:
- Changed compact to use source dir for move since the original dir
  could have changed as a result of an expand.
- Created copy of current directory so we don't overwrite ourselves
  during an internal commit update.

Also made sure all of the test suites provide reproducable results when
ran independently (the entry tests were behaving differently based on
which tests were ran before).

(Some where legitimate test failures)
Christopher Haster 7 years ago
parent
commit
3b3981eb74
3 changed files with 85 additions and 31 deletions
  1. 7 3
      lfs.c
  2. 76 27
      tests/test_alloc.sh
  3. 2 1
      tests/test_entries.sh

+ 7 - 3
lfs.c

@@ -658,7 +658,7 @@ static int lfs_commit_move(lfs_t *lfs, struct lfs_commit *commit,
             int32_t res = lfs_commit_get(lfs, commit->block,
             int32_t res = lfs_commit_get(lfs, commit->block,
                     commit->off, commit->ptag,
                     commit->off, commit->ptag,
                     lfs_tag_isuser(tag) ? 0x7ffff000 : 0x7c3ff000,
                     lfs_tag_isuser(tag) ? 0x7ffff000 : 0x7c3ff000,
-                    LFS_MKTAG(lfs_tag_type(tag), toid, 0),
+                    (tag & 0x7fc00000) | LFS_MKTAG(0, toid, 0),
                     0, NULL, true);
                     0, NULL, true);
             if (res < 0 && res != LFS_ERR_NOENT) {
             if (res < 0 && res != LFS_ERR_NOENT) {
                 return res;
                 return res;
@@ -1166,7 +1166,7 @@ split:
         tail.tail[0] = dir->tail[0];
         tail.tail[0] = dir->tail[0];
         tail.tail[1] = dir->tail[1];
         tail.tail[1] = dir->tail[1];
 
 
-        err = lfs_dir_compact(lfs, &tail, attrs, dir, ack+1-expanding, end);
+        err = lfs_dir_compact(lfs, &tail, attrs, source, ack+1-expanding, end);
         if (err) {
         if (err) {
             return err;
             return err;
         }
         }
@@ -1346,8 +1346,12 @@ compact:
     lfs_global_xor(&lfs->globals, &canceldiff);
     lfs_global_xor(&lfs->globals, &canceldiff);
 
 
     // update any directories that are affected
     // update any directories that are affected
+    lfs_mdir_t copy = *dir;
+
+    // two passes, once for things that aren't us, and one
+    // for things that are
     for (lfs_mlist_t *d = lfs->mlist; d; d = d->next) {
     for (lfs_mlist_t *d = lfs->mlist; d; d = d->next) {
-        if (lfs_pair_cmp(d->m.pair, dir->pair) == 0) {
+        if (lfs_pair_cmp(d->m.pair, copy.pair) == 0) {
             d->m = *dir;
             d->m = *dir;
             if (d->id == lfs_tag_id(deletetag)) {
             if (d->id == lfs_tag_id(deletetag)) {
                 d->m.pair[0] = 0xffffffff;
                 d->m.pair[0] = 0xffffffff;

+ 76 - 27
tests/test_alloc.sh

@@ -194,56 +194,99 @@ tests/test.py << TEST
     lfs_file_read(&lfs, &file[0], buffer, size) => size;
     lfs_file_read(&lfs, &file[0], buffer, size) => size;
     memcmp(buffer, "exhaustion", size) => 0;
     memcmp(buffer, "exhaustion", size) => 0;
     lfs_file_close(&lfs, &file[0]) => 0;
     lfs_file_close(&lfs, &file[0]) => 0;
+    lfs_remove(&lfs, "exhaustion") => 0;
     lfs_unmount(&lfs) => 0;
     lfs_unmount(&lfs) => 0;
 TEST
 TEST
 
 
 echo "--- Dir exhaustion test ---"
 echo "--- Dir exhaustion test ---"
 tests/test.py << TEST
 tests/test.py << TEST
     lfs_mount(&lfs, &cfg) => 0;
     lfs_mount(&lfs, &cfg) => 0;
-    lfs_remove(&lfs, "exhaustion") => 0;
 
 
-    lfs_file_open(&lfs, &file[0], "exhaustion", LFS_O_WRONLY | LFS_O_CREAT);
+    // find out max file size
+    lfs_mkdir(&lfs, "exhaustiondir") => 0;
     size = strlen("blahblahblahblah");
     size = strlen("blahblahblahblah");
     memcpy(buffer, "blahblahblahblah", size);
     memcpy(buffer, "blahblahblahblah", size);
-    for (lfs_size_t i = 0;
-            i < (cfg.block_count-4)*(cfg.block_size-8);
-            i += size) {
+    lfs_file_open(&lfs, &file[0], "exhaustion", LFS_O_WRONLY | LFS_O_CREAT);
+    int count = 0;
+    int err;
+    while (true) {
+        err = lfs_file_write(&lfs, &file[0], buffer, size);
+        if (err < 0) {
+            break;
+        }
+
+        count += 1;
+    }
+    err => LFS_ERR_NOSPC;
+    lfs_file_close(&lfs, &file[0]) => 0;
+
+    lfs_remove(&lfs, "exhaustion") => 0;
+    lfs_remove(&lfs, "exhaustiondir") => 0;
+
+    // see if dir fits with max file size
+    lfs_file_open(&lfs, &file[0], "exhaustion", LFS_O_WRONLY | LFS_O_CREAT);
+    for (int i = 0; i < count; i++) {
         lfs_file_write(&lfs, &file[0], buffer, size) => size;
         lfs_file_write(&lfs, &file[0], buffer, size) => size;
     }
     }
     lfs_file_close(&lfs, &file[0]) => 0;
     lfs_file_close(&lfs, &file[0]) => 0;
 
 
     lfs_mkdir(&lfs, "exhaustiondir") => 0;
     lfs_mkdir(&lfs, "exhaustiondir") => 0;
     lfs_remove(&lfs, "exhaustiondir") => 0;
     lfs_remove(&lfs, "exhaustiondir") => 0;
+    lfs_remove(&lfs, "exhaustion") => 0;
 
 
-    lfs_file_open(&lfs, &file[0], "exhaustion", LFS_O_WRONLY | LFS_O_APPEND);
-    size = strlen("blahblahblahblah");
-    memcpy(buffer, "blahblahblahblah", size);
-    for (lfs_size_t i = 0;
-            i < (cfg.block_size-8);
-            i += size) {
+    // see if dir fits with > max file size
+    lfs_file_open(&lfs, &file[0], "exhaustion", LFS_O_WRONLY | LFS_O_CREAT);
+    for (int i = 0; i < count+1; i++) {
         lfs_file_write(&lfs, &file[0], buffer, size) => size;
         lfs_file_write(&lfs, &file[0], buffer, size) => size;
     }
     }
     lfs_file_close(&lfs, &file[0]) => 0;
     lfs_file_close(&lfs, &file[0]) => 0;
 
 
     lfs_mkdir(&lfs, "exhaustiondir") => LFS_ERR_NOSPC;
     lfs_mkdir(&lfs, "exhaustiondir") => LFS_ERR_NOSPC;
+
+    lfs_remove(&lfs, "exhaustion") => 0;
     lfs_unmount(&lfs) => 0;
     lfs_unmount(&lfs) => 0;
 TEST
 TEST
 
 
 echo "--- Chained dir exhaustion test ---"
 echo "--- Chained dir exhaustion test ---"
 tests/test.py << TEST
 tests/test.py << TEST
     lfs_mount(&lfs, &cfg) => 0;
     lfs_mount(&lfs, &cfg) => 0;
-    lfs_remove(&lfs, "exhaustion") => 0;
 
 
-    lfs_file_open(&lfs, &file[0], "exhaustion", LFS_O_WRONLY | LFS_O_CREAT);
+    // find out max file size
+    lfs_mkdir(&lfs, "exhaustiondir") => 0;
+    for (int i = 0; i < 9; i++) {
+        sprintf((char*)buffer, "dirwithanexhaustivelylongnameforpadding%d", i);
+        lfs_mkdir(&lfs, (char*)buffer) => 0;
+    }
     size = strlen("blahblahblahblah");
     size = strlen("blahblahblahblah");
     memcpy(buffer, "blahblahblahblah", size);
     memcpy(buffer, "blahblahblahblah", size);
-    for (lfs_size_t i = 0;
-            i < (cfg.block_count-24)*(cfg.block_size-8);
-            i += size) {
-        lfs_file_write(&lfs, &file[0], buffer, size) => size;
+    lfs_file_open(&lfs, &file[0], "exhaustion", LFS_O_WRONLY | LFS_O_CREAT);
+    int count = 0;
+    int err;
+    while (true) {
+        err = lfs_file_write(&lfs, &file[0], buffer, size);
+        if (err < 0) {
+            break;
+        }
+
+        count += 1;
     }
     }
+    err => LFS_ERR_NOSPC;
     lfs_file_close(&lfs, &file[0]) => 0;
     lfs_file_close(&lfs, &file[0]) => 0;
 
 
+    lfs_remove(&lfs, "exhaustion") => 0;
+    lfs_remove(&lfs, "exhaustiondir") => 0;
+    for (int i = 0; i < 9; i++) {
+        sprintf((char*)buffer, "dirwithanexhaustivelylongnameforpadding%d", i);
+        lfs_remove(&lfs, (char*)buffer) => 0;
+    }
+
+    // see that chained dir fails
+    lfs_file_open(&lfs, &file[0], "exhaustion", LFS_O_WRONLY | LFS_O_CREAT);
+    for (int i = 0; i < count+1; i++) {
+        lfs_file_write(&lfs, &file[0], buffer, size) => size;
+    }
+    lfs_file_sync(&lfs, &file[0]) => 0;
+
     for (int i = 0; i < 9; i++) {
     for (int i = 0; i < 9; i++) {
         sprintf((char*)buffer, "dirwithanexhaustivelylongnameforpadding%d", i);
         sprintf((char*)buffer, "dirwithanexhaustivelylongnameforpadding%d", i);
         lfs_mkdir(&lfs, (char*)buffer) => 0;
         lfs_mkdir(&lfs, (char*)buffer) => 0;
@@ -251,19 +294,25 @@ tests/test.py << TEST
 
 
     lfs_mkdir(&lfs, "exhaustiondir") => LFS_ERR_NOSPC;
     lfs_mkdir(&lfs, "exhaustiondir") => LFS_ERR_NOSPC;
 
 
-    lfs_remove(&lfs, "exhaustion") => 0;
-    lfs_file_open(&lfs, &file[0], "exhaustion", LFS_O_WRONLY | LFS_O_CREAT);
-    size = strlen("blahblahblahblah");
-    memcpy(buffer, "blahblahblahblah", size);
-    for (lfs_size_t i = 0;
-            i < (cfg.block_count-26)*(cfg.block_size-8);
-            i += size) {
-        lfs_file_write(&lfs, &file[0], buffer, size) => size;
+    // shorten file to try a second chained dir
+    while (true) {
+        err = lfs_mkdir(&lfs, "exhaustiondir");
+        if (err != LFS_ERR_NOSPC) {
+            break;
+        }
+
+        lfs_ssize_t filesize = lfs_file_size(&lfs, &file[0]);
+        filesize > 0 => true;
+
+        lfs_file_truncate(&lfs, &file[0], filesize - size) => 0;
+        lfs_file_sync(&lfs, &file[0]) => 0;
     }
     }
-    lfs_file_close(&lfs, &file[0]) => 0;
+    err => 0;
 
 
-    lfs_mkdir(&lfs, "exhaustiondir") => 0;
     lfs_mkdir(&lfs, "exhaustiondir2") => LFS_ERR_NOSPC;
     lfs_mkdir(&lfs, "exhaustiondir2") => LFS_ERR_NOSPC;
+
+    lfs_file_close(&lfs, &file[0]) => 0;
+    lfs_unmount(&lfs) => 0;
 TEST
 TEST
 
 
 echo "--- Split dir test ---"
 echo "--- Split dir test ---"

+ 2 - 1
tests/test_entries.sh

@@ -4,7 +4,8 @@ set -eu
 # Note: These tests are intended for 512 byte inline size at different
 # Note: These tests are intended for 512 byte inline size at different
 # inline sizes they should still pass, but won't be testing anything
 # inline sizes they should still pass, but won't be testing anything
 
 
-echo "=== Directory tests ==="
+echo "=== Entry tests ==="
+rm -rf blocks
 function read_file {
 function read_file {
 cat << TEST
 cat << TEST