test: fs: Added tests for symlinks
authorJean-Jacques Hiblot <jjhiblot@ti.com>
Wed, 13 Feb 2019 11:15:27 +0000 (12:15 +0100)
committerTom Rini <trini@konsulko.com>
Wed, 10 Apr 2019 00:04:03 +0000 (20:04 -0400)
Test cases are:
1) basic link creation, verify it can be followed
2) chained links, verify it can be followed
3) replace exiting file a with a link, and a link with a link. verify it
   can be followed
4) create a broken link, verify it can't be followed

Signed-off-by: Jean-Jacques Hiblot <jjhiblot@ti.com>
Reviewed-by: Tom Rini <trini@konsulko.com>
test/py/tests/test_fs/conftest.py
test/py/tests/test_fs/fstest_defs.py
test/py/tests/test_fs/test_symlink.py [new file with mode: 0644]

index 745ed0e..9324657 100644 (file)
@@ -13,6 +13,7 @@ supported_fs_basic = ['fat16', 'fat32', 'ext4']
 supported_fs_ext = ['fat16', 'fat32']
 supported_fs_mkdir = ['fat16', 'fat32']
 supported_fs_unlink = ['fat16', 'fat32']
+supported_fs_symlink = ['ext4']
 
 #
 # Filesystem test specific setup
@@ -48,6 +49,7 @@ def pytest_configure(config):
     global supported_fs_ext
     global supported_fs_mkdir
     global supported_fs_unlink
+    global supported_fs_symlink
 
     def intersect(listA, listB):
         return  [x for x in listA if x in listB]
@@ -59,6 +61,7 @@ def pytest_configure(config):
         supported_fs_ext =  intersect(supported_fs, supported_fs_ext)
         supported_fs_mkdir =  intersect(supported_fs, supported_fs_mkdir)
         supported_fs_unlink =  intersect(supported_fs, supported_fs_unlink)
