mirror of
				https://github.com/eledio-devices/thirdparty-littlefs.git
				synced 2025-10-31 08:42:40 +01:00 
			
		
		
		
	Migrated bad-block tests
Even with adding better reentrance testing, the bad-block tests are still very useful at isolating the block eviction logic. This also required rewriting a bit of the internal testing wirework to allow custom block devices which opens up quite a bit more straegies for testing.
This commit is contained in:
		
							
								
								
									
										124
									
								
								scripts/test_.py
									
									
									
									
									
								
							
							
						
						
									
										124
									
								
								scripts/test_.py
									
									
									
									
									
								
							| @@ -19,6 +19,7 @@ | |||||||
| # x config chaining correct | # x config chaining correct | ||||||
| # - why can't gdb see my defines? | # - why can't gdb see my defines? | ||||||
| # - say no to internal? | # - say no to internal? | ||||||
|  | # - buffering stdout issues? | ||||||
|  |  | ||||||
| import toml | import toml | ||||||
| import glob | import glob | ||||||
| @@ -55,8 +56,79 @@ GLOBALS = """ | |||||||
| #include "filebd/lfs_filebd.h" | #include "filebd/lfs_filebd.h" | ||||||
| #include "rambd/lfs_rambd.h" | #include "rambd/lfs_rambd.h" | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
|  |  | ||||||
|  | extern const char *lfs_testbd_disk; | ||||||
|  | typedef union { | ||||||
|  |     lfs_filebd_t filebd; | ||||||
|  |     lfs_rambd_t rambd; | ||||||
|  | } lfs_testbd_t;  | ||||||
|  | struct lfs_testbd_config { | ||||||
|  |     struct lfs_filebd_config filecfg; | ||||||
|  |     struct lfs_rambd_config ramcfg; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | __attribute__((unused)) | ||||||
|  | static int lfs_testbd_createcfg(const struct lfs_config *cfg, | ||||||
|  |         const struct lfs_testbd_config *bdcfg) { | ||||||
|  |     if (lfs_testbd_disk) { | ||||||
|  |         return lfs_filebd_createcfg(cfg, lfs_testbd_disk, &bdcfg->filecfg); | ||||||
|  |     } else { | ||||||
|  |         return lfs_rambd_createcfg(cfg, &bdcfg->ramcfg); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | __attribute__((unused)) | ||||||
|  | static void lfs_testbd_destroy(const struct lfs_config *cfg) { | ||||||
|  |     if (lfs_testbd_disk) { | ||||||
|  |         lfs_filebd_destroy(cfg); | ||||||
|  |     } else { | ||||||
|  |         lfs_rambd_destroy(cfg); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | __attribute__((unused)) | ||||||
|  | static int lfs_testbd_read(const struct lfs_config *cfg, lfs_block_t block, | ||||||
|  |         lfs_off_t off, void *buffer, lfs_size_t size) { | ||||||
|  |     if (lfs_testbd_disk) { | ||||||
|  |         return lfs_filebd_read(cfg, block, off, buffer, size); | ||||||
|  |     } else { | ||||||
|  |         return lfs_rambd_read(cfg, block, off, buffer, size); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | __attribute__((unused)) | ||||||
|  | static int lfs_testbd_prog(const struct lfs_config *cfg, lfs_block_t block, | ||||||
|  |         lfs_off_t off, const void *buffer, lfs_size_t size) { | ||||||
|  |     if (lfs_testbd_disk) { | ||||||
|  |         return lfs_filebd_prog(cfg, block, off, buffer, size); | ||||||
|  |     } else { | ||||||
|  |         return lfs_rambd_prog(cfg, block, off, buffer, size); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | __attribute__((unused)) | ||||||
|  | static int lfs_testbd_erase(const struct lfs_config *cfg, lfs_block_t block) { | ||||||
|  |     if (lfs_testbd_disk) { | ||||||
|  |         return lfs_filebd_erase(cfg, block); | ||||||
|  |     } else { | ||||||
|  |         return lfs_rambd_erase(cfg, block); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | __attribute__((unused)) | ||||||
|  | static int lfs_testbd_sync(const struct lfs_config *cfg) { | ||||||
|  |     if (lfs_testbd_disk) { | ||||||
|  |         return lfs_filebd_sync(cfg); | ||||||
|  |     } else { | ||||||
|  |         return lfs_rambd_sync(cfg); | ||||||
|  |     } | ||||||
|  | } | ||||||
| """ | """ | ||||||
| DEFINES = { | DEFINES = { | ||||||
|  |     "LFS_BD_READ": "lfs_testbd_read", | ||||||
|  |     "LFS_BD_PROG": "lfs_testbd_prog", | ||||||
|  |     "LFS_BD_ERASE": "lfs_testbd_erase", | ||||||
|  |     "LFS_BD_SYNC": "lfs_testbd_sync", | ||||||
|     "LFS_READ_SIZE": 16, |     "LFS_READ_SIZE": 16, | ||||||
|     "LFS_PROG_SIZE": "LFS_READ_SIZE", |     "LFS_PROG_SIZE": "LFS_READ_SIZE", | ||||||
|     "LFS_BLOCK_SIZE": 512, |     "LFS_BLOCK_SIZE": 512, | ||||||
| @@ -68,11 +140,8 @@ DEFINES = { | |||||||
| } | } | ||||||
| PROLOGUE = """ | PROLOGUE = """ | ||||||
|     // prologue |     // prologue | ||||||
|     extern const char *LFS_DISK; |  | ||||||
|  |  | ||||||
|     __attribute__((unused)) lfs_t lfs; |     __attribute__((unused)) lfs_t lfs; | ||||||
|     __attribute__((unused)) lfs_filebd_t filebd; |     __attribute__((unused)) lfs_testbd_t bd; | ||||||
|     __attribute__((unused)) lfs_rambd_t rambd; |  | ||||||
|     __attribute__((unused)) lfs_file_t file; |     __attribute__((unused)) lfs_file_t file; | ||||||
|     __attribute__((unused)) lfs_dir_t dir; |     __attribute__((unused)) lfs_dir_t dir; | ||||||
|     __attribute__((unused)) struct lfs_info info; |     __attribute__((unused)) struct lfs_info info; | ||||||
| @@ -82,12 +151,11 @@ PROLOGUE = """ | |||||||
|     __attribute__((unused)) int err; |     __attribute__((unused)) int err; | ||||||
|      |      | ||||||
|     __attribute__((unused)) const struct lfs_config cfg = { |     __attribute__((unused)) const struct lfs_config cfg = { | ||||||
|         .context = LFS_DISK ? (void*)&filebd : (void*)&rambd, |         .context        = &bd, | ||||||
|         .read  = LFS_DISK ? &lfs_filebd_read  : &lfs_rambd_read, |         .read           = LFS_BD_READ, | ||||||
|         .prog  = LFS_DISK ? &lfs_filebd_prog  : &lfs_rambd_prog, |         .prog           = LFS_BD_PROG, | ||||||
|         .erase = LFS_DISK ? &lfs_filebd_erase : &lfs_rambd_erase, |         .erase          = LFS_BD_ERASE, | ||||||
|         .sync  = LFS_DISK ? &lfs_filebd_sync  : &lfs_rambd_sync, |         .sync           = LFS_BD_SYNC, | ||||||
|  |  | ||||||
|         .read_size      = LFS_READ_SIZE, |         .read_size      = LFS_READ_SIZE, | ||||||
|         .prog_size      = LFS_PROG_SIZE, |         .prog_size      = LFS_PROG_SIZE, | ||||||
|         .block_size     = LFS_BLOCK_SIZE, |         .block_size     = LFS_BLOCK_SIZE, | ||||||
| @@ -97,26 +165,16 @@ PROLOGUE = """ | |||||||
|         .lookahead_size = LFS_LOOKAHEAD_SIZE, |         .lookahead_size = LFS_LOOKAHEAD_SIZE, | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     __attribute__((unused)) const struct lfs_filebd_config filecfg = { |     __attribute__((unused)) const struct lfs_testbd_config bdcfg = { | ||||||
|         .erase_value = LFS_ERASE_VALUE, |         .filecfg.erase_value = LFS_ERASE_VALUE, | ||||||
|     }; |         .ramcfg.erase_value = LFS_ERASE_VALUE, | ||||||
|     __attribute__((unused)) const struct lfs_rambd_config ramcfg = { |  | ||||||
|         .erase_value = LFS_ERASE_VALUE, |  | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     if (LFS_DISK) { |     lfs_testbd_createcfg(&cfg, &bdcfg) => 0; | ||||||
|         lfs_filebd_createcfg(&cfg, LFS_DISK, &filecfg); |  | ||||||
|     } else { |  | ||||||
|         lfs_rambd_createcfg(&cfg, &ramcfg); |  | ||||||
|     } |  | ||||||
| """ | """ | ||||||
| EPILOGUE = """ | EPILOGUE = """ | ||||||
|     // epilogue |     // epilogue | ||||||
|     if (LFS_DISK) { |     lfs_testbd_destroy(&cfg); | ||||||
|         lfs_filebd_destroy(&cfg); |  | ||||||
|     } else { |  | ||||||
|         lfs_rambd_destroy(&cfg); |  | ||||||
|     } |  | ||||||
| """ | """ | ||||||
| PASS = '\033[32m✓\033[0m' | PASS = '\033[32m✓\033[0m' | ||||||
| FAIL = '\033[31m✗\033[0m' | FAIL = '\033[31m✗\033[0m' | ||||||
| @@ -363,15 +421,20 @@ class TestSuite: | |||||||
|                 if re.match(r'code\s*=\s*(\'\'\'|""")', line): |                 if re.match(r'code\s*=\s*(\'\'\'|""")', line): | ||||||
|                     code_linenos.append(i+2) |                     code_linenos.append(i+2) | ||||||
|  |  | ||||||
|  |             code_linenos.reverse() | ||||||
|  |  | ||||||
|         # grab global config |         # grab global config | ||||||
|         self.defines = config.get('define', {}) |         self.defines = config.get('define', {}) | ||||||
|  |         self.code = config.get('code', None) | ||||||
|  |         if self.code is not None: | ||||||
|  |             self.code_lineno = code_linenos.pop() | ||||||
|  |  | ||||||
|         # create initial test cases |         # create initial test cases | ||||||
|         self.cases = [] |         self.cases = [] | ||||||
|         for i, (case, lineno) in enumerate(zip(config['case'], linenos)): |         for i, (case, lineno) in enumerate(zip(config['case'], linenos)): | ||||||
|             # code lineno? |             # code lineno? | ||||||
|             if 'code' in case: |             if 'code' in case: | ||||||
|                 case['code_lineno'] = code_linenos.pop(0) |                 case['code_lineno'] = code_linenos.pop() | ||||||
|             # give our case's config a copy of our "global" config |             # give our case's config a copy of our "global" config | ||||||
|             for k, v in config.items(): |             for k, v in config.items(): | ||||||
|                 if k not in case: |                 if k not in case: | ||||||
| @@ -452,8 +515,11 @@ class TestSuite: | |||||||
|         # build test files |         # build test files | ||||||
|         tf = open(self.path + '.test.c.t', 'w') |         tf = open(self.path + '.test.c.t', 'w') | ||||||
|         tf.write(GLOBALS) |         tf.write(GLOBALS) | ||||||
|         tfs = {None: tf} |         if self.code is not None: | ||||||
|  |             tf.write('#line %d "%s"\n' % (self.code_lineno, self.path)) | ||||||
|  |             tf.write(self.code) | ||||||
|  |  | ||||||
|  |         tfs = {None: tf} | ||||||
|         for case in self.cases: |         for case in self.cases: | ||||||
|             if case.in_ not in tfs: |             if case.in_ not in tfs: | ||||||
|                 tfs[case.in_] = open(self.path+'.'+ |                 tfs[case.in_] = open(self.path+'.'+ | ||||||
| @@ -469,11 +535,11 @@ class TestSuite: | |||||||
|             case.build(tfs[case.in_], **args) |             case.build(tfs[case.in_], **args) | ||||||
|  |  | ||||||
|         tf.write('\n') |         tf.write('\n') | ||||||
|         tf.write('const char *LFS_DISK = NULL;\n') |         tf.write('const char *lfs_testbd_disk;\n') | ||||||
|         tf.write('int main(int argc, char **argv) {\n') |         tf.write('int main(int argc, char **argv) {\n') | ||||||
|         tf.write(4*' '+'int case_ = (argc >= 2) ? atoi(argv[1]) : 0;\n') |         tf.write(4*' '+'int case_ = (argc >= 2) ? atoi(argv[1]) : 0;\n') | ||||||
|         tf.write(4*' '+'int perm = (argc >= 3) ? atoi(argv[2]) : 0;\n') |         tf.write(4*' '+'int perm = (argc >= 3) ? atoi(argv[2]) : 0;\n') | ||||||
|         tf.write(4*' '+'LFS_DISK = (argc >= 4) ? argv[3] : NULL;\n') |         tf.write(4*' '+'lfs_testbd_disk = (argc >= 4) ? argv[3] : NULL;\n') | ||||||
|         for perm in self.perms: |         for perm in self.perms: | ||||||
|             # test declaration |             # test declaration | ||||||
|             tf.write(4*' '+'extern void test_case%d(%s);\n' % ( |             tf.write(4*' '+'extern void test_case%d(%s);\n' % ( | ||||||
|   | |||||||
							
								
								
									
										375
									
								
								tests_/test_badblocks.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										375
									
								
								tests_/test_badblocks.toml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,375 @@ | |||||||
|  | # special bad-block block device hook for simulating blocks | ||||||
|  | # that are no longer writable | ||||||
|  | code = ''' | ||||||
|  | lfs_block_t *bbbd_badblocks; | ||||||
|  | size_t bbbd_badblocks_count; | ||||||
|  |  | ||||||
|  | int bbbd_read(const struct lfs_config *c, lfs_block_t block, | ||||||
|  |         lfs_off_t off, void *buffer, lfs_size_t size) { | ||||||
|  |     for (size_t i = 0; i < bbbd_badblocks_count; i++) { | ||||||
|  |         if (bbbd_badblocks[i] == block) { | ||||||
|  |             return LFS_ERR_CORRUPT; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     return lfs_testbd_read(c, block, off, buffer, size); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int bbbd_prog(const struct lfs_config *c, lfs_block_t block, | ||||||
|  |         lfs_off_t off, const void *buffer, lfs_size_t size) { | ||||||
|  |     for (size_t i = 0; i < bbbd_badblocks_count; i++) { | ||||||
|  |         if (bbbd_badblocks[i] == block) { | ||||||
|  |             return LFS_ERR_CORRUPT; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     return lfs_testbd_prog(c, block, off, buffer, size); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int bbbd_erase(const struct lfs_config *c, lfs_block_t block) { | ||||||
|  |     for (size_t i = 0; i < bbbd_badblocks_count; i++) { | ||||||
|  |         if (bbbd_badblocks[i] == block) { | ||||||
|  |             return LFS_ERR_CORRUPT; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     return lfs_testbd_erase(c, block); | ||||||
|  | } | ||||||
|  | ''' | ||||||
|  |  | ||||||
|  | [[case]] # single bad blocks | ||||||
|  | define.LFS_BD_PROG = 'bbbd_prog' | ||||||
|  | define.NAMEMULT = 64 | ||||||
|  | define.FILEMULT = 1 | ||||||
|  | code = ''' | ||||||
|  |     for (lfs_block_t badblock = 2; badblock < LFS_BLOCK_COUNT; badblock++) { | ||||||
|  |         bbbd_badblocks = &(lfs_block_t){badblock}; | ||||||
|  |         bbbd_badblocks_count = 1; | ||||||
|  |          | ||||||
|  |         lfs_format(&lfs, &cfg) => 0; | ||||||
|  |  | ||||||
|  |         lfs_mount(&lfs, &cfg) => 0; | ||||||
|  |         for (int i = 1; i < 10; i++) { | ||||||
|  |             for (int j = 0; j < NAMEMULT; j++) { | ||||||
|  |                 buffer[j] = '0'+i; | ||||||
|  |             } | ||||||
|  |             buffer[NAMEMULT] = '\0'; | ||||||
|  |             lfs_mkdir(&lfs, (char*)buffer) => 0; | ||||||
|  |  | ||||||
|  |             buffer[NAMEMULT] = '/'; | ||||||
|  |             for (int j = 0; j < NAMEMULT; j++) { | ||||||
|  |                 buffer[j+NAMEMULT+1] = '0'+i; | ||||||
|  |             } | ||||||
|  |             buffer[2*NAMEMULT+1] = '\0'; | ||||||
|  |             lfs_file_open(&lfs, &file, (char*)buffer, | ||||||
|  |                     LFS_O_WRONLY | LFS_O_CREAT) => 0; | ||||||
|  |              | ||||||
|  |             size = NAMEMULT; | ||||||
|  |             for (int j = 0; j < i*FILEMULT; j++) { | ||||||
|  |                 lfs_file_write(&lfs, &file, buffer, size) => size; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             lfs_file_close(&lfs, &file) => 0; | ||||||
|  |         } | ||||||
|  |         lfs_unmount(&lfs) => 0; | ||||||
|  |  | ||||||
|  |         lfs_mount(&lfs, &cfg) => 0; | ||||||
|  |         for (int i = 1; i < 10; i++) { | ||||||
|  |             for (int j = 0; j < NAMEMULT; j++) { | ||||||
|  |                 buffer[j] = '0'+i; | ||||||
|  |             } | ||||||
|  |             buffer[NAMEMULT] = '\0'; | ||||||
|  |             lfs_stat(&lfs, (char*)buffer, &info) => 0; | ||||||
|  |             info.type => LFS_TYPE_DIR; | ||||||
|  |  | ||||||
|  |             buffer[NAMEMULT] = '/'; | ||||||
|  |             for (int j = 0; j < NAMEMULT; j++) { | ||||||
|  |                 buffer[j+NAMEMULT+1] = '0'+i; | ||||||
|  |             } | ||||||
|  |             buffer[2*NAMEMULT+1] = '\0'; | ||||||
|  |             lfs_file_open(&lfs, &file, (char*)buffer, LFS_O_RDONLY) => 0; | ||||||
|  |              | ||||||
|  |             size = NAMEMULT; | ||||||
|  |             for (int j = 0; j < i*FILEMULT; j++) { | ||||||
|  |                 uint8_t rbuffer[1024]; | ||||||
|  |                 lfs_file_read(&lfs, &file, rbuffer, size) => size; | ||||||
|  |                 memcmp(buffer, rbuffer, size) => 0; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             lfs_file_close(&lfs, &file) => 0; | ||||||
|  |         } | ||||||
|  |         lfs_unmount(&lfs) => 0; | ||||||
|  |     } | ||||||
|  | ''' | ||||||
|  |  | ||||||
|  | [[case]] # single persistent blocks (can't erase) | ||||||
|  | define.LFS_BD_ERASE = 'bbbd_erase' | ||||||
|  | define.NAMEMULT = 64 | ||||||
|  | define.FILEMULT = 1 | ||||||
|  | code = ''' | ||||||
|  |     for (lfs_block_t badblock = 2; badblock < LFS_BLOCK_COUNT; badblock++) { | ||||||
|  |         bbbd_badblocks = &(lfs_block_t){badblock}; | ||||||
|  |         bbbd_badblocks_count = 1; | ||||||
|  |          | ||||||
|  |         lfs_format(&lfs, &cfg) => 0; | ||||||
|  |  | ||||||
|  |         lfs_mount(&lfs, &cfg) => 0; | ||||||
|  |         for (int i = 1; i < 10; i++) { | ||||||
|  |             for (int j = 0; j < NAMEMULT; j++) { | ||||||
|  |                 buffer[j] = '0'+i; | ||||||
|  |             } | ||||||
|  |             buffer[NAMEMULT] = '\0'; | ||||||
|  |             lfs_mkdir(&lfs, (char*)buffer) => 0; | ||||||
|  |  | ||||||
|  |             buffer[NAMEMULT] = '/'; | ||||||
|  |             for (int j = 0; j < NAMEMULT; j++) { | ||||||
|  |                 buffer[j+NAMEMULT+1] = '0'+i; | ||||||
|  |             } | ||||||
|  |             buffer[2*NAMEMULT+1] = '\0'; | ||||||
|  |             lfs_file_open(&lfs, &file, (char*)buffer, | ||||||
|  |                     LFS_O_WRONLY | LFS_O_CREAT) => 0; | ||||||
|  |              | ||||||
|  |             size = NAMEMULT; | ||||||
|  |             for (int j = 0; j < i*FILEMULT; j++) { | ||||||
|  |                 lfs_file_write(&lfs, &file, buffer, size) => size; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             lfs_file_close(&lfs, &file) => 0; | ||||||
|  |         } | ||||||
|  |         lfs_unmount(&lfs) => 0; | ||||||
|  |  | ||||||
|  |         lfs_mount(&lfs, &cfg) => 0; | ||||||
|  |         for (int i = 1; i < 10; i++) { | ||||||
|  |             for (int j = 0; j < NAMEMULT; j++) { | ||||||
|  |                 buffer[j] = '0'+i; | ||||||
|  |             } | ||||||
|  |             buffer[NAMEMULT] = '\0'; | ||||||
|  |             lfs_stat(&lfs, (char*)buffer, &info) => 0; | ||||||
|  |             info.type => LFS_TYPE_DIR; | ||||||
|  |  | ||||||
|  |             buffer[NAMEMULT] = '/'; | ||||||
|  |             for (int j = 0; j < NAMEMULT; j++) { | ||||||
|  |                 buffer[j+NAMEMULT+1] = '0'+i; | ||||||
|  |             } | ||||||
|  |             buffer[2*NAMEMULT+1] = '\0'; | ||||||
|  |             lfs_file_open(&lfs, &file, (char*)buffer, LFS_O_RDONLY) => 0; | ||||||
|  |              | ||||||
|  |             size = NAMEMULT; | ||||||
|  |             for (int j = 0; j < i*FILEMULT; j++) { | ||||||
|  |                 uint8_t rbuffer[1024]; | ||||||
|  |                 lfs_file_read(&lfs, &file, rbuffer, size) => size; | ||||||
|  |                 memcmp(buffer, rbuffer, size) => 0; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             lfs_file_close(&lfs, &file) => 0; | ||||||
|  |         } | ||||||
|  |         lfs_unmount(&lfs) => 0; | ||||||
|  |     } | ||||||
|  | ''' | ||||||
|  |  | ||||||
|  | [[case]] # single unreadable blocks (can't read) | ||||||
|  | define.LFS_BD_READ = 'bbbd_read' | ||||||
|  | define.NAMEMULT = 64 | ||||||
|  | define.FILEMULT = 1 | ||||||
|  | code = ''' | ||||||
|  |     for (lfs_block_t badblock = 2; badblock < LFS_BLOCK_COUNT; badblock++) { | ||||||
|  |         bbbd_badblocks = &(lfs_block_t){badblock}; | ||||||
|  |         bbbd_badblocks_count = 1; | ||||||
|  |          | ||||||
|  |         lfs_format(&lfs, &cfg) => 0; | ||||||
|  |  | ||||||
|  |         lfs_mount(&lfs, &cfg) => 0; | ||||||
|  |         for (int i = 1; i < 10; i++) { | ||||||
|  |             for (int j = 0; j < NAMEMULT; j++) { | ||||||
|  |                 buffer[j] = '0'+i; | ||||||
|  |             } | ||||||
|  |             buffer[NAMEMULT] = '\0'; | ||||||
|  |             lfs_mkdir(&lfs, (char*)buffer) => 0; | ||||||
|  |  | ||||||
|  |             buffer[NAMEMULT] = '/'; | ||||||
|  |             for (int j = 0; j < NAMEMULT; j++) { | ||||||
|  |                 buffer[j+NAMEMULT+1] = '0'+i; | ||||||
|  |             } | ||||||
|  |             buffer[2*NAMEMULT+1] = '\0'; | ||||||
|  |             lfs_file_open(&lfs, &file, (char*)buffer, | ||||||
|  |                     LFS_O_WRONLY | LFS_O_CREAT) => 0; | ||||||
|  |              | ||||||
|  |             size = NAMEMULT; | ||||||
|  |             for (int j = 0; j < i*FILEMULT; j++) { | ||||||
|  |                 lfs_file_write(&lfs, &file, buffer, size) => size; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             lfs_file_close(&lfs, &file) => 0; | ||||||
|  |         } | ||||||
|  |         lfs_unmount(&lfs) => 0; | ||||||
|  |  | ||||||
|  |         lfs_mount(&lfs, &cfg) => 0; | ||||||
|  |         for (int i = 1; i < 10; i++) { | ||||||
|  |             for (int j = 0; j < NAMEMULT; j++) { | ||||||
|  |                 buffer[j] = '0'+i; | ||||||
|  |             } | ||||||
|  |             buffer[NAMEMULT] = '\0'; | ||||||
|  |             lfs_stat(&lfs, (char*)buffer, &info) => 0; | ||||||
|  |             info.type => LFS_TYPE_DIR; | ||||||
|  |  | ||||||
|  |             buffer[NAMEMULT] = '/'; | ||||||
|  |             for (int j = 0; j < NAMEMULT; j++) { | ||||||
|  |                 buffer[j+NAMEMULT+1] = '0'+i; | ||||||
|  |             } | ||||||
|  |             buffer[2*NAMEMULT+1] = '\0'; | ||||||
|  |             lfs_file_open(&lfs, &file, (char*)buffer, LFS_O_RDONLY) => 0; | ||||||
|  |              | ||||||
|  |             size = NAMEMULT; | ||||||
|  |             for (int j = 0; j < i*FILEMULT; j++) { | ||||||
|  |                 uint8_t rbuffer[1024]; | ||||||
|  |                 lfs_file_read(&lfs, &file, rbuffer, size) => size; | ||||||
|  |                 memcmp(buffer, rbuffer, size) => 0; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             lfs_file_close(&lfs, &file) => 0; | ||||||
|  |         } | ||||||
|  |         lfs_unmount(&lfs) => 0; | ||||||
|  |     } | ||||||
|  | ''' | ||||||
|  |  | ||||||
|  | [[case]] # region corruption (causes cascading failures) | ||||||
|  | define.LFS_BD_PROG  = '"BADTYPE == 0 ? bbbd_prog  : lfs_testbd_prog "' | ||||||
|  | define.LFS_BD_ERASE = '"BADTYPE == 1 ? bbbd_erase : lfs_testbd_erase"' | ||||||
|  | define.LFS_BD_READ  = '"BADTYPE == 2 ? bbbd_read  : lfs_testbd_read "' | ||||||
|  | define.BADTYPE = 'range(3)' | ||||||
|  | define.NAMEMULT = 64 | ||||||
|  | define.FILEMULT = 1 | ||||||
|  | code = ''' | ||||||
|  |     bbbd_badblocks_count = LFS_BLOCK_COUNT/2; | ||||||
|  |     bbbd_badblocks = malloc(bbbd_badblocks_count*sizeof(lfs_block_t)); | ||||||
|  |     for (size_t i = 0; i < bbbd_badblocks_count; i++) { | ||||||
|  |         bbbd_badblocks[i] = i+2; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     lfs_format(&lfs, &cfg) => 0; | ||||||
|  |  | ||||||
|  |     lfs_mount(&lfs, &cfg) => 0; | ||||||
|  |     for (int i = 1; i < 10; i++) { | ||||||
|  |         for (int j = 0; j < NAMEMULT; j++) { | ||||||
|  |             buffer[j] = '0'+i; | ||||||
|  |         } | ||||||
|  |         buffer[NAMEMULT] = '\0'; | ||||||
|  |         lfs_mkdir(&lfs, (char*)buffer) => 0; | ||||||
|  |  | ||||||
|  |         buffer[NAMEMULT] = '/'; | ||||||
|  |         for (int j = 0; j < NAMEMULT; j++) { | ||||||
|  |             buffer[j+NAMEMULT+1] = '0'+i; | ||||||
|  |         } | ||||||
|  |         buffer[2*NAMEMULT+1] = '\0'; | ||||||
|  |         lfs_file_open(&lfs, &file, (char*)buffer, | ||||||
|  |                 LFS_O_WRONLY | LFS_O_CREAT) => 0; | ||||||
|  |          | ||||||
|  |         size = NAMEMULT; | ||||||
|  |         for (int j = 0; j < i*FILEMULT; j++) { | ||||||
|  |             lfs_file_write(&lfs, &file, buffer, size) => size; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         lfs_file_close(&lfs, &file) => 0; | ||||||
|  |     } | ||||||
|  |     lfs_unmount(&lfs) => 0; | ||||||
|  |  | ||||||
|  |     lfs_mount(&lfs, &cfg) => 0; | ||||||
|  |     for (int i = 1; i < 10; i++) { | ||||||
|  |         for (int j = 0; j < NAMEMULT; j++) { | ||||||
|  |             buffer[j] = '0'+i; | ||||||
|  |         } | ||||||
|  |         buffer[NAMEMULT] = '\0'; | ||||||
|  |         lfs_stat(&lfs, (char*)buffer, &info) => 0; | ||||||
|  |         info.type => LFS_TYPE_DIR; | ||||||
|  |  | ||||||
|  |         buffer[NAMEMULT] = '/'; | ||||||
|  |         for (int j = 0; j < NAMEMULT; j++) { | ||||||
|  |             buffer[j+NAMEMULT+1] = '0'+i; | ||||||
|  |         } | ||||||
|  |         buffer[2*NAMEMULT+1] = '\0'; | ||||||
|  |         lfs_file_open(&lfs, &file, (char*)buffer, LFS_O_RDONLY) => 0; | ||||||
|  |          | ||||||
|  |         size = NAMEMULT; | ||||||
|  |         for (int j = 0; j < i*FILEMULT; j++) { | ||||||
|  |             uint8_t rbuffer[1024]; | ||||||
|  |             lfs_file_read(&lfs, &file, rbuffer, size) => size; | ||||||
|  |             memcmp(buffer, rbuffer, size) => 0; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         lfs_file_close(&lfs, &file) => 0; | ||||||
|  |     } | ||||||
|  |     lfs_unmount(&lfs) => 0; | ||||||
|  |  | ||||||
|  |     free(bbbd_badblocks); | ||||||
|  | ''' | ||||||
|  |  | ||||||
|  | [[case]] # alternating corruption (causes cascading failures) | ||||||
|  | define.LFS_BD_PROG  = '"BADTYPE == 0 ? bbbd_prog  : lfs_testbd_prog "' | ||||||
|  | define.LFS_BD_ERASE = '"BADTYPE == 1 ? bbbd_erase : lfs_testbd_erase"' | ||||||
|  | define.LFS_BD_READ  = '"BADTYPE == 2 ? bbbd_read  : lfs_testbd_read "' | ||||||
|  | define.BADTYPE = 'range(3)' | ||||||
|  | define.NAMEMULT = 64 | ||||||
|  | define.FILEMULT = 1 | ||||||
|  | code = ''' | ||||||
|  |     bbbd_badblocks_count = LFS_BLOCK_COUNT/2; | ||||||
|  |     bbbd_badblocks = malloc(bbbd_badblocks_count*sizeof(lfs_block_t)); | ||||||
|  |     for (size_t i = 0; i < bbbd_badblocks_count; i++) { | ||||||
|  |         bbbd_badblocks[i] = (2*i) + 2; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     lfs_format(&lfs, &cfg) => 0; | ||||||
|  |  | ||||||
|  |     lfs_mount(&lfs, &cfg) => 0; | ||||||
|  |     for (int i = 1; i < 10; i++) { | ||||||
|  |         for (int j = 0; j < NAMEMULT; j++) { | ||||||
|  |             buffer[j] = '0'+i; | ||||||
|  |         } | ||||||
|  |         buffer[NAMEMULT] = '\0'; | ||||||
|  |         lfs_mkdir(&lfs, (char*)buffer) => 0; | ||||||
|  |  | ||||||
|  |         buffer[NAMEMULT] = '/'; | ||||||
|  |         for (int j = 0; j < NAMEMULT; j++) { | ||||||
|  |             buffer[j+NAMEMULT+1] = '0'+i; | ||||||
|  |         } | ||||||
|  |         buffer[2*NAMEMULT+1] = '\0'; | ||||||
|  |         lfs_file_open(&lfs, &file, (char*)buffer, | ||||||
|  |                 LFS_O_WRONLY | LFS_O_CREAT) => 0; | ||||||
|  |          | ||||||
|  |         size = NAMEMULT; | ||||||
|  |         for (int j = 0; j < i*FILEMULT; j++) { | ||||||
|  |             lfs_file_write(&lfs, &file, buffer, size) => size; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         lfs_file_close(&lfs, &file) => 0; | ||||||
|  |     } | ||||||
|  |     lfs_unmount(&lfs) => 0; | ||||||
|  |  | ||||||
|  |     lfs_mount(&lfs, &cfg) => 0; | ||||||
|  |     for (int i = 1; i < 10; i++) { | ||||||
|  |         for (int j = 0; j < NAMEMULT; j++) { | ||||||
|  |             buffer[j] = '0'+i; | ||||||
|  |         } | ||||||
|  |         buffer[NAMEMULT] = '\0'; | ||||||
|  |         lfs_stat(&lfs, (char*)buffer, &info) => 0; | ||||||
|  |         info.type => LFS_TYPE_DIR; | ||||||
|  |  | ||||||
|  |         buffer[NAMEMULT] = '/'; | ||||||
|  |         for (int j = 0; j < NAMEMULT; j++) { | ||||||
|  |             buffer[j+NAMEMULT+1] = '0'+i; | ||||||
|  |         } | ||||||
|  |         buffer[2*NAMEMULT+1] = '\0'; | ||||||
|  |         lfs_file_open(&lfs, &file, (char*)buffer, LFS_O_RDONLY) => 0; | ||||||
|  |          | ||||||
|  |         size = NAMEMULT; | ||||||
|  |         for (int j = 0; j < i*FILEMULT; j++) { | ||||||
|  |             uint8_t rbuffer[1024]; | ||||||
|  |             lfs_file_read(&lfs, &file, rbuffer, size) => size; | ||||||
|  |             memcmp(buffer, rbuffer, size) => 0; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         lfs_file_close(&lfs, &file) => 0; | ||||||
|  |     } | ||||||
|  |     lfs_unmount(&lfs) => 0; | ||||||
|  |  | ||||||
|  |     free(bbbd_badblocks); | ||||||
|  | ''' | ||||||
		Reference in New Issue
	
	Block a user