mirror of
				https://github.com/eledio-devices/thirdparty-littlefs.git
				synced 2025-10-31 16:14:16 +01:00 
			
		
		
		
	Added test.py support for tmpfs-backed disks
RAM-backed testing is faster than file-backed testing. This is why test.py uses rambd by default. So why add support for tmpfs-backed disks if we can already run tests in RAM? For reentrant testing. Under reentrant testing we simulate power-loss by forcefully exiting the test program at specific times. To make this power-loss meaningful, we need to persist the disk across these power-losses. However, it's interesting to note this persistence doesn't need to be actually backed by the filesystem. It may be possible to rearchitecture the tests to simulate power-loss a different way, by say, using coroutines or setjmp/longjmp to leave behind ongoing filesystem operations without terminating the program completely. But at this point, I think it's best to work with what we have. And simply putting the test disks into a tmpfs mount-point seems to work just fine. Note this does force serialization of the tests, which isn't required otherwise. Currently they are only serialized due to limitations in test.py. If a future change wants to perallelize the tests, it may need to rework RAM-backed reentrant tests.
This commit is contained in:
		| @@ -15,6 +15,12 @@ script: | |||||||
|         -Duser_provided_block_device_sync=NULL |         -Duser_provided_block_device_sync=NULL | ||||||
|         -include stdio.h" |         -include stdio.h" | ||||||
|  |  | ||||||
|  |   # setup a ram-backed disk to speed up reentrant tests | ||||||
|  |   - | | ||||||
|  |     mkdir disks | ||||||
|  |     sudo mount -t tmpfs -o size=100m tmpfs disks | ||||||
|  |     export TFLAGS="$TFLAGS --disk=disks/disk" | ||||||
|  |  | ||||||
|   # run tests |   # run tests | ||||||
|   - make clean test TFLAGS+="-nrk" |   - make clean test TFLAGS+="-nrk" | ||||||
|  |  | ||||||
|   | |||||||
| @@ -200,22 +200,25 @@ class TestCase: | |||||||
|             return True |             return True | ||||||
|  |  | ||||||
|     def test(self, exec=[], persist=False, cycles=None, |     def test(self, exec=[], persist=False, cycles=None, | ||||||
|             gdb=False, failure=None, **args): |             gdb=False, failure=None, disk=None, **args): | ||||||
|         # build command |         # build command | ||||||
|         cmd = exec + ['./%s.test' % self.suite.path, |         cmd = exec + ['./%s.test' % self.suite.path, | ||||||
|             repr(self.caseno), repr(self.permno)] |             repr(self.caseno), repr(self.permno)] | ||||||
|  |  | ||||||
|         # persist disk or keep in RAM for speed? |         # persist disk or keep in RAM for speed? | ||||||
|         if persist: |         if persist: | ||||||
|  |             if not disk: | ||||||
|  |                 disk = self.suite.path + '.disk' | ||||||
|             if persist != 'noerase': |             if persist != 'noerase': | ||||||
|                 try: |                 try: | ||||||
|                     os.remove(self.suite.path + '.disk') |                     with open(disk, 'w') as f: | ||||||
|  |                         f.truncate(0) | ||||||
|                     if args.get('verbose', False): |                     if args.get('verbose', False): | ||||||
|                         print('rm', self.suite.path + '.disk') |                         print('truncate --size=0', disk) | ||||||
|                 except FileNotFoundError: |                 except FileNotFoundError: | ||||||
|                     pass |                     pass | ||||||
|  |  | ||||||
|             cmd.append(self.suite.path + '.disk') |             cmd.append(disk) | ||||||
|  |  | ||||||
|         # simulate power-loss after n cycles? |         # simulate power-loss after n cycles? | ||||||
|         if cycles: |         if cycles: | ||||||
| @@ -704,8 +707,6 @@ def main(**args): | |||||||
|                         stdout = perm.result.stdout[:-1] |                         stdout = perm.result.stdout[:-1] | ||||||
|                     else: |                     else: | ||||||
|                         stdout = perm.result.stdout |                         stdout = perm.result.stdout | ||||||
|                     if (not args.get('verbose', False) and len(stdout) > 5): |  | ||||||
|                         sys.stdout.write('...\n') |  | ||||||
|                     for line in stdout[-5:]: |                     for line in stdout[-5:]: | ||||||
|                         sys.stdout.write(line) |                         sys.stdout.write(line) | ||||||
|                 if perm.result.assert_: |                 if perm.result.assert_: | ||||||
| @@ -766,4 +767,6 @@ if __name__ == "__main__": | |||||||
|         help="Run non-leaky tests under valgrind to check for memory leaks.") |         help="Run non-leaky tests under valgrind to check for memory leaks.") | ||||||
|     parser.add_argument('-e', '--exec', default=[], type=lambda e: e.split(' '), |     parser.add_argument('-e', '--exec', default=[], type=lambda e: e.split(' '), | ||||||
|         help="Run tests with another executable prefixed on the command line.") |         help="Run tests with another executable prefixed on the command line.") | ||||||
|  |     parser.add_argument('-d', '--disk', | ||||||
|  |         help="Specify a file to use for persistent/reentrant tests.") | ||||||
|     sys.exit(main(**vars(parser.parse_args()))) |     sys.exit(main(**vars(parser.parse_args()))) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user