Skip to content

Commit 8d6b1ed

Browse files
committed
STORAGE: added test case to write/check n x 25kB files storing ~250kB data.
1 parent e3682be commit 8d6b1ed

File tree

4 files changed

+221
-417
lines changed

4 files changed

+221
-417
lines changed

features/TESTS/filesystem/fopen/fopen.cpp

Lines changed: 173 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ static char fsfat_fopen_utest_msg_g[FSFAT_UTEST_MSG_BUF_SIZE];
7171
#define FSFAT_FOPEN_TEST_MOUNT_PT_NAME "sd"
7272
#define FSFAT_FOPEN_TEST_MOUNT_PT_PATH "/"FSFAT_FOPEN_TEST_MOUNT_PT_NAME
7373
#define FSFAT_FOPEN_TEST_WORK_BUF_SIZE_1 64
74+
#define FSFAT_FOPEN_TEST_FILEPATH_MAX_DEPTH 20
7475
static const char *sd_badfile_path = "/sd/badfile.txt";
7576
static const char *sd_testfile_path = "/sd/test.txt";
7677

@@ -297,7 +298,7 @@ static int32_t fsfat_filepath_make_dirs(char* filepath, bool do_asserts)
297298
char *fpathbuf = NULL;
298299
char *buf = NULL;
299300
int pos = 0;
300-
char *parts[10];
301+
char *parts[FSFAT_FOPEN_TEST_FILEPATH_MAX_DEPTH];
301302

302303
FSFAT_DBGLOG("%s:entered\n", __func__);
303304
/* find the dirs to create*/
@@ -310,7 +311,7 @@ static int32_t fsfat_filepath_make_dirs(char* filepath, bool do_asserts)
310311
}
311312
memset(fpathbuf, 0, len+1);
312313
memcpy(fpathbuf, filepath, len);
313-
num_parts = fsfat_filepath_split(fpathbuf, parts, 10);
314+
num_parts = fsfat_filepath_split(fpathbuf, parts, FSFAT_FOPEN_TEST_FILEPATH_MAX_DEPTH);
314315
FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, "%s:Error: failed to split filepath (filename=\"%s\", num_parts=%d)\n", __func__, filepath, (int) num_parts);
315316
TEST_ASSERT_MESSAGE(num_parts > 0, fsfat_fopen_utest_msg_g);
316317

@@ -1332,6 +1333,175 @@ control_t fsfat_fopen_test_15(const size_t call_count)
13321333
}
13331334

13341335

