# Tests where the block device returns invalid values try: import vfs vfs.VfsFat vfs.VfsLfs2 except (ImportError, AttributeError): print("SKIP") raise SystemExit class RAMBlockDevice: ERASE_BLOCK_SIZE = 512 def __init__(self, blocks): self.data = bytearray(blocks * self.ERASE_BLOCK_SIZE) self.read_res = 0 self.write_res = 0 def readblocks(self, block, buf, off=0): # print("readblocks", block, len(buf), off) addr = block * self.ERASE_BLOCK_SIZE + off for i in range(len(buf)): buf[i] = self.data[addr + i] return self.read_res def writeblocks(self, block, buf, off=None): if off is None: # erase, then write off = 0 addr = block * self.ERASE_BLOCK_SIZE + off for i in range(len(buf)): self.data[addr + i] = buf[i] return self.write_res def ioctl(self, op, arg): if op == 4: # block count return len(self.data) // self.ERASE_BLOCK_SIZE if op == 5: # block size return self.ERASE_BLOCK_SIZE if op == 6: # erase block return 0 try: bdev = RAMBlockDevice(50) except MemoryError: print("SKIP") raise SystemExit def test(vfs_class): print(vfs_class) bdev.read_res = 0 # reset function results bdev.write_res = 0 vfs_class.mkfs(bdev) fs = vfs_class(bdev) with fs.open("test", "w") as f: f.write("a" * 64) for res in (0, -5, 5, 33, "invalid"): # -5 is a legitimate negative failure (EIO), positive integer # is not # This variant will fail on open bdev.read_res = res try: with fs.open("test", "r") as f: print("opened") except OSError as e: print("OSError", e) # This variant should succeed on open, may fail on read # unless the filesystem cached the contents already bdev.read_res = 0 try: with fs.open("test", "r") as f: bdev.read_res = res print("read 1", f.read(1)) print("read rest", f.read()) except OSError as e: print("OSError", e) test(vfs.VfsLfs2) test(vfs.VfsFat)