mirror of
				https://github.com/eledio-devices/thirdparty-littlefs.git
				synced 2025-10-31 00:32:38 +01:00 
			
		
		
		
	Refactored a handful of things in tests
- Now test errors have correct line reporting! #line directives
  are passed to the compiler that reference the relevant line in
  the test case shell script.
  --- Multi-block directory ---
  ./tests/test_dirs.sh:109: assert failed with 0, expected 1
      lfs_unmount(&lfs) => 1
- Cleaned up the number of implicit global variables provided to
  tests. A lot of these were infrequently used and made it difficult
  to remember what was provided. This isn't an MCU, so there's very
  little cost to stack allocations when needed.
- Minimized the results.py script (previously stats.py) output to
  match minimization of test output.
			
			
This commit is contained in:
		
							
								
								
									
										28
									
								
								scripts/results.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										28
									
								
								scripts/results.py
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,28 @@ | ||||
| #!/usr/bin/env python2 | ||||
|  | ||||
| import struct | ||||
| import sys | ||||
| import time | ||||
| import os | ||||
| import re | ||||
|  | ||||
| def main(): | ||||
|     with open('blocks/.config') as file: | ||||
|         read_size, prog_size, block_size, block_count = ( | ||||
|             struct.unpack('<LLLL', file.read())) | ||||
|  | ||||
|     real_size = sum( | ||||
|         os.path.getsize(os.path.join('blocks', f)) | ||||
|         for f in os.listdir('blocks') if re.match('\d+', f)) | ||||
|  | ||||
|     with open('blocks/.stats') as file: | ||||
|         read_count, prog_count, erase_count = ( | ||||
|             struct.unpack('<QQQ', file.read())) | ||||
|  | ||||
|     runtime = time.time() - os.stat('blocks').st_ctime | ||||
|  | ||||
|     print 'results: %dB %dB %dB %.3fs' % ( | ||||
|         read_count, prog_count, erase_count, runtime) | ||||
|  | ||||
| if __name__ == "__main__": | ||||
|     main(*sys.argv[1:]) | ||||
| @@ -1,30 +0,0 @@ | ||||
| #!/usr/bin/env python2 | ||||
|  | ||||
| import struct | ||||
| import sys | ||||
| import time | ||||
| import os | ||||
| import re | ||||
|  | ||||
| def main(): | ||||
|     with open('blocks/.config') as file: | ||||
|         s = struct.unpack('<LLLL', file.read()) | ||||
|         print 'read_size: %d' % s[0] | ||||
|         print 'prog_size: %d' % s[1] | ||||
|         print 'block_size: %d' % s[2] | ||||
|         print 'block_size: %d' % s[3] | ||||
|  | ||||
|     print 'real_size: %d' % sum( | ||||
|         os.path.getsize(os.path.join('blocks', f)) | ||||
|         for f in os.listdir('blocks') if re.match('\d+', f)) | ||||
|  | ||||
|     with open('blocks/.stats') as file: | ||||
|         s = struct.unpack('<QQQ', file.read()) | ||||
|         print 'read_count: %d' % s[0] | ||||
|         print 'prog_count: %d' % s[1] | ||||
|         print 'erase_count: %d' % s[2] | ||||
|  | ||||
|     print 'runtime: %.3f' % (time.time() - os.stat('blocks').st_ctime) | ||||
|  | ||||
| if __name__ == "__main__": | ||||
|     main(*sys.argv[1:]) | ||||
| @@ -10,14 +10,18 @@ | ||||
| static void test_assert(const char *file, unsigned line, | ||||
|         const char *s, uintmax_t v, uintmax_t e) {{ | ||||
|     if (v != e) {{ | ||||
|         fprintf(stderr, "\033[31m%s:%u: assert %s failed with %jd, " | ||||
|                 "expected %jd\033[0m\n", file, line, s, v, e); | ||||
|         fprintf(stderr, "\033[97m%s:%u: \033[91m" | ||||
|                 "assert failed with %jd, expected %jd\033[0m\n" | ||||
|                 "    %s\n\n", file, line, v, e, s); | ||||
|         exit(-2); | ||||
|     }} | ||||
| }} | ||||
|  | ||||
| #define test_assert(s, v, e) test_assert(__FILE__, __LINE__, s, v, e) | ||||
| #define test_assert(v, e) \ | ||||
|         test_assert(__FILE__, __LINE__, #v " => " #e, v, e) | ||||
|  | ||||
| // implicit variable for asserts | ||||
| uintmax_t test; | ||||
|  | ||||
| // utility functions for traversals | ||||
| static int __attribute__((used)) test_count(void *p, lfs_block_t b) {{ | ||||
| @@ -27,23 +31,17 @@ static int __attribute__((used)) test_count(void *p, lfs_block_t b) {{ | ||||
|     return 0; | ||||
| }} | ||||
|  | ||||
|  | ||||
| // lfs declarations | ||||
| lfs_t lfs; | ||||
| lfs_emubd_t bd; | ||||
| lfs_file_t file[4]; | ||||
| lfs_dir_t dir[4]; | ||||
| // other declarations for convenience | ||||
| lfs_file_t file; | ||||
| lfs_dir_t dir; | ||||
| struct lfs_info info; | ||||
|  | ||||
| uint8_t buffer[1024]; | ||||
| uint8_t wbuffer[1024]; | ||||
| uint8_t rbuffer[1024]; | ||||
| lfs_size_t size; | ||||
| lfs_size_t wsize; | ||||
| lfs_size_t rsize; | ||||
|  | ||||
| uintmax_t test; | ||||
| char path[1024]; | ||||
|  | ||||
| // test configuration options | ||||
| #ifndef LFS_READ_SIZE | ||||
| #define LFS_READ_SIZE 16 | ||||
| #endif | ||||
| @@ -94,6 +92,5 @@ int main(void) {{ | ||||
|     lfs_emubd_create(&cfg, "blocks"); | ||||
|  | ||||
| {tests} | ||||
|  | ||||
|     lfs_emubd_destroy(&cfg); | ||||
| }} | ||||
|   | ||||
| @@ -5,24 +5,36 @@ import sys | ||||
| import subprocess | ||||
| import os | ||||
|  | ||||
|  | ||||
| def generate(test): | ||||
|     with open("scripts/template.fmt") as file: | ||||
|         template = file.read() | ||||
|  | ||||
|     haslines = 'TEST_LINE' in os.environ and 'TEST_FILE' in os.environ | ||||
|  | ||||
|     lines = [] | ||||
|     for line in re.split('(?<=(?:.;| [{}]))\n', test.read()): | ||||
|         match = re.match('(?: *\n)*( *)(.*)=>(.*);', line, re.DOTALL | re.MULTILINE) | ||||
|     for offset, line in enumerate( | ||||
|             re.split('(?<=(?:.;| [{}]))\n', test.read())): | ||||
|         match = re.match('((?: *\n)*)( *)(.*)=>(.*);', | ||||
|                 line, re.DOTALL | re.MULTILINE) | ||||
|         if match: | ||||
|             tab, test, expect = match.groups() | ||||
|             lines.append(tab+'test = {test};'.format(test=test.strip())) | ||||
|             lines.append(tab+'test_assert("{name}", test, {expect});'.format( | ||||
|                     name = re.match('\w*', test.strip()).group(), | ||||
|                     expect = expect.strip())) | ||||
|             preface, tab, test, expect = match.groups() | ||||
|             lines.extend(['']*preface.count('\n')) | ||||
|             lines.append(tab+'test_assert({test}, {expect});'.format( | ||||
|                 test=test.strip(), expect=expect.strip())) | ||||
|         else: | ||||
|             lines.append(line) | ||||
|  | ||||
|     # Create test file | ||||
|     with open('test.c', 'w') as file: | ||||
|         if 'TEST_LINE' in os.environ and 'TEST_FILE' in os.environ: | ||||
|             lines.insert(0, '#line %d "%s"' % ( | ||||
|                     int(os.environ['TEST_LINE']) + 1, | ||||
|                     os.environ['TEST_FILE'])) | ||||
|             lines.append('#line %d "test.c"' % ( | ||||
|                     template[:template.find('{tests}')].count('\n') | ||||
|                     + len(lines) + 2)) | ||||
|  | ||||
|         file.write(template.format(tests='\n'.join(lines))) | ||||
|  | ||||
|     # Remove build artifacts to force rebuild | ||||
| @@ -44,18 +56,26 @@ def execute(): | ||||
|         subprocess.check_call(["./lfs"]) | ||||
|  | ||||
| def main(test=None): | ||||
|     if test and not test.startswith('-'): | ||||
|         with open(test) as file: | ||||
|             generate(file) | ||||
|     else: | ||||
|         generate(sys.stdin) | ||||
|     try: | ||||
|         if test and not test.startswith('-'): | ||||
|             with open(test) as file: | ||||
|                 generate(file) | ||||
|         else: | ||||
|             generate(sys.stdin) | ||||
|  | ||||
|     compile() | ||||
|         compile() | ||||
|  | ||||
|     if test == '-s': | ||||
|         sys.exit(1) | ||||
|         if test == '-s': | ||||
|             sys.exit(1) | ||||
|  | ||||
|     execute() | ||||
|         execute() | ||||
|  | ||||
|     except subprocess.CalledProcessError: | ||||
|         # Python stack trace is counterproductive, just exit | ||||
|         sys.exit(2) | ||||
|     except KeyboardInterrupt: | ||||
|         # Python stack trace is counterproductive, just exit | ||||
|         sys.exit(3) | ||||
|  | ||||
| if __name__ == "__main__": | ||||
|     main(*sys.argv[1:]) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user