From 9ab84d2455c0ddb37749fb17f602f2800c4c40d8 Mon Sep 17 00:00:00 2001 From: matejcik Date: Wed, 26 Feb 2020 18:41:00 +0100 Subject: [PATCH] core/tests: thoroughly test modified APIs --- .../extmod/modtrezorio/modtrezorio-fatfs.h | 2 +- core/mocks/generated/trezorio/fatfs.pyi | 2 +- core/tests/test_trezor.io.fatfs.py | 200 ++++++++++++++---- 3 files changed, 157 insertions(+), 47 deletions(-) diff --git a/core/embed/extmod/modtrezorio/modtrezorio-fatfs.h b/core/embed/extmod/modtrezorio/modtrezorio-fatfs.h index dcbce48bd..fa2c4dbc3 100644 --- a/core/embed/extmod/modtrezorio/modtrezorio-fatfs.h +++ b/core/embed/extmod/modtrezorio/modtrezorio-fatfs.h @@ -449,7 +449,7 @@ STATIC mp_obj_t mod_trezorio_fatfs_stat(mp_obj_t path) { STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorio_fatfs_stat_obj, mod_trezorio_fatfs_stat); -/// def rename(self, oldpath: str, newpath: str) -> None: +/// def rename(oldpath: str, newpath: str) -> None: /// """ /// Rename/Move a file or directory /// """ diff --git a/core/mocks/generated/trezorio/fatfs.pyi b/core/mocks/generated/trezorio/fatfs.pyi index ffb21e5ad..d8bc6fd82 100644 --- a/core/mocks/generated/trezorio/fatfs.pyi +++ b/core/mocks/generated/trezorio/fatfs.pyi @@ -101,7 +101,7 @@ def stat(path: str) -> Tuple[int, str, str]: # extmod/modtrezorio/modtrezorio-fatfs.h -def rename(self, oldpath: str, newpath: str) -> None: +def rename(oldpath: str, newpath: str) -> None: """ Rename/Move a file or directory """ diff --git a/core/tests/test_trezor.io.fatfs.py b/core/tests/test_trezor.io.fatfs.py index 1e2a7fbf7..269f10502 100644 --- a/core/tests/test_trezor.io.fatfs.py +++ b/core/tests/test_trezor.io.fatfs.py @@ -1,19 +1,17 @@ from common import * -from trezor import io +from trezorio import sdcard, fatfs class TestTrezorIoFatfs(unittest.TestCase): - def setUp(self): - io.sdcard.power_on() - self.fs = io.FatFS() - self.fs.mkfs() - self.fs.mount() + sdcard.power_on() + fatfs.mkfs() + fatfs.mount() def tearDown(self): - self.fs.unmount() - io.sdcard.power_off() + fatfs.unmount() + sdcard.power_off() def _filename(self, suffix=""): return "FILE%s.TXT" % suffix @@ -26,78 +24,80 @@ class TestTrezorIoFatfs(unittest.TestCase): pass def test_mkdir(self): - self.fs.mkdir("/%s" % self._dirname()) - s = self.fs.stat("/%s" % self._dirname()) + fatfs.mkdir("/%s" % self._dirname()) + s = fatfs.stat("/%s" % self._dirname()) self.assertEqual(s, (0, "---d-", self._dirname())) def test_listdir(self): - self.fs.mkdir("/%s" % self._dirname()) - with self.fs.open("/%s" % self._filename(), "w") as f: + fatfs.mkdir("/%s" % self._dirname()) + with fatfs.open("/%s" % self._filename(), "w") as f: f.write(bytearray(b"test")) - with self.fs.open("/%s/%s" % (self._dirname(), self._filename("2")), "w") as f: + with fatfs.open("/%s/%s" % (self._dirname(), self._filename("2")), "w") as f: f.write(bytearray(b"testtest")) - l = [e for e in self.fs.listdir("/")] - self.assertEqual(l, [(0, "---d-", self._dirname()), (4, "----a", self._filename())]) - l = [e for e in self.fs.listdir("/%s" % self._dirname())] + l = [e for e in fatfs.listdir("/")] + self.assertEqual( + l, [(0, "---d-", self._dirname()), (4, "----a", self._filename())] + ) + l = [e for e in fatfs.listdir("/%s" % self._dirname())] self.assertEqual(l, [(8, "----a", self._filename("2"))]) def test_unlink(self): - self.fs.mkdir("/%s" % self._dirname()) - with self.fs.open("/%s" % self._filename(), "w") as f: + fatfs.mkdir("/%s" % self._dirname()) + with fatfs.open("/%s" % self._filename(), "w") as f: f.write(bytearray(b"test")) - s = self.fs.stat("/%s" % self._dirname()) + s = fatfs.stat("/%s" % self._dirname()) self.assertEqual(s, (0, "---d-", self._dirname())) - s = self.fs.stat("/%s" % self._filename()) + s = fatfs.stat("/%s" % self._filename()) self.assertEqual(s, (4, "----a", self._filename())) - self.fs.unlink("/%s" % self._dirname()) - self.fs.unlink("/%s" % self._filename()) + fatfs.unlink("/%s" % self._dirname()) + fatfs.unlink("/%s" % self._filename()) with self.assertRaises(OSError): - self.fs.stat("/%s" % self._dirname()) + fatfs.stat("/%s" % self._dirname()) with self.assertRaises(OSError): - self.assertRaises(self.fs.stat("/%s" % self._filename())) + self.assertRaises(fatfs.stat("/%s" % self._filename())) def test_rename(self): - self.fs.mkdir("/%s" % self._dirname()) - with self.fs.open("/%s" % self._filename(), "w") as f: + fatfs.mkdir("/%s" % self._dirname()) + with fatfs.open("/%s" % self._filename(), "w") as f: f.write(bytearray(b"test")) - s = self.fs.stat("/%s" % self._dirname()) + s = fatfs.stat("/%s" % self._dirname()) self.assertEqual(s, (0, "---d-", self._dirname())) - s = self.fs.stat("/%s" % self._filename()) + s = fatfs.stat("/%s" % self._filename()) self.assertEqual(s, (4, "----a", self._filename())) - self.fs.rename("/%s" % self._dirname(), "/%s" % self._dirname("2")) - self.fs.rename("/%s" % self._filename(), "/%s" % self._filename("2")) + fatfs.rename("/%s" % self._dirname(), "/%s" % self._dirname("2")) + fatfs.rename("/%s" % self._filename(), "/%s" % self._filename("2")) with self.assertRaises(OSError): - self.fs.stat("/%s" % self._dirname()) + fatfs.stat("/%s" % self._dirname()) with self.assertRaises(OSError): - self.assertRaises(self.fs.stat("/%s" % self._filename())) - s = self.fs.stat("/%s" % self._dirname("2")) + self.assertRaises(fatfs.stat("/%s" % self._filename())) + s = fatfs.stat("/%s" % self._dirname("2")) self.assertEqual(s, (0, "---d-", self._dirname("2"))) - s = self.fs.stat("/%s" % self._filename("2")) + s = fatfs.stat("/%s" % self._filename("2")) self.assertEqual(s, (4, "----a", self._filename("2"))) def test_open_rw(self): - with self.fs.open("/%s" % self._filename(), "w") as f: + with fatfs.open("/%s" % self._filename(), "w") as f: f.write(bytearray(b"test")) - with self.fs.open("/%s" % self._filename(), "r") as f: + with fatfs.open("/%s" % self._filename(), "r") as f: b = bytearray(100) r = f.read(b) self.assertEqual(r, 4) self.assertEqual(bytes(b[:4]), b"test") def test_open_a(self): - with self.fs.open("/%s" % self._filename(), "w") as f: + with fatfs.open("/%s" % self._filename(), "w") as f: f.write(bytearray(b"test" * 200)) - with self.fs.open("/%s" % self._filename(), "a") as f: + with fatfs.open("/%s" % self._filename(), "a") as f: f.seek(800) f.write(bytearray(b"TEST" * 200)) - with self.fs.open("/%s" % self._filename(), "r") as f: + with fatfs.open("/%s" % self._filename(), "r") as f: b = bytearray(2000) r = f.read(b) self.assertEqual(r, 1600) self.assertEqual(bytes(b[:1600]), b"test" * 200 + b"TEST" * 200) def test_seek(self): - with self.fs.open("/%s" % self._filename(), "w+") as f: + with fatfs.open("/%s" % self._filename(), "w+") as f: f.write(bytearray(b"test" * 10)) f.seek(2) b = bytearray(8) @@ -106,19 +106,18 @@ class TestTrezorIoFatfs(unittest.TestCase): self.assertEqual(bytes(b[:8]), b"sttestte") def test_truncate(self): - with self.fs.open("/%s" % self._filename(), "w") as f: + with fatfs.open("/%s" % self._filename(), "w") as f: f.write(bytearray(b"test" * 100)) - s = self.fs.stat("/%s" % self._filename()) + s = fatfs.stat("/%s" % self._filename()) self.assertEqual(s, (400, "----a", self._filename())) - with self.fs.open("/%s" % self._filename(), "a") as f: + with fatfs.open("/%s" % self._filename(), "a") as f: f.seek(111) f.truncate() - s = self.fs.stat("/%s" % self._filename()) + s = fatfs.stat("/%s" % self._filename()) self.assertEqual(s, (111, "----a", self._filename())) class TestTrezorIoFatfsLfn(TestTrezorIoFatfs): - def _filename(self, suffix=""): return "reallylongfilename%s.textfile" % suffix @@ -126,5 +125,116 @@ class TestTrezorIoFatfsLfn(TestTrezorIoFatfs): return "reallylongdirname%s" % suffix +class TestTrezorIoFatfsMounting(unittest.TestCase): + MOUNTED_METHODS = [ + ("open", ("hello.txt", "w")), + ("listdir", ("",)), + ("mkdir", ("testdir",)), + ("unlink", ("hello.txt",)), + ("stat", ("testdir",)), + ("rename", ("testdir", "newdir")), + ("setlabel", ("label",)), + ] + UNMOUNTED_METHODS = [ + ("mkfs", ()), + ] + OTHER = { + "__name__", + "__class__", + "mount", + "unmount", + "is_mounted", + "FatFSFile", + "FatFSDir", + } + + def setUp(self): + sdcard.power_on() + + def tearDown(self): + sdcard.power_off() + + def test_mount_unmount(self): + fatfs.mkfs() + + self.assertFalse(fatfs.is_mounted()) + fatfs.mount() + self.assertTrue(fatfs.is_mounted()) + fatfs.mount() + self.assertTrue(fatfs.is_mounted()) + fatfs.unmount() + self.assertFalse(fatfs.is_mounted()) + + def test_no_filesystem(self): + # trash FAT table + sdcard.write(0, bytes([0xFF] * sdcard.BLOCK_SIZE)) + + self.assertFalse(fatfs.is_mounted()) + try: + fatfs.mount() + self.fail("should have raised") + except OSError as e: + self.assertEqual(e.args[0], 19) # ENODEV + self.assertFalse(fatfs.is_mounted()) + + def test_exhaustive(self): + all_symbols = ( + set(name for name, call in (self.MOUNTED_METHODS + self.UNMOUNTED_METHODS)) + | self.OTHER + ) + self.assertEqual(set(dir(fatfs)), all_symbols) + + def test_mounted(self): + fatfs.mkfs() + fatfs.mount() + self.assertTrue(fatfs.is_mounted()) + + for name, call in self.MOUNTED_METHODS: + function = getattr(fatfs, name) + function(*call) + + for name, call in self.UNMOUNTED_METHODS: + function = getattr(fatfs, name) + try: + function(*call) + self.fail("should have raised") + except OSError as e: + self.assertEqual(e.args[0], 16) # EBUSY + + def test_unmounted(self): + fatfs.unmount() + fatfs.mkfs() + self.assertFalse(fatfs.is_mounted()) + + for name, call in self.UNMOUNTED_METHODS: + function = getattr(fatfs, name) + function(*call) + self.assertFalse(fatfs.is_mounted()) + + for name, call in self.MOUNTED_METHODS: + function = getattr(fatfs, name) + try: + function(*call) + self.fail("should have raised") + except OSError as e: + self.assertEqual(e.args[0], 19) # ENODEV + + +class TestTrezorIoFatfsAndSdcard(unittest.TestCase): + def test_sd_power(self): + sdcard.power_off() + self.assertFalse(fatfs.is_mounted()) + self.assertRaises(OSError, fatfs.mount) + + sdcard.power_on() + self.assertFalse(fatfs.is_mounted()) + fatfs.mkfs() + fatfs.mount() + self.assertTrue(fatfs.is_mounted()) + + sdcard.power_off() + self.assertFalse(fatfs.is_mounted()) + + if __name__ == "__main__": unittest.main()