diff mbox series

[U-Boot,v2,21/23] test/py: convert fs-test.sh to pytest

Message ID 20180904074948.18146-22-takahiro.akashi@linaro.org
State Changes Requested
Delegated to: Tom Rini
Headers show
Series subject: fs: fat: extend FAT write operations | expand

Commit Message

AKASHI Takahiro Sept. 4, 2018, 7:49 a.m. UTC
In this commit, the same set of test cases as in test/fs/fs-test.sh
is provided using pytest framework.
Actually, fs-test.sh provides three variants:"sb" (sb command), "nonfs"
(fatxx and etc.) and "fs" (hostfs), and this patch currently supports
only "nonfs" variant; So it is not a replacement of fs-test.sh for now.

Simple usage:
  $ py.test test/py/tests/test_fs [<other options>]

You may also specify filesystem types to be tested:
  $ py.test test/py/tests/test_fs --fs-type fat32 [<other options>]

Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
---
 test/py/tests/test_fs/conftest.py    | 216 ++++++++++++++++++++
 test/py/tests/test_fs/fstest_defs.py |  10 +
 test/py/tests/test_fs/test_basic.py  | 287 +++++++++++++++++++++++++++
 3 files changed, 513 insertions(+)
 create mode 100644 test/py/tests/test_fs/conftest.py
 create mode 100644 test/py/tests/test_fs/fstest_defs.py
 create mode 100644 test/py/tests/test_fs/test_basic.py

Comments

Simon Glass Sept. 14, 2018, 10:54 a.m. UTC | #1
Hi Akashi,

On 4 September 2018 at 09:49, AKASHI Takahiro
<takahiro.akashi@linaro.org> wrote:
> In this commit, the same set of test cases as in test/fs/fs-test.sh
> is provided using pytest framework.
> Actually, fs-test.sh provides three variants:"sb" (sb command), "nonfs"
> (fatxx and etc.) and "fs" (hostfs), and this patch currently supports
> only "nonfs" variant; So it is not a replacement of fs-test.sh for now.
>
> Simple usage:
>   $ py.test test/py/tests/test_fs [<other options>]
>
> You may also specify filesystem types to be tested:
>   $ py.test test/py/tests/test_fs --fs-type fat32 [<other options>]
>
> Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
> ---
>  test/py/tests/test_fs/conftest.py    | 216 ++++++++++++++++++++
>  test/py/tests/test_fs/fstest_defs.py |  10 +
>  test/py/tests/test_fs/test_basic.py  | 287 +++++++++++++++++++++++++++
>  3 files changed, 513 insertions(+)
>  create mode 100644 test/py/tests/test_fs/conftest.py
>  create mode 100644 test/py/tests/test_fs/fstest_defs.py
>  create mode 100644 test/py/tests/test_fs/test_basic.py

Thanks for doing this!

Can you also please delete the old shell script?

Does this get automatically executed with 'make tests'?

If not, is it possible to do that easily, if we reduce the size of files, etc?

>
> diff --git a/test/py/tests/test_fs/conftest.py b/test/py/tests/test_fs/conftest.py
> new file mode 100644
> index 000000000000..9155ccf84266
> --- /dev/null
> +++ b/test/py/tests/test_fs/conftest.py
> @@ -0,0 +1,216 @@
> +# SPDX-License-Identifier:      GPL-2.0+
> +# Copyright (c) 2018, Linaro Limited
> +# Author: Takahiro Akashi <takahiro.akashi@linaro.org>
> +
> +import os
> +import os.path
> +import pytest
> +import re
> +from subprocess import call, check_call, check_output, CalledProcessError
> +from fstest_defs import *
> +
> +supported_fs_basic = ['fat16', 'fat32', 'ext4']
> +
> +#
> +# Filesystem test specific setup
> +#
> +def pytest_addoption(parser):

Please can you add full function comments to each function? You can
see other tests or binman for the format to use.
[...]

Regards,
Simon
AKASHI Takahiro Sept. 25, 2018, 4:47 a.m. UTC | #2
Simon,

Sorry for not responding soon.

