RTC auf true

Committer:
kevman
Date:
Wed Mar 13 11:03:24 2019 +0000
Revision:
2:7aab896b1a3b
2019-03-13

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kevman 2:7aab896b1a3b 1 /*
kevman 2:7aab896b1a3b 2 * mbed Microcontroller Library
kevman 2:7aab896b1a3b 3 * Copyright (c) 2006-2016 ARM Limited
kevman 2:7aab896b1a3b 4 *
kevman 2:7aab896b1a3b 5 * Licensed under the Apache License, Version 2.0 (the "License");
kevman 2:7aab896b1a3b 6 * you may not use this file except in compliance with the License.
kevman 2:7aab896b1a3b 7 * You may obtain a copy of the License at
kevman 2:7aab896b1a3b 8 *
kevman 2:7aab896b1a3b 9 * http://www.apache.org/licenses/LICENSE-2.0
kevman 2:7aab896b1a3b 10 *
kevman 2:7aab896b1a3b 11 * Unless required by applicable law or agreed to in writing, software
kevman 2:7aab896b1a3b 12 * distributed under the License is distributed on an "AS IS" BASIS,
kevman 2:7aab896b1a3b 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
kevman 2:7aab896b1a3b 14 * See the License for the specific language governing permissions and
kevman 2:7aab896b1a3b 15 * limitations under the License.
kevman 2:7aab896b1a3b 16 */
kevman 2:7aab896b1a3b 17
kevman 2:7aab896b1a3b 18 /** @file fopen.cpp Test cases to POSIX file fopen() interface.
kevman 2:7aab896b1a3b 19 *
kevman 2:7aab896b1a3b 20 * Please consult the documentation under the test-case functions for
kevman 2:7aab896b1a3b 21 * a description of the individual test case.
kevman 2:7aab896b1a3b 22 */
kevman 2:7aab896b1a3b 23
kevman 2:7aab896b1a3b 24 //#include "mbed.h"
kevman 2:7aab896b1a3b 25 #include "LittleFileSystem.h"
kevman 2:7aab896b1a3b 26 #include "fslittle_debug.h"
kevman 2:7aab896b1a3b 27 #include "fslittle_test.h"
kevman 2:7aab896b1a3b 28 #include "utest/utest.h"
kevman 2:7aab896b1a3b 29 #include "unity/unity.h"
kevman 2:7aab896b1a3b 30 #include "greentea-client/test_env.h"
kevman 2:7aab896b1a3b 31
kevman 2:7aab896b1a3b 32 #include <stdio.h>
kevman 2:7aab896b1a3b 33 #include <string.h>
kevman 2:7aab896b1a3b 34 #include <stdlib.h> /*rand()*/
kevman 2:7aab896b1a3b 35 #include <inttypes.h>
kevman 2:7aab896b1a3b 36 #include <errno.h>
kevman 2:7aab896b1a3b 37 /* mbed_retarget.h is included after errno.h so symbols are mapped to
kevman 2:7aab896b1a3b 38 * consistent values for all toolchains */
kevman 2:7aab896b1a3b 39 //#include "platform/mbed_retarget.h"
kevman 2:7aab896b1a3b 40
kevman 2:7aab896b1a3b 41 using namespace utest::v1;
kevman 2:7aab896b1a3b 42
kevman 2:7aab896b1a3b 43 /// @cond FSLITTLE_DOXYGEN_DISABLE
kevman 2:7aab896b1a3b 44 #ifdef FSLITTLE_DEBUG
kevman 2:7aab896b1a3b 45 #define FSLITTLE_FOPEN_GREENTEA_TIMEOUT_S 3000
kevman 2:7aab896b1a3b 46 #else
kevman 2:7aab896b1a3b 47 #define FSLITTLE_FOPEN_GREENTEA_TIMEOUT_S 1000
kevman 2:7aab896b1a3b 48 #endif
kevman 2:7aab896b1a3b 49 /// @endcond
kevman 2:7aab896b1a3b 50
kevman 2:7aab896b1a3b 51
kevman 2:7aab896b1a3b 52 /* DEVICE_SPI
kevman 2:7aab896b1a3b 53 * This symbol is defined in targets.json if the target has a SPI interface, which is required for SDCard support.
kevman 2:7aab896b1a3b 54 *
kevman 2:7aab896b1a3b 55 * MBED_CONF_APP_FSLITTLE_SDCARD_INSTALLED
kevman 2:7aab896b1a3b 56 * For testing purposes, an SDCard must be installed on the target for the test cases in this file to succeed.
kevman 2:7aab896b1a3b 57 * If the target has an SD card installed then the MBED_CONF_APP_FSLITTLE_SDCARD_INSTALLED will be generated
kevman 2:7aab896b1a3b 58 * from the mbed_app.json, which includes the line
kevman 2:7aab896b1a3b 59 * {
kevman 2:7aab896b1a3b 60 * "config": {
kevman 2:7aab896b1a3b 61 * "UART_RX": "D0",
kevman 2:7aab896b1a3b 62 * <<< lines removed >>>
kevman 2:7aab896b1a3b 63 * "DEVICE_SPI": 1,
kevman 2:7aab896b1a3b 64 * "FSLITTLE_SDCARD_INSTALLED": 1
kevman 2:7aab896b1a3b 65 * },
kevman 2:7aab896b1a3b 66 * <<< lines removed >>>
kevman 2:7aab896b1a3b 67 */
kevman 2:7aab896b1a3b 68
kevman 2:7aab896b1a3b 69 #include "FlashIAPBlockDevice.h"
kevman 2:7aab896b1a3b 70 #include "SlicingBlockDevice.h"
kevman 2:7aab896b1a3b 71
kevman 2:7aab896b1a3b 72 FlashIAPBlockDevice *flash;
kevman 2:7aab896b1a3b 73 SlicingBlockDevice *slice;
kevman 2:7aab896b1a3b 74 LittleFileSystem fs("sd");
kevman 2:7aab896b1a3b 75
kevman 2:7aab896b1a3b 76 static char fslittle_fopen_utest_msg_g[FSLITTLE_UTEST_MSG_BUF_SIZE];
kevman 2:7aab896b1a3b 77 #define FSLITTLE_FOPEN_TEST_MOUNT_PT_NAME "sd"
kevman 2:7aab896b1a3b 78 #define FSLITTLE_FOPEN_TEST_MOUNT_PT_PATH "/"FSLITTLE_FOPEN_TEST_MOUNT_PT_NAME
kevman 2:7aab896b1a3b 79 #define FSLITTLE_FOPEN_TEST_WORK_BUF_SIZE_1 64
kevman 2:7aab896b1a3b 80 #define FSLITTLE_FOPEN_TEST_FILEPATH_MAX_DEPTH 20
kevman 2:7aab896b1a3b 81 static const int MAX_TEST_SIZE = 256 * 1024 * 2;
kevman 2:7aab896b1a3b 82 static const char *sd_badfile_path = "/sd/badfile.txt";
kevman 2:7aab896b1a3b 83 static const char *sd_testfile_path = "/sd/test.txt";
kevman 2:7aab896b1a3b 84
kevman 2:7aab896b1a3b 85 #define FSLITTLE_FOPEN_TEST_00 fslittle_fopen_test_00
kevman 2:7aab896b1a3b 86 #define FSLITTLE_FOPEN_TEST_01 fslittle_fopen_test_01
kevman 2:7aab896b1a3b 87 #define FSLITTLE_FOPEN_TEST_02 fslittle_fopen_test_02
kevman 2:7aab896b1a3b 88 #define FSLITTLE_FOPEN_TEST_03 fslittle_fopen_test_03
kevman 2:7aab896b1a3b 89 #define FSLITTLE_FOPEN_TEST_04 fslittle_fopen_test_04
kevman 2:7aab896b1a3b 90 #define FSLITTLE_FOPEN_TEST_05 fslittle_fopen_test_05
kevman 2:7aab896b1a3b 91 #define FSLITTLE_FOPEN_TEST_06 fslittle_fopen_test_06
kevman 2:7aab896b1a3b 92 #define FSLITTLE_FOPEN_TEST_07 fslittle_fopen_test_07
kevman 2:7aab896b1a3b 93 #define FSLITTLE_FOPEN_TEST_08 fslittle_fopen_test_08
kevman 2:7aab896b1a3b 94 #define FSLITTLE_FOPEN_TEST_09 fslittle_fopen_test_09
kevman 2:7aab896b1a3b 95 #define FSLITTLE_FOPEN_TEST_10 fslittle_fopen_test_10
kevman 2:7aab896b1a3b 96 #define FSLITTLE_FOPEN_TEST_11 fslittle_fopen_test_11
kevman 2:7aab896b1a3b 97 #define FSLITTLE_FOPEN_TEST_12 fslittle_fopen_test_12
kevman 2:7aab896b1a3b 98 #define FSLITTLE_FOPEN_TEST_13 fslittle_fopen_test_13
kevman 2:7aab896b1a3b 99 #define FSLITTLE_FOPEN_TEST_14 fslittle_fopen_test_14
kevman 2:7aab896b1a3b 100 #define FSLITTLE_FOPEN_TEST_15 fslittle_fopen_test_15
kevman 2:7aab896b1a3b 101 #define FSLITTLE_FOPEN_TEST_17 fslittle_fopen_test_17
kevman 2:7aab896b1a3b 102 #define FSLITTLE_FOPEN_TEST_18 fslittle_fopen_test_18
kevman 2:7aab896b1a3b 103 #define FSLITTLE_FOPEN_TEST_19 fslittle_fopen_test_19
kevman 2:7aab896b1a3b 104 #define FSLITTLE_FOPEN_TEST_20 fslittle_fopen_test_20
kevman 2:7aab896b1a3b 105 #define FSLITTLE_FOPEN_TEST_21 fslittle_fopen_test_21
kevman 2:7aab896b1a3b 106 #define FSLITTLE_FOPEN_TEST_22 fslittle_fopen_test_22
kevman 2:7aab896b1a3b 107 #define FSLITTLE_FOPEN_TEST_23 fslittle_fopen_test_23
kevman 2:7aab896b1a3b 108 #define FSLITTLE_FOPEN_TEST_24 fslittle_fopen_test_24
kevman 2:7aab896b1a3b 109 #define FSLITTLE_FOPEN_TEST_25 fslittle_fopen_test_25
kevman 2:7aab896b1a3b 110 #define FSLITTLE_FOPEN_TEST_26 fslittle_fopen_test_26
kevman 2:7aab896b1a3b 111 #define FSLITTLE_FOPEN_TEST_27 fslittle_fopen_test_27
kevman 2:7aab896b1a3b 112 #define FSLITTLE_FOPEN_TEST_28 fslittle_fopen_test_28
kevman 2:7aab896b1a3b 113 #define FSLITTLE_FOPEN_TEST_29 fslittle_fopen_test_29
kevman 2:7aab896b1a3b 114 #define FSLITTLE_FOPEN_TEST_30 fslittle_fopen_test_30
kevman 2:7aab896b1a3b 115
kevman 2:7aab896b1a3b 116
kevman 2:7aab896b1a3b 117 /* support functions */
kevman 2:7aab896b1a3b 118
kevman 2:7aab896b1a3b 119 /*
kevman 2:7aab896b1a3b 120 * open tests that focus on testing fopen()
kevman 2:7aab896b1a3b 121 * fslittle_handle_t fopen(const char* filename, char* data, size_t* len, fslittle_key_desc_t* kdesc)
kevman 2:7aab896b1a3b 122 */
kevman 2:7aab896b1a3b 123
kevman 2:7aab896b1a3b 124 /* file data for test_01 */
kevman 2:7aab896b1a3b 125 static fslittle_kv_data_t fslittle_fopen_test_01_kv_data[] = {
kevman 2:7aab896b1a3b 126 { "/sd/fopentst/hello/world/animal/wobbly/dog/foot/frontlft.txt", "missing"},
kevman 2:7aab896b1a3b 127 { NULL, NULL},
kevman 2:7aab896b1a3b 128 };
kevman 2:7aab896b1a3b 129
kevman 2:7aab896b1a3b 130
kevman 2:7aab896b1a3b 131 /** @brief
kevman 2:7aab896b1a3b 132 * Split a file path into its component parts, setting '/' characters to '\0', and returning
kevman 2:7aab896b1a3b 133 * pointers to the file path components in the parts array. For example, if
kevman 2:7aab896b1a3b 134 * filepath = "/sd/fopentst/hello/world/animal/wobbly/dog/foot/frontlft.txt" then
kevman 2:7aab896b1a3b 135 * *parts[0] = "sd"
kevman 2:7aab896b1a3b 136 * *parts[1] = "fopentst"
kevman 2:7aab896b1a3b 137 * *parts[2] = "hello"
kevman 2:7aab896b1a3b 138 * *parts[3] = "world"
kevman 2:7aab896b1a3b 139 * *parts[4] = "animal"
kevman 2:7aab896b1a3b 140 * *parts[5] = "wobbly"
kevman 2:7aab896b1a3b 141 * *parts[6] = "dog"
kevman 2:7aab896b1a3b 142 * *parts[7] = "foot"
kevman 2:7aab896b1a3b 143 * *parts[8] = "frontlft.txt"
kevman 2:7aab896b1a3b 144 * parts[9] = NULL
kevman 2:7aab896b1a3b 145 *
kevman 2:7aab896b1a3b 146 * ARGUMENTS
kevman 2:7aab896b1a3b 147 * @param filepath IN file path string to split into component parts. Expected to start with '/'
kevman 2:7aab896b1a3b 148 * @param parts IN OUT array to hold pointers to parts
kevman 2:7aab896b1a3b 149 * @param num IN number of components available in parts
kevman 2:7aab896b1a3b 150 *
kevman 2:7aab896b1a3b 151 * @return On success, this returns the number of components in the filepath Returns number of compoee
kevman 2:7aab896b1a3b 152 */
kevman 2:7aab896b1a3b 153 static int32_t fslittle_filepath_split(char *filepath, char *parts[], uint32_t num)
kevman 2:7aab896b1a3b 154 {
kevman 2:7aab896b1a3b 155 uint32_t i = 0;
kevman 2:7aab896b1a3b 156 int32_t ret = -1;
kevman 2:7aab896b1a3b 157 char *z = filepath;
kevman 2:7aab896b1a3b 158
kevman 2:7aab896b1a3b 159 while (i < num && *z != '\0') {
kevman 2:7aab896b1a3b 160 if (*z == '/') {
kevman 2:7aab896b1a3b 161 *z = '\0';
kevman 2:7aab896b1a3b 162 parts[i] = ++z;
kevman 2:7aab896b1a3b 163 i++;
kevman 2:7aab896b1a3b 164 } else {
kevman 2:7aab896b1a3b 165 z++;
kevman 2:7aab896b1a3b 166 }
kevman 2:7aab896b1a3b 167 }
kevman 2:7aab896b1a3b 168 if (*z == '\0' && i > 0) {
kevman 2:7aab896b1a3b 169 ret = (int32_t) i;
kevman 2:7aab896b1a3b 170 }
kevman 2:7aab896b1a3b 171 return ret;
kevman 2:7aab896b1a3b 172 }
kevman 2:7aab896b1a3b 173
kevman 2:7aab896b1a3b 174
kevman 2:7aab896b1a3b 175 /** @brief
kevman 2:7aab896b1a3b 176 * remove all directories and file in the given filepath
kevman 2:7aab896b1a3b 177 *
kevman 2:7aab896b1a3b 178 * ARGUMENTS
kevman 2:7aab896b1a3b 179 * @param filepath IN file path string to split into component parts. Expected to start with '/'
kevman 2:7aab896b1a3b 180 *
kevman 2:7aab896b1a3b 181 * @return On success, this returns 0, otherwise < 0 is returned;
kevman 2:7aab896b1a3b 182 */
kevman 2:7aab896b1a3b 183 int32_t fslittle_filepath_remove_all(char *filepath)
kevman 2:7aab896b1a3b 184 {
kevman 2:7aab896b1a3b 185 int32_t ret = -1;
kevman 2:7aab896b1a3b 186 int32_t len = 0;
kevman 2:7aab896b1a3b 187 char *fpathbuf = NULL;
kevman 2:7aab896b1a3b 188 char *pos = NULL;
kevman 2:7aab896b1a3b 189
kevman 2:7aab896b1a3b 190 FSLITTLE_FENTRYLOG("%s:entered\n", __func__);
kevman 2:7aab896b1a3b 191 len = strlen(filepath);
kevman 2:7aab896b1a3b 192 fpathbuf = (char *) malloc(len + 1);
kevman 2:7aab896b1a3b 193 if (fpathbuf == NULL) {
kevman 2:7aab896b1a3b 194 FSLITTLE_DBGLOG("%s: failed to duplicate string (out of memory)\n", __func__);
kevman 2:7aab896b1a3b 195 return ret;
kevman 2:7aab896b1a3b 196 }
kevman 2:7aab896b1a3b 197 memset(fpathbuf, 0, len + 1);
kevman 2:7aab896b1a3b 198 memcpy(fpathbuf, filepath, len);
kevman 2:7aab896b1a3b 199
kevman 2:7aab896b1a3b 200 /* delete the leaf node first, and then successively parent directories. */
kevman 2:7aab896b1a3b 201 pos = fpathbuf + strlen(fpathbuf);
kevman 2:7aab896b1a3b 202 while (pos != fpathbuf) {
kevman 2:7aab896b1a3b 203 /* If the remaining file path is the mount point path then finish as the mount point cannot be removed */
kevman 2:7aab896b1a3b 204 if (strlen(fpathbuf) == strlen(FSLITTLE_FOPEN_TEST_MOUNT_PT_PATH) && strncmp(fpathbuf, FSLITTLE_FOPEN_TEST_MOUNT_PT_PATH, strlen(fpathbuf)) == 0) {
kevman 2:7aab896b1a3b 205 break;
kevman 2:7aab896b1a3b 206 }
kevman 2:7aab896b1a3b 207 ret = remove(fpathbuf);
kevman 2:7aab896b1a3b 208 pos = strrchr(fpathbuf, '/');
kevman 2:7aab896b1a3b 209 *pos = '\0';
kevman 2:7aab896b1a3b 210 }
kevman 2:7aab896b1a3b 211 if (fpathbuf) {
kevman 2:7aab896b1a3b 212 free(fpathbuf);
kevman 2:7aab896b1a3b 213 }
kevman 2:7aab896b1a3b 214 return ret;
kevman 2:7aab896b1a3b 215 }
kevman 2:7aab896b1a3b 216
kevman 2:7aab896b1a3b 217
kevman 2:7aab896b1a3b 218 /** @brief
kevman 2:7aab896b1a3b 219 * make all directories in the given filepath. Do not create the file if present at end of filepath
kevman 2:7aab896b1a3b 220 *
kevman 2:7aab896b1a3b 221 * ARGUMENTS
kevman 2:7aab896b1a3b 222 * @param filepath IN file path containing directories and file
kevman 2:7aab896b1a3b 223 * @param do_asserts IN set to true if function should assert on errors
kevman 2:7aab896b1a3b 224 *
kevman 2:7aab896b1a3b 225 * @return On success, this returns 0, otherwise < 0 is returned;
kevman 2:7aab896b1a3b 226 */
kevman 2:7aab896b1a3b 227 static int32_t fslittle_filepath_make_dirs(char *filepath, bool do_asserts)
kevman 2:7aab896b1a3b 228 {
kevman 2:7aab896b1a3b 229 int32_t i = 0;
kevman 2:7aab896b1a3b 230 int32_t num_parts = 0;
kevman 2:7aab896b1a3b 231 int32_t len = 0;
kevman 2:7aab896b1a3b 232 int32_t ret = -1;
kevman 2:7aab896b1a3b 233 char *fpathbuf = NULL;
kevman 2:7aab896b1a3b 234 char *buf = NULL;
kevman 2:7aab896b1a3b 235 int pos = 0;
kevman 2:7aab896b1a3b 236 char *parts[FSLITTLE_FOPEN_TEST_FILEPATH_MAX_DEPTH];
kevman 2:7aab896b1a3b 237
kevman 2:7aab896b1a3b 238 FSLITTLE_DBGLOG("%s:entered\n", __func__);
kevman 2:7aab896b1a3b 239 /* find the dirs to create*/
kevman 2:7aab896b1a3b 240 memset(parts, 0, sizeof(parts));
kevman 2:7aab896b1a3b 241 len = strlen(filepath);
kevman 2:7aab896b1a3b 242 fpathbuf = (char *) malloc(len + 1);
kevman 2:7aab896b1a3b 243 if (fpathbuf == NULL) {
kevman 2:7aab896b1a3b 244 FSLITTLE_DBGLOG("%s: failed to duplicate string (out of memory)\n", __func__);
kevman 2:7aab896b1a3b 245 return ret;
kevman 2:7aab896b1a3b 246 }
kevman 2:7aab896b1a3b 247 memset(fpathbuf, 0, len + 1);
kevman 2:7aab896b1a3b 248 memcpy(fpathbuf, filepath, len);
kevman 2:7aab896b1a3b 249 num_parts = fslittle_filepath_split(fpathbuf, parts, FSLITTLE_FOPEN_TEST_FILEPATH_MAX_DEPTH);
kevman 2:7aab896b1a3b 250 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: failed to split filepath (filename=\"%s\", num_parts=%d)\n", __func__, filepath, (int) num_parts);
kevman 2:7aab896b1a3b 251 TEST_ASSERT_MESSAGE(num_parts > 0, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 252
kevman 2:7aab896b1a3b 253 /* Now create the directories on the directory path.
kevman 2:7aab896b1a3b 254 * Skip creating dir for "/sd" which must be present */
kevman 2:7aab896b1a3b 255 buf = (char *) malloc(strlen(filepath) + 1);
kevman 2:7aab896b1a3b 256 memset(buf, 0, strlen(filepath) + 1);
kevman 2:7aab896b1a3b 257 pos = sprintf(buf, "/%s", parts[0]);
kevman 2:7aab896b1a3b 258 for (i = 1; i < num_parts - 1; i++) {
kevman 2:7aab896b1a3b 259 pos += sprintf(buf + pos, "/%s", parts[i]);
kevman 2:7aab896b1a3b 260 FSLITTLE_DBGLOG("mkdir(%s)\n", buf);
kevman 2:7aab896b1a3b 261 ret = mkdir(buf, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
kevman 2:7aab896b1a3b 262 if (do_asserts == true) {
kevman 2:7aab896b1a3b 263 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: failed to create directory (filepath2=\"%s\", ret=%d, errno=%d)\n", __func__, buf, (int) ret, errno);
kevman 2:7aab896b1a3b 264 TEST_ASSERT_MESSAGE(ret == 0, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 265 }
kevman 2:7aab896b1a3b 266 }
kevman 2:7aab896b1a3b 267
kevman 2:7aab896b1a3b 268 if (buf) {
kevman 2:7aab896b1a3b 269 free(buf);
kevman 2:7aab896b1a3b 270 }
kevman 2:7aab896b1a3b 271 if (fpathbuf) {
kevman 2:7aab896b1a3b 272 free(fpathbuf);
kevman 2:7aab896b1a3b 273 }
kevman 2:7aab896b1a3b 274 return ret;
kevman 2:7aab896b1a3b 275 }
kevman 2:7aab896b1a3b 276
kevman 2:7aab896b1a3b 277
kevman 2:7aab896b1a3b 278 /* FIX ME: errno not set correctly when error occurs. This indicates a problem with the implementation. */
kevman 2:7aab896b1a3b 279
kevman 2:7aab896b1a3b 280 /** @brief
kevman 2:7aab896b1a3b 281 * Basic fopen test which does the following:
kevman 2:7aab896b1a3b 282 * - creates file and writes some data to the value blob.
kevman 2:7aab896b1a3b 283 * - closes the newly created file.
kevman 2:7aab896b1a3b 284 * - opens the file (r-only)
kevman 2:7aab896b1a3b 285 * - reads the file data and checks its the same as the previously created data.
kevman 2:7aab896b1a3b 286 * - closes the opened file
kevman 2:7aab896b1a3b 287 *
kevman 2:7aab896b1a3b 288 * @return on success returns CaseNext to continue to next test case, otherwise will assert on errors.
kevman 2:7aab896b1a3b 289 */
kevman 2:7aab896b1a3b 290 static control_t fslittle_fopen_test_01(const size_t call_count)
kevman 2:7aab896b1a3b 291 {
kevman 2:7aab896b1a3b 292 char *read_buf;
kevman 2:7aab896b1a3b 293 int32_t ret = 0;
kevman 2:7aab896b1a3b 294 size_t len = 0;
kevman 2:7aab896b1a3b 295 fslittle_kv_data_t *node;
kevman 2:7aab896b1a3b 296 FILE *fp = NULL;
kevman 2:7aab896b1a3b 297
kevman 2:7aab896b1a3b 298 FSLITTLE_DBGLOG("%s:entered\n", __func__);
kevman 2:7aab896b1a3b 299 (void) call_count;
kevman 2:7aab896b1a3b 300 node = fslittle_fopen_test_01_kv_data;
kevman 2:7aab896b1a3b 301
kevman 2:7aab896b1a3b 302 /* remove file and directory from a previous failed test run, if present */
kevman 2:7aab896b1a3b 303 fslittle_filepath_remove_all((char *) node->filename);
kevman 2:7aab896b1a3b 304
kevman 2:7aab896b1a3b 305 /* create dirs */
kevman 2:7aab896b1a3b 306 ret = fslittle_filepath_make_dirs((char *) node->filename, true);
kevman 2:7aab896b1a3b 307 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: failed to create dirs for filename (filename=\"%s\")(ret=%d)\n", __func__, node->filename, (int) ret);
kevman 2:7aab896b1a3b 308 TEST_ASSERT_MESSAGE(ret == 0, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 309
kevman 2:7aab896b1a3b 310 FSLITTLE_DBGLOG("%s:About to create new file (filename=\"%s\", data=\"%s\")\n", __func__, node->filename, node->value);
kevman 2:7aab896b1a3b 311 fp = fopen(node->filename, "w+");
kevman 2:7aab896b1a3b 312 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_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);
kevman 2:7aab896b1a3b 313 TEST_ASSERT_MESSAGE(fp != NULL, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 314
kevman 2:7aab896b1a3b 315 FSLITTLE_DBGLOG("%s:length of file=%d (filename=\"%s\", data=\"%s\")\n", __func__, (int) len, node->filename, node->value);
kevman 2:7aab896b1a3b 316 len = strlen(node->value);
kevman 2:7aab896b1a3b 317 ret = fwrite((const void *) node->value, len, 1, fp);
kevman 2:7aab896b1a3b 318 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: failed to write file (filename=\"%s\", data=\"%s\")(ret=%d)\n", __func__, node->filename, node->value, (int) ret);
kevman 2:7aab896b1a3b 319 TEST_ASSERT_MESSAGE(ret == 1, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 320
kevman 2:7aab896b1a3b 321 FSLITTLE_DBGLOG("Created file successfully (filename=\"%s\", data=\"%s\")\n", node->filename, node->value);
kevman 2:7aab896b1a3b 322 ret = fclose(fp);
kevman 2:7aab896b1a3b 323 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: failed to close file (ret=%d, errno=%d)\n", __func__, (int) ret, errno);
kevman 2:7aab896b1a3b 324 TEST_ASSERT_MESSAGE(ret == 0, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 325
kevman 2:7aab896b1a3b 326 /* now open the newly created key */
kevman 2:7aab896b1a3b 327 fp = NULL;
kevman 2:7aab896b1a3b 328 fp = fopen(node->filename, "r");
kevman 2:7aab896b1a3b 329 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_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);
kevman 2:7aab896b1a3b 330 TEST_ASSERT_MESSAGE(fp != NULL, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 331
kevman 2:7aab896b1a3b 332 len = strlen(node->value) + 1;
kevman 2:7aab896b1a3b 333 read_buf = (char *) malloc(len);
kevman 2:7aab896b1a3b 334 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: failed to allocated read buffer \n", __func__);
kevman 2:7aab896b1a3b 335 TEST_ASSERT_MESSAGE(read_buf != NULL, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 336
kevman 2:7aab896b1a3b 337 FSLITTLE_DBGLOG("Opened file successfully (filename=\"%s\", data=\"%s\")\n", node->filename, node->value);
kevman 2:7aab896b1a3b 338 memset(read_buf, 0, len);
kevman 2:7aab896b1a3b 339 ret = fread((void *) read_buf, len, 1, fp);
kevman 2:7aab896b1a3b 340 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_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);
kevman 2:7aab896b1a3b 341 /* FIX ME: fread should return the number of items read, not 0 when an item is read successfully.
kevman 2:7aab896b1a3b 342 * This indicates a problem with the implementation, as the correct data is read. The correct assert should be:
kevman 2:7aab896b1a3b 343 * TEST_ASSERT_MESSAGE(ret == 1, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 344 * The following assert is curerntly used until the implementation is fixed
kevman 2:7aab896b1a3b 345 */
kevman 2:7aab896b1a3b 346 TEST_ASSERT_MESSAGE(ret == 0, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 347
kevman 2:7aab896b1a3b 348 /* check read data is as expected */
kevman 2:7aab896b1a3b 349 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_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);
kevman 2:7aab896b1a3b 350 TEST_ASSERT_MESSAGE(strncmp(read_buf, node->value, strlen(node->value)) == 0, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 351
kevman 2:7aab896b1a3b 352 if (read_buf) {
kevman 2:7aab896b1a3b 353 free(read_buf);
kevman 2:7aab896b1a3b 354 }
kevman 2:7aab896b1a3b 355 ret = fclose(fp);
kevman 2:7aab896b1a3b 356 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: fclose() call failed (ret=%d, errno=%d).\n", __func__, (int) ret, errno);
kevman 2:7aab896b1a3b 357 TEST_ASSERT_MESSAGE(ret == 0, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 358 return CaseNext;
kevman 2:7aab896b1a3b 359 }
kevman 2:7aab896b1a3b 360
kevman 2:7aab896b1a3b 361 static fslittle_kv_data_t fslittle_fopen_test_02_data[] = {
kevman 2:7aab896b1a3b 362 FSLITTLE_INIT_1_TABLE_MID_NODE,
kevman 2:7aab896b1a3b 363 { NULL, NULL},
kevman 2:7aab896b1a3b 364 };
kevman 2:7aab896b1a3b 365
kevman 2:7aab896b1a3b 366 /**
kevman 2:7aab896b1a3b 367 * @brief test to fopen() a pre-existing key and try to write it, which should fail
kevman 2:7aab896b1a3b 368 * as by default pre-existing keys are opened read-only
kevman 2:7aab896b1a3b 369 *
kevman 2:7aab896b1a3b 370 * Basic open test which does the following:
kevman 2:7aab896b1a3b 371 * - creates file with default rw perms and writes some data to the value blob.
kevman 2:7aab896b1a3b 372 * - closes the newly created file.
kevman 2:7aab896b1a3b 373 * - opens the file with the default permissions (read-only)
kevman 2:7aab896b1a3b 374 * - tries to write the file data which should fail because file was not opened with write flag set.
kevman 2:7aab896b1a3b 375 * - closes the opened key
kevman 2:7aab896b1a3b 376 *
kevman 2:7aab896b1a3b 377 * @return on success returns CaseNext to continue to next test case, otherwise will assert on errors.
kevman 2:7aab896b1a3b 378 */
kevman 2:7aab896b1a3b 379 control_t fslittle_fopen_test_02(const size_t call_count)
kevman 2:7aab896b1a3b 380 {
kevman 2:7aab896b1a3b 381 int32_t ret = -1;
kevman 2:7aab896b1a3b 382 size_t len = 0;
kevman 2:7aab896b1a3b 383 FILE *fp = NULL;
kevman 2:7aab896b1a3b 384
kevman 2:7aab896b1a3b 385 FSLITTLE_FENTRYLOG("%s:entered\n", __func__);
kevman 2:7aab896b1a3b 386 (void) call_count;
kevman 2:7aab896b1a3b 387 len = strlen(fslittle_fopen_test_02_data[0].value);
kevman 2:7aab896b1a3b 388 ret = fslittle_test_create(fslittle_fopen_test_02_data[0].filename, (char *) fslittle_fopen_test_02_data[0].value, len);
kevman 2:7aab896b1a3b 389 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: failed to create file (ret=%d).\n", __func__, (int) ret);
kevman 2:7aab896b1a3b 390 TEST_ASSERT_MESSAGE(ret >= 0, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 391
kevman 2:7aab896b1a3b 392 /* by default, owner of key opens with read-only permissions*/
kevman 2:7aab896b1a3b 393 fp = fopen(fslittle_fopen_test_02_data[0].filename, "r");
kevman 2:7aab896b1a3b 394 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: failed to open file (filename=\"%s\", ret=%d)\n", __func__, fslittle_fopen_test_02_data[0].filename, (int) ret);
kevman 2:7aab896b1a3b 395 TEST_ASSERT_MESSAGE(fp != NULL, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 396
kevman 2:7aab896b1a3b 397 len = strlen(fslittle_fopen_test_02_data[0].value);
kevman 2:7aab896b1a3b 398 ret = fwrite((const void *) fslittle_fopen_test_02_data[0].value, len, 1, fp);
kevman 2:7aab896b1a3b 399 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: call to fwrite() succeeded when should have failed for read-only file (filename=\"%s\")(ret=%d).\n", __func__, fslittle_fopen_test_02_data[0].filename, (int) ret);
kevman 2:7aab896b1a3b 400 TEST_ASSERT_MESSAGE(ret <= 0, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 401
kevman 2:7aab896b1a3b 402 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: fclose() call failed.\n", __func__);
kevman 2:7aab896b1a3b 403 TEST_ASSERT_MESSAGE(fclose(fp) == 0, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 404
kevman 2:7aab896b1a3b 405 return CaseNext;
kevman 2:7aab896b1a3b 406 }
kevman 2:7aab896b1a3b 407
kevman 2:7aab896b1a3b 408
kevman 2:7aab896b1a3b 409 /**
kevman 2:7aab896b1a3b 410 * @brief test to fopen() a pre-existing file and try to write it, which should succeed
kevman 2:7aab896b1a3b 411 * because the key was opened read-write permissions explicitly
kevman 2:7aab896b1a3b 412 *
kevman 2:7aab896b1a3b 413 * Basic open test which does the following:
kevman 2:7aab896b1a3b 414 * - creates file with default rw perms and writes some data to the value blob.
kevman 2:7aab896b1a3b 415 * - closes the newly created file.
kevman 2:7aab896b1a3b 416 * - opens the file with the rw permissions (non default)
kevman 2:7aab896b1a3b 417 * - tries to write the file data which should succeeds because file was opened with write flag set.
kevman 2:7aab896b1a3b 418 * - closes the opened key
kevman 2:7aab896b1a3b 419 *
kevman 2:7aab896b1a3b 420 * @return on success returns CaseNext to continue to next test case, otherwise will assert on errors.
kevman 2:7aab896b1a3b 421 */
kevman 2:7aab896b1a3b 422 control_t fslittle_fopen_test_03(const size_t call_count)
kevman 2:7aab896b1a3b 423 {
kevman 2:7aab896b1a3b 424 int32_t ret = -1;
kevman 2:7aab896b1a3b 425 size_t len = 0;
kevman 2:7aab896b1a3b 426 FILE *fp = NULL;
kevman 2:7aab896b1a3b 427
kevman 2:7aab896b1a3b 428 FSLITTLE_FENTRYLOG("%s:entered\n", __func__);
kevman 2:7aab896b1a3b 429 (void) call_count;
kevman 2:7aab896b1a3b 430 len = strlen(fslittle_fopen_test_02_data[0].value);
kevman 2:7aab896b1a3b 431 ret = fslittle_test_create(fslittle_fopen_test_02_data[0].filename, (char *) fslittle_fopen_test_02_data[0].value, len);
kevman 2:7aab896b1a3b 432 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: failed to create file in store (ret=%d).\n", __func__, (int) ret);
kevman 2:7aab896b1a3b 433 TEST_ASSERT_MESSAGE(ret >= 0, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 434
kevman 2:7aab896b1a3b 435 /* opens with read-write permissions*/
kevman 2:7aab896b1a3b 436 fp = fopen(fslittle_fopen_test_02_data[0].filename, "w+");
kevman 2:7aab896b1a3b 437 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: failed to open file (filename=\"%s\")(ret=%d)\n", __func__, fslittle_fopen_test_02_data[0].filename, (int) ret);
kevman 2:7aab896b1a3b 438 TEST_ASSERT_MESSAGE(ret >= 0, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 439
kevman 2:7aab896b1a3b 440 len = strlen(fslittle_fopen_test_02_data[0].value);
kevman 2:7aab896b1a3b 441 ret = fwrite((const void *) fslittle_fopen_test_02_data[0].value, len, 1, fp);
kevman 2:7aab896b1a3b 442 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: call to fwrite() failed when should have succeeded (filename=\"%s\", ret=%d).\n", __func__, fslittle_fopen_test_02_data[0].filename, (int) ret);
kevman 2:7aab896b1a3b 443 TEST_ASSERT_MESSAGE(ret >= 0, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 444
kevman 2:7aab896b1a3b 445 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: fclose() call failed.\n", __func__);
kevman 2:7aab896b1a3b 446 TEST_ASSERT_MESSAGE(fclose(fp) >= 0, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 447
kevman 2:7aab896b1a3b 448 /* clean-up */
kevman 2:7aab896b1a3b 449 ret = remove(fslittle_fopen_test_02_data[0].filename);
kevman 2:7aab896b1a3b 450 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: unable to delete file (filename=%s, ret=%d) .\n", __func__, fslittle_fopen_test_02_data[0].filename, (int) ret);
kevman 2:7aab896b1a3b 451 TEST_ASSERT_MESSAGE(ret >= 0, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 452
kevman 2:7aab896b1a3b 453 return CaseNext;
kevman 2:7aab896b1a3b 454 }
kevman 2:7aab896b1a3b 455
kevman 2:7aab896b1a3b 456
kevman 2:7aab896b1a3b 457 /** @brief test to call fopen() with a filename string that exceeds the maximum length
kevman 2:7aab896b1a3b 458 * - check that filenames of this length can be created
kevman 2:7aab896b1a3b 459 *
kevman 2:7aab896b1a3b 460 * @return on success returns CaseNext to continue to next test case, otherwise will assert on errors.
kevman 2:7aab896b1a3b 461 */
kevman 2:7aab896b1a3b 462 control_t fslittle_fopen_test_04(const size_t call_count)
kevman 2:7aab896b1a3b 463 {
kevman 2:7aab896b1a3b 464 char filename_good[FSLITTLE_FILENAME_MAX_LENGTH + 1];
kevman 2:7aab896b1a3b 465 char filename_bad[FSLITTLE_FILENAME_MAX_LENGTH + 2];
kevman 2:7aab896b1a3b 466 int32_t ret = -1;
kevman 2:7aab896b1a3b 467 size_t len = 0;
kevman 2:7aab896b1a3b 468
kevman 2:7aab896b1a3b 469 FSLITTLE_FENTRYLOG("%s:entered\n", __func__);
kevman 2:7aab896b1a3b 470 (void) call_count;
kevman 2:7aab896b1a3b 471
kevman 2:7aab896b1a3b 472 memset(filename_good, 0, FSLITTLE_FILENAME_MAX_LENGTH + 1);
kevman 2:7aab896b1a3b 473 memset(filename_bad, 0, FSLITTLE_FILENAME_MAX_LENGTH + 2);
kevman 2:7aab896b1a3b 474 ret = fslittle_test_filename_gen(filename_good, FSLITTLE_FILENAME_MAX_LENGTH);
kevman 2:7aab896b1a3b 475 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: unable to generate filename_good.\n", __func__);
kevman 2:7aab896b1a3b 476 TEST_ASSERT_MESSAGE(ret >= 0, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 477
kevman 2:7aab896b1a3b 478 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_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) FSLITTLE_FILENAME_MAX_LENGTH);
kevman 2:7aab896b1a3b 479 TEST_ASSERT_MESSAGE(strlen(filename_good) == FSLITTLE_FILENAME_MAX_LENGTH, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 480
kevman 2:7aab896b1a3b 481 ret = fslittle_test_filename_gen(filename_bad, FSLITTLE_FILENAME_MAX_LENGTH + 1);
kevman 2:7aab896b1a3b 482 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: unable to generate filename_bad.\n", __func__);
kevman 2:7aab896b1a3b 483 TEST_ASSERT_MESSAGE(ret >= 0, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 484 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: filename_bad is not the correct length (len=%d, expected=%d).\n", __func__, (int) strlen(filename_bad), (int) FSLITTLE_FILENAME_MAX_LENGTH + 1);
kevman 2:7aab896b1a3b 485 TEST_ASSERT_MESSAGE(strlen(filename_bad) == FSLITTLE_FILENAME_MAX_LENGTH + 1, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 486
kevman 2:7aab896b1a3b 487 len = strlen(filename_good);
kevman 2:7aab896b1a3b 488 ret = fslittle_test_create(filename_good, filename_good, len);
kevman 2:7aab896b1a3b 489
kevman 2:7aab896b1a3b 490 len = strlen(filename_bad);
kevman 2:7aab896b1a3b 491 ret = fslittle_test_create(filename_bad, filename_bad, len);
kevman 2:7aab896b1a3b 492 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_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);
kevman 2:7aab896b1a3b 493 TEST_ASSERT_MESSAGE(ret < 0, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 494 return CaseNext;
kevman 2:7aab896b1a3b 495 }
kevman 2:7aab896b1a3b 496
kevman 2:7aab896b1a3b 497
kevman 2:7aab896b1a3b 498 /// @cond FSLITTLE_DOXYGEN_DISABLE
kevman 2:7aab896b1a3b 499 typedef struct fslittle_fopen_kv_name_ascii_node {
kevman 2:7aab896b1a3b 500 uint32_t code;
kevman 2:7aab896b1a3b 501 uint32_t f_allowed : 1;
kevman 2:7aab896b1a3b 502 } fslittle_fopen_kv_name_ascii_node;
kevman 2:7aab896b1a3b 503 /// @endcond
kevman 2:7aab896b1a3b 504
kevman 2:7aab896b1a3b 505 static const uint32_t fslittle_fopen_kv_name_ascii_table_code_sentinel_g = 256;
kevman 2:7aab896b1a3b 506
kevman 2:7aab896b1a3b 507 /*@brief table recording ascii character codes permitted in kv names */
kevman 2:7aab896b1a3b 508 static fslittle_fopen_kv_name_ascii_node fslittle_fopen_kv_name_ascii_table[] = {
kevman 2:7aab896b1a3b 509 {0, true}, /* code 0-33 allowed*/
kevman 2:7aab896b1a3b 510 {34, false}, /* '"' not allowed */
kevman 2:7aab896b1a3b 511 {35, true}, /* allowed */
kevman 2:7aab896b1a3b 512 {42, false}, /* '*' not allowed */
kevman 2:7aab896b1a3b 513 {43, true}, /* allowed */
kevman 2:7aab896b1a3b 514 {47, false}, /* '/' not allowed */
kevman 2:7aab896b1a3b 515 {48, true}, /* allowed */
kevman 2:7aab896b1a3b 516 {58, false}, /* ':' not allowed */
kevman 2:7aab896b1a3b 517 {59, true}, /* allowed */
kevman 2:7aab896b1a3b 518 {60, false}, /* '<' not allowed */
kevman 2:7aab896b1a3b 519 {61, true}, /* allowed */
kevman 2:7aab896b1a3b 520 {62, false}, /* '?', '>' not allowed */
kevman 2:7aab896b1a3b 521 {64, true}, /* allowed */
kevman 2:7aab896b1a3b 522 {92, false}, /* '\' not allowed */
kevman 2:7aab896b1a3b 523 {93, true}, /* allowed */
kevman 2:7aab896b1a3b 524 {124, false}, /* '!' not allowed */
kevman 2:7aab896b1a3b 525 {125, true}, /* allowed */
kevman 2:7aab896b1a3b 526 {127, false}, /* DEL not allowed */
kevman 2:7aab896b1a3b 527 {128, true}, /* allowed */
kevman 2:7aab896b1a3b 528 {fslittle_fopen_kv_name_ascii_table_code_sentinel_g, false}, /* sentinel */
kevman 2:7aab896b1a3b 529 };
kevman 2:7aab896b1a3b 530
kevman 2:7aab896b1a3b 531
kevman 2:7aab896b1a3b 532 /// @cond FSLITTLE_DOXYGEN_DISABLE
kevman 2:7aab896b1a3b 533 enum fslittle_fopen_kv_name_pos {
kevman 2:7aab896b1a3b 534 fslittle_fopen_kv_name_pos_start = 0x0,
kevman 2:7aab896b1a3b 535 fslittle_fopen_kv_name_pos_mid,
kevman 2:7aab896b1a3b 536 fslittle_fopen_kv_name_pos_end,
kevman 2:7aab896b1a3b 537 fslittle_fopen_kv_name_pos_max
kevman 2:7aab896b1a3b 538 };
kevman 2:7aab896b1a3b 539 /// @endcond
kevman 2:7aab896b1a3b 540
kevman 2:7aab896b1a3b 541 /** @brief test to call fopen() with filename that in includes illegal characters
kevman 2:7aab896b1a3b 542 * - the character(s) can be at the beginning of the filename
kevman 2:7aab896b1a3b 543 * - the character(s) can be at the end of the filename
kevman 2:7aab896b1a3b 544 * - the character(s) can be somewhere within the filename string
kevman 2:7aab896b1a3b 545 * - a max-length string of random characters (legal and illegal)
kevman 2:7aab896b1a3b 546 * - a max-length string of random illegal characters only
kevman 2:7aab896b1a3b 547 *
kevman 2:7aab896b1a3b 548 * @return on success returns CaseNext to continue to next test case, otherwise will assert on errors.
kevman 2:7aab896b1a3b 549 */
kevman 2:7aab896b1a3b 550 control_t fslittle_fopen_test_05(const size_t call_count)
kevman 2:7aab896b1a3b 551 {
kevman 2:7aab896b1a3b 552 bool f_allowed = false;
kevman 2:7aab896b1a3b 553 const char *mnt_pt = FSLITTLE_FOPEN_TEST_MOUNT_PT_PATH;
kevman 2:7aab896b1a3b 554 const char *basename = "goodfile";
kevman 2:7aab896b1a3b 555 const char *extname = "txt";
kevman 2:7aab896b1a3b 556 const size_t basename_len = strlen(basename);
kevman 2:7aab896b1a3b 557 const size_t filename_len = strlen(mnt_pt) + strlen(basename) + strlen(extname) + 2; /* extra 2 chars for '/' and '.' in "/sd/goodfile.txt" */
kevman 2:7aab896b1a3b 558 char filename[FSLITTLE_BUF_MAX_LENGTH];
kevman 2:7aab896b1a3b 559 size_t len = 0;
kevman 2:7aab896b1a3b 560 uint32_t j = 0;
kevman 2:7aab896b1a3b 561 int32_t ret = 0;
kevman 2:7aab896b1a3b 562 fslittle_fopen_kv_name_ascii_node *node = NULL;
kevman 2:7aab896b1a3b 563 uint32_t pos;
kevman 2:7aab896b1a3b 564
kevman 2:7aab896b1a3b 565 FSLITTLE_FENTRYLOG("%s:entered\n", __func__);
kevman 2:7aab896b1a3b 566 (void) call_count;
kevman 2:7aab896b1a3b 567
kevman 2:7aab896b1a3b 568 #ifdef FSLITTLE_DEBUG
kevman 2:7aab896b1a3b 569 /* symbol only used why debug is enabled */
kevman 2:7aab896b1a3b 570 const char *pos_str = NULL;
kevman 2:7aab896b1a3b 571 #endif
kevman 2:7aab896b1a3b 572
kevman 2:7aab896b1a3b 573 /* create bad keyname strings with invalid character code at start of keyname */
kevman 2:7aab896b1a3b 574 node = fslittle_fopen_kv_name_ascii_table;
kevman 2:7aab896b1a3b 575 memset(filename, 0, FSLITTLE_BUF_MAX_LENGTH);
kevman 2:7aab896b1a3b 576 while (node->code != fslittle_fopen_kv_name_ascii_table_code_sentinel_g) {
kevman 2:7aab896b1a3b 577 /* loop over range */
kevman 2:7aab896b1a3b 578 for (j = node->code; j < (node + 1)->code; j++) {
kevman 2:7aab896b1a3b 579 if ((j >= 48 && j <= 57) || (j >= 65 && j <= 90) || (j >= 97 && j <= 122)) {
kevman 2:7aab896b1a3b 580 FSLITTLE_DBGLOG("%s: skipping alpha-numeric ascii character code %d (%c).\n", __func__, (int) j, (char) j);
kevman 2:7aab896b1a3b 581 continue;
kevman 2:7aab896b1a3b 582 }
kevman 2:7aab896b1a3b 583
kevman 2:7aab896b1a3b 584 /* set the start, mid, last character of the name to the test char code */
kevman 2:7aab896b1a3b 585 for (pos = (uint32_t) fslittle_fopen_kv_name_pos_start; pos < (uint32_t) fslittle_fopen_kv_name_pos_max; pos++) {
kevman 2:7aab896b1a3b 586 len = snprintf(filename, filename_len + 1, "%s/%s.%s", mnt_pt, basename, extname);
kevman 2:7aab896b1a3b 587 /* overwrite a char at the pos start, mid, end of the filename with an ascii char code (both illegal and legal)*/
kevman 2:7aab896b1a3b 588 switch (pos) {
kevman 2:7aab896b1a3b 589 case fslittle_fopen_kv_name_pos_start:
kevman 2:7aab896b1a3b 590 filename[5] = (char) j; /* 5 so at to write the second basename char (bad chars as first char not accepted)*/
kevman 2:7aab896b1a3b 591 break;
kevman 2:7aab896b1a3b 592 case fslittle_fopen_kv_name_pos_mid:
kevman 2:7aab896b1a3b 593 /* create bad keyname strings with invalid character code in the middle of keyname */
kevman 2:7aab896b1a3b 594 filename[5 + basename_len / 2] = (char) j;
kevman 2:7aab896b1a3b 595 break;
kevman 2:7aab896b1a3b 596 case fslittle_fopen_kv_name_pos_end:
kevman 2:7aab896b1a3b 597 /* create bad keyname strings with invalid character code at end of keyname */
kevman 2:7aab896b1a3b 598 filename[5 + basename_len - 1] = (char) j;
kevman 2:7aab896b1a3b 599 break;
kevman 2:7aab896b1a3b 600 default:
kevman 2:7aab896b1a3b 601 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: unexpected value of pos (pos=%d).\n", __func__, (int) pos);
kevman 2:7aab896b1a3b 602 TEST_ASSERT_MESSAGE(ret >= 0, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 603 break;
kevman 2:7aab896b1a3b 604 }
kevman 2:7aab896b1a3b 605
kevman 2:7aab896b1a3b 606 #ifdef FSLITTLE_DEBUG
kevman 2:7aab896b1a3b 607 /* processing only required when debug trace enabled */
kevman 2:7aab896b1a3b 608 switch (pos) {
kevman 2:7aab896b1a3b 609 case fslittle_fopen_kv_name_pos_start:
kevman 2:7aab896b1a3b 610 pos_str = "start";
kevman 2:7aab896b1a3b 611 break;
kevman 2:7aab896b1a3b 612 case fslittle_fopen_kv_name_pos_mid:
kevman 2:7aab896b1a3b 613 pos_str = "middle";
kevman 2:7aab896b1a3b 614 break;
kevman 2:7aab896b1a3b 615 case fslittle_fopen_kv_name_pos_end:
kevman 2:7aab896b1a3b 616 pos_str = "end";
kevman 2:7aab896b1a3b 617 break;
kevman 2:7aab896b1a3b 618 default:
kevman 2:7aab896b1a3b 619 break;
kevman 2:7aab896b1a3b 620 }
kevman 2:7aab896b1a3b 621 #endif
kevman 2:7aab896b1a3b 622 ret = fslittle_test_create(filename, (const char *) filename, len);
kevman 2:7aab896b1a3b 623
kevman 2:7aab896b1a3b 624 /* special cases */
kevman 2:7aab896b1a3b 625 switch (j) {
kevman 2:7aab896b1a3b 626 //case 0 :
kevman 2:7aab896b1a3b 627 //case 46 :
kevman 2:7aab896b1a3b 628 // switch(pos)
kevman 2:7aab896b1a3b 629 // {
kevman 2:7aab896b1a3b 630 // /* for code = 0 (null terminator). permitted at mid and end of string */
kevman 2:7aab896b1a3b 631 // /* for code = 46 ('.'). permitted at mid and end of string but not at start */
kevman 2:7aab896b1a3b 632 // case fslittle_fopen_kv_name_pos_start:
kevman 2:7aab896b1a3b 633 // f_allowed = false;
kevman 2:7aab896b1a3b 634 // break;
kevman 2:7aab896b1a3b 635 // case fslittle_fopen_kv_name_pos_mid:
kevman 2:7aab896b1a3b 636 // case fslittle_fopen_kv_name_pos_end:
kevman 2:7aab896b1a3b 637 // default:
kevman 2:7aab896b1a3b 638 // f_allowed = true;
kevman 2:7aab896b1a3b 639 // break;
kevman 2:7aab896b1a3b 640 // }
kevman 2:7aab896b1a3b 641 // break;
kevman 2:7aab896b1a3b 642 default:
kevman 2:7aab896b1a3b 643 f_allowed = node->f_allowed;
kevman 2:7aab896b1a3b 644 break;
kevman 2:7aab896b1a3b 645 }
kevman 2:7aab896b1a3b 646 if (f_allowed == true) {
kevman 2:7aab896b1a3b 647 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_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);
kevman 2:7aab896b1a3b 648 TEST_ASSERT_MESSAGE(ret >= 0, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 649 /* revert FSLITTLE_LOG for more trace */
kevman 2:7aab896b1a3b 650 FSLITTLE_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);
kevman 2:7aab896b1a3b 651 FSLITTLE_LOG("%c", '.');
kevman 2:7aab896b1a3b 652
kevman 2:7aab896b1a3b 653 ret = fslittle_test_delete(filename);
kevman 2:7aab896b1a3b 654 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: failed to delete file previously created (code=%d, ret=%d).\n", __func__, (int) j, (int) ret);
kevman 2:7aab896b1a3b 655 TEST_ASSERT_MESSAGE(ret >= 0, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 656 } else {
kevman 2:7aab896b1a3b 657 /*node->f_allowed == false => not allowed to create kv name with ascii code */
kevman 2:7aab896b1a3b 658 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_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);
kevman 2:7aab896b1a3b 659 TEST_ASSERT_MESSAGE(ret < 0, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 660 /* revert FSLITTLE_LOG for more trace */
kevman 2:7aab896b1a3b 661 FSLITTLE_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);
kevman 2:7aab896b1a3b 662 FSLITTLE_LOG("%c", '.');
kevman 2:7aab896b1a3b 663 }
kevman 2:7aab896b1a3b 664 }
kevman 2:7aab896b1a3b 665 }
kevman 2:7aab896b1a3b 666 node++;
kevman 2:7aab896b1a3b 667 }
kevman 2:7aab896b1a3b 668
kevman 2:7aab896b1a3b 669 FSLITTLE_LOG("%c", '\n');
kevman 2:7aab896b1a3b 670 return CaseNext;
kevman 2:7aab896b1a3b 671 }
kevman 2:7aab896b1a3b 672
kevman 2:7aab896b1a3b 673
kevman 2:7aab896b1a3b 674 static const char fslittle_fopen_ascii_illegal_buf_g[] = "\"?'*+,./:;<=>?[\\]|";
kevman 2:7aab896b1a3b 675
kevman 2:7aab896b1a3b 676 /** @brief test to call fopen() with filename that in includes
kevman 2:7aab896b1a3b 677 * illegal characters
kevman 2:7aab896b1a3b 678 * - a max-length string of random illegal characters only
kevman 2:7aab896b1a3b 679 *
kevman 2:7aab896b1a3b 680 * @return on success returns CaseNext to continue to next test case, otherwise will assert on errors.
kevman 2:7aab896b1a3b 681 */
kevman 2:7aab896b1a3b 682 control_t fslittle_fopen_test_06(const size_t call_count)
kevman 2:7aab896b1a3b 683 {
kevman 2:7aab896b1a3b 684 // legal in LittleFS
kevman 2:7aab896b1a3b 685 #if 0
kevman 2:7aab896b1a3b 686 const char *mnt_pt = FSLITTLE_FOPEN_TEST_MOUNT_PT_PATH;
kevman 2:7aab896b1a3b 687 const char *extname = "txt";
kevman 2:7aab896b1a3b 688 const size_t filename_len = strlen(mnt_pt) + FSLITTLE_MAX_FILE_BASENAME + strlen(extname) + 2; /* extra 2 chars for '/' and '.' in "/sd/goodfile.txt" */
kevman 2:7aab896b1a3b 689 char filename[FSLITTLE_BUF_MAX_LENGTH];
kevman 2:7aab896b1a3b 690 int32_t i = 0;
kevman 2:7aab896b1a3b 691 int32_t j = 0;
kevman 2:7aab896b1a3b 692 uint32_t pos = 0;
kevman 2:7aab896b1a3b 693 uint32_t len = 0;
kevman 2:7aab896b1a3b 694 int32_t ret = -1;
kevman 2:7aab896b1a3b 695 size_t buf_data_max = 0;
kevman 2:7aab896b1a3b 696
kevman 2:7aab896b1a3b 697 FSLITTLE_FENTRYLOG("%s:entered\n", __func__);
kevman 2:7aab896b1a3b 698 (void) call_count;
kevman 2:7aab896b1a3b 699
kevman 2:7aab896b1a3b 700 memset(filename, 0, FSLITTLE_BUF_MAX_LENGTH);
kevman 2:7aab896b1a3b 701 /* create bad keyname strings with invalid character code at start of keyname */
kevman 2:7aab896b1a3b 702 buf_data_max = strlen(fslittle_fopen_ascii_illegal_buf_g);
kevman 2:7aab896b1a3b 703
kevman 2:7aab896b1a3b 704 /* generate a number of illegal filenames */
kevman 2:7aab896b1a3b 705 for (j = 0; i < FSLITTLE_MAX_FILE_BASENAME; j++) {
kevman 2:7aab896b1a3b 706 /* generate a kv name of illegal chars*/
kevman 2:7aab896b1a3b 707 len = snprintf(filename, filename_len + 1, "%s/", mnt_pt);
kevman 2:7aab896b1a3b 708 for (i = 0; i < FSLITTLE_MAX_FILE_BASENAME; i++) {
kevman 2:7aab896b1a3b 709 pos = rand() % (buf_data_max + 1);
kevman 2:7aab896b1a3b 710 len += snprintf(filename + len, filename_len + 1, "%c", fslittle_fopen_ascii_illegal_buf_g[pos]);
kevman 2:7aab896b1a3b 711
kevman 2:7aab896b1a3b 712 }
kevman 2:7aab896b1a3b 713 len += snprintf(filename + len, filename_len + 1, ".%s", extname);
kevman 2:7aab896b1a3b 714 ret = fslittle_test_create(filename, filename, len);
kevman 2:7aab896b1a3b 715 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: created file when filename contains invalid characters (filename=%s, ret=%d).\n", __func__, filename, (int) ret);
kevman 2:7aab896b1a3b 716 TEST_ASSERT_MESSAGE(ret < 0, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 717 }
kevman 2:7aab896b1a3b 718 #endif
kevman 2:7aab896b1a3b 719 return CaseNext;
kevman 2:7aab896b1a3b 720 }
kevman 2:7aab896b1a3b 721
kevman 2:7aab896b1a3b 722
kevman 2:7aab896b1a3b 723 /** @brief test for errno reporting on a failed fopen()call
kevman 2:7aab896b1a3b 724 *
kevman 2:7aab896b1a3b 725 * This test does the following:
kevman 2:7aab896b1a3b 726 * - tries to open a file that does not exist for reading, and checks that a NULL pointer is returned.
kevman 2:7aab896b1a3b 727 * - checks that errno is not 0 as there is an error.
kevman 2:7aab896b1a3b 728 * - checks that ferror() returns 1 indicating an error exists.
kevman 2:7aab896b1a3b 729 *
kevman 2:7aab896b1a3b 730 * Note: see NOTE_1 below.
kevman 2:7aab896b1a3b 731 *
kevman 2:7aab896b1a3b 732 * @return on success returns CaseNext to continue to next test case, otherwise will assert on errors.
kevman 2:7aab896b1a3b 733 */
kevman 2:7aab896b1a3b 734 control_t fslittle_fopen_test_07(const size_t call_count)
kevman 2:7aab896b1a3b 735 {
kevman 2:7aab896b1a3b 736 FILE *f = NULL;
kevman 2:7aab896b1a3b 737 int ret = -1;
kevman 2:7aab896b1a3b 738 int errno_val = 0;
kevman 2:7aab896b1a3b 739 const char *filename = sd_badfile_path;
kevman 2:7aab896b1a3b 740
kevman 2:7aab896b1a3b 741 FSLITTLE_FENTRYLOG("%s:entered\n", __func__);
kevman 2:7aab896b1a3b 742 (void) call_count;
kevman 2:7aab896b1a3b 743
kevman 2:7aab896b1a3b 744 errno = 0;
kevman 2:7aab896b1a3b 745 /* this is expect to fail as the file doesnt exist */
kevman 2:7aab896b1a3b 746 f = fopen(filename, "r");
kevman 2:7aab896b1a3b 747
kevman 2:7aab896b1a3b 748 /* Store errno so the current value set is not changed by new function call */
kevman 2:7aab896b1a3b 749 errno_val = errno;
kevman 2:7aab896b1a3b 750
kevman 2:7aab896b1a3b 751 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: opened non-existent file for reading (filename=%s, f=%p).\n", __func__, filename, f);
kevman 2:7aab896b1a3b 752 TEST_ASSERT_MESSAGE(f == NULL, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 753
kevman 2:7aab896b1a3b 754 /* check errno is set correctly */
kevman 2:7aab896b1a3b 755 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: errno has unexpected value (errno != 0 expected) (filename=%s, errno=%d).\n", __func__, filename, errno);
kevman 2:7aab896b1a3b 756 TEST_ASSERT_MESSAGE(errno_val != 0, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 757
kevman 2:7aab896b1a3b 758 return CaseNext;
kevman 2:7aab896b1a3b 759 }
kevman 2:7aab896b1a3b 760
kevman 2:7aab896b1a3b 761
kevman 2:7aab896b1a3b 762 /** @brief test for operation of clearerr() and ferror()
kevman 2:7aab896b1a3b 763 *
kevman 2:7aab896b1a3b 764 * The test does the following:
kevman 2:7aab896b1a3b 765 * - opens and then closes a file, but keeps a copy of the FILE pointer fp.
kevman 2:7aab896b1a3b 766 * - set errno to 0.
kevman 2:7aab896b1a3b 767 * - write to the close file with fwrite(fp) which should return 0 (no writes) and set the errno.
kevman 2:7aab896b1a3b 768 * - check the error condition is set with ferror().
kevman 2:7aab896b1a3b 769 * - clear the error with clearerr().
kevman 2:7aab896b1a3b 770 * - check the error condition is reset with ferror().
kevman 2:7aab896b1a3b 771 *
kevman 2:7aab896b1a3b 772 * NOTE_1: GCC/ARMCC support for setting errno
kevman 2:7aab896b1a3b 773 * - Documentation (e.g. fwrite() man page) does not explicity say fwrite() sets errno
kevman 2:7aab896b1a3b 774 * (e.g. for an fwrite() on a read-only file).
kevman 2:7aab896b1a3b 775 * - GCC libc fwrite() appears to set errno as expected.
kevman 2:7aab896b1a3b 776 * - ARMCC & IAR libc fwrite() appears not to set errno.
kevman 2:7aab896b1a3b 777 *
kevman 2:7aab896b1a3b 778 * The following ARMCC documents are silent on whether fwrite() sets errno:
kevman 2:7aab896b1a3b 779 * - "ARM C and C++ Libraries and Floating-Point Support".
kevman 2:7aab896b1a3b 780 * - "RL-ARM User Guide fwrite() section".
kevman 2:7aab896b1a3b 781 *
kevman 2:7aab896b1a3b 782 * @return on success returns CaseNext to continue to next test case, otherwise will assert on errors.
kevman 2:7aab896b1a3b 783 */
kevman 2:7aab896b1a3b 784 control_t fslittle_fopen_test_08(const size_t call_count)
kevman 2:7aab896b1a3b 785 {
kevman 2:7aab896b1a3b 786 FILE *fp = NULL;
kevman 2:7aab896b1a3b 787 int ret = -1;
kevman 2:7aab896b1a3b 788 int ret_ferror = -1;
kevman 2:7aab896b1a3b 789 const char *filename = sd_testfile_path;
kevman 2:7aab896b1a3b 790
kevman 2:7aab896b1a3b 791 FSLITTLE_FENTRYLOG("%s:entered\n", __func__);
kevman 2:7aab896b1a3b 792 (void) call_count;
kevman 2:7aab896b1a3b 793
kevman 2:7aab896b1a3b 794 errno = 0;
kevman 2:7aab896b1a3b 795 fp = fopen(filename, "w+");
kevman 2:7aab896b1a3b 796 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: failed to open file (filename=%s, f=%p).\n", __func__, filename, fp);
kevman 2:7aab896b1a3b 797 TEST_ASSERT_MESSAGE(fp != NULL, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 798
kevman 2:7aab896b1a3b 799 /* close the fp but then try to read or write it */
kevman 2:7aab896b1a3b 800 ret = fclose(fp);
kevman 2:7aab896b1a3b 801 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: failed to close file (ret=%d, errno=%d)\n", __func__, (int) ret, errno);
kevman 2:7aab896b1a3b 802 TEST_ASSERT_MESSAGE(ret == 0, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 803
kevman 2:7aab896b1a3b 804 /* open file */
kevman 2:7aab896b1a3b 805 errno = 0;
kevman 2:7aab896b1a3b 806 fp = fopen(filename, "r");
kevman 2:7aab896b1a3b 807 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: failed to open file for reading (filename=\"%s\", ret=%d)\n", __func__, filename, (int) ret);
kevman 2:7aab896b1a3b 808 TEST_ASSERT_MESSAGE(fp != NULL, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 809
kevman 2:7aab896b1a3b 810 /* Perform fwrite() operation that will fail. */
kevman 2:7aab896b1a3b 811 errno = 0;
kevman 2:7aab896b1a3b 812 ret = fwrite("42!", 4, 1, fp);
kevman 2:7aab896b1a3b 813
kevman 2:7aab896b1a3b 814 ret_ferror = ferror(fp);
kevman 2:7aab896b1a3b 815 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: ferror() failed to report error (filename=%s, ret_ferror=%d).\n", __func__, filename, (int) ret_ferror);
kevman 2:7aab896b1a3b 816 TEST_ASSERT_MESSAGE(ret_ferror != 0, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 817
kevman 2:7aab896b1a3b 818 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: fwrite successfully wrote to read-only file (filename=%s, ret=%d).\n", __func__, filename, (int) ret);
kevman 2:7aab896b1a3b 819 /* the fwrite() should fail and return 0. */
kevman 2:7aab896b1a3b 820 TEST_ASSERT_MESSAGE(ret == 0, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 821
kevman 2:7aab896b1a3b 822 #if ! defined(__ARMCC_VERSION) && defined(__GNUC__)
kevman 2:7aab896b1a3b 823 /* check that errno is set. ARMCC appears not to set errno for fwrite() failure. */
kevman 2:7aab896b1a3b 824 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: unexpected zero value for errno (filename=%s, ret=%d, errno=%d).\n", __func__, filename, (int) ret, errno);
kevman 2:7aab896b1a3b 825 TEST_ASSERT_MESSAGE(errno != 0, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 826
kevman 2:7aab896b1a3b 827 /* check that errno is set to the expected value (this may change differ for different libc's) */
kevman 2:7aab896b1a3b 828 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: errno != EBADF (filename=%s, ret=%d, errno=%d).\n", __func__, filename, (int) ret, errno);
kevman 2:7aab896b1a3b 829 TEST_ASSERT_MESSAGE(errno == EBADF, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 830 #endif /* ! defined(__ARMCC_VERSION) && defined(__GNUC__) */
kevman 2:7aab896b1a3b 831
kevman 2:7aab896b1a3b 832 /* check clearerr() return clears the error */
kevman 2:7aab896b1a3b 833 clearerr(fp);
kevman 2:7aab896b1a3b 834 ret = ferror(fp);
kevman 2:7aab896b1a3b 835 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_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);
kevman 2:7aab896b1a3b 836 TEST_ASSERT_MESSAGE(ret == 0, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 837
kevman 2:7aab896b1a3b 838 fclose(fp);
kevman 2:7aab896b1a3b 839 return CaseNext;
kevman 2:7aab896b1a3b 840 }
kevman 2:7aab896b1a3b 841
kevman 2:7aab896b1a3b 842
kevman 2:7aab896b1a3b 843 /** @brief test for operation of ftell()
kevman 2:7aab896b1a3b 844 *
kevman 2:7aab896b1a3b 845 * @return on success returns CaseNext to continue to next test case, otherwise will assert on errors.
kevman 2:7aab896b1a3b 846 */
kevman 2:7aab896b1a3b 847 control_t fslittle_fopen_test_09(const size_t call_count)
kevman 2:7aab896b1a3b 848 {
kevman 2:7aab896b1a3b 849 FILE *fp = NULL;
kevman 2:7aab896b1a3b 850 int ret = -1;
kevman 2:7aab896b1a3b 851 int32_t len = 0;
kevman 2:7aab896b1a3b 852
kevman 2:7aab896b1a3b 853 FSLITTLE_FENTRYLOG("%s:entered\n", __func__);
kevman 2:7aab896b1a3b 854 (void) call_count;
kevman 2:7aab896b1a3b 855
kevman 2:7aab896b1a3b 856 /* create a file of a certain length */
kevman 2:7aab896b1a3b 857 len = strlen(fslittle_fopen_test_02_data[0].value);
kevman 2:7aab896b1a3b 858 ret = fslittle_test_create(fslittle_fopen_test_02_data[0].filename, (char *) fslittle_fopen_test_02_data[0].value, len);
kevman 2:7aab896b1a3b 859
kevman 2:7aab896b1a3b 860 errno = 0;
kevman 2:7aab896b1a3b 861 /* Open the file for reading so the file is not truncated to 0 length. */
kevman 2:7aab896b1a3b 862 fp = fopen(fslittle_fopen_test_02_data[0].filename, "r");
kevman 2:7aab896b1a3b 863 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: failed to open file (filename=%s, fp=%p, errno=%d).\n", __func__, fslittle_fopen_test_02_data[0].filename, fp, errno);
kevman 2:7aab896b1a3b 864 TEST_ASSERT_MESSAGE(fp != NULL, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 865
kevman 2:7aab896b1a3b 866 errno = 0;
kevman 2:7aab896b1a3b 867 ret = fseek(fp, 0, SEEK_END);
kevman 2:7aab896b1a3b 868 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: fseek() failed to SEEK_END (filename=%s, ret=%d, errno=%d).\n", __func__, fslittle_fopen_test_02_data[0].filename, (int) ret, errno);
kevman 2:7aab896b1a3b 869 TEST_ASSERT_MESSAGE(ret == 0, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 870
kevman 2:7aab896b1a3b 871 errno = 0;
kevman 2:7aab896b1a3b 872 ret = ftell(fp);
kevman 2:7aab896b1a3b 873 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: ftell() failed to report correct offset value (filename=%s, ret=%d, errno=%d).\n", __func__, fslittle_fopen_test_02_data[0].filename, (int) ret, errno);
kevman 2:7aab896b1a3b 874 TEST_ASSERT_MESSAGE(ret == len, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 875
kevman 2:7aab896b1a3b 876 errno = 0;
kevman 2:7aab896b1a3b 877 ret = fclose(fp);
kevman 2:7aab896b1a3b 878 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: failed to close file (ret=%d, errno=%d)\n", __func__, (int) ret, errno);
kevman 2:7aab896b1a3b 879 TEST_ASSERT_MESSAGE(ret == 0, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 880
kevman 2:7aab896b1a3b 881 return CaseNext;
kevman 2:7aab896b1a3b 882 }
kevman 2:7aab896b1a3b 883
kevman 2:7aab896b1a3b 884
kevman 2:7aab896b1a3b 885 /* file data for test_10 */
kevman 2:7aab896b1a3b 886 static fslittle_kv_data_t fslittle_fopen_test_10_kv_data[] = {
kevman 2:7aab896b1a3b 887 { "/sd/test_10/testfile.txt", "test_data"},
kevman 2:7aab896b1a3b 888 { NULL, NULL},
kevman 2:7aab896b1a3b 889 };
kevman 2:7aab896b1a3b 890
kevman 2:7aab896b1a3b 891 /** @brief test for operation of remove()
kevman 2:7aab896b1a3b 892 *
kevman 2:7aab896b1a3b 893 * Performs the following tests:
kevman 2:7aab896b1a3b 894 * 1. test remove() on a file that exists. This should succeed.
kevman 2:7aab896b1a3b 895 * 2. test remove() on a dir that exists. This should succeed.
kevman 2:7aab896b1a3b 896 * 3. test remove() on a file that doesnt exist. This should fail. check errno set.
kevman 2:7aab896b1a3b 897 * 4. test remove() on a dir that doesnt exist. This should fail. check errno set.
kevman 2:7aab896b1a3b 898 *
kevman 2:7aab896b1a3b 899 * @return on success returns CaseNext to continue to next test case, otherwise will assert on errors.
kevman 2:7aab896b1a3b 900 */
kevman 2:7aab896b1a3b 901 control_t fslittle_fopen_test_10(const size_t call_count)
kevman 2:7aab896b1a3b 902 {
kevman 2:7aab896b1a3b 903 char buf[FSLITTLE_FOPEN_TEST_WORK_BUF_SIZE_1];
kevman 2:7aab896b1a3b 904 char *pos = NULL;
kevman 2:7aab896b1a3b 905 int32_t ret = -1;
kevman 2:7aab896b1a3b 906 size_t len = 0;
kevman 2:7aab896b1a3b 907 fslittle_kv_data_t *node = fslittle_fopen_test_10_kv_data;
kevman 2:7aab896b1a3b 908
kevman 2:7aab896b1a3b 909 FSLITTLE_FENTRYLOG("%s:entered\n", __func__);
kevman 2:7aab896b1a3b 910 (void) call_count;
kevman 2:7aab896b1a3b 911
kevman 2:7aab896b1a3b 912 TEST_ASSERT(strlen(node->filename) < FSLITTLE_FOPEN_TEST_WORK_BUF_SIZE_1);
kevman 2:7aab896b1a3b 913
kevman 2:7aab896b1a3b 914 /* start from a known state i.e. directory to be created in not present */
kevman 2:7aab896b1a3b 915 fslittle_filepath_remove_all((char *) node->filename);
kevman 2:7aab896b1a3b 916
kevman 2:7aab896b1a3b 917 /* (1) */
kevman 2:7aab896b1a3b 918 errno = 0;
kevman 2:7aab896b1a3b 919 ret = fslittle_filepath_make_dirs((char *) node->filename, false);
kevman 2:7aab896b1a3b 920 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: failed to create dir (dirname=%s, ret=%d, errno=%d)\n", __func__, node->filename, (int) ret, errno);
kevman 2:7aab896b1a3b 921 TEST_ASSERT_MESSAGE(ret == 0, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 922
kevman 2:7aab896b1a3b 923 len = strlen(node->value);
kevman 2:7aab896b1a3b 924 ret = fslittle_test_create(node->filename, (char *) node->value, len);
kevman 2:7aab896b1a3b 925 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: failed to create file (ret=%d).\n", __func__, (int) ret);
kevman 2:7aab896b1a3b 926 TEST_ASSERT_MESSAGE(ret >= 0, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 927
kevman 2:7aab896b1a3b 928 ret = remove(node->filename);
kevman 2:7aab896b1a3b 929 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: delete file operation failed (filename=%s, ret=%d) .\n", __func__, node->filename, (int) ret);
kevman 2:7aab896b1a3b 930 TEST_ASSERT_MESSAGE(ret == 0, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 931
kevman 2:7aab896b1a3b 932 /* (3) */
kevman 2:7aab896b1a3b 933 ret = remove(node->filename);
kevman 2:7aab896b1a3b 934 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_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);
kevman 2:7aab896b1a3b 935 TEST_ASSERT_MESSAGE(ret != 0, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 936
kevman 2:7aab896b1a3b 937 /* (2) */
kevman 2:7aab896b1a3b 938 memset(buf, 0, FSLITTLE_FOPEN_TEST_WORK_BUF_SIZE_1);
kevman 2:7aab896b1a3b 939 memcpy(buf, node->filename, strlen(node->filename));
kevman 2:7aab896b1a3b 940 pos = strrchr(buf, '/');
kevman 2:7aab896b1a3b 941 *pos = '\0';
kevman 2:7aab896b1a3b 942 ret = remove(buf);
kevman 2:7aab896b1a3b 943 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: delete directory operation failed (directory name=%s, ret=%d, errno=%d).\n", __func__, buf, (int) ret, errno);
kevman 2:7aab896b1a3b 944 TEST_ASSERT_MESSAGE(ret == 0, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 945
kevman 2:7aab896b1a3b 946 /* (4) */
kevman 2:7aab896b1a3b 947 ret = remove(buf);
kevman 2:7aab896b1a3b 948 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_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);
kevman 2:7aab896b1a3b 949 TEST_ASSERT_MESSAGE(ret != 0, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 950
kevman 2:7aab896b1a3b 951 return CaseNext;
kevman 2:7aab896b1a3b 952 }
kevman 2:7aab896b1a3b 953
kevman 2:7aab896b1a3b 954
kevman 2:7aab896b1a3b 955 /* file data for test_11 */
kevman 2:7aab896b1a3b 956 static fslittle_kv_data_t fslittle_fopen_test_11_kv_data[] = {
kevman 2:7aab896b1a3b 957 { "/sd/test_11/step0.txt", "test_data"},
kevman 2:7aab896b1a3b 958 { "/sd/test_11/step1.txt", "test_data"},
kevman 2:7aab896b1a3b 959 { "/sd/test_11/subdir/step3.txt", "test_data"},
kevman 2:7aab896b1a3b 960 { NULL, NULL},
kevman 2:7aab896b1a3b 961 };
kevman 2:7aab896b1a3b 962
kevman 2:7aab896b1a3b 963 /** @brief test for operation of rename()
kevman 2:7aab896b1a3b 964 *
kevman 2:7aab896b1a3b 965 * This test does the following:
kevman 2:7aab896b1a3b 966 * 1) test rename() on a file that exists to a new filename within the same directory.
kevman 2:7aab896b1a3b 967 * 2) test rename() on a file that exists to a new filename within a different directory.
kevman 2:7aab896b1a3b 968 *
kevman 2:7aab896b1a3b 969 * @return on success returns CaseNext to continue to next test case, otherwise will assert on errors.
kevman 2:7aab896b1a3b 970 */
kevman 2:7aab896b1a3b 971 control_t fslittle_fopen_test_11(const size_t call_count)
kevman 2:7aab896b1a3b 972 {
kevman 2:7aab896b1a3b 973 int32_t ret = -1;
kevman 2:7aab896b1a3b 974 size_t len = 0;
kevman 2:7aab896b1a3b 975 fslittle_kv_data_t *node = fslittle_fopen_test_11_kv_data;
kevman 2:7aab896b1a3b 976
kevman 2:7aab896b1a3b 977 FSLITTLE_FENTRYLOG("%s:entered\n", __func__);
kevman 2:7aab896b1a3b 978 (void) call_count;
kevman 2:7aab896b1a3b 979
kevman 2:7aab896b1a3b 980 TEST_ASSERT(strlen(node->filename) < FSLITTLE_FOPEN_TEST_WORK_BUF_SIZE_1);
kevman 2:7aab896b1a3b 981
kevman 2:7aab896b1a3b 982 /* start from a known state i.e. directory to be created in not present, files not present */
kevman 2:7aab896b1a3b 983 while (node->filename != NULL) {
kevman 2:7aab896b1a3b 984 fslittle_filepath_remove_all((char *) node->filename);
kevman 2:7aab896b1a3b 985 node++;
kevman 2:7aab896b1a3b 986 }
kevman 2:7aab896b1a3b 987
kevman 2:7aab896b1a3b 988 /* create file and directories ready for rename() tests */
kevman 2:7aab896b1a3b 989 errno = 0;
kevman 2:7aab896b1a3b 990 node = fslittle_fopen_test_11_kv_data;
kevman 2:7aab896b1a3b 991 ret = fslittle_filepath_make_dirs((char *) node->filename, false);
kevman 2:7aab896b1a3b 992 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: failed to create dir (dirname=%s, ret=%d, errno=%d)\n", __func__, node->filename, (int) ret, errno);
kevman 2:7aab896b1a3b 993 TEST_ASSERT_MESSAGE(ret == 0, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 994
kevman 2:7aab896b1a3b 995 len = strlen(node->value);
kevman 2:7aab896b1a3b 996 ret = fslittle_test_create(node->filename, (char *) node->value, len);
kevman 2:7aab896b1a3b 997 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: failed to create file (ret=%d).\n", __func__, (int) ret);
kevman 2:7aab896b1a3b 998 TEST_ASSERT_MESSAGE(ret >= 0, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 999
kevman 2:7aab896b1a3b 1000 errno = 0;
kevman 2:7aab896b1a3b 1001 node = &fslittle_fopen_test_11_kv_data[2];
kevman 2:7aab896b1a3b 1002 ret = fslittle_filepath_make_dirs((char *) node->filename, false);
kevman 2:7aab896b1a3b 1003 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: failed to create dir (dirname=%s, ret=%d, errno=%d)\n", __func__, node->filename, (int) ret, errno);
kevman 2:7aab896b1a3b 1004 TEST_ASSERT_MESSAGE(ret == 0, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 1005
kevman 2:7aab896b1a3b 1006 /* (1) */
kevman 2:7aab896b1a3b 1007 ret = rename(fslittle_fopen_test_11_kv_data[0].filename, fslittle_fopen_test_11_kv_data[1].filename);
kevman 2:7aab896b1a3b 1008 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: unable to rename file from (%s) to (%s) (ret=%d, errno=%d).\n", __func__, fslittle_fopen_test_11_kv_data[0].filename, fslittle_fopen_test_11_kv_data[1].filename, (int) ret, errno);
kevman 2:7aab896b1a3b 1009 TEST_ASSERT_MESSAGE(ret == 0, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 1010
kevman 2:7aab896b1a3b 1011 /* (2) */
kevman 2:7aab896b1a3b 1012 ret = rename(fslittle_fopen_test_11_kv_data[1].filename, fslittle_fopen_test_11_kv_data[2].filename);
kevman 2:7aab896b1a3b 1013 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: unable to rename file from (%s) to (%s) (ret=%d, errno=%d).\n", __func__, fslittle_fopen_test_11_kv_data[1].filename, fslittle_fopen_test_11_kv_data[2].filename, (int) ret, errno);
kevman 2:7aab896b1a3b 1014 TEST_ASSERT_MESSAGE(ret == 0, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 1015
kevman 2:7aab896b1a3b 1016 return CaseNext;
kevman 2:7aab896b1a3b 1017 }
kevman 2:7aab896b1a3b 1018
kevman 2:7aab896b1a3b 1019
kevman 2:7aab896b1a3b 1020 /* file data for test_12 */
kevman 2:7aab896b1a3b 1021 static fslittle_kv_data_t fslittle_fopen_test_12_kv_data[] = {
kevman 2:7aab896b1a3b 1022 { "/sd/test_12/subdir/testfil1.txt", "testfil1.txt"},
kevman 2:7aab896b1a3b 1023 { "/sd/test_12/testfil2.txt", "testfil2.txt"},
kevman 2:7aab896b1a3b 1024 { "/sd/test_12/testfil3.txt", "testfil3.txt"},
kevman 2:7aab896b1a3b 1025 { "/sd/test_12/testfil4.txt", "testfil4.txt"},
kevman 2:7aab896b1a3b 1026 { "/sd/test_12/testfil5.txt", "testfil5.txt"},
kevman 2:7aab896b1a3b 1027 { NULL, NULL},
kevman 2:7aab896b1a3b 1028 };
kevman 2:7aab896b1a3b 1029
kevman 2:7aab896b1a3b 1030 /** @brief test for operation of readdir().
kevman 2:7aab896b1a3b 1031 *
kevman 2:7aab896b1a3b 1032 * Note, rewinddir(), telldir() and seekdir() dont appear to work reliably.
kevman 2:7aab896b1a3b 1033 * opendir() not available on ARM/IAR toolchains.
kevman 2:7aab896b1a3b 1034 *
kevman 2:7aab896b1a3b 1035 * @return on success returns CaseNext to continue to next test case, otherwise will assert on errors.
kevman 2:7aab896b1a3b 1036 */
kevman 2:7aab896b1a3b 1037 control_t fslittle_fopen_test_12(const size_t call_count)
kevman 2:7aab896b1a3b 1038 {
kevman 2:7aab896b1a3b 1039 char buf[FSLITTLE_FOPEN_TEST_WORK_BUF_SIZE_1];
kevman 2:7aab896b1a3b 1040 char *pos = NULL;
kevman 2:7aab896b1a3b 1041 int32_t count = 0;
kevman 2:7aab896b1a3b 1042 int32_t ret = -1;
kevman 2:7aab896b1a3b 1043 size_t len = 0;
kevman 2:7aab896b1a3b 1044 DIR *dir;
kevman 2:7aab896b1a3b 1045 struct dirent *dp;
kevman 2:7aab896b1a3b 1046 fslittle_kv_data_t *node = fslittle_fopen_test_12_kv_data;
kevman 2:7aab896b1a3b 1047
kevman 2:7aab896b1a3b 1048 FSLITTLE_FENTRYLOG("%s:entered\n", __func__);
kevman 2:7aab896b1a3b 1049 (void) call_count;
kevman 2:7aab896b1a3b 1050
kevman 2:7aab896b1a3b 1051 #if ! defined(__ARMCC_VERSION) && defined(__GNUC__)
kevman 2:7aab896b1a3b 1052
kevman 2:7aab896b1a3b 1053 /* start from a known state i.e. directory to be created in not present */
kevman 2:7aab896b1a3b 1054 while (node->filename != NULL) {
kevman 2:7aab896b1a3b 1055 fslittle_filepath_remove_all((char *) node->filename);
kevman 2:7aab896b1a3b 1056 node++;
kevman 2:7aab896b1a3b 1057 }
kevman 2:7aab896b1a3b 1058
kevman 2:7aab896b1a3b 1059 /* create a file */
kevman 2:7aab896b1a3b 1060 node = fslittle_fopen_test_12_kv_data;
kevman 2:7aab896b1a3b 1061 errno = 0;
kevman 2:7aab896b1a3b 1062 ret = fslittle_filepath_make_dirs((char *) node->filename, false);
kevman 2:7aab896b1a3b 1063 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: failed to create dir (dirname=%s, ret=%d, errno=%d)\n", __func__, node->filename, (int) ret, errno);
kevman 2:7aab896b1a3b 1064 TEST_ASSERT_MESSAGE(ret == 0, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 1065
kevman 2:7aab896b1a3b 1066 node = fslittle_fopen_test_12_kv_data;
kevman 2:7aab896b1a3b 1067 while (node->filename != NULL) {
kevman 2:7aab896b1a3b 1068 len = strlen(node->value);
kevman 2:7aab896b1a3b 1069 ret = fslittle_test_create(node->filename, (char *) node->value, len);
kevman 2:7aab896b1a3b 1070 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: failed to create file (ret=%d).\n", __func__, (int) ret);
kevman 2:7aab896b1a3b 1071 TEST_ASSERT_MESSAGE(ret >= 0, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 1072 node++;
kevman 2:7aab896b1a3b 1073 }
kevman 2:7aab896b1a3b 1074
kevman 2:7aab896b1a3b 1075 node = fslittle_fopen_test_12_kv_data;
kevman 2:7aab896b1a3b 1076 memset(buf, 0, FSLITTLE_FOPEN_TEST_WORK_BUF_SIZE_1);
kevman 2:7aab896b1a3b 1077 memcpy(buf, node->filename, strlen(node->filename));
kevman 2:7aab896b1a3b 1078 pos = strrchr(buf, '/');
kevman 2:7aab896b1a3b 1079 *pos = '\0';
kevman 2:7aab896b1a3b 1080 dir = opendir(buf);
kevman 2:7aab896b1a3b 1081
kevman 2:7aab896b1a3b 1082 dp = readdir(dir);
kevman 2:7aab896b1a3b 1083 TEST_ASSERT_MESSAGE(dp != 0, "Error: readdir() failed\n");
kevman 2:7aab896b1a3b 1084 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: unexpected object name (name=%s, expected=%s).\n", __func__, dp->d_name, ".");
kevman 2:7aab896b1a3b 1085 TEST_ASSERT_MESSAGE(strncmp(dp->d_name, ".", strlen(".")) == 0, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 1086 dp = readdir(dir);
kevman 2:7aab896b1a3b 1087 TEST_ASSERT_MESSAGE(dp != 0, "Error: readdir() failed\n");
kevman 2:7aab896b1a3b 1088 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: unexpected object name (name=%s, expected=%s).\n", __func__, dp->d_name, "..");
kevman 2:7aab896b1a3b 1089 TEST_ASSERT_MESSAGE(strncmp(dp->d_name, "..", strlen("..")) == 0, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 1090
kevman 2:7aab896b1a3b 1091 while ((dp = readdir(dir)) != NULL) {
kevman 2:7aab896b1a3b 1092 FSLITTLE_DBGLOG("%s: filename: \"%s\"\n", __func__, dp->d_name);
kevman 2:7aab896b1a3b 1093 TEST_ASSERT_MESSAGE(dp != 0, "Error: readdir() failed\n");
kevman 2:7aab896b1a3b 1094 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: unexpected object name (name=%s, expected=%s).\n", __func__, dp->d_name, fslittle_fopen_test_12_kv_data[count].value);
kevman 2:7aab896b1a3b 1095 TEST_ASSERT_MESSAGE(strncmp(dp->d_name, fslittle_fopen_test_12_kv_data[count].value, strlen(fslittle_fopen_test_12_kv_data[count].value)) == 0, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 1096 count++;
kevman 2:7aab896b1a3b 1097 }
kevman 2:7aab896b1a3b 1098 closedir(dir);
kevman 2:7aab896b1a3b 1099
kevman 2:7aab896b1a3b 1100 /* cleanup */
kevman 2:7aab896b1a3b 1101 node = fslittle_fopen_test_12_kv_data;
kevman 2:7aab896b1a3b 1102 while (node->filename != NULL) {
kevman 2:7aab896b1a3b 1103 fslittle_filepath_remove_all((char *) node->filename);
kevman 2:7aab896b1a3b 1104 node++;
kevman 2:7aab896b1a3b 1105 }
kevman 2:7aab896b1a3b 1106 #endif /* ! defined(__ARMCC_VERSION) && defined(__GNUC__) */
kevman 2:7aab896b1a3b 1107 return CaseNext;
kevman 2:7aab896b1a3b 1108 }
kevman 2:7aab896b1a3b 1109
kevman 2:7aab896b1a3b 1110
kevman 2:7aab896b1a3b 1111 /* file data for test_13 */
kevman 2:7aab896b1a3b 1112 static fslittle_kv_data_t fslittle_fopen_test_13_kv_data[] = {
kevman 2:7aab896b1a3b 1113 /* a file is included in the filepath even though its not created by the test,
kevman 2:7aab896b1a3b 1114 * as the fslittle_filepath_make_dirs() works with it present. */
kevman 2:7aab896b1a3b 1115 { "/sd/test_13/dummy.txt", "testdir"},
kevman 2:7aab896b1a3b 1116 { NULL, NULL},
kevman 2:7aab896b1a3b 1117 };
kevman 2:7aab896b1a3b 1118 /** @brief test for operation of mkdir()/remove()
kevman 2:7aab896b1a3b 1119 *
kevman 2:7aab896b1a3b 1120 * This test checks that:
kevman 2:7aab896b1a3b 1121 * - The mkdir() function successfully creates a directory that is not already present.
kevman 2:7aab896b1a3b 1122 * - The mkdir() function returns EEXIST when trying to create a directory thats already present.
kevman 2:7aab896b1a3b 1123 * - The remove() function successfully removes a directory that is present.
kevman 2:7aab896b1a3b 1124 *
kevman 2:7aab896b1a3b 1125 * @return on success returns CaseNext to continue to next test case, otherwise will assert on errors.
kevman 2:7aab896b1a3b 1126 */
kevman 2:7aab896b1a3b 1127 control_t fslittle_fopen_test_13(const size_t call_count)
kevman 2:7aab896b1a3b 1128 {
kevman 2:7aab896b1a3b 1129 int32_t ret = 0;
kevman 2:7aab896b1a3b 1130
kevman 2:7aab896b1a3b 1131 FSLITTLE_DBGLOG("%s:entered\n", __func__);
kevman 2:7aab896b1a3b 1132 (void) call_count;
kevman 2:7aab896b1a3b 1133
kevman 2:7aab896b1a3b 1134 /* start from a known state i.e. directory to be created in not present */
kevman 2:7aab896b1a3b 1135 fslittle_filepath_remove_all((char *) fslittle_fopen_test_13_kv_data[0].filename);
kevman 2:7aab896b1a3b 1136
kevman 2:7aab896b1a3b 1137 errno = 0;
kevman 2:7aab896b1a3b 1138 ret = fslittle_filepath_make_dirs((char *) fslittle_fopen_test_13_kv_data[0].filename, false);
kevman 2:7aab896b1a3b 1139 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: failed to create dir (dirname=%s, ret=%d, errno=%d)\n", __func__, fslittle_fopen_test_13_kv_data[0].filename, (int) ret, errno);
kevman 2:7aab896b1a3b 1140 TEST_ASSERT_MESSAGE(ret == 0, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 1141
kevman 2:7aab896b1a3b 1142 /* check that get a suitable error when try to create it again.*/
kevman 2:7aab896b1a3b 1143 errno = 0;
kevman 2:7aab896b1a3b 1144 ret = fslittle_filepath_make_dirs((char *) fslittle_fopen_test_13_kv_data[0].filename, false);
kevman 2:7aab896b1a3b 1145 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: permitted to create directory when already exists (dirname=%s, ret=%d, errno=%d)\n", __func__, fslittle_fopen_test_13_kv_data[0].filename, (int) ret, errno);
kevman 2:7aab896b1a3b 1146 TEST_ASSERT_MESSAGE(ret != 0, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 1147
kevman 2:7aab896b1a3b 1148 /* check errno is as expected */
kevman 2:7aab896b1a3b 1149 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: errno != EEXIST (dirname=%s, ret=%d, errno=%d)\n", __func__, fslittle_fopen_test_13_kv_data[0].filename, (int) ret, errno);
kevman 2:7aab896b1a3b 1150 TEST_ASSERT_MESSAGE(errno == EEXIST, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 1151
kevman 2:7aab896b1a3b 1152 ret = fslittle_filepath_remove_all((char *) fslittle_fopen_test_13_kv_data[0].filename);
kevman 2:7aab896b1a3b 1153 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: failed to remove directory (dirname=%s, ret=%d, errno=%d)\n", __func__, fslittle_fopen_test_13_kv_data[0].filename, (int) ret, errno);
kevman 2:7aab896b1a3b 1154 TEST_ASSERT_MESSAGE(ret == 0, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 1155
kevman 2:7aab896b1a3b 1156 return CaseNext;
kevman 2:7aab896b1a3b 1157 }
kevman 2:7aab896b1a3b 1158
kevman 2:7aab896b1a3b 1159 /* file data for test_14 */
kevman 2:7aab896b1a3b 1160 static fslittle_kv_data_t fslittle_fopen_test_14_kv_data[] = {
kevman 2:7aab896b1a3b 1161 /* a file is included in the filepath even though its not created by the test,
kevman 2:7aab896b1a3b 1162 * as the fslittle_filepath_make_dirs() works with it present. */
kevman 2:7aab896b1a3b 1163 { "/sd/test_14/testfile.txt", "testdata"},
kevman 2:7aab896b1a3b 1164 { NULL, NULL},
kevman 2:7aab896b1a3b 1165 };
kevman 2:7aab896b1a3b 1166
kevman 2:7aab896b1a3b 1167 /** @brief test for operation of stat()
kevman 2:7aab896b1a3b 1168 *
kevman 2:7aab896b1a3b 1169 * stat() is currently no supported by ARMCC and IAR toolchains libc.
kevman 2:7aab896b1a3b 1170 *
kevman 2:7aab896b1a3b 1171 * @return on success returns CaseNext to continue to next test case, otherwise will assert on errors.
kevman 2:7aab896b1a3b 1172 */
kevman 2:7aab896b1a3b 1173 control_t fslittle_fopen_test_14(const size_t call_count)
kevman 2:7aab896b1a3b 1174 {
kevman 2:7aab896b1a3b 1175 #if ! defined(__ARMCC_VERSION) && defined(__GNUC__)
kevman 2:7aab896b1a3b 1176
kevman 2:7aab896b1a3b 1177 char buf[FSLITTLE_FOPEN_TEST_WORK_BUF_SIZE_1];
kevman 2:7aab896b1a3b 1178 char *pos = NULL;
kevman 2:7aab896b1a3b 1179 int32_t ret = -1;
kevman 2:7aab896b1a3b 1180 size_t len = 0;
kevman 2:7aab896b1a3b 1181 struct stat file_stat;
kevman 2:7aab896b1a3b 1182 fslittle_kv_data_t *node = fslittle_fopen_test_14_kv_data;
kevman 2:7aab896b1a3b 1183
kevman 2:7aab896b1a3b 1184 FSLITTLE_FENTRYLOG("%s:entered\n", __func__);
kevman 2:7aab896b1a3b 1185 (void) call_count;
kevman 2:7aab896b1a3b 1186
kevman 2:7aab896b1a3b 1187 TEST_ASSERT(strlen(node->filename) < FSLITTLE_FOPEN_TEST_WORK_BUF_SIZE_1);
kevman 2:7aab896b1a3b 1188
kevman 2:7aab896b1a3b 1189 /* start from a known state i.e. directory to be created in not present */
kevman 2:7aab896b1a3b 1190 fslittle_filepath_remove_all((char *) node->filename);
kevman 2:7aab896b1a3b 1191
kevman 2:7aab896b1a3b 1192 /* Create file in a directory. */
kevman 2:7aab896b1a3b 1193 errno = 0;
kevman 2:7aab896b1a3b 1194 ret = fslittle_filepath_make_dirs((char *) node->filename, false);
kevman 2:7aab896b1a3b 1195 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: failed to create dir (dirname=%s, ret=%d, errno=%d)\n", __func__, node->filename, (int) ret, errno);
kevman 2:7aab896b1a3b 1196 TEST_ASSERT_MESSAGE(ret == 0, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 1197
kevman 2:7aab896b1a3b 1198 len = strlen(node->value);
kevman 2:7aab896b1a3b 1199 ret = fslittle_test_create(node->filename, (char *) node->value, len);
kevman 2:7aab896b1a3b 1200 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: failed to create file (ret=%d).\n", __func__, (int) ret);
kevman 2:7aab896b1a3b 1201 TEST_ASSERT_MESSAGE(ret >= 0, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 1202
kevman 2:7aab896b1a3b 1203 /* Test stat() on the file returns the correct attribute set */
kevman 2:7aab896b1a3b 1204 memset(&file_stat, 0, sizeof(file_stat));
kevman 2:7aab896b1a3b 1205 ret = stat(node->filename, &file_stat);
kevman 2:7aab896b1a3b 1206 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: stat() operation on file failed (filename=%s, ret=%d, errno=%d).\n", __func__, node->filename, (int) ret, errno);
kevman 2:7aab896b1a3b 1207 TEST_ASSERT_MESSAGE(ret == 0, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 1208
kevman 2:7aab896b1a3b 1209 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: expected st_mode S_IFREG flag not set (filename=%s).\n", __func__, node->filename);
kevman 2:7aab896b1a3b 1210 TEST_ASSERT_MESSAGE((file_stat.st_mode & S_IFREG) == S_IFREG, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 1211
kevman 2:7aab896b1a3b 1212 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: unexpected st_mode S_IFDIR flag set (filename=%s).\n", __func__, node->filename);
kevman 2:7aab896b1a3b 1213 TEST_ASSERT_MESSAGE((file_stat.st_mode & S_IFDIR) != S_IFDIR, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 1214
kevman 2:7aab896b1a3b 1215 /* Test stat() on the directory returns the correct attribute set */
kevman 2:7aab896b1a3b 1216 memset(&file_stat, 0, sizeof(file_stat));
kevman 2:7aab896b1a3b 1217 memset(buf, 0, FSLITTLE_FOPEN_TEST_WORK_BUF_SIZE_1);
kevman 2:7aab896b1a3b 1218 memcpy(buf, node->filename, strlen(node->filename));
kevman 2:7aab896b1a3b 1219 pos = strrchr(buf, '/');
kevman 2:7aab896b1a3b 1220 *pos = '\0';
kevman 2:7aab896b1a3b 1221 ret = stat(buf, &file_stat);
kevman 2:7aab896b1a3b 1222 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: stat() operation on directory failed (directory name=%s, ret=%d, errno=%d).\n", __func__, buf, (int) ret, errno);
kevman 2:7aab896b1a3b 1223 TEST_ASSERT_MESSAGE(ret == 0, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 1224
kevman 2:7aab896b1a3b 1225 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: unexpected st_mode S_IFREG flag set (directory name=%s).\n", __func__, buf);
kevman 2:7aab896b1a3b 1226 TEST_ASSERT_MESSAGE((file_stat.st_mode & S_IFREG) != S_IFREG, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 1227
kevman 2:7aab896b1a3b 1228 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: expected st_mode S_IFDIR flag not set (directory name=%s).\n", __func__, buf);
kevman 2:7aab896b1a3b 1229 TEST_ASSERT_MESSAGE((file_stat.st_mode & S_IFDIR) == S_IFDIR, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 1230
kevman 2:7aab896b1a3b 1231 /* clean up after successful test */
kevman 2:7aab896b1a3b 1232 fslittle_filepath_remove_all((char *) node->filename);
kevman 2:7aab896b1a3b 1233
kevman 2:7aab896b1a3b 1234 #endif /* ! defined(__ARMCC_VERSION) && defined(__GNUC__) */
kevman 2:7aab896b1a3b 1235 return CaseNext;
kevman 2:7aab896b1a3b 1236 }
kevman 2:7aab896b1a3b 1237
kevman 2:7aab896b1a3b 1238 /** @brief test for operation of SDFileSystem::format()
kevman 2:7aab896b1a3b 1239 *
kevman 2:7aab896b1a3b 1240 * @return on success returns CaseNext to continue to next test case, otherwise will assert on errors.
kevman 2:7aab896b1a3b 1241 */
kevman 2:7aab896b1a3b 1242 control_t fslittle_fopen_test_00(const size_t call_count)
kevman 2:7aab896b1a3b 1243 {
kevman 2:7aab896b1a3b 1244
kevman 2:7aab896b1a3b 1245 FSLITTLE_FENTRYLOG("%s:entered\n", __func__);
kevman 2:7aab896b1a3b 1246 (void) call_count;
kevman 2:7aab896b1a3b 1247 int32_t ret = -1;
kevman 2:7aab896b1a3b 1248
kevman 2:7aab896b1a3b 1249 flash = new FlashIAPBlockDevice();
kevman 2:7aab896b1a3b 1250 ret = flash->init();
kevman 2:7aab896b1a3b 1251 TEST_ASSERT_EQUAL(0, ret);
kevman 2:7aab896b1a3b 1252
kevman 2:7aab896b1a3b 1253 // Use slice of last sectors
kevman 2:7aab896b1a3b 1254 bd_addr_t slice_addr = flash->size();
kevman 2:7aab896b1a3b 1255 bd_size_t slice_size = 0;
kevman 2:7aab896b1a3b 1256 while (slice_size < MAX_TEST_SIZE) {
kevman 2:7aab896b1a3b 1257 bd_size_t unit_size = flash->get_erase_size(slice_addr - 1);
kevman 2:7aab896b1a3b 1258 slice_addr -= unit_size;
kevman 2:7aab896b1a3b 1259 slice_size += unit_size;
kevman 2:7aab896b1a3b 1260 }
kevman 2:7aab896b1a3b 1261 slice = new SlicingBlockDevice(flash, slice_addr);
kevman 2:7aab896b1a3b 1262 slice->init();
kevman 2:7aab896b1a3b 1263
kevman 2:7aab896b1a3b 1264 ret = fs.reformat(slice);
kevman 2:7aab896b1a3b 1265 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: failed to format sdcard (ret=%d)\n", __func__, (int) ret);
kevman 2:7aab896b1a3b 1266 TEST_ASSERT_MESSAGE(ret == 0, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 1267 fs.mount(slice);
kevman 2:7aab896b1a3b 1268
kevman 2:7aab896b1a3b 1269 return CaseNext;
kevman 2:7aab896b1a3b 1270 }
kevman 2:7aab896b1a3b 1271
kevman 2:7aab896b1a3b 1272
kevman 2:7aab896b1a3b 1273 /* @brief test utility function to create a file of a given size.
kevman 2:7aab896b1a3b 1274 *
kevman 2:7aab896b1a3b 1275 * A reference data table is used of so that the data file can be later be
kevman 2:7aab896b1a3b 1276 * checked with fslittle_test_check_data_file().
kevman 2:7aab896b1a3b 1277 *
kevman 2:7aab896b1a3b 1278 * @param filename name of the file including path
kevman 2:7aab896b1a3b 1279 * @param data data to store in file
kevman 2:7aab896b1a3b 1280 * @param len number of bytes of data present in the data buffer.
kevman 2:7aab896b1a3b 1281 */
kevman 2:7aab896b1a3b 1282 int32_t fslittle_test_create_data_file(const char *filename, size_t len)
kevman 2:7aab896b1a3b 1283 {
kevman 2:7aab896b1a3b 1284 int32_t ret = -1;
kevman 2:7aab896b1a3b 1285 FILE *fp = NULL;
kevman 2:7aab896b1a3b 1286 size_t write_len = 0;
kevman 2:7aab896b1a3b 1287 size_t written_len = 0;
kevman 2:7aab896b1a3b 1288 int32_t exp = 0;
kevman 2:7aab896b1a3b 1289 const int32_t exp_max = 8; /* so as not to exceed FSLITTLE_TEST_BYTE_DATA_TABLE_SIZE/2 */
kevman 2:7aab896b1a3b 1290
kevman 2:7aab896b1a3b 1291 FSLITTLE_FENTRYLOG("%s:entered (filename=%s, len=%d).\n", __func__, filename, (int) len);
kevman 2:7aab896b1a3b 1292 TEST_ASSERT(len % FSLITTLE_TEST_BYTE_DATA_TABLE_SIZE == 0);
kevman 2:7aab896b1a3b 1293 fp = fopen(filename, "a");
kevman 2:7aab896b1a3b 1294 if (fp == NULL) {
kevman 2:7aab896b1a3b 1295 return ret;
kevman 2:7aab896b1a3b 1296 }
kevman 2:7aab896b1a3b 1297
kevman 2:7aab896b1a3b 1298 while (written_len < len) {
kevman 2:7aab896b1a3b 1299 /* write fslittle_test_byte_data_table or part thereof, in 9 writes of sizes
kevman 2:7aab896b1a3b 1300 * 1, 2, 4, 8, 16, 32, 64, 128, 1, totalling 256 bytes len permitting. */
kevman 2:7aab896b1a3b 1301 for (exp = 0; (exp <= exp_max) && (written_len < len); exp++) {
kevman 2:7aab896b1a3b 1302 write_len = 0x1 << (exp % exp_max);
kevman 2:7aab896b1a3b 1303 write_len = len - written_len > write_len ? write_len : len - written_len;
kevman 2:7aab896b1a3b 1304 ret = fwrite((const void *) &fslittle_test_byte_data_table[written_len % FSLITTLE_TEST_BYTE_DATA_TABLE_SIZE], write_len, 1, fp);
kevman 2:7aab896b1a3b 1305 written_len += write_len;
kevman 2:7aab896b1a3b 1306 if (ret != 1) {
kevman 2:7aab896b1a3b 1307 FSLITTLE_DBGLOG("%s:Error: fwrite() failed (ret=%d)\n", __func__, (int) ret);
kevman 2:7aab896b1a3b 1308 ret = -1;
kevman 2:7aab896b1a3b 1309 goto out0;
kevman 2:7aab896b1a3b 1310 }
kevman 2:7aab896b1a3b 1311 }
kevman 2:7aab896b1a3b 1312 }
kevman 2:7aab896b1a3b 1313 if (written_len == len) {
kevman 2:7aab896b1a3b 1314 ret = 0;
kevman 2:7aab896b1a3b 1315 } else {
kevman 2:7aab896b1a3b 1316 ret = -1;
kevman 2:7aab896b1a3b 1317 }
kevman 2:7aab896b1a3b 1318 out0:
kevman 2:7aab896b1a3b 1319 fclose(fp);
kevman 2:7aab896b1a3b 1320 return ret;
kevman 2:7aab896b1a3b 1321 }
kevman 2:7aab896b1a3b 1322
kevman 2:7aab896b1a3b 1323
kevman 2:7aab896b1a3b 1324 /* @brief test utility function to check the data in the specified file is correct.
kevman 2:7aab896b1a3b 1325 *
kevman 2:7aab896b1a3b 1326 * The data read from the file is check that it agrees with the data written by
kevman 2:7aab896b1a3b 1327 * fslittle_test_create_data_file().
kevman 2:7aab896b1a3b 1328 *
kevman 2:7aab896b1a3b 1329 * @param filename name of the file including path
kevman 2:7aab896b1a3b 1330 * @param data data to store in file
kevman 2:7aab896b1a3b 1331 * @param len number of bytes of data present in the data buffer.
kevman 2:7aab896b1a3b 1332 */
kevman 2:7aab896b1a3b 1333 int32_t fslittle_test_check_data_file(const char *filename, size_t len)
kevman 2:7aab896b1a3b 1334 {
kevman 2:7aab896b1a3b 1335 int32_t ret = -1;
kevman 2:7aab896b1a3b 1336 FILE *fp = NULL;
kevman 2:7aab896b1a3b 1337 size_t read_len = 0;
kevman 2:7aab896b1a3b 1338 uint8_t buf[FSLITTLE_TEST_BYTE_DATA_TABLE_SIZE];
kevman 2:7aab896b1a3b 1339
kevman 2:7aab896b1a3b 1340 FSLITTLE_FENTRYLOG("%s:entered (filename=%s, len=%d).\n", __func__, filename, (int) len);
kevman 2:7aab896b1a3b 1341 TEST_ASSERT(len % FSLITTLE_TEST_BYTE_DATA_TABLE_SIZE == 0);
kevman 2:7aab896b1a3b 1342 fp = fopen(filename, "r");
kevman 2:7aab896b1a3b 1343 if (fp == NULL) {
kevman 2:7aab896b1a3b 1344 return ret;
kevman 2:7aab896b1a3b 1345 }
kevman 2:7aab896b1a3b 1346
kevman 2:7aab896b1a3b 1347 while (read_len < len) {
kevman 2:7aab896b1a3b 1348 ret = fread((void *) buf, FSLITTLE_TEST_BYTE_DATA_TABLE_SIZE, 1, fp);
kevman 2:7aab896b1a3b 1349 read_len += FSLITTLE_TEST_BYTE_DATA_TABLE_SIZE;
kevman 2:7aab896b1a3b 1350 if (ret == 0) {
kevman 2:7aab896b1a3b 1351 /* end of read*/
kevman 2:7aab896b1a3b 1352 FSLITTLE_DBGLOG("%s:unable to read data\n", __func__);
kevman 2:7aab896b1a3b 1353 break;
kevman 2:7aab896b1a3b 1354 }
kevman 2:7aab896b1a3b 1355 if (memcmp(buf, fslittle_test_byte_data_table, FSLITTLE_TEST_BYTE_DATA_TABLE_SIZE) != 0) {
kevman 2:7aab896b1a3b 1356 FSLITTLE_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__,
kevman 2:7aab896b1a3b 1357 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]);
kevman 2:7aab896b1a3b 1358 ret = -1;
kevman 2:7aab896b1a3b 1359 goto out0;
kevman 2:7aab896b1a3b 1360 }
kevman 2:7aab896b1a3b 1361 }
kevman 2:7aab896b1a3b 1362 if (read_len == len) {
kevman 2:7aab896b1a3b 1363 ret = 0;
kevman 2:7aab896b1a3b 1364 }
kevman 2:7aab896b1a3b 1365 out0:
kevman 2:7aab896b1a3b 1366 fclose(fp);
kevman 2:7aab896b1a3b 1367 return ret;
kevman 2:7aab896b1a3b 1368 }
kevman 2:7aab896b1a3b 1369
kevman 2:7aab896b1a3b 1370 /* file data for test_16 */
kevman 2:7aab896b1a3b 1371 static fslittle_kv_data_t fslittle_fopen_test_15_kv_data[] = {
kevman 2:7aab896b1a3b 1372 { "/sd/tst16_0/testfil0.txt", "dummy_data"},
kevman 2:7aab896b1a3b 1373 { "/sd/tst16_1/subdir0/testfil0.txt", "dummy_data"},
kevman 2:7aab896b1a3b 1374 { "/sd/tst16_2/subdir0/subdir1/testfil0.txt", "dummy_data"},
kevman 2:7aab896b1a3b 1375 { "/sd/tst16_3/subdir0/subdir1/subdir2/subdir3/testfil0.txt", "dummy_data"},
kevman 2:7aab896b1a3b 1376
kevman 2:7aab896b1a3b 1377 #if 0
kevman 2:7aab896b1a3b 1378 { "/sd/tst16_4/subdir0/subdir1/subdir2/subdir3/subdir4/testfil0.txt", "dummy_data"},
kevman 2:7aab896b1a3b 1379 { "/sd/tst16_5/subdir0/subdir1/subdir2/subdir3/subdir4/subdir5/testfil0.txt", "dummy_data"},
kevman 2:7aab896b1a3b 1380 { "/sd/tst16_6/subdir0/subdir1/subdir2/subdir3/subdir4/subdir5/subdir6/testfil0.txt", "dummy_data"},
kevman 2:7aab896b1a3b 1381 { "/sd/tst16_7/subdir0/subdir1/subdir2/subdir3/subdir4/subdir5/subdir6/subdir7/testfil0.txt", "dummy_data"},
kevman 2:7aab896b1a3b 1382 { "/sd/tst16_8/subdir0/subdir1/subdir2/subdir3/subdir4/subdir5/subdir6/subdir7/subdir8/testfil0.txt", "dummy_data"},
kevman 2:7aab896b1a3b 1383 { "/sd/tst16_9/subdir0/subdir1/subdir2/subdir3/subdir4/subdir5/subdir6/subdir7/subdir8/subdir9/testfil0.txt", "dummy_data"},
kevman 2:7aab896b1a3b 1384 #endif
kevman 2:7aab896b1a3b 1385 { NULL, NULL},
kevman 2:7aab896b1a3b 1386 };
kevman 2:7aab896b1a3b 1387
kevman 2:7aab896b1a3b 1388
kevman 2:7aab896b1a3b 1389 /** @brief stress test to write data to fs
kevman 2:7aab896b1a3b 1390 *
kevman 2:7aab896b1a3b 1391 * @return on success returns CaseNext to continue to next test case, otherwise will assert on errors.
kevman 2:7aab896b1a3b 1392 */
kevman 2:7aab896b1a3b 1393 control_t fslittle_fopen_test_15(const size_t call_count)
kevman 2:7aab896b1a3b 1394 {
kevman 2:7aab896b1a3b 1395 int32_t ret = 0;
kevman 2:7aab896b1a3b 1396 fslittle_kv_data_t *node = fslittle_fopen_test_15_kv_data;
kevman 2:7aab896b1a3b 1397 const int32_t num_blocks = 100; /* each file ~25kB */
kevman 2:7aab896b1a3b 1398
kevman 2:7aab896b1a3b 1399 FSLITTLE_DBGLOG("%s:entered\n", __func__);
kevman 2:7aab896b1a3b 1400 (void) call_count;
kevman 2:7aab896b1a3b 1401
kevman 2:7aab896b1a3b 1402 /* remove file and directory from a previous failed test run, if present */
kevman 2:7aab896b1a3b 1403 while (node->filename != NULL) {
kevman 2:7aab896b1a3b 1404 fslittle_filepath_remove_all((char *) node->filename);
kevman 2:7aab896b1a3b 1405 node++;
kevman 2:7aab896b1a3b 1406 }
kevman 2:7aab896b1a3b 1407
kevman 2:7aab896b1a3b 1408 /* create dirs */
kevman 2:7aab896b1a3b 1409 node = fslittle_fopen_test_15_kv_data;
kevman 2:7aab896b1a3b 1410 while (node->filename != NULL) {
kevman 2:7aab896b1a3b 1411 ret = fslittle_filepath_make_dirs((char *) node->filename, true);
kevman 2:7aab896b1a3b 1412 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: failed to create dirs for filename (filename=\"%s\")(ret=%d)\n", __func__, node->filename, (int) ret);
kevman 2:7aab896b1a3b 1413 TEST_ASSERT_MESSAGE(ret == 0, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 1414 node++;
kevman 2:7aab896b1a3b 1415 }
kevman 2:7aab896b1a3b 1416
kevman 2:7aab896b1a3b 1417 /* create the data files */
kevman 2:7aab896b1a3b 1418 node = fslittle_fopen_test_15_kv_data;
kevman 2:7aab896b1a3b 1419 while (node->filename != NULL) {
kevman 2:7aab896b1a3b 1420 ret = fslittle_test_create_data_file(node->filename, num_blocks * FSLITTLE_TEST_BYTE_DATA_TABLE_SIZE);
kevman 2:7aab896b1a3b 1421 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: failed to create data file (filename=\"%s\")(ret=%d)\n", __func__, node->filename, (int) ret);
kevman 2:7aab896b1a3b 1422 TEST_ASSERT_MESSAGE(ret == 0, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 1423 node++;
kevman 2:7aab896b1a3b 1424 }
kevman 2:7aab896b1a3b 1425
kevman 2:7aab896b1a3b 1426 /* read the data back and check its as expected */
kevman 2:7aab896b1a3b 1427 node = fslittle_fopen_test_15_kv_data;
kevman 2:7aab896b1a3b 1428 while (node->filename != NULL) {
kevman 2:7aab896b1a3b 1429 ret = fslittle_test_check_data_file(node->filename, num_blocks * FSLITTLE_TEST_BYTE_DATA_TABLE_SIZE);
kevman 2:7aab896b1a3b 1430 FSLITTLE_TEST_UTEST_MESSAGE(fslittle_fopen_utest_msg_g, FSLITTLE_UTEST_MSG_BUF_SIZE, "%s:Error: failed to check data file (filename=\"%s\")(ret=%d)\n", __func__, node->filename, (int) ret);
kevman 2:7aab896b1a3b 1431 TEST_ASSERT_MESSAGE(ret == 0, fslittle_fopen_utest_msg_g);
kevman 2:7aab896b1a3b 1432 node++;
kevman 2:7aab896b1a3b 1433 }
kevman 2:7aab896b1a3b 1434
kevman 2:7aab896b1a3b 1435 /* clean up */
kevman 2:7aab896b1a3b 1436 node = fslittle_fopen_test_15_kv_data;
kevman 2:7aab896b1a3b 1437 while (node->filename != NULL) {
kevman 2:7aab896b1a3b 1438 fslittle_filepath_remove_all((char *) node->filename);
kevman 2:7aab896b1a3b 1439 node++;
kevman 2:7aab896b1a3b 1440 }
kevman 2:7aab896b1a3b 1441 return CaseNext;
kevman 2:7aab896b1a3b 1442 }
kevman 2:7aab896b1a3b 1443
kevman 2:7aab896b1a3b 1444 /// @cond FSLITTLE_DOXYGEN_DISABLE
kevman 2:7aab896b1a3b 1445 utest::v1::status_t greentea_setup(const size_t number_of_cases)
kevman 2:7aab896b1a3b 1446 {
kevman 2:7aab896b1a3b 1447 GREENTEA_SETUP(FSLITTLE_FOPEN_GREENTEA_TIMEOUT_S, "default_auto");
kevman 2:7aab896b1a3b 1448 return greentea_test_setup_handler(number_of_cases);
kevman 2:7aab896b1a3b 1449 }
kevman 2:7aab896b1a3b 1450
kevman 2:7aab896b1a3b 1451 Case cases[] = {
kevman 2:7aab896b1a3b 1452 /* 1 2 3 4 5 6 7 */
kevman 2:7aab896b1a3b 1453 /* 1234567890123456789012345678901234567890123456789012345678901234567890 */
kevman 2:7aab896b1a3b 1454 Case("FSLITTLE_FOPEN_TEST_00: format() test.", FSLITTLE_FOPEN_TEST_00),
kevman 2:7aab896b1a3b 1455 Case("FSLITTLE_FOPEN_TEST_01: fopen()/fwrite()/fclose() directories/file in multi-dir filepath.", FSLITTLE_FOPEN_TEST_01),
kevman 2:7aab896b1a3b 1456 Case("FSLITTLE_FOPEN_TEST_02: fopen(r) pre-existing file try to write it.", FSLITTLE_FOPEN_TEST_02),
kevman 2:7aab896b1a3b 1457 Case("FSLITTLE_FOPEN_TEST_03: fopen(w+) pre-existing file try to write it.", FSLITTLE_FOPEN_TEST_03),
kevman 2:7aab896b1a3b 1458 Case("FSLITTLE_FOPEN_TEST_04: fopen() with a filename exceeding the maximum length.", FSLITTLE_FOPEN_TEST_04),
kevman 2:7aab896b1a3b 1459 #ifdef FOPEN_EXTENDED_TESTING
kevman 2:7aab896b1a3b 1460 Case("FSLITTLE_FOPEN_TEST_05: fopen() with bad filenames (extended).", FSLITTLE_FOPEN_TEST_05),
kevman 2:7aab896b1a3b 1461 #endif
kevman 2:7aab896b1a3b 1462 Case("FSLITTLE_FOPEN_TEST_06: fopen() with bad filenames (minimal).", FSLITTLE_FOPEN_TEST_06),
kevman 2:7aab896b1a3b 1463 Case("FSLITTLE_FOPEN_TEST_07: fopen()/errno handling.", FSLITTLE_FOPEN_TEST_07),
kevman 2:7aab896b1a3b 1464 Case("FSLITTLE_FOPEN_TEST_08: ferror()/clearerr()/errno handling.", FSLITTLE_FOPEN_TEST_08),
kevman 2:7aab896b1a3b 1465 Case("FSLITTLE_FOPEN_TEST_09: ftell() handling.", FSLITTLE_FOPEN_TEST_09),
kevman 2:7aab896b1a3b 1466 Case("FSLITTLE_FOPEN_TEST_10: remove() test.", FSLITTLE_FOPEN_TEST_10),
kevman 2:7aab896b1a3b 1467 Case("FSLITTLE_FOPEN_TEST_11: rename().", FSLITTLE_FOPEN_TEST_11),
kevman 2:7aab896b1a3b 1468 Case("FSLITTLE_FOPEN_TEST_12: opendir(), readdir(), closedir() test.", FSLITTLE_FOPEN_TEST_12),
kevman 2:7aab896b1a3b 1469 Case("FSLITTLE_FOPEN_TEST_13: mkdir() test.", FSLITTLE_FOPEN_TEST_13),
kevman 2:7aab896b1a3b 1470 Case("FSLITTLE_FOPEN_TEST_14: stat() test.", FSLITTLE_FOPEN_TEST_14),
kevman 2:7aab896b1a3b 1471 Case("FSLITTLE_FOPEN_TEST_15: write/check n x 25kB data files.", FSLITTLE_FOPEN_TEST_15),
kevman 2:7aab896b1a3b 1472 };
kevman 2:7aab896b1a3b 1473
kevman 2:7aab896b1a3b 1474
kevman 2:7aab896b1a3b 1475 /* Declare your test specification with a custom setup handler */
kevman 2:7aab896b1a3b 1476 Specification specification(greentea_setup, cases);
kevman 2:7aab896b1a3b 1477
kevman 2:7aab896b1a3b 1478 int main()
kevman 2:7aab896b1a3b 1479 {
kevman 2:7aab896b1a3b 1480 return !Harness::run(specification);
kevman 2:7aab896b1a3b 1481 }
kevman 2:7aab896b1a3b 1482 /// @endcond