test/py: fs: add extended write operation test
authorAKASHI Takahiro <takahiro.akashi@linaro.org>
Tue, 11 Sep 2018 06:59:20 +0000 (15:59 +0900)
committerAlexander Graf <agraf@suse.de>
Sun, 23 Sep 2018 19:55:30 +0000 (21:55 +0200)
In this commit and the following, test scripts for new filesystem
functionalities introduced by my patch set, "fs: fat: extend FAT write
operations," are provided.

In particular, this patch adds test cases for sub-directory write
and write with non-zero offset.

Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
Signed-off-by: Alexander Graf <agraf@suse.de>
test/py/tests/test_fs/conftest.py
test/py/tests/test_fs/fstest_defs.py
test/py/tests/test_fs/test_ext.py [new file with mode: 0644]

index 3437acc..d290859 100644 (file)
@@ -10,6 +10,7 @@ from subprocess import call, check_call, check_output, CalledProcessError
 from fstest_defs import *
 
 supported_fs_basic = ['fat16', 'fat32', 'ext4']
+supported_fs_ext = ['fat16', 'fat32']
 
 #
 # Filesystem test specific setup
@@ -20,6 +21,7 @@ def pytest_addoption(parser):
 
 def pytest_configure(config):
     global supported_fs_basic
+    global supported_fs_ext
 
     def intersect(listA, listB):
         return  [x for x in listA if x in listB]
@@ -28,11 +30,15 @@ def pytest_configure(config):
     if supported_fs:
         print("*** FS TYPE modified: %s" % supported_fs)
         supported_fs_basic =  intersect(supported_fs, supported_fs_basic)
+        supported_fs_ext =  intersect(supported_fs, supported_fs_ext)
 
 def pytest_generate_tests(metafunc):
     if 'fs_obj_basic' in metafunc.fixturenames:
         metafunc.parametrize('fs_obj_basic', supported_fs_basic,
             indirect=True, scope='module')
+    if 'fs_obj_ext' in metafunc.fixturenames:
+        metafunc.parametrize('fs_obj_ext', supported_fs_ext,
+            indirect=True, scope='module')
 
 #
 # Helper functions
@@ -216,3 +222,80 @@ def fs_obj_basic(request, u_boot_config):
         call('rmdir %s' % mount_dir, shell=True)
         if fs_img:
             call('rm -f %s' % fs_img, shell=True)
+
+#
+# Fixture for extended fs test
+#
+# NOTE: yield_fixture was deprecated since pytest-3.0
+@pytest.yield_fixture()
+def fs_obj_ext(request, u_boot_config):
+    fs_type = request.param
+    fs_img = ''
+
+    fs_ubtype = fstype_to_ubname(fs_type)
+    check_ubconfig(u_boot_config, fs_ubtype)
+
+    mount_dir = u_boot_config.persistent_data_dir + '/mnt'
+
+    min_file = mount_dir + '/' + MIN_FILE
+    tmp_file = mount_dir + '/tmpfile'
+
+    try:
+
+        # 128MiB volume
+        fs_img = mk_fs(u_boot_config, fs_type, 0x8000000, '128MB')
+
+        # Mount the image so we can populate it.
+        check_call('mkdir -p %s' % mount_dir, shell=True)
+        mount_fs(fs_type, fs_img, mount_dir)
+
+        # Create a test directory
+        check_call('mkdir %s/dir1' % mount_dir, shell=True)
+
+        # Create a small file and calculate md5
+        check_call('dd if=/dev/urandom of=%s bs=1K count=20'
+            % min_file, shell=True)
+        out = check_output(
+            'dd if=%s bs=1K 2> /dev/null | md5sum'
+            % min_file, shell=True)
+        md5val = [ out.split()[0] ]
+
+        # Calculate md5sum of Test Case 4
+        check_call('dd if=%s of=%s bs=1K count=20'
+            % (min_file, tmp_file), shell=True)
+        check_call('dd if=%s of=%s bs=1K seek=5 count=20'
+            % (min_file, tmp_file), shell=True)
+        out = check_output('dd if=%s bs=1K 2> /dev/null | md5sum'
+            % tmp_file, shell=True)
+        md5val.append(out.split()[0])
+
+        # Calculate md5sum of Test Case 5
+        check_call('dd if=%s of=%s bs=1K count=20'
+            % (min_file, tmp_file), shell=True)
+        check_call('dd if=%s of=%s bs=1K seek=5 count=5'
+            % (min_file, tmp_file), shell=True)
+        out = check_output('dd if=%s bs=1K 2> /dev/null | md5sum'
+            % tmp_file, shell=True)
+        md5val.append(out.split()[0])
+
+        # Calculate md5sum of Test Case 7
+        check_call('dd if=%s of=%s bs=1K count=20'
+            % (min_file, tmp_file), shell=True)
+        check_call('dd if=%s of=%s bs=1K seek=20 count=20'
+            % (min_file, tmp_file), shell=True)
+        out = check_output('dd if=%s bs=1K 2> /dev/null | md5sum'
+            % tmp_file, shell=True)
+        md5val.append(out.split()[0])
+
+        check_call('rm %s' % tmp_file, shell=True)
+        umount_fs(fs_type, mount_dir)
+    except CalledProcessError:
+        pytest.skip('Setup failed for filesystem: ' + fs_type)
+        return
+    else:
+        yield [fs_ubtype, fs_img, md5val]
+    finally:
+        umount_fs(fs_type, mount_dir)
+        call('rmdir %s' % mount_dir, shell=True)
+        if fs_img:
+            call('rm -f %s' % fs_img, shell=True)
index f26dd06..5f10756 100644 (file)
@@ -1,5 +1,8 @@
 # SPDX-License-Identifier:      GPL-2.0+
 
