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