+        supported_fs_symlink =  intersect(supported_fs, supported_fs_symlink)
 
 def pytest_generate_tests(metafunc):
     """Parametrize fixtures, fs_obj_xxx
@@ -84,6 +87,9 @@ def pytest_generate_tests(metafunc):
     if 'fs_obj_unlink' in metafunc.fixturenames:
         metafunc.parametrize('fs_obj_unlink', supported_fs_unlink,
             indirect=True, scope='module')
+    if 'fs_obj_symlink' in metafunc.fixturenames:
+        metafunc.parametrize('fs_obj_symlink', supported_fs_symlink,
+            indirect=True, scope='module')
 
 #
 # Helper functions
@@ -525,3 +531,72 @@ def fs_obj_unlink(request, u_boot_config):
         call('rmdir %s' % mount_dir, shell=True)
         if fs_img:
             call('rm -f %s' % fs_img, shell=True)
+
+#
+# Fixture for symlink fs test
+#
+# NOTE: yield_fixture was deprecated since pytest-3.0
+@pytest.yield_fixture()
+def fs_obj_symlink(request, u_boot_config):
+    """Set up a file system to be used in symlink fs test.
+
+    Args:
+        request: Pytest request object.
+        u_boot_config: U-boot configuration.
+
+    Return:
+        A fixture for basic fs test, i.e. a triplet of file system type,
+        volume file name and  a list of MD5 hashes.
+    """
+    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'
+
+    small_file = mount_dir + '/' + SMALL_FILE
+    medium_file = mount_dir + '/' + MEDIUM_FILE
+
+    try:
+
+        # 3GiB volume
+        fs_img = mk_fs(u_boot_config, fs_type, 0x40000000, '1GB')
+
+        # 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 subdirectory.
+        check_call('mkdir %s/SUBDIR' % mount_dir, shell=True)
+
+        # Create a small file in this image.
+        check_call('dd if=/dev/urandom of=%s bs=1M count=1'
+                   % small_file, shell=True)
+
+        # Create a medium file in this image.
+        check_call('dd if=/dev/urandom of=%s bs=10M count=1'
+                   % medium_file, shell=True)
+
+        # Generate the md5sums of reads that we will test against small file
+        out = check_output(
+            'dd if=%s bs=1M skip=0 count=1 2> /dev/null | md5sum'
+            % small_file, shell=True)
+        md5val = [out.split()[0]]
+        out = check_output(
+            'dd if=%s bs=10M skip=0 count=1 2> /dev/null | md5sum'
+            % medium_file, shell=True)
+        md5val.extend([out.split()[0]])
+
+        umount_fs(mount_dir)
+    except CalledProcessError:
+        pytest.skip('Setup failed for filesystem: ' + fs_type)
+        return
+    else:
+        yield [fs_ubtype, fs_img, md5val]
+    finally:
+        umount_fs(mount_dir)
+        call('rmdir %s' % mount_dir, shell=True)
+        if fs_img:
+            call('rm -f %s' % fs_img, shell=True)
index 5f10756..35b2bb6 100644 (file)
@@ -6,6 +6,9 @@ MIN_FILE='testfile'
 # $SMALL_FILE is the name of the 1MB file in the file system image
 SMALL_FILE='1MB.file'
 
+# $MEDIUM_FILE is the name of the 10MB file in the file system image
+MEDIUM_FILE='10MB.file'
+
 # $BIG_FILE is the name of the 2.5GB file in the file system image
 BIG_FILE='2.5GB.file'
 
diff --git a/test/py/tests/test_fs/test_symlink.py b/test/py/tests/test_fs/test_symlink.py
new file mode 100644 (file)
index 0000000..9ced101
--- /dev/null
@@ -0,0 +1,130 @@
+# SPDX-License-Identifier:      GPL-2.0+
+# Copyright (c) 2019, Texas Instrument
+# Author: Jean-Jacques Hiblot <jjhiblot@ti.com>
+#
+# U-Boot File System:symlink Test
+
+"""
+This test verifies unlink operation (deleting a file or a directory)
+on file system.
+"""
+
+import pytest
+import re
+from fstest_defs import *
+from fstest_helpers import assert_fs_integrity
+
+
+@pytest.mark.boardspec('sandbox')
+@pytest.mark.slow
+class TestSymlink(object):
+    def test_symlink1(self, u_boot_console, fs_obj_symlink):
+        """
+        Test Case 1 - create a link. and follow it when reading
+        """
+        fs_type, fs_img, md5val = fs_obj_symlink
+        with u_boot_console.log.section('Test Case 1 - create link and read'):
+            output = u_boot_console.run_command_list([
+                'host bind 0 %s' % fs_img,
+                'setenv filesize',
+                'ln host 0:0 %s /%s.link ' % (SMALL_FILE, SMALL_FILE),
+            ])
+            assert('' in ''.join(output))
+
+            output = u_boot_console.run_command_list([
+                '%sload host 0:0 %x /%s.link' % (fs_type, ADDR, SMALL_FILE),
+                'printenv filesize'])
+            assert('filesize=100000' in ''.join(output))
+
+            # Test Case 4b - Read full 1MB of small file
+            output = u_boot_console.run_command_list([
+                'md5sum %x $filesize' % ADDR,
+                'setenv filesize'])
+            assert(md5val[0] in ''.join(output))
+            assert_fs_integrity(fs_type, fs_img)
+
+    def test_symlink2(self, u_boot_console, fs_obj_symlink):
+        """
+        Test Case 2 - create chained links
+        """
+        fs_type, fs_img, md5val = fs_obj_symlink
+        with u_boot_console.log.section('Test Case 2 - create chained links'):
+            output = u_boot_console.run_command_list([
+                'host bind 0 %s' % fs_img,
+                'setenv filesize',
+                'ln host 0:0 %s /%s.link1 ' % (SMALL_FILE, SMALL_FILE),
+                'ln host 0:0 /%s.link1 /SUBDIR/%s.link2' % (
+                    SMALL_FILE, SMALL_FILE),
+                'ln host 0:0 SUBDIR/%s.link2 /%s.link3' % (
+                    SMALL_FILE, SMALL_FILE),
+            ])
+            assert('' in ''.join(output))
+
+            output = u_boot_console.run_command_list([
+                '%sload host 0:0 %x /%s.link3' % (fs_type, ADDR, SMALL_FILE),
+                'printenv filesize'])
+            assert('filesize=100000' in ''.join(output))
+
+            # Test Case 4b - Read full 1MB of small file
+            output = u_boot_console.run_command_list([
+                'md5sum %x $filesize' % ADDR,
+                'setenv filesize'])
+            assert(md5val[0] in ''.join(output))
+            assert_fs_integrity(fs_type, fs_img)
+
+    def test_symlink3(self, u_boot_console, fs_obj_symlink):
+        """
+        Test Case 3 - replace file/link with link
+        """
+        fs_type, fs_img, md5val = fs_obj_symlink
+        with u_boot_console.log.section('Test Case 1 - create link and read'):
+            output = u_boot_console.run_command_list([
+                'host bind 0 %s' % fs_img,
+                'setenv filesize',
+                'ln host 0:0 %s /%s ' % (MEDIUM_FILE, SMALL_FILE),
+                'ln host 0:0 %s /%s.link ' % (MEDIUM_FILE, MEDIUM_FILE),
+            ])
+            assert('' in ''.join(output))
+
+            output = u_boot_console.run_command_list([
+                '%sload host 0:0 %x /%s' % (fs_type, ADDR, SMALL_FILE),
+                'printenv filesize'])
+            assert('filesize=a00000' in ''.join(output))
+
+            output = u_boot_console.run_command_list([
+                'md5sum %x $filesize' % ADDR,
+                'setenv filesize'])
+            assert(md5val[1] in ''.join(output))
+
+            output = u_boot_console.run_command_list([
+                'ln host 0:0 %s.link /%s ' % (MEDIUM_FILE, SMALL_FILE),
+                '%sload host 0:0 %x /%s' % (fs_type, ADDR, SMALL_FILE),
+                'printenv filesize'])
+            assert('filesize=a00000' in ''.join(output))
+
+            output = u_boot_console.run_command_list([
+                'md5sum %x $filesize' % ADDR,
+                'setenv filesize'])
+            assert(md5val[1] in ''.join(output))
+            assert_fs_integrity(fs_type, fs_img)
+
+    def test_symlink4(self, u_boot_console, fs_obj_symlink):
+        """
+        Test Case 4 - create a broken link
+        """
+        fs_type, fs_img, md5val = fs_obj_symlink
+        with u_boot_console.log.section('Test Case 1 - create link and read'):
+
+            output = u_boot_console.run_command_list([
+                'setenv filesize',
+                'ln host 0:0 nowhere /link ',
+            ])
+            assert('' in ''.join(output))
+
+            output = u_boot_console.run_command(
+                '%sload host 0:0 %x /link' %
+                (fs_type, ADDR))
+            with u_boot_console.disable_check('error_notification'):
+                output = u_boot_console.run_command('printenv filesize')
+            assert('"filesize" not defined' in ''.join(output))
+            assert_fs_integrity(fs_type, fs_img)