1336+
/* @brief test utility function to create a file of a given size.
1337+
*
1338+
* A reference data table is used of so that the data file can be later be
1339+
* checked with fsfat_test_check_data_file().
1340+
*
1341+
* @param filename name of the file including path
1342+
* @param data data to store in file
1343+
* @param len number of bytes of data present in the data buffer.
1344+
*/
1345+
int32_t fsfat_test_create_data_file(const char* filename, size_t len)
1346+
{
1347+
int32_t ret = -1;
1348+
FILE *fp = NULL;
1349+
size_t write_len = 0;
1350+
size_t written_len = 0;
1351+
int32_t exp = 0;
1352+
const int32_t exp_max = 8; /* so as not to exceed FSFAT_TEST_BYTE_DATA_TABLE_SIZE/2 */
1353+
1354+
FSFAT_FENTRYLOG("%s:entered (filename=%s, len=%d).\n", __func__, filename, (int) len);
1355+
TEST_ASSERT(len % FSFAT_TEST_BYTE_DATA_TABLE_SIZE == 0);
1356+
fp = fopen(filename, "a");
1357+
if(fp == NULL){
1358+
return ret;
1359+
}
1360+
1361+
while(written_len < len) {
1362+
/* write fsfat_test_byte_data_table or part thereof, in 9 writes of sizes
1363+
* 1, 2, 4, 8, 16, 32, 64, 128, 1, totalling 256 bytes len permitting. */
1364+
for(exp = 0; (exp <= exp_max) && (written_len < len); exp++){
1365+
write_len = 0x1 << (exp % exp_max);
1366+
write_len = len - written_len > write_len ? write_len : len - written_len;
1367+
ret = fwrite((const void*) &fsfat_test_byte_data_table[written_len % FSFAT_TEST_BYTE_DATA_TABLE_SIZE], write_len, 1, fp);
1368+
written_len += write_len;
1369+
if(ret != 1){
1370+
FSFAT_DBGLOG("%s:Error: fwrite() failed (ret=%d)\n", __func__, (int) ret);
1371+
ret = -1;
1372+
goto out0;
1373+
}
1374+
}
1375+
}
1376+
if(written_len == len) {
1377+
ret = 0;
1378+
} else {
1379+
ret = -1;
1380+
}
1381+
out0:
1382+
fclose(fp);
1383+
return ret;
1384+
}
1385+
1386+
1387+
/* @brief test utility function to check the data in the specified file is correct.
1388+
*
1389+
* The data read from the file is check that it agrees with the data written by
1390+
* fsfat_test_create_data_file().
1391+
*
1392+
* @param filename name of the file including path
1393+
* @param data data to store in file
1394+
* @param len number of bytes of data present in the data buffer.
1395+
*/
1396+
int32_t fsfat_test_check_data_file(const char* filename, size_t len)
1397+
{
1398+
int32_t ret = -1;
1399+
FILE *fp = NULL;
1400+
size_t read_len = 0;
1401+
uint8_t buf[FSFAT_TEST_BYTE_DATA_TABLE_SIZE];
1402+
1403+
FSFAT_FENTRYLOG("%s:entered (filename=%s, len=%d).\n", __func__, filename, (int) len);
1404+
TEST_ASSERT(len % FSFAT_TEST_BYTE_DATA_TABLE_SIZE == 0);
1405+
fp = fopen(filename, "r");
1406+
if(fp == NULL){
1407+
return ret;
1408+
}
1409+
1410+
while(read_len < len) {
1411+
ret = fread((void*) buf, FSFAT_TEST_BYTE_DATA_TABLE_SIZE, 1, fp);
1412+
read_len += FSFAT_TEST_BYTE_DATA_TABLE_SIZE;
1413+
if(ret == 0){
1414+
/* end of read*/
1415+
FSFAT_DBGLOG("%s:unable to read data\n", __func__);
1416+
break;
1417+
}
1418+
if(memcmp(buf, fsfat_test_byte_data_table, FSFAT_TEST_BYTE_DATA_TABLE_SIZE) != 0) {
1419+
FSFAT_DBGLOG("%s:Error: read data not as expected (0x%2x, 0x%2x, 0x%2x, 0x%2x, 0x%2x, 0x%2x, 0x%2x, 0x%2x, 0x%2x, 0x%2x, 0x%2x, 0x%2x, 0x%2x, 0x%2x, 0x%2x, 0x%2x\n", __func__,
1420+
buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7], buf[8], buf[9], buf[10], buf[11], buf[12], buf[13], buf[14], buf[15]);
1421+
ret = -1;
1422+
goto out0;
1423+
}
1424+
}
1425+
if(read_len == len) {
1426+
ret = 0;
1427+
}
1428+
out0:
1429+
fclose(fp);
1430+
return ret;
1431+
}
1432+
1433+
/* file data for test_16 */
1434+
static fsfat_kv_data_t fsfat_fopen_test_16_kv_data[] = {
1435+
{ "/sd/tst16_0/testfil0.txt", "dummy_data"},
1436+
{ "/sd/tst16_1/subdir0/testfil0.txt", "dummy_data"},
1437+
{ "/sd/tst16_2/subdir0/subdir1/testfil0.txt", "dummy_data"},
1438+
{ "/sd/tst16_3/subdir0/subdir1/subdir2/subdir3/testfil0.txt", "dummy_data"},
1439+
{ "/sd/tst16_4/subdir0/subdir1/subdir2/subdir3/subdir4/testfil0.txt", "dummy_data"},
1440+
{ "/sd/tst16_5/subdir0/subdir1/subdir2/subdir3/subdir4/subdir5/testfil0.txt", "dummy_data"},
1441+
{ "/sd/tst16_6/subdir0/subdir1/subdir2/subdir3/subdir4/subdir5/subdir6/testfil0.txt", "dummy_data"},
1442+
{ "/sd/tst16_7/subdir0/subdir1/subdir2/subdir3/subdir4/subdir5/subdir6/subdir7/testfil0.txt", "dummy_data"},
1443+
{ "/sd/tst16_8/subdir0/subdir1/subdir2/subdir3/subdir4/subdir5/subdir6/subdir7/subdir8/testfil0.txt", "dummy_data"},
1444+
{ "/sd/tst16_9/subdir0/subdir1/subdir2/subdir3/subdir4/subdir5/subdir6/subdir7/subdir8/subdir9/testfil0.txt", "dummy_data"},
1445+
{ NULL, NULL},
1446+
};
1447+
1448+
1449+
/** @brief stress test to write data to fs
1450+
*
1451+
* @return on success returns CaseNext to continue to next test case, otherwise will assert on errors.
1452+
*/
1453+
control_t fsfat_fopen_test_16(const size_t call_count)
1454+
{
1455+
int32_t ret = 0;
1456+
fsfat_kv_data_t *node = fsfat_fopen_test_16_kv_data;
1457+
const int32_t num_blocks = 100; /* each file ~25kB */
1458+
1459+
FSFAT_DBGLOG("%s:entered\n", __func__);
1460+
(void) call_count;
1461+
1462+
/* remove file and directory from a previous failed test run, if present */
1463+
while(node->filename != NULL) {
1464+
fsfat_filepath_remove_all((char*) node->filename);
1465+
node++;
1466+
}
1467+
1468+
/* create dirs */
1469+
node = fsfat_fopen_test_16_kv_data;
1470+
while(node->filename != NULL) {
1471+
ret = fsfat_filepath_make_dirs((char*) node->filename, true);
1472+
FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, "%s:Error: failed to create dirs for filename (filename=\"%s\")(ret=%d)\n", __func__, node->filename, (int) ret);
1473+
TEST_ASSERT_MESSAGE(ret == 0, fsfat_fopen_utest_msg_g);
1474+
node++;
1475+
}
1476+
1477+
/* create the data files */
1478+
node = fsfat_fopen_test_16_kv_data;
1479+
while(node->filename != NULL) {
1480+
ret = fsfat_test_create_data_file(node->filename, num_blocks * FSFAT_TEST_BYTE_DATA_TABLE_SIZE);
1481+
FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, "%s:Error: failed to create data file (filename=\"%s\")(ret=%d)\n", __func__, node->filename, (int) ret);
1482+
TEST_ASSERT_MESSAGE(ret == 0, fsfat_fopen_utest_msg_g);
1483+
node++;
1484+
}
1485+
1486+
/* read the data back and check its as expected */
1487+
node = fsfat_fopen_test_16_kv_data;
1488+
while(node->filename != NULL) {
1489+
ret = fsfat_test_check_data_file(node->filename, num_blocks * FSFAT_TEST_BYTE_DATA_TABLE_SIZE);
1490+
FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, "%s:Error: failed to check data file (filename=\"%s\")(ret=%d)\n", __func__, node->filename, (int) ret);
1491+
TEST_ASSERT_MESSAGE(ret == 0, fsfat_fopen_utest_msg_g);
1492+
node++;
1493+
}
1494+
1495+
/* clean up */
1496+
node = fsfat_fopen_test_16_kv_data;
1497+
while(node->filename != NULL) {
1498+
fsfat_filepath_remove_all((char*) node->filename);
1499+
node++;
1500+
}
1501+
return CaseNext;
1502+
}
1503+
1504+
13351505
#else
13361506

