mirror of
				https://github.com/eledio-devices/thirdparty-littlefs.git
				synced 2025-10-31 08:42:40 +01:00 
			
		
		
		
	Added file read/write tests and some framework updates
This commit is contained in:
		| @@ -88,7 +88,7 @@ int lfs_emubd_read(lfs_emubd_t *emu, lfs_block_t block, | |||||||
|  |  | ||||||
|     // Iterate over blocks until enough data is read |     // Iterate over blocks until enough data is read | ||||||
|     while (size > 0) { |     while (size > 0) { | ||||||
|         snprintf(emu->child, LFS_NAME_MAX, "%d", block); |         snprintf(emu->child, LFS_NAME_MAX, "%x", block); | ||||||
|         size_t count = lfs_min(emu->info.erase_size - off, size); |         size_t count = lfs_min(emu->info.erase_size - off, size); | ||||||
|  |  | ||||||
|         FILE *f = fopen(emu->path, "rb"); |         FILE *f = fopen(emu->path, "rb"); | ||||||
| @@ -137,7 +137,7 @@ int lfs_emubd_prog(lfs_emubd_t *emu, lfs_block_t block, | |||||||
|  |  | ||||||
|     // Iterate over blocks until enough data is read |     // Iterate over blocks until enough data is read | ||||||
|     while (size > 0) { |     while (size > 0) { | ||||||
|         snprintf(emu->child, LFS_NAME_MAX, "%d", block); |         snprintf(emu->child, LFS_NAME_MAX, "%x", block); | ||||||
|         size_t count = lfs_min(emu->info.erase_size - off, size); |         size_t count = lfs_min(emu->info.erase_size - off, size); | ||||||
|  |  | ||||||
|         FILE *f = fopen(emu->path, "r+b"); |         FILE *f = fopen(emu->path, "r+b"); | ||||||
| @@ -186,7 +186,7 @@ int lfs_emubd_erase(lfs_emubd_t *emu, lfs_block_t block, | |||||||
|  |  | ||||||
|     // Iterate and erase blocks |     // Iterate and erase blocks | ||||||
|     while (size > 0) { |     while (size > 0) { | ||||||
|         snprintf(emu->child, LFS_NAME_MAX, "%d", block); |         snprintf(emu->child, LFS_NAME_MAX, "%x", block); | ||||||
|         struct stat st; |         struct stat st; | ||||||
|         int err = stat(emu->path, &st); |         int err = stat(emu->path, &st); | ||||||
|         if (err && errno != ENOENT) { |         if (err && errno != ENOENT) { | ||||||
|   | |||||||
| @@ -5,19 +5,31 @@ | |||||||
| #include <string.h> | #include <string.h> | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
|  |  | ||||||
|  |  | ||||||
| // test stuff | // test stuff | ||||||
| void test_log(const char *s, uintmax_t v) {{ | void test_log(const char *s, uintmax_t v) {{ | ||||||
|     printf("%s: %jd\n", s, v); |     printf("%s: %jd\n", s, v); | ||||||
| }} | }} | ||||||
|  |  | ||||||
| void test_assert(const char *s, uintmax_t v, uintmax_t e) {{ | void test_assert(const char *file, unsigned line, | ||||||
|     test_log(s, v); |         const char *s, uintmax_t v, uintmax_t e) {{ | ||||||
|  |     static const char *last[2] = {{0, 0}}; | ||||||
|  |     if (v != e || !(last[0] == s || last[1] == s)) {{ | ||||||
|  |         test_log(s, v); | ||||||
|  |         last[0] = last[1]; | ||||||
|  |         last[1] = s; | ||||||
|  |     }} | ||||||
|  |  | ||||||
|     if (v != e) {{ |     if (v != e) {{ | ||||||
|         printf("\033[31massert %s failed, expected %jd\033[0m\n", s, e); |         printf("\033[31m%s:%u: assert %s failed, expected %jd\033[0m\n", | ||||||
|  |                 file, line, s, e); | ||||||
|         exit(-2); |         exit(-2); | ||||||
|     }} |     }} | ||||||
| }} | }} | ||||||
|  |  | ||||||
|  | #define test_assert(s, v, e) test_assert(__FILE__, __LINE__, s, v, e) | ||||||
|  |  | ||||||
|  |  | ||||||
| // lfs declarations | // lfs declarations | ||||||
| lfs_t lfs; | lfs_t lfs; | ||||||
| lfs_emubd_t bd; | lfs_emubd_t bd; | ||||||
| @@ -42,6 +54,7 @@ const struct lfs_config config = {{ | |||||||
| }}; | }}; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | // Entry point | ||||||
| int main() {{ | int main() {{ | ||||||
|     lfs_emubd_create(&bd, "blocks"); |     lfs_emubd_create(&bd, "blocks"); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -11,22 +11,22 @@ def generate(test): | |||||||
|  |  | ||||||
|     lines = [] |     lines = [] | ||||||
|  |  | ||||||
|     for line in test: |     for line in re.split('(?<=[;{}])\n', test.read()): | ||||||
|         if '=>' in line: |         match = re.match('( *)(.*)=>(.*);', line, re.MULTILINE) | ||||||
|             test, expect = line.strip().strip(';').split('=>') |         if match: | ||||||
|             lines.append('res = {test};'.format(test=test.strip())) |             tab, test, expect = match.groups() | ||||||
|             lines.append('test_assert("{name}", res, {expect});'.format( |             lines.append(tab+'res = {test};'.format(test=test.strip())) | ||||||
|  |             lines.append(tab+'test_assert("{name}", res, {expect});'.format( | ||||||
|                     name = re.match('\w*', test.strip()).group(), |                     name = re.match('\w*', test.strip()).group(), | ||||||
|                     expect = expect.strip())) |                     expect = expect.strip())) | ||||||
|         else: |         else: | ||||||
|             lines.append(line.strip()) |             lines.append(line) | ||||||
|  |  | ||||||
|     with open('test.c', 'w') as file: |     with open('test.c', 'w') as file: | ||||||
|         file.write(template.format(tests='\n'.join(4*' ' + l for l in lines))) |         file.write(template.format(tests='\n'.join(lines))) | ||||||
|  |  | ||||||
| def compile(): | def compile(): | ||||||
|     os.environ['DEBUG'] = '1' |     os.environ['CFLAGS'] = os.environ.get('CFLAGS', '') + ' -Werror' | ||||||
|     os.environ['CFLAGS'] = '-Werror' |  | ||||||
|     subprocess.check_call(['make', '--no-print-directory', '-s'], env=os.environ) |     subprocess.check_call(['make', '--no-print-directory', '-s'], env=os.environ) | ||||||
|  |  | ||||||
| def execute(): | def execute(): | ||||||
|   | |||||||
| @@ -3,13 +3,16 @@ set -eu | |||||||
|  |  | ||||||
| echo "=== Directory tests ===" | echo "=== Directory tests ===" | ||||||
| rm -rf blocks | rm -rf blocks | ||||||
|  | tests/test.py << TEST | ||||||
|  |     lfs_format(&lfs, &config) => 0; | ||||||
|  | TEST | ||||||
|  |  | ||||||
| echo "--- Root directory ---" | echo "--- Root directory ---" | ||||||
| tests/test.py << TEST | tests/test.py << TEST | ||||||
|     lfs_format(&lfs, &config) => 0; |     lfs_mount(&lfs, &config) => 0; | ||||||
|  |  | ||||||
|     lfs_dir_open(&lfs, &dir[0], "/") => 0; |     lfs_dir_open(&lfs, &dir[0], "/") => 0; | ||||||
|     lfs_dir_close(&lfs, &dir[0]) => 0; |     lfs_dir_close(&lfs, &dir[0]) => 0; | ||||||
|  |     lfs_unmount(&lfs) => 0; | ||||||
| TEST | TEST | ||||||
|  |  | ||||||
| echo "--- Directory creation ---" | echo "--- Directory creation ---" | ||||||
| @@ -33,12 +36,16 @@ tests/test.py << TEST | |||||||
|     lfs_dir_open(&lfs, &dir[0], "/") => 0; |     lfs_dir_open(&lfs, &dir[0], "/") => 0; | ||||||
|     lfs_dir_read(&lfs, &dir[0], &info) => 1; |     lfs_dir_read(&lfs, &dir[0], &info) => 1; | ||||||
|     strcmp(info.name, ".") => 0; |     strcmp(info.name, ".") => 0; | ||||||
|  |     info.type => LFS_TYPE_DIR; | ||||||
|     lfs_dir_read(&lfs, &dir[0], &info) => 1; |     lfs_dir_read(&lfs, &dir[0], &info) => 1; | ||||||
|     strcmp(info.name, "..") => 0; |     strcmp(info.name, "..") => 0; | ||||||
|  |     info.type => LFS_TYPE_DIR; | ||||||
|     lfs_dir_read(&lfs, &dir[0], &info) => 1; |     lfs_dir_read(&lfs, &dir[0], &info) => 1; | ||||||
|     strcmp(info.name, "potato") => 0; |     strcmp(info.name, "potato") => 0; | ||||||
|  |     info.type => LFS_TYPE_DIR; | ||||||
|     lfs_dir_read(&lfs, &dir[0], &info) => 1; |     lfs_dir_read(&lfs, &dir[0], &info) => 1; | ||||||
|     strcmp(info.name, "burito") => 0; |     strcmp(info.name, "burito") => 0; | ||||||
|  |     info.type => LFS_TYPE_REG; | ||||||
|     lfs_dir_read(&lfs, &dir[0], &info) => 0; |     lfs_dir_read(&lfs, &dir[0], &info) => 0; | ||||||
|     lfs_dir_close(&lfs, &dir[0]) => 0; |     lfs_dir_close(&lfs, &dir[0]) => 0; | ||||||
|     lfs_unmount(&lfs) => 0; |     lfs_unmount(&lfs) => 0; | ||||||
|   | |||||||
							
								
								
									
										110
									
								
								tests/test_files.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										110
									
								
								tests/test_files.sh
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,110 @@ | |||||||
|  | #!/bin/bash | ||||||
|  | set -eu | ||||||
|  |  | ||||||
|  | SMALLSIZE=32 | ||||||
|  | MEDIUMSIZE=8192 | ||||||
|  | LARGESIZE=262144 | ||||||
|  |  | ||||||
|  | echo "=== File tests ===" | ||||||
|  | rm -rf blocks | ||||||
|  | tests/test.py << TEST | ||||||
|  |     lfs_format(&lfs, &config) => 0; | ||||||
|  | TEST | ||||||
|  |  | ||||||
|  | echo "--- Simple file test ---" | ||||||
|  | tests/test.py << TEST | ||||||
|  |     lfs_mount(&lfs, &config) => 0; | ||||||
|  |     lfs_file_open(&lfs, &file[0], "hello", LFS_O_RDWR | LFS_O_CREAT | LFS_O_APPEND) => 0; | ||||||
|  |     size = strlen("Hello World!\n"); | ||||||
|  |     memcpy(wbuffer, "Hello World!\n", size); | ||||||
|  |     lfs_file_write(&lfs, &file[0], wbuffer, size) => size; | ||||||
|  |     lfs_file_read(&lfs, &file[0], rbuffer, size) => size; | ||||||
|  |     memcmp(rbuffer, wbuffer, size) => 0; | ||||||
|  |     lfs_file_close(&lfs, &file[0]) => 0; | ||||||
|  |     lfs_unmount(&lfs) => 0; | ||||||
|  | TEST | ||||||
|  |  | ||||||
|  | w_test() { | ||||||
|  | tests/test.py << TEST | ||||||
|  |     lfs_size_t size = $1; | ||||||
|  |     lfs_size_t chunk = 31; | ||||||
|  |     srand(0); | ||||||
|  |     lfs_mount(&lfs, &config) => 0; | ||||||
|  |     lfs_file_open(&lfs, &file[0], "$2", LFS_O_WRONLY | LFS_O_CREAT) => 0; | ||||||
|  |     for (lfs_size_t i = 0; i < size; i += chunk) { | ||||||
|  |         chunk = (chunk < size - i) ? chunk : size - i; | ||||||
|  |         for (lfs_size_t b = 0; b < chunk; b++) { | ||||||
|  |             buffer[b] = rand() & 0xff; | ||||||
|  |         } | ||||||
|  |         lfs_file_write(&lfs, &file[0], buffer, chunk) => chunk; | ||||||
|  |     } | ||||||
|  |     lfs_file_close(&lfs, &file[0]) => 0; | ||||||
|  |     lfs_unmount(&lfs) => 0; | ||||||
|  | TEST | ||||||
|  | } | ||||||
|  |  | ||||||
|  | r_test() { | ||||||
|  | tests/test.py << TEST | ||||||
|  |     lfs_size_t size = $1; | ||||||
|  |     lfs_size_t chunk = 29; | ||||||
|  |     srand(0); | ||||||
|  |     lfs_mount(&lfs, &config) => 0; | ||||||
|  |     lfs_file_open(&lfs, &file[0], "$2", LFS_O_RDONLY) => 0; | ||||||
|  |     for (lfs_size_t i = 0; i < size; i += chunk) { | ||||||
|  |         chunk = (chunk < size - i) ? chunk : size - i; | ||||||
|  |         lfs_file_read(&lfs, &file[0], buffer, chunk) => chunk; | ||||||
|  |         for (lfs_size_t b = 0; b < chunk && i+b < size; b++) { | ||||||
|  |             buffer[b] => rand() & 0xff; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     lfs_file_close(&lfs, &file[0]) => 0; | ||||||
|  |     lfs_unmount(&lfs) => 0; | ||||||
|  | TEST | ||||||
|  | } | ||||||
|  |  | ||||||
|  | echo "--- Small file test ---" | ||||||
|  | w_test $SMALLSIZE smallavacado | ||||||
|  | r_test $SMALLSIZE smallavacado | ||||||
|  |  | ||||||
|  | echo "--- Medium file test ---" | ||||||
|  | w_test $MEDIUMSIZE mediumavacado | ||||||
|  | r_test $MEDIUMSIZE mediumavacado | ||||||
|  |  | ||||||
|  | echo "--- Large file test ---" | ||||||
|  | w_test $LARGESIZE largeavacado | ||||||
|  | r_test $LARGESIZE largeavacado | ||||||
|  |  | ||||||
|  | echo "--- Non-overlap check ---" | ||||||
|  | r_test $SMALLSIZE smallavacado | ||||||
|  | r_test $MEDIUMSIZE mediumavacado | ||||||
|  | r_test $LARGESIZE largeavacado | ||||||
|  |  | ||||||
|  | echo "--- Dir check ---" | ||||||
|  | tests/test.py << TEST | ||||||
|  |     lfs_mount(&lfs, &config) => 0; | ||||||
|  |     lfs_dir_open(&lfs, &dir[0], "/") => 0; | ||||||
|  |     lfs_dir_read(&lfs, &dir[0], &info) => 1; | ||||||
|  |     lfs_dir_read(&lfs, &dir[0], &info) => 1; | ||||||
|  |     lfs_dir_read(&lfs, &dir[0], &info) => 1; | ||||||
|  |     strcmp(info.name, "hello") => 0; | ||||||
|  |     info.type => LFS_TYPE_REG; | ||||||
|  |     info.size => strlen("Hello World!\n"); | ||||||
|  |     lfs_dir_read(&lfs, &dir[0], &info) => 1; | ||||||
|  |     strcmp(info.name, "smallavacado") => 0; | ||||||
|  |     info.type => LFS_TYPE_REG; | ||||||
|  |     info.size => $SMALLSIZE; | ||||||
|  |     lfs_dir_read(&lfs, &dir[0], &info) => 1; | ||||||
|  |     strcmp(info.name, "mediumavacado") => 0; | ||||||
|  |     info.type => LFS_TYPE_REG; | ||||||
|  |     info.size => $MEDIUMSIZE; | ||||||
|  |     lfs_dir_read(&lfs, &dir[0], &info) => 1; | ||||||
|  |     strcmp(info.name, "largeavacado") => 0; | ||||||
|  |     info.type => LFS_TYPE_REG; | ||||||
|  |     info.size => $LARGESIZE; | ||||||
|  |     lfs_dir_read(&lfs, &dir[0], &info) => 0; | ||||||
|  |     lfs_dir_close(&lfs, &dir[0]) => 0; | ||||||
|  |     lfs_unmount(&lfs) => 0; | ||||||
|  | TEST | ||||||
|  |  | ||||||
|  | echo "--- Results ---" | ||||||
|  | tests/stats.py | ||||||
		Reference in New Issue
	
	Block a user