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 352 by
fopen.cpp
00001 /* 00002 * mbed Microcontroller Library 00003 * Copyright (c) 2006-2016 ARM Limited 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); 00006 * you may not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 00018 /** @file fopen.cpp Test cases to POSIX file fopen() interface. 00019 * 00020 * Please consult the documentation under the test-case functions for 00021 * a description of the individual test case. 00022 */ 00023 00024 #include "mbed.h" 00025 #include "mbed_config.h" 00026 #include "SDBlockDevice.h" 00027 #include "FATFileSystem.h" 00028 #include "fsfat_debug.h" 00029 #include "fsfat_test.h" 00030 #include "utest/utest.h" 00031 #include "unity/unity.h" 00032 #include "greentea-client/test_env.h" 00033 00034 #include <stdio.h> 00035 #include <string.h> 00036 #include <stdlib.h> /*rand()*/ 00037 #include <inttypes.h> 00038 #include <errno.h> 00039 /* mbed_retarget.h is included after errno.h so symbols are mapped to 00040 * consistent values for all toolchains */ 00041 #include "platform/mbed_retarget.h" 00042 00043 /* This is needed for stat() test, but is not available on ARMCC. 00044 * The following checks whether GCC_ARM compiler is being used because: 00045 * - both the ARMCC compiler and the GCC_ARM compile define __GNUC__. 00046 * - only the ARMCC compiler defines __ARMCC_VERSION. 00047 * - hence if __ARMCC_VERSION is not defined and __GNUC__ is defined, it must be GCC_ARM. */ 00048 #if ! defined(__ARMCC_VERSION) && defined(__GNUC__) 00049 #include <sys/stat.h> 00050 #endif 00051 using namespace utest::v1; 00052 00053 /// @cond FSFAT_DOXYGEN_DISABLE 00054 #ifdef FSFAT_DEBUG 00055 #define FSFAT_FOPEN_GREENTEA_TIMEOUT_S 3000 00056 #else 00057 #define FSFAT_FOPEN_GREENTEA_TIMEOUT_S 1000 00058 #endif 00059 /// @endcond 00060 00061 00062 /* DEVICE_SPI 00063 * This symbol is defined in targets.json if the target has a SPI interface, which is required for SDCard support. 00064 * 00065 * MBED_CONF_APP_FSFAT_SDCARD_INSTALLED 00066 * For testing purposes, an SDCard must be installed on the target for the test cases in this file to succeed. 00067 * If the target has an SD card installed then the MBED_CONF_APP_FSFAT_SDCARD_INSTALLED will be generated 00068 * from the mbed_app.json, which includes the line 00069 * { 00070 * "config": { 00071 * "UART_RX": "D0", 00072 * <<< lines removed >>> 00073 * "DEVICE_SPI": 1, 00074 * "FSFAT_SDCARD_INSTALLED": 1 00075 * }, 00076 * <<< lines removed >>> 00077 */ 00078 #if defined(DEVICE_SPI) && defined(MBED_CONF_APP_FSFAT_SDCARD_INSTALLED) 00079 00080 static char fsfat_fopen_utest_msg_g[FSFAT_UTEST_MSG_BUF_SIZE]; 00081 #define FSFAT_FOPEN_TEST_MOUNT_PT_NAME "sd" 00082 #define FSFAT_FOPEN_TEST_MOUNT_PT_PATH "/"FSFAT_FOPEN_TEST_MOUNT_PT_NAME 00083 #define FSFAT_FOPEN_TEST_WORK_BUF_SIZE_1 64 00084 #define FSFAT_FOPEN_TEST_FILEPATH_MAX_DEPTH 20 00085 static const char *sd_badfile_path = "/sd/badfile.txt"; 00086 static const char *sd_testfile_path = "/sd/test.txt"; 00087 00088 SDBlockDevice sd(MBED_CONF_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 Tue Jul 12 2022 21:51:19 by
