1# SPDX-License-Identifier:      GPL-2.0+
2# Copyright (c) 2018, Linaro Limited
3# Author: Takahiro Akashi <takahiro.akashi@linaro.org>
4#
5# U-Boot File System:Exntented Test
6
7"""
8This test verifies extended write operation on file system.
9"""
10
11import pytest
12import re
13from fstest_defs import *
14from fstest_helpers import assert_fs_integrity
15
16@pytest.mark.boardspec('sandbox')
17@pytest.mark.slow
18class TestFsExt(object):
19    def test_fs_ext1(self, u_boot_console, fs_obj_ext):
20        """
21        Test Case 1 - write a file with absolute path
22        """
23        fs_type,fs_img,md5val = fs_obj_ext
24        with u_boot_console.log.section('Test Case 1 - write with abs path'):
25            # Test Case 1a - Check if command successfully returned
26            output = u_boot_console.run_command_list([
27                'host bind 0 %s' % fs_img,
28                '%sload host 0:0 %x /%s' % (fs_type, ADDR, MIN_FILE),
29                '%swrite host 0:0 %x /dir1/%s.w1 $filesize'
30                    % (fs_type, ADDR, MIN_FILE)])
31            assert('20480 bytes written' in ''.join(output))
32
33            # Test Case 1b - Check md5 of file content
34            output = u_boot_console.run_command_list([
35                'mw.b %x 00 100' % ADDR,
36                '%sload host 0:0 %x /dir1/%s.w1' % (fs_type, ADDR, MIN_FILE),
37                'md5sum %x $filesize' % ADDR,
38                'setenv filesize'])
39            assert(md5val[0] in ''.join(output))
40            assert_fs_integrity(fs_type, fs_img)
41
42    def test_fs_ext2(self, u_boot_console, fs_obj_ext):
43        """
44        Test Case 2 - write to a file with relative path
45        """
46        fs_type,fs_img,md5val = fs_obj_ext
47        with u_boot_console.log.section('Test Case 2 - write with rel path'):
48            # Test Case 2a - Check if command successfully returned
49            output = u_boot_console.run_command_list([
50                'host bind 0 %s' % fs_img,
51                '%sload host 0:0 %x /%s' % (fs_type, ADDR, MIN_FILE),
52                '%swrite host 0:0 %x dir1/%s.w2 $filesize'
53                    % (fs_type, ADDR, MIN_FILE)])
54            assert('20480 bytes written' in ''.join(output))
55
56            # Test Case 2b - Check md5 of file content
57            output = u_boot_console.run_command_list([
58                'mw.b %x 00 100' % ADDR,
59                '%sload host 0:0 %x dir1/%s.w2' % (fs_type, ADDR, MIN_FILE),
60                'md5sum %x $filesize' % ADDR,
61                'setenv filesize'])
62            assert(md5val[0] in ''.join(output))
63            assert_fs_integrity(fs_type, fs_img)
64
65    def test_fs_ext3(self, u_boot_console, fs_obj_ext):
66        """
67        Test Case 3 - write to a file with invalid path
68        """
69        fs_type,fs_img,md5val = fs_obj_ext
70        with u_boot_console.log.section('Test Case 3 - write with invalid path'):
71            # Test Case 3 - Check if command expectedly failed
72            output = u_boot_console.run_command_list([
73                'host bind 0 %s' % fs_img,
74                '%sload host 0:0 %x /%s' % (fs_type, ADDR, MIN_FILE),
75                '%swrite host 0:0 %x /dir1/none/%s.w3 $filesize'
76                    % (fs_type, ADDR, MIN_FILE)])
77            assert('Unable to write file /dir1/none/' in ''.join(output))
78            assert_fs_integrity(fs_type, fs_img)
79
80    def test_fs_ext4(self, u_boot_console, fs_obj_ext):
81        """
82        Test Case 4 - write at non-zero offset, enlarging file size
83        """
84        fs_type,fs_img,md5val = fs_obj_ext
85        with u_boot_console.log.section('Test Case 4 - write at non-zero offset, enlarging file size'):
86            # Test Case 4a - Check if command successfully returned
87            output = u_boot_console.run_command_list([
88                'host bind 0 %s' % fs_img,
89                '%sload host 0:0 %x /%s' % (fs_type, ADDR, MIN_FILE),
90                '%swrite host 0:0 %x /dir1/%s.w4 $filesize'
91                    % (fs_type, ADDR, MIN_FILE)])
92            output = u_boot_console.run_command(
93                '%swrite host 0:0 %x /dir1/%s.w4 $filesize 0x1400'
94                    % (fs_type, ADDR, MIN_FILE))
95            assert('20480 bytes written' in output)
96
97            # Test Case 4b - Check size of written file
98            output = u_boot_console.run_command_list([
99                '%ssize host 0:0 /dir1/%s.w4' % (fs_type, MIN_FILE),
100                'printenv filesize',
101                'setenv filesize'])
102            assert('filesize=6400' in ''.join(output))
103
104            # Test Case 4c - Check md5 of file content
105            output = u_boot_console.run_command_list([
106                'mw.b %x 00 100' % ADDR,
107                '%sload host 0:0 %x /dir1/%s.w4' % (fs_type, ADDR, MIN_FILE),
108                'md5sum %x $filesize' % ADDR,
109                'setenv filesize'])
110            assert(md5val[1] in ''.join(output))
111            assert_fs_integrity(fs_type, fs_img)
112
113    def test_fs_ext5(self, u_boot_console, fs_obj_ext):
114        """
115        Test Case 5 - write at non-zero offset, shrinking file size
116        """
117        fs_type,fs_img,md5val = fs_obj_ext
118        with u_boot_console.log.section('Test Case 5 - write at non-zero offset, shrinking file size'):
119            # Test Case 5a - Check if command successfully returned
120            output = u_boot_console.run_command_list([
121                'host bind 0 %s' % fs_img,
122                '%sload host 0:0 %x /%s' % (fs_type, ADDR, MIN_FILE),
123                '%swrite host 0:0 %x /dir1/%s.w5 $filesize'
124                    % (fs_type, ADDR, MIN_FILE)])
125            output = u_boot_console.run_command(
126                '%swrite host 0:0 %x /dir1/%s.w5 0x1400 0x1400'
127                    % (fs_type, ADDR, MIN_FILE))
128            assert('5120 bytes written' in output)
129
130            # Test Case 5b - Check size of written file
131            output = u_boot_console.run_command_list([
132                '%ssize host 0:0 /dir1/%s.w5' % (fs_type, MIN_FILE),
133                'printenv filesize',
134                'setenv filesize'])
135            assert('filesize=2800' in ''.join(output))
136
137            # Test Case 5c - Check md5 of file content
138            output = u_boot_console.run_command_list([
139                'mw.b %x 00 100' % ADDR,
140                '%sload host 0:0 %x /dir1/%s.w5' % (fs_type, ADDR, MIN_FILE),
141                'md5sum %x $filesize' % ADDR,
142                'setenv filesize'])
143            assert(md5val[2] in ''.join(output))
144            assert_fs_integrity(fs_type, fs_img)
145
146    def test_fs_ext6(self, u_boot_console, fs_obj_ext):
147        """
148        Test Case 6 - write nothing at the start, truncating to zero
149        """
150        fs_type,fs_img,md5val = fs_obj_ext
151        with u_boot_console.log.section('Test Case 6 - write nothing at the start, truncating to zero'):
152            # Test Case 6a - Check if command successfully returned
153            output = u_boot_console.run_command_list([
154                'host bind 0 %s' % fs_img,
155                '%sload host 0:0 %x /%s' % (fs_type, ADDR, MIN_FILE),
156                '%swrite host 0:0 %x /dir1/%s.w6 $filesize'
157                    % (fs_type, ADDR, MIN_FILE)])
158            output = u_boot_console.run_command(
159                '%swrite host 0:0 %x /dir1/%s.w6 0 0'
160                    % (fs_type, ADDR, MIN_FILE))
161            assert('0 bytes written' in output)
162
163            # Test Case 6b - Check size of written file
164            output = u_boot_console.run_command_list([
165                '%ssize host 0:0 /dir1/%s.w6' % (fs_type, MIN_FILE),
166                'printenv filesize',
167                'setenv filesize'])
168            assert('filesize=0' in ''.join(output))
169            assert_fs_integrity(fs_type, fs_img)
170
171    def test_fs_ext7(self, u_boot_console, fs_obj_ext):
172        """
173        Test Case 7 - write at the end (append)
174        """
175        fs_type,fs_img,md5val = fs_obj_ext
176        with u_boot_console.log.section('Test Case 7 - write at the end (append)'):
177            # Test Case 7a - Check if command successfully returned
178            output = u_boot_console.run_command_list([
179                'host bind 0 %s' % fs_img,
180                '%sload host 0:0 %x /%s' % (fs_type, ADDR, MIN_FILE),
181                '%swrite host 0:0 %x /dir1/%s.w7 $filesize'
182                    % (fs_type, ADDR, MIN_FILE)])
183            output = u_boot_console.run_command(
184                '%swrite host 0:0 %x /dir1/%s.w7 $filesize $filesize'
185                    % (fs_type, ADDR, MIN_FILE))
186            assert('20480 bytes written' in output)
187
188            # Test Case 7b - Check size of written file
189            output = u_boot_console.run_command_list([
190                '%ssize host 0:0 /dir1/%s.w7' % (fs_type, MIN_FILE),
191                'printenv filesize',
192                'setenv filesize'])
193            assert('filesize=a000' in ''.join(output))
194
195            # Test Case 7c - Check md5 of file content
196            output = u_boot_console.run_command_list([
197                'mw.b %x 00 100' % ADDR,
198                '%sload host 0:0 %x /dir1/%s.w7' % (fs_type, ADDR, MIN_FILE),
199                'md5sum %x $filesize' % ADDR,
200                'setenv filesize'])
201            assert(md5val[3] in ''.join(output))
202            assert_fs_integrity(fs_type, fs_img)
203
204    def test_fs_ext8(self, u_boot_console, fs_obj_ext):
205        """
206        Test Case 8 - write at offset beyond the end of file
207        """
208        fs_type,fs_img,md5val = fs_obj_ext
209        with u_boot_console.log.section('Test Case 8 - write beyond the end'):
210            # Test Case 8a - Check if command expectedly failed
211            output = u_boot_console.run_command_list([
212                'host bind 0 %s' % fs_img,
213                '%sload host 0:0 %x /%s' % (fs_type, ADDR, MIN_FILE),
214                '%swrite host 0:0 %x /dir1/%s.w8 $filesize'
215                    % (fs_type, ADDR, MIN_FILE)])
216            output = u_boot_console.run_command(
217                '%swrite host 0:0 %x /dir1/%s.w8 0x1400 %x'
218                    % (fs_type, ADDR, MIN_FILE, 0x100000 + 0x1400))
219            assert('Unable to write file /dir1' in output)
220            assert_fs_integrity(fs_type, fs_img)
221
222    def test_fs_ext9(self, u_boot_console, fs_obj_ext):
223        """
224        Test Case 9 - write to a non-existing file at non-zero offset
225        """
226        fs_type,fs_img,md5val = fs_obj_ext
227        with u_boot_console.log.section('Test Case 9 - write to non-existing file with non-zero offset'):
228            # Test Case 9a - Check if command expectedly failed
229            output = u_boot_console.run_command_list([
230                'host bind 0 %s' % fs_img,
231                '%sload host 0:0 %x /%s' % (fs_type, ADDR, MIN_FILE),
232                '%swrite host 0:0 %x /dir1/%s.w9 0x1400 0x1400'
233                    % (fs_type, ADDR, MIN_FILE)])
234            assert('Unable to write file /dir1' in ''.join(output))
235            assert_fs_integrity(fs_type, fs_img)
236
237    def test_fs_ext10(self, u_boot_console, fs_obj_ext):
238        """
239        'Test Case 10 - create/delete as many directories under root directory
240        as amount of directory entries goes beyond one cluster size)'
241        """
242        fs_type,fs_img,md5val = fs_obj_ext
243        with u_boot_console.log.section('Test Case 10 - create/delete (many)'):
244            # Test Case 10a - Create many files
245            #   Please note that the size of directory entry is 32 bytes.
246            #   So one typical cluster may holds 64 (2048/32) entries.
247            output = u_boot_console.run_command(
248                'host bind 0 %s' % fs_img)
249
250            for i in range(0, 66):
251                output = u_boot_console.run_command(
252                    '%swrite host 0:0 %x /FILE0123456789_%02x 100'
253                    % (fs_type, ADDR, i))
254            output = u_boot_console.run_command('%sls host 0:0 /' % fs_type)
255            assert('FILE0123456789_00' in output)
256            assert('FILE0123456789_41' in output)
257
258            # Test Case 10b - Delete many files
259            for i in range(0, 66):
260                output = u_boot_console.run_command(
261                    '%srm host 0:0 /FILE0123456789_%02x'
262                    % (fs_type, i))
263            output = u_boot_console.run_command('%sls host 0:0 /' % fs_type)
264            assert(not 'FILE0123456789_00' in output)
265            assert(not 'FILE0123456789_41' in output)
266
267            # Test Case 10c - Create many files again
268            # Please note no.64 and 65 are intentionally re-created
269            for i in range(64, 128):
270                output = u_boot_console.run_command(
271                    '%swrite host 0:0 %x /FILE0123456789_%02x 100'
272                    % (fs_type, ADDR, i))
273            output = u_boot_console.run_command('%sls host 0:0 /' % fs_type)
274            assert('FILE0123456789_40' in output)
275            assert('FILE0123456789_79' in output)
276
277            assert_fs_integrity(fs_type, fs_img)
278
279    def test_fs_ext11(self, u_boot_console, fs_obj_ext):
280        """
281        'Test Case 11 - create/delete as many directories under non-root
282        directory as amount of directory entries goes beyond one cluster size)'
283        """
284        fs_type,fs_img,md5val = fs_obj_ext
285        with u_boot_console.log.section('Test Case 11 - create/delete (many)'):
286            # Test Case 11a - Create many files
287            #   Please note that the size of directory entry is 32 bytes.
288            #   So one typical cluster may holds 64 (2048/32) entries.
289            output = u_boot_console.run_command(
290                'host bind 0 %s' % fs_img)
291
292            for i in range(0, 66):
293                output = u_boot_console.run_command(
294                    '%swrite host 0:0 %x /dir1/FILE0123456789_%02x 100'
295                    % (fs_type, ADDR, i))
296            output = u_boot_console.run_command('%sls host 0:0 /dir1' % fs_type)
297            assert('FILE0123456789_00' in output)
298            assert('FILE0123456789_41' in output)
299
300            # Test Case 11b - Delete many files
301            for i in range(0, 66):
302                output = u_boot_console.run_command(
303                    '%srm host 0:0 /dir1/FILE0123456789_%02x'
304                    % (fs_type, i))
305            output = u_boot_console.run_command('%sls host 0:0 /dir1' % fs_type)
306            assert(not 'FILE0123456789_00' in output)
307            assert(not 'FILE0123456789_41' in output)
308
309            # Test Case 11c - Create many files again
310            # Please note no.64 and 65 are intentionally re-created
311            for i in range(64, 128):
312                output = u_boot_console.run_command(
313                    '%swrite host 0:0 %x /dir1/FILE0123456789_%02x 100'
314                    % (fs_type, ADDR, i))
315            output = u_boot_console.run_command('%sls host 0:0 /dir1' % fs_type)
316            assert('FILE0123456789_40' in output)
317            assert('FILE0123456789_79' in output)
318
319            assert_fs_integrity(fs_type, fs_img)
320