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