+# $MIN_FILE is the name of the 20KB file in the file system image
+MIN_FILE='testfile'
+
 # $SMALL_FILE is the name of the 1MB file in the file system image
 SMALL_FILE='1MB.file'
 
diff --git a/test/py/tests/test_fs/test_ext.py b/test/py/tests/test_fs/test_ext.py
new file mode 100644 (file)
index 0000000..38217d0
--- /dev/null
@@ -0,0 +1,224 @@
+# SPDX-License-Identifier:      GPL-2.0+
+# Copyright (c) 2018, Linaro Limited
+# Author: Takahiro Akashi <takahiro.akashi@linaro.org>
+#
+# U-Boot File System:Exntented Test
+
+"""
+This test verifies extended write operation on file system.
+"""
+
+import pytest
+import re
+from fstest_defs import *
+
+@pytest.mark.boardspec('sandbox')
+class TestFsExt(object):
+    def test_fs_ext1(self, u_boot_console, fs_obj_ext):
+        """
+        Test Case 1 - write a file with absolute path
+        """
+        fs_type,fs_img,md5val = fs_obj_ext
+        with u_boot_console.log.section('Test Case 1 - write with abs path'):
+            # Test Case 1a - Check if command successfully returned
+            output = u_boot_console.run_command_list([
+                'host bind 0 %s' % fs_img,
+                '%sload host 0:0 %x /%s' % (fs_type, ADDR, MIN_FILE),
+                '%swrite host 0:0 %x /dir1/%s.w1 $filesize'
+                    % (fs_type, ADDR, MIN_FILE)])
+            assert('20480 bytes written' in ''.join(output))
+
+            # Test Case 1b - Check md5 of file content
+            output = u_boot_console.run_command_list([
+                'mw.b %x 00 100' % ADDR,
+                '%sload host 0:0 %x /dir1/%s.w1' % (fs_type, ADDR, MIN_FILE),
+                'md5sum %x $filesize' % ADDR,
+                'setenv filesize'])
+            assert(md5val[0] in ''.join(output))
+
+    def test_fs_ext2(self, u_boot_console, fs_obj_ext):
+        """
+        Test Case 2 - write to a file with relative path
+        """
+        fs_type,fs_img,md5val = fs_obj_ext
+        with u_boot_console.log.section('Test Case 2 - write with rel path'):
+            # Test Case 2a - Check if command successfully returned
+            output = u_boot_console.run_command_list([
+                'host bind 0 %s' % fs_img,
+                '%sload host 0:0 %x /%s' % (fs_type, ADDR, MIN_FILE),
+                '%swrite host 0:0 %x dir1/%s.w2 $filesize'
+                    % (fs_type, ADDR, MIN_FILE)])
+            assert('20480 bytes written' in ''.join(output))
+
+            # Test Case 2b - Check md5 of file content
+            output = u_boot_console.run_command_list([
+                'mw.b %x 00 100' % ADDR,
+                '%sload host 0:0 %x dir1/%s.w2' % (fs_type, ADDR, MIN_FILE),
+                'md5sum %x $filesize' % ADDR,
+                'setenv filesize'])
+            assert(md5val[0] in ''.join(output))
+
+    def test_fs_ext3(self, u_boot_console, fs_obj_ext):
+        """
+        Test Case 3 - write to a file with invalid path
+        """
+        fs_type,fs_img,md5val = fs_obj_ext
+        with u_boot_console.log.section('Test Case 3 - write with invalid path'):
+            # Test Case 3 - Check if command expectedly failed
+            output = u_boot_console.run_command_list([
+                'host bind 0 %s' % fs_img,
+                '%sload host 0:0 %x /%s' % (fs_type, ADDR, MIN_FILE),
+                '%swrite host 0:0 %x /dir1/none/%s.w3 $filesize'
+                    % (fs_type, ADDR, MIN_FILE)])
+            assert('Unable to write "/dir1/none/' in ''.join(output))
+
+    def test_fs_ext4(self, u_boot_console, fs_obj_ext):
+        """
+        Test Case 4 - write at non-zero offset, enlarging file size
+        """
+        fs_type,fs_img,md5val = fs_obj_ext
+        with u_boot_console.log.section('Test Case 4 - write at non-zero offset, enlarging file size'):
+            # Test Case 4a - Check if command successfully returned
+            output = u_boot_console.run_command_list([
+                'host bind 0 %s' % fs_img,
+                '%sload host 0:0 %x /%s' % (fs_type, ADDR, MIN_FILE),
+                '%swrite host 0:0 %x /dir1/%s.w4 $filesize'
+                    % (fs_type, ADDR, MIN_FILE)])
+            output = u_boot_console.run_command(
+                '%swrite host 0:0 %x /dir1/%s.w4 $filesize 0x1400'
+                    % (fs_type, ADDR, MIN_FILE))
+            assert('20480 bytes written' in output)
+
+            # Test Case 4b - Check size of written file
+            output = u_boot_console.run_command_list([
+                '%ssize host 0:0 /dir1/%s.w4' % (fs_type, MIN_FILE),
+                'printenv filesize',
+                'setenv filesize'])
+            assert('filesize=6400' in ''.join(output))
+
+            # Test Case 4c - Check md5 of file content
+            output = u_boot_console.run_command_list([
+                'mw.b %x 00 100' % ADDR,
+                '%sload host 0:0 %x /dir1/%s.w4' % (fs_type, ADDR, MIN_FILE),
+                'md5sum %x $filesize' % ADDR,
+                'setenv filesize'])
+            assert(md5val[1] in ''.join(output))
+
+    def test_fs_ext5(self, u_boot_console, fs_obj_ext):
+        """
+        Test Case 5 - write at non-zero offset, shrinking file size
+        """
+        fs_type,fs_img,md5val = fs_obj_ext
+        with u_boot_console.log.section('Test Case 5 - write at non-zero offset, shrinking file size'):
+            # Test Case 5a - Check if command successfully returned
+            output = u_boot_console.run_command_list([
+                'host bind 0 %s' % fs_img,
+                '%sload host 0:0 %x /%s' % (fs_type, ADDR, MIN_FILE),
+                '%swrite host 0:0 %x /dir1/%s.w5 $filesize'
+                    % (fs_type, ADDR, MIN_FILE)])
+            output = u_boot_console.run_command(
+                '%swrite host 0:0 %x /dir1/%s.w5 0x1400 0x1400'
+                    % (fs_type, ADDR, MIN_FILE))
+            assert('5120 bytes written' in output)
+
+            # Test Case 5b - Check size of written file
+            output = u_boot_console.run_command_list([
+                '%ssize host 0:0 /dir1/%s.w5' % (fs_type, MIN_FILE),
+                'printenv filesize',
+                'setenv filesize'])
+            assert('filesize=2800' in ''.join(output))
+
+            # Test Case 5c - Check md5 of file content
+            output = u_boot_console.run_command_list([
+                'mw.b %x 00 100' % ADDR,
+                '%sload host 0:0 %x /dir1/%s.w5' % (fs_type, ADDR, MIN_FILE),
+                'md5sum %x $filesize' % ADDR,
+                'setenv filesize'])
+            assert(md5val[2] in ''.join(output))
+
+    def test_fs_ext6(self, u_boot_console, fs_obj_ext):
+        """
+        Test Case 6 - write nothing at the start, truncating to zero
+        """
+        fs_type,fs_img,md5val = fs_obj_ext
+        with u_boot_console.log.section('Test Case 6 - write nothing at the start, truncating to zero'):
+            # Test Case 6a - Check if command successfully returned
+            output = u_boot_console.run_command_list([
+                'host bind 0 %s' % fs_img,
+                '%sload host 0:0 %x /%s' % (fs_type, ADDR, MIN_FILE),
+                '%swrite host 0:0 %x /dir1/%s.w6 $filesize'
+                    % (fs_type, ADDR, MIN_FILE)])
+            output = u_boot_console.run_command(
+                '%swrite host 0:0 %x /dir1/%s.w6 0 0'
+                    % (fs_type, ADDR, MIN_FILE))
+            assert('0 bytes written' in output)
+
+            # Test Case 6b - Check size of written file
+            output = u_boot_console.run_command_list([
+                '%ssize host 0:0 /dir1/%s.w6' % (fs_type, MIN_FILE),
+                'printenv filesize',
+                'setenv filesize'])
+            assert('filesize=0' in ''.join(output))
+
+    def test_fs_ext7(self, u_boot_console, fs_obj_ext):
+        """
+        Test Case 7 - write at the end (append)
+        """
+        fs_type,fs_img,md5val = fs_obj_ext
+        with u_boot_console.log.section('Test Case 7 - write at the end (append)'):
+            # Test Case 7a - Check if command successfully returned
+            output = u_boot_console.run_command_list([
+                'host bind 0 %s' % fs_img,
+                '%sload host 0:0 %x /%s' % (fs_type, ADDR, MIN_FILE),
+                '%swrite host 0:0 %x /dir1/%s.w7 $filesize'
+                    % (fs_type, ADDR, MIN_FILE)])
+            output = u_boot_console.run_command(
+                '%swrite host 0:0 %x /dir1/%s.w7 $filesize $filesize'
+                    % (fs_type, ADDR, MIN_FILE))
+            assert('20480 bytes written' in output)
+
+            # Test Case 7b - Check size of written file
+            output = u_boot_console.run_command_list([
+                '%ssize host 0:0 /dir1/%s.w7' % (fs_type, MIN_FILE),
+                'printenv filesize',
+                'setenv filesize'])
+            assert('filesize=a000' in ''.join(output))
+
+            # Test Case 7c - Check md5 of file content
+            output = u_boot_console.run_command_list([
+                'mw.b %x 00 100' % ADDR,
+                '%sload host 0:0 %x /dir1/%s.w7' % (fs_type, ADDR, MIN_FILE),
+                'md5sum %x $filesize' % ADDR,
+                'setenv filesize'])
+            assert(md5val[3] in ''.join(output))
+
+    def test_fs_ext8(self, u_boot_console, fs_obj_ext):
+        """
+        Test Case 8 - write at offset beyond the end of file
+        """
+        fs_type,fs_img,md5val = fs_obj_ext
+        with u_boot_console.log.section('Test Case 8 - write beyond the end'):
+            # Test Case 8a - Check if command expectedly failed
+            output = u_boot_console.run_command_list([
+                'host bind 0 %s' % fs_img,
+                '%sload host 0:0 %x /%s' % (fs_type, ADDR, MIN_FILE),
+                '%swrite host 0:0 %x /dir1/%s.w8 $filesize'
+                    % (fs_type, ADDR, MIN_FILE)])
+            output = u_boot_console.run_command(
+                '%swrite host 0:0 %x /dir1/%s.w8 0x1400 %x'
+                    % (fs_type, ADDR, MIN_FILE, 0x100000 + 0x1400))
+            assert('Unable to write "/dir1' in output)
+
+    def test_fs_ext9(self, u_boot_console, fs_obj_ext):
+        """
+        Test Case 9 - write to a non-existing file at non-zero offset
+        """
+        fs_type,fs_img,md5val = fs_obj_ext
+        with u_boot_console.log.section('Test Case 9 - write to non-existing file with non-zero offset'):
+            # Test Case 9a - Check if command expectedly failed
+            output = u_boot_console.run_command_list([
+                'host bind 0 %s' % fs_img,
+                '%sload host 0:0 %x /%s' % (fs_type, ADDR, MIN_FILE),
+                '%swrite host 0:0 %x /dir1/%s.w9 0x1400 0x1400'
+                    % (fs_type, ADDR, MIN_FILE)])
+            assert('Unable to write "/dir1' in ''.join(output))