From 73fddb84e5b2a313170e1286013b99f23430dbed Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 18 Oct 2019 17:25:48 +1100 Subject: [PATCH] tests/extmod: Add littlefs tests. --- tests/extmod/vfs_lfs.py | 107 +++++++++++++++++++++++++ tests/extmod/vfs_lfs.py.exp | 46 +++++++++++ tests/extmod/vfs_lfs_corrupt.py | 106 +++++++++++++++++++++++++ tests/extmod/vfs_lfs_corrupt.py.exp | 12 +++ tests/extmod/vfs_lfs_error.py | 116 +++++++++++++++++++++++++++ tests/extmod/vfs_lfs_error.py.exp | 28 +++++++ tests/extmod/vfs_lfs_file.py | 117 ++++++++++++++++++++++++++++ tests/extmod/vfs_lfs_file.py.exp | 28 +++++++ tests/extmod/vfs_lfs_mount.py | 73 +++++++++++++++++ tests/extmod/vfs_lfs_mount.py.exp | 6 ++ 10 files changed, 639 insertions(+) create mode 100644 tests/extmod/vfs_lfs.py create mode 100644 tests/extmod/vfs_lfs.py.exp create mode 100644 tests/extmod/vfs_lfs_corrupt.py create mode 100644 tests/extmod/vfs_lfs_corrupt.py.exp create mode 100644 tests/extmod/vfs_lfs_error.py create mode 100644 tests/extmod/vfs_lfs_error.py.exp create mode 100644 tests/extmod/vfs_lfs_file.py create mode 100644 tests/extmod/vfs_lfs_file.py.exp create mode 100644 tests/extmod/vfs_lfs_mount.py create mode 100644 tests/extmod/vfs_lfs_mount.py.exp diff --git a/tests/extmod/vfs_lfs.py b/tests/extmod/vfs_lfs.py new file mode 100644 index 0000000000..46c770b437 --- /dev/null +++ b/tests/extmod/vfs_lfs.py @@ -0,0 +1,107 @@ +# Test for VfsLittle using a RAM device + +try: + import uos + uos.VfsLfs1 + uos.VfsLfs2 +except (ImportError, AttributeError): + print("SKIP") + raise SystemExit + +class RAMBlockDevice: + ERASE_BLOCK_SIZE = 1024 + + def __init__(self, blocks): + self.data = bytearray(blocks * self.ERASE_BLOCK_SIZE) + + def readblocks(self, block, buf, off): + addr = block * self.ERASE_BLOCK_SIZE + off + for i in range(len(buf)): + buf[i] = self.data[addr + i] + + def writeblocks(self, block, buf, off): + addr = block * self.ERASE_BLOCK_SIZE + off + for i in range(len(buf)): + self.data[addr + i] = buf[i] + + 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 + +def test(bdev, vfs_class): + print('test', vfs_class) + + # mkfs + vfs_class.mkfs(bdev) + + # construction + vfs = vfs_class(bdev) + + # statvfs + print(vfs.statvfs('/')) + + # open, write close + f = vfs.open('test', 'w') + f.write('littlefs') + f.close() + + # statvfs after creating a file + print(vfs.statvfs('/')) + + # ilistdir + print(list(vfs.ilistdir())) + print(list(vfs.ilistdir('/'))) + print(list(vfs.ilistdir(b'/'))) + + # mkdir, rmdir + vfs.mkdir('testdir') + print(list(vfs.ilistdir())) + print(list(vfs.ilistdir('testdir'))) + vfs.rmdir('testdir') + print(list(vfs.ilistdir())) + vfs.mkdir('testdir') + + # stat a file + print(vfs.stat('test')) + + # stat a dir (size seems to vary on LFS2 so don't print that) + print(vfs.stat('testdir')[:6]) + + # read + with vfs.open('test', 'r') as f: + print(f.read()) + + # create large file + with vfs.open('testbig', 'w') as f: + data = 'large012' * 32 * 16 + print('data length:', len(data)) + for i in range(4): + print('write', i) + f.write(data) + + # stat after creating large file + print(vfs.statvfs('/')) + + # rename + vfs.rename('testbig', 'testbig2') + print(list(vfs.ilistdir())) + + # remove + vfs.remove('testbig2') + print(list(vfs.ilistdir())) + + # getcwd, chdir + print(vfs.getcwd()) + vfs.chdir('/testdir') + print(vfs.getcwd()) + vfs.chdir('/') + print(vfs.getcwd()) + vfs.rmdir('testdir') + +bdev = RAMBlockDevice(30) +test(bdev, uos.VfsLfs1) +test(bdev, uos.VfsLfs2) diff --git a/tests/extmod/vfs_lfs.py.exp b/tests/extmod/vfs_lfs.py.exp new file mode 100644 index 0000000000..c16e727b81 --- /dev/null +++ b/tests/extmod/vfs_lfs.py.exp @@ -0,0 +1,46 @@ +test +(1024, 1024, 30, 26, 26, 0, 0, 0, 0, 255) +(1024, 1024, 30, 25, 25, 0, 0, 0, 0, 255) +[('test', 32768, 0, 8)] +[('test', 32768, 0, 8)] +[(b'test', 32768, 0, 8)] +[('test', 32768, 0, 8), ('testdir', 16384, 0, 0)] +[] +[('test', 32768, 0, 8)] +(32768, 0, 0, 0, 0, 0, 8, 0, 0, 0) +(16384, 0, 0, 0, 0, 0) +littlefs +data length: 4096 +write 0 +write 1 +write 2 +write 3 +(1024, 1024, 30, 6, 6, 0, 0, 0, 0, 255) +[('test', 32768, 0, 8), ('testdir', 16384, 0, 0), ('testbig2', 32768, 0, 16384)] +[('test', 32768, 0, 8), ('testdir', 16384, 0, 0)] +/ +/testdir +/ +test +(1024, 1024, 30, 28, 28, 0, 0, 0, 0, 255) +(1024, 1024, 30, 28, 28, 0, 0, 0, 0, 255) +[('test', 32768, 0, 8)] +[('test', 32768, 0, 8)] +[(b'test', 32768, 0, 8)] +[('testdir', 16384, 0, 0), ('test', 32768, 0, 8)] +[] +[('test', 32768, 0, 8)] +(32768, 0, 0, 0, 0, 0, 8, 0, 0, 0) +(16384, 0, 0, 0, 0, 0) +littlefs +data length: 4096 +write 0 +write 1 +write 2 +write 3 +(1024, 1024, 30, 9, 9, 0, 0, 0, 0, 255) +[('testbig2', 32768, 0, 16384), ('testdir', 16384, 0, 0), ('test', 32768, 0, 8)] +[('testdir', 16384, 0, 0), ('test', 32768, 0, 8)] +/ +/testdir +/ diff --git a/tests/extmod/vfs_lfs_corrupt.py b/tests/extmod/vfs_lfs_corrupt.py new file mode 100644 index 0000000000..90c3e82163 --- /dev/null +++ b/tests/extmod/vfs_lfs_corrupt.py @@ -0,0 +1,106 @@ +# Test for VfsLittle using a RAM device, testing error handling from corrupt block device + +try: + import uos + uos.VfsLfs1 + uos.VfsLfs2 +except (ImportError, AttributeError): + print("SKIP") + raise SystemExit + +class RAMBlockDevice: + ERASE_BLOCK_SIZE = 1024 + + def __init__(self, blocks): + self.data = bytearray(blocks * self.ERASE_BLOCK_SIZE) + self.ret = 0 + + def readblocks(self, block, buf, off): + addr = block * self.ERASE_BLOCK_SIZE + off + for i in range(len(buf)): + buf[i] = self.data[addr + i] + return self.ret + + def writeblocks(self, block, buf, off): + addr = block * self.ERASE_BLOCK_SIZE + off + for i in range(len(buf)): + self.data[addr + i] = buf[i] + return self.ret + + 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 + +def corrupt(bdev, block): + addr = block * bdev.ERASE_BLOCK_SIZE + for i in range(bdev.ERASE_BLOCK_SIZE): + bdev.data[addr + i] = i & 0xff + +def create_vfs(bdev, vfs_class): + bdev.ret = 0 + vfs_class.mkfs(bdev) + vfs = vfs_class(bdev) + with vfs.open('f', 'w') as f: + for i in range(100): + f.write('test') + return vfs + +def test(bdev, vfs_class): + print('test', vfs_class) + + # statvfs + vfs = create_vfs(bdev, vfs_class) + corrupt(bdev, 0) + corrupt(bdev, 1) + try: + print(vfs.statvfs('')) + except OSError: + print('statvfs OSError') + + # error during read + vfs = create_vfs(bdev, vfs_class) + f = vfs.open('f', 'r') + bdev.ret = -5 # EIO + try: + f.read(10) + except OSError: + print('read OSError') + + # error during write + vfs = create_vfs(bdev, vfs_class) + f = vfs.open('f', 'a') + bdev.ret = -5 # EIO + try: + f.write('test') + except OSError: + print('write OSError') + + # error during close + vfs = create_vfs(bdev, vfs_class) + f = vfs.open('f', 'w') + f.write('test') + bdev.ret = -5 # EIO + try: + f.close() + except OSError: + print('close OSError') + + # error during flush + vfs = create_vfs(bdev, vfs_class) + f = vfs.open('f', 'w') + f.write('test') + bdev.ret = -5 # EIO + try: + f.flush() + except OSError: + print('flush OSError') + bdev.ret = 0 + f.close() + +bdev = RAMBlockDevice(30) +test(bdev, uos.VfsLfs1) +test(bdev, uos.VfsLfs2) diff --git a/tests/extmod/vfs_lfs_corrupt.py.exp b/tests/extmod/vfs_lfs_corrupt.py.exp new file mode 100644 index 0000000000..d6f5f54252 --- /dev/null +++ b/tests/extmod/vfs_lfs_corrupt.py.exp @@ -0,0 +1,12 @@ +test +statvfs OSError +read OSError +write OSError +close OSError +flush OSError +test +statvfs OSError +read OSError +write OSError +close OSError +flush OSError diff --git a/tests/extmod/vfs_lfs_error.py b/tests/extmod/vfs_lfs_error.py new file mode 100644 index 0000000000..b97fe6ec15 --- /dev/null +++ b/tests/extmod/vfs_lfs_error.py @@ -0,0 +1,116 @@ +# Test for VfsLittle using a RAM device, testing error handling + +try: + import uos + uos.VfsLfs1 + uos.VfsLfs2 +except (ImportError, AttributeError): + print("SKIP") + raise SystemExit + +class RAMBlockDevice: + ERASE_BLOCK_SIZE = 1024 + + def __init__(self, blocks): + self.data = bytearray(blocks * self.ERASE_BLOCK_SIZE) + + def readblocks(self, block, buf, off): + addr = block * self.ERASE_BLOCK_SIZE + off + for i in range(len(buf)): + buf[i] = self.data[addr + i] + + def writeblocks(self, block, buf, off): + addr = block * self.ERASE_BLOCK_SIZE + off + for i in range(len(buf)): + self.data[addr + i] = buf[i] + + 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 + +def test(bdev, vfs_class): + print('test', vfs_class) + + # mkfs with too-small block device + try: + vfs_class.mkfs(RAMBlockDevice(1)) + except OSError: + print('mkfs OSError') + + # mount with invalid filesystem + try: + vfs_class(bdev) + except OSError: + print('mount OSError') + + # set up for following tests + vfs_class.mkfs(bdev) + vfs = vfs_class(bdev) + with vfs.open('testfile', 'w') as f: + f.write('test') + vfs.mkdir('testdir') + + # ilistdir + try: + vfs.ilistdir('noexist') + except OSError: + print('ilistdir OSError') + + # remove + try: + vfs.remove('noexist') + except OSError: + print('remove OSError') + + # rmdir + try: + vfs.rmdir('noexist') + except OSError: + print('rmdir OSError') + + # rename + try: + vfs.rename('noexist', 'somethingelse') + except OSError: + print('rename OSError') + + # mkdir + try: + vfs.mkdir('testdir') + except OSError: + print('mkdir OSError') + + # chdir to nonexistent + try: + vfs.chdir('noexist') + except OSError: + print('chdir OSError') + print(vfs.getcwd()) # check still at root + + # chdir to file + try: + vfs.chdir('testfile') + except OSError: + print('chdir OSError') + print(vfs.getcwd()) # check still at root + + # stat + try: + vfs.stat('noexist') + except OSError: + print('stat OSError') + + # error during seek + with vfs.open('testfile', 'r') as f: + try: + f.seek(1 << 31) + except OSError: + print('seek OSError') + +bdev = RAMBlockDevice(30) +test(bdev, uos.VfsLfs1) +test(bdev, uos.VfsLfs2) diff --git a/tests/extmod/vfs_lfs_error.py.exp b/tests/extmod/vfs_lfs_error.py.exp new file mode 100644 index 0000000000..f4327f6962 --- /dev/null +++ b/tests/extmod/vfs_lfs_error.py.exp @@ -0,0 +1,28 @@ +test +mkfs OSError +mount OSError +ilistdir OSError +remove OSError +rmdir OSError +rename OSError +mkdir OSError +chdir OSError +/ +chdir OSError +/ +stat OSError +seek OSError +test +mkfs OSError +mount OSError +ilistdir OSError +remove OSError +rmdir OSError +rename OSError +mkdir OSError +chdir OSError +/ +chdir OSError +/ +stat OSError +seek OSError diff --git a/tests/extmod/vfs_lfs_file.py b/tests/extmod/vfs_lfs_file.py new file mode 100644 index 0000000000..477a62e2ff --- /dev/null +++ b/tests/extmod/vfs_lfs_file.py @@ -0,0 +1,117 @@ +# Test for VfsLittle using a RAM device, file IO + +try: + import uos + uos.VfsLfs1 + uos.VfsLfs2 +except (ImportError, AttributeError): + print("SKIP") + raise SystemExit + +class RAMBlockDevice: + ERASE_BLOCK_SIZE = 1024 + + def __init__(self, blocks): + self.data = bytearray(blocks * self.ERASE_BLOCK_SIZE) + + def readblocks(self, block, buf, off): + addr = block * self.ERASE_BLOCK_SIZE + off + for i in range(len(buf)): + buf[i] = self.data[addr + i] + + def writeblocks(self, block, buf, off): + addr = block * self.ERASE_BLOCK_SIZE + off + for i in range(len(buf)): + self.data[addr + i] = buf[i] + + 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 + +def test(bdev, vfs_class): + print('test', vfs_class) + + # mkfs + vfs_class.mkfs(bdev) + + # construction + vfs = vfs_class(bdev) + + # create text, print, write, close + f = vfs.open('test.txt', 'wt') + print(f) + f.write('littlefs') + f.close() + + # close already-closed file + f.close() + + # create binary, print, write, flush, close + f = vfs.open('test.bin', 'wb') + print(f) + f.write('littlefs') + f.flush() + f.close() + + # create for append + f = vfs.open('test.bin', 'ab') + f.write('more') + f.close() + + # create exclusive + f = vfs.open('test2.bin', 'xb') + f.close() + + # create exclusive with error + try: + vfs.open('test2.bin', 'x') + except OSError: + print('open OSError') + + # read default + with vfs.open('test.txt', '') as f: + print(f.read()) + + # read text + with vfs.open('test.txt', 'rt') as f: + print(f.read()) + + # read binary + with vfs.open('test.bin', 'rb') as f: + print(f.read()) + + # create read and write + with vfs.open('test.bin', 'r+b') as f: + print(f.read(8)) + f.write('MORE') + with vfs.open('test.bin', 'rb') as f: + print(f.read()) + + # seek and tell + f = vfs.open('test.txt', 'r') + print(f.tell()) + f.seek(3, 0) + print(f.tell()) + f.close() + + # open nonexistent + try: + vfs.open('noexist', 'r') + except OSError: + print('open OSError') + + # open multiple files at the same time + f1 = vfs.open('test.txt', '') + f2 = vfs.open('test.bin', 'b') + print(f1.read()) + print(f2.read()) + f1.close() + f2.close() + +bdev = RAMBlockDevice(30) +test(bdev, uos.VfsLfs1) +test(bdev, uos.VfsLfs2) diff --git a/tests/extmod/vfs_lfs_file.py.exp b/tests/extmod/vfs_lfs_file.py.exp new file mode 100644 index 0000000000..55531539ec --- /dev/null +++ b/tests/extmod/vfs_lfs_file.py.exp @@ -0,0 +1,28 @@ +test + + +open OSError +littlefs +littlefs +b'littlefsmore' +b'littlefs' +b'littlefsMORE' +0 +3 +open OSError +littlefs +b'littlefsMORE' +test + + +open OSError +littlefs +littlefs +b'littlefsmore' +b'littlefs' +b'littlefsMORE' +0 +3 +open OSError +littlefs +b'littlefsMORE' diff --git a/tests/extmod/vfs_lfs_mount.py b/tests/extmod/vfs_lfs_mount.py new file mode 100644 index 0000000000..76263f4978 --- /dev/null +++ b/tests/extmod/vfs_lfs_mount.py @@ -0,0 +1,73 @@ +# Test for VfsLittle using a RAM device, with mount/umount + +try: + import uos + uos.VfsLfs1 + uos.VfsLfs2 +except (ImportError, AttributeError): + print("SKIP") + raise SystemExit + +class RAMBlockDevice: + ERASE_BLOCK_SIZE = 1024 + + def __init__(self, blocks): + self.data = bytearray(blocks * self.ERASE_BLOCK_SIZE) + + def readblocks(self, block, buf, off): + addr = block * self.ERASE_BLOCK_SIZE + off + for i in range(len(buf)): + buf[i] = self.data[addr + i] + + def writeblocks(self, block, buf, off): + addr = block * self.ERASE_BLOCK_SIZE + off + for i in range(len(buf)): + self.data[addr + i] = buf[i] + + 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 + +def test(bdev, vfs_class): + print('test', vfs_class) + + # mkfs + vfs_class.mkfs(bdev) + + # construction + vfs = vfs_class(bdev) + + # mount + uos.mount(vfs, '/lfs') + + # import + with open('/lfs/lfsmod.py', 'w') as f: + f.write('print("hello from lfs")\n') + import lfsmod + + # import package + uos.mkdir('/lfs/lfspkg') + with open('/lfs/lfspkg/__init__.py', 'w') as f: + f.write('print("package")\n') + import lfspkg + + # umount + uos.umount('/lfs') + + # clear imported modules + sys.modules.clear() + +bdev = RAMBlockDevice(30) + +# initialise path +import sys +sys.path.clear() +sys.path.append('/lfs') + +# run tests +test(bdev, uos.VfsLfs1) +test(bdev, uos.VfsLfs2) diff --git a/tests/extmod/vfs_lfs_mount.py.exp b/tests/extmod/vfs_lfs_mount.py.exp new file mode 100644 index 0000000000..90aff35016 --- /dev/null +++ b/tests/extmod/vfs_lfs_mount.py.exp @@ -0,0 +1,6 @@ +test +hello from lfs +package +test +hello from lfs +package