aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorDamien George2020-07-29 01:01:48 +1000
committerDamien George2020-08-25 17:35:19 +1000
commit2acc087880de39d7e17abc9344b8d2faba3478dd (patch)
treee7a8e21a14bad32ef1b78b351c8d754962e18d1c /tests
parentee50a6effebf315c38d4a129dc9f65ee722eb5b6 (diff)
extmod/vfs_lfs: Add mtime support to littlefs files.
This commit adds support for modification time of files on littlefs v2 filesystems, using file attributes. For some background see issue #6114. Features/properties of this implementation: - Only supported on littlefs2 (not littlefs1). - Uses littlefs2's general file attributes to store the timestamp. - The timestamp is 64-bits and stores nanoseconds since 1970/1/1 (if the range to the year 2554 is not enough then additional bits can be added to this timestamp by adding another file attribute). - mtime is enabled by default but can be disabled in the constructor, eg: uos.mount(uos.VfsLfs2(bdev, mtime=False), '/flash') - It's fully backwards compatible, existing littlefs2 filesystems will work without reformatting and timestamps will be added transparently to existing files (once they are opened for writing). - Files without timestamps will open correctly, and stat will just return 0 for their timestamp. - mtime can be disabled or enabled each mount time and timestamps will only be updated if mtime is enabled (otherwise they will be untouched). Signed-off-by: Damien George <damien@micropython.org>
Diffstat (limited to 'tests')
-rw-r--r--tests/extmod/vfs_lfs.py13
-rw-r--r--tests/extmod/vfs_lfs.py.exp16
-rw-r--r--tests/extmod/vfs_lfs_mtime.py98
-rw-r--r--tests/extmod/vfs_lfs_mtime.py.exp13
4 files changed, 128 insertions, 12 deletions
diff --git a/tests/extmod/vfs_lfs.py b/tests/extmod/vfs_lfs.py
index 609d9f949..8e56400df 100644
--- a/tests/extmod/vfs_lfs.py
+++ b/tests/extmod/vfs_lfs.py
@@ -35,6 +35,11 @@ class RAMBlockDevice:
return 0
+def print_stat(st, print_size=True):
+ # don't print times (just check that they have the correct type)
+ print(st[:6], st[6] if print_size else -1, type(st[7]), type(st[8]), type(st[9]))
+
+
def test(bdev, vfs_class):
print("test", vfs_class)
@@ -69,10 +74,10 @@ def test(bdev, vfs_class):
vfs.mkdir("testdir")
# stat a file
- print(vfs.stat("test"))
+ print_stat(vfs.stat("test"))
# stat a dir (size seems to vary on LFS2 so don't print that)
- print(vfs.stat("testdir")[:6])
+ print_stat(vfs.stat("testdir"), False)
# read
with vfs.open("test", "r") as f:
@@ -112,8 +117,8 @@ def test(bdev, vfs_class):
# create file in directory to make sure paths are relative
vfs.open("test2", "w").close()
- print(vfs.stat("test2"))
- print(vfs.stat("/testdir/test2"))
+ print_stat(vfs.stat("test2"))
+ print_stat(vfs.stat("/testdir/test2"))
vfs.remove("test2")
# chdir back to root and remove testdir
diff --git a/tests/extmod/vfs_lfs.py.exp b/tests/extmod/vfs_lfs.py.exp
index a70255774..a0450c84b 100644
--- a/tests/extmod/vfs_lfs.py.exp
+++ b/tests/extmod/vfs_lfs.py.exp
@@ -7,8 +7,8 @@ test <class 'VfsLfs1'>
[('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)
+(32768, 0, 0, 0, 0, 0) 8 <class 'int'> <class 'int'> <class 'int'>
+(16384, 0, 0, 0, 0, 0) -1 <class 'int'> <class 'int'> <class 'int'>
littlefs
data length: 4096
write 0
@@ -22,8 +22,8 @@ write 3
[('test', 32768, 0, 8), ('testdir', 16384, 0, 0)]
/
/testdir
-(32768, 0, 0, 0, 0, 0, 0, 0, 0, 0)
-(32768, 0, 0, 0, 0, 0, 0, 0, 0, 0)
+(32768, 0, 0, 0, 0, 0) 0 <class 'int'> <class 'int'> <class 'int'>
+(32768, 0, 0, 0, 0, 0) 0 <class 'int'> <class 'int'> <class 'int'>
/
/testdir
/
@@ -44,8 +44,8 @@ test <class 'VfsLfs2'>
[('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)
+(32768, 0, 0, 0, 0, 0) 8 <class 'int'> <class 'int'> <class 'int'>
+(16384, 0, 0, 0, 0, 0) -1 <class 'int'> <class 'int'> <class 'int'>
littlefs
data length: 4096
write 0
@@ -59,8 +59,8 @@ write 3
[('test', 32768, 0, 8), ('testdir', 16384, 0, 0)]
/
/testdir
-(32768, 0, 0, 0, 0, 0, 0, 0, 0, 0)
-(32768, 0, 0, 0, 0, 0, 0, 0, 0, 0)
+(32768, 0, 0, 0, 0, 0) 0 <class 'int'> <class 'int'> <class 'int'>
+(32768, 0, 0, 0, 0, 0) 0 <class 'int'> <class 'int'> <class 'int'>
/
/testdir
/
diff --git a/tests/extmod/vfs_lfs_mtime.py b/tests/extmod/vfs_lfs_mtime.py
new file mode 100644
index 000000000..010807688
--- /dev/null
+++ b/tests/extmod/vfs_lfs_mtime.py
@@ -0,0 +1,98 @@
+# Test for VfsLfs using a RAM device, mtime feature
+
+try:
+ import utime, uos
+
+ utime.sleep
+ 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)
+
+ # Initial format of block device.
+ vfs_class.mkfs(bdev)
+
+ # construction
+ print("mtime=True")
+ vfs = vfs_class(bdev, mtime=True)
+
+ # Create an empty file, should have a timestamp.
+ vfs.open("test1", "wt").close()
+
+ # Wait 1 second so mtime will increase by at least 1.
+ utime.sleep(1)
+
+ # Create another empty file, should have a timestamp.
+ vfs.open("test2", "wt").close()
+
+ # Stat the files and check that test1 is older than test2.
+ stat1 = vfs.stat("test1")
+ stat2 = vfs.stat("test2")
+ print(stat1[8] != 0, stat2[8] != 0)
+ print(stat1[8] < stat2[8])
+
+ # Wait 1 second so mtime will increase by at least 1.
+ utime.sleep(1)
+
+ # Open test1 for reading and ensure mtime did not change.
+ vfs.open("test1", "rt").close()
+ print(vfs.stat("test1") == stat1)
+
+ # Open test1 for writing and ensure mtime increased from the previous value.
+ vfs.open("test1", "wt").close()
+ stat1_old = stat1
+ stat1 = vfs.stat("test1")
+ print(stat1_old[8] < stat1[8])
+
+ # Unmount.
+ vfs.umount()
+
+ # Check that remounting with mtime=False can read the timestamps.
+ print("mtime=False")
+ vfs = vfs_class(bdev, mtime=False)
+ print(vfs.stat("test1") == stat1)
+ print(vfs.stat("test2") == stat2)
+ f = vfs.open("test1", "wt")
+ f.close()
+ print(vfs.stat("test1") == stat1)
+ vfs.umount()
+
+ # Check that remounting with mtime=True still has the timestamps.
+ print("mtime=True")
+ vfs = vfs_class(bdev, mtime=True)
+ print(vfs.stat("test1") == stat1)
+ print(vfs.stat("test2") == stat2)
+ vfs.umount()
+
+
+bdev = RAMBlockDevice(30)
+test(bdev, uos.VfsLfs2)
diff --git a/tests/extmod/vfs_lfs_mtime.py.exp b/tests/extmod/vfs_lfs_mtime.py.exp
new file mode 100644
index 000000000..2e3d7491b
--- /dev/null
+++ b/tests/extmod/vfs_lfs_mtime.py.exp
@@ -0,0 +1,13 @@
+test <class 'VfsLfs2'>
+mtime=True
+True True
+True
+True
+True
+mtime=False
+True
+True
+True
+mtime=True
+True
+True