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