SEND
Fork of Final351CW_FINAL by
Embed:
(wiki syntax)
Show/hide line numbers
fopen.cpp
Go to the documentation of this file.
00001 /* 00002 * mbed Microcontroller Library 00003 * Copyright (c) 2006-2016 ARM Limited 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); 00006 * you may not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 00018 /** @file fopen.cpp Test cases to POSIX file fopen() interface. 00019 * 00020 * Please consult the documentation under the test-case functions for 00021 * a description of the individual test case. 00022 */ 00023 00024 #include "mbed.h" 00025 #include "mbed_config.h" 00026 #include "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_SD_SPI_MOSI, MBED_CONF_SD_SPI_MISO, MBED_CONF_SD_SPI_CLK, MBED_CONF_SD_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 #endif /* ! defined(__ARMCC_VERSION) && defined(__GNUC__) */ 00779 return CaseNext; 00780 } 00781 00782 00783 /** @brief test for operation of clearerr() and ferror() 00784 * 00785 * The test does the following: 00786 * - opens and then closes a file, but keeps a copy of the FILE pointer fp. 00787 * - set errno to 0. 00788 * - write to the close file with fwrite(fp) which should return 0 (no writes) and set the errno. 00789 * - check the error condition is set with ferror(). 00790 * - clear the error with clearerr(). 00791 * - check the error condition is reset with ferror(). 00792 * 00793 * NOTE_1: GCC/ARMCC support for setting errno 00794 * - Documentation (e.g. fwrite() man page) does not explicity say fwrite() sets errno 00795 * (e.g. for an fwrite() on a read-only file). 00796 * - GCC libc fwrite() appears to set errno as expected. 00797 * - ARMCC & IAR libc fwrite() appears not to set errno. 00798 * 00799 * The following ARMCC documents are silent on whether fwrite() sets errno: 00800 * - "ARM C and C++ Libraries and Floating-Point Support". 00801 * - "RL-ARM User Guide fwrite() section". 00802 * 00803 * @return on success returns CaseNext to continue to next test case, otherwise will assert on errors. 00804 */ 00805 control_t fsfat_fopen_test_08(const size_t call_count) 00806 { 00807 FILE *fp = NULL; 00808 int ret = -1; 00809 int ret_ferror = -1; 00810 const char *filename = sd_testfile_path; 00811 00812 FSFAT_FENTRYLOG("%s:entered\n", __func__); 00813 (void) call_count; 00814 00815 errno = 0; 00816 fp = fopen(filename,"w+"); 00817 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); 00818 TEST_ASSERT_MESSAGE(fp != NULL, fsfat_fopen_utest_msg_g); 00819 00820 /* close the fp but then try to read or write it */ 00821 ret = fclose(fp); 00822 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); 00823 TEST_ASSERT_MESSAGE(ret == 0, fsfat_fopen_utest_msg_g); 00824 00825 /* open file */ 00826 errno = 0; 00827 fp = fopen(filename, "r"); 00828 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); 00829 TEST_ASSERT_MESSAGE(fp != NULL, fsfat_fopen_utest_msg_g); 00830 00831 /* Perform fwrite() operation that will fail. */ 00832 errno = 0; 00833 ret = fwrite("42!", 4, 1, fp); 00834 00835 ret_ferror = ferror(fp); 00836 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); 00837 TEST_ASSERT_MESSAGE(ret_ferror != 0, fsfat_fopen_utest_msg_g); 00838 00839 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); 00840 /* the fwrite() should fail and return 0. */ 00841 TEST_ASSERT_MESSAGE(ret == 0, fsfat_fopen_utest_msg_g); 00842 00843 #if ! defined(__ARMCC_VERSION) && defined(__GNUC__) 00844 /* check that errno is set. ARMCC appears not to set errno for fwrite() failure. */ 00845 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); 00846 TEST_ASSERT_MESSAGE(errno != 0, fsfat_fopen_utest_msg_g); 00847 00848 /* check that errno is set to the expected value (this may change differ for different libc's) */ 00849 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); 00850 TEST_ASSERT_MESSAGE(errno == EBADF, fsfat_fopen_utest_msg_g); 00851 #endif /* ! defined(__ARMCC_VERSION) && defined(__GNUC__) */ 00852 00853 /* check clearerr() return clears the error */ 00854 clearerr(fp); 00855 ret = ferror(fp); 00856 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); 00857 TEST_ASSERT_MESSAGE(ret == 0, fsfat_fopen_utest_msg_g); 00858 00859 fclose(fp); 00860 return CaseNext; 00861 } 00862 00863 00864 /** @brief test for operation of ftell() 00865 * 00866 * @return on success returns CaseNext to continue to next test case, otherwise will assert on errors. 00867 */ 00868 control_t fsfat_fopen_test_09(const size_t call_count) 00869 { 00870 FILE *fp = NULL; 00871 int ret = -1; 00872 int32_t len = 0; 00873 00874 FSFAT_FENTRYLOG("%s:entered\n", __func__); 00875 (void) call_count; 00876 00877 /* create a file of a certain length */ 00878 len = strlen(fsfat_fopen_test_02_data[0].value); 00879 ret = fsfat_test_create(fsfat_fopen_test_02_data[0].filename, (char*) fsfat_fopen_test_02_data[0].value, len); 00880 00881 errno = 0; 00882 /* Open the file for reading so the file is not truncated to 0 length. */ 00883 fp = fopen(fsfat_fopen_test_02_data[0].filename, "r"); 00884 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); 00885 TEST_ASSERT_MESSAGE(fp != NULL, fsfat_fopen_utest_msg_g); 00886 00887 errno = 0; 00888 ret = fseek(fp, 0, SEEK_END); 00889 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); 00890 TEST_ASSERT_MESSAGE(ret == 0, fsfat_fopen_utest_msg_g); 00891 00892 errno = 0; 00893 ret = ftell(fp); 00894 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); 00895 TEST_ASSERT_MESSAGE(ret == len, fsfat_fopen_utest_msg_g); 00896 00897 errno = 0; 00898 ret = fclose(fp); 00899 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); 00900 TEST_ASSERT_MESSAGE(ret == 0, fsfat_fopen_utest_msg_g); 00901 00902 return CaseNext; 00903 } 00904 00905 00906 /* file data for test_10 */ 00907 static fsfat_kv_data_t fsfat_fopen_test_10_kv_data[] = { 00908 { "/sd/test_10/testfile.txt", "test_data"}, 00909 { NULL, NULL}, 00910 }; 00911 00912 /** @brief test for operation of remove() 00913 * 00914 * Performs the following tests: 00915 * 1. test remove() on a file that exists. This should succeed. 00916 * 2. test remove() on a dir that exists. This should succeed. 00917 * 3. test remove() on a file that doesnt exist. This should fail. check errno set. 00918 * 4. test remove() on a dir that doesnt exist. This should fail. check errno set. 00919 * 00920 * @return on success returns CaseNext to continue to next test case, otherwise will assert on errors. 00921 */ 00922 control_t fsfat_fopen_test_10(const size_t call_count) 00923 { 00924 char buf[FSFAT_FOPEN_TEST_WORK_BUF_SIZE_1]; 00925 char *pos = NULL; 00926 int32_t ret = -1; 00927 size_t len = 0; 00928 fsfat_kv_data_t *node = fsfat_fopen_test_10_kv_data; 00929 00930 FSFAT_FENTRYLOG("%s:entered\n", __func__); 00931 (void) call_count; 00932 00933 TEST_ASSERT(strlen(node->filename) < FSFAT_FOPEN_TEST_WORK_BUF_SIZE_1); 00934 00935 /* start from a known state i.e. directory to be created in not present */ 00936 fsfat_filepath_remove_all((char*) node->filename); 00937 00938 /* (1) */ 00939 errno = 0; 00940 ret = fsfat_filepath_make_dirs((char*) node->filename, false); 00941 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); 00942 TEST_ASSERT_MESSAGE(ret == 0, fsfat_fopen_utest_msg_g); 00943 00944 len = strlen(node->value); 00945 ret = fsfat_test_create(node->filename, (char*) node->value, len); 00946 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); 00947 TEST_ASSERT_MESSAGE(ret >= 0, fsfat_fopen_utest_msg_g); 00948 00949 ret = remove(node->filename); 00950 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); 00951 TEST_ASSERT_MESSAGE(ret == 0, fsfat_fopen_utest_msg_g); 00952 00953 /* (3) */ 00954 ret = remove(node->filename); 00955 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); 00956 TEST_ASSERT_MESSAGE(ret != 0, fsfat_fopen_utest_msg_g); 00957 00958 /* (2) */ 00959 memset(buf, 0, FSFAT_FOPEN_TEST_WORK_BUF_SIZE_1); 00960 memcpy(buf, node->filename, strlen(node->filename)); 00961 pos = strrchr(buf, '/'); 00962 *pos = '\0'; 00963 ret = remove(buf); 00964 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); 00965 TEST_ASSERT_MESSAGE(ret == 0, fsfat_fopen_utest_msg_g); 00966 00967 /* (4) */ 00968 ret = remove(buf); 00969 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); 00970 TEST_ASSERT_MESSAGE(ret != 0, fsfat_fopen_utest_msg_g); 00971 00972 return CaseNext; 00973 } 00974 00975 00976 /* file data for test_11 */ 00977 static fsfat_kv_data_t fsfat_fopen_test_11_kv_data[] = { 00978 { "/sd/test_11/step0.txt", "test_data"}, 00979 { "/sd/test_11/step1.txt", "test_data"}, 00980 { "/sd/test_11/subdir/step3.txt", "test_data"}, 00981 { NULL, NULL}, 00982 }; 00983 00984 /** @brief test for operation of rename() 00985 * 00986 * This test does the following: 00987 * 1) test rename() on a file that exists to a new filename within the same directory. 00988 * 2) test rename() on a file that exists to a new filename within a different directory. 00989 * 00990 * @return on success returns CaseNext to continue to next test case, otherwise will assert on errors. 00991 */ 00992 control_t fsfat_fopen_test_11(const size_t call_count) 00993 { 00994 int32_t ret = -1; 00995 size_t len = 0; 00996 fsfat_kv_data_t *node = fsfat_fopen_test_11_kv_data; 00997 00998 FSFAT_FENTRYLOG("%s:entered\n", __func__); 00999 (void) call_count; 01000 01001 TEST_ASSERT(strlen(node->filename) < FSFAT_FOPEN_TEST_WORK_BUF_SIZE_1); 01002 01003 /* start from a known state i.e. directory to be created in not present, files not present */ 01004 while(node->filename != NULL) { 01005 fsfat_filepath_remove_all((char*) node->filename); 01006 node++; 01007 } 01008 01009 /* create file and directories ready for rename() tests */ 01010 errno = 0; 01011 node = fsfat_fopen_test_11_kv_data; 01012 ret = fsfat_filepath_make_dirs((char*) node->filename, false); 01013 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); 01014 TEST_ASSERT_MESSAGE(ret == 0, fsfat_fopen_utest_msg_g); 01015 01016 len = strlen(node->value); 01017 ret = fsfat_test_create(node->filename, (char*) node->value, len); 01018 FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, "%s:Error: failed to create file (ret=%d).\n", __func__, (int) ret); 01019 TEST_ASSERT_MESSAGE(ret >= 0, fsfat_fopen_utest_msg_g); 01020 01021 errno = 0; 01022 node = &fsfat_fopen_test_11_kv_data[2]; 01023 ret = fsfat_filepath_make_dirs((char*) node->filename, false); 01024 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); 01025 TEST_ASSERT_MESSAGE(ret == 0, fsfat_fopen_utest_msg_g); 01026 01027 /* (1) */ 01028 ret = rename(fsfat_fopen_test_11_kv_data[0].filename, fsfat_fopen_test_11_kv_data[1].filename); 01029 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); 01030 TEST_ASSERT_MESSAGE(ret == 0, fsfat_fopen_utest_msg_g); 01031 01032 /* (2) */ 01033 ret = rename(fsfat_fopen_test_11_kv_data[1].filename, fsfat_fopen_test_11_kv_data[2].filename); 01034 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); 01035 TEST_ASSERT_MESSAGE(ret == 0, fsfat_fopen_utest_msg_g); 01036 01037 return CaseNext; 01038 } 01039 01040 01041 /* file data for test_12 */ 01042 static fsfat_kv_data_t fsfat_fopen_test_12_kv_data[] = { 01043 { "/sd/test_12/subdir/testfil1.txt", "testfil1.txt"}, 01044 { "/sd/test_12/testfil2.txt", "testfil2.txt"}, 01045 { "/sd/test_12/testfil3.txt", "testfil3.txt"}, 01046 { "/sd/test_12/testfil4.txt", "testfil4.txt"}, 01047 { "/sd/test_12/testfil5.txt", "testfil5.txt"}, 01048 { NULL, NULL}, 01049 }; 01050 01051 /** @brief test for operation of readdir(). 01052 * 01053 * Note, rewinddir(), telldir() and seekdir() dont appear to work reliably. 01054 * opendir() not available on ARM/IAR toolchains. 01055 * 01056 * @return on success returns CaseNext to continue to next test case, otherwise will assert on errors. 01057 */ 01058 control_t fsfat_fopen_test_12(const size_t call_count) 01059 { 01060 char buf[FSFAT_FOPEN_TEST_WORK_BUF_SIZE_1]; 01061 char *pos = NULL; 01062 int32_t count = 0; 01063 int32_t ret = -1; 01064 size_t len = 0; 01065 DIR *dir; 01066 struct dirent *dp; 01067 fsfat_kv_data_t *node = fsfat_fopen_test_12_kv_data; 01068 01069 FSFAT_FENTRYLOG("%s:entered\n", __func__); 01070 (void) call_count; 01071 01072 #if ! defined(__ARMCC_VERSION) && defined(__GNUC__) 01073 01074 /* start from a known state i.e. directory to be created in not present */ 01075 while(node->filename != NULL) { 01076 fsfat_filepath_remove_all((char*) node->filename); 01077 node++; 01078 } 01079 01080 /* create a file */ 01081 node = fsfat_fopen_test_12_kv_data; 01082 errno = 0; 01083 ret = fsfat_filepath_make_dirs((char*) node->filename, false); 01084 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); 01085 TEST_ASSERT_MESSAGE(ret == 0, fsfat_fopen_utest_msg_g); 01086 01087 node = fsfat_fopen_test_12_kv_data; 01088 while(node->filename != NULL) { 01089 len = strlen(node->value); 01090 ret = fsfat_test_create(node->filename, (char*) node->value, len); 01091 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); 01092 TEST_ASSERT_MESSAGE(ret >= 0, fsfat_fopen_utest_msg_g); 01093 node++; 01094 } 01095 01096 node = fsfat_fopen_test_12_kv_data; 01097 memset(buf, 0, FSFAT_FOPEN_TEST_WORK_BUF_SIZE_1); 01098 memcpy(buf, node->filename, strlen(node->filename)); 01099 pos = strrchr(buf, '/'); 01100 *pos = '\0'; 01101 dir = opendir(buf); 01102 01103 dp = readdir(dir); 01104 TEST_ASSERT_MESSAGE(dp != 0, "Error: readdir() failed\n"); 01105 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, "."); 01106 TEST_ASSERT_MESSAGE(strncmp(dp->d_name, ".", strlen(".")) == 0, fsfat_fopen_utest_msg_g); 01107 dp = readdir(dir); 01108 TEST_ASSERT_MESSAGE(dp != 0, "Error: readdir() failed\n"); 01109 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, ".."); 01110 TEST_ASSERT_MESSAGE(strncmp(dp->d_name, "..", strlen("..")) == 0, fsfat_fopen_utest_msg_g); 01111 01112 while ((dp = readdir(dir)) != NULL) { 01113 FSFAT_DBGLOG("%s: filename: \"%s\"\n", __func__, dp->d_name); 01114 TEST_ASSERT_MESSAGE(dp != 0, "Error: readdir() failed\n"); 01115 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); 01116 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); 01117 count++; 01118 } 01119 closedir(dir); 01120 01121 /* cleanup */ 01122 node = fsfat_fopen_test_12_kv_data; 01123 while(node->filename != NULL) { 01124 fsfat_filepath_remove_all((char*) node->filename); 01125 node++; 01126 } 01127 #endif /* ! defined(__ARMCC_VERSION) && defined(__GNUC__) */ 01128 return CaseNext; 01129 } 01130 01131 01132 /* file data for test_13 */ 01133 static fsfat_kv_data_t fsfat_fopen_test_13_kv_data[] = { 01134 /* a file is included in the filepath even though its not created by the test, 01135 * as the fsfat_filepath_make_dirs() works with it present. */ 01136 { "/sd/test_13/dummy.txt", "testdir"}, 01137 { NULL, NULL}, 01138 }; 01139 /** @brief test for operation of mkdir()/remove() 01140 * 01141 * This test checks that: 01142 * - The mkdir() function successfully creates a directory that is not already present. 01143 * - The mkdir() function returns EEXIST when trying to create a directory thats already present. 01144 * - The remove() function successfully removes a directory that is present. 01145 * 01146 * @return on success returns CaseNext to continue to next test case, otherwise will assert on errors. 01147 */ 01148 control_t fsfat_fopen_test_13(const size_t call_count) 01149 { 01150 int32_t ret = 0; 01151 01152 FSFAT_DBGLOG("%s:entered\n", __func__); 01153 (void) call_count; 01154 01155 /* start from a known state i.e. directory to be created in not present */ 01156 fsfat_filepath_remove_all((char*) fsfat_fopen_test_13_kv_data[0].filename); 01157 01158 errno = 0; 01159 ret = fsfat_filepath_make_dirs((char*) fsfat_fopen_test_13_kv_data[0].filename, false); 01160 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); 01161 TEST_ASSERT_MESSAGE(ret == 0, fsfat_fopen_utest_msg_g); 01162 01163 /* check that get a suitable error when try to create it again.*/ 01164 errno = 0; 01165 ret = fsfat_filepath_make_dirs((char*) fsfat_fopen_test_13_kv_data[0].filename, false); 01166 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); 01167 TEST_ASSERT_MESSAGE(ret != 0, fsfat_fopen_utest_msg_g); 01168 01169 /* check errno is as expected */ 01170 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); 01171 TEST_ASSERT_MESSAGE(errno == EEXIST, fsfat_fopen_utest_msg_g); 01172 01173 ret = fsfat_filepath_remove_all((char*) fsfat_fopen_test_13_kv_data[0].filename); 01174 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); 01175 TEST_ASSERT_MESSAGE(ret == 0, fsfat_fopen_utest_msg_g); 01176 01177 return CaseNext; 01178 } 01179 01180 /* file data for test_14 */ 01181 static fsfat_kv_data_t fsfat_fopen_test_14_kv_data[] = { 01182 /* a file is included in the filepath even though its not created by the test, 01183 * as the fsfat_filepath_make_dirs() works with it present. */ 01184 { "/sd/test_14/testfile.txt", "testdata"}, 01185 { NULL, NULL}, 01186 }; 01187 01188 /** @brief test for operation of stat() 01189 * 01190 * stat() is currently no supported by ARMCC and IAR toolchains libc. 01191 * 01192 * @return on success returns CaseNext to continue to next test case, otherwise will assert on errors. 01193 */ 01194 control_t fsfat_fopen_test_14(const size_t call_count) 01195 { 01196 #if ! defined(__ARMCC_VERSION) && defined(__GNUC__) 01197 01198 char buf[FSFAT_FOPEN_TEST_WORK_BUF_SIZE_1]; 01199 char *pos = NULL; 01200 int32_t ret = -1; 01201 size_t len = 0; 01202 struct stat file_stat; 01203 fsfat_kv_data_t *node = fsfat_fopen_test_14_kv_data; 01204 01205 FSFAT_FENTRYLOG("%s:entered\n", __func__); 01206 (void) call_count; 01207 01208 TEST_ASSERT(strlen(node->filename) < FSFAT_FOPEN_TEST_WORK_BUF_SIZE_1); 01209 01210 /* start from a known state i.e. directory to be created in not present */ 01211 fsfat_filepath_remove_all((char*) node->filename); 01212 01213 /* Create file in a directory. */ 01214 errno = 0; 01215 ret = fsfat_filepath_make_dirs((char*) node->filename, false); 01216 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); 01217 TEST_ASSERT_MESSAGE(ret == 0, fsfat_fopen_utest_msg_g); 01218 01219 len = strlen(node->value); 01220 ret = fsfat_test_create(node->filename, (char*) node->value, len); 01221 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); 01222 TEST_ASSERT_MESSAGE(ret >= 0, fsfat_fopen_utest_msg_g); 01223 01224 /* Test stat() on the file returns the correct attribute set */ 01225 memset(&file_stat, 0, sizeof(file_stat)); 01226 ret = stat(node->filename, &file_stat); 01227 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); 01228 TEST_ASSERT_MESSAGE(ret == 0, fsfat_fopen_utest_msg_g); 01229 01230 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); 01231 TEST_ASSERT_MESSAGE((file_stat.st_mode & S_IFREG) == S_IFREG, fsfat_fopen_utest_msg_g); 01232 01233 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); 01234 TEST_ASSERT_MESSAGE((file_stat.st_mode & S_IFDIR) != S_IFDIR, fsfat_fopen_utest_msg_g); 01235 01236 /* Test stat() on the directory returns the correct attribute set */ 01237 memset(&file_stat, 0, sizeof(file_stat)); 01238 memset(buf, 0, FSFAT_FOPEN_TEST_WORK_BUF_SIZE_1); 01239 memcpy(buf, node->filename, strlen(node->filename)); 01240 pos = strrchr(buf, '/'); 01241 *pos = '\0'; 01242 ret = stat(buf, &file_stat); 01243 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); 01244 TEST_ASSERT_MESSAGE(ret == 0, fsfat_fopen_utest_msg_g); 01245 01246 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); 01247 TEST_ASSERT_MESSAGE((file_stat.st_mode & S_IFREG) != S_IFREG, fsfat_fopen_utest_msg_g); 01248 01249 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); 01250 TEST_ASSERT_MESSAGE((file_stat.st_mode & S_IFDIR) == S_IFDIR, fsfat_fopen_utest_msg_g); 01251 01252 /* clean up after successful test */ 01253 fsfat_filepath_remove_all((char*) node->filename); 01254 01255 #endif /* ! defined(__ARMCC_VERSION) && defined(__GNUC__) */ 01256 return CaseNext; 01257 } 01258 01259 /** @brief test for operation of SDFileSystem::format() 01260 * 01261 * @return on success returns CaseNext to continue to next test case, otherwise will assert on errors. 01262 */ 01263 control_t fsfat_fopen_test_15(const size_t call_count) 01264 { 01265 01266 FSFAT_FENTRYLOG("%s:entered\n", __func__); 01267 (void) call_count; 01268 int32_t ret = -1; 01269 01270 /* the allocation_unit of 0 means chanFS will use the default for the card (varies according to capacity). */ 01271 fs.unmount(); 01272 ret = fs.format(&sd); 01273 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); 01274 TEST_ASSERT_MESSAGE(ret == 0, fsfat_fopen_utest_msg_g); 01275 fs.mount(&sd); 01276 return CaseNext; 01277 } 01278 01279 01280 /* @brief test utility function to create a file of a given size. 01281 * 01282 * A reference data table is used of so that the data file can be later be 01283 * checked with fsfat_test_check_data_file(). 01284 * 01285 * @param filename name of the file including path 01286 * @param data data to store in file 01287 * @param len number of bytes of data present in the data buffer. 01288 */ 01289 int32_t fsfat_test_create_data_file(const char* filename, size_t len) 01290 { 01291 int32_t ret = -1; 01292 FILE *fp = NULL; 01293 size_t write_len = 0; 01294 size_t written_len = 0; 01295 int32_t exp = 0; 01296 const int32_t exp_max = 8; /* so as not to exceed FSFAT_TEST_BYTE_DATA_TABLE_SIZE/2 */ 01297 01298 FSFAT_FENTRYLOG("%s:entered (filename=%s, len=%d).\n", __func__, filename, (int) len); 01299 TEST_ASSERT(len % FSFAT_TEST_BYTE_DATA_TABLE_SIZE == 0); 01300 fp = fopen(filename, "a"); 01301 if(fp == NULL){ 01302 return ret; 01303 } 01304 01305 while(written_len < len) { 01306 /* write fsfat_test_byte_data_table or part thereof, in 9 writes of sizes 01307 * 1, 2, 4, 8, 16, 32, 64, 128, 1, totalling 256 bytes len permitting. */ 01308 for(exp = 0; (exp <= exp_max) && (written_len < len); exp++){ 01309 write_len = 0x1 << (exp % exp_max); 01310 write_len = len - written_len > write_len ? write_len : len - written_len; 01311 ret = fwrite((const void*) &fsfat_test_byte_data_table[written_len % FSFAT_TEST_BYTE_DATA_TABLE_SIZE], write_len, 1, fp); 01312 written_len += write_len; 01313 if(ret != 1){ 01314 FSFAT_DBGLOG("%s:Error: fwrite() failed (ret=%d)\n", __func__, (int) ret); 01315 ret = -1; 01316 goto out0; 01317 } 01318 } 01319 } 01320 if(written_len == len) { 01321 ret = 0; 01322 } else { 01323 ret = -1; 01324 } 01325 out0: 01326 fclose(fp); 01327 return ret; 01328 } 01329 01330 01331 /* @brief test utility function to check the data in the specified file is correct. 01332 * 01333 * The data read from the file is check that it agrees with the data written by 01334 * fsfat_test_create_data_file(). 01335 * 01336 * @param filename name of the file including path 01337 * @param data data to store in file 01338 * @param len number of bytes of data present in the data buffer. 01339 */ 01340 int32_t fsfat_test_check_data_file(const char* filename, size_t len) 01341 { 01342 int32_t ret = -1; 01343 FILE *fp = NULL; 01344 size_t read_len = 0; 01345 uint8_t buf[FSFAT_TEST_BYTE_DATA_TABLE_SIZE]; 01346 01347 FSFAT_FENTRYLOG("%s:entered (filename=%s, len=%d).\n", __func__, filename, (int) len); 01348 TEST_ASSERT(len % FSFAT_TEST_BYTE_DATA_TABLE_SIZE == 0); 01349 fp = fopen(filename, "r"); 01350 if(fp == NULL){ 01351 return ret; 01352 } 01353 01354 while(read_len < len) { 01355 ret = fread((void*) buf, FSFAT_TEST_BYTE_DATA_TABLE_SIZE, 1, fp); 01356 read_len += FSFAT_TEST_BYTE_DATA_TABLE_SIZE; 01357 if(ret == 0){ 01358 /* end of read*/ 01359 FSFAT_DBGLOG("%s:unable to read data\n", __func__); 01360 break; 01361 } 01362 if(memcmp(buf, fsfat_test_byte_data_table, FSFAT_TEST_BYTE_DATA_TABLE_SIZE) != 0) { 01363 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__, 01364 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]); 01365 ret = -1; 01366 goto out0; 01367 } 01368 } 01369 if(read_len == len) { 01370 ret = 0; 01371 } 01372 out0: 01373 fclose(fp); 01374 return ret; 01375 } 01376 01377 /* file data for test_16 */ 01378 static fsfat_kv_data_t fsfat_fopen_test_16_kv_data[] = { 01379 { "/sd/tst16_0/testfil0.txt", "dummy_data"}, 01380 { "/sd/tst16_1/subdir0/testfil0.txt", "dummy_data"}, 01381 { "/sd/tst16_2/subdir0/subdir1/testfil0.txt", "dummy_data"}, 01382 { "/sd/tst16_3/subdir0/subdir1/subdir2/subdir3/testfil0.txt", "dummy_data"}, 01383 { "/sd/tst16_4/subdir0/subdir1/subdir2/subdir3/subdir4/testfil0.txt", "dummy_data"}, 01384 { "/sd/tst16_5/subdir0/subdir1/subdir2/subdir3/subdir4/subdir5/testfil0.txt", "dummy_data"}, 01385 { "/sd/tst16_6/subdir0/subdir1/subdir2/subdir3/subdir4/subdir5/subdir6/testfil0.txt", "dummy_data"}, 01386 { "/sd/tst16_7/subdir0/subdir1/subdir2/subdir3/subdir4/subdir5/subdir6/subdir7/testfil0.txt", "dummy_data"}, 01387 { "/sd/tst16_8/subdir0/subdir1/subdir2/subdir3/subdir4/subdir5/subdir6/subdir7/subdir8/testfil0.txt", "dummy_data"}, 01388 { "/sd/tst16_9/subdir0/subdir1/subdir2/subdir3/subdir4/subdir5/subdir6/subdir7/subdir8/subdir9/testfil0.txt", "dummy_data"}, 01389 { NULL, NULL}, 01390 }; 01391 01392 01393 /** @brief stress test to write data to fs 01394 * 01395 * @return on success returns CaseNext to continue to next test case, otherwise will assert on errors. 01396 */ 01397 control_t fsfat_fopen_test_16(const size_t call_count) 01398 { 01399 int32_t ret = 0; 01400 fsfat_kv_data_t *node = fsfat_fopen_test_16_kv_data; 01401 const int32_t num_blocks = 100; /* each file ~25kB */ 01402 01403 FSFAT_DBGLOG("%s:entered\n", __func__); 01404 (void) call_count; 01405 01406 /* remove file and directory from a previous failed test run, if present */ 01407 while(node->filename != NULL) { 01408 fsfat_filepath_remove_all((char*) node->filename); 01409 node++; 01410 } 01411 01412 /* create dirs */ 01413 node = fsfat_fopen_test_16_kv_data; 01414 while(node->filename != NULL) { 01415 ret = fsfat_filepath_make_dirs((char*) node->filename, true); 01416 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); 01417 TEST_ASSERT_MESSAGE(ret == 0, fsfat_fopen_utest_msg_g); 01418 node++; 01419 } 01420 01421 /* create the data files */ 01422 node = fsfat_fopen_test_16_kv_data; 01423 while(node->filename != NULL) { 01424 ret = fsfat_test_create_data_file(node->filename, num_blocks * FSFAT_TEST_BYTE_DATA_TABLE_SIZE); 01425 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); 01426 TEST_ASSERT_MESSAGE(ret == 0, fsfat_fopen_utest_msg_g); 01427 node++; 01428 } 01429 01430 /* read the data back and check its as expected */ 01431 node = fsfat_fopen_test_16_kv_data; 01432 while(node->filename != NULL) { 01433 ret = fsfat_test_check_data_file(node->filename, num_blocks * FSFAT_TEST_BYTE_DATA_TABLE_SIZE); 01434 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); 01435 TEST_ASSERT_MESSAGE(ret == 0, fsfat_fopen_utest_msg_g); 01436 node++; 01437 } 01438 01439 /* clean up */ 01440 node = fsfat_fopen_test_16_kv_data; 01441 while(node->filename != NULL) { 01442 fsfat_filepath_remove_all((char*) node->filename); 01443 node++; 01444 } 01445 return CaseNext; 01446 } 01447 01448 01449 #else 01450 01451 01452 #define FSFAT_FOPEN_TEST_01 fsfat_fopen_test_dummy 01453 #define FSFAT_FOPEN_TEST_02 fsfat_fopen_test_dummy 01454 #define FSFAT_FOPEN_TEST_03 fsfat_fopen_test_dummy 01455 #define FSFAT_FOPEN_TEST_04 fsfat_fopen_test_dummy 01456 #define FSFAT_FOPEN_TEST_05 fsfat_fopen_test_dummy 01457 #define FSFAT_FOPEN_TEST_06 fsfat_fopen_test_dummy 01458 #define FSFAT_FOPEN_TEST_07 fsfat_fopen_test_dummy 01459 #define FSFAT_FOPEN_TEST_08 fsfat_fopen_test_dummy 01460 #define FSFAT_FOPEN_TEST_09 fsfat_fopen_test_dummy 01461 #define FSFAT_FOPEN_TEST_10 fsfat_fopen_test_dummy 01462 #define FSFAT_FOPEN_TEST_11 fsfat_fopen_test_dummy 01463 #define FSFAT_FOPEN_TEST_12 fsfat_fopen_test_dummy 01464 #define FSFAT_FOPEN_TEST_13 fsfat_fopen_test_dummy 01465 #define FSFAT_FOPEN_TEST_14 fsfat_fopen_test_dummy 01466 #define FSFAT_FOPEN_TEST_15 fsfat_fopen_test_dummy 01467 #define FSFAT_FOPEN_TEST_16 fsfat_fopen_test_dummy 01468 #define FSFAT_FOPEN_TEST_17 fsfat_fopen_test_dummy 01469 #define FSFAT_FOPEN_TEST_18 fsfat_fopen_test_dummy 01470 #define FSFAT_FOPEN_TEST_19 fsfat_fopen_test_dummy 01471 #define FSFAT_FOPEN_TEST_20 fsfat_fopen_test_dummy 01472 #define FSFAT_FOPEN_TEST_21 fsfat_fopen_test_dummy 01473 #define FSFAT_FOPEN_TEST_22 fsfat_fopen_test_dummy 01474 #define FSFAT_FOPEN_TEST_23 fsfat_fopen_test_dummy 01475 #define FSFAT_FOPEN_TEST_24 fsfat_fopen_test_dummy 01476 #define FSFAT_FOPEN_TEST_25 fsfat_fopen_test_dummy 01477 #define FSFAT_FOPEN_TEST_26 fsfat_fopen_test_dummy 01478 #define FSFAT_FOPEN_TEST_27 fsfat_fopen_test_dummy 01479 #define FSFAT_FOPEN_TEST_28 fsfat_fopen_test_dummy 01480 #define FSFAT_FOPEN_TEST_29 fsfat_fopen_test_dummy 01481 #define FSFAT_FOPEN_TEST_30 fsfat_fopen_test_dummy 01482 01483 /** @brief fsfat_fopen_test_dummy Dummy test case for testing when platform doesnt have an SDCard installed. 01484 * 01485 * @return success always 01486 */ 01487 static control_t fsfat_fopen_test_dummy() 01488 { 01489 printf("Null test\n"); 01490 return CaseNext; 01491 } 01492 01493 #endif /* defined(DEVICE_SPI) && defined(MBED_CONF_APP_FSFAT_SDCARD_INSTALLED) */ 01494 01495 01496 /// @cond FSFAT_DOXYGEN_DISABLE 01497 utest::v1::status_t greentea_setup(const size_t number_of_cases) 01498 { 01499 GREENTEA_SETUP(FSFAT_FOPEN_GREENTEA_TIMEOUT_S, "default_auto"); 01500 return greentea_test_setup_handler(number_of_cases); 01501 } 01502 01503 Case cases[] = { 01504 /* 1 2 3 4 5 6 7 */ 01505 /* 1234567890123456789012345678901234567890123456789012345678901234567890 */ 01506 Case("FSFAT_FOPEN_TEST_01: fopen()/fwrite()/fclose() directories/file in multi-dir filepath.", FSFAT_FOPEN_TEST_01), 01507 Case("FSFAT_FOPEN_TEST_02: fopen(r) pre-existing file try to write it.", FSFAT_FOPEN_TEST_02), 01508 Case("FSFAT_FOPEN_TEST_03: fopen(w+) pre-existing file try to write it.", FSFAT_FOPEN_TEST_03), 01509 Case("FSFAT_FOPEN_TEST_04: fopen() with a filename exceeding the maximum length.", FSFAT_FOPEN_TEST_04), 01510 #ifdef FOPEN_EXTENDED_TESTING 01511 Case("FSFAT_FOPEN_TEST_05: fopen() with bad filenames (extended).", FSFAT_FOPEN_TEST_05), 01512 #endif 01513 Case("FSFAT_FOPEN_TEST_06: fopen() with bad filenames (minimal).", FSFAT_FOPEN_TEST_06), 01514 Case("FSFAT_FOPEN_TEST_07: fopen()/errno handling.", FSFAT_FOPEN_TEST_07), 01515 Case("FSFAT_FOPEN_TEST_08: ferror()/clearerr()/errno handling.", FSFAT_FOPEN_TEST_08), 01516 Case("FSFAT_FOPEN_TEST_09: ftell() handling.", FSFAT_FOPEN_TEST_09), 01517 Case("FSFAT_FOPEN_TEST_10: remove() test.", FSFAT_FOPEN_TEST_10), 01518 Case("FSFAT_FOPEN_TEST_11: rename().", FSFAT_FOPEN_TEST_11), 01519 Case("FSFAT_FOPEN_TEST_12: opendir(), readdir(), closedir() test.", FSFAT_FOPEN_TEST_12), 01520 Case("FSFAT_FOPEN_TEST_13: mkdir() test.", FSFAT_FOPEN_TEST_13), 01521 Case("FSFAT_FOPEN_TEST_14: stat() test.", FSFAT_FOPEN_TEST_14), 01522 Case("FSFAT_FOPEN_TEST_15: format() test.", FSFAT_FOPEN_TEST_15), 01523 Case("FSFAT_FOPEN_TEST_16: write/check n x 25kB data files.", FSFAT_FOPEN_TEST_16), 01524 }; 01525 01526 01527 /* Declare your test specification with a custom setup handler */ 01528 Specification specification(greentea_setup, cases); 01529 01530 int main() 01531 { 01532 return !Harness::run(specification); 01533 } 01534 /// @endcond
Generated on Mon Jul 18 2022 05:40:54 by
1.7.2