13371507

@@ -1406,7 +1576,7 @@ Case cases[] = {
14061576
Case("FSFAT_FOPEN_TEST_13: mkdir() test.", FSFAT_FOPEN_TEST_13),
14071577
Case("FSFAT_FOPEN_TEST_14: stat() test.", FSFAT_FOPEN_TEST_14),
14081578
Case("FSFAT_FOPEN_TEST_15: format() test.", FSFAT_FOPEN_TEST_15),
1409-
1579+
Case("FSFAT_FOPEN_TEST_16: write/check n x 25kB data files.", FSFAT_FOPEN_TEST_16),
14101580
};
14111581

14121582

features/filesystem/README.md

Lines changed: 46 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ This section describes how to build and run the POSIX file API test case. The fo
3333
- [Installing the Tools](#installing-the-tools). This section briefly describes how to setup the mbedos development environment.
3434
- [Git Clone the Public mbedOS Repo](#git-clone-the-mbedos-repo). This section describes how to git clone the mbedOS repository containing the FAT32/SDCard and POSIX File API test case of interest.
3535
- [Build the mbedOS Test Cases](#build-the-mbedos-test-cases). This section describes how to build the mbedOS test cases.
36+
- [Insert a microSD Card Into the K64F](#insert-sdcard-into-k64f).This section describes how to format (if required) a microSD card prior to running the tests.
3637
- [Run the POSIX File Test Case](#run-the-posix-file-test-cases).This section describes how to run the POSIX file test case basic.cpp.
3738

3839
### <a name="installing-the-tools"></a> Installing the Tools
@@ -53,7 +54,6 @@ Using a Git Bash terminal, setup mbed-cli in the following way:
5354
simhug01@E107851:/d/demo_area/mbed-cli/$ python.exe setup.py install
5455
simhug01@E107851:/d/demo_area/mbed-cli/$ popd
5556

56-
5757
Using a Git Bash terminal, setup Greentea in the following way:
5858

5959
simhug01@E107851:/d/demo_area$ git clone [email protected]:/armmbed/greentea
@@ -101,6 +101,24 @@ Build the test cases for the K64F target using the following commands:
101101
The complete [build log][BUILD-TESTS-GCC-20161219-1007] is available for reference.
102102

103103

104+
### <a name="insert-sdcard-into-k64f"></a> Insert SDCard into K64F
105+
106+
The test cases have been run on a K64F with the following microSDHC cards:
107+
108+
- Kingston 2GB mircoSDHC card.
109+
- Kingston 8GB mircoSDHC card.
110+
- SanDisk 16GB mircoSDHC ultra card.
111+
112+
If the card requires formatting then the following procedure is known to work:
113+
114+
- Insert microSD card into SD adapter in USB stick (or similar) so the microSD card can be insert into windows PC.
115+
- Within file explorer, right click/Format on the USB drive.
116+
- Select FAT32, 4096 cluster size, Quick Format.
117+
- Format the drive.
118+
119+
The microSD card should then be ready for use in the K64F.
120+
121+
104122
### <a name="run-the-posix-file-test-cases"></a> Run the POSIX File Test Case
105123

106124
To setup for running the test cases, complete the following steps:
@@ -174,11 +192,11 @@ The full [test output log][RUN-TESTS-GCC-20161219-1011] is available for referen
174192

175193
mbedOS supports a subset of the POSIX File API, as outlined below:
176194

177-
- clearerr()
195+
- [clearerr()][MAN_CLEARERR].
178196
- STATUS: Basic testing implemented. Working.
179197
- [fclose()][MAN_FCLOSE].
180198
- STATUS: Basic testing implemented. Working.
181-
- ferror()
199+
- [ferror()][MAN_CLEARERR].
182200
- STATUS: Basic testing implemented.
183201
- STATUS: GCC_ARM: Working.
184202
- STATUS: ARMCC: ARMCC has problem with ferror(filep) where filep is NULL. Appears to work for non-NULL pointer.
@@ -190,18 +208,20 @@ mbedOS supports a subset of the POSIX File API, as outlined below:
190208
- STATUS: Unknown.
191209
- [fputs()][MAN_FPUTS].
192210
- STATUS: Basic testing implemented. Working.
193-
- fprintf()
211+
- [fprintf()][MAN_FPRINTF].
194212
- STATUS: Basic testing implemented. Working.
195-
- fopen()
213+
- [fopen()][MAN_FOPEN].
196214
- STATUS: Basic testing implemented. Working.
197-
- freopen()
215+
- [freopen()][MAN_FOPEN].
198216
- STATUS: This is not tested.
199-
- [fread()][MAN_FREAD]
217+
- [fread()][MAN_FREAD].
200218
- STATUS: Basic testing implemented. Working.
201-
- ftell()
219+
- STATUS: n x 25kB stress test working.
220+
- [ftell()][MAN_FTELL].
202221
- STATUS: Basic testing implemented. Working.
203-
- [fwrite()][MAN_FWRITE]
222+
- [fwrite()][MAN_FWRITE].
204223
- STATUS: Basic testing implemented. Working.
224+
- STATUS: n x 25kB stress test working.
205225
- [fseek()][MAN_FSEEK]
206226
- STATUS: Basic testing implemented. Working.
207227
- [getc()][MAN_FGETS].
@@ -214,10 +234,11 @@ mbedOS supports a subset of the POSIX File API, as outlined below:
214234
- STATUS: Unknown.
215235
- [remove()][MAN_REMOVE]
216236
- STATUS: Basic testing implemented. Working.
217-
- rewinddir().
218-
- STATUS: Implemented. Not tested.
219-
- stat()
220-
- STATUS: Implemented. Not tested.
237+
- [rewind()][MAN_REWIND].
238+
- STATUS: Basic testing implemented. Working.
239+
- [stat()][MAN_STAT]
240+
- STATUS: Implemented. Working.
241+
- STATUS: Not supported by ARMCC/IAR libc.
221242
- tmpfile()
222243
- STATUS: Not implemented.
223244
- tmpnam()
@@ -226,23 +247,23 @@ mbedOS supports a subset of the POSIX File API, as outlined below:
226247
Supported directory related operations are as follows:
227248

228249
- closedir().
229-
- STATUS: Implemented. Not tested.
250+
- STATUS: Implemented. Working.
230251
- mkdir().
231252
- STATUS: Basic testing implemented. Working.
232253
- opendir().
233-
- STATUS: Implemented. Not tested.
254+
- STATUS: Implemented. Working.
234255
- readdir().
235-
- STATUS: Implemented. Not tested.
256+
- STATUS: Implemented. Working.
236257
- [remove()][MAN_REMOVE]
237258
- STATUS: Basic testing implemented. Working.
238259
- rename()
239260
- STATUS: Implemented. Not tested.
240-
- [rewind()][MAN_REWIND].
241-
- STATUS: Basic testing implemented. Working.
261+
- rewinddir().
262+
- STATUS: Implemented. Found not to work. Test case not present in repo.
242263
- seekdir()
243-
- STATUS: Implemented. Not tested.
264+
- STATUS: Implemented. Found not to work. Test case not present in repo.
244265
- telldir().
245-
- STATUS: Implemented. Not tested.
266+
- STATUS: Implemented. Found not to work. Test case not present in repo.
246267

247268
## errno
248269

@@ -276,11 +297,16 @@ The FAT32/SDCard test cases are at following locations in the source code tree:
276297
[BUILD-TESTS-GCC-20161219-1007]: https://github.com/ARMmbed/meVo/blob/master/docs/ARM_MBED/TN/ARM_MBED_TN_0017/build_tests_gcc_20161219_1007.txt
277298
[RUN-TESTS-GCC-20161219-1011]: https://github.com/ARMmbed/meVo/blob/master/docs/ARM_MBED/TN/ARM_MBED_TN_0017/run_tests_master_gcc_ex_app2_fat_basic_20161219_1011.txt
278299

300+
[MAN_CLEARERR]: https://linux.die.net/man/3/clearerr
279301
[MAN_FCLOSE]: https://linux.die.net/man/3/fclose
280302
[MAN_FGETS]: https://linux.die.net/man/3/fgets
303+
[MAN_FOPEN]: https://linux.die.net/man/3/fopen
304+
[MAN_FPRINTF]: https://linux.die.net/man/3/fprintf
281305
[MAN_FPUTS]: https://linux.die.net/man/3/fputs
282306
[MAN_FREAD]: https://linux.die.net/man/3/fread
283307
[MAN_FSEEK]: https://linux.die.net/man/3/fseek
284308
[MAN_FWRITE]: https://linux.die.net/man/3/fwrite
285309
[MAN_REMOVE]: https://linux.die.net/man/3/remove
286310
[MAN_REWIND]: https://linux.die.net/man/3/rewind
311+
[MAN_STAT]: https://linux.die.net/man/2/stat
312+
[MAN_FTELL]: https://linux.die.net/man/3/ftell

0 commit comments

Comments
 (0)