diff --git a/tests/extmod/vfs_fat_fileio1.py b/tests/extmod/vfs_fat_fileio1.py index d0a5e4b73..7fe040d53 100644 --- a/tests/extmod/vfs_fat_fileio1.py +++ b/tests/extmod/vfs_fat_fileio1.py @@ -109,29 +109,3 @@ except OSError as e: vfs.remove("foo_file.txt") print(list(vfs.ilistdir())) - -# Here we test that opening a file with the heap locked fails correctly. This -# is a special case because file objects use a finaliser and allocating with a -# finaliser is a different path to normal allocation. It would be better to -# test this in the core tests but there are no core objects that use finaliser. -import micropython -micropython.heap_lock() -try: - vfs.open('x', 'r') -except MemoryError: - print('MemoryError') -micropython.heap_unlock() - -# Here we test that the finaliser is actually called during a garbage collection. -import gc -N = 4 -for i in range(N): - n = 'x%d' % i - f = vfs.open(n, 'w') - f.write(n) - f = None # release f without closing - [0, 1, 2, 3] # use up Python stack so f is really gone -gc.collect() # should finalise all N files by closing them -for i in range(N): - with vfs.open('x%d' % i, 'r') as f: - print(f.read()) diff --git a/tests/extmod/vfs_fat_fileio1.py.exp b/tests/extmod/vfs_fat_fileio1.py.exp index 4eb50402c..8da96e16b 100644 --- a/tests/extmod/vfs_fat_fileio1.py.exp +++ b/tests/extmod/vfs_fat_fileio1.py.exp @@ -11,8 +11,3 @@ o d True [('foo_dir', 16384, 0, 0)] -MemoryError -x0 -x1 -x2 -x3 diff --git a/tests/extmod/vfs_fat_finaliser.py b/tests/extmod/vfs_fat_finaliser.py new file mode 100644 index 000000000..c7254c5f0 --- /dev/null +++ b/tests/extmod/vfs_fat_finaliser.py @@ -0,0 +1,66 @@ +# Test VfsFat class and its finaliser + +try: + import uerrno, uos + uos.VfsFat +except (ImportError, AttributeError): + print("SKIP") + raise SystemExit + + +class RAMBlockDevice: + def __init__(self, blocks, sec_size=512): + self.sec_size = sec_size + self.data = bytearray(blocks * self.sec_size) + + def readblocks(self, n, buf): + for i in range(len(buf)): + buf[i] = self.data[n * self.sec_size + i] + + def writeblocks(self, n, buf): + for i in range(len(buf)): + self.data[n * self.sec_size + i] = buf[i] + + def ioctl(self, op, arg): + if op == 4: # MP_BLOCKDEV_IOCTL_BLOCK_COUNT + return len(self.data) // self.sec_size + if op == 5: # MP_BLOCKDEV_IOCTL_BLOCK_SIZE + return self.sec_size + + +# Create block device, and skip test if not enough RAM +try: + bdev = RAMBlockDevice(50) +except MemoryError: + print("SKIP") + raise SystemExit + +# Format block device and create VFS object +uos.VfsFat.mkfs(bdev) +vfs = uos.VfsFat(bdev) + +# Here we test that opening a file with the heap locked fails correctly. This +# is a special case because file objects use a finaliser and allocating with a +# finaliser is a different path to normal allocation. It would be better to +# test this in the core tests but there are no core objects that use finaliser. +import micropython +micropython.heap_lock() +try: + vfs.open('x', 'r') +except MemoryError: + print('MemoryError') +micropython.heap_unlock() + +# Here we test that the finaliser is actually called during a garbage collection. +import gc +N = 4 +for i in range(N): + n = 'x%d' % i + f = vfs.open(n, 'w') + f.write(n) + f = None # release f without closing + [0, 1, 2, 3] # use up Python stack so f is really gone +gc.collect() # should finalise all N files by closing them +for i in range(N): + with vfs.open('x%d' % i, 'r') as f: + print(f.read()) diff --git a/tests/extmod/vfs_fat_finaliser.py.exp b/tests/extmod/vfs_fat_finaliser.py.exp new file mode 100644 index 000000000..cc51daf2a --- /dev/null +++ b/tests/extmod/vfs_fat_finaliser.py.exp @@ -0,0 +1,5 @@ +MemoryError +x0 +x1 +x2 +x3