On Fri, Sep 14, 2018 at 12:54:57PM +0200, Simon Glass wrote:
> Hi Akashi,
> 
> On 4 September 2018 at 09:49, AKASHI Takahiro
> <takahiro.akashi@linaro.org> wrote:
> > In this commit, the same set of test cases as in test/fs/fs-test.sh
> > is provided using pytest framework.
> > Actually, fs-test.sh provides three variants:"sb" (sb command), "nonfs"
> > (fatxx and etc.) and "fs" (hostfs), and this patch currently supports
> > only "nonfs" variant; So it is not a replacement of fs-test.sh for now.
> >
> > Simple usage:
> >   $ py.test test/py/tests/test_fs [<other options>]
> >
> > You may also specify filesystem types to be tested:
> >   $ py.test test/py/tests/test_fs --fs-type fat32 [<other options>]
> >
> > Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
> > ---
> >  test/py/tests/test_fs/conftest.py    | 216 ++++++++++++++++++++
> >  test/py/tests/test_fs/fstest_defs.py |  10 +
> >  test/py/tests/test_fs/test_basic.py  | 287 +++++++++++++++++++++++++++
> >  3 files changed, 513 insertions(+)
> >  create mode 100644 test/py/tests/test_fs/conftest.py
> >  create mode 100644 test/py/tests/test_fs/fstest_defs.py
> >  create mode 100644 test/py/tests/test_fs/test_basic.py
> 
> Thanks for doing this!
> 
> Can you also please delete the old shell script?

No, we can't.
As I said in the commit message, my script currently supports
only one of three test variants in fs-test.sh, "nonfs."
"sb" and "fs" are yet to be implemented (if necessary).

> Does this get automatically executed with 'make tests'?

Yes, of course.

> If not, is it possible to do that easily, if we reduce the size of files, etc?
> 
> >
> > diff --git a/test/py/tests/test_fs/conftest.py b/test/py/tests/test_fs/conftest.py
> > new file mode 100644
> > index 000000000000..9155ccf84266
> > --- /dev/null
> > +++ b/test/py/tests/test_fs/conftest.py
> > @@ -0,0 +1,216 @@
> > +# SPDX-License-Identifier:      GPL-2.0+
> > +# Copyright (c) 2018, Linaro Limited
> > +# Author: Takahiro Akashi <takahiro.akashi@linaro.org>
> > +
> > +import os
> > +import os.path
> > +import pytest
> > +import re
> > +from subprocess import call, check_call, check_output, CalledProcessError
> > +from fstest_defs import *
> > +
> > +supported_fs_basic = ['fat16', 'fat32', 'ext4']
> > +
> > +#
> > +# Filesystem test specific setup
> > +#
> > +def pytest_addoption(parser):
> 
> Please can you add full function comments to each function? You can
> see other tests or binman for the format to use.
> [...]

OK.

-Takahiro Akashi


> Regards,
> Simon
diff mbox series

Patch

