SDHI_driver patch (mbedOS 5.11.5)
Embed:
(wiki syntax)
Show/hide line numbers
fopen.cpp
Go to the documentation of this file.
00001 /* 00002 * mbed Microcontroller Library 00003 * Copyright (c) 2006-2016 ARM Limited 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); 00006 * you may not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 00018 /** @file fopen.cpp Test cases to POSIX file fopen() interface. 00019 * 00020 * Please consult the documentation under the test-case functions for 00021 * a description of the individual test case. 00022 */ 00023 00024 #include "mbed.h" 00025 #include "mbed_config.h" 00026 #include "RZ_SDHIBlockDevice.hpp" 00027 #include "FATFileSystem.h" 00028 #include "fsfat_debug.h" 00029 #include "fsfat_test.h" 00030 #include "utest/utest.h" 00031 #include "unity/unity.h" 00032 #include "greentea-client/test_env.h" 00033 00034 #include <stdio.h> 00035 #include <string.h> 00036 #include <stdlib.h> /*rand()*/ 00037 #include <inttypes.h> 00038 #include <errno.h> 00039 /* mbed_retarget.h is included after errno.h so symbols are mapped to 00040 * consistent values for all toolchains */ 00041 #include "platform/mbed_retarget.h" 00042 00043 using namespace utest::v1; 00044 00045 /// @cond FSFAT_DOXYGEN_DISABLE 00046 #ifdef FSFAT_DEBUG 00047 #define FSFAT_FOPEN_GREENTEA_TIMEOUT_S 3000 00048 #else 00049 #define FSFAT_FOPEN_GREENTEA_TIMEOUT_S 1000 00050 #endif 00051 /// @endcond 00052 00053 00054 /* DEVICE_SPI 00055 * This symbol is defined in targets.json if the target has a SPI interface, which is required for SDCard support. 00056 * 00057 * MBED_CONF_APP_FSFAT_SDCARD_INSTALLED 00058 * For testing purposes, an SDCard must be installed on the target for the test cases in this file to succeed. 00059 * If the target has an SD card installed then the MBED_CONF_APP_FSFAT_SDCARD_INSTALLED will be generated 00060 * from the mbed_app.json, which includes the line 00061 * { 00062 * "config": { 00063 * "UART_RX": "D0", 00064 * <<< lines removed >>> 00065 * "DEVICE_SPI": 1, 00066 * "FSFAT_SDCARD_INSTALLED": 1 00067 * }, 00068 * <<< lines removed >>> 00069 */ 00070 00071 #if DEVICE_SPI && ( defined(MBED_CONF_APP_FSFAT_SDCARD_INSTALLED) || (MBED_CONF_SD_FSFAT_SDCARD_INSTALLED)) 00072 static char fsfat_fopen_utest_msg_g[FSFAT_UTEST_MSG_BUF_SIZE]; 00073 #define FSFAT_FOPEN_TEST_MOUNT_PT_NAME "sd" 00074 #define FSFAT_FOPEN_TEST_MOUNT_PT_PATH "/" FSFAT_FOPEN_TEST_MOUNT_PT_NAME 00075 #define FSFAT_FOPEN_TEST_WORK_BUF_SIZE_1 64 00076 #define FSFAT_FOPEN_TEST_FILEPATH_MAX_DEPTH 20 00077 static const char *sd_badfile_path = "/sd/badfile.txt"; 00078 static const char *sd_testfile_path = "/sd/test.txt"; 00079 00080 SDHIBlockDevice sd(MBED_CONF_RZ_SDHI_CH); 00081 FATFileSystem fs("sd", &sd); 00082 00083 #define FSFAT_FOPEN_TEST_00 fsfat_fopen_test_00 00084 #define FSFAT_FOPEN_TEST_01 fsfat_fopen_test_01 00085 #define FSFAT_FOPEN_TEST_02 fsfat_fopen_test_02 00086 #define FSFAT_FOPEN_TEST_03 fsfat_fopen_test_03 00087 #define FSFAT_FOPEN_TEST_04 fsfat_fopen_test_04 00088 #define FSFAT_FOPEN_TEST_05 fsfat_fopen_test_05 00089 #define FSFAT_FOPEN_TEST_06 fsfat_fopen_test_06 00090 #define FSFAT_FOPEN_TEST_07 fsfat_fopen_test_07 00091 #define FSFAT_FOPEN_TEST_08 fsfat_fopen_test_08 00092 #define FSFAT_FOPEN_TEST_09 fsfat_fopen_test_09 00093 #define FSFAT_FOPEN_TEST_10 fsfat_fopen_test_10 00094 #define FSFAT_FOPEN_TEST_11 fsfat_fopen_test_11 00095 #define FSFAT_FOPEN_TEST_12 fsfat_fopen_test_12 00096 #define FSFAT_FOPEN_TEST_13 fsfat_fopen_test_13 00097 #define FSFAT_FOPEN_TEST_14 fsfat_fopen_test_14 00098 #define FSFAT_FOPEN_TEST_15 fsfat_fopen_test_15 00099 #define FSFAT_FOPEN_TEST_16 fsfat_fopen_test_16 00100 #define FSFAT_FOPEN_TEST_17 fsfat_fopen_test_17 00101 #define FSFAT_FOPEN_TEST_18 fsfat_fopen_test_18 00102 #define FSFAT_FOPEN_TEST_19 fsfat_fopen_test_19 00103 #define FSFAT_FOPEN_TEST_20 fsfat_fopen_test_20 00104 #define FSFAT_FOPEN_TEST_21 fsfat_fopen_test_21 00105 #define FSFAT_FOPEN_TEST_22 fsfat_fopen_test_22 00106 #define FSFAT_FOPEN_TEST_23 fsfat_fopen_test_23 00107 #define FSFAT_FOPEN_TEST_24 fsfat_fopen_test_24 00108 #define FSFAT_FOPEN_TEST_25 fsfat_fopen_test_25 00109 #define FSFAT_FOPEN_TEST_26 fsfat_fopen_test_26 00110 #define FSFAT_FOPEN_TEST_27 fsfat_fopen_test_27 00111 #define FSFAT_FOPEN_TEST_28 fsfat_fopen_test_28 00112 #define FSFAT_FOPEN_TEST_29 fsfat_fopen_test_29 00113 #define FSFAT_FOPEN_TEST_30 fsfat_fopen_test_30 00114 00115 00116 /* support functions */ 00117 00118 /* 00119 * open tests that focus on testing fopen() 00120 * fsfat_handle_t fopen(const char* filename, char* data, size_t* len, fsfat_key_desc_t* kdesc) 00121 */ 00122 00123 /* file data for test_01 */ 00124 static fsfat_kv_data_t fsfat_fopen_test_01_kv_data[] = { 00125 { "/sd/fopentst/hello/world/animal/wobbly/dog/foot/frontlft.txt", "missing"}, 00126 { NULL, NULL}, 00127 }; 00128 00129 00130 /** @brief 00131 * Split a file path into its component parts, setting '/' characters to '\0', and returning 00132 * pointers to the file path components in the parts array. For example, if 00133 * filepath = "/sd/fopentst/hello/world/animal/wobbly/dog/foot/frontlft.txt" then 00134 * *parts[0] = "sd" 00135 * *parts[1] = "fopentst" 00136 * *parts[2] = "hello" 00137 * *parts[3] = "world" 00138 * *parts[4] = "animal" 00139 * *parts[5] = "wobbly" 00140 * *parts[6] = "dog" 00141 * *parts[7] = "foot" 00142 * *parts[8] = "frontlft.txt" 00143 * parts[9] = NULL 00144 * 00145 * ARGUMENTS 00146 * @param filepath IN file path string to split into component parts. Expected to start with '/' 00147 * @param parts IN OUT array to hold pointers to parts 00148 * @param num IN number of components available in parts 00149 * 00150 * @return On success, this returns the number of components in the filepath Returns number of compoee 00151 */ 00152 static int32_t fsfat_filepath_split(char *filepath, char *parts[], uint32_t num) 00153 { 00154 uint32_t i = 0; 00155 int32_t ret = -1; 00156 char *z = filepath; 00157 00158 while (i < num && *z != '\0') { 00159 if (*z == '/') { 00160 *z = '\0'; 00161 parts[i] = ++z; 00162 i++; 00163 } else { 00164 z++; 00165 } 00166 } 00167 if (*z == '\0' && i > 0) { 00168 ret = (int32_t) i; 00169 } 00170 return ret; 00171 } 00172 00173 00174 /** @brief 00175 * remove all directories and file in the given filepath 00176 * 00177 * ARGUMENTS 00178 * @param filepath IN file path string to split into component parts. Expected to start with '/' 00179 * 00180 * @return On success, this returns 0, otherwise < 0 is returned; 00181 */ 00182 int32_t fsfat_filepath_remove_all(char *filepath) 00183 { 00184 int32_t ret = -1; 00185 int32_t len = 0; 00186 char *fpathbuf = NULL; 00187 char *pos = NULL; 00188 00189 FSFAT_FENTRYLOG("%s:entered\n", __func__); 00190 len = strlen(filepath); 00191 fpathbuf = (char *) malloc(len + 1); 00192 if (fpathbuf == NULL) { 00193 FSFAT_DBGLOG("%s: failed to duplicate string (out of memory)\n", __func__); 00194 return ret; 00195 } 00196 memset(fpathbuf, 0, len + 1); 00197 memcpy(fpathbuf, filepath, len); 00198 00199 /* delete the leaf node first, and then successively parent directories. */ 00200 pos = fpathbuf + strlen(fpathbuf); 00201 while (pos != fpathbuf) { 00202 /* If the remaining file path is the mount point path then finish as the mount point cannot be removed */ 00203 if (strlen(fpathbuf) == strlen(FSFAT_FOPEN_TEST_MOUNT_PT_PATH)) { 00204 if (strncmp(fpathbuf, FSFAT_FOPEN_TEST_MOUNT_PT_PATH, strlen(fpathbuf)) == 0) { 00205 break; 00206 } 00207 } 00208 ret = remove(fpathbuf); 00209 pos = strrchr(fpathbuf, '/'); 00210 *pos = '\0'; 00211 } 00212 if (fpathbuf) { 00213 free(fpathbuf); 00214 } 00215 return ret; 00216 } 00217 00218 00219 /** @brief 00220 * make all directories in the given filepath. Do not create the file if present at end of filepath 00221 * 00222 * ARGUMENTS 00223 * @param filepath IN file path containing directories and file 00224 * @param do_asserts IN set to true if function should assert on errors 00225 * 00226 * @return On success, this returns 0, otherwise < 0 is returned; 00227 */ 00228 static int32_t fsfat_filepath_make_dirs(char *filepath, bool do_asserts) 00229 { 00230 int32_t i = 0; 00231 int32_t num_parts = 0; 00232 int32_t len = 0; 00233 int32_t ret = -1; 00234 char *fpathbuf = NULL; 00235 char *buf = NULL; 00236 int pos = 0; 00237 char *parts[FSFAT_FOPEN_TEST_FILEPATH_MAX_DEPTH]; 00238 00239 FSFAT_DBGLOG("%s:entered\n", __func__); 00240 /* find the dirs to create*/ 00241 memset(parts, 0, sizeof(parts)); 00242 len = strlen(filepath); 00243 fpathbuf = (char *) malloc(len + 1); 00244 if (fpathbuf == NULL) { 00245 FSFAT_DBGLOG("%s: failed to duplicate string (out of memory)\n", __func__); 00246 return ret; 00247 } 00248 memset(fpathbuf, 0, len + 1); 00249 memcpy(fpathbuf, filepath, len); 00250 num_parts = fsfat_filepath_split(fpathbuf, parts, FSFAT_FOPEN_TEST_FILEPATH_MAX_DEPTH); 00251 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 00252 "%s:Error: failed to split filepath (filename=\"%s\", num_parts=%d)\n", __func__, filepath, (int) num_parts); 00253 TEST_ASSERT_MESSAGE(num_parts > 0, fsfat_fopen_utest_msg_g); 00254 00255 /* Now create the directories on the directory path. 00256 * Skip creating dir for "/sd" which must be present */ 00257 buf = (char *) malloc(strlen(filepath) + 1); 00258 memset(buf, 0, strlen(filepath) + 1); 00259 pos = sprintf(buf, "/%s", parts[0]); 00260 for (i = 1; i < num_parts - 1; i++) { 00261 pos += sprintf(buf + pos, "/%s", parts[i]); 00262 FSFAT_DBGLOG("mkdir(%s)\n", buf); 00263 ret = mkdir(buf, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); 00264 if (do_asserts == true) { 00265 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 00266 "%s:Error: failed to create directory (filepath2=\"%s\", ret=%d, errno=%d)\n", __func__, buf, (int) ret, errno); 00267 TEST_ASSERT_MESSAGE(ret == 0, fsfat_fopen_utest_msg_g); 00268 } 00269 } 00270 00271 if (buf) { 00272 free(buf); 00273 } 00274 if (fpathbuf) { 00275 free(fpathbuf); 00276 } 00277 return ret; 00278 } 00279 00280 /** @brief 00281 * First and last test must format the SD card to FAT FS format: 00282 * @return on success returns CaseNext to continue to next test case, otherwise will assert on errors. 00283 */ 00284 control_t fsfat_fopen_test_00(const size_t call_count) 00285 { 00286 FSFAT_FENTRYLOG("%s:entered\n", __func__); 00287 (void) call_count; 00288 int32_t ret = -1; 00289 00290 fs.unmount(); 00291 ret = fs.format(&sd); 00292 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 00293 "%s:Error: failed to format sdcard (ret=%d)\n", __func__, (int) ret); 00294 TEST_ASSERT_MESSAGE(ret == 0, fsfat_fopen_utest_msg_g); 00295 fs.mount(&sd); 00296 00297 return CaseNext; 00298 } 00299 00300 00301 /* FIX ME: errno not set correctly when error occurs. This indicates a problem with the implementation. */ 00302 00303 /** @brief 00304 * Basic fopen test which does the following: 00305 * - creates file and writes some data to the value blob. 00306 * - closes the newly created file. 00307 * - opens the file (r-only) 00308 * - reads the file data and checks its the same as the previously created data. 00309 * - closes the opened file 00310 * 00311 * @return on success returns CaseNext to continue to next test case, otherwise will assert on errors. 00312 */ 00313 static control_t fsfat_fopen_test_01(const size_t call_count) 00314 { 00315 char *read_buf; 00316 int32_t ret = 0; 00317 size_t len = 0; 00318 fsfat_kv_data_t *node; 00319 FILE *fp = NULL; 00320 00321 FSFAT_DBGLOG("%s:entered\n", __func__); 00322 (void) call_count; 00323 node = fsfat_fopen_test_01_kv_data; 00324 00325 /* remove file and directory from a previous failed test run, if present */ 00326 fsfat_filepath_remove_all((char *) node->filename); 00327 00328 /* create dirs */ 00329 ret = fsfat_filepath_make_dirs((char *) node->filename, true); 00330 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 00331 "%s:Error: failed to create dirs for filename (filename=\"%s\")(ret=%d)\n", __func__, node->filename, (int) ret); 00332 TEST_ASSERT_MESSAGE(ret == 0, fsfat_fopen_utest_msg_g); 00333 00334 FSFAT_DBGLOG("%s:About to create new file (filename=\"%s\", data=\"%s\")\n", __func__, node->filename, node->value); 00335 fp = fopen(node->filename, "w+"); 00336 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 00337 "%s:Error: failed to create file (filename=\"%s\", data=\"%s\")(ret=%d, errno=%d)\n", __func__, node->filename, 00338 node->value, (int) ret, errno); 00339 TEST_ASSERT_MESSAGE(fp != NULL, fsfat_fopen_utest_msg_g); 00340 00341 FSFAT_DBGLOG("%s:length of file=%d (filename=\"%s\", data=\"%s\")\n", __func__, (int) len, node->filename, node->value); 00342 len = strlen(node->value); 00343 ret = fwrite((const void *) node->value, len, 1, fp); 00344 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 00345 "%s:Error: failed to write file (filename=\"%s\", data=\"%s\")(ret=%d)\n", __func__, node->filename, node->value, 00346 (int) ret); 00347 TEST_ASSERT_MESSAGE(ret == 1, fsfat_fopen_utest_msg_g); 00348 00349 FSFAT_DBGLOG("Created file successfully (filename=\"%s\", data=\"%s\")\n", node->filename, node->value); 00350 ret = fclose(fp); 00351 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 00352 "%s:Error: failed to close file (ret=%d, errno=%d)\n", __func__, (int) ret, errno); 00353 TEST_ASSERT_MESSAGE(ret == 0, fsfat_fopen_utest_msg_g); 00354 00355 /* now open the newly created key */ 00356 fp = NULL; 00357 fp = fopen(node->filename, "r"); 00358 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 00359 "%s:Error: failed to open file for reading (filename=\"%s\", data=\"%s\")(ret=%d)\n", __func__, node->filename, 00360 node->value, (int) ret); 00361 TEST_ASSERT_MESSAGE(fp != NULL, fsfat_fopen_utest_msg_g); 00362 00363 len = strlen(node->value) + 1; 00364 read_buf = (char *) malloc(len); 00365 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 00366 "%s:Error: failed to allocated read buffer \n", __func__); 00367 TEST_ASSERT_MESSAGE(read_buf != NULL, fsfat_fopen_utest_msg_g); 00368 00369 FSFAT_DBGLOG("Opened file successfully (filename=\"%s\", data=\"%s\")\n", node->filename, node->value); 00370 memset(read_buf, 0, len); 00371 ret = fread((void *) read_buf, len, 1, fp); 00372 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 00373 "%s:Error: failed to read file (filename=\"%s\", data=\"%s\", read_buf=\"%s\", ret=%d)\n", __func__, node->filename, 00374 node->value, read_buf, (int) ret); 00375 /* FIX ME: fread should return the number of items read, not 0 when an item is read successfully. 00376 * This indicates a problem with the implementation, as the correct data is read. The correct assert should be: 00377 * TEST_ASSERT_MESSAGE(ret == 1, fsfat_fopen_utest_msg_g); 00378 * The following assert is curerntly used until the implementation is fixed 00379 */ 00380 TEST_ASSERT_MESSAGE(ret == 0, fsfat_fopen_utest_msg_g); 00381 00382 /* check read data is as expected */ 00383 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 00384 "%s:Error: read value data (%s) != expected value data (filename=\"%s\", data=\"%s\", read_buf=\"%s\", ret=%d)\n", 00385 __func__, read_buf, node->filename, node->value, read_buf, (int) ret); 00386 TEST_ASSERT_MESSAGE(strncmp(read_buf, node->value, strlen(node->value)) == 0, fsfat_fopen_utest_msg_g); 00387 00388 if (read_buf) { 00389 free(read_buf); 00390 } 00391 ret = fclose(fp); 00392 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 00393 "%s:Error: fclose() call failed (ret=%d, errno=%d).\n", __func__, (int) ret, errno); 00394 TEST_ASSERT_MESSAGE(ret == 0, fsfat_fopen_utest_msg_g); 00395 return CaseNext; 00396 } 00397 00398 static fsfat_kv_data_t fsfat_fopen_test_02_data[] = { 00399 FSFAT_INIT_1_TABLE_MID_NODE, 00400 { NULL, NULL}, 00401 }; 00402 00403 /** 00404 * @brief test to fopen() a pre-existing key and try to write it, which should fail 00405 * as by default pre-existing keys are opened read-only 00406 * 00407 * Basic open test which does the following: 00408 * - creates file with default rw perms and writes some data to the value blob. 00409 * - closes the newly created file. 00410 * - opens the file with the default permissions (read-only) 00411 * - tries to write the file data which should fail because file was not opened with write flag set. 00412 * - closes the opened key 00413 * 00414 * @return on success returns CaseNext to continue to next test case, otherwise will assert on errors. 00415 */ 00416 control_t fsfat_fopen_test_02(const size_t call_count) 00417 { 00418 int32_t ret = -1; 00419 size_t len = 0; 00420 FILE *fp = NULL; 00421 00422 FSFAT_FENTRYLOG("%s:entered\n", __func__); 00423 (void) call_count; 00424 len = strlen(fsfat_fopen_test_02_data[0].value); 00425 ret = fsfat_test_create(fsfat_fopen_test_02_data[0].filename, (char *) fsfat_fopen_test_02_data[0].value, len); 00426 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 00427 "%s:Error: failed to create file (ret=%d).\n", __func__, (int) ret); 00428 TEST_ASSERT_MESSAGE(ret >= 0, fsfat_fopen_utest_msg_g); 00429 00430 /* by default, owner of key opens with read-only permissions*/ 00431 fp = fopen(fsfat_fopen_test_02_data[0].filename, "r"); 00432 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 00433 "%s:Error: failed to open file (filename=\"%s\", ret=%d)\n", __func__, fsfat_fopen_test_02_data[0].filename, (int) ret); 00434 TEST_ASSERT_MESSAGE(fp != NULL, fsfat_fopen_utest_msg_g); 00435 00436 len = strlen(fsfat_fopen_test_02_data[0].value); 00437 ret = fwrite((const void *) fsfat_fopen_test_02_data[0].value, len, 1, fp); 00438 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 00439 "%s:Error: call to fwrite() succeeded when should have failed for read-only file (filename=\"%s\")(ret=%d).\n", 00440 __func__, fsfat_fopen_test_02_data[0].filename, (int) ret); 00441 TEST_ASSERT_MESSAGE(ret <= 0, fsfat_fopen_utest_msg_g); 00442 00443 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, "%s:Error: fclose() call failed.\n", 00444 __func__); 00445 TEST_ASSERT_MESSAGE(fclose(fp) == 0, fsfat_fopen_utest_msg_g); 00446 00447 return CaseNext; 00448 } 00449 00450 00451 /** 00452 * @brief test to fopen() a pre-existing file and try to write it, which should succeed 00453 * because the key was opened read-write permissions explicitly 00454 * 00455 * Basic open test which does the following: 00456 * - creates file with default rw perms and writes some data to the value blob. 00457 * - closes the newly created file. 00458 * - opens the file with the rw permissions (non default) 00459 * - tries to write the file data which should succeeds because file was opened with write flag set. 00460 * - closes the opened key 00461 * 00462 * @return on success returns CaseNext to continue to next test case, otherwise will assert on errors. 00463 */ 00464 control_t fsfat_fopen_test_03(const size_t call_count) 00465 { 00466 int32_t ret = -1; 00467 size_t len = 0; 00468 FILE *fp = NULL; 00469 00470 FSFAT_FENTRYLOG("%s:entered\n", __func__); 00471 (void) call_count; 00472 len = strlen(fsfat_fopen_test_02_data[0].value); 00473 ret = fsfat_test_create(fsfat_fopen_test_02_data[0].filename, (char *) fsfat_fopen_test_02_data[0].value, len); 00474 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 00475 "%s:Error: failed to create file in store (ret=%d).\n", __func__, (int) ret); 00476 TEST_ASSERT_MESSAGE(ret >= 0, fsfat_fopen_utest_msg_g); 00477 00478 /* opens with read-write permissions*/ 00479 fp = fopen(fsfat_fopen_test_02_data[0].filename, "w+"); 00480 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 00481 "%s:Error: failed to open file (filename=\"%s\")(ret=%d)\n", __func__, fsfat_fopen_test_02_data[0].filename, (int) ret); 00482 TEST_ASSERT_MESSAGE(ret >= 0, fsfat_fopen_utest_msg_g); 00483 00484 len = strlen(fsfat_fopen_test_02_data[0].value); 00485 ret = fwrite((const void *) fsfat_fopen_test_02_data[0].value, len, 1, fp); 00486 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 00487 "%s:Error: call to fwrite() failed when should have succeeded (filename=\"%s\", ret=%d).\n", __func__, 00488 fsfat_fopen_test_02_data[0].filename, (int) ret); 00489 TEST_ASSERT_MESSAGE(ret >= 0, fsfat_fopen_utest_msg_g); 00490 00491 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, "%s:Error: fclose() call failed.\n", 00492 __func__); 00493 TEST_ASSERT_MESSAGE(fclose(fp) >= 0, fsfat_fopen_utest_msg_g); 00494 00495 /* clean-up */ 00496 ret = remove(fsfat_fopen_test_02_data[0].filename); 00497 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 00498 "%s:Error: unable to delete file (filename=%s, ret=%d) .\n", __func__, fsfat_fopen_test_02_data[0].filename, (int) ret); 00499 TEST_ASSERT_MESSAGE(ret >= 0, fsfat_fopen_utest_msg_g); 00500 00501 return CaseNext; 00502 } 00503 00504 00505 /** @brief test to call fopen() with a filename string that exceeds the maximum length 00506 * - chanFS supports the exFAT format which should support 255 char filenames 00507 * - check that filenames of this length can be created 00508 * 00509 * @return on success returns CaseNext to continue to next test case, otherwise will assert on errors. 00510 */ 00511 control_t fsfat_fopen_test_04(const size_t call_count) 00512 { 00513 char filename_good[FSFAT_FILENAME_MAX_LENGTH + 1]; 00514 char filename_bad[FSFAT_FILENAME_MAX_LENGTH + 2]; 00515 int32_t ret = -1; 00516 size_t len = 0; 00517 00518 FSFAT_FENTRYLOG("%s:entered\n", __func__); 00519 (void) call_count; 00520 00521 memset(filename_good, 0, FSFAT_FILENAME_MAX_LENGTH + 1); 00522 memset(filename_bad, 0, FSFAT_FILENAME_MAX_LENGTH + 2); 00523 ret = fsfat_test_filename_gen(filename_good, FSFAT_FILENAME_MAX_LENGTH); 00524 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 00525 "%s:Error: unable to generate filename_good.\n", __func__); 00526 TEST_ASSERT_MESSAGE(ret >= 0, fsfat_fopen_utest_msg_g); 00527 00528 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 00529 "%s:Error: filename_good is not the correct length (filename_good=%s, len=%d, expected=%d).\n", __func__, filename_good, 00530 (int) strlen(filename_good), (int) FSFAT_FILENAME_MAX_LENGTH); 00531 TEST_ASSERT_MESSAGE(strlen(filename_good) == FSFAT_FILENAME_MAX_LENGTH, fsfat_fopen_utest_msg_g); 00532 00533 ret = fsfat_test_filename_gen(filename_bad, FSFAT_FILENAME_MAX_LENGTH + 1); 00534 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 00535 "%s:Error: unable to generate filename_bad.\n", __func__); 00536 TEST_ASSERT_MESSAGE(ret >= 0, fsfat_fopen_utest_msg_g); 00537 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 00538 "%s:Error: filename_bad is not the correct length (len=%d, expected=%d).\n", __func__, (int) strlen(filename_bad), 00539 (int) FSFAT_FILENAME_MAX_LENGTH + 1); 00540 TEST_ASSERT_MESSAGE(strlen(filename_bad) == FSFAT_FILENAME_MAX_LENGTH + 1, fsfat_fopen_utest_msg_g); 00541 00542 len = strlen(filename_good); 00543 ret = fsfat_test_create(filename_good, filename_good, len); 00544 /* FIXME: 00545 * The current implementation can create file with a filename with 9 chars (more than the 8 restriction of FAT32 Short File Names). 00546 * However, the exFAT 255 char filesnames is not supported and hence the following is commented out. Find out what is 00547 * the supported max filename length and change this testcase according. 00548 * 00549 * FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, "%s:Error: failed to create file (filename=%s, ret=%d).\n", __func__, filename_good, (int) ret); 00550 * TEST_ASSERT_MESSAGE(ret >= 0, fsfat_fopen_utest_msg_g); 00551 */ 00552 00553 len = strlen(filename_bad); 00554 ret = fsfat_test_create(filename_bad, filename_bad, len); 00555 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 00556 "%s:Error: created file in store for filename_bad when should have failed (filename=%s, ret=%d).\n", __func__, 00557 filename_bad, (int) ret); 00558 TEST_ASSERT_MESSAGE(ret < 0, fsfat_fopen_utest_msg_g); 00559 return CaseNext; 00560 } 00561 00562 00563 /// @cond FSFAT_DOXYGEN_DISABLE 00564 typedef struct fsfat_fopen_kv_name_ascii_node { 00565 uint32_t code; 00566 uint32_t f_allowed : 1; 00567 } fsfat_fopen_kv_name_ascii_node; 00568 /// @endcond 00569 00570 static const uint32_t fsfat_fopen_kv_name_ascii_table_code_sentinel_g = 256; 00571 00572 /*@brief table recording ascii character codes permitted in kv names */ 00573 static fsfat_fopen_kv_name_ascii_node fsfat_fopen_kv_name_ascii_table[] = { 00574 {0, true}, /* code 0-33 allowed*/ 00575 {34, false}, /* '"' not allowed */ 00576 {35, true}, /* allowed */ 00577 {42, false}, /* '*' not allowed */ 00578 {43, true}, /* allowed */ 00579 {47, false}, /* '/' not allowed */ 00580 {48, true}, /* allowed */ 00581 {58, false}, /* ':' not allowed */ 00582 {59, true}, /* allowed */ 00583 {60, false}, /* '<' not allowed */ 00584 {61, true}, /* allowed */ 00585 {62, false}, /* '?', '>' not allowed */ 00586 {64, true}, /* allowed */ 00587 {92, false}, /* '\' not allowed */ 00588 {93, true}, /* allowed */ 00589 {124, false}, /* '!' not allowed */ 00590 {125, true}, /* allowed */ 00591 {127, false}, /* DEL not allowed */ 00592 {128, true}, /* allowed */ 00593 {fsfat_fopen_kv_name_ascii_table_code_sentinel_g, false}, /* sentinel */ 00594 }; 00595 00596 00597 /// @cond FSFAT_DOXYGEN_DISABLE 00598 enum fsfat_fopen_kv_name_pos { 00599 fsfat_fopen_kv_name_pos_start = 0x0, 00600 fsfat_fopen_kv_name_pos_mid, 00601 fsfat_fopen_kv_name_pos_end, 00602 fsfat_fopen_kv_name_pos_max 00603 }; 00604 /// @endcond 00605 00606 /** @brief test to call fopen() with filename that in includes illegal characters 00607 * - the character(s) can be at the beginning of the filename 00608 * - the character(s) can be at the end of the filename 00609 * - the character(s) can be somewhere within the filename string 00610 * - a max-length string of random characters (legal and illegal) 00611 * - a max-length string of random illegal characters only 00612 * 00613 * @return on success returns CaseNext to continue to next test case, otherwise will assert on errors. 00614 */ 00615 control_t fsfat_fopen_test_05(const size_t call_count) 00616 { 00617 bool f_allowed = false; 00618 const char *mnt_pt = FSFAT_FOPEN_TEST_MOUNT_PT_PATH; 00619 const char *basename = "goodfile"; 00620 const char *extname = "txt"; 00621 const size_t basename_len = strlen(basename); 00622 const size_t filename_len = strlen(mnt_pt) + strlen(basename) + strlen(extname) + 00623 2; /* extra 2 chars for '/' and '.' in "/sd/goodfile.txt" */ 00624 char filename[FSFAT_BUF_MAX_LENGTH]; 00625 size_t len = 0; 00626 uint32_t j = 0; 00627 int32_t ret = 0; 00628 fsfat_fopen_kv_name_ascii_node *node = NULL; 00629 uint32_t pos; 00630 00631 FSFAT_FENTRYLOG("%s:entered\n", __func__); 00632 (void) call_count; 00633 00634 #ifdef FSFAT_DEBUG 00635 /* symbol only used why debug is enabled */ 00636 const char *pos_str = NULL; 00637 #endif 00638 00639 /* create bad keyname strings with invalid character code at start of keyname */ 00640 node = fsfat_fopen_kv_name_ascii_table; 00641 memset(filename, 0, FSFAT_BUF_MAX_LENGTH); 00642 while (node->code != fsfat_fopen_kv_name_ascii_table_code_sentinel_g) { 00643 /* loop over range */ 00644 for (j = node->code; j < (node + 1)->code; j++) { 00645 if ((j >= 48 && j <= 57) || (j >= 65 && j <= 90) || (j >= 97 && j <= 122)) { 00646 FSFAT_DBGLOG("%s: skipping alpha-numeric ascii character code %d (%c).\n", __func__, (int) j, (char) j); 00647 continue; 00648 } 00649 00650 /* set the start, mid, last character of the name to the test char code */ 00651 for (pos = (uint32_t) fsfat_fopen_kv_name_pos_start; pos < (uint32_t) fsfat_fopen_kv_name_pos_max; pos++) { 00652 len = snprintf(filename, filename_len + 1, "%s/%s.%s", mnt_pt, basename, extname); 00653 /* overwrite a char at the pos start, mid, end of the filename with an ascii char code (both illegal and legal)*/ 00654 switch (pos) { 00655 case fsfat_fopen_kv_name_pos_start: 00656 filename[5] = (char) j; /* 5 so at to write the second basename char (bad chars as first char not accepted)*/ 00657 break; 00658 case fsfat_fopen_kv_name_pos_mid: 00659 /* create bad keyname strings with invalid character code in the middle of keyname */ 00660 filename[5 + basename_len / 2] = (char) j; 00661 break; 00662 case fsfat_fopen_kv_name_pos_end: 00663 /* create bad keyname strings with invalid character code at end of keyname */ 00664 filename[5 + basename_len - 1] = (char) j; 00665 break; 00666 default: 00667 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 00668 "%s:Error: unexpected value of pos (pos=%d).\n", __func__, (int) pos); 00669 TEST_ASSERT_MESSAGE(ret >= 0, fsfat_fopen_utest_msg_g); 00670 break; 00671 } 00672 00673 #ifdef FSFAT_DEBUG 00674 /* processing only required when debug trace enabled */ 00675 switch (pos) { 00676 case fsfat_fopen_kv_name_pos_start: 00677 pos_str = "start"; 00678 break; 00679 case fsfat_fopen_kv_name_pos_mid: 00680 pos_str = "middle"; 00681 break; 00682 case fsfat_fopen_kv_name_pos_end: 00683 pos_str = "end"; 00684 break; 00685 default: 00686 break; 00687 } 00688 #endif 00689 ret = fsfat_test_create(filename, (const char *) filename, len); 00690 00691 /* special cases */ 00692 switch (j) { 00693 //case 0 : 00694 //case 46 : 00695 // switch(pos) 00696 // { 00697 // /* for code = 0 (null terminator). permitted at mid and end of string */ 00698 // /* for code = 46 ('.'). permitted at mid and end of string but not at start */ 00699 // case fsfat_fopen_kv_name_pos_start: 00700 // f_allowed = false; 00701 // break; 00702 // case fsfat_fopen_kv_name_pos_mid: 00703 // case fsfat_fopen_kv_name_pos_end: 00704 // default: 00705 // f_allowed = true; 00706 // break; 00707 // } 00708 // break; 00709 default: 00710 f_allowed = node->f_allowed; 00711 break; 00712 } 00713 if (f_allowed == true) { 00714 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 00715 "%s:Error: failed to create file in store when filename contains valid characters (code=%d, ret=%d).\n", __func__, 00716 (int) j, (int) ret); 00717 TEST_ASSERT_MESSAGE(ret >= 0, fsfat_fopen_utest_msg_g); 00718 /* revert FSFAT_LOG for more trace */ 00719 FSFAT_DBGLOG("Successfully created a file with valid keyname containing ascii character code %d (%c) at the %s of the keyname.\n", 00720 (int) j, (int) j, pos_str); 00721 FSFAT_LOG("%c", '.'); 00722 00723 ret = fsfat_test_delete(filename); 00724 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 00725 "%s:Error: failed to delete file previously created (code=%d, ret=%d).\n", __func__, (int) j, (int) ret); 00726 TEST_ASSERT_MESSAGE(ret >= 0, fsfat_fopen_utest_msg_g); 00727 } else { 00728 /*node->f_allowed == false => not allowed to create kv name with ascii code */ 00729 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 00730 "%s:Error: created file in store when filename contains an invalid character (code=%d, ret=%d).\n", __func__, (int) j, 00731 (int) ret); 00732 TEST_ASSERT_MESSAGE(ret < 0, fsfat_fopen_utest_msg_g); 00733 /* revert FSFAT_LOG for more trace */ 00734 FSFAT_DBGLOG("Successfully failed to create a file with an invalid keyname containing ascii character code %d at the %s of the keyname.\n", 00735 (int) j, pos_str); 00736 FSFAT_LOG("%c", '.'); 00737 } 00738 } 00739 } 00740 node++; 00741 } 00742 00743 FSFAT_LOG("%c", '\n'); 00744 return CaseNext; 00745 } 00746 00747 00748 static const char fsfat_fopen_ascii_illegal_buf_g[] = "\"�'*+,./:;<=>?[\\]|"; 00749 00750 /** @brief test to call fopen() with filename that in includes 00751 * illegal characters 00752 * - a max-length string of random illegal characters only 00753 * 00754 * @return on success returns CaseNext to continue to next test case, otherwise will assert on errors. 00755 */ 00756 control_t fsfat_fopen_test_06(const size_t call_count) 00757 { 00758 const char *mnt_pt = FSFAT_FOPEN_TEST_MOUNT_PT_PATH; 00759 const char *extname = "txt"; 00760 const size_t filename_len = strlen(mnt_pt) + FSFAT_MAX_FILE_BASENAME + strlen(extname) + 00761 2; /* extra 2 chars for '/' and '.' in "/sd/goodfile.txt" */ 00762 char filename[FSFAT_BUF_MAX_LENGTH]; 00763 int32_t i = 0; 00764 int32_t j = 0; 00765 uint32_t pos = 0; 00766 uint32_t len = 0; 00767 int32_t ret = -1; 00768 size_t buf_data_max = 0; 00769 00770 FSFAT_FENTRYLOG("%s:entered\n", __func__); 00771 (void) call_count; 00772 00773 memset(filename, 0, FSFAT_BUF_MAX_LENGTH); 00774 /* create bad keyname strings with invalid character code at start of keyname */ 00775 buf_data_max = strlen(fsfat_fopen_ascii_illegal_buf_g); 00776 00777 /* generate a number of illegal filenames */ 00778 for (j = 0; i < FSFAT_MAX_FILE_BASENAME; j++) { 00779 /* generate a kv name of illegal chars*/ 00780 len = snprintf(filename, filename_len + 1, "%s/", mnt_pt); 00781 for (i = 0; i < FSFAT_MAX_FILE_BASENAME; i++) { 00782 pos = rand() % (buf_data_max + 1); 00783 len += snprintf(filename + len, filename_len + 1, "%c", fsfat_fopen_ascii_illegal_buf_g[pos]); 00784 00785 } 00786 len += snprintf(filename + len, filename_len + 1, ".%s", extname); 00787 ret = fsfat_test_create(filename, filename, len); 00788 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 00789 "%s:Error: created file when filename contains invalid characters (filename=%s, ret=%d).\n", __func__, filename, 00790 (int) ret); 00791 TEST_ASSERT_MESSAGE(ret < 0, fsfat_fopen_utest_msg_g); 00792 } 00793 return CaseNext; 00794 } 00795 00796 00797 /** @brief test for errno reporting on a failed fopen()call 00798 * 00799 * This test does the following: 00800 * - tries to open a file that does not exist for reading, and checks that a NULL pointer is returned. 00801 * - checks that errno is not 0 as there is an error. 00802 * - checks that ferror() returns 1 indicating an error exists. 00803 * 00804 * Note: see NOTE_1 below. 00805 * 00806 * @return on success returns CaseNext to continue to next test case, otherwise will assert on errors. 00807 */ 00808 control_t fsfat_fopen_test_07(const size_t call_count) 00809 { 00810 FILE *f = NULL; 00811 int ret = -1; 00812 int errno_val = 0; 00813 const char *filename = sd_badfile_path; 00814 00815 FSFAT_FENTRYLOG("%s:entered\n", __func__); 00816 (void) call_count; 00817 00818 errno = 0; 00819 /* this is expect to fail as the file doesnt exist */ 00820 f = fopen(filename, "r"); 00821 00822 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 00823 "%s:Error: opened non-existent file for reading (filename=%s, f=%p).\n", __func__, filename, f); 00824 TEST_ASSERT_MESSAGE(f == NULL, fsfat_fopen_utest_msg_g); 00825 00826 /* check errno is set correctly */ 00827 #if ! defined(__ARMCC_VERSION) && defined(__GNUC__) 00828 /* Store errno so the current value set is not changed by new function call */ 00829 errno_val = errno; 00830 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 00831 "%s:Error: errno has unexpected value (errno != 0 expected) (filename=%s, errno=%d).\n", __func__, filename, errno); 00832 TEST_ASSERT_MESSAGE(errno_val != 0, fsfat_fopen_utest_msg_g); 00833 #endif /* ! defined(__ARMCC_VERSION) && defined(__GNUC__) */ 00834 return CaseNext; 00835 } 00836 00837 00838 /** @brief test for operation of clearerr() and ferror() 00839 * 00840 * The test does the following: 00841 * - opens and then closes a file, but keeps a copy of the FILE pointer fp. 00842 * - set errno to 0. 00843 * - write to the close file with fwrite(fp) which should return 0 (no writes) and set the errno. 00844 * - check the error condition is set with ferror(). 00845 * - clear the error with clearerr(). 00846 * - check the error condition is reset with ferror(). 00847 * 00848 * NOTE_1: GCC/ARMCC support for setting errno 00849 * - Documentation (e.g. fwrite() man page) does not explicity say fwrite() sets errno 00850 * (e.g. for an fwrite() on a read-only file). 00851 * - GCC libc fwrite() appears to set errno as expected. 00852 * - ARMCC & IAR libc fwrite() appears not to set errno. 00853 * 00854 * The following ARMCC documents are silent on whether fwrite() sets errno: 00855 * - "ARM C and C++ Libraries and Floating-Point Support". 00856 * - "RL-ARM User Guide fwrite() section". 00857 * 00858 * @return on success returns CaseNext to continue to next test case, otherwise will assert on errors. 00859 */ 00860 control_t fsfat_fopen_test_08(const size_t call_count) 00861 { 00862 FILE *fp = NULL; 00863 int ret = -1; 00864 int ret_ferror = -1; 00865 const char *filename = sd_testfile_path; 00866 00867 FSFAT_FENTRYLOG("%s:entered\n", __func__); 00868 (void) call_count; 00869 00870 errno = 0; 00871 fp = fopen(filename, "w+"); 00872 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 00873 "%s:Error: failed to open file (filename=%s, f=%p).\n", __func__, filename, fp); 00874 TEST_ASSERT_MESSAGE(fp != NULL, fsfat_fopen_utest_msg_g); 00875 00876 /* close the fp but then try to read or write it */ 00877 ret = fclose(fp); 00878 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 00879 "%s:Error: failed to close file (ret=%d, errno=%d)\n", __func__, (int) ret, errno); 00880 TEST_ASSERT_MESSAGE(ret == 0, fsfat_fopen_utest_msg_g); 00881 00882 /* open file */ 00883 errno = 0; 00884 fp = fopen(filename, "r"); 00885 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 00886 "%s:Error: failed to open file for reading (filename=\"%s\", ret=%d)\n", __func__, filename, (int) ret); 00887 TEST_ASSERT_MESSAGE(fp != NULL, fsfat_fopen_utest_msg_g); 00888 00889 /* Perform fwrite() operation that will fail. */ 00890 errno = 0; 00891 ret = fwrite("42!", 4, 1, fp); 00892 00893 ret_ferror = ferror(fp); 00894 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 00895 "%s:Error: ferror() failed to report error (filename=%s, ret_ferror=%d).\n", __func__, filename, (int) ret_ferror); 00896 TEST_ASSERT_MESSAGE(ret_ferror != 0, fsfat_fopen_utest_msg_g); 00897 00898 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 00899 "%s:Error: fwrite successfully wrote to read-only file (filename=%s, ret=%d).\n", __func__, filename, (int) ret); 00900 /* the fwrite() should fail and return 0. */ 00901 TEST_ASSERT_MESSAGE(ret == 0, fsfat_fopen_utest_msg_g); 00902 00903 #if ! defined(__ARMCC_VERSION) && defined(__GNUC__) 00904 /* check that errno is set. ARMCC appears not to set errno for fwrite() failure. */ 00905 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 00906 "%s:Error: unexpected zero value for errno (filename=%s, ret=%d, errno=%d).\n", __func__, filename, (int) ret, errno); 00907 TEST_ASSERT_MESSAGE(errno != 0, fsfat_fopen_utest_msg_g); 00908 00909 /* check that errno is set to the expected value (this may change differ for different libc's) */ 00910 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 00911 "%s:Error: errno != EBADF (filename=%s, ret=%d, errno=%d).\n", __func__, filename, (int) ret, errno); 00912 TEST_ASSERT_MESSAGE(errno == EBADF, fsfat_fopen_utest_msg_g); 00913 #endif /* ! defined(__ARMCC_VERSION) && defined(__GNUC__) */ 00914 00915 /* check clearerr() return clears the error */ 00916 clearerr(fp); 00917 ret = ferror(fp); 00918 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 00919 "%s:Error: ferror() did not return zero value when error has been cleared (filename=%s, ret=%d).\n", __func__, filename, 00920 (int) ret); 00921 TEST_ASSERT_MESSAGE(ret == 0, fsfat_fopen_utest_msg_g); 00922 00923 fclose(fp); 00924 return CaseNext; 00925 } 00926 00927 00928 /** @brief test for operation of ftell() 00929 * 00930 * @return on success returns CaseNext to continue to next test case, otherwise will assert on errors. 00931 */ 00932 control_t fsfat_fopen_test_09(const size_t call_count) 00933 { 00934 FILE *fp = NULL; 00935 int ret = -1; 00936 int32_t len = 0; 00937 00938 FSFAT_FENTRYLOG("%s:entered\n", __func__); 00939 (void) call_count; 00940 00941 /* create a file of a certain length */ 00942 len = strlen(fsfat_fopen_test_02_data[0].value); 00943 ret = fsfat_test_create(fsfat_fopen_test_02_data[0].filename, (char *) fsfat_fopen_test_02_data[0].value, len); 00944 00945 errno = 0; 00946 /* Open the file for reading so the file is not truncated to 0 length. */ 00947 fp = fopen(fsfat_fopen_test_02_data[0].filename, "r"); 00948 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 00949 "%s:Error: failed to open file (filename=%s, fp=%p, errno=%d).\n", __func__, fsfat_fopen_test_02_data[0].filename, fp, 00950 errno); 00951 TEST_ASSERT_MESSAGE(fp != NULL, fsfat_fopen_utest_msg_g); 00952 00953 errno = 0; 00954 ret = fseek(fp, 0, SEEK_END); 00955 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 00956 "%s:Error: fseek() failed to SEEK_END (filename=%s, ret=%d, errno=%d).\n", __func__, 00957 fsfat_fopen_test_02_data[0].filename, (int) ret, errno); 00958 TEST_ASSERT_MESSAGE(ret == 0, fsfat_fopen_utest_msg_g); 00959 00960 errno = 0; 00961 ret = ftell(fp); 00962 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 00963 "%s:Error: ftell() failed to report correct offset value (filename=%s, ret=%d, errno=%d).\n", __func__, 00964 fsfat_fopen_test_02_data[0].filename, (int) ret, errno); 00965 TEST_ASSERT_MESSAGE(ret == len, fsfat_fopen_utest_msg_g); 00966 00967 errno = 0; 00968 ret = fclose(fp); 00969 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 00970 "%s:Error: failed to close file (ret=%d, errno=%d)\n", __func__, (int) ret, errno); 00971 TEST_ASSERT_MESSAGE(ret == 0, fsfat_fopen_utest_msg_g); 00972 00973 return CaseNext; 00974 } 00975 00976 00977 /* file data for test_10 */ 00978 static fsfat_kv_data_t fsfat_fopen_test_10_kv_data[] = { 00979 { "/sd/test_10/testfile.txt", "test_data"}, 00980 { NULL, NULL}, 00981 }; 00982 00983 /** @brief test for operation of remove() 00984 * 00985 * Performs the following tests: 00986 * 1. test remove() on a file that exists. This should succeed. 00987 * 2. test remove() on a dir that exists. This should succeed. 00988 * 3. test remove() on a file that doesnt exist. This should fail. check errno set. 00989 * 4. test remove() on a dir that doesnt exist. This should fail. check errno set. 00990 * 00991 * @return on success returns CaseNext to continue to next test case, otherwise will assert on errors. 00992 */ 00993 control_t fsfat_fopen_test_10(const size_t call_count) 00994 { 00995 char buf[FSFAT_FOPEN_TEST_WORK_BUF_SIZE_1]; 00996 char *pos = NULL; 00997 int32_t ret = -1; 00998 size_t len = 0; 00999 fsfat_kv_data_t *node = fsfat_fopen_test_10_kv_data; 01000 01001 FSFAT_FENTRYLOG("%s:entered\n", __func__); 01002 (void) call_count; 01003 01004 TEST_ASSERT(strlen(node->filename) < FSFAT_FOPEN_TEST_WORK_BUF_SIZE_1); 01005 01006 /* start from a known state i.e. directory to be created in not present */ 01007 fsfat_filepath_remove_all((char *) node->filename); 01008 01009 /* (1) */ 01010 errno = 0; 01011 ret = fsfat_filepath_make_dirs((char *) node->filename, false); 01012 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 01013 "%s:Error: failed to create dir (dirname=%s, ret=%d, errno=%d)\n", __func__, node->filename, (int) ret, errno); 01014 TEST_ASSERT_MESSAGE(ret == 0, fsfat_fopen_utest_msg_g); 01015 01016 len = strlen(node->value); 01017 ret = fsfat_test_create(node->filename, (char *) node->value, len); 01018 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 01019 "%s:Error: failed to create file (ret=%d).\n", __func__, (int) ret); 01020 TEST_ASSERT_MESSAGE(ret >= 0, fsfat_fopen_utest_msg_g); 01021 01022 ret = remove(node->filename); 01023 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 01024 "%s:Error: delete file operation failed (filename=%s, ret=%d) .\n", __func__, node->filename, (int) ret); 01025 TEST_ASSERT_MESSAGE(ret == 0, fsfat_fopen_utest_msg_g); 01026 01027 /* (3) */ 01028 ret = remove(node->filename); 01029 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 01030 "%s:Error: deleted a file that doesn't exist (filename=%s, ret=%d, errno=%d) .\n", __func__, node->filename, (int) ret, 01031 errno); 01032 TEST_ASSERT_MESSAGE(ret != 0, fsfat_fopen_utest_msg_g); 01033 01034 /* (2) */ 01035 memset(buf, 0, FSFAT_FOPEN_TEST_WORK_BUF_SIZE_1); 01036 memcpy(buf, node->filename, strlen(node->filename)); 01037 pos = strrchr(buf, '/'); 01038 *pos = '\0'; 01039 ret = remove(buf); 01040 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 01041 "%s:Error: delete directory operation failed (directory name=%s, ret=%d, errno=%d).\n", __func__, buf, (int) ret, 01042 errno); 01043 TEST_ASSERT_MESSAGE(ret == 0, fsfat_fopen_utest_msg_g); 01044 01045 /* (4) */ 01046 ret = remove(buf); 01047 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 01048 "%s:Error: deleted a directory that doesn't exist (directory name=%s, ret=%d, errno=%d).\n", __func__, buf, (int) ret, 01049 errno); 01050 TEST_ASSERT_MESSAGE(ret != 0, fsfat_fopen_utest_msg_g); 01051 01052 return CaseNext; 01053 } 01054 01055 01056 /* file data for test_11 */ 01057 static fsfat_kv_data_t fsfat_fopen_test_11_kv_data[] = { 01058 { "/sd/test_11/step0.txt", "test_data"}, 01059 { "/sd/test_11/step1.txt", "test_data"}, 01060 { "/sd/test_11/subdir/step3.txt", "test_data"}, 01061 { NULL, NULL}, 01062 }; 01063 01064 /** @brief test for operation of rename() 01065 * 01066 * This test does the following: 01067 * 1) test rename() on a file that exists to a new filename within the same directory. 01068 * 2) test rename() on a file that exists to a new filename within a different directory. 01069 * 01070 * @return on success returns CaseNext to continue to next test case, otherwise will assert on errors. 01071 */ 01072 control_t fsfat_fopen_test_11(const size_t call_count) 01073 { 01074 int32_t ret = -1; 01075 size_t len = 0; 01076 fsfat_kv_data_t *node = fsfat_fopen_test_11_kv_data; 01077 01078 FSFAT_FENTRYLOG("%s:entered\n", __func__); 01079 (void) call_count; 01080 01081 TEST_ASSERT(strlen(node->filename) < FSFAT_FOPEN_TEST_WORK_BUF_SIZE_1); 01082 01083 /* start from a known state i.e. directory to be created in not present, files not present */ 01084 while (node->filename != NULL) { 01085 fsfat_filepath_remove_all((char *) node->filename); 01086 node++; 01087 } 01088 01089 /* create file and directories ready for rename() tests */ 01090 errno = 0; 01091 node = fsfat_fopen_test_11_kv_data; 01092 ret = fsfat_filepath_make_dirs((char *) node->filename, false); 01093 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 01094 "%s:Error: failed to create dir (dirname=%s, ret=%d, errno=%d)\n", __func__, node->filename, (int) ret, errno); 01095 TEST_ASSERT_MESSAGE(ret == 0, fsfat_fopen_utest_msg_g); 01096 01097 len = strlen(node->value); 01098 ret = fsfat_test_create(node->filename, (char *) node->value, len); 01099 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 01100 "%s:Error: failed to create file (ret=%d).\n", __func__, (int) ret); 01101 TEST_ASSERT_MESSAGE(ret >= 0, fsfat_fopen_utest_msg_g); 01102 01103 errno = 0; 01104 node = &fsfat_fopen_test_11_kv_data[2]; 01105 ret = fsfat_filepath_make_dirs((char *) node->filename, false); 01106 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 01107 "%s:Error: failed to create dir (dirname=%s, ret=%d, errno=%d)\n", __func__, node->filename, (int) ret, errno); 01108 TEST_ASSERT_MESSAGE(ret == 0, fsfat_fopen_utest_msg_g); 01109 01110 /* (1) */ 01111 ret = rename(fsfat_fopen_test_11_kv_data[0].filename, fsfat_fopen_test_11_kv_data[1].filename); 01112 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 01113 "%s:Error: unable to rename file from (%s) to (%s) (ret=%d, errno=%d).\n", __func__, 01114 fsfat_fopen_test_11_kv_data[0].filename, fsfat_fopen_test_11_kv_data[1].filename, (int) ret, errno); 01115 TEST_ASSERT_MESSAGE(ret == 0, fsfat_fopen_utest_msg_g); 01116 01117 /* (2) */ 01118 ret = rename(fsfat_fopen_test_11_kv_data[1].filename, fsfat_fopen_test_11_kv_data[2].filename); 01119 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 01120 "%s:Error: unable to rename file from (%s) to (%s) (ret=%d, errno=%d).\n", __func__, 01121 fsfat_fopen_test_11_kv_data[1].filename, fsfat_fopen_test_11_kv_data[2].filename, (int) ret, errno); 01122 TEST_ASSERT_MESSAGE(ret == 0, fsfat_fopen_utest_msg_g); 01123 01124 return CaseNext; 01125 } 01126 01127 01128 /* file data for test_12 */ 01129 static fsfat_kv_data_t fsfat_fopen_test_12_kv_data[] = { 01130 { "/sd/test_12/subdir/testfil1.txt", "testfil1.txt"}, 01131 { "/sd/test_12/testfil2.txt", "testfil2.txt"}, 01132 { "/sd/test_12/testfil3.txt", "testfil3.txt"}, 01133 { "/sd/test_12/testfil4.txt", "testfil4.txt"}, 01134 { "/sd/test_12/testfil5.txt", "testfil5.txt"}, 01135 { NULL, NULL}, 01136 }; 01137 01138 /** @brief test for operation of readdir(). 01139 * 01140 * Note, rewinddir(), telldir() and seekdir() dont appear to work reliably. 01141 * opendir() not available on ARM/IAR toolchains. 01142 * 01143 * @return on success returns CaseNext to continue to next test case, otherwise will assert on errors. 01144 */ 01145 control_t fsfat_fopen_test_12(const size_t call_count) 01146 { 01147 char buf[FSFAT_FOPEN_TEST_WORK_BUF_SIZE_1]; 01148 char *pos = NULL; 01149 int32_t count = 0; 01150 int32_t ret = -1; 01151 size_t len = 0; 01152 DIR *dir; 01153 struct dirent *dp; 01154 fsfat_kv_data_t *node = fsfat_fopen_test_12_kv_data; 01155 01156 FSFAT_FENTRYLOG("%s:entered\n", __func__); 01157 (void) call_count; 01158 01159 #if ! defined(__ARMCC_VERSION) && defined(__GNUC__) 01160 01161 /* start from a known state i.e. directory to be created in not present */ 01162 while (node->filename != NULL) { 01163 fsfat_filepath_remove_all((char *) node->filename); 01164 node++; 01165 } 01166 01167 /* create a file */ 01168 node = fsfat_fopen_test_12_kv_data; 01169 errno = 0; 01170 ret = fsfat_filepath_make_dirs((char *) node->filename, false); 01171 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 01172 "%s:Error: failed to create dir (dirname=%s, ret=%d, errno=%d)\n", __func__, node->filename, (int) ret, errno); 01173 TEST_ASSERT_MESSAGE(ret == 0, fsfat_fopen_utest_msg_g); 01174 01175 node = fsfat_fopen_test_12_kv_data; 01176 while (node->filename != NULL) { 01177 len = strlen(node->value); 01178 ret = fsfat_test_create(node->filename, (char *) node->value, len); 01179 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 01180 "%s:Error: failed to create file (ret=%d).\n", __func__, (int) ret); 01181 TEST_ASSERT_MESSAGE(ret >= 0, fsfat_fopen_utest_msg_g); 01182 node++; 01183 } 01184 01185 node = fsfat_fopen_test_12_kv_data; 01186 memset(buf, 0, FSFAT_FOPEN_TEST_WORK_BUF_SIZE_1); 01187 memcpy(buf, node->filename, strlen(node->filename)); 01188 pos = strrchr(buf, '/'); 01189 *pos = '\0'; 01190 dir = opendir(buf); 01191 01192 while ((dp = readdir(dir)) != NULL) { 01193 FSFAT_DBGLOG("%s: filename: \"%s\"\n", __func__, dp->d_name); 01194 TEST_ASSERT_MESSAGE(dp != 0, "Error: readdir() failed\n"); 01195 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 01196 "%s:Error: unexpected object name (name=%s, expected=%s).\n", __func__, dp->d_name, 01197 fsfat_fopen_test_12_kv_data[count].value); 01198 TEST_ASSERT_MESSAGE(strncmp(dp->d_name, fsfat_fopen_test_12_kv_data[count].value, 01199 strlen(fsfat_fopen_test_12_kv_data[count].value)) == 0, fsfat_fopen_utest_msg_g); 01200 count++; 01201 } 01202 closedir(dir); 01203 01204 /* cleanup */ 01205 node = fsfat_fopen_test_12_kv_data; 01206 while (node->filename != NULL) { 01207 fsfat_filepath_remove_all((char *) node->filename); 01208 node++; 01209 } 01210 #endif /* ! defined(__ARMCC_VERSION) && defined(__GNUC__) */ 01211 return CaseNext; 01212 } 01213 01214 01215 /* file data for test_13 */ 01216 static fsfat_kv_data_t fsfat_fopen_test_13_kv_data[] = { 01217 /* a file is included in the filepath even though its not created by the test, 01218 * as the fsfat_filepath_make_dirs() works with it present. */ 01219 { "/sd/test_13/dummy.txt", "testdir"}, 01220 { NULL, NULL}, 01221 }; 01222 /** @brief test for operation of mkdir()/remove() 01223 * 01224 * This test checks that: 01225 * - The mkdir() function successfully creates a directory that is not already present. 01226 * - The mkdir() function returns EEXIST when trying to create a directory thats already present. 01227 * - The remove() function successfully removes a directory that is present. 01228 * 01229 * @return on success returns CaseNext to continue to next test case, otherwise will assert on errors. 01230 */ 01231 control_t fsfat_fopen_test_13(const size_t call_count) 01232 { 01233 int32_t ret = 0; 01234 01235 FSFAT_DBGLOG("%s:entered\n", __func__); 01236 (void) call_count; 01237 01238 /* start from a known state i.e. directory to be created in not present */ 01239 fsfat_filepath_remove_all((char *) fsfat_fopen_test_13_kv_data[0].filename); 01240 01241 errno = 0; 01242 ret = fsfat_filepath_make_dirs((char *) fsfat_fopen_test_13_kv_data[0].filename, false); 01243 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 01244 "%s:Error: failed to create dir (dirname=%s, ret=%d, errno=%d)\n", __func__, fsfat_fopen_test_13_kv_data[0].filename, 01245 (int) ret, errno); 01246 TEST_ASSERT_MESSAGE(ret == 0, fsfat_fopen_utest_msg_g); 01247 01248 /* check that get a suitable error when try to create it again.*/ 01249 errno = 0; 01250 ret = fsfat_filepath_make_dirs((char *) fsfat_fopen_test_13_kv_data[0].filename, false); 01251 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 01252 "%s:Error: permitted to create directory when already exists (dirname=%s, ret=%d, errno=%d)\n", __func__, 01253 fsfat_fopen_test_13_kv_data[0].filename, (int) ret, errno); 01254 TEST_ASSERT_MESSAGE(ret != 0, fsfat_fopen_utest_msg_g); 01255 01256 /* check errno is as expected */ 01257 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 01258 "%s:Error: errno != EEXIST (dirname=%s, ret=%d, errno=%d)\n", __func__, fsfat_fopen_test_13_kv_data[0].filename, 01259 (int) ret, errno); 01260 TEST_ASSERT_MESSAGE(errno == EEXIST, fsfat_fopen_utest_msg_g); 01261 01262 ret = fsfat_filepath_remove_all((char *) fsfat_fopen_test_13_kv_data[0].filename); 01263 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 01264 "%s:Error: failed to remove directory (dirname=%s, ret=%d, errno=%d)\n", __func__, 01265 fsfat_fopen_test_13_kv_data[0].filename, (int) ret, errno); 01266 TEST_ASSERT_MESSAGE(ret == 0, fsfat_fopen_utest_msg_g); 01267 01268 return CaseNext; 01269 } 01270 01271 /* file data for test_14 */ 01272 static fsfat_kv_data_t fsfat_fopen_test_14_kv_data[] = { 01273 /* a file is included in the filepath even though its not created by the test, 01274 * as the fsfat_filepath_make_dirs() works with it present. */ 01275 { "/sd/test_14/testfile.txt", "testdata"}, 01276 { NULL, NULL}, 01277 }; 01278 01279 /** @brief test for operation of stat() 01280 * 01281 * stat() is currently no supported by ARMCC and IAR toolchains libc. 01282 * 01283 * @return on success returns CaseNext to continue to next test case, otherwise will assert on errors. 01284 */ 01285 control_t fsfat_fopen_test_14(const size_t call_count) 01286 { 01287 #if ! defined(__ARMCC_VERSION) && defined(__GNUC__) 01288 01289 char buf[FSFAT_FOPEN_TEST_WORK_BUF_SIZE_1]; 01290 char *pos = NULL; 01291 int32_t ret = -1; 01292 size_t len = 0; 01293 struct stat file_stat; 01294 fsfat_kv_data_t *node = fsfat_fopen_test_14_kv_data; 01295 01296 FSFAT_FENTRYLOG("%s:entered\n", __func__); 01297 (void) call_count; 01298 01299 TEST_ASSERT(strlen(node->filename) < FSFAT_FOPEN_TEST_WORK_BUF_SIZE_1); 01300 01301 /* start from a known state i.e. directory to be created in not present */ 01302 fsfat_filepath_remove_all((char *) node->filename); 01303 01304 /* Create file in a directory. */ 01305 errno = 0; 01306 ret = fsfat_filepath_make_dirs((char *) node->filename, false); 01307 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 01308 "%s:Error: failed to create dir (dirname=%s, ret=%d, errno=%d)\n", __func__, node->filename, (int) ret, errno); 01309 TEST_ASSERT_MESSAGE(ret == 0, fsfat_fopen_utest_msg_g); 01310 01311 len = strlen(node->value); 01312 ret = fsfat_test_create(node->filename, (char *) node->value, len); 01313 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 01314 "%s:Error: failed to create file (ret=%d).\n", __func__, (int) ret); 01315 TEST_ASSERT_MESSAGE(ret >= 0, fsfat_fopen_utest_msg_g); 01316 01317 /* Test stat() on the file returns the correct attribute set */ 01318 memset(&file_stat, 0, sizeof(file_stat)); 01319 ret = stat(node->filename, &file_stat); 01320 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 01321 "%s:Error: stat() operation on file failed (filename=%s, ret=%d, errno=%d).\n", __func__, node->filename, (int) ret, 01322 errno); 01323 TEST_ASSERT_MESSAGE(ret == 0, fsfat_fopen_utest_msg_g); 01324 01325 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 01326 "%s:Error: expected st_mode S_IFREG flag not set (filename=%s).\n", __func__, node->filename); 01327 TEST_ASSERT_MESSAGE((file_stat.st_mode & S_IFREG) == S_IFREG, fsfat_fopen_utest_msg_g); 01328 01329 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 01330 "%s:Error: unexpected st_mode S_IFDIR flag set (filename=%s).\n", __func__, node->filename); 01331 TEST_ASSERT_MESSAGE((file_stat.st_mode & S_IFDIR) != S_IFDIR, fsfat_fopen_utest_msg_g); 01332 01333 /* Test stat() on the directory returns the correct attribute set */ 01334 memset(&file_stat, 0, sizeof(file_stat)); 01335 memset(buf, 0, FSFAT_FOPEN_TEST_WORK_BUF_SIZE_1); 01336 memcpy(buf, node->filename, strlen(node->filename)); 01337 pos = strrchr(buf, '/'); 01338 *pos = '\0'; 01339 ret = stat(buf, &file_stat); 01340 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 01341 "%s:Error: stat() operation on directory failed (directory name=%s, ret=%d, errno=%d).\n", __func__, buf, (int) ret, 01342 errno); 01343 TEST_ASSERT_MESSAGE(ret == 0, fsfat_fopen_utest_msg_g); 01344 01345 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 01346 "%s:Error: unexpected st_mode S_IFREG flag set (directory name=%s).\n", __func__, buf); 01347 TEST_ASSERT_MESSAGE((file_stat.st_mode & S_IFREG) != S_IFREG, fsfat_fopen_utest_msg_g); 01348 01349 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 01350 "%s:Error: expected st_mode S_IFDIR flag not set (directory name=%s).\n", __func__, buf); 01351 TEST_ASSERT_MESSAGE((file_stat.st_mode & S_IFDIR) == S_IFDIR, fsfat_fopen_utest_msg_g); 01352 01353 /* clean up after successful test */ 01354 fsfat_filepath_remove_all((char *) node->filename); 01355 01356 #endif /* ! defined(__ARMCC_VERSION) && defined(__GNUC__) */ 01357 return CaseNext; 01358 } 01359 01360 /** @brief test for operation of SDFileSystem::format() 01361 * 01362 * @return on success returns CaseNext to continue to next test case, otherwise will assert on errors. 01363 */ 01364 control_t fsfat_fopen_test_15(const size_t call_count) 01365 { 01366 01367 FSFAT_FENTRYLOG("%s:entered\n", __func__); 01368 (void) call_count; 01369 int32_t ret = -1; 01370 01371 /* the allocation_unit of 0 means chanFS will use the default for the card (varies according to capacity). */ 01372 fs.unmount(); 01373 ret = fs.format(&sd); 01374 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 01375 "%s:Error: failed to format sdcard (ret=%d)\n", __func__, (int) ret); 01376 TEST_ASSERT_MESSAGE(ret == 0, fsfat_fopen_utest_msg_g); 01377 fs.mount(&sd); 01378 return CaseNext; 01379 } 01380 01381 01382 /* @brief test utility function to create a file of a given size. 01383 * 01384 * A reference data table is used of so that the data file can be later be 01385 * checked with fsfat_test_check_data_file(). 01386 * 01387 * @param filename name of the file including path 01388 * @param data data to store in file 01389 * @param len number of bytes of data present in the data buffer. 01390 */ 01391 int32_t fsfat_test_create_data_file(const char *filename, size_t len) 01392 { 01393 int32_t ret = -1; 01394 FILE *fp = NULL; 01395 size_t write_len = 0; 01396 size_t written_len = 0; 01397 int32_t exp = 0; 01398 const int32_t exp_max = 8; /* so as not to exceed FSFAT_TEST_BYTE_DATA_TABLE_SIZE/2 */ 01399 01400 FSFAT_FENTRYLOG("%s:entered (filename=%s, len=%d).\n", __func__, filename, (int) len); 01401 TEST_ASSERT(len % FSFAT_TEST_BYTE_DATA_TABLE_SIZE == 0); 01402 fp = fopen(filename, "a"); 01403 if (fp == NULL) { 01404 return ret; 01405 } 01406 01407 while (written_len < len) { 01408 /* write fsfat_test_byte_data_table or part thereof, in 9 writes of sizes 01409 * 1, 2, 4, 8, 16, 32, 64, 128, 1, totalling 256 bytes len permitting. */ 01410 for (exp = 0; (exp <= exp_max) && (written_len < len); exp++) { 01411 write_len = 0x1 << (exp % exp_max); 01412 write_len = len - written_len > write_len ? write_len : len - written_len; 01413 ret = fwrite((const void *) &fsfat_test_byte_data_table[written_len % FSFAT_TEST_BYTE_DATA_TABLE_SIZE], write_len, 1, 01414 fp); 01415 written_len += write_len; 01416 if (ret != 1) { 01417 FSFAT_DBGLOG("%s:Error: fwrite() failed (ret=%d)\n", __func__, (int) ret); 01418 ret = -1; 01419 goto out0; 01420 } 01421 } 01422 } 01423 if (written_len == len) { 01424 ret = 0; 01425 } else { 01426 ret = -1; 01427 } 01428 out0: 01429 fclose(fp); 01430 return ret; 01431 } 01432 01433 01434 /* @brief test utility function to check the data in the specified file is correct. 01435 * 01436 * The data read from the file is check that it agrees with the data written by 01437 * fsfat_test_create_data_file(). 01438 * 01439 * @param filename name of the file including path 01440 * @param data data to store in file 01441 * @param len number of bytes of data present in the data buffer. 01442 */ 01443 int32_t fsfat_test_check_data_file(const char *filename, size_t len) 01444 { 01445 int32_t ret = -1; 01446 FILE *fp = NULL; 01447 size_t read_len = 0; 01448 uint8_t buf[FSFAT_TEST_BYTE_DATA_TABLE_SIZE]; 01449 01450 FSFAT_FENTRYLOG("%s:entered (filename=%s, len=%d).\n", __func__, filename, (int) len); 01451 TEST_ASSERT(len % FSFAT_TEST_BYTE_DATA_TABLE_SIZE == 0); 01452 fp = fopen(filename, "r"); 01453 if (fp == NULL) { 01454 return ret; 01455 } 01456 01457 while (read_len < len) { 01458 ret = fread((void *) buf, FSFAT_TEST_BYTE_DATA_TABLE_SIZE, 1, fp); 01459 read_len += FSFAT_TEST_BYTE_DATA_TABLE_SIZE; 01460 if (ret == 0) { 01461 /* end of read*/ 01462 FSFAT_DBGLOG("%s:unable to read data\n", __func__); 01463 break; 01464 } 01465 if (memcmp(buf, fsfat_test_byte_data_table, FSFAT_TEST_BYTE_DATA_TABLE_SIZE) != 0) { 01466 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", 01467 __func__, 01468 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], 01469 buf[14], buf[15]); 01470 ret = -1; 01471 goto out0; 01472 } 01473 } 01474 if (read_len == len) { 01475 ret = 0; 01476 } 01477 out0: 01478 fclose(fp); 01479 return ret; 01480 } 01481 01482 /* file data for test_16 */ 01483 static fsfat_kv_data_t fsfat_fopen_test_16_kv_data[] = { 01484 { "/sd/tst16_0/testfil0.txt", "dummy_data"}, 01485 { "/sd/tst16_1/subdir0/testfil0.txt", "dummy_data"}, 01486 { "/sd/tst16_2/subdir0/subdir1/testfil0.txt", "dummy_data"}, 01487 { "/sd/tst16_3/subdir0/subdir1/subdir2/subdir3/testfil0.txt", "dummy_data"}, 01488 { "/sd/tst16_4/subdir0/subdir1/subdir2/subdir3/subdir4/testfil0.txt", "dummy_data"}, 01489 { "/sd/tst16_5/subdir0/subdir1/subdir2/subdir3/subdir4/subdir5/testfil0.txt", "dummy_data"}, 01490 { "/sd/tst16_6/subdir0/subdir1/subdir2/subdir3/subdir4/subdir5/subdir6/testfil0.txt", "dummy_data"}, 01491 { "/sd/tst16_7/subdir0/subdir1/subdir2/subdir3/subdir4/subdir5/subdir6/subdir7/testfil0.txt", "dummy_data"}, 01492 { "/sd/tst16_8/subdir0/subdir1/subdir2/subdir3/subdir4/subdir5/subdir6/subdir7/subdir8/testfil0.txt", "dummy_data"}, 01493 { "/sd/tst16_9/subdir0/subdir1/subdir2/subdir3/subdir4/subdir5/subdir6/subdir7/subdir8/subdir9/testfil0.txt", "dummy_data"}, 01494 { NULL, NULL}, 01495 }; 01496 01497 01498 /** @brief stress test to write data to fs 01499 * 01500 * @return on success returns CaseNext to continue to next test case, otherwise will assert on errors. 01501 */ 01502 control_t fsfat_fopen_test_16(const size_t call_count) 01503 { 01504 int32_t ret = 0; 01505 fsfat_kv_data_t *node = fsfat_fopen_test_16_kv_data; 01506 const int32_t num_blocks = 100; /* each file ~25kB */ 01507 01508 FSFAT_DBGLOG("%s:entered\n", __func__); 01509 (void) call_count; 01510 01511 /* remove file and directory from a previous failed test run, if present */ 01512 while (node->filename != NULL) { 01513 fsfat_filepath_remove_all((char *) node->filename); 01514 node++; 01515 } 01516 01517 /* create dirs */ 01518 node = fsfat_fopen_test_16_kv_data; 01519 while (node->filename != NULL) { 01520 ret = fsfat_filepath_make_dirs((char *) node->filename, true); 01521 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 01522 "%s:Error: failed to create dirs for filename (filename=\"%s\")(ret=%d)\n", __func__, node->filename, (int) ret); 01523 TEST_ASSERT_MESSAGE(ret == 0, fsfat_fopen_utest_msg_g); 01524 node++; 01525 } 01526 01527 /* create the data files */ 01528 node = fsfat_fopen_test_16_kv_data; 01529 while (node->filename != NULL) { 01530 ret = fsfat_test_create_data_file(node->filename, num_blocks * FSFAT_TEST_BYTE_DATA_TABLE_SIZE); 01531 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 01532 "%s:Error: failed to create data file (filename=\"%s\")(ret=%d)\n", __func__, node->filename, (int) ret); 01533 TEST_ASSERT_MESSAGE(ret == 0, fsfat_fopen_utest_msg_g); 01534 node++; 01535 } 01536 01537 /* read the data back and check its as expected */ 01538 node = fsfat_fopen_test_16_kv_data; 01539 while (node->filename != NULL) { 01540 ret = fsfat_test_check_data_file(node->filename, num_blocks * FSFAT_TEST_BYTE_DATA_TABLE_SIZE); 01541 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, 01542 "%s:Error: failed to check data file (filename=\"%s\")(ret=%d)\n", __func__, node->filename, (int) ret); 01543 TEST_ASSERT_MESSAGE(ret == 0, fsfat_fopen_utest_msg_g); 01544 node++; 01545 } 01546 01547 /* clean up */ 01548 node = fsfat_fopen_test_16_kv_data; 01549 while (node->filename != NULL) { 01550 fsfat_filepath_remove_all((char *) node->filename); 01551 node++; 01552 } 01553 return CaseNext; 01554 } 01555 01556 01557 #else 01558 01559 #define FSFAT_FOPEN_TEST_00 fsfat_fopen_test_dummy 01560 #define FSFAT_FOPEN_TEST_01 fsfat_fopen_test_dummy 01561 #define FSFAT_FOPEN_TEST_02 fsfat_fopen_test_dummy 01562 #define FSFAT_FOPEN_TEST_03 fsfat_fopen_test_dummy 01563 #define FSFAT_FOPEN_TEST_04 fsfat_fopen_test_dummy 01564 #define FSFAT_FOPEN_TEST_05 fsfat_fopen_test_dummy 01565 #define FSFAT_FOPEN_TEST_06 fsfat_fopen_test_dummy 01566 #define FSFAT_FOPEN_TEST_07 fsfat_fopen_test_dummy 01567 #define FSFAT_FOPEN_TEST_08 fsfat_fopen_test_dummy 01568 #define FSFAT_FOPEN_TEST_09 fsfat_fopen_test_dummy 01569 #define FSFAT_FOPEN_TEST_10 fsfat_fopen_test_dummy 01570 #define FSFAT_FOPEN_TEST_11 fsfat_fopen_test_dummy 01571 #define FSFAT_FOPEN_TEST_12 fsfat_fopen_test_dummy 01572 #define FSFAT_FOPEN_TEST_13 fsfat_fopen_test_dummy 01573 #define FSFAT_FOPEN_TEST_14 fsfat_fopen_test_dummy 01574 #define FSFAT_FOPEN_TEST_15 fsfat_fopen_test_dummy 01575 #define FSFAT_FOPEN_TEST_16 fsfat_fopen_test_dummy 01576 #define FSFAT_FOPEN_TEST_17 fsfat_fopen_test_dummy 01577 #define FSFAT_FOPEN_TEST_18 fsfat_fopen_test_dummy 01578 #define FSFAT_FOPEN_TEST_19 fsfat_fopen_test_dummy 01579 #define FSFAT_FOPEN_TEST_20 fsfat_fopen_test_dummy 01580 #define FSFAT_FOPEN_TEST_21 fsfat_fopen_test_dummy 01581 #define FSFAT_FOPEN_TEST_22 fsfat_fopen_test_dummy 01582 #define FSFAT_FOPEN_TEST_23 fsfat_fopen_test_dummy 01583 #define FSFAT_FOPEN_TEST_24 fsfat_fopen_test_dummy 01584 #define FSFAT_FOPEN_TEST_25 fsfat_fopen_test_dummy 01585 #define FSFAT_FOPEN_TEST_26 fsfat_fopen_test_dummy 01586 #define FSFAT_FOPEN_TEST_27 fsfat_fopen_test_dummy 01587 #define FSFAT_FOPEN_TEST_28 fsfat_fopen_test_dummy 01588 #define FSFAT_FOPEN_TEST_29 fsfat_fopen_test_dummy 01589 #define FSFAT_FOPEN_TEST_30 fsfat_fopen_test_dummy 01590 01591 /** @brief fsfat_fopen_test_dummy Dummy test case for testing when platform doesnt have an SDCard installed. 01592 * 01593 * @return success always 01594 */ 01595 static control_t fsfat_fopen_test_dummy() 01596 { 01597 printf("Null test\n"); 01598 return CaseNext; 01599 } 01600 01601 #endif 01602 01603 01604 /// @cond FSFAT_DOXYGEN_DISABLE 01605 utest::v1::status_t greentea_setup(const size_t number_of_cases) 01606 { 01607 GREENTEA_SETUP(FSFAT_FOPEN_GREENTEA_TIMEOUT_S, "default_auto"); 01608 return greentea_test_setup_handler(number_of_cases); 01609 } 01610 01611 Case cases[] = { 01612 /* 1 2 3 4 5 6 7 */ 01613 /* 1234567890123456789012345678901234567890123456789012345678901234567890 */ 01614 Case("FSFAT_FOPEN_TEST_00: format sd card to FAT FS.", FSFAT_FOPEN_TEST_00), 01615 Case("FSFAT_FOPEN_TEST_01: fopen()/fwrite()/fclose() directories/file in multi-dir filepath.", FSFAT_FOPEN_TEST_01), 01616 Case("FSFAT_FOPEN_TEST_02: fopen(r) pre-existing file try to write it.", FSFAT_FOPEN_TEST_02), 01617 Case("FSFAT_FOPEN_TEST_03: fopen(w+) pre-existing file try to write it.", FSFAT_FOPEN_TEST_03), 01618 Case("FSFAT_FOPEN_TEST_04: fopen() with a filename exceeding the maximum length.", FSFAT_FOPEN_TEST_04), 01619 #ifdef FOPEN_EXTENDED_TESTING 01620 Case("FSFAT_FOPEN_TEST_05: fopen() with bad filenames (extended).", FSFAT_FOPEN_TEST_05), 01621 #endif 01622 Case("FSFAT_FOPEN_TEST_06: fopen() with bad filenames (minimal).", FSFAT_FOPEN_TEST_06), 01623 Case("FSFAT_FOPEN_TEST_07: fopen()/errno handling.", FSFAT_FOPEN_TEST_07), 01624 Case("FSFAT_FOPEN_TEST_08: ferror()/clearerr()/errno handling.", FSFAT_FOPEN_TEST_08), 01625 Case("FSFAT_FOPEN_TEST_09: ftell() handling.", FSFAT_FOPEN_TEST_09), 01626 Case("FSFAT_FOPEN_TEST_10: remove() test.", FSFAT_FOPEN_TEST_10), 01627 Case("FSFAT_FOPEN_TEST_11: rename().", FSFAT_FOPEN_TEST_11), 01628 Case("FSFAT_FOPEN_TEST_12: opendir(), readdir(), closedir() test.", FSFAT_FOPEN_TEST_12), 01629 Case("FSFAT_FOPEN_TEST_13: mkdir() test.", FSFAT_FOPEN_TEST_13), 01630 Case("FSFAT_FOPEN_TEST_14: stat() test.", FSFAT_FOPEN_TEST_14), 01631 Case("FSFAT_FOPEN_TEST_15: format() test.", FSFAT_FOPEN_TEST_15), 01632 Case("FSFAT_FOPEN_TEST_16: write/check n x 25kB data files.", FSFAT_FOPEN_TEST_16), 01633 }; 01634 01635 01636 /* Declare your test specification with a custom setup handler */ 01637 Specification specification(greentea_setup, cases); 01638 01639 int main() 01640 { 01641 return !Harness::run(specification); 01642 } 01643 /// @endcond
Generated on Sun Jul 17 2022 03:41:56 by
1.7.2