mirror of
				https://github.com/eledio-devices/thirdparty-littlefs.git
				synced 2025-10-31 08:42:40 +01:00 
			
		
		
		
	Generated v2 prefixes
This commit is contained in:
		
							
								
								
									
										120
									
								
								tests/test_orphans.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										120
									
								
								tests/test_orphans.toml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,120 @@ | ||||
| [[case]] # orphan test | ||||
| in = "lfs2.c" | ||||
| if = 'LFS2_PROG_SIZE <= 0x3fe' # only works with one crc per commit | ||||
| code = ''' | ||||
|     lfs2_format(&lfs2, &cfg) => 0; | ||||
|     lfs2_mount(&lfs2, &cfg) => 0; | ||||
|     lfs2_mkdir(&lfs2, "parent") => 0; | ||||
|     lfs2_mkdir(&lfs2, "parent/orphan") => 0; | ||||
|     lfs2_mkdir(&lfs2, "parent/child") => 0; | ||||
|     lfs2_remove(&lfs2, "parent/orphan") => 0; | ||||
|     lfs2_unmount(&lfs2) => 0; | ||||
|  | ||||
|     // corrupt the child's most recent commit, this should be the update | ||||
|     // to the linked-list entry, which should orphan the orphan. Note this | ||||
|     // makes a lot of assumptions about the remove operation. | ||||
|     lfs2_mount(&lfs2, &cfg) => 0; | ||||
|     lfs2_dir_open(&lfs2, &dir, "parent/child") => 0; | ||||
|     lfs2_block_t block = dir.m.pair[0]; | ||||
|     lfs2_dir_close(&lfs2, &dir) => 0; | ||||
|     lfs2_unmount(&lfs2) => 0; | ||||
|     uint8_t bbuffer[LFS2_BLOCK_SIZE]; | ||||
|     cfg.read(&cfg, block, 0, bbuffer, LFS2_BLOCK_SIZE) => 0; | ||||
|     int off = LFS2_BLOCK_SIZE-1; | ||||
|     while (off >= 0 && bbuffer[off] == LFS2_ERASE_VALUE) { | ||||
|         off -= 1; | ||||
|     } | ||||
|     memset(&bbuffer[off-3], LFS2_BLOCK_SIZE, 3); | ||||
|     cfg.erase(&cfg, block) => 0; | ||||
|     cfg.prog(&cfg, block, 0, bbuffer, LFS2_BLOCK_SIZE) => 0; | ||||
|     cfg.sync(&cfg) => 0; | ||||
|  | ||||
|     lfs2_mount(&lfs2, &cfg) => 0; | ||||
|     lfs2_stat(&lfs2, "parent/orphan", &info) => LFS2_ERR_NOENT; | ||||
|     lfs2_stat(&lfs2, "parent/child", &info) => 0; | ||||
|     lfs2_fs_size(&lfs2) => 8; | ||||
|     lfs2_unmount(&lfs2) => 0; | ||||
|  | ||||
|     lfs2_mount(&lfs2, &cfg) => 0; | ||||
|     lfs2_stat(&lfs2, "parent/orphan", &info) => LFS2_ERR_NOENT; | ||||
|     lfs2_stat(&lfs2, "parent/child", &info) => 0; | ||||
|     lfs2_fs_size(&lfs2) => 8; | ||||
|     // this mkdir should both create a dir and deorphan, so size | ||||
|     // should be unchanged | ||||
|     lfs2_mkdir(&lfs2, "parent/otherchild") => 0; | ||||
|     lfs2_stat(&lfs2, "parent/orphan", &info) => LFS2_ERR_NOENT; | ||||
|     lfs2_stat(&lfs2, "parent/child", &info) => 0; | ||||
|     lfs2_stat(&lfs2, "parent/otherchild", &info) => 0; | ||||
|     lfs2_fs_size(&lfs2) => 8; | ||||
|     lfs2_unmount(&lfs2) => 0; | ||||
|  | ||||
|     lfs2_mount(&lfs2, &cfg) => 0; | ||||
|     lfs2_stat(&lfs2, "parent/orphan", &info) => LFS2_ERR_NOENT; | ||||
|     lfs2_stat(&lfs2, "parent/child", &info) => 0; | ||||
|     lfs2_stat(&lfs2, "parent/otherchild", &info) => 0; | ||||
|     lfs2_fs_size(&lfs2) => 8; | ||||
|     lfs2_unmount(&lfs2) => 0; | ||||
| ''' | ||||
|  | ||||
| [[case]] # reentrant testing for orphans, basically just spam mkdir/remove | ||||
| reentrant = true | ||||
| # TODO fix this case, caused by non-DAG trees | ||||
| if = '!(DEPTH == 3 && LFS2_CACHE_SIZE != 64)' | ||||
| define = [ | ||||
|     {FILES=6,  DEPTH=1, CYCLES=20}, | ||||
|     {FILES=26, DEPTH=1, CYCLES=20}, | ||||
|     {FILES=3,  DEPTH=3, CYCLES=20}, | ||||
| ] | ||||
| code = ''' | ||||
|     err = lfs2_mount(&lfs2, &cfg); | ||||
|     if (err) { | ||||
|         lfs2_format(&lfs2, &cfg) => 0; | ||||
|         lfs2_mount(&lfs2, &cfg) => 0; | ||||
|     } | ||||
|  | ||||
|     srand(1); | ||||
|     const char alpha[] = "abcdefghijklmnopqrstuvwxyz"; | ||||
|     for (int i = 0; i < CYCLES; i++) { | ||||
|         // create random path | ||||
|         char full_path[256]; | ||||
|         for (int d = 0; d < DEPTH; d++) { | ||||
|             sprintf(&full_path[2*d], "/%c", alpha[rand() % FILES]); | ||||
|         } | ||||
|  | ||||
|         // if it does not exist, we create it, else we destroy | ||||
|         int res = lfs2_stat(&lfs2, full_path, &info); | ||||
|         if (res == LFS2_ERR_NOENT) { | ||||
|             // create each directory in turn, ignore if dir already exists | ||||
|             for (int d = 0; d < DEPTH; d++) { | ||||
|                 strcpy(path, full_path); | ||||
|                 path[2*d+2] = '\0'; | ||||
|                 err = lfs2_mkdir(&lfs2, path); | ||||
|                 assert(!err || err == LFS2_ERR_EXIST); | ||||
|             } | ||||
|  | ||||
|             for (int d = 0; d < DEPTH; d++) { | ||||
|                 strcpy(path, full_path); | ||||
|                 path[2*d+2] = '\0'; | ||||
|                 lfs2_stat(&lfs2, path, &info) => 0; | ||||
|                 assert(strcmp(info.name, &path[2*d+1]) == 0); | ||||
|                 assert(info.type == LFS2_TYPE_DIR); | ||||
|             } | ||||
|         } else { | ||||
|             // is valid dir? | ||||
|             assert(strcmp(info.name, &full_path[2*(DEPTH-1)+1]) == 0); | ||||
|             assert(info.type == LFS2_TYPE_DIR); | ||||
|  | ||||
|             // try to delete path in reverse order, ignore if dir is not empty | ||||
|             for (int d = DEPTH-1; d >= 0; d--) { | ||||
|                 strcpy(path, full_path); | ||||
|                 path[2*d+2] = '\0'; | ||||
|                 err = lfs2_remove(&lfs2, path); | ||||
|                 assert(!err || err == LFS2_ERR_NOTEMPTY); | ||||
|             } | ||||
|  | ||||
|             lfs2_stat(&lfs2, full_path, &info) => LFS2_ERR_NOENT; | ||||
|         } | ||||
|     } | ||||
|     lfs2_unmount(&lfs2) => 0; | ||||
| ''' | ||||
|  | ||||
		Reference in New Issue
	
	Block a user