diff --git a/test/py/tests/test_fs/conftest.py b/test/py/tests/test_fs/conftest.py
new file mode 100644
index 000000000000..9155ccf84266
--- /dev/null
+++ b/test/py/tests/test_fs/conftest.py
@@ -0,0 +1,216 @@ 
+# SPDX-License-Identifier:      GPL-2.0+
+# Copyright (c) 2018, Linaro Limited
+# Author: Takahiro Akashi <takahiro.akashi@linaro.org>
+
+import os
+import os.path
+import pytest
+import re
+from subprocess import call, check_call, check_output, CalledProcessError
+from fstest_defs import *
+
+supported_fs_basic = ['fat16', 'fat32', 'ext4']
+
+#
+# Filesystem test specific setup
+#
+def pytest_addoption(parser):
+    parser.addoption('--fs-type', action='append', default=None,
+        help='Targeting Filesystem Types')
+
+def pytest_configure(config):
+    global supported_fs_basic
+
+    def intersect(listA, listB):
+        return  [x for x in listA if x in listB]
+
+    supported_fs = config.getoption('fs_type')
+    if supported_fs:
+        print("*** FS TYPE modified: %s" % supported_fs)
+        supported_fs_basic =  intersect(supported_fs, supported_fs_basic)
+
+def pytest_generate_tests(metafunc):
+    if 'fs_obj_basic' in metafunc.fixturenames:
+        metafunc.parametrize('fs_obj_basic', supported_fs_basic,
+            indirect=True, scope='module')
+
+#
+# Helper functions
+#
+def fstype_to_ubname(fs_type):
+    if re.match('fat', fs_type):
+        return 'fat'
+    else:
+        return fs_type
+
+def check_ubconfig(config, fs_type):
+    if not config.buildconfig.get('config_cmd_%s' % fs_type, None):
+        pytest.skip('.config feature "CMD_%s" not enabled' % fs_type.upper())
+    if not config.buildconfig.get('config_%s_write' % fs_type, None):
+        pytest.skip('.config feature "%s_WRITE" not enabled'
+        % fs_type.upper())
+
+def mk_fs(config, fs_type, size, id):
+    fs_img = '%s.%s.img' % (id, fs_type)
+    fs_img = config.persistent_data_dir + '/' + fs_img
+
+    if fs_type == 'fat16':
+        mkfs_opt = '-F 16'
+    elif fs_type == 'fat32':
+        mkfs_opt = '-F 32'
+    else:
+        mkfs_opt = ''
+
+    if re.match('fat', fs_type):
+        fs_lnxtype = 'vfat'
+    else:
+        fs_lnxtype = fs_type
+
+    count = (size + 1048576 - 1) / 1048576
+
+    try:
+        check_call('rm -f %s' % fs_img, shell=True)
+        check_call('dd if=/dev/zero of=%s bs=1M count=%d'
+            % (fs_img, count), shell=True)
+        check_call('mkfs.%s %s %s'
+            % (fs_lnxtype, mkfs_opt, fs_img), shell=True)
+        return fs_img
+    except CalledProcessError:
+        call('rm -f %s' % fs_img, shell=True)
+        raise
+
+# from test/py/conftest.py
+def tool_is_in_path(tool):
+    for path in os.environ["PATH"].split(os.pathsep):
+        fn = os.path.join(path, tool)
+        if os.path.isfile(fn) and os.access(fn, os.X_OK):
+            return True
+    return False
+
+fuse_mounted = False
+
+def mount_fs(config, fs_type, device, mount_point):
+    fuse_mounted = False
+
+    try:
+        if fs_type == 'ext4' and tool_is_in_path('fuse2fs'):
+            check_call('fuse2fs %s %s' % (device, mount_point), shell=True)
+            fuse_mounted = True
+        else:
+            mount_opt = "loop,rw"
+            if re.match('fat', fs_type):
+                mount_opt += ",umask=0000"
+
+            check_call('sudo mount -o %s %s %s'
+                % (mount_opt, device, mount_point), shell=True)
+
+        # may not be effective for some file systems
+        check_call('sudo chmod a+rw %s' % mount_point, shell=True)
+    except CalledProcessError:
+        raise
+
+def umount_fs(config, fs_type, mount_point):
+    if fuse_mounted:
+        call('fusermount -u %s' % mount_point, shell=True)
+    else:
+        call('sudo umount %s' % mount_point, shell=True)
+
+
+#
+# Fixture for basic fs test
+#     derived from test/fs/fs-test.sh
+#
+# NOTE: yield_fixture was deprecated since pytest-3.0
+@pytest.yield_fixture()
+def fs_obj_basic(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'
+
+    small_file = mount_dir + '/' + SMALL_FILE
+    big_file = mount_dir + '/' + BIG_FILE
+
+    try:
+
+        # 3GiB volume
+        fs_img = mk_fs(u_boot_config, fs_type, 0xc0000000, '3GB')
+
+        # Mount the image so we can populate it.
+        check_call('mkdir -p %s' % mount_dir, shell=True)
+        mount_fs(u_boot_config, fs_type, fs_img, mount_dir)
+
+        # Create a subdirectory.
+        check_call('mkdir %s/SUBDIR' % mount_dir, shell=True)
+
+        # Create big file in this image.
+        # Note that we work only on the start 1MB, couple MBs in the 2GB range
+        # and the last 1 MB of the huge 2.5GB file.
+        # So, just put random values only in those areas.
+        check_call('dd if=/dev/urandom of=%s bs=1M count=1'
+	    % big_file, shell=True)
+        check_call('dd if=/dev/urandom of=%s bs=1M count=2 seek=2047'
+            % big_file, shell=True)
+        check_call('dd if=/dev/urandom of=%s bs=1M count=1 seek=2499'
+            % big_file, 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)
+
+        # Delete the small file copies which possibly are written as part of a
+        # previous test.
+        # check_call('rm -f "%s.w"' % MB1, shell=True)
+        # check_call('rm -f "%s.w2"' % MB1, 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] ]
+
+        # Generate the md5sums of reads that we will test against big file
+        # One from beginning of file.
+        out = check_output(
+            'dd if=%s bs=1M skip=0 count=1 2> /dev/null | md5sum'
+	    % big_file, shell=True)
+        md5val.append(out.split()[0])
+
+        # One from end of file.
+        out = check_output(
+            'dd if=%s bs=1M skip=2499 count=1 2> /dev/null | md5sum'
+	    % big_file, shell=True)
+        md5val.append(out.split()[0])
+
+        # One from the last 1MB chunk of 2GB
+        out = check_output(
+            'dd if=%s bs=1M skip=2047 count=1 2> /dev/null | md5sum'
+	    % big_file, shell=True)
+        md5val.append(out.split()[0])
+
+        # One from the start 1MB chunk from 2GB
+        out = check_output(
+            'dd if=%s bs=1M skip=2048 count=1 2> /dev/null | md5sum'
+	    % big_file, shell=True)
+        md5val.append(out.split()[0])
+
+        # One 1MB chunk crossing the 2GB boundary
+        out = check_output(
+            'dd if=%s bs=512K skip=4095 count=2 2> /dev/null | md5sum'
+	    % big_file, shell=True)
+        md5val.append(out.split()[0])
+
+        umount_fs(u_boot_config, 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(u_boot_config, fs_type, mount_dir)
+        call('rmdir %s' % mount_dir, shell=True)
+#        if fs_img:
+#            call('rm -f %s' % fs_img, shell=True)
diff --git a/test/py/tests/test_fs/fstest_defs.py b/test/py/tests/test_fs/fstest_defs.py
new file mode 100644
index 000000000000..f26dd06cacf2
--- /dev/null
+++ b/test/py/tests/test_fs/fstest_defs.py
@@ -0,0 +1,10 @@ 
+# SPDX-License-Identifier:      GPL-2.0+
+
+# $SMALL_FILE is the name of the 1MB file in the file system image
+SMALL_FILE='1MB.file'
+
+# $BIG_FILE is the name of the 2.5GB file in the file system image
+BIG_FILE='2.5GB.file'
+
+ADDR=0x01000008
+LENGTH=0x00100000
diff --git a/test/py/tests/test_fs/test_basic.py b/test/py/tests/test_fs/test_basic.py
new file mode 100644
index 000000000000..c067cc9ba3f6
--- /dev/null
+++ b/test/py/tests/test_fs/test_basic.py
@@ -0,0 +1,287 @@ 
+# SPDX-License-Identifier:      GPL-2.0+
+# Copyright (c) 2018, Linaro Limited
+# Author: Takahiro Akashi <takahiro.akashi@linaro.org>
+#
+# U-Boot File System:Basic Test
+
+"""
+This test verifies basic read/write operation on file system.
+"""
+
+import pytest
+import re
+from fstest_defs import *
+
+@pytest.mark.boardspec('sandbox')
+class TestFsBasic(object):
+    def test_fs1(self, u_boot_console, fs_obj_basic):
+        """
+        Test Case 1 - ls command, listing a root directory and invalid directory
+        """
+        fs_type,fs_img,md5val = fs_obj_basic
+        with u_boot_console.log.section('Test Case 1a - ls'):
+            # Test Case 1 - ls
+            output = u_boot_console.run_command_list([
+                'host bind 0 %s' % fs_img,
+                '%sls host 0:0' % fs_type])
+            assert(re.search('2621440000 *%s' % BIG_FILE, ''.join(output)))
+            assert(re.search('1048576 *%s' % SMALL_FILE, ''.join(output)))
+
+        with u_boot_console.log.section('Test Case 1b - ls (invalid dir)'):
+            # In addition, test with a nonexistent directory to see if we crash.
+            output = u_boot_console.run_command(
+                '%sls host 0:0 invalid_d' % fs_type)
+            if fs_type == 'ext4':
+                assert('Can not find directory' in output)
+            else:
+                assert('' == output)
+
+    def test_fs2(self, u_boot_console, fs_obj_basic):
+        """
+        Test Case 2 - size command for a small file
+        """
+        fs_type,fs_img,md5val = fs_obj_basic
+        with u_boot_console.log.section('Test Case 2a - size (small)'):
+            # 1MB is 0x0010 0000
+            # Test Case 2a - size of small file
+            output = u_boot_console.run_command_list([
+                'host bind 0 %s' % fs_img,
+                '%ssize host 0:0 /%s' % (fs_type, SMALL_FILE),
+                'printenv filesize',
+                'setenv filesize'])
+            assert('filesize=100000' in ''.join(output))
+
+        with u_boot_console.log.section('Test Case 2b - size (/../<file>)'):
+            # Test Case 2b - size of small file via a path using '..'
+            output = u_boot_console.run_command_list([
+                '%ssize host 0:0 /SUBDIR/../%s' % (fs_type, SMALL_FILE),
+                'printenv filesize',
+                'setenv filesize'])
+            assert('filesize=100000' in ''.join(output))
+
+    def test_fs3(self, u_boot_console, fs_obj_basic):
+        """
+        Test Case 3 - size command for a large file
+        """
+        fs_type,fs_img,md5val = fs_obj_basic
+        with u_boot_console.log.section('Test Case 3 - size (large)'):
+            # 2.5GB (1024*1024*2500) is 0x9C40 0000
+            # Test Case 3 - size of big file
+            output = u_boot_console.run_command_list([
+                'host bind 0 %s' % fs_img,
+                '%ssize host 0:0 /%s' % (fs_type, BIG_FILE),
+                'printenv filesize',
+                'setenv filesize'])
+            assert('filesize=9c400000' in ''.join(output))
+
+    def test_fs4(self, u_boot_console, fs_obj_basic):
+        """
+        Test Case 4 - load a small file, 1MB
+        """
+        fs_type,fs_img,md5val = fs_obj_basic
+        with u_boot_console.log.section('Test Case 4 - load (small)'):
+            # Test Case 4a - Read full 1MB of small file
+            output = u_boot_console.run_command_list([
+                'host bind 0 %s' % fs_img,
+                '%sload host 0:0 %x /%s' % (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))
+
+    def test_fs5(self, u_boot_console, fs_obj_basic):
+        """
+        Test Case 5 - load, reading first 1MB of 3GB file
+        """
+        fs_type,fs_img,md5val = fs_obj_basic
+        with u_boot_console.log.section('Test Case 5 - load (first 1MB)'):
+            # Test Case 5a - First 1MB of big file
+            output = u_boot_console.run_command_list([
+                'host bind 0 %s' % fs_img,
+                '%sload host 0:0 %x /%s %x 0x0' % (fs_type, ADDR, BIG_FILE, LENGTH),
+                'printenv filesize'])
+            assert('filesize=100000' in ''.join(output))
+
+            # Test Case 5b - First 1MB of big file
+            output = u_boot_console.run_command_list([
+                'md5sum %x $filesize' % ADDR,
+                'setenv filesize'])
+            assert(md5val[1] in ''.join(output))
+
+    def test_fs6(self, u_boot_console, fs_obj_basic):
+        """
+        Test Case 6 - load, reading last 1MB of 3GB file
+        """
+        fs_type,fs_img,md5val = fs_obj_basic
+        with u_boot_console.log.section('Test Case 6 - load (last 1MB)'):
+            # fails for ext as no offset support
+            # Test Case 6a - Last 1MB of big file
+            output = u_boot_console.run_command_list([
+                'host bind 0 %s' % fs_img,
+                '%sload host 0:0 %x /%s %x 0x9c300000'
+                    % (fs_type, ADDR, BIG_FILE, LENGTH),
+                'printenv filesize'])
+            assert('filesize=100000' in ''.join(output))
+
+            # Test Case 6b - Last 1MB of big file
+            output = u_boot_console.run_command_list([
+                'md5sum %x $filesize' % ADDR,
+                'setenv filesize'])
+            assert(md5val[2] in ''.join(output))
+
+    def test_fs7(self, u_boot_console, fs_obj_basic):
+        """
+        Test Case 7 - load, 1MB from the last 1MB in 2GB
+        """
+        fs_type,fs_img,md5val = fs_obj_basic
+        with u_boot_console.log.section('Test Case 7 - load (last 1MB in 2GB)'):
+            # fails for ext as no offset support
+            # Test Case 7a - One from the last 1MB chunk of 2GB
+            output = u_boot_console.run_command_list([
+                'host bind 0 %s' % fs_img,
+                '%sload host 0:0 %x /%s %x 0x7ff00000'
+                    % (fs_type, ADDR, BIG_FILE, LENGTH),
+                'printenv filesize'])
+            assert('filesize=100000' in ''.join(output))
+
+            # Test Case 7b - One from the last 1MB chunk of 2GB
+            output = u_boot_console.run_command_list([
+                'md5sum %x $filesize' % ADDR,
+                'setenv filesize'])
+            assert(md5val[3] in ''.join(output))
+
+    def test_fs8(self, u_boot_console, fs_obj_basic):
+        """
+        Test Case 8 - load, reading first 1MB in 2GB
+        """
+        fs_type,fs_img,md5val = fs_obj_basic
+        with u_boot_console.log.section('Test Case 8 - load (first 1MB in 2GB)'):
+            # fails for ext as no offset support
+            # Test Case 8a - One from the start 1MB chunk from 2GB
+            output = u_boot_console.run_command_list([
+                'host bind 0 %s' % fs_img,
+                '%sload host 0:0 %x /%s %x 0x80000000'
+                    % (fs_type, ADDR, BIG_FILE, LENGTH),
+                'printenv filesize'])
+            assert('filesize=100000' in ''.join(output))
+
+            # Test Case 8b - One from the start 1MB chunk from 2GB
+            output = u_boot_console.run_command_list([
+                'md5sum %x $filesize' % ADDR,
+                'setenv filesize'])
+            assert(md5val[4] in ''.join(output))
+
+    def test_fs9(self, u_boot_console, fs_obj_basic):
+        """
+        Test Case 9 - load, 1MB crossing 2GB boundary
+        """
+        fs_type,fs_img,md5val = fs_obj_basic
+        with u_boot_console.log.section('Test Case 9 - load (crossing 2GB boundary)'):
+            # fails for ext as no offset support
+            # Test Case 9a - One 1MB chunk crossing the 2GB boundary
+            output = u_boot_console.run_command_list([
+                'host bind 0 %s' % fs_img,
+                '%sload host 0:0 %x /%s %x 0x7ff80000'
+                    % (fs_type, ADDR, BIG_FILE, LENGTH),
+                'printenv filesize'])
+            assert('filesize=100000' in ''.join(output))
+
+            # Test Case 9b - One 1MB chunk crossing the 2GB boundary
+            output = u_boot_console.run_command_list([
+                'md5sum %x $filesize' % ADDR,
+                'setenv filesize'])
+            assert(md5val[5] in ''.join(output))
+
+    def test_fs10(self, u_boot_console, fs_obj_basic):
+        """
+        Test Case 10 - load, reading beyond file end'):
+        """
+        fs_type,fs_img,md5val = fs_obj_basic
+        with u_boot_console.log.section('Test Case 10 - load (beyond file end)'):
+            # Generic failure case
+            # Test Case 10 - 2MB chunk from the last 1MB of big file
+            output = u_boot_console.run_command_list([
+                'host bind 0 %s' % fs_img,
+                '%sload host 0:0 %x /%s 0x00200000 0x9c300000'
+                    % (fs_type, ADDR, BIG_FILE),
+                'printenv filesize',
+                'md5sum %x $filesize' % ADDR,
+                'setenv filesize'])
+        assert('filesize=100000' in ''.join(output))
+
+    def test_fs11(self, u_boot_console, fs_obj_basic):
+        """
+        Test Case 11 - write'
+        """
+        fs_type,fs_img,md5val = fs_obj_basic
+        with u_boot_console.log.section('Test Case 11 - write'):
+            # Read 1MB from small file
+            # Write it back to test the writes
+            # Test Case 11a - Check that the write succeeded
+            output = u_boot_console.run_command_list([
+                'host bind 0 %s' % fs_img,
+                '%sload host 0:0 %x /%s' % (fs_type, ADDR, SMALL_FILE),
+                '%swrite host 0:0 %x /%s.w $filesize'
+                    % (fs_type, ADDR, SMALL_FILE)])
+            assert('1048576 bytes written' in ''.join(output))
+
+            # Test Case 11b - Check md5 of written to is same
+            # as the one read from
+            output = u_boot_console.run_command_list([
+                '%sload host 0:0 %x /%s.w' % (fs_type, ADDR, SMALL_FILE),
+                'md5sum %x $filesize' % ADDR,
+                'setenv filesize'])
+            assert(md5val[0] in ''.join(output))
+
+    def test_fs12(self, u_boot_console, fs_obj_basic):
+        """
+        Test Case 12 - write to "." directory
+        """
+        fs_type,fs_img,md5val = fs_obj_basic
+        with u_boot_console.log.section('Test Case 12 - write (".")'):
+            # Next test case checks writing a file whose dirent
+            # is the first in the block, which is always true for "."
+            # The write should fail, but the lookup should work
+            # Test Case 12 - Check directory traversal
+            output = u_boot_console.run_command_list([
+                'host bind 0 %s' % fs_img,
+                '%swrite host 0:0 %x /. 0x10' % (fs_type, ADDR)])
+            assert('Unable to write' in ''.join(output))
+
+    def test_fs13(self, u_boot_console, fs_obj_basic):
+        """
+        Test Case 13 - write to a file with "/./<filename>"
+        """
+        fs_type,fs_img,md5val = fs_obj_basic
+        with u_boot_console.log.section('Test Case 13 - write  ("./<file>")'):
+            # Read 1MB from small file
+            # Write it via "same directory", i.e. "." dirent
+            # Test Case 13a - Check directory traversal
+            output = u_boot_console.run_command_list([
+                'host bind 0 %s' % fs_img,
+                '%sload host 0:0 %x /%s' % (fs_type, ADDR, SMALL_FILE),
+                '%swrite host 0:0 %x /./%s2 $filesize'
+                    % (fs_type, ADDR, SMALL_FILE)])
+            assert('1048576 bytes written' in ''.join(output))
+
+            # Test Case 13b - Check md5 of written to is same
+            # as the one read from
+            output = u_boot_console.run_command_list([
+                'mw.b %x 00 100' % ADDR,
+                '%sload host 0:0 %x /./%s2' % (fs_type, ADDR, SMALL_FILE),
+                'md5sum %x $filesize' % ADDR,
+                'setenv filesize'])
+            assert(md5val[0] in ''.join(output))
+
+            # Test Case 13c - Check md5 of written to is same
+            # as the one read from
+            output = u_boot_console.run_command_list([
+                'mw.b %x 00 100' % ADDR,
+                '%sload host 0:0 %x /%s2' % (fs_type, ADDR, SMALL_FILE),
+                'md5sum %x $filesize' % ADDR,
+                'setenv filesize'])
+            assert(md5val[0] in ''.join(output))