diff --git a/.travis.yml b/.travis.yml index dbdceed..67e9237 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,8 +23,20 @@ script: - make test QUIET=1 CFLAGS+="-DLFS2_BLOCK_COUNT=1023 -DLFS2_LOOKAHEAD_SIZE=256" - make clean test QUIET=1 CFLAGS+="-DLFS2_INLINE_MAX=0" + - make clean test QUIET=1 CFLAGS+="-DLFS2_EMUBD_ERASE_VALUE=0xff" - make clean test QUIET=1 CFLAGS+="-DLFS2_NO_INTRINSICS" + # additional configurations that don't support all tests (this should be + # fixed but at the moment it is what it is) + - make test_files QUIET=1 + CFLAGS+="-DLFS2_READ_SIZE=1 -DLFS2_BLOCK_SIZE=4096" + - make test_files QUIET=1 + CFLAGS+="-DLFS2_READ_SIZE=\(2*1024\) -DLFS2_BLOCK_SIZE=\(64*1024\)" + - make test_files QUIET=1 + CFLAGS+="-DLFS2_READ_SIZE=\(8*1024\) -DLFS2_BLOCK_SIZE=\(64*1024\)" + - make test_files QUIET=1 + CFLAGS+="-DLFS2_READ_SIZE=11 -DLFS2_BLOCK_SIZE=704" + # compile and find the code size with the smallest configuration - make clean size OBJ="$(ls lfs2*.o | tr '\n' ' ')" @@ -111,7 +123,7 @@ jobs: if: branch !~ -prefix$ install: - sudo apt-get install libfuse-dev - - git clone --depth 1 https://github.com/geky/littlefs-fuse -b v2-alpha + - git clone --depth 1 https://github.com/geky/littlefs-fuse -b v2 - fusermount -V - gcc --version before_script: @@ -146,7 +158,7 @@ jobs: if: branch !~ -prefix$ install: - sudo apt-get install libfuse-dev - - git clone --depth 1 https://github.com/geky/littlefs-fuse -b v2-alpha v2 + - git clone --depth 1 https://github.com/geky/littlefs-fuse -b v2 v2 - git clone --depth 1 https://github.com/geky/littlefs-fuse -b v1 v1 - fusermount -V - gcc --version diff --git a/Makefile b/Makefile index a22428b..ffc067a 100644 --- a/Makefile +++ b/Makefile @@ -24,6 +24,9 @@ endif ifdef WORD override CFLAGS += -m$(WORD) endif +ifdef TRACE +override CFLAGS += -DLFS2_YES_TRACE +endif override CFLAGS += -I. override CFLAGS += -std=c99 -Wall -pedantic override CFLAGS += -Wextra -Wshadow -Wjump-misses-init @@ -39,14 +42,25 @@ size: $(OBJ) $(SIZE) -t $^ .SUFFIXES: -test: test_format test_dirs test_files test_seek test_truncate \ - test_entries test_interspersed test_alloc test_paths test_attrs \ - test_move test_orphan test_corrupt +test: \ + test_format \ + test_dirs \ + test_files \ + test_seek \ + test_truncate \ + test_entries \ + test_interspersed \ + test_alloc \ + test_paths \ + test_attrs \ + test_move \ + test_orphan \ + test_corrupt @rm test.c test_%: tests/test_%.sh ifdef QUIET - @./$< | sed -n '/^[-=]/p' + @./$< | sed -nu '/^[-=]/p' else ./$< endif diff --git a/emubd/lfs2_emubd.c b/emubd/lfs2_emubd.c index 3ff87e7..98d2906 100644 --- a/emubd/lfs2_emubd.c +++ b/emubd/lfs2_emubd.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -55,6 +54,15 @@ static inline void lfs2_emubd_fromle32(lfs2_emubd_t *emu) { // Block device emulated on existing filesystem int lfs2_emubd_create(const struct lfs2_config *cfg, const char *path) { + LFS2_TRACE("lfs2_emubd_create(%p {.context=%p, " + ".read=%p, .prog=%p, .erase=%p, .sync=%p, " + ".read_size=%"PRIu32", .prog_size=%"PRIu32", " + ".block_size=%"PRIu32", .block_count=%"PRIu32"}, \"%s\")", + (void*)cfg, cfg->context, + (void*)(uintptr_t)cfg->read, (void*)(uintptr_t)cfg->prog, + (void*)(uintptr_t)cfg->erase, (void*)(uintptr_t)cfg->sync, + cfg->read_size, cfg->prog_size, cfg->block_size, cfg->block_count, + path); lfs2_emubd_t *emu = cfg->context; emu->cfg.read_size = cfg->read_size; emu->cfg.prog_size = cfg->prog_size; @@ -65,7 +73,9 @@ int lfs2_emubd_create(const struct lfs2_config *cfg, const char *path) { size_t pathlen = strlen(path); emu->path = malloc(pathlen + 1 + LFS2_NAME_MAX + 1); if (!emu->path) { - return -ENOMEM; + int err = -ENOMEM; + LFS2_TRACE("lfs2_emubd_create -> %"PRId32, err); + return err; } strcpy(emu->path, path); @@ -76,24 +86,30 @@ int lfs2_emubd_create(const struct lfs2_config *cfg, const char *path) { // Create directory if it doesn't exist int err = mkdir(path, 0777); if (err && errno != EEXIST) { - return -errno; + err = -errno; + LFS2_TRACE("lfs2_emubd_create -> %"PRId32, err); + return err; } // Load stats to continue incrementing snprintf(emu->child, LFS2_NAME_MAX, ".stats"); FILE *f = fopen(emu->path, "r"); if (!f) { - memset(&emu->stats, 0, sizeof(emu->stats)); + memset(&emu->stats, LFS2_EMUBD_ERASE_VALUE, sizeof(emu->stats)); } else { size_t res = fread(&emu->stats, sizeof(emu->stats), 1, f); lfs2_emubd_fromle32(emu); if (res < 1) { - return -errno; + err = -errno; + LFS2_TRACE("lfs2_emubd_create -> %"PRId32, err); + return err; } err = fclose(f); if (err) { - return -errno; + err = -errno; + LFS2_TRACE("lfs2_emubd_create -> %"PRId32, err); + return err; } } @@ -106,27 +122,36 @@ int lfs2_emubd_create(const struct lfs2_config *cfg, const char *path) { size_t res = fread(&emu->history, sizeof(emu->history), 1, f); lfs2_emubd_fromle32(emu); if (res < 1) { - return -errno; + err = -errno; + LFS2_TRACE("lfs2_emubd_create -> %"PRId32, err); + return err; } err = fclose(f); if (err) { - return -errno; + err = -errno; + LFS2_TRACE("lfs2_emubd_create -> %"PRId32, err); + return err; } } + LFS2_TRACE("lfs2_emubd_create -> %"PRId32, 0); return 0; } void lfs2_emubd_destroy(const struct lfs2_config *cfg) { + LFS2_TRACE("lfs2_emubd_destroy(%p)", (void*)cfg); lfs2_emubd_sync(cfg); lfs2_emubd_t *emu = cfg->context; free(emu->path); + LFS2_TRACE("lfs2_emubd_destroy -> %s", "void"); } int lfs2_emubd_read(const struct lfs2_config *cfg, lfs2_block_t block, lfs2_off_t off, void *buffer, lfs2_size_t size) { + LFS2_TRACE("lfs2_emubd_read(%p, 0x%"PRIx32", %"PRIu32", %p, %"PRIu32")", + (void*)cfg, block, off, buffer, size); lfs2_emubd_t *emu = cfg->context; uint8_t *data = buffer; @@ -143,32 +168,43 @@ int lfs2_emubd_read(const struct lfs2_config *cfg, lfs2_block_t block, FILE *f = fopen(emu->path, "rb"); if (!f && errno != ENOENT) { - return -errno; + int err = -errno; + LFS2_TRACE("lfs2_emubd_read -> %d", err); + return err; } if (f) { int err = fseek(f, off, SEEK_SET); if (err) { - return -errno; + err = -errno; + LFS2_TRACE("lfs2_emubd_read -> %d", err); + return err; } size_t res = fread(data, 1, size, f); if (res < size && !feof(f)) { - return -errno; + err = -errno; + LFS2_TRACE("lfs2_emubd_read -> %d", err); + return err; } err = fclose(f); if (err) { - return -errno; + err = -errno; + LFS2_TRACE("lfs2_emubd_read -> %d", err); + return err; } } - emu->stats.read_count += 1; + emu->stats.read_count += size; + LFS2_TRACE("lfs2_emubd_read -> %d", 0); return 0; } int lfs2_emubd_prog(const struct lfs2_config *cfg, lfs2_block_t block, lfs2_off_t off, const void *buffer, lfs2_size_t size) { + LFS2_TRACE("lfs2_emubd_prog(%p, 0x%"PRIx32", %"PRIu32", %p, %"PRIu32")", + (void*)cfg, block, off, buffer, size); lfs2_emubd_t *emu = cfg->context; const uint8_t *data = buffer; @@ -182,7 +218,9 @@ int lfs2_emubd_prog(const struct lfs2_config *cfg, lfs2_block_t block, FILE *f = fopen(emu->path, "r+b"); if (!f) { - return (errno == EACCES) ? 0 : -errno; + int err = (errno == EACCES) ? 0 : -errno; + LFS2_TRACE("lfs2_emubd_prog -> %d", err); + return err; } // Check that file was erased @@ -190,42 +228,54 @@ int lfs2_emubd_prog(const struct lfs2_config *cfg, lfs2_block_t block, int err = fseek(f, off, SEEK_SET); if (err) { - return -errno; + err = -errno; + LFS2_TRACE("lfs2_emubd_prog -> %d", err); + return err; } size_t res = fwrite(data, 1, size, f); if (res < size) { - return -errno; + err = -errno; + LFS2_TRACE("lfs2_emubd_prog -> %d", err); + return err; } err = fseek(f, off, SEEK_SET); if (err) { - return -errno; + err = -errno; + LFS2_TRACE("lfs2_emubd_prog -> %d", err); + return err; } uint8_t dat; res = fread(&dat, 1, 1, f); if (res < 1) { - return -errno; + err = -errno; + LFS2_TRACE("lfs2_emubd_prog -> %d", err); + return err; } err = fclose(f); if (err) { - return -errno; + err = -errno; + LFS2_TRACE("lfs2_emubd_prog -> %d", err); + return err; } // update history and stats if (block != emu->history.blocks[0]) { - memcpy(&emu->history.blocks[1], &emu->history.blocks[0], + memmove(&emu->history.blocks[1], &emu->history.blocks[0], sizeof(emu->history) - sizeof(emu->history.blocks[0])); emu->history.blocks[0] = block; } - emu->stats.prog_count += 1; + emu->stats.prog_count += size; + LFS2_TRACE("lfs2_emubd_prog -> %d", 0); return 0; } int lfs2_emubd_erase(const struct lfs2_config *cfg, lfs2_block_t block) { + LFS2_TRACE("lfs2_emubd_erase(%p, 0x%"PRIx32")", (void*)cfg, block); lfs2_emubd_t *emu = cfg->context; // Check if erase is valid @@ -236,89 +286,118 @@ int lfs2_emubd_erase(const struct lfs2_config *cfg, lfs2_block_t block) { struct stat st; int err = stat(emu->path, &st); if (err && errno != ENOENT) { - return -errno; + err = -errno; + LFS2_TRACE("lfs2_emubd_erase -> %d", err); + return err; } if (!err && S_ISREG(st.st_mode) && (S_IWUSR & st.st_mode)) { err = unlink(emu->path); if (err) { - return -errno; + err = -errno; + LFS2_TRACE("lfs2_emubd_erase -> %d", err); + return err; } } if (err || (S_ISREG(st.st_mode) && (S_IWUSR & st.st_mode))) { FILE *f = fopen(emu->path, "w"); if (!f) { - return -errno; + err = -errno; + LFS2_TRACE("lfs2_emubd_erase -> %d", err); + return err; } err = fclose(f); if (err) { - return -errno; + err = -errno; + LFS2_TRACE("lfs2_emubd_erase -> %d", err); + return err; } } - emu->stats.erase_count += 1; + emu->stats.erase_count += cfg->block_size; + LFS2_TRACE("lfs2_emubd_erase -> %d", 0); return 0; } int lfs2_emubd_sync(const struct lfs2_config *cfg) { + LFS2_TRACE("lfs2_emubd_sync(%p)", (void*)cfg); lfs2_emubd_t *emu = cfg->context; // Just write out info/stats for later lookup snprintf(emu->child, LFS2_NAME_MAX, ".config"); FILE *f = fopen(emu->path, "w"); if (!f) { - return -errno; + int err = -errno; + LFS2_TRACE("lfs2_emubd_sync -> %d", err); + return err; } lfs2_emubd_tole32(emu); size_t res = fwrite(&emu->cfg, sizeof(emu->cfg), 1, f); lfs2_emubd_fromle32(emu); if (res < 1) { - return -errno; + int err = -errno; + LFS2_TRACE("lfs2_emubd_sync -> %d", err); + return err; } int err = fclose(f); if (err) { - return -errno; + err = -errno; + LFS2_TRACE("lfs2_emubd_sync -> %d", err); + return err; } snprintf(emu->child, LFS2_NAME_MAX, ".stats"); f = fopen(emu->path, "w"); if (!f) { - return -errno; + err = -errno; + LFS2_TRACE("lfs2_emubd_sync -> %d", err); + return err; } lfs2_emubd_tole32(emu); res = fwrite(&emu->stats, sizeof(emu->stats), 1, f); lfs2_emubd_fromle32(emu); if (res < 1) { - return -errno; + err = -errno; + LFS2_TRACE("lfs2_emubd_sync -> %d", err); + return err; } err = fclose(f); if (err) { - return -errno; + err = -errno; + LFS2_TRACE("lfs2_emubd_sync -> %d", err); + return err; } snprintf(emu->child, LFS2_NAME_MAX, ".history"); f = fopen(emu->path, "w"); if (!f) { - return -errno; + err = -errno; + LFS2_TRACE("lfs2_emubd_sync -> %d", err); + return err; } lfs2_emubd_tole32(emu); res = fwrite(&emu->history, sizeof(emu->history), 1, f); lfs2_emubd_fromle32(emu); if (res < 1) { - return -errno; + err = -errno; + LFS2_TRACE("lfs2_emubd_sync -> %d", err); + return err; } err = fclose(f); if (err) { - return -errno; + err = -errno; + LFS2_TRACE("lfs2_emubd_sync -> %d", err); + return err; } + LFS2_TRACE("lfs2_emubd_sync -> %d", 0); return 0; } diff --git a/emubd/lfs2_emubd.h b/emubd/lfs2_emubd.h index 42dbfe5..1028ea0 100644 --- a/emubd/lfs2_emubd.h +++ b/emubd/lfs2_emubd.h @@ -17,20 +17,8 @@ extern "C" // Config options -#ifndef LFS2_EMUBD_READ_SIZE -#define LFS2_EMUBD_READ_SIZE 1 -#endif - -#ifndef LFS2_EMUBD_PROG_SIZE -#define LFS2_EMUBD_PROG_SIZE 1 -#endif - -#ifndef LFS2_EMUBD_ERASE_SIZE -#define LFS2_EMUBD_ERASE_SIZE 512 -#endif - -#ifndef LFS2_EMUBD_TOTAL_SIZE -#define LFS2_EMUBD_TOTAL_SIZE 524288 +#ifndef LFS2_EMUBD_ERASE_VALUE +#define LFS2_EMUBD_ERASE_VALUE 0x00 #endif diff --git a/lfs2.c b/lfs2.c index ccaf63c..04bfa40 100644 --- a/lfs2.c +++ b/lfs2.c @@ -1,19 +1,8 @@ /* * The little filesystem * - * Copyright (c) 2017 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright (c) 2017, Arm Limited. All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause */ #include "lfs2.h" #include "lfs2_util.h" @@ -92,6 +81,7 @@ static int lfs2_bd_read(lfs2_t *lfs2, lfs2->cfg->cache_size); int err = lfs2->cfg->read(lfs2->cfg, rcache->block, rcache->off, rcache->buffer, rcache->size); + LFS2_ASSERT(err <= 0); if (err) { return err; } @@ -136,6 +126,7 @@ static int lfs2_bd_flush(lfs2_t *lfs2, lfs2_size_t diff = lfs2_alignup(pcache->size, lfs2->cfg->prog_size); int err = lfs2->cfg->prog(lfs2->cfg, pcache->block, pcache->off, pcache->buffer, diff); + LFS2_ASSERT(err <= 0); if (err) { return err; } @@ -170,7 +161,9 @@ static int lfs2_bd_sync(lfs2_t *lfs2, return err; } - return lfs2->cfg->sync(lfs2->cfg); + err = lfs2->cfg->sync(lfs2->cfg); + LFS2_ASSERT(err <= 0); + return err; } static int lfs2_bd_prog(lfs2_t *lfs2, @@ -221,7 +214,9 @@ static int lfs2_bd_prog(lfs2_t *lfs2, static int lfs2_bd_erase(lfs2_t *lfs2, lfs2_block_t block) { LFS2_ASSERT(block < lfs2->cfg->block_count); - return lfs2->cfg->erase(lfs2->cfg, block); + int err = lfs2->cfg->erase(lfs2->cfg, block); + LFS2_ASSERT(err <= 0); + return err; } @@ -414,7 +409,7 @@ static int lfs2_dir_commit(lfs2_t *lfs2, lfs2_mdir_t *dir, static int lfs2_dir_compact(lfs2_t *lfs2, lfs2_mdir_t *dir, const struct lfs2_mattr *attrs, int attrcount, lfs2_mdir_t *source, uint16_t begin, uint16_t end); -static int lfs2_file_relocate(lfs2_t *lfs2, lfs2_file_t *file); +static int lfs2_file_outline(lfs2_t *lfs2, lfs2_file_t *file); static int lfs2_file_flush(lfs2_t *lfs2, lfs2_file_t *file); static void lfs2_fs_preporphans(lfs2_t *lfs2, int8_t orphans); static void lfs2_fs_prepmove(lfs2_t *lfs2, @@ -471,7 +466,7 @@ static int lfs2_alloc(lfs2_t *lfs2, lfs2_block_t *block) { // check if we have looked at all blocks since last ack if (lfs2->free.ack == 0) { - LFS2_WARN("No more free space %"PRIu32, + LFS2_ERROR("No more free space %"PRIu32, lfs2->free.i + lfs2->free.off); return LFS2_ERR_NOSPC; } @@ -630,11 +625,17 @@ static int lfs2_dir_traverse_filter(void *p, lfs2_tag_t *filtertag = p; (void)buffer; + // which mask depends on unique bit in tag structure + uint32_t mask = (tag & LFS2_MKTAG(0x100, 0, 0)) + ? LFS2_MKTAG(0x7ff, 0x3ff, 0) + : LFS2_MKTAG(0x700, 0x3ff, 0); + // check for redundancy - uint32_t mask = LFS2_MKTAG(0x7ff, 0x3ff, 0); if ((mask & tag) == (mask & *filtertag) || - (mask & tag) == (LFS2_MKTAG(LFS2_TYPE_DELETE, 0, 0) | - (LFS2_MKTAG(0, 0x3ff, 0) & *filtertag))) { + lfs2_tag_isdelete(*filtertag) || + (LFS2_MKTAG(0x7ff, 0x3ff, 0) & tag) == ( + LFS2_MKTAG(LFS2_TYPE_DELETE, 0, 0) | + (LFS2_MKTAG(0, 0x3ff, 0) & *filtertag))) { return true; } @@ -965,7 +966,7 @@ static lfs2_stag_t lfs2_dir_fetchmatch(lfs2_t *lfs2, dir->rev = revs[(r+1)%2]; } - LFS2_ERROR("Corrupted dir pair at %"PRIu32" %"PRIu32, + LFS2_ERROR("Corrupted dir pair at %"PRIx32" %"PRIx32, dir->pair[0], dir->pair[1]); return LFS2_ERR_CORRUPT; } @@ -1232,65 +1233,85 @@ static int lfs2_dir_commitattr(lfs2_t *lfs2, struct lfs2_commit *commit, static int lfs2_dir_commitcrc(lfs2_t *lfs2, struct lfs2_commit *commit) { // align to program units - lfs2_off_t off = lfs2_alignup(commit->off + 2*sizeof(uint32_t), + const lfs2_off_t off1 = commit->off + sizeof(lfs2_tag_t); + const lfs2_off_t end = lfs2_alignup(off1 + sizeof(uint32_t), lfs2->cfg->prog_size); - // read erased state from next program unit - lfs2_tag_t tag; - int err = lfs2_bd_read(lfs2, - NULL, &lfs2->rcache, sizeof(tag), - commit->block, off, &tag, sizeof(tag)); - if (err && err != LFS2_ERR_CORRUPT) { - return err; - } + // create crc tags to fill up remainder of commit, note that + // padding is not crcd, which lets fetches skip padding but + // makes committing a bit more complicated + while (commit->off < end) { + lfs2_off_t off = commit->off + sizeof(lfs2_tag_t); + lfs2_off_t noff = lfs2_min(end - off, 0x3fe) + off; + if (noff < end) { + noff = lfs2_min(noff, end - 2*sizeof(uint32_t)); + } - // build crc tag - bool reset = ~lfs2_frombe32(tag) >> 31; - tag = LFS2_MKTAG(LFS2_TYPE_CRC + reset, 0x3ff, - off - (commit->off+sizeof(lfs2_tag_t))); + // read erased state from next program unit + lfs2_tag_t tag = 0xffffffff; + int err = lfs2_bd_read(lfs2, + NULL, &lfs2->rcache, sizeof(tag), + commit->block, noff, &tag, sizeof(tag)); + if (err && err != LFS2_ERR_CORRUPT) { + return err; + } - // write out crc - uint32_t footer[2]; - footer[0] = lfs2_tobe32(tag ^ commit->ptag); - commit->crc = lfs2_crc(commit->crc, &footer[0], sizeof(footer[0])); - footer[1] = lfs2_tole32(commit->crc); - err = lfs2_bd_prog(lfs2, - &lfs2->pcache, &lfs2->rcache, false, - commit->block, commit->off, &footer, sizeof(footer)); - if (err) { - return err; - } - commit->off += sizeof(tag)+lfs2_tag_size(tag); - commit->ptag = tag ^ (reset << 31); + // build crc tag + bool reset = ~lfs2_frombe32(tag) >> 31; + tag = LFS2_MKTAG(LFS2_TYPE_CRC + reset, 0x3ff, noff - off); - // flush buffers - err = lfs2_bd_sync(lfs2, &lfs2->pcache, &lfs2->rcache, false); - if (err) { - return err; - } - - // successful commit, check checksum to make sure - uint32_t crc = 0xffffffff; - lfs2_size_t size = commit->off - lfs2_tag_size(tag) - commit->begin; - for (lfs2_off_t i = 0; i < size; i++) { - // leave it up to caching to make this efficient - uint8_t dat; - err = lfs2_bd_read(lfs2, - NULL, &lfs2->rcache, size-i, - commit->block, commit->begin+i, &dat, 1); + // write out crc + uint32_t footer[2]; + footer[0] = lfs2_tobe32(tag ^ commit->ptag); + commit->crc = lfs2_crc(commit->crc, &footer[0], sizeof(footer[0])); + footer[1] = lfs2_tole32(commit->crc); + err = lfs2_bd_prog(lfs2, + &lfs2->pcache, &lfs2->rcache, false, + commit->block, commit->off, &footer, sizeof(footer)); if (err) { return err; } - crc = lfs2_crc(crc, &dat, 1); + commit->off += sizeof(tag)+lfs2_tag_size(tag); + commit->ptag = tag ^ (reset << 31); + commit->crc = 0xffffffff; // reset crc for next "commit" } + // flush buffers + int err = lfs2_bd_sync(lfs2, &lfs2->pcache, &lfs2->rcache, false); if (err) { return err; } - if (crc != commit->crc) { - return LFS2_ERR_CORRUPT; + // successful commit, check checksums to make sure + lfs2_off_t off = commit->begin; + lfs2_off_t noff = off1; + while (off < end) { + uint32_t crc = 0xffffffff; + for (lfs2_off_t i = off; i < noff+sizeof(uint32_t); i++) { + // leave it up to caching to make this efficient + uint8_t dat; + err = lfs2_bd_read(lfs2, + NULL, &lfs2->rcache, noff+sizeof(uint32_t)-i, + commit->block, i, &dat, 1); + if (err) { + return err; + } + + crc = lfs2_crc(crc, &dat, 1); + } + + // detected write error? + if (crc != 0) { + return LFS2_ERR_CORRUPT; + } + + // skip padding + off = lfs2_min(end - noff, 0x3fe) + noff; + if (off < end) { + off = lfs2_min(off, end - 2*sizeof(uint32_t)); + } + noff = off + sizeof(uint32_t); } return 0; @@ -1453,7 +1474,7 @@ static int lfs2_dir_compact(lfs2_t *lfs2, // increment revision count dir->rev += 1; - if (lfs2->cfg->block_cycles && + if (lfs2->cfg->block_cycles > 0 && (dir->rev % (lfs2->cfg->block_cycles+1) == 0)) { if (lfs2_pair_cmp(dir->pair, (const lfs2_block_t[2]){0, 1}) == 0) { // oh no! we're writing too much to the superblock, @@ -1479,6 +1500,11 @@ static int lfs2_dir_compact(lfs2_t *lfs2, end = begin; } } +#if LFS2_MIGRATE + } else if (lfs2_pair_cmp(dir->pair, lfs2->root) == 0 && lfs2->lfs21) { + // we can't relocate our root during migrations, as this would + // cause the superblock to get updated, which would clobber v1 +#endif } else { // we're writing too much, time to relocate exhausted = true; @@ -1583,11 +1609,11 @@ static int lfs2_dir_compact(lfs2_t *lfs2, } // successful compaction, swap dir pair to indicate most recent + LFS2_ASSERT(commit.off % lfs2->cfg->prog_size == 0); lfs2_pair_swap(dir->pair); dir->count = end - begin; dir->off = commit.off; dir->etag = commit.ptag; - dir->erased = (dir->off % lfs2->cfg->prog_size == 0); // note we able to have already handled move here if (lfs2_gstate_hasmovehere(&lfs2->gpending, dir->pair)) { lfs2_gstate_xormove(&lfs2->gpending, @@ -1601,12 +1627,12 @@ relocate: relocated = true; lfs2_cache_drop(lfs2, &lfs2->pcache); if (!exhausted) { - LFS2_DEBUG("Bad block at %"PRIu32, dir->pair[1]); + LFS2_DEBUG("Bad block at %"PRIx32, dir->pair[1]); } // can't relocate superblock, filesystem is now frozen if (lfs2_pair_cmp(oldpair, (const lfs2_block_t[2]){0, 1}) == 0) { - LFS2_WARN("Superblock %"PRIu32" has become unwritable", oldpair[1]); + LFS2_WARN("Superblock %"PRIx32" has become unwritable", oldpair[1]); return LFS2_ERR_NOSPC; } @@ -1624,7 +1650,7 @@ relocate: lfs2->gdelta = (struct lfs2_gstate){0}; } else { // update references if we relocated - LFS2_DEBUG("Relocating %"PRIu32" %"PRIu32" to %"PRIu32" %"PRIu32, + LFS2_DEBUG("Relocating %"PRIx32" %"PRIx32" -> %"PRIx32" %"PRIx32, oldpair[0], oldpair[1], dir->pair[0], dir->pair[1]); int err = lfs2_fs_relocate(lfs2, oldpair, dir->pair); if (err) { @@ -1643,11 +1669,7 @@ static int lfs2_dir_commit(lfs2_t *lfs2, lfs2_mdir_t *dir, if (dir != &f->m && lfs2_pair_cmp(f->m.pair, dir->pair) == 0 && f->type == LFS2_TYPE_REG && (f->flags & LFS2_F_INLINE) && f->ctz.size > lfs2->cfg->cache_size) { - f->flags &= ~LFS2_F_READING; - f->off = 0; - - lfs2_alloc_ack(lfs2); - int err = lfs2_file_relocate(lfs2, f); + int err = lfs2_file_outline(lfs2, f); if (err) { return err; } @@ -1758,6 +1780,7 @@ static int lfs2_dir_commit(lfs2_t *lfs2, lfs2_mdir_t *dir, } // successful commit, update dir + LFS2_ASSERT(commit.off % lfs2->cfg->prog_size == 0); dir->off = commit.off; dir->etag = commit.ptag; @@ -1821,9 +1844,11 @@ compact: /// Top level directory operations /// int lfs2_mkdir(lfs2_t *lfs2, const char *path) { + LFS2_TRACE("lfs2_mkdir(%p, \"%s\")", (void*)lfs2, path); // deorphan if we haven't yet, needed at most once after poweron int err = lfs2_fs_forceconsistency(lfs2); if (err) { + LFS2_TRACE("lfs2_mkdir -> %d", err); return err; } @@ -1831,12 +1856,14 @@ int lfs2_mkdir(lfs2_t *lfs2, const char *path) { uint16_t id; err = lfs2_dir_find(lfs2, &cwd, &path, &id); if (!(err == LFS2_ERR_NOENT && id != 0x3ff)) { + LFS2_TRACE("lfs2_mkdir -> %d", (err < 0) ? err : LFS2_ERR_EXIST); return (err < 0) ? err : LFS2_ERR_EXIST; } // check that name fits lfs2_size_t nlen = strlen(path); if (nlen > lfs2->name_max) { + LFS2_TRACE("lfs2_mkdir -> %d", LFS2_ERR_NAMETOOLONG); return LFS2_ERR_NAMETOOLONG; } @@ -1845,6 +1872,7 @@ int lfs2_mkdir(lfs2_t *lfs2, const char *path) { lfs2_mdir_t dir; err = lfs2_dir_alloc(lfs2, &dir); if (err) { + LFS2_TRACE("lfs2_mkdir -> %d", err); return err; } @@ -1853,6 +1881,7 @@ int lfs2_mkdir(lfs2_t *lfs2, const char *path) { while (pred.split) { err = lfs2_dir_fetch(lfs2, &pred, pred.tail); if (err) { + LFS2_TRACE("lfs2_mkdir -> %d", err); return err; } } @@ -1863,6 +1892,7 @@ int lfs2_mkdir(lfs2_t *lfs2, const char *path) { {LFS2_MKTAG(LFS2_TYPE_SOFTTAIL, 0x3ff, 8), pred.tail})); lfs2_pair_fromle32(pred.tail); if (err) { + LFS2_TRACE("lfs2_mkdir -> %d", err); return err; } @@ -1875,6 +1905,7 @@ int lfs2_mkdir(lfs2_t *lfs2, const char *path) { {LFS2_MKTAG(LFS2_TYPE_SOFTTAIL, 0x3ff, 8), dir.pair})); lfs2_pair_fromle32(dir.pair); if (err) { + LFS2_TRACE("lfs2_mkdir -> %d", err); return err; } lfs2_fs_preporphans(lfs2, -1); @@ -1891,19 +1922,24 @@ int lfs2_mkdir(lfs2_t *lfs2, const char *path) { : LFS2_MKTAG(LFS2_FROM_NOOP, 0, 0), dir.pair})); lfs2_pair_fromle32(dir.pair); if (err) { + LFS2_TRACE("lfs2_mkdir -> %d", err); return err; } + LFS2_TRACE("lfs2_mkdir -> %d", 0); return 0; } int lfs2_dir_open(lfs2_t *lfs2, lfs2_dir_t *dir, const char *path) { + LFS2_TRACE("lfs2_dir_open(%p, %p, \"%s\")", (void*)lfs2, (void*)dir, path); lfs2_stag_t tag = lfs2_dir_find(lfs2, &dir->m, &path, NULL); if (tag < 0) { + LFS2_TRACE("lfs2_dir_open -> %d", tag); return tag; } if (lfs2_tag_type3(tag) != LFS2_TYPE_DIR) { + LFS2_TRACE("lfs2_dir_open -> %d", LFS2_ERR_NOTDIR); return LFS2_ERR_NOTDIR; } @@ -1917,6 +1953,7 @@ int lfs2_dir_open(lfs2_t *lfs2, lfs2_dir_t *dir, const char *path) { lfs2_stag_t res = lfs2_dir_get(lfs2, &dir->m, LFS2_MKTAG(0x700, 0x3ff, 0), LFS2_MKTAG(LFS2_TYPE_STRUCT, lfs2_tag_id(tag), 8), pair); if (res < 0) { + LFS2_TRACE("lfs2_dir_open -> %d", res); return res; } lfs2_pair_fromle32(pair); @@ -1925,6 +1962,7 @@ int lfs2_dir_open(lfs2_t *lfs2, lfs2_dir_t *dir, const char *path) { // fetch first pair int err = lfs2_dir_fetch(lfs2, &dir->m, pair); if (err) { + LFS2_TRACE("lfs2_dir_open -> %d", err); return err; } @@ -1939,10 +1977,12 @@ int lfs2_dir_open(lfs2_t *lfs2, lfs2_dir_t *dir, const char *path) { dir->next = (lfs2_dir_t*)lfs2->mlist; lfs2->mlist = (struct lfs2_mlist*)dir; + LFS2_TRACE("lfs2_dir_open -> %d", 0); return 0; } int lfs2_dir_close(lfs2_t *lfs2, lfs2_dir_t *dir) { + LFS2_TRACE("lfs2_dir_close(%p, %p)", (void*)lfs2, (void*)dir); // remove from list of mdirs for (struct lfs2_mlist **p = &lfs2->mlist; *p; p = &(*p)->next) { if (*p == (struct lfs2_mlist*)dir) { @@ -1951,10 +1991,13 @@ int lfs2_dir_close(lfs2_t *lfs2, lfs2_dir_t *dir) { } } + LFS2_TRACE("lfs2_dir_close -> %d", 0); return 0; } int lfs2_dir_read(lfs2_t *lfs2, lfs2_dir_t *dir, struct lfs2_info *info) { + LFS2_TRACE("lfs2_dir_read(%p, %p, %p)", + (void*)lfs2, (void*)dir, (void*)info); memset(info, 0, sizeof(*info)); // special offset for '.' and '..' @@ -1962,22 +2005,26 @@ int lfs2_dir_read(lfs2_t *lfs2, lfs2_dir_t *dir, struct lfs2_info *info) { info->type = LFS2_TYPE_DIR; strcpy(info->name, "."); dir->pos += 1; - return 1; + LFS2_TRACE("lfs2_dir_read -> %d", true); + return true; } else if (dir->pos == 1) { info->type = LFS2_TYPE_DIR; strcpy(info->name, ".."); dir->pos += 1; - return 1; + LFS2_TRACE("lfs2_dir_read -> %d", true); + return true; } while (true) { if (dir->id == dir->m.count) { if (!dir->m.split) { + LFS2_TRACE("lfs2_dir_read -> %d", false); return false; } int err = lfs2_dir_fetch(lfs2, &dir->m, dir->m.tail); if (err) { + LFS2_TRACE("lfs2_dir_read -> %d", err); return err; } @@ -1986,6 +2033,7 @@ int lfs2_dir_read(lfs2_t *lfs2, lfs2_dir_t *dir, struct lfs2_info *info) { int err = lfs2_dir_getinfo(lfs2, &dir->m, dir->id, info); if (err && err != LFS2_ERR_NOENT) { + LFS2_TRACE("lfs2_dir_read -> %d", err); return err; } @@ -1996,13 +2044,17 @@ int lfs2_dir_read(lfs2_t *lfs2, lfs2_dir_t *dir, struct lfs2_info *info) { } dir->pos += 1; + LFS2_TRACE("lfs2_dir_read -> %d", true); return true; } int lfs2_dir_seek(lfs2_t *lfs2, lfs2_dir_t *dir, lfs2_off_t off) { + LFS2_TRACE("lfs2_dir_seek(%p, %p, %"PRIu32")", + (void*)lfs2, (void*)dir, off); // simply walk from head dir int err = lfs2_dir_rewind(lfs2, dir); if (err) { + LFS2_TRACE("lfs2_dir_seek -> %d", err); return err; } @@ -2017,28 +2069,35 @@ int lfs2_dir_seek(lfs2_t *lfs2, lfs2_dir_t *dir, lfs2_off_t off) { if (dir->id == dir->m.count) { if (!dir->m.split) { + LFS2_TRACE("lfs2_dir_seek -> %d", LFS2_ERR_INVAL); return LFS2_ERR_INVAL; } err = lfs2_dir_fetch(lfs2, &dir->m, dir->m.tail); if (err) { + LFS2_TRACE("lfs2_dir_seek -> %d", err); return err; } } } + LFS2_TRACE("lfs2_dir_seek -> %d", 0); return 0; } lfs2_soff_t lfs2_dir_tell(lfs2_t *lfs2, lfs2_dir_t *dir) { + LFS2_TRACE("lfs2_dir_tell(%p, %p)", (void*)lfs2, (void*)dir); (void)lfs2; + LFS2_TRACE("lfs2_dir_tell -> %"PRId32, dir->pos); return dir->pos; } int lfs2_dir_rewind(lfs2_t *lfs2, lfs2_dir_t *dir) { + LFS2_TRACE("lfs2_dir_rewind(%p, %p)", (void*)lfs2, (void*)dir); // reload the head dir int err = lfs2_dir_fetch(lfs2, &dir->m, dir->head); if (err) { + LFS2_TRACE("lfs2_dir_rewind -> %d", err); return err; } @@ -2046,6 +2105,7 @@ int lfs2_dir_rewind(lfs2_t *lfs2, lfs2_dir_t *dir) { dir->m.pair[1] = dir->head[1]; dir->id = 0; dir->pos = 0; + LFS2_TRACE("lfs2_dir_rewind -> %d", 0); return 0; } @@ -2193,7 +2253,7 @@ static int lfs2_ctz_extend(lfs2_t *lfs2, } relocate: - LFS2_DEBUG("Bad block at %"PRIu32, nblock); + LFS2_DEBUG("Bad block at %"PRIx32, nblock); // just clear cache and try a new block lfs2_cache_drop(lfs2, pcache); @@ -2248,10 +2308,16 @@ static int lfs2_ctz_traverse(lfs2_t *lfs2, int lfs2_file_opencfg(lfs2_t *lfs2, lfs2_file_t *file, const char *path, int flags, const struct lfs2_file_config *cfg) { + LFS2_TRACE("lfs2_file_opencfg(%p, %p, \"%s\", %x, %p {" + ".buffer=%p, .attrs=%p, .attr_count=%"PRIu32"})", + (void*)lfs2, (void*)file, path, flags, + (void*)cfg, cfg->buffer, (void*)cfg->attrs, cfg->attr_count); + // deorphan if we haven't yet, needed at most once after poweron if ((flags & 3) != LFS2_O_RDONLY) { int err = lfs2_fs_forceconsistency(lfs2); if (err) { + LFS2_TRACE("lfs2_file_opencfg -> %d", err); return err; } } @@ -2259,7 +2325,7 @@ int lfs2_file_opencfg(lfs2_t *lfs2, lfs2_file_t *file, // setup simple file details int err; file->cfg = cfg; - file->flags = flags; + file->flags = flags | LFS2_F_OPENED; file->pos = 0; file->cache.buffer = NULL; @@ -2381,22 +2447,31 @@ int lfs2_file_opencfg(lfs2_t *lfs2, lfs2_file_t *file, } } + LFS2_TRACE("lfs2_file_opencfg -> %d", 0); return 0; cleanup: // clean up lingering resources file->flags |= LFS2_F_ERRED; lfs2_file_close(lfs2, file); + LFS2_TRACE("lfs2_file_opencfg -> %d", err); return err; } int lfs2_file_open(lfs2_t *lfs2, lfs2_file_t *file, const char *path, int flags) { + LFS2_TRACE("lfs2_file_open(%p, %p, \"%s\", %x)", + (void*)lfs2, (void*)file, path, flags); static const struct lfs2_file_config defaults = {0}; - return lfs2_file_opencfg(lfs2, file, path, flags, &defaults); + int err = lfs2_file_opencfg(lfs2, file, path, flags, &defaults); + LFS2_TRACE("lfs2_file_open -> %d", err); + return err; } int lfs2_file_close(lfs2_t *lfs2, lfs2_file_t *file) { + LFS2_TRACE("lfs2_file_close(%p, %p)", (void*)lfs2, (void*)file); + LFS2_ASSERT(file->flags & LFS2_F_OPENED); + int err = lfs2_file_sync(lfs2, file); // remove from list of mdirs @@ -2412,10 +2487,14 @@ int lfs2_file_close(lfs2_t *lfs2, lfs2_file_t *file) { lfs2_free(file->cache.buffer); } + file->flags &= ~LFS2_F_OPENED; + LFS2_TRACE("lfs2_file_close -> %d", err); return err; } static int lfs2_file_relocate(lfs2_t *lfs2, lfs2_file_t *file) { + LFS2_ASSERT(file->flags & LFS2_F_OPENED); + while (true) { // just relocate what exists into new block lfs2_block_t nblock; @@ -2473,19 +2552,32 @@ static int lfs2_file_relocate(lfs2_t *lfs2, lfs2_file_t *file) { lfs2_cache_zero(lfs2, &lfs2->pcache); file->block = nblock; - file->flags &= ~LFS2_F_INLINE; file->flags |= LFS2_F_WRITING; return 0; relocate: - LFS2_DEBUG("Bad block at %"PRIu32, nblock); + LFS2_DEBUG("Bad block at %"PRIx32, nblock); // just clear cache and try a new block lfs2_cache_drop(lfs2, &lfs2->pcache); } } +static int lfs2_file_outline(lfs2_t *lfs2, lfs2_file_t *file) { + file->off = file->pos; + lfs2_alloc_ack(lfs2); + int err = lfs2_file_relocate(lfs2, file); + if (err) { + return err; + } + + file->flags &= ~LFS2_F_INLINE; + return 0; +} + static int lfs2_file_flush(lfs2_t *lfs2, lfs2_file_t *file) { + LFS2_ASSERT(file->flags & LFS2_F_OPENED); + if (file->flags & LFS2_F_READING) { if (!(file->flags & LFS2_F_INLINE)) { lfs2_cache_drop(lfs2, &file->cache); @@ -2501,7 +2593,7 @@ static int lfs2_file_flush(lfs2_t *lfs2, lfs2_file_t *file) { lfs2_file_t orig = { .ctz.head = file->ctz.head, .ctz.size = file->ctz.size, - .flags = LFS2_O_RDONLY, + .flags = LFS2_O_RDONLY | LFS2_F_OPENED, .pos = file->pos, .cache = lfs2->rcache, }; @@ -2541,7 +2633,7 @@ static int lfs2_file_flush(lfs2_t *lfs2, lfs2_file_t *file) { break; relocate: - LFS2_DEBUG("Bad block at %"PRIu32, file->block); + LFS2_DEBUG("Bad block at %"PRIx32, file->block); err = lfs2_file_relocate(lfs2, file); if (err) { return err; @@ -2564,10 +2656,14 @@ relocate: } int lfs2_file_sync(lfs2_t *lfs2, lfs2_file_t *file) { + LFS2_TRACE("lfs2_file_sync(%p, %p)", (void*)lfs2, (void*)file); + LFS2_ASSERT(file->flags & LFS2_F_OPENED); + while (true) { int err = lfs2_file_flush(lfs2, file); if (err) { file->flags |= LFS2_F_ERRED; + LFS2_TRACE("lfs2_file_sync -> %d", err); return err; } @@ -2604,20 +2700,22 @@ int lfs2_file_sync(lfs2_t *lfs2, lfs2_file_t *file) { goto relocate; } file->flags |= LFS2_F_ERRED; + LFS2_TRACE("lfs2_file_sync -> %d", err); return err; } file->flags &= ~LFS2_F_DIRTY; } + LFS2_TRACE("lfs2_file_sync -> %d", 0); return 0; relocate: // inline file doesn't fit anymore - file->off = file->pos; - err = lfs2_file_relocate(lfs2, file); + err = lfs2_file_outline(lfs2, file); if (err) { file->flags |= LFS2_F_ERRED; + LFS2_TRACE("lfs2_file_sync -> %d", err); return err; } } @@ -2625,23 +2723,26 @@ relocate: lfs2_ssize_t lfs2_file_read(lfs2_t *lfs2, lfs2_file_t *file, void *buffer, lfs2_size_t size) { + LFS2_TRACE("lfs2_file_read(%p, %p, %p, %"PRIu32")", + (void*)lfs2, (void*)file, buffer, size); + LFS2_ASSERT(file->flags & LFS2_F_OPENED); + LFS2_ASSERT((file->flags & 3) != LFS2_O_WRONLY); + uint8_t *data = buffer; lfs2_size_t nsize = size; - if ((file->flags & 3) == LFS2_O_WRONLY) { - return LFS2_ERR_BADF; - } - if (file->flags & LFS2_F_WRITING) { // flush out any writes int err = lfs2_file_flush(lfs2, file); if (err) { + LFS2_TRACE("lfs2_file_read -> %"PRId32, err); return err; } } if (file->pos >= file->ctz.size) { // eof if past end + LFS2_TRACE("lfs2_file_read -> %"PRId32, 0); return 0; } @@ -2657,6 +2758,7 @@ lfs2_ssize_t lfs2_file_read(lfs2_t *lfs2, lfs2_file_t *file, file->ctz.head, file->ctz.size, file->pos, &file->block, &file->off); if (err) { + LFS2_TRACE("lfs2_file_read -> %"PRId32, err); return err; } } else { @@ -2676,6 +2778,7 @@ lfs2_ssize_t lfs2_file_read(lfs2_t *lfs2, lfs2_file_t *file, LFS2_MKTAG(LFS2_TYPE_INLINESTRUCT, file->id, 0), file->off, data, diff); if (err) { + LFS2_TRACE("lfs2_file_read -> %"PRId32, err); return err; } } else { @@ -2683,6 +2786,7 @@ lfs2_ssize_t lfs2_file_read(lfs2_t *lfs2, lfs2_file_t *file, NULL, &file->cache, lfs2->cfg->block_size, file->block, file->off, data, diff); if (err) { + LFS2_TRACE("lfs2_file_read -> %"PRId32, err); return err; } } @@ -2693,22 +2797,25 @@ lfs2_ssize_t lfs2_file_read(lfs2_t *lfs2, lfs2_file_t *file, nsize -= diff; } + LFS2_TRACE("lfs2_file_read -> %"PRId32, size); return size; } lfs2_ssize_t lfs2_file_write(lfs2_t *lfs2, lfs2_file_t *file, const void *buffer, lfs2_size_t size) { + LFS2_TRACE("lfs2_file_write(%p, %p, %p, %"PRIu32")", + (void*)lfs2, (void*)file, buffer, size); + LFS2_ASSERT(file->flags & LFS2_F_OPENED); + LFS2_ASSERT((file->flags & 3) != LFS2_O_RDONLY); + const uint8_t *data = buffer; lfs2_size_t nsize = size; - if ((file->flags & 3) == LFS2_O_RDONLY) { - return LFS2_ERR_BADF; - } - if (file->flags & LFS2_F_READING) { // drop any reads int err = lfs2_file_flush(lfs2, file); if (err) { + LFS2_TRACE("lfs2_file_write -> %"PRId32, err); return err; } } @@ -2719,6 +2826,7 @@ lfs2_ssize_t lfs2_file_write(lfs2_t *lfs2, lfs2_file_t *file, if (file->pos + size > lfs2->file_max) { // Larger than file limit? + LFS2_TRACE("lfs2_file_write -> %"PRId32, LFS2_ERR_FBIG); return LFS2_ERR_FBIG; } @@ -2730,6 +2838,7 @@ lfs2_ssize_t lfs2_file_write(lfs2_t *lfs2, lfs2_file_t *file, while (file->pos < pos) { lfs2_ssize_t res = lfs2_file_write(lfs2, file, &(uint8_t){0}, 1); if (res < 0) { + LFS2_TRACE("lfs2_file_write -> %"PRId32, res); return res; } } @@ -2740,11 +2849,10 @@ lfs2_ssize_t lfs2_file_write(lfs2_t *lfs2, lfs2_file_t *file, lfs2_min(0x3fe, lfs2_min( lfs2->cfg->cache_size, lfs2->cfg->block_size/8))) { // inline file doesn't fit anymore - file->off = file->pos; - lfs2_alloc_ack(lfs2); - int err = lfs2_file_relocate(lfs2, file); + int err = lfs2_file_outline(lfs2, file); if (err) { file->flags |= LFS2_F_ERRED; + LFS2_TRACE("lfs2_file_write -> %"PRId32, err); return err; } } @@ -2761,6 +2869,7 @@ lfs2_ssize_t lfs2_file_write(lfs2_t *lfs2, lfs2_file_t *file, file->pos-1, &file->block, &file->off); if (err) { file->flags |= LFS2_F_ERRED; + LFS2_TRACE("lfs2_file_write -> %"PRId32, err); return err; } @@ -2775,6 +2884,7 @@ lfs2_ssize_t lfs2_file_write(lfs2_t *lfs2, lfs2_file_t *file, &file->block, &file->off); if (err) { file->flags |= LFS2_F_ERRED; + LFS2_TRACE("lfs2_file_write -> %"PRId32, err); return err; } } else { @@ -2795,6 +2905,7 @@ lfs2_ssize_t lfs2_file_write(lfs2_t *lfs2, lfs2_file_t *file, goto relocate; } file->flags |= LFS2_F_ERRED; + LFS2_TRACE("lfs2_file_write -> %"PRId32, err); return err; } @@ -2803,6 +2914,7 @@ relocate: err = lfs2_file_relocate(lfs2, file); if (err) { file->flags |= LFS2_F_ERRED; + LFS2_TRACE("lfs2_file_write -> %"PRId32, err); return err; } } @@ -2816,14 +2928,20 @@ relocate: } file->flags &= ~LFS2_F_ERRED; + LFS2_TRACE("lfs2_file_write -> %"PRId32, size); return size; } lfs2_soff_t lfs2_file_seek(lfs2_t *lfs2, lfs2_file_t *file, lfs2_soff_t off, int whence) { + LFS2_TRACE("lfs2_file_seek(%p, %p, %"PRId32", %d)", + (void*)lfs2, (void*)file, off, whence); + LFS2_ASSERT(file->flags & LFS2_F_OPENED); + // write out everything beforehand, may be noop if rdonly int err = lfs2_file_flush(lfs2, file); if (err) { + LFS2_TRACE("lfs2_file_seek -> %"PRId32, err); return err; } @@ -2839,20 +2957,24 @@ lfs2_soff_t lfs2_file_seek(lfs2_t *lfs2, lfs2_file_t *file, if (npos > lfs2->file_max) { // file position out of range + LFS2_TRACE("lfs2_file_seek -> %"PRId32, LFS2_ERR_INVAL); return LFS2_ERR_INVAL; } // update pos file->pos = npos; + LFS2_TRACE("lfs2_file_seek -> %"PRId32, npos); return npos; } int lfs2_file_truncate(lfs2_t *lfs2, lfs2_file_t *file, lfs2_off_t size) { - if ((file->flags & 3) == LFS2_O_RDONLY) { - return LFS2_ERR_BADF; - } + LFS2_TRACE("lfs2_file_truncate(%p, %p, %"PRIu32")", + (void*)lfs2, (void*)file, size); + LFS2_ASSERT(file->flags & LFS2_F_OPENED); + LFS2_ASSERT((file->flags & 3) != LFS2_O_RDONLY); if (size > LFS2_FILE_MAX) { + LFS2_TRACE("lfs2_file_truncate -> %d", LFS2_ERR_INVAL); return LFS2_ERR_INVAL; } @@ -2861,6 +2983,7 @@ int lfs2_file_truncate(lfs2_t *lfs2, lfs2_file_t *file, lfs2_off_t size) { // need to flush since directly changing metadata int err = lfs2_file_flush(lfs2, file); if (err) { + LFS2_TRACE("lfs2_file_truncate -> %d", err); return err; } @@ -2869,6 +2992,7 @@ int lfs2_file_truncate(lfs2_t *lfs2, lfs2_file_t *file, lfs2_off_t size) { file->ctz.head, file->ctz.size, size, &file->block, &file->off); if (err) { + LFS2_TRACE("lfs2_file_truncate -> %d", err); return err; } @@ -2882,6 +3006,7 @@ int lfs2_file_truncate(lfs2_t *lfs2, lfs2_file_t *file, lfs2_off_t size) { if (file->pos != oldsize) { int err = lfs2_file_seek(lfs2, file, 0, LFS2_SEEK_END); if (err < 0) { + LFS2_TRACE("lfs2_file_truncate -> %d", err); return err; } } @@ -2890,6 +3015,7 @@ int lfs2_file_truncate(lfs2_t *lfs2, lfs2_file_t *file, lfs2_off_t size) { while (file->pos < size) { lfs2_ssize_t res = lfs2_file_write(lfs2, file, &(uint8_t){0}, 1); if (res < 0) { + LFS2_TRACE("lfs2_file_truncate -> %d", res); return res; } } @@ -2897,32 +3023,45 @@ int lfs2_file_truncate(lfs2_t *lfs2, lfs2_file_t *file, lfs2_off_t size) { // restore pos int err = lfs2_file_seek(lfs2, file, pos, LFS2_SEEK_SET); if (err < 0) { + LFS2_TRACE("lfs2_file_truncate -> %d", err); return err; } } + LFS2_TRACE("lfs2_file_truncate -> %d", 0); return 0; } lfs2_soff_t lfs2_file_tell(lfs2_t *lfs2, lfs2_file_t *file) { + LFS2_TRACE("lfs2_file_tell(%p, %p)", (void*)lfs2, (void*)file); + LFS2_ASSERT(file->flags & LFS2_F_OPENED); (void)lfs2; + LFS2_TRACE("lfs2_file_tell -> %"PRId32, file->pos); return file->pos; } int lfs2_file_rewind(lfs2_t *lfs2, lfs2_file_t *file) { + LFS2_TRACE("lfs2_file_rewind(%p, %p)", (void*)lfs2, (void*)file); lfs2_soff_t res = lfs2_file_seek(lfs2, file, 0, LFS2_SEEK_SET); if (res < 0) { + LFS2_TRACE("lfs2_file_rewind -> %d", res); return res; } + LFS2_TRACE("lfs2_file_rewind -> %d", 0); return 0; } lfs2_soff_t lfs2_file_size(lfs2_t *lfs2, lfs2_file_t *file) { + LFS2_TRACE("lfs2_file_size(%p, %p)", (void*)lfs2, (void*)file); + LFS2_ASSERT(file->flags & LFS2_F_OPENED); (void)lfs2; if (file->flags & LFS2_F_WRITING) { + LFS2_TRACE("lfs2_file_size -> %"PRId32, + lfs2_max(file->pos, file->ctz.size)); return lfs2_max(file->pos, file->ctz.size); } else { + LFS2_TRACE("lfs2_file_size -> %"PRId32, file->ctz.size); return file->ctz.size; } } @@ -2930,25 +3069,32 @@ lfs2_soff_t lfs2_file_size(lfs2_t *lfs2, lfs2_file_t *file) { /// General fs operations /// int lfs2_stat(lfs2_t *lfs2, const char *path, struct lfs2_info *info) { + LFS2_TRACE("lfs2_stat(%p, \"%s\", %p)", (void*)lfs2, path, (void*)info); lfs2_mdir_t cwd; lfs2_stag_t tag = lfs2_dir_find(lfs2, &cwd, &path, NULL); if (tag < 0) { + LFS2_TRACE("lfs2_stat -> %d", tag); return tag; } - return lfs2_dir_getinfo(lfs2, &cwd, lfs2_tag_id(tag), info); + int err = lfs2_dir_getinfo(lfs2, &cwd, lfs2_tag_id(tag), info); + LFS2_TRACE("lfs2_stat -> %d", err); + return err; } int lfs2_remove(lfs2_t *lfs2, const char *path) { + LFS2_TRACE("lfs2_remove(%p, \"%s\")", (void*)lfs2, path); // deorphan if we haven't yet, needed at most once after poweron int err = lfs2_fs_forceconsistency(lfs2); if (err) { + LFS2_TRACE("lfs2_remove -> %d", err); return err; } lfs2_mdir_t cwd; lfs2_stag_t tag = lfs2_dir_find(lfs2, &cwd, &path, NULL); if (tag < 0 || lfs2_tag_id(tag) == 0x3ff) { + LFS2_TRACE("lfs2_remove -> %d", (tag < 0) ? tag : LFS2_ERR_INVAL); return (tag < 0) ? tag : LFS2_ERR_INVAL; } @@ -2959,16 +3105,19 @@ int lfs2_remove(lfs2_t *lfs2, const char *path) { lfs2_stag_t res = lfs2_dir_get(lfs2, &cwd, LFS2_MKTAG(0x700, 0x3ff, 0), LFS2_MKTAG(LFS2_TYPE_STRUCT, lfs2_tag_id(tag), 8), pair); if (res < 0) { + LFS2_TRACE("lfs2_remove -> %d", res); return res; } lfs2_pair_fromle32(pair); err = lfs2_dir_fetch(lfs2, &dir, pair); if (err) { + LFS2_TRACE("lfs2_remove -> %d", err); return err; } if (dir.count > 0 || dir.split) { + LFS2_TRACE("lfs2_remove -> %d", LFS2_ERR_NOTEMPTY); return LFS2_ERR_NOTEMPTY; } @@ -2980,6 +3129,7 @@ int lfs2_remove(lfs2_t *lfs2, const char *path) { err = lfs2_dir_commit(lfs2, &cwd, LFS2_MKATTRS( {LFS2_MKTAG(LFS2_TYPE_DELETE, lfs2_tag_id(tag), 0), NULL})); if (err) { + LFS2_TRACE("lfs2_remove -> %d", err); return err; } @@ -2989,22 +3139,28 @@ int lfs2_remove(lfs2_t *lfs2, const char *path) { err = lfs2_fs_pred(lfs2, dir.pair, &cwd); if (err) { + LFS2_TRACE("lfs2_remove -> %d", err); return err; } err = lfs2_dir_drop(lfs2, &cwd, &dir); if (err) { + LFS2_TRACE("lfs2_remove -> %d", err); return err; } } + LFS2_TRACE("lfs2_remove -> %d", 0); return 0; } int lfs2_rename(lfs2_t *lfs2, const char *oldpath, const char *newpath) { + LFS2_TRACE("lfs2_rename(%p, \"%s\", \"%s\")", (void*)lfs2, oldpath, newpath); + // deorphan if we haven't yet, needed at most once after poweron int err = lfs2_fs_forceconsistency(lfs2); if (err) { + LFS2_TRACE("lfs2_rename -> %d", err); return err; } @@ -3012,6 +3168,7 @@ int lfs2_rename(lfs2_t *lfs2, const char *oldpath, const char *newpath) { lfs2_mdir_t oldcwd; lfs2_stag_t oldtag = lfs2_dir_find(lfs2, &oldcwd, &oldpath, NULL); if (oldtag < 0 || lfs2_tag_id(oldtag) == 0x3ff) { + LFS2_TRACE("lfs2_rename -> %d", (oldtag < 0) ? oldtag : LFS2_ERR_INVAL); return (oldtag < 0) ? oldtag : LFS2_ERR_INVAL; } @@ -3021,6 +3178,7 @@ int lfs2_rename(lfs2_t *lfs2, const char *oldpath, const char *newpath) { lfs2_stag_t prevtag = lfs2_dir_find(lfs2, &newcwd, &newpath, &newid); if ((prevtag < 0 || lfs2_tag_id(prevtag) == 0x3ff) && !(prevtag == LFS2_ERR_NOENT && newid != 0x3ff)) { + LFS2_TRACE("lfs2_rename -> %d", (prevtag < 0) ? prevtag : LFS2_ERR_INVAL); return (prevtag < 0) ? prevtag : LFS2_ERR_INVAL; } @@ -3029,9 +3187,11 @@ int lfs2_rename(lfs2_t *lfs2, const char *oldpath, const char *newpath) { // check that name fits lfs2_size_t nlen = strlen(newpath); if (nlen > lfs2->name_max) { + LFS2_TRACE("lfs2_rename -> %d", LFS2_ERR_NAMETOOLONG); return LFS2_ERR_NAMETOOLONG; } } else if (lfs2_tag_type3(prevtag) != lfs2_tag_type3(oldtag)) { + LFS2_TRACE("lfs2_rename -> %d", LFS2_ERR_ISDIR); return LFS2_ERR_ISDIR; } else if (lfs2_tag_type3(prevtag) == LFS2_TYPE_DIR) { // must be empty before removal @@ -3039,6 +3199,7 @@ int lfs2_rename(lfs2_t *lfs2, const char *oldpath, const char *newpath) { lfs2_stag_t res = lfs2_dir_get(lfs2, &newcwd, LFS2_MKTAG(0x700, 0x3ff, 0), LFS2_MKTAG(LFS2_TYPE_STRUCT, newid, 8), prevpair); if (res < 0) { + LFS2_TRACE("lfs2_rename -> %d", res); return res; } lfs2_pair_fromle32(prevpair); @@ -3046,10 +3207,12 @@ int lfs2_rename(lfs2_t *lfs2, const char *oldpath, const char *newpath) { // must be empty before removal err = lfs2_dir_fetch(lfs2, &prevdir, prevpair); if (err) { + LFS2_TRACE("lfs2_rename -> %d", err); return err; } if (prevdir.count > 0 || prevdir.split) { + LFS2_TRACE("lfs2_rename -> %d", LFS2_ERR_NOTEMPTY); return LFS2_ERR_NOTEMPTY; } @@ -3079,6 +3242,7 @@ int lfs2_rename(lfs2_t *lfs2, const char *oldpath, const char *newpath) { newpath}, {LFS2_MKTAG(LFS2_FROM_MOVE, newid, lfs2_tag_id(oldtag)), &oldcwd})); if (err) { + LFS2_TRACE("lfs2_rename -> %d", err); return err; } @@ -3087,6 +3251,7 @@ int lfs2_rename(lfs2_t *lfs2, const char *oldpath, const char *newpath) { if (lfs2_pair_cmp(oldcwd.pair, newcwd.pair) != 0) { err = lfs2_dir_commit(lfs2, &oldcwd, NULL, 0); if (err) { + LFS2_TRACE("lfs2_rename -> %d", err); return err; } } @@ -3097,23 +3262,29 @@ int lfs2_rename(lfs2_t *lfs2, const char *oldpath, const char *newpath) { err = lfs2_fs_pred(lfs2, prevdir.pair, &newcwd); if (err) { + LFS2_TRACE("lfs2_rename -> %d", err); return err; } err = lfs2_dir_drop(lfs2, &newcwd, &prevdir); if (err) { + LFS2_TRACE("lfs2_rename -> %d", err); return err; } } + LFS2_TRACE("lfs2_rename -> %d", 0); return 0; } lfs2_ssize_t lfs2_getattr(lfs2_t *lfs2, const char *path, uint8_t type, void *buffer, lfs2_size_t size) { + LFS2_TRACE("lfs2_getattr(%p, \"%s\", %"PRIu8", %p, %"PRIu32")", + (void*)lfs2, path, type, buffer, size); lfs2_mdir_t cwd; lfs2_stag_t tag = lfs2_dir_find(lfs2, &cwd, &path, NULL); if (tag < 0) { + LFS2_TRACE("lfs2_getattr -> %"PRId32, tag); return tag; } @@ -3123,6 +3294,7 @@ lfs2_ssize_t lfs2_getattr(lfs2_t *lfs2, const char *path, id = 0; int err = lfs2_dir_fetch(lfs2, &cwd, lfs2->root); if (err) { + LFS2_TRACE("lfs2_getattr -> %"PRId32, err); return err; } } @@ -3133,12 +3305,17 @@ lfs2_ssize_t lfs2_getattr(lfs2_t *lfs2, const char *path, buffer); if (tag < 0) { if (tag == LFS2_ERR_NOENT) { + LFS2_TRACE("lfs2_getattr -> %"PRId32, LFS2_ERR_NOATTR); return LFS2_ERR_NOATTR; } + + LFS2_TRACE("lfs2_getattr -> %"PRId32, tag); return tag; } - return lfs2_tag_size(tag); + size = lfs2_tag_size(tag); + LFS2_TRACE("lfs2_getattr -> %"PRId32, size); + return size; } static int lfs2_commitattr(lfs2_t *lfs2, const char *path, @@ -3165,15 +3342,23 @@ static int lfs2_commitattr(lfs2_t *lfs2, const char *path, int lfs2_setattr(lfs2_t *lfs2, const char *path, uint8_t type, const void *buffer, lfs2_size_t size) { + LFS2_TRACE("lfs2_setattr(%p, \"%s\", %"PRIu8", %p, %"PRIu32")", + (void*)lfs2, path, type, buffer, size); if (size > lfs2->attr_max) { + LFS2_TRACE("lfs2_setattr -> %d", LFS2_ERR_NOSPC); return LFS2_ERR_NOSPC; } - return lfs2_commitattr(lfs2, path, type, buffer, size); + int err = lfs2_commitattr(lfs2, path, type, buffer, size); + LFS2_TRACE("lfs2_setattr -> %d", err); + return err; } int lfs2_removeattr(lfs2_t *lfs2, const char *path, uint8_t type) { - return lfs2_commitattr(lfs2, path, type, NULL, 0x3ff); + LFS2_TRACE("lfs2_removeattr(%p, \"%s\", %"PRIu8")", (void*)lfs2, path, type); + int err = lfs2_commitattr(lfs2, path, type, NULL, 0x3ff); + LFS2_TRACE("lfs2_removeattr -> %d", err); + return err; } @@ -3192,8 +3377,14 @@ static int lfs2_init(lfs2_t *lfs2, const struct lfs2_config *cfg) { LFS2_ASSERT(4*lfs2_npw2(0xffffffff / (lfs2->cfg->block_size-2*4)) <= lfs2->cfg->block_size); - // we don't support some corner cases - LFS2_ASSERT(lfs2->cfg->block_cycles < 0xffffffff); + // block_cycles = 0 is no longer supported. + // + // block_cycles is the number of erase cycles before littlefs evicts + // metadata logs as a part of wear leveling. Suggested values are in the + // range of 100-1000, or set block_cycles to -1 to disable block-level + // wear-leveling. + LFS2_ASSERT(lfs2->cfg->block_cycles != 0); + // setup read cache if (lfs2->cfg->read_buffer) { @@ -3291,10 +3482,27 @@ static int lfs2_deinit(lfs2_t *lfs2) { } int lfs2_format(lfs2_t *lfs2, const struct lfs2_config *cfg) { + LFS2_TRACE("lfs2_format(%p, %p {.context=%p, " + ".read=%p, .prog=%p, .erase=%p, .sync=%p, " + ".read_size=%"PRIu32", .prog_size=%"PRIu32", " + ".block_size=%"PRIu32", .block_count=%"PRIu32", " + ".block_cycles=%"PRIu32", .cache_size=%"PRIu32", " + ".lookahead_size=%"PRIu32", .read_buffer=%p, " + ".prog_buffer=%p, .lookahead_buffer=%p, " + ".name_max=%"PRIu32", .file_max=%"PRIu32", " + ".attr_max=%"PRIu32"})", + (void*)lfs2, (void*)cfg, cfg->context, + (void*)(uintptr_t)cfg->read, (void*)(uintptr_t)cfg->prog, + (void*)(uintptr_t)cfg->erase, (void*)(uintptr_t)cfg->sync, + cfg->read_size, cfg->prog_size, cfg->block_size, cfg->block_count, + cfg->block_cycles, cfg->cache_size, cfg->lookahead_size, + cfg->read_buffer, cfg->prog_buffer, cfg->lookahead_buffer, + cfg->name_max, cfg->file_max, cfg->attr_max); int err = 0; { err = lfs2_init(lfs2, cfg); if (err) { + LFS2_TRACE("lfs2_format -> %d", err); return err; } @@ -3324,7 +3532,7 @@ int lfs2_format(lfs2_t *lfs2, const struct lfs2_config *cfg) { }; lfs2_superblock_tole32(&superblock); - err = lfs2_dir_commit(lfs2, &root, LFS2_MKATTRS( + err = lfs2_dir_commit(lfs2, &root, LFS2_MKATTRS( {LFS2_MKTAG(LFS2_TYPE_CREATE, 0, 0), NULL}, {LFS2_MKTAG(LFS2_TYPE_SUPERBLOCK, 0, 8), "littlefs"}, {LFS2_MKTAG(LFS2_TYPE_INLINESTRUCT, 0, sizeof(superblock)), @@ -3350,12 +3558,30 @@ int lfs2_format(lfs2_t *lfs2, const struct lfs2_config *cfg) { cleanup: lfs2_deinit(lfs2); + LFS2_TRACE("lfs2_format -> %d", err); return err; } int lfs2_mount(lfs2_t *lfs2, const struct lfs2_config *cfg) { + LFS2_TRACE("lfs2_mount(%p, %p {.context=%p, " + ".read=%p, .prog=%p, .erase=%p, .sync=%p, " + ".read_size=%"PRIu32", .prog_size=%"PRIu32", " + ".block_size=%"PRIu32", .block_count=%"PRIu32", " + ".block_cycles=%"PRIu32", .cache_size=%"PRIu32", " + ".lookahead_size=%"PRIu32", .read_buffer=%p, " + ".prog_buffer=%p, .lookahead_buffer=%p, " + ".name_max=%"PRIu32", .file_max=%"PRIu32", " + ".attr_max=%"PRIu32"})", + (void*)lfs2, (void*)cfg, cfg->context, + (void*)(uintptr_t)cfg->read, (void*)(uintptr_t)cfg->prog, + (void*)(uintptr_t)cfg->erase, (void*)(uintptr_t)cfg->sync, + cfg->read_size, cfg->prog_size, cfg->block_size, cfg->block_count, + cfg->block_cycles, cfg->cache_size, cfg->lookahead_size, + cfg->read_buffer, cfg->prog_buffer, cfg->lookahead_buffer, + cfg->name_max, cfg->file_max, cfg->attr_max); int err = lfs2_init(lfs2, cfg); if (err) { + LFS2_TRACE("lfs2_mount -> %d", err); return err; } @@ -3440,7 +3666,7 @@ int lfs2_mount(lfs2_t *lfs2, const struct lfs2_config *cfg) { // has gstate? err = lfs2_dir_getgstate(lfs2, &dir, &lfs2->gpending); if (err) { - return err; + goto cleanup; } } @@ -3454,7 +3680,7 @@ int lfs2_mount(lfs2_t *lfs2, const struct lfs2_config *cfg) { lfs2->gpending.tag += !lfs2_tag_isvalid(lfs2->gpending.tag); lfs2->gstate = lfs2->gpending; if (lfs2_gstate_hasmove(&lfs2->gstate)) { - LFS2_DEBUG("Found move %"PRIu32" %"PRIu32" %"PRIu16, + LFS2_DEBUG("Found move %"PRIx32" %"PRIx32" %"PRIx16, lfs2->gstate.pair[0], lfs2->gstate.pair[1], lfs2_tag_id(lfs2->gstate.tag)); @@ -3466,21 +3692,28 @@ int lfs2_mount(lfs2_t *lfs2, const struct lfs2_config *cfg) { lfs2->free.i = 0; lfs2_alloc_ack(lfs2); + LFS2_TRACE("lfs2_mount -> %d", 0); return 0; cleanup: lfs2_unmount(lfs2); + LFS2_TRACE("lfs2_mount -> %d", err); return err; } int lfs2_unmount(lfs2_t *lfs2) { - return lfs2_deinit(lfs2); + LFS2_TRACE("lfs2_unmount(%p)", (void*)lfs2); + int err = lfs2_deinit(lfs2); + LFS2_TRACE("lfs2_unmount -> %d", err); + return err; } /// Filesystem filesystem operations /// int lfs2_fs_traverse(lfs2_t *lfs2, int (*cb)(void *data, lfs2_block_t block), void *data) { + LFS2_TRACE("lfs2_fs_traverse(%p, %p, %p)", + (void*)lfs2, (void*)(uintptr_t)cb, data); // iterate over metadata pairs lfs2_mdir_t dir = {.tail = {0, 1}}; @@ -3489,6 +3722,7 @@ int lfs2_fs_traverse(lfs2_t *lfs2, if (lfs2->lfs21) { int err = lfs21_traverse(lfs2, cb, data); if (err) { + LFS2_TRACE("lfs2_fs_traverse -> %d", err); return err; } @@ -3501,6 +3735,7 @@ int lfs2_fs_traverse(lfs2_t *lfs2, for (int i = 0; i < 2; i++) { int err = cb(data, dir.tail[i]); if (err) { + LFS2_TRACE("lfs2_fs_traverse -> %d", err); return err; } } @@ -3508,6 +3743,7 @@ int lfs2_fs_traverse(lfs2_t *lfs2, // iterate through ids in directory int err = lfs2_dir_fetch(lfs2, &dir, dir.tail); if (err) { + LFS2_TRACE("lfs2_fs_traverse -> %d", err); return err; } @@ -3519,6 +3755,7 @@ int lfs2_fs_traverse(lfs2_t *lfs2, if (tag == LFS2_ERR_NOENT) { continue; } + LFS2_TRACE("lfs2_fs_traverse -> %d", tag); return tag; } lfs2_ctz_fromle32(&ctz); @@ -3527,6 +3764,7 @@ int lfs2_fs_traverse(lfs2_t *lfs2, err = lfs2_ctz_traverse(lfs2, NULL, &lfs2->rcache, ctz.head, ctz.size, cb, data); if (err) { + LFS2_TRACE("lfs2_fs_traverse -> %d", err); return err; } } @@ -3543,6 +3781,7 @@ int lfs2_fs_traverse(lfs2_t *lfs2, int err = lfs2_ctz_traverse(lfs2, &f->cache, &lfs2->rcache, f->ctz.head, f->ctz.size, cb, data); if (err) { + LFS2_TRACE("lfs2_fs_traverse -> %d", err); return err; } } @@ -3551,11 +3790,13 @@ int lfs2_fs_traverse(lfs2_t *lfs2, int err = lfs2_ctz_traverse(lfs2, &f->cache, &lfs2->rcache, f->block, f->pos, cb, data); if (err) { + LFS2_TRACE("lfs2_fs_traverse -> %d", err); return err; } } } + LFS2_TRACE("lfs2_fs_traverse -> %d", 0); return 0; } @@ -3626,7 +3867,7 @@ static int lfs2_fs_relocate(lfs2_t *lfs2, const lfs2_block_t oldpair[2], lfs2_block_t newpair[2]) { // update internal root if (lfs2_pair_cmp(oldpair, lfs2->root) == 0) { - LFS2_DEBUG("Relocating root %"PRIu32" %"PRIu32, + LFS2_DEBUG("Relocating root %"PRIx32" %"PRIx32, newpair[0], newpair[1]); lfs2->root[0] = newpair[0]; lfs2->root[1] = newpair[1]; @@ -3704,7 +3945,7 @@ static int lfs2_fs_demove(lfs2_t *lfs2) { } // Fix bad moves - LFS2_DEBUG("Fixing move %"PRIu32" %"PRIu32" %"PRIu16, + LFS2_DEBUG("Fixing move %"PRIx32" %"PRIx32" %"PRIx16, lfs2->gstate.pair[0], lfs2->gstate.pair[1], lfs2_tag_id(lfs2->gstate.tag)); @@ -3752,7 +3993,7 @@ static int lfs2_fs_deorphan(lfs2_t *lfs2) { if (tag == LFS2_ERR_NOENT) { // we are an orphan - LFS2_DEBUG("Fixing orphan %"PRIu32" %"PRIu32, + LFS2_DEBUG("Fixing orphan %"PRIx32" %"PRIx32, pdir.tail[0], pdir.tail[1]); err = lfs2_dir_drop(lfs2, &pdir, &dir); @@ -3773,7 +4014,7 @@ static int lfs2_fs_deorphan(lfs2_t *lfs2) { if (!lfs2_pair_sync(pair, pdir.tail)) { // we have desynced - LFS2_DEBUG("Fixing half-orphan %"PRIu32" %"PRIu32, + LFS2_DEBUG("Fixing half-orphan %"PRIx32" %"PRIx32, pair[0], pair[1]); lfs2_pair_tole32(pair); @@ -3819,13 +4060,16 @@ static int lfs2_fs_size_count(void *p, lfs2_block_t block) { } lfs2_ssize_t lfs2_fs_size(lfs2_t *lfs2) { + LFS2_TRACE("lfs2_fs_size(%p)", (void*)lfs2); lfs2_size_t size = 0; int err = lfs2_fs_traverse(lfs2, lfs2_fs_size_count, &size); if (err) { + LFS2_TRACE("lfs2_fs_size -> %"PRId32, err); return err; } - return size; + LFS2_TRACE("lfs2_fs_size -> %"PRId32, err); + return size; } #ifdef LFS2_MIGRATE @@ -4033,7 +4277,7 @@ static int lfs21_dir_fetch(lfs2_t *lfs2, } if (!valid) { - LFS2_ERROR("Corrupted dir pair at %" PRIu32 " %" PRIu32 , + LFS2_ERROR("Corrupted dir pair at %" PRIx32 " %" PRIx32 , tpair[0], tpair[1]); return LFS2_ERR_CORRUPT; } @@ -4249,9 +4493,26 @@ static int lfs21_unmount(lfs2_t *lfs2) { /// v1 migration /// int lfs2_migrate(lfs2_t *lfs2, const struct lfs2_config *cfg) { + LFS2_TRACE("lfs2_migrate(%p, %p {.context=%p, " + ".read=%p, .prog=%p, .erase=%p, .sync=%p, " + ".read_size=%"PRIu32", .prog_size=%"PRIu32", " + ".block_size=%"PRIu32", .block_count=%"PRIu32", " + ".block_cycles=%"PRIu32", .cache_size=%"PRIu32", " + ".lookahead_size=%"PRIu32", .read_buffer=%p, " + ".prog_buffer=%p, .lookahead_buffer=%p, " + ".name_max=%"PRIu32", .file_max=%"PRIu32", " + ".attr_max=%"PRIu32"})", + (void*)lfs2, (void*)cfg, cfg->context, + (void*)(uintptr_t)cfg->read, (void*)(uintptr_t)cfg->prog, + (void*)(uintptr_t)cfg->erase, (void*)(uintptr_t)cfg->sync, + cfg->read_size, cfg->prog_size, cfg->block_size, cfg->block_count, + cfg->block_cycles, cfg->cache_size, cfg->lookahead_size, + cfg->read_buffer, cfg->prog_buffer, cfg->lookahead_buffer, + cfg->name_max, cfg->file_max, cfg->attr_max); struct lfs21 lfs21; int err = lfs21_mount(lfs2, &lfs21, cfg); if (err) { + LFS2_TRACE("lfs2_migrate -> %d", err); return err; } @@ -4311,7 +4572,7 @@ int lfs2_migrate(lfs2_t *lfs2, const struct lfs2_config *cfg) { entry1.d.type &= ~0x80; } - + // also fetch name char name[LFS2_NAME_MAX+1]; memset(name, 0, sizeof(name)); @@ -4378,7 +4639,7 @@ int lfs2_migrate(lfs2_t *lfs2, const struct lfs2_config *cfg) { // Copy over first block to thread into fs. Unfortunately // if this fails there is not much we can do. - LFS2_DEBUG("Migrating %"PRIu32" %"PRIu32" -> %"PRIu32" %"PRIu32, + LFS2_DEBUG("Migrating %"PRIx32" %"PRIx32" -> %"PRIx32" %"PRIx32, lfs2->root[0], lfs2->root[1], dir1.head[0], dir1.head[1]); err = lfs2_bd_erase(lfs2, dir1.head[1]); @@ -4466,6 +4727,7 @@ int lfs2_migrate(lfs2_t *lfs2, const struct lfs2_config *cfg) { cleanup: lfs21_unmount(lfs2); + LFS2_TRACE("lfs2_migrate -> %d", err); return err; } diff --git a/lfs2.h b/lfs2.h index a345d54..fdbe007 100644 --- a/lfs2.h +++ b/lfs2.h @@ -21,7 +21,7 @@ extern "C" // Software library version // Major (top-nibble), incremented on backwards incompatible changes // Minor (bottom-nibble), incremented on feature additions -#define LFS2_VERSION 0x00020000 +#define LFS2_VERSION 0x00020001 #define LFS2_VERSION_MAJOR (0xffff & (LFS2_VERSION >> 16)) #define LFS2_VERSION_MINOR (0xffff & (LFS2_VERSION >> 0)) @@ -136,6 +136,7 @@ enum lfs2_open_flags { LFS2_F_READING = 0x040000, // File has been read since last flush LFS2_F_ERRED = 0x080000, // An error occured during write LFS2_F_INLINE = 0x100000, // Currently inlined in directory entry + LFS2_F_OPENED = 0x200000, // File has been opened }; // File seek flags @@ -190,9 +191,13 @@ struct lfs2_config { // Number of erasable blocks on the device. lfs2_size_t block_count; - // Number of erase cycles before we should move data to another block. - // May be zero, in which case no block-level wear-leveling is performed. - uint32_t block_cycles; + // Number of erase cycles before littlefs evicts metadata logs and moves + // the metadata to another block. Suggested values are in the + // range 100-1000, with large values having better performance at the cost + // of less consistent wear distribution. + // + // Set to -1 to disable block-level wear-leveling. + int32_t block_cycles; // Size of block caches. Each cache buffers a portion of a block in RAM. // The littlefs needs a read cache, a program cache, and one additional @@ -204,7 +209,7 @@ struct lfs2_config { // Size of the lookahead buffer in bytes. A larger lookahead buffer // increases the number of blocks found during an allocation pass. The // lookahead buffer is stored as a compact bitmap, so each byte of RAM - // can track 8 blocks. Must be a multiple of 4. + // can track 8 blocks. Must be a multiple of 8. lfs2_size_t lookahead_size; // Optional statically allocated read buffer. Must be cache_size. @@ -216,7 +221,7 @@ struct lfs2_config { void *prog_buffer; // Optional statically allocated lookahead buffer. Must be lookahead_size - // and aligned to a 64-bit boundary. By default lfs2_malloc is used to + // and aligned to a 32-bit boundary. By default lfs2_malloc is used to // allocate this buffer. void *lookahead_buffer; @@ -528,7 +533,7 @@ lfs2_ssize_t lfs2_file_write(lfs2_t *lfs2, lfs2_file_t *file, // Change the position of the file // // The change in position is determined by the offset and whence flag. -// Returns the old position of the file, or a negative error code on failure. +// Returns the new position of the file, or a negative error code on failure. lfs2_soff_t lfs2_file_seek(lfs2_t *lfs2, lfs2_file_t *file, lfs2_soff_t off, int whence); @@ -545,7 +550,7 @@ lfs2_soff_t lfs2_file_tell(lfs2_t *lfs2, lfs2_file_t *file); // Change the position of the file to the beginning of the file // -// Equivalent to lfs2_file_seek(lfs2, file, 0, LFS2_SEEK_CUR) +// Equivalent to lfs2_file_seek(lfs2, file, 0, LFS2_SEEK_SET) // Returns a negative error code on failure. int lfs2_file_rewind(lfs2_t *lfs2, lfs2_file_t *file); diff --git a/lfs2_util.h b/lfs2_util.h index 8e68210..0f27073 100644 --- a/lfs2_util.h +++ b/lfs2_util.h @@ -31,7 +31,10 @@ #ifndef LFS2_NO_ASSERT #include #endif -#if !defined(LFS2_NO_DEBUG) || !defined(LFS2_NO_WARN) || !defined(LFS2_NO_ERROR) +#if !defined(LFS2_NO_DEBUG) || \ + !defined(LFS2_NO_WARN) || \ + !defined(LFS2_NO_ERROR) || \ + defined(LFS2_YES_TRACE) #include #endif @@ -46,23 +49,30 @@ extern "C" // code footprint // Logging functions +#ifdef LFS2_YES_TRACE +#define LFS2_TRACE(fmt, ...) \ + printf("lfs2_trace:%d: " fmt "\n", __LINE__, __VA_ARGS__) +#else +#define LFS2_TRACE(fmt, ...) +#endif + #ifndef LFS2_NO_DEBUG #define LFS2_DEBUG(fmt, ...) \ - printf("lfs2 debug:%d: " fmt "\n", __LINE__, __VA_ARGS__) + printf("lfs2_debug:%d: " fmt "\n", __LINE__, __VA_ARGS__) #else #define LFS2_DEBUG(fmt, ...) #endif #ifndef LFS2_NO_WARN #define LFS2_WARN(fmt, ...) \ - printf("lfs2 warn:%d: " fmt "\n", __LINE__, __VA_ARGS__) + printf("lfs2_warn:%d: " fmt "\n", __LINE__, __VA_ARGS__) #else #define LFS2_WARN(fmt, ...) #endif #ifndef LFS2_NO_ERROR #define LFS2_ERROR(fmt, ...) \ - printf("lfs2 error:%d: " fmt "\n", __LINE__, __VA_ARGS__) + printf("lfs2_error:%d: " fmt "\n", __LINE__, __VA_ARGS__) #else #define LFS2_ERROR(fmt, ...) #endif diff --git a/tests/corrupt.py b/scripts/corrupt.py similarity index 100% rename from tests/corrupt.py rename to scripts/corrupt.py diff --git a/tests/debug.py b/scripts/debug.py similarity index 98% rename from tests/debug.py rename to scripts/debug.py index f8c0484..ba7525d 100755 --- a/tests/debug.py +++ b/scripts/debug.py @@ -95,7 +95,7 @@ def main(*blocks): print '%04x: %08x %-15s %3s %4s %-23s %-8s' % ( off, tag, typeof(type) + (' bad!' if iscrc and ~crc else ''), - id if id != 0x3ff else '.', + hex(id)[2:] if id != 0x3ff else '.', size if size != 0x3ff else 'x', ' '.join('%02x' % ord(c) for c in data[:8]), ''.join(c if c >= ' ' and c <= '~' else '.' for c in data[:8])) diff --git a/scripts/results.py b/scripts/results.py new file mode 100755 index 0000000..0e5cfc6 --- /dev/null +++ b/scripts/results.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python2 + +import struct +import sys +import time +import os +import re + +def main(): + with open('blocks/.config') as file: + read_size, prog_size, block_size, block_count = ( + struct.unpack(' " #e, v, e) +// implicit variable for asserts +uintmax_t test; // utility functions for traversals static int __attribute__((used)) test_count(void *p, lfs2_block_t b) {{ @@ -44,23 +31,17 @@ static int __attribute__((used)) test_count(void *p, lfs2_block_t b) {{ return 0; }} - // lfs2 declarations lfs2_t lfs2; lfs2_emubd_t bd; -lfs2_file_t file[4]; -lfs2_dir_t dir[4]; +// other declarations for convenience +lfs2_file_t file; +lfs2_dir_t dir; struct lfs2_info info; - uint8_t buffer[1024]; -uint8_t wbuffer[1024]; -uint8_t rbuffer[1024]; -lfs2_size_t size; -lfs2_size_t wsize; -lfs2_size_t rsize; - -uintmax_t test; +char path[1024]; +// test configuration options #ifndef LFS2_READ_SIZE #define LFS2_READ_SIZE 16 #endif @@ -82,7 +63,7 @@ uintmax_t test; #endif #ifndef LFS2_CACHE_SIZE -#define LFS2_CACHE_SIZE 64 +#define LFS2_CACHE_SIZE (64 % LFS2_PROG_SIZE == 0 ? 64 : LFS2_PROG_SIZE) #endif #ifndef LFS2_LOOKAHEAD_SIZE @@ -111,6 +92,5 @@ int main(void) {{ lfs2_emubd_create(&cfg, "blocks"); {tests} - lfs2_emubd_destroy(&cfg); }} diff --git a/scripts/test.py b/scripts/test.py new file mode 100755 index 0000000..fff7390 --- /dev/null +++ b/scripts/test.py @@ -0,0 +1,81 @@ +#!/usr/bin/env python2 + +import re +import sys +import subprocess +import os + + +def generate(test): + with open("scripts/template.fmt") as file: + template = file.read() + + haslines = 'TEST_LINE' in os.environ and 'TEST_FILE' in os.environ + + lines = [] + for offset, line in enumerate( + re.split('(?<=(?:.;| [{}]))\n', test.read())): + match = re.match('((?: *\n)*)( *)(.*)=>(.*);', + line, re.DOTALL | re.MULTILINE) + if match: + preface, tab, test, expect = match.groups() + lines.extend(['']*preface.count('\n')) + lines.append(tab+'test_assert({test}, {expect});'.format( + test=test.strip(), expect=expect.strip())) + else: + lines.append(line) + + # Create test file + with open('test.c', 'w') as file: + if 'TEST_LINE' in os.environ and 'TEST_FILE' in os.environ: + lines.insert(0, '#line %d "%s"' % ( + int(os.environ['TEST_LINE']) + 1, + os.environ['TEST_FILE'])) + lines.append('#line %d "test.c"' % ( + template[:template.find('{tests}')].count('\n') + + len(lines) + 2)) + + file.write(template.format(tests='\n'.join(lines))) + + # Remove build artifacts to force rebuild + try: + os.remove('test.o') + os.remove('lfs2') + except OSError: + pass + +def compile(): + subprocess.check_call([ + os.environ.get('MAKE', 'make'), + '--no-print-directory', '-s']) + +def execute(): + if 'EXEC' in os.environ: + subprocess.check_call([os.environ['EXEC'], "./lfs2"]) + else: + subprocess.check_call(["./lfs2"]) + +def main(test=None): + try: + if test and not test.startswith('-'): + with open(test) as file: + generate(file) + else: + generate(sys.stdin) + + compile() + + if test == '-s': + sys.exit(1) + + execute() + + except subprocess.CalledProcessError: + # Python stack trace is counterproductive, just exit + sys.exit(2) + except KeyboardInterrupt: + # Python stack trace is counterproductive, just exit + sys.exit(3) + +if __name__ == "__main__": + main(*sys.argv[1:]) diff --git a/tests/stats.py b/tests/stats.py deleted file mode 100755 index c2d0fab..0000000 --- a/tests/stats.py +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env python2 - -import struct -import sys -import time -import os -import re - -def main(): - with open('blocks/.config') as file: - s = struct.unpack('(.*);', line, re.DOTALL | re.MULTILINE) - if match: - tab, test, expect = match.groups() - lines.append(tab+'test = {test};'.format(test=test.strip())) - lines.append(tab+'test_assert("{name}", test, {expect});'.format( - name = re.match('\w*', test.strip()).group(), - expect = expect.strip())) - else: - lines.append(line) - - # Create test file - with open('test.c', 'w') as file: - file.write(template.format(tests='\n'.join(lines))) - - # Remove build artifacts to force rebuild - try: - os.remove('test.o') - os.remove('lfs2') - except OSError: - pass - -def compile(): - subprocess.check_call([ - os.environ.get('MAKE', 'make'), - '--no-print-directory', '-s']) - -def execute(): - if 'EXEC' in os.environ: - subprocess.check_call([os.environ['EXEC'], "./lfs2"]) - else: - subprocess.check_call(["./lfs2"]) - -def main(test=None): - if test and not test.startswith('-'): - with open(test) as file: - generate(file) - else: - generate(sys.stdin) - - compile() - - if test == '-s': - sys.exit(1) - - execute() - -if __name__ == "__main__": - main(*sys.argv[1:]) diff --git a/tests/test_alloc.sh b/tests/test_alloc.sh index 36019a9..da66683 100755 --- a/tests/test_alloc.sh +++ b/tests/test_alloc.sh @@ -1,16 +1,18 @@ #!/bin/bash -set -eu +set -euE +export TEST_FILE=$0 +trap 'export TEST_LINE=$LINENO' DEBUG echo "=== Allocator tests ===" rm -rf blocks -tests/test.py << TEST +scripts/test.py << TEST lfs2_format(&lfs2, &cfg) => 0; TEST SIZE=15000 lfs2_mkdir() { -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; lfs2_mkdir(&lfs2, "$1") => 0; lfs2_unmount(&lfs2) => 0; @@ -18,7 +20,7 @@ TEST } lfs2_remove() { -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; lfs2_remove(&lfs2, "$1/eggs") => 0; lfs2_remove(&lfs2, "$1/bacon") => 0; @@ -29,22 +31,23 @@ TEST } lfs2_alloc_singleproc() { -tests/test.py << TEST +scripts/test.py << TEST const char *names[] = {"bacon", "eggs", "pancakes"}; + lfs2_file_t files[sizeof(names)/sizeof(names[0])]; lfs2_mount(&lfs2, &cfg) => 0; for (unsigned n = 0; n < sizeof(names)/sizeof(names[0]); n++) { - sprintf((char*)buffer, "$1/%s", names[n]); - lfs2_file_open(&lfs2, &file[n], (char*)buffer, + sprintf(path, "$1/%s", names[n]); + lfs2_file_open(&lfs2, &files[n], path, LFS2_O_WRONLY | LFS2_O_CREAT | LFS2_O_APPEND) => 0; } for (unsigned n = 0; n < sizeof(names)/sizeof(names[0]); n++) { - size = strlen(names[n]); + lfs2_size_t size = strlen(names[n]); for (int i = 0; i < $SIZE; i++) { - lfs2_file_write(&lfs2, &file[n], names[n], size) => size; + lfs2_file_write(&lfs2, &files[n], names[n], size) => size; } } for (unsigned n = 0; n < sizeof(names)/sizeof(names[0]); n++) { - lfs2_file_close(&lfs2, &file[n]) => 0; + lfs2_file_close(&lfs2, &files[n]) => 0; } lfs2_unmount(&lfs2) => 0; TEST @@ -53,16 +56,16 @@ TEST lfs2_alloc_multiproc() { for name in bacon eggs pancakes do -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; - lfs2_file_open(&lfs2, &file[0], "$1/$name", + lfs2_file_open(&lfs2, &file, "$1/$name", LFS2_O_WRONLY | LFS2_O_CREAT | LFS2_O_APPEND) => 0; - size = strlen("$name"); + lfs2_size_t size = strlen("$name"); memcpy(buffer, "$name", size); for (int i = 0; i < $SIZE; i++) { - lfs2_file_write(&lfs2, &file[0], buffer, size) => size; + lfs2_file_write(&lfs2, &file, buffer, size) => size; } - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_close(&lfs2, &file) => 0; lfs2_unmount(&lfs2) => 0; TEST done @@ -71,15 +74,15 @@ done lfs2_verify() { for name in bacon eggs pancakes do -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; - lfs2_file_open(&lfs2, &file[0], "$1/$name", LFS2_O_RDONLY) => 0; - size = strlen("$name"); + lfs2_file_open(&lfs2, &file, "$1/$name", LFS2_O_RDONLY) => 0; + lfs2_size_t size = strlen("$name"); for (int i = 0; i < $SIZE; i++) { - lfs2_file_read(&lfs2, &file[0], buffer, size) => size; + lfs2_file_read(&lfs2, &file, buffer, size) => size; memcmp(buffer, "$name", size) => 0; } - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_close(&lfs2, &file) => 0; lfs2_unmount(&lfs2) => 0; TEST done @@ -115,19 +118,19 @@ lfs2_remove multiprocreuse lfs2_remove singleprocreuse echo "--- Exhaustion test ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; - lfs2_file_open(&lfs2, &file[0], "exhaustion", LFS2_O_WRONLY | LFS2_O_CREAT); - size = strlen("exhaustion"); + lfs2_file_open(&lfs2, &file, "exhaustion", LFS2_O_WRONLY | LFS2_O_CREAT); + lfs2_size_t size = strlen("exhaustion"); memcpy(buffer, "exhaustion", size); - lfs2_file_write(&lfs2, &file[0], buffer, size) => size; - lfs2_file_sync(&lfs2, &file[0]) => 0; + lfs2_file_write(&lfs2, &file, buffer, size) => size; + lfs2_file_sync(&lfs2, &file) => 0; size = strlen("blahblahblahblah"); memcpy(buffer, "blahblahblahblah", size); lfs2_ssize_t res; while (true) { - res = lfs2_file_write(&lfs2, &file[0], buffer, size); + res = lfs2_file_write(&lfs2, &file, buffer, size); if (res < 0) { break; } @@ -136,45 +139,45 @@ tests/test.py << TEST } res => LFS2_ERR_NOSPC; - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_close(&lfs2, &file) => 0; lfs2_unmount(&lfs2) => 0; TEST -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; - lfs2_file_open(&lfs2, &file[0], "exhaustion", LFS2_O_RDONLY); - size = strlen("exhaustion"); - lfs2_file_size(&lfs2, &file[0]) => size; - lfs2_file_read(&lfs2, &file[0], buffer, size) => size; + lfs2_file_open(&lfs2, &file, "exhaustion", LFS2_O_RDONLY); + lfs2_size_t size = strlen("exhaustion"); + lfs2_file_size(&lfs2, &file) => size; + lfs2_file_read(&lfs2, &file, buffer, size) => size; memcmp(buffer, "exhaustion", size) => 0; - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_close(&lfs2, &file) => 0; lfs2_unmount(&lfs2) => 0; TEST echo "--- Exhaustion wraparound test ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; lfs2_remove(&lfs2, "exhaustion") => 0; - lfs2_file_open(&lfs2, &file[0], "padding", LFS2_O_WRONLY | LFS2_O_CREAT); - size = strlen("buffering"); + lfs2_file_open(&lfs2, &file, "padding", LFS2_O_WRONLY | LFS2_O_CREAT); + lfs2_size_t size = strlen("buffering"); memcpy(buffer, "buffering", size); for (int i = 0; i < $SIZE; i++) { - lfs2_file_write(&lfs2, &file[0], buffer, size) => size; + lfs2_file_write(&lfs2, &file, buffer, size) => size; } - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_close(&lfs2, &file) => 0; lfs2_remove(&lfs2, "padding") => 0; - lfs2_file_open(&lfs2, &file[0], "exhaustion", LFS2_O_WRONLY | LFS2_O_CREAT); + lfs2_file_open(&lfs2, &file, "exhaustion", LFS2_O_WRONLY | LFS2_O_CREAT); size = strlen("exhaustion"); memcpy(buffer, "exhaustion", size); - lfs2_file_write(&lfs2, &file[0], buffer, size) => size; - lfs2_file_sync(&lfs2, &file[0]) => 0; + lfs2_file_write(&lfs2, &file, buffer, size) => size; + lfs2_file_sync(&lfs2, &file) => 0; size = strlen("blahblahblahblah"); memcpy(buffer, "blahblahblahblah", size); lfs2_ssize_t res; while (true) { - res = lfs2_file_write(&lfs2, &file[0], buffer, size); + res = lfs2_file_write(&lfs2, &file, buffer, size); if (res < 0) { break; } @@ -183,34 +186,34 @@ tests/test.py << TEST } res => LFS2_ERR_NOSPC; - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_close(&lfs2, &file) => 0; lfs2_unmount(&lfs2) => 0; TEST -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; - lfs2_file_open(&lfs2, &file[0], "exhaustion", LFS2_O_RDONLY); - size = strlen("exhaustion"); - lfs2_file_size(&lfs2, &file[0]) => size; - lfs2_file_read(&lfs2, &file[0], buffer, size) => size; + lfs2_file_open(&lfs2, &file, "exhaustion", LFS2_O_RDONLY); + lfs2_size_t size = strlen("exhaustion"); + lfs2_file_size(&lfs2, &file) => size; + lfs2_file_read(&lfs2, &file, buffer, size) => size; memcmp(buffer, "exhaustion", size) => 0; - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_close(&lfs2, &file) => 0; lfs2_remove(&lfs2, "exhaustion") => 0; lfs2_unmount(&lfs2) => 0; TEST echo "--- Dir exhaustion test ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; // find out max file size lfs2_mkdir(&lfs2, "exhaustiondir") => 0; - size = strlen("blahblahblahblah"); + lfs2_size_t size = strlen("blahblahblahblah"); memcpy(buffer, "blahblahblahblah", size); - lfs2_file_open(&lfs2, &file[0], "exhaustion", LFS2_O_WRONLY | LFS2_O_CREAT); + lfs2_file_open(&lfs2, &file, "exhaustion", LFS2_O_WRONLY | LFS2_O_CREAT); int count = 0; int err; while (true) { - err = lfs2_file_write(&lfs2, &file[0], buffer, size); + err = lfs2_file_write(&lfs2, &file, buffer, size); if (err < 0) { break; } @@ -218,28 +221,28 @@ tests/test.py << TEST count += 1; } err => LFS2_ERR_NOSPC; - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_close(&lfs2, &file) => 0; lfs2_remove(&lfs2, "exhaustion") => 0; lfs2_remove(&lfs2, "exhaustiondir") => 0; // see if dir fits with max file size - lfs2_file_open(&lfs2, &file[0], "exhaustion", LFS2_O_WRONLY | LFS2_O_CREAT); + lfs2_file_open(&lfs2, &file, "exhaustion", LFS2_O_WRONLY | LFS2_O_CREAT); for (int i = 0; i < count; i++) { - lfs2_file_write(&lfs2, &file[0], buffer, size) => size; + lfs2_file_write(&lfs2, &file, buffer, size) => size; } - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_close(&lfs2, &file) => 0; lfs2_mkdir(&lfs2, "exhaustiondir") => 0; lfs2_remove(&lfs2, "exhaustiondir") => 0; lfs2_remove(&lfs2, "exhaustion") => 0; // see if dir fits with > max file size - lfs2_file_open(&lfs2, &file[0], "exhaustion", LFS2_O_WRONLY | LFS2_O_CREAT); + lfs2_file_open(&lfs2, &file, "exhaustion", LFS2_O_WRONLY | LFS2_O_CREAT); for (int i = 0; i < count+1; i++) { - lfs2_file_write(&lfs2, &file[0], buffer, size) => size; + lfs2_file_write(&lfs2, &file, buffer, size) => size; } - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_close(&lfs2, &file) => 0; lfs2_mkdir(&lfs2, "exhaustiondir") => LFS2_ERR_NOSPC; @@ -248,22 +251,22 @@ tests/test.py << TEST TEST echo "--- Chained dir exhaustion test ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; // find out max file size lfs2_mkdir(&lfs2, "exhaustiondir") => 0; for (int i = 0; i < 10; i++) { - sprintf((char*)buffer, "dirwithanexhaustivelylongnameforpadding%d", i); - lfs2_mkdir(&lfs2, (char*)buffer) => 0; + sprintf(path, "dirwithanexhaustivelylongnameforpadding%d", i); + lfs2_mkdir(&lfs2, path) => 0; } - size = strlen("blahblahblahblah"); + lfs2_size_t size = strlen("blahblahblahblah"); memcpy(buffer, "blahblahblahblah", size); - lfs2_file_open(&lfs2, &file[0], "exhaustion", LFS2_O_WRONLY | LFS2_O_CREAT); + lfs2_file_open(&lfs2, &file, "exhaustion", LFS2_O_WRONLY | LFS2_O_CREAT); int count = 0; int err; while (true) { - err = lfs2_file_write(&lfs2, &file[0], buffer, size); + err = lfs2_file_write(&lfs2, &file, buffer, size); if (err < 0) { break; } @@ -271,25 +274,25 @@ tests/test.py << TEST count += 1; } err => LFS2_ERR_NOSPC; - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_close(&lfs2, &file) => 0; lfs2_remove(&lfs2, "exhaustion") => 0; lfs2_remove(&lfs2, "exhaustiondir") => 0; for (int i = 0; i < 10; i++) { - sprintf((char*)buffer, "dirwithanexhaustivelylongnameforpadding%d", i); - lfs2_remove(&lfs2, (char*)buffer) => 0; + sprintf(path, "dirwithanexhaustivelylongnameforpadding%d", i); + lfs2_remove(&lfs2, path) => 0; } // see that chained dir fails - lfs2_file_open(&lfs2, &file[0], "exhaustion", LFS2_O_WRONLY | LFS2_O_CREAT); + lfs2_file_open(&lfs2, &file, "exhaustion", LFS2_O_WRONLY | LFS2_O_CREAT); for (int i = 0; i < count+1; i++) { - lfs2_file_write(&lfs2, &file[0], buffer, size) => size; + lfs2_file_write(&lfs2, &file, buffer, size) => size; } - lfs2_file_sync(&lfs2, &file[0]) => 0; + lfs2_file_sync(&lfs2, &file) => 0; for (int i = 0; i < 10; i++) { - sprintf((char*)buffer, "dirwithanexhaustivelylongnameforpadding%d", i); - lfs2_mkdir(&lfs2, (char*)buffer) => 0; + sprintf(path, "dirwithanexhaustivelylongnameforpadding%d", i); + lfs2_mkdir(&lfs2, path) => 0; } lfs2_mkdir(&lfs2, "exhaustiondir") => LFS2_ERR_NOSPC; @@ -301,45 +304,44 @@ tests/test.py << TEST break; } - lfs2_ssize_t filesize = lfs2_file_size(&lfs2, &file[0]); + lfs2_ssize_t filesize = lfs2_file_size(&lfs2, &file); filesize > 0 => true; - lfs2_file_truncate(&lfs2, &file[0], filesize - size) => 0; - lfs2_file_sync(&lfs2, &file[0]) => 0; + lfs2_file_truncate(&lfs2, &file, filesize - size) => 0; + lfs2_file_sync(&lfs2, &file) => 0; } err => 0; lfs2_mkdir(&lfs2, "exhaustiondir2") => LFS2_ERR_NOSPC; - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_close(&lfs2, &file) => 0; lfs2_unmount(&lfs2) => 0; TEST echo "--- Split dir test ---" -rm -rf blocks -tests/test.py << TEST +scripts/test.py << TEST lfs2_format(&lfs2, &cfg) => 0; TEST -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; // create one block hole for half a directory - lfs2_file_open(&lfs2, &file[0], "bump", LFS2_O_WRONLY | LFS2_O_CREAT) => 0; + lfs2_file_open(&lfs2, &file, "bump", LFS2_O_WRONLY | LFS2_O_CREAT) => 0; for (lfs2_size_t i = 0; i < cfg.block_size; i += 2) { memcpy(&buffer[i], "hi", 2); } - lfs2_file_write(&lfs2, &file[0], buffer, cfg.block_size) => cfg.block_size; - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_write(&lfs2, &file, buffer, cfg.block_size) => cfg.block_size; + lfs2_file_close(&lfs2, &file) => 0; - lfs2_file_open(&lfs2, &file[0], "exhaustion", LFS2_O_WRONLY | LFS2_O_CREAT); - size = strlen("blahblahblahblah"); + lfs2_file_open(&lfs2, &file, "exhaustion", LFS2_O_WRONLY | LFS2_O_CREAT); + lfs2_size_t size = strlen("blahblahblahblah"); memcpy(buffer, "blahblahblahblah", size); for (lfs2_size_t i = 0; i < (cfg.block_count-4)*(cfg.block_size-8); i += size) { - lfs2_file_write(&lfs2, &file[0], buffer, size) => size; + lfs2_file_write(&lfs2, &file, buffer, size) => size; } - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_close(&lfs2, &file) => 0; // remount to force reset of lookahead lfs2_unmount(&lfs2) => 0; @@ -349,137 +351,134 @@ tests/test.py << TEST lfs2_remove(&lfs2, "bump") => 0; lfs2_mkdir(&lfs2, "splitdir") => 0; - lfs2_file_open(&lfs2, &file[0], "splitdir/bump", + lfs2_file_open(&lfs2, &file, "splitdir/bump", LFS2_O_WRONLY | LFS2_O_CREAT) => 0; for (lfs2_size_t i = 0; i < cfg.block_size; i += 2) { memcpy(&buffer[i], "hi", 2); } - lfs2_file_write(&lfs2, &file[0], buffer, 2*cfg.block_size) => LFS2_ERR_NOSPC; - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_write(&lfs2, &file, buffer, 2*cfg.block_size) => LFS2_ERR_NOSPC; + lfs2_file_close(&lfs2, &file) => 0; lfs2_unmount(&lfs2) => 0; TEST echo "--- Outdated lookahead test ---" -rm -rf blocks -tests/test.py << TEST +scripts/test.py << TEST lfs2_format(&lfs2, &cfg) => 0; lfs2_mount(&lfs2, &cfg) => 0; // fill completely with two files - lfs2_file_open(&lfs2, &file[0], "exhaustion1", + lfs2_file_open(&lfs2, &file, "exhaustion1", LFS2_O_WRONLY | LFS2_O_CREAT) => 0; - size = strlen("blahblahblahblah"); + lfs2_size_t size = strlen("blahblahblahblah"); memcpy(buffer, "blahblahblahblah", size); for (lfs2_size_t i = 0; i < ((cfg.block_count-2)/2)*(cfg.block_size-8); i += size) { - lfs2_file_write(&lfs2, &file[0], buffer, size) => size; + lfs2_file_write(&lfs2, &file, buffer, size) => size; } - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_close(&lfs2, &file) => 0; - lfs2_file_open(&lfs2, &file[0], "exhaustion2", + lfs2_file_open(&lfs2, &file, "exhaustion2", LFS2_O_WRONLY | LFS2_O_CREAT) => 0; size = strlen("blahblahblahblah"); memcpy(buffer, "blahblahblahblah", size); for (lfs2_size_t i = 0; i < ((cfg.block_count-2+1)/2)*(cfg.block_size-8); i += size) { - lfs2_file_write(&lfs2, &file[0], buffer, size) => size; + lfs2_file_write(&lfs2, &file, buffer, size) => size; } - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_close(&lfs2, &file) => 0; // remount to force reset of lookahead lfs2_unmount(&lfs2) => 0; lfs2_mount(&lfs2, &cfg) => 0; // rewrite one file - lfs2_file_open(&lfs2, &file[0], "exhaustion1", + lfs2_file_open(&lfs2, &file, "exhaustion1", LFS2_O_WRONLY | LFS2_O_TRUNC) => 0; - lfs2_file_sync(&lfs2, &file[0]) => 0; + lfs2_file_sync(&lfs2, &file) => 0; size = strlen("blahblahblahblah"); memcpy(buffer, "blahblahblahblah", size); for (lfs2_size_t i = 0; i < ((cfg.block_count-2)/2)*(cfg.block_size-8); i += size) { - lfs2_file_write(&lfs2, &file[0], buffer, size) => size; + lfs2_file_write(&lfs2, &file, buffer, size) => size; } - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_close(&lfs2, &file) => 0; // rewrite second file, this requires lookahead does not // use old population - lfs2_file_open(&lfs2, &file[0], "exhaustion2", + lfs2_file_open(&lfs2, &file, "exhaustion2", LFS2_O_WRONLY | LFS2_O_TRUNC) => 0; - lfs2_file_sync(&lfs2, &file[0]) => 0; + lfs2_file_sync(&lfs2, &file) => 0; size = strlen("blahblahblahblah"); memcpy(buffer, "blahblahblahblah", size); for (lfs2_size_t i = 0; i < ((cfg.block_count-2+1)/2)*(cfg.block_size-8); i += size) { - lfs2_file_write(&lfs2, &file[0], buffer, size) => size; + lfs2_file_write(&lfs2, &file, buffer, size) => size; } - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_close(&lfs2, &file) => 0; TEST echo "--- Outdated lookahead and split dir test ---" -rm -rf blocks -tests/test.py << TEST +scripts/test.py << TEST lfs2_format(&lfs2, &cfg) => 0; lfs2_mount(&lfs2, &cfg) => 0; // fill completely with two files - lfs2_file_open(&lfs2, &file[0], "exhaustion1", + lfs2_file_open(&lfs2, &file, "exhaustion1", LFS2_O_WRONLY | LFS2_O_CREAT) => 0; - size = strlen("blahblahblahblah"); + lfs2_size_t size = strlen("blahblahblahblah"); memcpy(buffer, "blahblahblahblah", size); for (lfs2_size_t i = 0; i < ((cfg.block_count-2)/2)*(cfg.block_size-8); i += size) { - lfs2_file_write(&lfs2, &file[0], buffer, size) => size; + lfs2_file_write(&lfs2, &file, buffer, size) => size; } - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_close(&lfs2, &file) => 0; - lfs2_file_open(&lfs2, &file[0], "exhaustion2", + lfs2_file_open(&lfs2, &file, "exhaustion2", LFS2_O_WRONLY | LFS2_O_CREAT) => 0; size = strlen("blahblahblahblah"); memcpy(buffer, "blahblahblahblah", size); for (lfs2_size_t i = 0; i < ((cfg.block_count-2+1)/2)*(cfg.block_size-8); i += size) { - lfs2_file_write(&lfs2, &file[0], buffer, size) => size; + lfs2_file_write(&lfs2, &file, buffer, size) => size; } - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_close(&lfs2, &file) => 0; // remount to force reset of lookahead lfs2_unmount(&lfs2) => 0; lfs2_mount(&lfs2, &cfg) => 0; // rewrite one file with a hole of one block - lfs2_file_open(&lfs2, &file[0], "exhaustion1", + lfs2_file_open(&lfs2, &file, "exhaustion1", LFS2_O_WRONLY | LFS2_O_TRUNC) => 0; - lfs2_file_sync(&lfs2, &file[0]) => 0; + lfs2_file_sync(&lfs2, &file) => 0; size = strlen("blahblahblahblah"); memcpy(buffer, "blahblahblahblah", size); for (lfs2_size_t i = 0; i < ((cfg.block_count-2)/2 - 1)*(cfg.block_size-8); i += size) { - lfs2_file_write(&lfs2, &file[0], buffer, size) => size; + lfs2_file_write(&lfs2, &file, buffer, size) => size; } - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_close(&lfs2, &file) => 0; // try to allocate a directory, should fail! lfs2_mkdir(&lfs2, "split") => LFS2_ERR_NOSPC; // file should not fail - lfs2_file_open(&lfs2, &file[0], "notasplit", + lfs2_file_open(&lfs2, &file, "notasplit", LFS2_O_WRONLY | LFS2_O_CREAT) => 0; - lfs2_file_write(&lfs2, &file[0], "hi", 2) => 2; - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_write(&lfs2, &file, "hi", 2) => 2; + lfs2_file_close(&lfs2, &file) => 0; lfs2_unmount(&lfs2) => 0; TEST -echo "--- Results ---" -tests/stats.py +scripts/results.py diff --git a/tests/test_attrs.sh b/tests/test_attrs.sh index 02041cd..2ef5cee 100755 --- a/tests/test_attrs.sh +++ b/tests/test_attrs.sh @@ -1,24 +1,27 @@ #!/bin/bash set -eu +export TEST_FILE=$0 +trap 'export TEST_LINE=$LINENO' DEBUG echo "=== Attr tests ===" rm -rf blocks -tests/test.py << TEST +scripts/test.py << TEST lfs2_format(&lfs2, &cfg) => 0; lfs2_mount(&lfs2, &cfg) => 0; lfs2_mkdir(&lfs2, "hello") => 0; - lfs2_file_open(&lfs2, &file[0], "hello/hello", + lfs2_file_open(&lfs2, &file, "hello/hello", LFS2_O_WRONLY | LFS2_O_CREAT) => 0; - lfs2_file_write(&lfs2, &file[0], "hello", strlen("hello")) + lfs2_file_write(&lfs2, &file, "hello", strlen("hello")) => strlen("hello"); - lfs2_file_close(&lfs2, &file[0]); + lfs2_file_close(&lfs2, &file); lfs2_unmount(&lfs2) => 0; TEST echo "--- Set/get attribute ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; + memset(buffer, 0, sizeof(buffer)); lfs2_setattr(&lfs2, "hello", 'A', "aaaa", 4) => 0; lfs2_setattr(&lfs2, "hello", 'B', "bbbbbb", 6) => 0; lfs2_setattr(&lfs2, "hello", 'C', "ccccc", 5) => 0; @@ -69,8 +72,9 @@ tests/test.py << TEST lfs2_unmount(&lfs2) => 0; TEST -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; + memset(buffer, 0, sizeof(buffer)); lfs2_getattr(&lfs2, "hello", 'A', buffer, 4) => 4; lfs2_getattr(&lfs2, "hello", 'B', buffer+4, 9) => 9; lfs2_getattr(&lfs2, "hello", 'C', buffer+13, 5) => 5; @@ -78,16 +82,17 @@ tests/test.py << TEST memcmp(buffer+4, "fffffffff", 9) => 0; memcmp(buffer+13, "ccccc", 5) => 0; - lfs2_file_open(&lfs2, &file[0], "hello/hello", LFS2_O_RDONLY) => 0; - lfs2_file_read(&lfs2, &file[0], buffer, sizeof(buffer)) => strlen("hello"); + lfs2_file_open(&lfs2, &file, "hello/hello", LFS2_O_RDONLY) => 0; + lfs2_file_read(&lfs2, &file, buffer, sizeof(buffer)) => strlen("hello"); memcmp(buffer, "hello", strlen("hello")) => 0; - lfs2_file_close(&lfs2, &file[0]); + lfs2_file_close(&lfs2, &file); lfs2_unmount(&lfs2) => 0; TEST echo "--- Set/get root attribute ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; + memset(buffer, 0, sizeof(buffer)); lfs2_setattr(&lfs2, "/", 'A', "aaaa", 4) => 0; lfs2_setattr(&lfs2, "/", 'B', "bbbbbb", 6) => 0; lfs2_setattr(&lfs2, "/", 'C', "ccccc", 5) => 0; @@ -137,8 +142,9 @@ tests/test.py << TEST lfs2_getattr(&lfs2, "/", 'C', buffer+10, 5) => 5; lfs2_unmount(&lfs2) => 0; TEST -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; + memset(buffer, 0, sizeof(buffer)); lfs2_getattr(&lfs2, "/", 'A', buffer, 4) => 4; lfs2_getattr(&lfs2, "/", 'B', buffer+4, 9) => 9; lfs2_getattr(&lfs2, "/", 'C', buffer+13, 5) => 5; @@ -146,16 +152,17 @@ tests/test.py << TEST memcmp(buffer+4, "fffffffff", 9) => 0; memcmp(buffer+13, "ccccc", 5) => 0; - lfs2_file_open(&lfs2, &file[0], "hello/hello", LFS2_O_RDONLY) => 0; - lfs2_file_read(&lfs2, &file[0], buffer, sizeof(buffer)) => strlen("hello"); + lfs2_file_open(&lfs2, &file, "hello/hello", LFS2_O_RDONLY) => 0; + lfs2_file_read(&lfs2, &file, buffer, sizeof(buffer)) => strlen("hello"); memcmp(buffer, "hello", strlen("hello")) => 0; - lfs2_file_close(&lfs2, &file[0]); + lfs2_file_close(&lfs2, &file); lfs2_unmount(&lfs2) => 0; TEST echo "--- Set/get file attribute ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; + memset(buffer, 0, sizeof(buffer)); struct lfs2_attr attrs1[] = { {'A', buffer, 4}, {'B', buffer+4, 6}, @@ -163,55 +170,55 @@ tests/test.py << TEST }; struct lfs2_file_config cfg1 = {.attrs=attrs1, .attr_count=3}; - lfs2_file_opencfg(&lfs2, &file[0], "hello/hello", LFS2_O_WRONLY, &cfg1) => 0; + lfs2_file_opencfg(&lfs2, &file, "hello/hello", LFS2_O_WRONLY, &cfg1) => 0; memcpy(buffer, "aaaa", 4); memcpy(buffer+4, "bbbbbb", 6); memcpy(buffer+10, "ccccc", 5); - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_close(&lfs2, &file) => 0; memset(buffer, 0, 15); - lfs2_file_opencfg(&lfs2, &file[0], "hello/hello", LFS2_O_RDONLY, &cfg1) => 0; - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_opencfg(&lfs2, &file, "hello/hello", LFS2_O_RDONLY, &cfg1) => 0; + lfs2_file_close(&lfs2, &file) => 0; memcmp(buffer, "aaaa", 4) => 0; memcmp(buffer+4, "bbbbbb", 6) => 0; memcmp(buffer+10, "ccccc", 5) => 0; attrs1[1].size = 0; - lfs2_file_opencfg(&lfs2, &file[0], "hello/hello", LFS2_O_WRONLY, &cfg1) => 0; - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_opencfg(&lfs2, &file, "hello/hello", LFS2_O_WRONLY, &cfg1) => 0; + lfs2_file_close(&lfs2, &file) => 0; memset(buffer, 0, 15); attrs1[1].size = 6; - lfs2_file_opencfg(&lfs2, &file[0], "hello/hello", LFS2_O_RDONLY, &cfg1) => 0; - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_opencfg(&lfs2, &file, "hello/hello", LFS2_O_RDONLY, &cfg1) => 0; + lfs2_file_close(&lfs2, &file) => 0; memcmp(buffer, "aaaa", 4) => 0; memcmp(buffer+4, "\0\0\0\0\0\0", 6) => 0; memcmp(buffer+10, "ccccc", 5) => 0; attrs1[1].size = 6; - lfs2_file_opencfg(&lfs2, &file[0], "hello/hello", LFS2_O_WRONLY, &cfg1) => 0; + lfs2_file_opencfg(&lfs2, &file, "hello/hello", LFS2_O_WRONLY, &cfg1) => 0; memcpy(buffer+4, "dddddd", 6); - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_close(&lfs2, &file) => 0; memset(buffer, 0, 15); attrs1[1].size = 6; - lfs2_file_opencfg(&lfs2, &file[0], "hello/hello", LFS2_O_RDONLY, &cfg1) => 0; - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_opencfg(&lfs2, &file, "hello/hello", LFS2_O_RDONLY, &cfg1) => 0; + lfs2_file_close(&lfs2, &file) => 0; memcmp(buffer, "aaaa", 4) => 0; memcmp(buffer+4, "dddddd", 6) => 0; memcmp(buffer+10, "ccccc", 5) => 0; attrs1[1].size = 3; - lfs2_file_opencfg(&lfs2, &file[0], "hello/hello", LFS2_O_WRONLY, &cfg1) => 0; + lfs2_file_opencfg(&lfs2, &file, "hello/hello", LFS2_O_WRONLY, &cfg1) => 0; memcpy(buffer+4, "eee", 3); - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_close(&lfs2, &file) => 0; memset(buffer, 0, 15); attrs1[1].size = 6; - lfs2_file_opencfg(&lfs2, &file[0], "hello/hello", LFS2_O_RDONLY, &cfg1) => 0; - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_opencfg(&lfs2, &file, "hello/hello", LFS2_O_RDONLY, &cfg1) => 0; + lfs2_file_close(&lfs2, &file) => 0; memcmp(buffer, "aaaa", 4) => 0; memcmp(buffer+4, "eee\0\0\0", 6) => 0; memcmp(buffer+10, "ccccc", 5) => 0; attrs1[0].size = LFS2_ATTR_MAX+1; - lfs2_file_opencfg(&lfs2, &file[0], "hello/hello", LFS2_O_WRONLY, &cfg1) + lfs2_file_opencfg(&lfs2, &file, "hello/hello", LFS2_O_WRONLY, &cfg1) => LFS2_ERR_NOSPC; struct lfs2_attr attrs2[] = { @@ -220,17 +227,18 @@ tests/test.py << TEST {'C', buffer+13, 5}, }; struct lfs2_file_config cfg2 = {.attrs=attrs2, .attr_count=3}; - lfs2_file_opencfg(&lfs2, &file[0], "hello/hello", LFS2_O_RDWR, &cfg2) => 0; + lfs2_file_opencfg(&lfs2, &file, "hello/hello", LFS2_O_RDWR, &cfg2) => 0; memcpy(buffer+4, "fffffffff", 9); - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_close(&lfs2, &file) => 0; attrs1[0].size = 4; - lfs2_file_opencfg(&lfs2, &file[0], "hello/hello", LFS2_O_RDONLY, &cfg1) => 0; - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_opencfg(&lfs2, &file, "hello/hello", LFS2_O_RDONLY, &cfg1) => 0; + lfs2_file_close(&lfs2, &file) => 0; lfs2_unmount(&lfs2) => 0; TEST -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; + memset(buffer, 0, sizeof(buffer)); struct lfs2_attr attrs2[] = { {'A', buffer, 4}, {'B', buffer+4, 9}, @@ -238,22 +246,23 @@ tests/test.py << TEST }; struct lfs2_file_config cfg2 = {.attrs=attrs2, .attr_count=3}; - lfs2_file_opencfg(&lfs2, &file[0], "hello/hello", LFS2_O_RDONLY, &cfg2) => 0; - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_opencfg(&lfs2, &file, "hello/hello", LFS2_O_RDONLY, &cfg2) => 0; + lfs2_file_close(&lfs2, &file) => 0; memcmp(buffer, "aaaa", 4) => 0; memcmp(buffer+4, "fffffffff", 9) => 0; memcmp(buffer+13, "ccccc", 5) => 0; - lfs2_file_open(&lfs2, &file[0], "hello/hello", LFS2_O_RDONLY) => 0; - lfs2_file_read(&lfs2, &file[0], buffer, sizeof(buffer)) => strlen("hello"); + lfs2_file_open(&lfs2, &file, "hello/hello", LFS2_O_RDONLY) => 0; + lfs2_file_read(&lfs2, &file, buffer, sizeof(buffer)) => strlen("hello"); memcmp(buffer, "hello", strlen("hello")) => 0; - lfs2_file_close(&lfs2, &file[0]); + lfs2_file_close(&lfs2, &file); lfs2_unmount(&lfs2) => 0; TEST echo "--- Deferred file attributes ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; + memset(buffer, 0, sizeof(buffer)); struct lfs2_attr attrs1[] = { {'B', "gggg", 4}, {'C', "", 0}, @@ -261,7 +270,7 @@ tests/test.py << TEST }; struct lfs2_file_config cfg1 = {.attrs=attrs1, .attr_count=3}; - lfs2_file_opencfg(&lfs2, &file[0], "hello/hello", LFS2_O_WRONLY, &cfg1) => 0; + lfs2_file_opencfg(&lfs2, &file, "hello/hello", LFS2_O_WRONLY, &cfg1) => 0; lfs2_getattr(&lfs2, "hello/hello", 'B', buffer, 9) => 9; lfs2_getattr(&lfs2, "hello/hello", 'C', buffer+9, 9) => 5; @@ -270,7 +279,7 @@ tests/test.py << TEST memcmp(buffer+9, "ccccc\0\0\0\0", 9) => 0; memcmp(buffer+18, "\0\0\0\0\0\0\0\0\0", 9) => 0; - lfs2_file_sync(&lfs2, &file[0]) => 0; + lfs2_file_sync(&lfs2, &file) => 0; lfs2_getattr(&lfs2, "hello/hello", 'B', buffer, 9) => 4; lfs2_getattr(&lfs2, "hello/hello", 'C', buffer+9, 9) => 0; lfs2_getattr(&lfs2, "hello/hello", 'D', buffer+18, 9) => 4; @@ -278,9 +287,8 @@ tests/test.py << TEST memcmp(buffer+9, "\0\0\0\0\0\0\0\0\0", 9) => 0; memcmp(buffer+18, "hhhh\0\0\0\0\0", 9) => 0; - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_close(&lfs2, &file) => 0; lfs2_unmount(&lfs2) => 0; TEST -echo "--- Results ---" -tests/stats.py +scripts/results.py diff --git a/tests/test_corrupt.sh b/tests/test_corrupt.sh index f2f823c..2a55232 100755 --- a/tests/test_corrupt.sh +++ b/tests/test_corrupt.sh @@ -1,5 +1,7 @@ #!/bin/bash set -eu +export TEST_FILE=$0 +trap 'export TEST_LINE=$LINENO' DEBUG echo "=== Corrupt tests ===" @@ -7,7 +9,7 @@ NAMEMULT=64 FILEMULT=1 lfs2_mktree() { -tests/test.py ${1:-} << TEST +scripts/test.py ${1:-} << TEST lfs2_format(&lfs2, &cfg) => 0; lfs2_mount(&lfs2, &cfg) => 0; @@ -23,22 +25,22 @@ tests/test.py ${1:-} << TEST buffer[j+$NAMEMULT+1] = '0'+i; } buffer[2*$NAMEMULT+1] = '\0'; - lfs2_file_open(&lfs2, &file[0], (char*)buffer, + lfs2_file_open(&lfs2, &file, (char*)buffer, LFS2_O_WRONLY | LFS2_O_CREAT) => 0; - size = $NAMEMULT; + lfs2_size_t size = $NAMEMULT; for (int j = 0; j < i*$FILEMULT; j++) { - lfs2_file_write(&lfs2, &file[0], buffer, size) => size; + lfs2_file_write(&lfs2, &file, buffer, size) => size; } - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_close(&lfs2, &file) => 0; } lfs2_unmount(&lfs2) => 0; TEST } lfs2_chktree() { -tests/test.py ${1:-} << TEST +scripts/test.py ${1:-} << TEST lfs2_mount(&lfs2, &cfg) => 0; for (int i = 1; i < 10; i++) { for (int j = 0; j < $NAMEMULT; j++) { @@ -53,15 +55,16 @@ tests/test.py ${1:-} << TEST buffer[j+$NAMEMULT+1] = '0'+i; } buffer[2*$NAMEMULT+1] = '\0'; - lfs2_file_open(&lfs2, &file[0], (char*)buffer, LFS2_O_RDONLY) => 0; + lfs2_file_open(&lfs2, &file, (char*)buffer, LFS2_O_RDONLY) => 0; - size = $NAMEMULT; + lfs2_size_t size = $NAMEMULT; for (int j = 0; j < i*$FILEMULT; j++) { - lfs2_file_read(&lfs2, &file[0], rbuffer, size) => size; + uint8_t rbuffer[1024]; + lfs2_file_read(&lfs2, &file, rbuffer, size) => size; memcmp(buffer, rbuffer, size) => 0; } - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_close(&lfs2, &file) => 0; } lfs2_unmount(&lfs2) => 0; TEST @@ -114,5 +117,4 @@ done lfs2_mktree lfs2_chktree -echo "--- Results ---" -tests/stats.py +scripts/results.py diff --git a/tests/test_dirs.sh b/tests/test_dirs.sh index c293b6c..6cec7de 100755 --- a/tests/test_dirs.sh +++ b/tests/test_dirs.sh @@ -1,188 +1,191 @@ #!/bin/bash set -eu +export TEST_FILE=$0 +trap 'export TEST_LINE=$LINENO' DEBUG + +echo "=== Directory tests ===" LARGESIZE=128 -echo "=== Directory tests ===" rm -rf blocks -tests/test.py << TEST +scripts/test.py << TEST lfs2_format(&lfs2, &cfg) => 0; TEST echo "--- Root directory ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; - lfs2_dir_open(&lfs2, &dir[0], "/") => 0; - lfs2_dir_close(&lfs2, &dir[0]) => 0; + lfs2_dir_open(&lfs2, &dir, "/") => 0; + lfs2_dir_close(&lfs2, &dir) => 0; lfs2_unmount(&lfs2) => 0; TEST echo "--- Directory creation ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; lfs2_mkdir(&lfs2, "potato") => 0; lfs2_unmount(&lfs2) => 0; TEST echo "--- File creation ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; - lfs2_file_open(&lfs2, &file[0], "burito", LFS2_O_CREAT | LFS2_O_WRONLY) => 0; - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_open(&lfs2, &file, "burito", LFS2_O_CREAT | LFS2_O_WRONLY) => 0; + lfs2_file_close(&lfs2, &file) => 0; lfs2_unmount(&lfs2) => 0; TEST echo "--- Directory iteration ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; - lfs2_dir_open(&lfs2, &dir[0], "/") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_open(&lfs2, &dir, "/") => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, ".") => 0; info.type => LFS2_TYPE_DIR; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "..") => 0; info.type => LFS2_TYPE_DIR; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "burito") => 0; info.type => LFS2_TYPE_REG; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "potato") => 0; info.type => LFS2_TYPE_DIR; - lfs2_dir_read(&lfs2, &dir[0], &info) => 0; - lfs2_dir_close(&lfs2, &dir[0]) => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 0; + lfs2_dir_close(&lfs2, &dir) => 0; lfs2_unmount(&lfs2) => 0; TEST echo "--- Directory failures ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; lfs2_mkdir(&lfs2, "potato") => LFS2_ERR_EXIST; - lfs2_dir_open(&lfs2, &dir[0], "tomato") => LFS2_ERR_NOENT; - lfs2_dir_open(&lfs2, &dir[0], "burito") => LFS2_ERR_NOTDIR; - lfs2_file_open(&lfs2, &file[0], "tomato", LFS2_O_RDONLY) => LFS2_ERR_NOENT; - lfs2_file_open(&lfs2, &file[0], "potato", LFS2_O_RDONLY) => LFS2_ERR_ISDIR; + lfs2_dir_open(&lfs2, &dir, "tomato") => LFS2_ERR_NOENT; + lfs2_dir_open(&lfs2, &dir, "burito") => LFS2_ERR_NOTDIR; + lfs2_file_open(&lfs2, &file, "tomato", LFS2_O_RDONLY) => LFS2_ERR_NOENT; + lfs2_file_open(&lfs2, &file, "potato", LFS2_O_RDONLY) => LFS2_ERR_ISDIR; lfs2_unmount(&lfs2) => 0; TEST echo "--- Nested directories ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; lfs2_mkdir(&lfs2, "potato/baked") => 0; lfs2_mkdir(&lfs2, "potato/sweet") => 0; lfs2_mkdir(&lfs2, "potato/fried") => 0; lfs2_unmount(&lfs2) => 0; TEST -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; - lfs2_dir_open(&lfs2, &dir[0], "potato") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_open(&lfs2, &dir, "potato") => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, ".") => 0; info.type => LFS2_TYPE_DIR; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "..") => 0; info.type => LFS2_TYPE_DIR; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "baked") => 0; info.type => LFS2_TYPE_DIR; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "fried") => 0; info.type => LFS2_TYPE_DIR; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "sweet") => 0; info.type => LFS2_TYPE_DIR; - lfs2_dir_read(&lfs2, &dir[0], &info) => 0; - lfs2_dir_close(&lfs2, &dir[0]) => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 0; + lfs2_dir_close(&lfs2, &dir) => 0; lfs2_unmount(&lfs2) => 0; TEST echo "--- Multi-block directory ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; lfs2_mkdir(&lfs2, "cactus") => 0; for (int i = 0; i < $LARGESIZE; i++) { - sprintf((char*)buffer, "cactus/test%03d", i); - lfs2_mkdir(&lfs2, (char*)buffer) => 0; + sprintf(path, "cactus/test%03d", i); + lfs2_mkdir(&lfs2, path) => 0; } lfs2_unmount(&lfs2) => 0; TEST -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; - lfs2_dir_open(&lfs2, &dir[0], "cactus") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_open(&lfs2, &dir, "cactus") => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, ".") => 0; info.type => LFS2_TYPE_DIR; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "..") => 0; info.type => LFS2_TYPE_DIR; for (int i = 0; i < $LARGESIZE; i++) { - sprintf((char*)buffer, "test%03d", i); - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; - strcmp(info.name, (char*)buffer) => 0; + sprintf(path, "test%03d", i); + lfs2_dir_read(&lfs2, &dir, &info) => 1; + strcmp(info.name, path) => 0; info.type => LFS2_TYPE_DIR; } - lfs2_dir_read(&lfs2, &dir[0], &info) => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 0; lfs2_unmount(&lfs2) => 0; TEST echo "--- Directory remove ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; lfs2_remove(&lfs2, "potato") => LFS2_ERR_NOTEMPTY; lfs2_remove(&lfs2, "potato/sweet") => 0; lfs2_remove(&lfs2, "potato/baked") => 0; lfs2_remove(&lfs2, "potato/fried") => 0; - lfs2_dir_open(&lfs2, &dir[0], "potato") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_open(&lfs2, &dir, "potato") => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, ".") => 0; info.type => LFS2_TYPE_DIR; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "..") => 0; info.type => LFS2_TYPE_DIR; - lfs2_dir_read(&lfs2, &dir[0], &info) => 0; - lfs2_dir_close(&lfs2, &dir[0]) => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 0; + lfs2_dir_close(&lfs2, &dir) => 0; lfs2_remove(&lfs2, "potato") => 0; - lfs2_dir_open(&lfs2, &dir[0], "/") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_open(&lfs2, &dir, "/") => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, ".") => 0; info.type => LFS2_TYPE_DIR; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "..") => 0; info.type => LFS2_TYPE_DIR; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "burito") => 0; info.type => LFS2_TYPE_REG; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "cactus") => 0; info.type => LFS2_TYPE_DIR; - lfs2_dir_read(&lfs2, &dir[0], &info) => 0; - lfs2_dir_close(&lfs2, &dir[0]) => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 0; + lfs2_dir_close(&lfs2, &dir) => 0; lfs2_unmount(&lfs2) => 0; TEST -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; - lfs2_dir_open(&lfs2, &dir[0], "/") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_open(&lfs2, &dir, "/") => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, ".") => 0; info.type => LFS2_TYPE_DIR; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "..") => 0; info.type => LFS2_TYPE_DIR; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "burito") => 0; info.type => LFS2_TYPE_REG; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "cactus") => 0; info.type => LFS2_TYPE_DIR; - lfs2_dir_read(&lfs2, &dir[0], &info) => 0; - lfs2_dir_close(&lfs2, &dir[0]) => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 0; + lfs2_dir_close(&lfs2, &dir) => 0; lfs2_unmount(&lfs2) => 0; TEST echo "--- Directory rename ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; lfs2_mkdir(&lfs2, "coldpotato") => 0; lfs2_mkdir(&lfs2, "coldpotato/baked") => 0; @@ -190,34 +193,34 @@ tests/test.py << TEST lfs2_mkdir(&lfs2, "coldpotato/fried") => 0; lfs2_unmount(&lfs2) => 0; TEST -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; lfs2_rename(&lfs2, "coldpotato", "hotpotato") => 0; lfs2_unmount(&lfs2) => 0; TEST -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; - lfs2_dir_open(&lfs2, &dir[0], "hotpotato") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_open(&lfs2, &dir, "hotpotato") => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, ".") => 0; info.type => LFS2_TYPE_DIR; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "..") => 0; info.type => LFS2_TYPE_DIR; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "baked") => 0; info.type => LFS2_TYPE_DIR; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "fried") => 0; info.type => LFS2_TYPE_DIR; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "sweet") => 0; info.type => LFS2_TYPE_DIR; - lfs2_dir_read(&lfs2, &dir[0], &info) => 0; - lfs2_dir_close(&lfs2, &dir[0]) => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 0; + lfs2_dir_close(&lfs2, &dir) => 0; lfs2_unmount(&lfs2) => 0; TEST -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; lfs2_mkdir(&lfs2, "warmpotato") => 0; lfs2_mkdir(&lfs2, "warmpotato/mushy") => 0; @@ -228,29 +231,29 @@ tests/test.py << TEST lfs2_unmount(&lfs2) => 0; TEST -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; - lfs2_dir_open(&lfs2, &dir[0], "warmpotato") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_open(&lfs2, &dir, "warmpotato") => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, ".") => 0; info.type => LFS2_TYPE_DIR; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "..") => 0; info.type => LFS2_TYPE_DIR; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "baked") => 0; info.type => LFS2_TYPE_DIR; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "fried") => 0; info.type => LFS2_TYPE_DIR; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "sweet") => 0; info.type => LFS2_TYPE_DIR; - lfs2_dir_read(&lfs2, &dir[0], &info) => 0; - lfs2_dir_close(&lfs2, &dir[0]) => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 0; + lfs2_dir_close(&lfs2, &dir) => 0; lfs2_unmount(&lfs2) => 0; TEST -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; lfs2_mkdir(&lfs2, "coldpotato") => 0; lfs2_rename(&lfs2, "warmpotato/baked", "coldpotato/baked") => 0; @@ -260,225 +263,227 @@ tests/test.py << TEST lfs2_remove(&lfs2, "warmpotato") => 0; lfs2_unmount(&lfs2) => 0; TEST -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; - lfs2_dir_open(&lfs2, &dir[0], "coldpotato") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_open(&lfs2, &dir, "coldpotato") => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, ".") => 0; info.type => LFS2_TYPE_DIR; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "..") => 0; info.type => LFS2_TYPE_DIR; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "baked") => 0; info.type => LFS2_TYPE_DIR; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "fried") => 0; info.type => LFS2_TYPE_DIR; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "sweet") => 0; info.type => LFS2_TYPE_DIR; - lfs2_dir_read(&lfs2, &dir[0], &info) => 0; - lfs2_dir_close(&lfs2, &dir[0]) => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 0; + lfs2_dir_close(&lfs2, &dir) => 0; lfs2_unmount(&lfs2) => 0; TEST echo "--- Recursive remove ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; lfs2_remove(&lfs2, "coldpotato") => LFS2_ERR_NOTEMPTY; - lfs2_dir_open(&lfs2, &dir[0], "coldpotato") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_open(&lfs2, &dir, "coldpotato") => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; while (true) { - int err = lfs2_dir_read(&lfs2, &dir[0], &info); + int err = lfs2_dir_read(&lfs2, &dir, &info); err >= 0 => 1; if (err == 0) { break; } - strcpy((char*)buffer, "coldpotato/"); - strcat((char*)buffer, info.name); - lfs2_remove(&lfs2, (char*)buffer) => 0; + strcpy(path, "coldpotato/"); + strcat(path, info.name); + lfs2_remove(&lfs2, path) => 0; } lfs2_remove(&lfs2, "coldpotato") => 0; TEST -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; - lfs2_dir_open(&lfs2, &dir[0], "/") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_open(&lfs2, &dir, "/") => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, ".") => 0; info.type => LFS2_TYPE_DIR; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "..") => 0; info.type => LFS2_TYPE_DIR; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "burito") => 0; info.type => LFS2_TYPE_REG; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "cactus") => 0; info.type => LFS2_TYPE_DIR; - lfs2_dir_read(&lfs2, &dir[0], &info) => 0; - lfs2_dir_close(&lfs2, &dir[0]) => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 0; + lfs2_dir_close(&lfs2, &dir) => 0; lfs2_unmount(&lfs2) => 0; TEST echo "--- Multi-block rename ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; for (int i = 0; i < $LARGESIZE; i++) { - sprintf((char*)buffer, "cactus/test%03d", i); - sprintf((char*)wbuffer, "cactus/tedd%03d", i); - lfs2_rename(&lfs2, (char*)buffer, (char*)wbuffer) => 0; + char oldpath[1024]; + char newpath[1024]; + sprintf(oldpath, "cactus/test%03d", i); + sprintf(newpath, "cactus/tedd%03d", i); + lfs2_rename(&lfs2, oldpath, newpath) => 0; } lfs2_unmount(&lfs2) => 0; TEST -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; - lfs2_dir_open(&lfs2, &dir[0], "cactus") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_open(&lfs2, &dir, "cactus") => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, ".") => 0; info.type => LFS2_TYPE_DIR; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "..") => 0; info.type => LFS2_TYPE_DIR; for (int i = 0; i < $LARGESIZE; i++) { - sprintf((char*)buffer, "tedd%03d", i); - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; - strcmp(info.name, (char*)buffer) => 0; + sprintf(path, "tedd%03d", i); + lfs2_dir_read(&lfs2, &dir, &info) => 1; + strcmp(info.name, path) => 0; info.type => LFS2_TYPE_DIR; } - lfs2_dir_read(&lfs2, &dir[0], &info) => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 0; lfs2_unmount(&lfs2) => 0; TEST echo "--- Multi-block remove ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; lfs2_remove(&lfs2, "cactus") => LFS2_ERR_NOTEMPTY; for (int i = 0; i < $LARGESIZE; i++) { - sprintf((char*)buffer, "cactus/tedd%03d", i); - lfs2_remove(&lfs2, (char*)buffer) => 0; + sprintf(path, "cactus/tedd%03d", i); + lfs2_remove(&lfs2, path) => 0; } lfs2_remove(&lfs2, "cactus") => 0; lfs2_unmount(&lfs2) => 0; TEST -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; - lfs2_dir_open(&lfs2, &dir[0], "/") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_open(&lfs2, &dir, "/") => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, ".") => 0; info.type => LFS2_TYPE_DIR; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "..") => 0; info.type => LFS2_TYPE_DIR; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "burito") => 0; info.type => LFS2_TYPE_REG; - lfs2_dir_read(&lfs2, &dir[0], &info) => 0; - lfs2_dir_close(&lfs2, &dir[0]) => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 0; + lfs2_dir_close(&lfs2, &dir) => 0; lfs2_unmount(&lfs2) => 0; TEST echo "--- Multi-block directory with files ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; lfs2_mkdir(&lfs2, "prickly-pear") => 0; for (int i = 0; i < $LARGESIZE; i++) { - sprintf((char*)buffer, "prickly-pear/test%03d", i); - lfs2_file_open(&lfs2, &file[0], (char*)buffer, - LFS2_O_WRONLY | LFS2_O_CREAT) => 0; - size = 6; - memcpy(wbuffer, "Hello", size); - lfs2_file_write(&lfs2, &file[0], wbuffer, size) => size; - lfs2_file_close(&lfs2, &file[0]) => 0; + sprintf(path, "prickly-pear/test%03d", i); + lfs2_file_open(&lfs2, &file, path, LFS2_O_WRONLY | LFS2_O_CREAT) => 0; + lfs2_size_t size = 6; + memcpy(buffer, "Hello", size); + lfs2_file_write(&lfs2, &file, buffer, size) => size; + lfs2_file_close(&lfs2, &file) => 0; } lfs2_unmount(&lfs2) => 0; TEST -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; - lfs2_dir_open(&lfs2, &dir[0], "prickly-pear") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_open(&lfs2, &dir, "prickly-pear") => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, ".") => 0; info.type => LFS2_TYPE_DIR; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "..") => 0; info.type => LFS2_TYPE_DIR; for (int i = 0; i < $LARGESIZE; i++) { - sprintf((char*)buffer, "test%03d", i); - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; - strcmp(info.name, (char*)buffer) => 0; + sprintf(path, "test%03d", i); + lfs2_dir_read(&lfs2, &dir, &info) => 1; + strcmp(info.name, path) => 0; info.type => LFS2_TYPE_REG; info.size => 6; } - lfs2_dir_read(&lfs2, &dir[0], &info) => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 0; lfs2_unmount(&lfs2) => 0; TEST echo "--- Multi-block rename with files ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; for (int i = 0; i < $LARGESIZE; i++) { - sprintf((char*)buffer, "prickly-pear/test%03d", i); - sprintf((char*)wbuffer, "prickly-pear/tedd%03d", i); - lfs2_rename(&lfs2, (char*)buffer, (char*)wbuffer) => 0; + char oldpath[1024]; + char newpath[1024]; + sprintf(oldpath, "prickly-pear/test%03d", i); + sprintf(newpath, "prickly-pear/tedd%03d", i); + lfs2_rename(&lfs2, oldpath, newpath) => 0; } lfs2_unmount(&lfs2) => 0; TEST -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; - lfs2_dir_open(&lfs2, &dir[0], "prickly-pear") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_open(&lfs2, &dir, "prickly-pear") => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, ".") => 0; info.type => LFS2_TYPE_DIR; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "..") => 0; info.type => LFS2_TYPE_DIR; for (int i = 0; i < $LARGESIZE; i++) { - sprintf((char*)buffer, "tedd%03d", i); - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; - strcmp(info.name, (char*)buffer) => 0; + sprintf(path, "tedd%03d", i); + lfs2_dir_read(&lfs2, &dir, &info) => 1; + strcmp(info.name, path) => 0; info.type => LFS2_TYPE_REG; info.size => 6; } - lfs2_dir_read(&lfs2, &dir[0], &info) => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 0; lfs2_unmount(&lfs2) => 0; TEST echo "--- Multi-block remove with files ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; lfs2_remove(&lfs2, "prickly-pear") => LFS2_ERR_NOTEMPTY; for (int i = 0; i < $LARGESIZE; i++) { - sprintf((char*)buffer, "prickly-pear/tedd%03d", i); - lfs2_remove(&lfs2, (char*)buffer) => 0; + sprintf(path, "prickly-pear/tedd%03d", i); + lfs2_remove(&lfs2, path) => 0; } lfs2_remove(&lfs2, "prickly-pear") => 0; lfs2_unmount(&lfs2) => 0; TEST -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; - lfs2_dir_open(&lfs2, &dir[0], "/") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_open(&lfs2, &dir, "/") => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, ".") => 0; info.type => LFS2_TYPE_DIR; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "..") => 0; info.type => LFS2_TYPE_DIR; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "burito") => 0; info.type => LFS2_TYPE_REG; - lfs2_dir_read(&lfs2, &dir[0], &info) => 0; - lfs2_dir_close(&lfs2, &dir[0]) => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 0; + lfs2_dir_close(&lfs2, &dir) => 0; lfs2_unmount(&lfs2) => 0; TEST -echo "--- Results ---" -tests/stats.py +scripts/results.py diff --git a/tests/test_entries.sh b/tests/test_entries.sh index d9616ba..b5ab7d7 100755 --- a/tests/test_entries.sh +++ b/tests/test_entries.sh @@ -1,19 +1,22 @@ #!/bin/bash set -eu +export TEST_FILE=$0 +trap 'export TEST_LINE=$LINENO' DEBUG + +echo "=== Entry tests ===" # Note: These tests are intended for 512 byte inline size at different # inline sizes they should still pass, but won't be testing anything -echo "=== Entry tests ===" rm -rf blocks function read_file { cat << TEST size = $2; - lfs2_file_open(&lfs2, &file[0], "$1", LFS2_O_RDONLY) => 0; - lfs2_file_read(&lfs2, &file[0], rbuffer, size) => size; + lfs2_file_open(&lfs2, &file, "$1", LFS2_O_RDONLY) => 0; + lfs2_file_read(&lfs2, &file, rbuffer, size) => size; memcmp(rbuffer, wbuffer, size) => 0; - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_close(&lfs2, &file) => 0; TEST } @@ -21,18 +24,22 @@ function write_file { cat << TEST size = $2; - lfs2_file_open(&lfs2, &file[0], "$1", + lfs2_file_open(&lfs2, &file, "$1", LFS2_O_WRONLY | LFS2_O_CREAT | LFS2_O_TRUNC) => 0; memset(wbuffer, 'c', size); - lfs2_file_write(&lfs2, &file[0], wbuffer, size) => size; - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_write(&lfs2, &file, wbuffer, size) => size; + lfs2_file_close(&lfs2, &file) => 0; TEST } echo "--- Entry grow test ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_format(&lfs2, &cfg) => 0; + uint8_t wbuffer[1024]; + uint8_t rbuffer[1024]; + lfs2_size_t size; + lfs2_mount(&lfs2, &cfg) => 0; $(write_file "hi0" 20) $(write_file "hi1" 20) @@ -50,9 +57,13 @@ tests/test.py << TEST TEST echo "--- Entry shrink test ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_format(&lfs2, &cfg) => 0; + uint8_t wbuffer[1024]; + uint8_t rbuffer[1024]; + lfs2_size_t size; + lfs2_mount(&lfs2, &cfg) => 0; $(write_file "hi0" 20) $(write_file "hi1" 200) @@ -70,9 +81,13 @@ tests/test.py << TEST TEST echo "--- Entry spill test ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_format(&lfs2, &cfg) => 0; + uint8_t wbuffer[1024]; + uint8_t rbuffer[1024]; + lfs2_size_t size; + lfs2_mount(&lfs2, &cfg) => 0; $(write_file "hi0" 200) $(write_file "hi1" 200) @@ -87,9 +102,13 @@ tests/test.py << TEST TEST echo "--- Entry push spill test ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_format(&lfs2, &cfg) => 0; + uint8_t wbuffer[1024]; + uint8_t rbuffer[1024]; + lfs2_size_t size; + lfs2_mount(&lfs2, &cfg) => 0; $(write_file "hi0" 200) $(write_file "hi1" 20) @@ -107,9 +126,13 @@ tests/test.py << TEST TEST echo "--- Entry push spill two test ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_format(&lfs2, &cfg) => 0; + uint8_t wbuffer[1024]; + uint8_t rbuffer[1024]; + lfs2_size_t size; + lfs2_mount(&lfs2, &cfg) => 0; $(write_file "hi0" 200) $(write_file "hi1" 20) @@ -129,9 +152,13 @@ tests/test.py << TEST TEST echo "--- Entry drop test ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_format(&lfs2, &cfg) => 0; + uint8_t wbuffer[1024]; + uint8_t rbuffer[1024]; + lfs2_size_t size; + lfs2_mount(&lfs2, &cfg) => 0; $(write_file "hi0" 200) $(write_file "hi1" 200) @@ -159,63 +186,66 @@ tests/test.py << TEST TEST echo "--- Create too big ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_format(&lfs2, &cfg) => 0; lfs2_mount(&lfs2, &cfg) => 0; - memset(buffer, 'm', 200); - buffer[200] = '\0'; + memset(path, 'm', 200); + path[200] = '\0'; - size = 400; - lfs2_file_open(&lfs2, &file[0], (char*)buffer, + lfs2_size_t size = 400; + lfs2_file_open(&lfs2, &file, path, LFS2_O_WRONLY | LFS2_O_CREAT | LFS2_O_TRUNC) => 0; + uint8_t wbuffer[1024]; memset(wbuffer, 'c', size); - lfs2_file_write(&lfs2, &file[0], wbuffer, size) => size; - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_write(&lfs2, &file, wbuffer, size) => size; + lfs2_file_close(&lfs2, &file) => 0; size = 400; - lfs2_file_open(&lfs2, &file[0], (char*)buffer, LFS2_O_RDONLY) => 0; - lfs2_file_read(&lfs2, &file[0], rbuffer, size) => size; + lfs2_file_open(&lfs2, &file, path, LFS2_O_RDONLY) => 0; + uint8_t rbuffer[1024]; + lfs2_file_read(&lfs2, &file, rbuffer, size) => size; memcmp(rbuffer, wbuffer, size) => 0; - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_close(&lfs2, &file) => 0; lfs2_unmount(&lfs2) => 0; TEST echo "--- Resize too big ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_format(&lfs2, &cfg) => 0; lfs2_mount(&lfs2, &cfg) => 0; - memset(buffer, 'm', 200); - buffer[200] = '\0'; + memset(path, 'm', 200); + path[200] = '\0'; + + lfs2_size_t size = 40; + lfs2_file_open(&lfs2, &file, path, + LFS2_O_WRONLY | LFS2_O_CREAT | LFS2_O_TRUNC) => 0; + uint8_t wbuffer[1024]; + memset(wbuffer, 'c', size); + lfs2_file_write(&lfs2, &file, wbuffer, size) => size; + lfs2_file_close(&lfs2, &file) => 0; size = 40; - lfs2_file_open(&lfs2, &file[0], (char*)buffer, - LFS2_O_WRONLY | LFS2_O_CREAT | LFS2_O_TRUNC) => 0; - memset(wbuffer, 'c', size); - lfs2_file_write(&lfs2, &file[0], wbuffer, size) => size; - lfs2_file_close(&lfs2, &file[0]) => 0; - - size = 40; - lfs2_file_open(&lfs2, &file[0], (char*)buffer, LFS2_O_RDONLY) => 0; - lfs2_file_read(&lfs2, &file[0], rbuffer, size) => size; + lfs2_file_open(&lfs2, &file, path, LFS2_O_RDONLY) => 0; + uint8_t rbuffer[1024]; + lfs2_file_read(&lfs2, &file, rbuffer, size) => size; memcmp(rbuffer, wbuffer, size) => 0; - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_close(&lfs2, &file) => 0; size = 400; - lfs2_file_open(&lfs2, &file[0], (char*)buffer, + lfs2_file_open(&lfs2, &file, path, LFS2_O_WRONLY | LFS2_O_CREAT | LFS2_O_TRUNC) => 0; memset(wbuffer, 'c', size); - lfs2_file_write(&lfs2, &file[0], wbuffer, size) => size; - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_write(&lfs2, &file, wbuffer, size) => size; + lfs2_file_close(&lfs2, &file) => 0; size = 400; - lfs2_file_open(&lfs2, &file[0], (char*)buffer, LFS2_O_RDONLY) => 0; - lfs2_file_read(&lfs2, &file[0], rbuffer, size) => size; + lfs2_file_open(&lfs2, &file, path, LFS2_O_RDONLY) => 0; + lfs2_file_read(&lfs2, &file, rbuffer, size) => size; memcmp(rbuffer, wbuffer, size) => 0; - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_close(&lfs2, &file) => 0; lfs2_unmount(&lfs2) => 0; TEST -echo "--- Results ---" -tests/stats.py +scripts/results.py diff --git a/tests/test_files.sh b/tests/test_files.sh index b042c3e..5059392 100755 --- a/tests/test_files.sh +++ b/tests/test_files.sh @@ -1,71 +1,76 @@ #!/bin/bash set -eu +export TEST_FILE=$0 +trap 'export TEST_LINE=$LINENO' DEBUG + +echo "=== File tests ===" SMALLSIZE=32 MEDIUMSIZE=8192 LARGESIZE=262144 -echo "=== File tests ===" rm -rf blocks -tests/test.py << TEST +scripts/test.py << TEST lfs2_format(&lfs2, &cfg) => 0; TEST echo "--- Simple file test ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; - lfs2_file_open(&lfs2, &file[0], "hello", LFS2_O_WRONLY | LFS2_O_CREAT) => 0; - size = strlen("Hello World!\n"); + lfs2_file_open(&lfs2, &file, "hello", LFS2_O_WRONLY | LFS2_O_CREAT) => 0; + lfs2_size_t size = strlen("Hello World!\n"); + uint8_t wbuffer[1024]; memcpy(wbuffer, "Hello World!\n", size); - lfs2_file_write(&lfs2, &file[0], wbuffer, size) => size; - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_write(&lfs2, &file, wbuffer, size) => size; + lfs2_file_close(&lfs2, &file) => 0; - lfs2_file_open(&lfs2, &file[0], "hello", LFS2_O_RDONLY) => 0; + lfs2_file_open(&lfs2, &file, "hello", LFS2_O_RDONLY) => 0; size = strlen("Hello World!\n"); - lfs2_file_read(&lfs2, &file[0], rbuffer, size) => size; + uint8_t rbuffer[1024]; + lfs2_file_read(&lfs2, &file, rbuffer, size) => size; memcmp(rbuffer, wbuffer, size) => 0; - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_close(&lfs2, &file) => 0; lfs2_unmount(&lfs2) => 0; TEST w_test() { -tests/test.py ${4:-} << TEST - size = $1; +scripts/test.py ${4:-} << TEST + lfs2_size_t size = $1; lfs2_size_t chunk = 31; srand(0); lfs2_mount(&lfs2, &cfg) => 0; - lfs2_file_open(&lfs2, &file[0], "$2", + lfs2_file_open(&lfs2, &file, "$2", ${3:-LFS2_O_WRONLY | LFS2_O_CREAT | LFS2_O_TRUNC}) => 0; for (lfs2_size_t i = 0; i < size; i += chunk) { chunk = (chunk < size - i) ? chunk : size - i; for (lfs2_size_t b = 0; b < chunk; b++) { buffer[b] = rand() & 0xff; } - lfs2_file_write(&lfs2, &file[0], buffer, chunk) => chunk; + lfs2_file_write(&lfs2, &file, buffer, chunk) => chunk; } - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_close(&lfs2, &file) => 0; lfs2_unmount(&lfs2) => 0; TEST } r_test() { -tests/test.py << TEST - size = $1; +scripts/test.py << TEST + lfs2_size_t size = $1; lfs2_size_t chunk = 29; srand(0); lfs2_mount(&lfs2, &cfg) => 0; lfs2_stat(&lfs2, "$2", &info) => 0; info.type => LFS2_TYPE_REG; info.size => size; - lfs2_file_open(&lfs2, &file[0], "$2", ${3:-LFS2_O_RDONLY}) => 0; + lfs2_file_open(&lfs2, &file, "$2", ${3:-LFS2_O_RDONLY}) => 0; for (lfs2_size_t i = 0; i < size; i += chunk) { chunk = (chunk < size - i) ? chunk : size - i; - lfs2_file_read(&lfs2, &file[0], buffer, chunk) => chunk; + lfs2_file_read(&lfs2, &file, buffer, chunk) => chunk; for (lfs2_size_t b = 0; b < chunk && i+b < size; b++) { buffer[b] => rand() & 0xff; } } - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_close(&lfs2, &file) => 0; lfs2_unmount(&lfs2) => 0; TEST } @@ -105,54 +110,112 @@ r_test $LARGESIZE largeavacado r_test 0 noavacado echo "--- Dir check ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; - lfs2_dir_open(&lfs2, &dir[0], "/") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_open(&lfs2, &dir, "/") => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "hello") => 0; info.type => LFS2_TYPE_REG; info.size => strlen("Hello World!\n"); - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "largeavacado") => 0; info.type => LFS2_TYPE_REG; info.size => $LARGESIZE; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "mediumavacado") => 0; info.type => LFS2_TYPE_REG; info.size => $MEDIUMSIZE; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "noavacado") => 0; info.type => LFS2_TYPE_REG; info.size => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "smallavacado") => 0; info.type => LFS2_TYPE_REG; info.size => $SMALLSIZE; - lfs2_dir_read(&lfs2, &dir[0], &info) => 0; - lfs2_dir_close(&lfs2, &dir[0]) => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 0; + lfs2_dir_close(&lfs2, &dir) => 0; lfs2_unmount(&lfs2) => 0; TEST -echo "--- Many file test ---" -tests/test.py << TEST +echo "--- Many files test ---" +scripts/test.py << TEST lfs2_format(&lfs2, &cfg) => 0; TEST -tests/test.py << TEST - // Create 300 files of 6 bytes +scripts/test.py << TEST + // Create 300 files of 7 bytes lfs2_mount(&lfs2, &cfg) => 0; - lfs2_mkdir(&lfs2, "directory") => 0; for (unsigned i = 0; i < 300; i++) { - snprintf((char*)buffer, sizeof(buffer), "file_%03d", i); - lfs2_file_open(&lfs2, &file[0], (char*)buffer, LFS2_O_WRONLY | LFS2_O_CREAT) => 0; - size = 6; - memcpy(wbuffer, "Hello", size); - lfs2_file_write(&lfs2, &file[0], wbuffer, size) => size; - lfs2_file_close(&lfs2, &file[0]) => 0; + sprintf(path, "file_%03d", i); + lfs2_file_open(&lfs2, &file, path, + LFS2_O_RDWR | LFS2_O_CREAT | LFS2_O_EXCL) => 0; + lfs2_size_t size = 7; + uint8_t wbuffer[1024]; + uint8_t rbuffer[1024]; + snprintf((char*)wbuffer, size, "Hi %03d", i); + lfs2_file_write(&lfs2, &file, wbuffer, size) => size; + lfs2_file_rewind(&lfs2, &file) => 0; + lfs2_file_read(&lfs2, &file, rbuffer, size) => size; + memcmp(wbuffer, rbuffer, size) => 0; + lfs2_file_close(&lfs2, &file) => 0; } lfs2_unmount(&lfs2) => 0; TEST -echo "--- Results ---" -tests/stats.py +echo "--- Many files with flush test ---" +scripts/test.py << TEST + lfs2_format(&lfs2, &cfg) => 0; +TEST +scripts/test.py << TEST + // Create 300 files of 7 bytes + lfs2_mount(&lfs2, &cfg) => 0; + for (unsigned i = 0; i < 300; i++) { + sprintf(path, "file_%03d", i); + lfs2_file_open(&lfs2, &file, path, + LFS2_O_WRONLY | LFS2_O_CREAT | LFS2_O_EXCL) => 0; + lfs2_size_t size = 7; + uint8_t wbuffer[1024]; + uint8_t rbuffer[1024]; + snprintf((char*)wbuffer, size, "Hi %03d", i); + lfs2_file_write(&lfs2, &file, wbuffer, size) => size; + lfs2_file_close(&lfs2, &file) => 0; + + lfs2_file_open(&lfs2, &file, path, LFS2_O_RDONLY) => 0; + lfs2_file_read(&lfs2, &file, rbuffer, size) => size; + memcmp(wbuffer, rbuffer, size) => 0; + lfs2_file_close(&lfs2, &file) => 0; + } + lfs2_unmount(&lfs2) => 0; +TEST + +echo "--- Many files with power cycle test ---" +scripts/test.py << TEST + lfs2_format(&lfs2, &cfg) => 0; +TEST +scripts/test.py << TEST + // Create 300 files of 7 bytes + lfs2_mount(&lfs2, &cfg) => 0; + for (unsigned i = 0; i < 300; i++) { + sprintf(path, "file_%03d", i); + lfs2_file_open(&lfs2, &file, path, + LFS2_O_WRONLY | LFS2_O_CREAT | LFS2_O_EXCL) => 0; + lfs2_size_t size = 7; + uint8_t wbuffer[1024]; + uint8_t rbuffer[1024]; + snprintf((char*)wbuffer, size, "Hi %03d", i); + lfs2_file_write(&lfs2, &file, wbuffer, size) => size; + lfs2_file_close(&lfs2, &file) => 0; + lfs2_unmount(&lfs2) => 0; + + lfs2_mount(&lfs2, &cfg) => 0; + lfs2_file_open(&lfs2, &file, path, LFS2_O_RDONLY) => 0; + lfs2_file_read(&lfs2, &file, rbuffer, size) => size; + memcmp(wbuffer, rbuffer, size) => 0; + lfs2_file_close(&lfs2, &file) => 0; + } + lfs2_unmount(&lfs2) => 0; +TEST + +scripts/results.py diff --git a/tests/test_format.sh b/tests/test_format.sh index cfb9d21..148702e 100755 --- a/tests/test_format.sh +++ b/tests/test_format.sh @@ -1,16 +1,18 @@ #!/bin/bash set -eu +export TEST_FILE=$0 +trap 'export TEST_LINE=$LINENO' DEBUG echo "=== Formatting tests ===" rm -rf blocks echo "--- Basic formatting ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_format(&lfs2, &cfg) => 0; TEST echo "--- Basic mounting ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_format(&lfs2, &cfg) => 0; lfs2_mount(&lfs2, &cfg) => 0; @@ -20,18 +22,18 @@ TEST echo "--- Invalid superblocks ---" ln -f -s /dev/zero blocks/0 ln -f -s /dev/zero blocks/1 -tests/test.py << TEST +scripts/test.py << TEST lfs2_format(&lfs2, &cfg) => LFS2_ERR_NOSPC; TEST rm blocks/0 blocks/1 echo "--- Invalid mount ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => LFS2_ERR_CORRUPT; TEST echo "--- Expanding superblock ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_format(&lfs2, &cfg) => 0; lfs2_mount(&lfs2, &cfg) => 0; for (int i = 0; i < 100; i++) { @@ -40,11 +42,10 @@ tests/test.py << TEST } lfs2_unmount(&lfs2) => 0; TEST -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; lfs2_mkdir(&lfs2, "dummy") => 0; lfs2_unmount(&lfs2) => 0; TEST -echo "--- Results ---" -tests/stats.py +scripts/results.py diff --git a/tests/test_interspersed.sh b/tests/test_interspersed.sh index c08c1a4..529a7da 100755 --- a/tests/test_interspersed.sh +++ b/tests/test_interspersed.sh @@ -1,89 +1,93 @@ #!/bin/bash set -eu +export TEST_FILE=$0 +trap 'export TEST_LINE=$LINENO' DEBUG echo "=== Interspersed tests ===" rm -rf blocks -tests/test.py << TEST +scripts/test.py << TEST lfs2_format(&lfs2, &cfg) => 0; TEST echo "--- Interspersed file test ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; - lfs2_file_open(&lfs2, &file[0], "a", LFS2_O_WRONLY | LFS2_O_CREAT) => 0; - lfs2_file_open(&lfs2, &file[1], "b", LFS2_O_WRONLY | LFS2_O_CREAT) => 0; - lfs2_file_open(&lfs2, &file[2], "c", LFS2_O_WRONLY | LFS2_O_CREAT) => 0; - lfs2_file_open(&lfs2, &file[3], "d", LFS2_O_WRONLY | LFS2_O_CREAT) => 0; + lfs2_file_t files[4]; + lfs2_file_open(&lfs2, &files[0], "a", LFS2_O_WRONLY | LFS2_O_CREAT) => 0; + lfs2_file_open(&lfs2, &files[1], "b", LFS2_O_WRONLY | LFS2_O_CREAT) => 0; + lfs2_file_open(&lfs2, &files[2], "c", LFS2_O_WRONLY | LFS2_O_CREAT) => 0; + lfs2_file_open(&lfs2, &files[3], "d", LFS2_O_WRONLY | LFS2_O_CREAT) => 0; for (int i = 0; i < 10; i++) { - lfs2_file_write(&lfs2, &file[0], (const void*)"a", 1) => 1; - lfs2_file_write(&lfs2, &file[1], (const void*)"b", 1) => 1; - lfs2_file_write(&lfs2, &file[2], (const void*)"c", 1) => 1; - lfs2_file_write(&lfs2, &file[3], (const void*)"d", 1) => 1; + lfs2_file_write(&lfs2, &files[0], (const void*)"a", 1) => 1; + lfs2_file_write(&lfs2, &files[1], (const void*)"b", 1) => 1; + lfs2_file_write(&lfs2, &files[2], (const void*)"c", 1) => 1; + lfs2_file_write(&lfs2, &files[3], (const void*)"d", 1) => 1; } - lfs2_file_close(&lfs2, &file[0]); - lfs2_file_close(&lfs2, &file[1]); - lfs2_file_close(&lfs2, &file[2]); - lfs2_file_close(&lfs2, &file[3]); + lfs2_file_close(&lfs2, &files[0]); + lfs2_file_close(&lfs2, &files[1]); + lfs2_file_close(&lfs2, &files[2]); + lfs2_file_close(&lfs2, &files[3]); - lfs2_dir_open(&lfs2, &dir[0], "/") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_open(&lfs2, &dir, "/") => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, ".") => 0; info.type => LFS2_TYPE_DIR; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "..") => 0; info.type => LFS2_TYPE_DIR; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "a") => 0; info.type => LFS2_TYPE_REG; info.size => 10; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "b") => 0; info.type => LFS2_TYPE_REG; info.size => 10; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "c") => 0; info.type => LFS2_TYPE_REG; info.size => 10; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "d") => 0; info.type => LFS2_TYPE_REG; info.size => 10; - lfs2_dir_read(&lfs2, &dir[0], &info) => 0; - lfs2_dir_close(&lfs2, &dir[0]) => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 0; + lfs2_dir_close(&lfs2, &dir) => 0; - lfs2_file_open(&lfs2, &file[0], "a", LFS2_O_RDONLY) => 0; - lfs2_file_open(&lfs2, &file[1], "b", LFS2_O_RDONLY) => 0; - lfs2_file_open(&lfs2, &file[2], "c", LFS2_O_RDONLY) => 0; - lfs2_file_open(&lfs2, &file[3], "d", LFS2_O_RDONLY) => 0; + lfs2_file_open(&lfs2, &files[0], "a", LFS2_O_RDONLY) => 0; + lfs2_file_open(&lfs2, &files[1], "b", LFS2_O_RDONLY) => 0; + lfs2_file_open(&lfs2, &files[2], "c", LFS2_O_RDONLY) => 0; + lfs2_file_open(&lfs2, &files[3], "d", LFS2_O_RDONLY) => 0; for (int i = 0; i < 10; i++) { - lfs2_file_read(&lfs2, &file[0], buffer, 1) => 1; + lfs2_file_read(&lfs2, &files[0], buffer, 1) => 1; buffer[0] => 'a'; - lfs2_file_read(&lfs2, &file[1], buffer, 1) => 1; + lfs2_file_read(&lfs2, &files[1], buffer, 1) => 1; buffer[0] => 'b'; - lfs2_file_read(&lfs2, &file[2], buffer, 1) => 1; + lfs2_file_read(&lfs2, &files[2], buffer, 1) => 1; buffer[0] => 'c'; - lfs2_file_read(&lfs2, &file[3], buffer, 1) => 1; + lfs2_file_read(&lfs2, &files[3], buffer, 1) => 1; buffer[0] => 'd'; } - lfs2_file_close(&lfs2, &file[0]); - lfs2_file_close(&lfs2, &file[1]); - lfs2_file_close(&lfs2, &file[2]); - lfs2_file_close(&lfs2, &file[3]); + lfs2_file_close(&lfs2, &files[0]); + lfs2_file_close(&lfs2, &files[1]); + lfs2_file_close(&lfs2, &files[2]); + lfs2_file_close(&lfs2, &files[3]); lfs2_unmount(&lfs2) => 0; TEST echo "--- Interspersed remove file test ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; - lfs2_file_open(&lfs2, &file[0], "e", LFS2_O_WRONLY | LFS2_O_CREAT) => 0; + lfs2_file_t files[4]; + lfs2_file_open(&lfs2, &files[0], "e", LFS2_O_WRONLY | LFS2_O_CREAT) => 0; for (int i = 0; i < 5; i++) { - lfs2_file_write(&lfs2, &file[0], (const void*)"e", 1) => 1; + lfs2_file_write(&lfs2, &files[0], (const void*)"e", 1) => 1; } lfs2_remove(&lfs2, "a") => 0; @@ -92,95 +96,95 @@ tests/test.py << TEST lfs2_remove(&lfs2, "d") => 0; for (int i = 0; i < 5; i++) { - lfs2_file_write(&lfs2, &file[0], (const void*)"e", 1) => 1; + lfs2_file_write(&lfs2, &files[0], (const void*)"e", 1) => 1; } - lfs2_file_close(&lfs2, &file[0]); + lfs2_file_close(&lfs2, &files[0]); - lfs2_dir_open(&lfs2, &dir[0], "/") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_open(&lfs2, &dir, "/") => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, ".") => 0; info.type => LFS2_TYPE_DIR; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "..") => 0; info.type => LFS2_TYPE_DIR; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "e") => 0; info.type => LFS2_TYPE_REG; info.size => 10; - lfs2_dir_read(&lfs2, &dir[0], &info) => 0; - lfs2_dir_close(&lfs2, &dir[0]) => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 0; + lfs2_dir_close(&lfs2, &dir) => 0; - lfs2_file_open(&lfs2, &file[0], "e", LFS2_O_RDONLY) => 0; + lfs2_file_open(&lfs2, &files[0], "e", LFS2_O_RDONLY) => 0; for (int i = 0; i < 10; i++) { - lfs2_file_read(&lfs2, &file[0], buffer, 1) => 1; + lfs2_file_read(&lfs2, &files[0], buffer, 1) => 1; buffer[0] => 'e'; } - lfs2_file_close(&lfs2, &file[0]); + lfs2_file_close(&lfs2, &files[0]); lfs2_unmount(&lfs2) => 0; TEST echo "--- Remove inconveniently test ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; - lfs2_file_open(&lfs2, &file[0], "e", LFS2_O_WRONLY | LFS2_O_TRUNC) => 0; - lfs2_file_open(&lfs2, &file[1], "f", LFS2_O_WRONLY | LFS2_O_CREAT) => 0; - lfs2_file_open(&lfs2, &file[2], "g", LFS2_O_WRONLY | LFS2_O_CREAT) => 0; + lfs2_file_t files[4]; + lfs2_file_open(&lfs2, &files[0], "e", LFS2_O_WRONLY | LFS2_O_TRUNC) => 0; + lfs2_file_open(&lfs2, &files[1], "f", LFS2_O_WRONLY | LFS2_O_CREAT) => 0; + lfs2_file_open(&lfs2, &files[2], "g", LFS2_O_WRONLY | LFS2_O_CREAT) => 0; for (int i = 0; i < 5; i++) { - lfs2_file_write(&lfs2, &file[0], (const void*)"e", 1) => 1; - lfs2_file_write(&lfs2, &file[1], (const void*)"f", 1) => 1; - lfs2_file_write(&lfs2, &file[2], (const void*)"g", 1) => 1; + lfs2_file_write(&lfs2, &files[0], (const void*)"e", 1) => 1; + lfs2_file_write(&lfs2, &files[1], (const void*)"f", 1) => 1; + lfs2_file_write(&lfs2, &files[2], (const void*)"g", 1) => 1; } lfs2_remove(&lfs2, "f") => 0; for (int i = 0; i < 5; i++) { - lfs2_file_write(&lfs2, &file[0], (const void*)"e", 1) => 1; - lfs2_file_write(&lfs2, &file[1], (const void*)"f", 1) => 1; - lfs2_file_write(&lfs2, &file[2], (const void*)"g", 1) => 1; + lfs2_file_write(&lfs2, &files[0], (const void*)"e", 1) => 1; + lfs2_file_write(&lfs2, &files[1], (const void*)"f", 1) => 1; + lfs2_file_write(&lfs2, &files[2], (const void*)"g", 1) => 1; } - lfs2_file_close(&lfs2, &file[0]); - lfs2_file_close(&lfs2, &file[1]); - lfs2_file_close(&lfs2, &file[2]); + lfs2_file_close(&lfs2, &files[0]); + lfs2_file_close(&lfs2, &files[1]); + lfs2_file_close(&lfs2, &files[2]); - lfs2_dir_open(&lfs2, &dir[0], "/") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_open(&lfs2, &dir, "/") => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, ".") => 0; info.type => LFS2_TYPE_DIR; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "..") => 0; info.type => LFS2_TYPE_DIR; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "e") => 0; info.type => LFS2_TYPE_REG; info.size => 10; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "g") => 0; info.type => LFS2_TYPE_REG; info.size => 10; - lfs2_dir_read(&lfs2, &dir[0], &info) => 0; - lfs2_dir_close(&lfs2, &dir[0]) => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 0; + lfs2_dir_close(&lfs2, &dir) => 0; - lfs2_file_open(&lfs2, &file[0], "e", LFS2_O_RDONLY) => 0; - lfs2_file_open(&lfs2, &file[1], "g", LFS2_O_RDONLY) => 0; + lfs2_file_open(&lfs2, &files[0], "e", LFS2_O_RDONLY) => 0; + lfs2_file_open(&lfs2, &files[1], "g", LFS2_O_RDONLY) => 0; for (int i = 0; i < 10; i++) { - lfs2_file_read(&lfs2, &file[0], buffer, 1) => 1; + lfs2_file_read(&lfs2, &files[0], buffer, 1) => 1; buffer[0] => 'e'; - lfs2_file_read(&lfs2, &file[1], buffer, 1) => 1; + lfs2_file_read(&lfs2, &files[1], buffer, 1) => 1; buffer[0] => 'g'; } - lfs2_file_close(&lfs2, &file[0]); - lfs2_file_close(&lfs2, &file[1]); + lfs2_file_close(&lfs2, &files[0]); + lfs2_file_close(&lfs2, &files[1]); lfs2_unmount(&lfs2) => 0; TEST -echo "--- Results ---" -tests/stats.py +scripts/results.py diff --git a/tests/test_move.sh b/tests/test_move.sh index 9017dff..53def6c 100755 --- a/tests/test_move.sh +++ b/tests/test_move.sh @@ -1,9 +1,11 @@ #!/bin/bash set -eu +export TEST_FILE=$0 +trap 'export TEST_LINE=$LINENO' DEBUG echo "=== Move tests ===" rm -rf blocks -tests/test.py << TEST +scripts/test.py << TEST lfs2_format(&lfs2, &cfg) => 0; lfs2_mount(&lfs2, &cfg) => 0; @@ -17,272 +19,272 @@ tests/test.py << TEST lfs2_mkdir(&lfs2, "a/hi/bonjour") => 0; lfs2_mkdir(&lfs2, "a/hi/ohayo") => 0; - lfs2_file_open(&lfs2, &file[0], "a/hello", LFS2_O_CREAT | LFS2_O_WRONLY) => 0; - lfs2_file_write(&lfs2, &file[0], "hola\n", 5) => 5; - lfs2_file_write(&lfs2, &file[0], "bonjour\n", 8) => 8; - lfs2_file_write(&lfs2, &file[0], "ohayo\n", 6) => 6; - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_open(&lfs2, &file, "a/hello", LFS2_O_CREAT | LFS2_O_WRONLY) => 0; + lfs2_file_write(&lfs2, &file, "hola\n", 5) => 5; + lfs2_file_write(&lfs2, &file, "bonjour\n", 8) => 8; + lfs2_file_write(&lfs2, &file, "ohayo\n", 6) => 6; + lfs2_file_close(&lfs2, &file) => 0; lfs2_unmount(&lfs2) => 0; TEST echo "--- Move file ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; lfs2_rename(&lfs2, "a/hello", "b/hello") => 0; lfs2_unmount(&lfs2) => 0; TEST -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; - lfs2_dir_open(&lfs2, &dir[0], "a") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_open(&lfs2, &dir, "a") => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, ".") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "..") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "hi") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 0; - lfs2_dir_close(&lfs2, &dir[0]) => 0; - lfs2_dir_open(&lfs2, &dir[0], "b") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 0; + lfs2_dir_close(&lfs2, &dir) => 0; + lfs2_dir_open(&lfs2, &dir, "b") => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, ".") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "..") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "hello") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 0; lfs2_unmount(&lfs2) => 0; TEST echo "--- Move file corrupt source ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; lfs2_rename(&lfs2, "b/hello", "c/hello") => 0; lfs2_unmount(&lfs2) => 0; TEST -tests/corrupt.py -n 1 -tests/test.py << TEST +scripts/corrupt.py -n 1 +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; - lfs2_dir_open(&lfs2, &dir[0], "b") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_open(&lfs2, &dir, "b") => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, ".") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "..") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 0; - lfs2_dir_close(&lfs2, &dir[0]) => 0; - lfs2_dir_open(&lfs2, &dir[0], "c") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 0; + lfs2_dir_close(&lfs2, &dir) => 0; + lfs2_dir_open(&lfs2, &dir, "c") => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, ".") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "..") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "hello") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 0; lfs2_unmount(&lfs2) => 0; TEST echo "--- Move file corrupt source and dest ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; lfs2_rename(&lfs2, "c/hello", "d/hello") => 0; lfs2_unmount(&lfs2) => 0; TEST -tests/corrupt.py -n 2 -tests/test.py << TEST +scripts/corrupt.py -n 2 +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; - lfs2_dir_open(&lfs2, &dir[0], "c") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_open(&lfs2, &dir, "c") => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, ".") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "..") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "hello") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 0; - lfs2_dir_close(&lfs2, &dir[0]) => 0; - lfs2_dir_open(&lfs2, &dir[0], "d") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 0; + lfs2_dir_close(&lfs2, &dir) => 0; + lfs2_dir_open(&lfs2, &dir, "d") => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, ".") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "..") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 0; lfs2_unmount(&lfs2) => 0; TEST echo "--- Move file after corrupt ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; lfs2_rename(&lfs2, "c/hello", "d/hello") => 0; lfs2_unmount(&lfs2) => 0; TEST -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; - lfs2_dir_open(&lfs2, &dir[0], "c") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_open(&lfs2, &dir, "c") => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, ".") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "..") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 0; - lfs2_dir_close(&lfs2, &dir[0]) => 0; - lfs2_dir_open(&lfs2, &dir[0], "d") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 0; + lfs2_dir_close(&lfs2, &dir) => 0; + lfs2_dir_open(&lfs2, &dir, "d") => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, ".") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "..") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "hello") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 0; lfs2_unmount(&lfs2) => 0; TEST echo "--- Move dir ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; lfs2_rename(&lfs2, "a/hi", "b/hi") => 0; lfs2_unmount(&lfs2) => 0; TEST -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; - lfs2_dir_open(&lfs2, &dir[0], "a") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_open(&lfs2, &dir, "a") => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, ".") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "..") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 0; - lfs2_dir_close(&lfs2, &dir[0]) => 0; - lfs2_dir_open(&lfs2, &dir[0], "b") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 0; + lfs2_dir_close(&lfs2, &dir) => 0; + lfs2_dir_open(&lfs2, &dir, "b") => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, ".") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "..") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "hi") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 0; lfs2_unmount(&lfs2) => 0; TEST echo "--- Move dir corrupt source ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; lfs2_rename(&lfs2, "b/hi", "c/hi") => 0; lfs2_unmount(&lfs2) => 0; TEST -tests/corrupt.py -n 1 -tests/test.py << TEST +scripts/corrupt.py -n 1 +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; - lfs2_dir_open(&lfs2, &dir[0], "b") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_open(&lfs2, &dir, "b") => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, ".") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "..") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 0; - lfs2_dir_close(&lfs2, &dir[0]) => 0; - lfs2_dir_open(&lfs2, &dir[0], "c") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 0; + lfs2_dir_close(&lfs2, &dir) => 0; + lfs2_dir_open(&lfs2, &dir, "c") => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, ".") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "..") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "hi") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 0; lfs2_unmount(&lfs2) => 0; TEST echo "--- Move dir corrupt source and dest ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; lfs2_rename(&lfs2, "c/hi", "d/hi") => 0; lfs2_unmount(&lfs2) => 0; TEST -tests/corrupt.py -n 2 -tests/test.py << TEST +scripts/corrupt.py -n 2 +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; - lfs2_dir_open(&lfs2, &dir[0], "c") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_open(&lfs2, &dir, "c") => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, ".") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "..") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "hi") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 0; - lfs2_dir_close(&lfs2, &dir[0]) => 0; - lfs2_dir_open(&lfs2, &dir[0], "d") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 0; + lfs2_dir_close(&lfs2, &dir) => 0; + lfs2_dir_open(&lfs2, &dir, "d") => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, ".") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "..") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "hello") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 0; lfs2_unmount(&lfs2) => 0; TEST echo "--- Move dir after corrupt ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; lfs2_rename(&lfs2, "c/hi", "d/hi") => 0; lfs2_unmount(&lfs2) => 0; TEST -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; - lfs2_dir_open(&lfs2, &dir[0], "c") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_open(&lfs2, &dir, "c") => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, ".") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "..") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 0; - lfs2_dir_close(&lfs2, &dir[0]) => 0; - lfs2_dir_open(&lfs2, &dir[0], "d") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 0; + lfs2_dir_close(&lfs2, &dir) => 0; + lfs2_dir_open(&lfs2, &dir, "d") => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, ".") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "..") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "hello") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "hi") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 0; lfs2_unmount(&lfs2) => 0; TEST echo "--- Move check ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; - lfs2_dir_open(&lfs2, &dir[0], "a/hi") => LFS2_ERR_NOENT; - lfs2_dir_open(&lfs2, &dir[0], "b/hi") => LFS2_ERR_NOENT; - lfs2_dir_open(&lfs2, &dir[0], "c/hi") => LFS2_ERR_NOENT; + lfs2_dir_open(&lfs2, &dir, "a/hi") => LFS2_ERR_NOENT; + lfs2_dir_open(&lfs2, &dir, "b/hi") => LFS2_ERR_NOENT; + lfs2_dir_open(&lfs2, &dir, "c/hi") => LFS2_ERR_NOENT; - lfs2_dir_open(&lfs2, &dir[0], "d/hi") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_open(&lfs2, &dir, "d/hi") => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, ".") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "..") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "bonjour") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "hola") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "ohayo") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 0; - lfs2_dir_close(&lfs2, &dir[0]) => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 0; + lfs2_dir_close(&lfs2, &dir) => 0; - lfs2_dir_open(&lfs2, &dir[0], "a/hello") => LFS2_ERR_NOENT; - lfs2_dir_open(&lfs2, &dir[0], "b/hello") => LFS2_ERR_NOENT; - lfs2_dir_open(&lfs2, &dir[0], "c/hello") => LFS2_ERR_NOENT; + lfs2_dir_open(&lfs2, &dir, "a/hello") => LFS2_ERR_NOENT; + lfs2_dir_open(&lfs2, &dir, "b/hello") => LFS2_ERR_NOENT; + lfs2_dir_open(&lfs2, &dir, "c/hello") => LFS2_ERR_NOENT; - lfs2_file_open(&lfs2, &file[0], "d/hello", LFS2_O_RDONLY) => 0; - lfs2_file_read(&lfs2, &file[0], buffer, 5) => 5; + lfs2_file_open(&lfs2, &file, "d/hello", LFS2_O_RDONLY) => 0; + lfs2_file_read(&lfs2, &file, buffer, 5) => 5; memcmp(buffer, "hola\n", 5) => 0; - lfs2_file_read(&lfs2, &file[0], buffer, 8) => 8; + lfs2_file_read(&lfs2, &file, buffer, 8) => 8; memcmp(buffer, "bonjour\n", 8) => 0; - lfs2_file_read(&lfs2, &file[0], buffer, 6) => 6; + lfs2_file_read(&lfs2, &file, buffer, 6) => 6; memcmp(buffer, "ohayo\n", 6) => 0; - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_close(&lfs2, &file) => 0; lfs2_unmount(&lfs2) => 0; TEST echo "--- Move state stealing ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; lfs2_remove(&lfs2, "b") => 0; @@ -290,43 +292,42 @@ tests/test.py << TEST lfs2_unmount(&lfs2) => 0; TEST -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; - lfs2_dir_open(&lfs2, &dir[0], "a/hi") => LFS2_ERR_NOENT; - lfs2_dir_open(&lfs2, &dir[0], "b") => LFS2_ERR_NOENT; - lfs2_dir_open(&lfs2, &dir[0], "c") => LFS2_ERR_NOENT; + lfs2_dir_open(&lfs2, &dir, "a/hi") => LFS2_ERR_NOENT; + lfs2_dir_open(&lfs2, &dir, "b") => LFS2_ERR_NOENT; + lfs2_dir_open(&lfs2, &dir, "c") => LFS2_ERR_NOENT; - lfs2_dir_open(&lfs2, &dir[0], "d/hi") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_open(&lfs2, &dir, "d/hi") => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, ".") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "..") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "bonjour") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "hola") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "ohayo") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 0; - lfs2_dir_close(&lfs2, &dir[0]) => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 0; + lfs2_dir_close(&lfs2, &dir) => 0; - lfs2_dir_open(&lfs2, &dir[0], "a/hello") => LFS2_ERR_NOENT; - lfs2_dir_open(&lfs2, &dir[0], "b") => LFS2_ERR_NOENT; - lfs2_dir_open(&lfs2, &dir[0], "c") => LFS2_ERR_NOENT; + lfs2_dir_open(&lfs2, &dir, "a/hello") => LFS2_ERR_NOENT; + lfs2_dir_open(&lfs2, &dir, "b") => LFS2_ERR_NOENT; + lfs2_dir_open(&lfs2, &dir, "c") => LFS2_ERR_NOENT; - lfs2_file_open(&lfs2, &file[0], "d/hello", LFS2_O_RDONLY) => 0; - lfs2_file_read(&lfs2, &file[0], buffer, 5) => 5; + lfs2_file_open(&lfs2, &file, "d/hello", LFS2_O_RDONLY) => 0; + lfs2_file_read(&lfs2, &file, buffer, 5) => 5; memcmp(buffer, "hola\n", 5) => 0; - lfs2_file_read(&lfs2, &file[0], buffer, 8) => 8; + lfs2_file_read(&lfs2, &file, buffer, 8) => 8; memcmp(buffer, "bonjour\n", 8) => 0; - lfs2_file_read(&lfs2, &file[0], buffer, 6) => 6; + lfs2_file_read(&lfs2, &file, buffer, 6) => 6; memcmp(buffer, "ohayo\n", 6) => 0; - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_close(&lfs2, &file) => 0; lfs2_unmount(&lfs2) => 0; TEST -echo "--- Results ---" -tests/stats.py +scripts/results.py diff --git a/tests/test_orphan.sh b/tests/test_orphan.sh index 8c5b1f6..8322c51 100755 --- a/tests/test_orphan.sh +++ b/tests/test_orphan.sh @@ -1,14 +1,16 @@ #!/bin/bash set -eu +export TEST_FILE=$0 +trap 'export TEST_LINE=$LINENO' DEBUG echo "=== Orphan tests ===" rm -rf blocks -tests/test.py << TEST +scripts/test.py << TEST lfs2_format(&lfs2, &cfg) => 0; TEST echo "--- Orphan test ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; lfs2_mkdir(&lfs2, "parent") => 0; lfs2_mkdir(&lfs2, "parent/orphan") => 0; @@ -17,8 +19,8 @@ tests/test.py << TEST TEST # corrupt most recent commit, this should be the update to the previous # linked-list entry and should orphan the child -tests/corrupt.py -tests/test.py << TEST +scripts/corrupt.py +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; lfs2_stat(&lfs2, "parent/orphan", &info) => LFS2_ERR_NOENT; @@ -41,5 +43,4 @@ tests/test.py << TEST lfs2_unmount(&lfs2) => 0; TEST -echo "--- Results ---" -tests/stats.py +scripts/results.py diff --git a/tests/test_paths.sh b/tests/test_paths.sh index c73baad..f05f79f 100755 --- a/tests/test_paths.sh +++ b/tests/test_paths.sh @@ -1,13 +1,15 @@ #!/bin/bash set -eu +export TEST_FILE=$0 +trap 'export TEST_LINE=$LINENO' DEBUG echo "=== Path tests ===" rm -rf blocks -tests/test.py << TEST +scripts/test.py << TEST lfs2_format(&lfs2, &cfg) => 0; TEST -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; lfs2_mkdir(&lfs2, "tea") => 0; lfs2_mkdir(&lfs2, "coffee") => 0; @@ -25,7 +27,7 @@ tests/test.py << TEST TEST echo "--- Root path tests ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; lfs2_stat(&lfs2, "tea/hottea", &info) => 0; strcmp(info.name, "hottea") => 0; @@ -39,7 +41,7 @@ tests/test.py << TEST TEST echo "--- Redundant slash path tests ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; lfs2_stat(&lfs2, "/tea/hottea", &info) => 0; strcmp(info.name, "hottea") => 0; @@ -55,7 +57,7 @@ tests/test.py << TEST TEST echo "--- Dot path tests ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; lfs2_stat(&lfs2, "./tea/hottea", &info) => 0; strcmp(info.name, "hottea") => 0; @@ -73,7 +75,7 @@ tests/test.py << TEST TEST echo "--- Dot dot path tests ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; lfs2_stat(&lfs2, "coffee/../tea/hottea", &info) => 0; strcmp(info.name, "hottea") => 0; @@ -91,7 +93,7 @@ tests/test.py << TEST TEST echo "--- Trailing dot path tests ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; lfs2_stat(&lfs2, "tea/hottea/", &info) => 0; strcmp(info.name, "hottea") => 0; @@ -107,7 +109,7 @@ tests/test.py << TEST TEST echo "--- Root dot dot path tests ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; lfs2_stat(&lfs2, "coffee/../../../../../../tea/hottea", &info) => 0; strcmp(info.name, "hottea") => 0; @@ -119,14 +121,14 @@ tests/test.py << TEST TEST echo "--- Root tests ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; lfs2_stat(&lfs2, "/", &info) => 0; info.type => LFS2_TYPE_DIR; strcmp(info.name, "/") => 0; lfs2_mkdir(&lfs2, "/") => LFS2_ERR_EXIST; - lfs2_file_open(&lfs2, &file[0], "/", LFS2_O_WRONLY | LFS2_O_CREAT) + lfs2_file_open(&lfs2, &file, "/", LFS2_O_WRONLY | LFS2_O_CREAT) => LFS2_ERR_ISDIR; // more corner cases @@ -140,7 +142,7 @@ tests/test.py << TEST TEST echo "--- Sketchy path tests ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; lfs2_mkdir(&lfs2, "dirt/ground") => LFS2_ERR_NOENT; lfs2_mkdir(&lfs2, "dirt/ground/earth") => LFS2_ERR_NOENT; @@ -148,7 +150,7 @@ tests/test.py << TEST TEST echo "--- Superblock conflict test ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; lfs2_mkdir(&lfs2, "littlefs") => 0; lfs2_remove(&lfs2, "littlefs") => 0; @@ -156,46 +158,45 @@ tests/test.py << TEST TEST echo "--- Max path test ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; - memset(buffer, 'w', LFS2_NAME_MAX+1); - buffer[LFS2_NAME_MAX+2] = '\0'; - lfs2_mkdir(&lfs2, (char*)buffer) => LFS2_ERR_NAMETOOLONG; - lfs2_file_open(&lfs2, &file[0], (char*)buffer, + memset(path, 'w', LFS2_NAME_MAX+1); + path[LFS2_NAME_MAX+2] = '\0'; + lfs2_mkdir(&lfs2, path) => LFS2_ERR_NAMETOOLONG; + lfs2_file_open(&lfs2, &file, path, LFS2_O_WRONLY | LFS2_O_CREAT) => LFS2_ERR_NAMETOOLONG; - memcpy(buffer, "coffee/", strlen("coffee/")); - memset(buffer+strlen("coffee/"), 'w', LFS2_NAME_MAX+1); - buffer[strlen("coffee/")+LFS2_NAME_MAX+2] = '\0'; - lfs2_mkdir(&lfs2, (char*)buffer) => LFS2_ERR_NAMETOOLONG; - lfs2_file_open(&lfs2, &file[0], (char*)buffer, + memcpy(path, "coffee/", strlen("coffee/")); + memset(path+strlen("coffee/"), 'w', LFS2_NAME_MAX+1); + path[strlen("coffee/")+LFS2_NAME_MAX+2] = '\0'; + lfs2_mkdir(&lfs2, path) => LFS2_ERR_NAMETOOLONG; + lfs2_file_open(&lfs2, &file, path, LFS2_O_WRONLY | LFS2_O_CREAT) => LFS2_ERR_NAMETOOLONG; lfs2_unmount(&lfs2) => 0; TEST echo "--- Really big path test ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; - memset(buffer, 'w', LFS2_NAME_MAX); - buffer[LFS2_NAME_MAX+1] = '\0'; - lfs2_mkdir(&lfs2, (char*)buffer) => 0; - lfs2_remove(&lfs2, (char*)buffer) => 0; - lfs2_file_open(&lfs2, &file[0], (char*)buffer, + memset(path, 'w', LFS2_NAME_MAX); + path[LFS2_NAME_MAX+1] = '\0'; + lfs2_mkdir(&lfs2, path) => 0; + lfs2_remove(&lfs2, path) => 0; + lfs2_file_open(&lfs2, &file, path, LFS2_O_WRONLY | LFS2_O_CREAT) => 0; - lfs2_file_close(&lfs2, &file[0]) => 0; - lfs2_remove(&lfs2, (char*)buffer) => 0; + lfs2_file_close(&lfs2, &file) => 0; + lfs2_remove(&lfs2, path) => 0; - memcpy(buffer, "coffee/", strlen("coffee/")); - memset(buffer+strlen("coffee/"), 'w', LFS2_NAME_MAX); - buffer[strlen("coffee/")+LFS2_NAME_MAX+1] = '\0'; - lfs2_mkdir(&lfs2, (char*)buffer) => 0; - lfs2_remove(&lfs2, (char*)buffer) => 0; - lfs2_file_open(&lfs2, &file[0], (char*)buffer, + memcpy(path, "coffee/", strlen("coffee/")); + memset(path+strlen("coffee/"), 'w', LFS2_NAME_MAX); + path[strlen("coffee/")+LFS2_NAME_MAX+1] = '\0'; + lfs2_mkdir(&lfs2, path) => 0; + lfs2_remove(&lfs2, path) => 0; + lfs2_file_open(&lfs2, &file, path, LFS2_O_WRONLY | LFS2_O_CREAT) => 0; - lfs2_file_close(&lfs2, &file[0]) => 0; - lfs2_remove(&lfs2, (char*)buffer) => 0; + lfs2_file_close(&lfs2, &file) => 0; + lfs2_remove(&lfs2, path) => 0; lfs2_unmount(&lfs2) => 0; TEST -echo "--- Results ---" -tests/stats.py +scripts/results.py diff --git a/tests/test_seek.sh b/tests/test_seek.sh index 111e129..a4391e7 100755 --- a/tests/test_seek.sh +++ b/tests/test_seek.sh @@ -1,429 +1,431 @@ #!/bin/bash set -eu +export TEST_FILE=$0 +trap 'export TEST_LINE=$LINENO' DEBUG + +echo "=== Seek tests ===" SMALLSIZE=4 MEDIUMSIZE=128 LARGESIZE=132 -echo "=== Seek tests ===" rm -rf blocks -tests/test.py << TEST +scripts/test.py << TEST lfs2_format(&lfs2, &cfg) => 0; lfs2_mount(&lfs2, &cfg) => 0; lfs2_mkdir(&lfs2, "hello") => 0; for (int i = 0; i < $LARGESIZE; i++) { - sprintf((char*)buffer, "hello/kitty%03d", i); - lfs2_file_open(&lfs2, &file[0], (char*)buffer, + sprintf(path, "hello/kitty%03d", i); + lfs2_file_open(&lfs2, &file, path, LFS2_O_WRONLY | LFS2_O_CREAT | LFS2_O_APPEND) => 0; - size = strlen("kittycatcat"); + lfs2_size_t size = strlen("kittycatcat"); memcpy(buffer, "kittycatcat", size); for (int j = 0; j < $LARGESIZE; j++) { - lfs2_file_write(&lfs2, &file[0], buffer, size); + lfs2_file_write(&lfs2, &file, buffer, size); } - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_close(&lfs2, &file) => 0; } lfs2_unmount(&lfs2) => 0; TEST echo "--- Simple dir seek ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; - lfs2_dir_open(&lfs2, &dir[0], "hello") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_open(&lfs2, &dir, "hello") => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, ".") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "..") => 0; lfs2_soff_t pos; int i; for (i = 0; i < $SMALLSIZE; i++) { - sprintf((char*)buffer, "kitty%03d", i); - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; - strcmp(info.name, (char*)buffer) => 0; - pos = lfs2_dir_tell(&lfs2, &dir[0]); + sprintf(path, "kitty%03d", i); + lfs2_dir_read(&lfs2, &dir, &info) => 1; + strcmp(info.name, path) => 0; + pos = lfs2_dir_tell(&lfs2, &dir); } pos >= 0 => 1; - lfs2_dir_seek(&lfs2, &dir[0], pos) => 0; - sprintf((char*)buffer, "kitty%03d", i); - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; - strcmp(info.name, (char*)buffer) => 0; + lfs2_dir_seek(&lfs2, &dir, pos) => 0; + sprintf(path, "kitty%03d", i); + lfs2_dir_read(&lfs2, &dir, &info) => 1; + strcmp(info.name, path) => 0; - lfs2_dir_rewind(&lfs2, &dir[0]) => 0; - sprintf((char*)buffer, "kitty%03d", 0); - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_rewind(&lfs2, &dir) => 0; + sprintf(path, "kitty%03d", 0); + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, ".") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "..") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; - strcmp(info.name, (char*)buffer) => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 1; + strcmp(info.name, path) => 0; - lfs2_dir_seek(&lfs2, &dir[0], pos) => 0; - sprintf((char*)buffer, "kitty%03d", i); - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; - strcmp(info.name, (char*)buffer) => 0; + lfs2_dir_seek(&lfs2, &dir, pos) => 0; + sprintf(path, "kitty%03d", i); + lfs2_dir_read(&lfs2, &dir, &info) => 1; + strcmp(info.name, path) => 0; - lfs2_dir_close(&lfs2, &dir[0]) => 0; + lfs2_dir_close(&lfs2, &dir) => 0; lfs2_unmount(&lfs2) => 0; TEST echo "--- Large dir seek ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; - lfs2_dir_open(&lfs2, &dir[0], "hello") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_open(&lfs2, &dir, "hello") => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, ".") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "..") => 0; lfs2_soff_t pos; int i; for (i = 0; i < $MEDIUMSIZE; i++) { - sprintf((char*)buffer, "kitty%03d", i); - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; - strcmp(info.name, (char*)buffer) => 0; - pos = lfs2_dir_tell(&lfs2, &dir[0]); + sprintf(path, "kitty%03d", i); + lfs2_dir_read(&lfs2, &dir, &info) => 1; + strcmp(info.name, path) => 0; + pos = lfs2_dir_tell(&lfs2, &dir); } pos >= 0 => 1; - lfs2_dir_seek(&lfs2, &dir[0], pos) => 0; - sprintf((char*)buffer, "kitty%03d", i); - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; - strcmp(info.name, (char*)buffer) => 0; + lfs2_dir_seek(&lfs2, &dir, pos) => 0; + sprintf(path, "kitty%03d", i); + lfs2_dir_read(&lfs2, &dir, &info) => 1; + strcmp(info.name, path) => 0; - lfs2_dir_rewind(&lfs2, &dir[0]) => 0; - sprintf((char*)buffer, "kitty%03d", 0); - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_rewind(&lfs2, &dir) => 0; + sprintf(path, "kitty%03d", 0); + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, ".") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; + lfs2_dir_read(&lfs2, &dir, &info) => 1; strcmp(info.name, "..") => 0; - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; - strcmp(info.name, (char*)buffer) => 0; + lfs2_dir_read(&lfs2, &dir, &info) => 1; + strcmp(info.name, path) => 0; - lfs2_dir_seek(&lfs2, &dir[0], pos) => 0; - sprintf((char*)buffer, "kitty%03d", i); - lfs2_dir_read(&lfs2, &dir[0], &info) => 1; - strcmp(info.name, (char*)buffer) => 0; + lfs2_dir_seek(&lfs2, &dir, pos) => 0; + sprintf(path, "kitty%03d", i); + lfs2_dir_read(&lfs2, &dir, &info) => 1; + strcmp(info.name, path) => 0; - lfs2_dir_close(&lfs2, &dir[0]) => 0; + lfs2_dir_close(&lfs2, &dir) => 0; lfs2_unmount(&lfs2) => 0; TEST echo "--- Simple file seek ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; - lfs2_file_open(&lfs2, &file[0], "hello/kitty042", LFS2_O_RDONLY) => 0; + lfs2_file_open(&lfs2, &file, "hello/kitty042", LFS2_O_RDONLY) => 0; lfs2_soff_t pos; - size = strlen("kittycatcat"); + lfs2_size_t size = strlen("kittycatcat"); for (int i = 0; i < $SMALLSIZE; i++) { - lfs2_file_read(&lfs2, &file[0], buffer, size) => size; + lfs2_file_read(&lfs2, &file, buffer, size) => size; memcmp(buffer, "kittycatcat", size) => 0; - pos = lfs2_file_tell(&lfs2, &file[0]); + pos = lfs2_file_tell(&lfs2, &file); } pos >= 0 => 1; - lfs2_file_seek(&lfs2, &file[0], pos, LFS2_SEEK_SET) => pos; - lfs2_file_read(&lfs2, &file[0], buffer, size) => size; + lfs2_file_seek(&lfs2, &file, pos, LFS2_SEEK_SET) => pos; + lfs2_file_read(&lfs2, &file, buffer, size) => size; memcmp(buffer, "kittycatcat", size) => 0; - lfs2_file_rewind(&lfs2, &file[0]) => 0; - lfs2_file_read(&lfs2, &file[0], buffer, size) => size; + lfs2_file_rewind(&lfs2, &file) => 0; + lfs2_file_read(&lfs2, &file, buffer, size) => size; memcmp(buffer, "kittycatcat", size) => 0; - lfs2_file_seek(&lfs2, &file[0], 0, LFS2_SEEK_CUR) => size; - lfs2_file_read(&lfs2, &file[0], buffer, size) => size; + lfs2_file_seek(&lfs2, &file, 0, LFS2_SEEK_CUR) => size; + lfs2_file_read(&lfs2, &file, buffer, size) => size; memcmp(buffer, "kittycatcat", size) => 0; - lfs2_file_seek(&lfs2, &file[0], size, LFS2_SEEK_CUR) => 3*size; - lfs2_file_read(&lfs2, &file[0], buffer, size) => size; + lfs2_file_seek(&lfs2, &file, size, LFS2_SEEK_CUR) => 3*size; + lfs2_file_read(&lfs2, &file, buffer, size) => size; memcmp(buffer, "kittycatcat", size) => 0; - lfs2_file_seek(&lfs2, &file[0], pos, LFS2_SEEK_SET) => pos; - lfs2_file_read(&lfs2, &file[0], buffer, size) => size; + lfs2_file_seek(&lfs2, &file, pos, LFS2_SEEK_SET) => pos; + lfs2_file_read(&lfs2, &file, buffer, size) => size; memcmp(buffer, "kittycatcat", size) => 0; - lfs2_file_seek(&lfs2, &file[0], -size, LFS2_SEEK_CUR) => pos; - lfs2_file_read(&lfs2, &file[0], buffer, size) => size; + lfs2_file_seek(&lfs2, &file, -size, LFS2_SEEK_CUR) => pos; + lfs2_file_read(&lfs2, &file, buffer, size) => size; memcmp(buffer, "kittycatcat", size) => 0; - lfs2_file_seek(&lfs2, &file[0], -size, LFS2_SEEK_END) >= 0 => 1; - lfs2_file_read(&lfs2, &file[0], buffer, size) => size; + lfs2_file_seek(&lfs2, &file, -size, LFS2_SEEK_END) >= 0 => 1; + lfs2_file_read(&lfs2, &file, buffer, size) => size; memcmp(buffer, "kittycatcat", size) => 0; - size = lfs2_file_size(&lfs2, &file[0]); - lfs2_file_seek(&lfs2, &file[0], 0, LFS2_SEEK_CUR) => size; + size = lfs2_file_size(&lfs2, &file); + lfs2_file_seek(&lfs2, &file, 0, LFS2_SEEK_CUR) => size; - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_close(&lfs2, &file) => 0; lfs2_unmount(&lfs2) => 0; TEST echo "--- Large file seek ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; - lfs2_file_open(&lfs2, &file[0], "hello/kitty042", LFS2_O_RDONLY) => 0; + lfs2_file_open(&lfs2, &file, "hello/kitty042", LFS2_O_RDONLY) => 0; lfs2_soff_t pos; - size = strlen("kittycatcat"); + lfs2_size_t size = strlen("kittycatcat"); for (int i = 0; i < $MEDIUMSIZE; i++) { - lfs2_file_read(&lfs2, &file[0], buffer, size) => size; + lfs2_file_read(&lfs2, &file, buffer, size) => size; memcmp(buffer, "kittycatcat", size) => 0; - pos = lfs2_file_tell(&lfs2, &file[0]); + pos = lfs2_file_tell(&lfs2, &file); } pos >= 0 => 1; - lfs2_file_seek(&lfs2, &file[0], pos, LFS2_SEEK_SET) => pos; - lfs2_file_read(&lfs2, &file[0], buffer, size) => size; + lfs2_file_seek(&lfs2, &file, pos, LFS2_SEEK_SET) => pos; + lfs2_file_read(&lfs2, &file, buffer, size) => size; memcmp(buffer, "kittycatcat", size) => 0; - lfs2_file_rewind(&lfs2, &file[0]) => 0; - lfs2_file_read(&lfs2, &file[0], buffer, size) => size; + lfs2_file_rewind(&lfs2, &file) => 0; + lfs2_file_read(&lfs2, &file, buffer, size) => size; memcmp(buffer, "kittycatcat", size) => 0; - lfs2_file_seek(&lfs2, &file[0], 0, LFS2_SEEK_CUR) => size; - lfs2_file_read(&lfs2, &file[0], buffer, size) => size; + lfs2_file_seek(&lfs2, &file, 0, LFS2_SEEK_CUR) => size; + lfs2_file_read(&lfs2, &file, buffer, size) => size; memcmp(buffer, "kittycatcat", size) => 0; - lfs2_file_seek(&lfs2, &file[0], size, LFS2_SEEK_CUR) => 3*size; - lfs2_file_read(&lfs2, &file[0], buffer, size) => size; + lfs2_file_seek(&lfs2, &file, size, LFS2_SEEK_CUR) => 3*size; + lfs2_file_read(&lfs2, &file, buffer, size) => size; memcmp(buffer, "kittycatcat", size) => 0; - lfs2_file_seek(&lfs2, &file[0], pos, LFS2_SEEK_SET) => pos; - lfs2_file_read(&lfs2, &file[0], buffer, size) => size; + lfs2_file_seek(&lfs2, &file, pos, LFS2_SEEK_SET) => pos; + lfs2_file_read(&lfs2, &file, buffer, size) => size; memcmp(buffer, "kittycatcat", size) => 0; - lfs2_file_seek(&lfs2, &file[0], -size, LFS2_SEEK_CUR) => pos; - lfs2_file_read(&lfs2, &file[0], buffer, size) => size; + lfs2_file_seek(&lfs2, &file, -size, LFS2_SEEK_CUR) => pos; + lfs2_file_read(&lfs2, &file, buffer, size) => size; memcmp(buffer, "kittycatcat", size) => 0; - lfs2_file_seek(&lfs2, &file[0], -size, LFS2_SEEK_END) >= 0 => 1; - lfs2_file_read(&lfs2, &file[0], buffer, size) => size; + lfs2_file_seek(&lfs2, &file, -size, LFS2_SEEK_END) >= 0 => 1; + lfs2_file_read(&lfs2, &file, buffer, size) => size; memcmp(buffer, "kittycatcat", size) => 0; - size = lfs2_file_size(&lfs2, &file[0]); - lfs2_file_seek(&lfs2, &file[0], 0, LFS2_SEEK_CUR) => size; + size = lfs2_file_size(&lfs2, &file); + lfs2_file_seek(&lfs2, &file, 0, LFS2_SEEK_CUR) => size; - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_close(&lfs2, &file) => 0; lfs2_unmount(&lfs2) => 0; TEST echo "--- Simple file seek and write ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; - lfs2_file_open(&lfs2, &file[0], "hello/kitty042", LFS2_O_RDWR) => 0; + lfs2_file_open(&lfs2, &file, "hello/kitty042", LFS2_O_RDWR) => 0; lfs2_soff_t pos; - size = strlen("kittycatcat"); + lfs2_size_t size = strlen("kittycatcat"); for (int i = 0; i < $SMALLSIZE; i++) { - lfs2_file_read(&lfs2, &file[0], buffer, size) => size; + lfs2_file_read(&lfs2, &file, buffer, size) => size; memcmp(buffer, "kittycatcat", size) => 0; - pos = lfs2_file_tell(&lfs2, &file[0]); + pos = lfs2_file_tell(&lfs2, &file); } pos >= 0 => 1; memcpy(buffer, "doggodogdog", size); - lfs2_file_seek(&lfs2, &file[0], pos, LFS2_SEEK_SET) => pos; - lfs2_file_write(&lfs2, &file[0], buffer, size) => size; + lfs2_file_seek(&lfs2, &file, pos, LFS2_SEEK_SET) => pos; + lfs2_file_write(&lfs2, &file, buffer, size) => size; - lfs2_file_seek(&lfs2, &file[0], pos, LFS2_SEEK_SET) => pos; - lfs2_file_read(&lfs2, &file[0], buffer, size) => size; + lfs2_file_seek(&lfs2, &file, pos, LFS2_SEEK_SET) => pos; + lfs2_file_read(&lfs2, &file, buffer, size) => size; memcmp(buffer, "doggodogdog", size) => 0; - lfs2_file_rewind(&lfs2, &file[0]) => 0; - lfs2_file_read(&lfs2, &file[0], buffer, size) => size; + lfs2_file_rewind(&lfs2, &file) => 0; + lfs2_file_read(&lfs2, &file, buffer, size) => size; memcmp(buffer, "kittycatcat", size) => 0; - lfs2_file_seek(&lfs2, &file[0], pos, LFS2_SEEK_SET) => pos; - lfs2_file_read(&lfs2, &file[0], buffer, size) => size; + lfs2_file_seek(&lfs2, &file, pos, LFS2_SEEK_SET) => pos; + lfs2_file_read(&lfs2, &file, buffer, size) => size; memcmp(buffer, "doggodogdog", size) => 0; - lfs2_file_seek(&lfs2, &file[0], -size, LFS2_SEEK_END) >= 0 => 1; - lfs2_file_read(&lfs2, &file[0], buffer, size) => size; + lfs2_file_seek(&lfs2, &file, -size, LFS2_SEEK_END) >= 0 => 1; + lfs2_file_read(&lfs2, &file, buffer, size) => size; memcmp(buffer, "kittycatcat", size) => 0; - size = lfs2_file_size(&lfs2, &file[0]); - lfs2_file_seek(&lfs2, &file[0], 0, LFS2_SEEK_CUR) => size; + size = lfs2_file_size(&lfs2, &file); + lfs2_file_seek(&lfs2, &file, 0, LFS2_SEEK_CUR) => size; - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_close(&lfs2, &file) => 0; lfs2_unmount(&lfs2) => 0; TEST echo "--- Large file seek and write ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; - lfs2_file_open(&lfs2, &file[0], "hello/kitty042", LFS2_O_RDWR) => 0; + lfs2_file_open(&lfs2, &file, "hello/kitty042", LFS2_O_RDWR) => 0; lfs2_soff_t pos; - size = strlen("kittycatcat"); + lfs2_size_t size = strlen("kittycatcat"); for (int i = 0; i < $MEDIUMSIZE; i++) { - lfs2_file_read(&lfs2, &file[0], buffer, size) => size; + lfs2_file_read(&lfs2, &file, buffer, size) => size; if (i != $SMALLSIZE) { memcmp(buffer, "kittycatcat", size) => 0; } - pos = lfs2_file_tell(&lfs2, &file[0]); + pos = lfs2_file_tell(&lfs2, &file); } pos >= 0 => 1; memcpy(buffer, "doggodogdog", size); - lfs2_file_seek(&lfs2, &file[0], pos, LFS2_SEEK_SET) => pos; - lfs2_file_write(&lfs2, &file[0], buffer, size) => size; + lfs2_file_seek(&lfs2, &file, pos, LFS2_SEEK_SET) => pos; + lfs2_file_write(&lfs2, &file, buffer, size) => size; - lfs2_file_seek(&lfs2, &file[0], pos, LFS2_SEEK_SET) => pos; - lfs2_file_read(&lfs2, &file[0], buffer, size) => size; + lfs2_file_seek(&lfs2, &file, pos, LFS2_SEEK_SET) => pos; + lfs2_file_read(&lfs2, &file, buffer, size) => size; memcmp(buffer, "doggodogdog", size) => 0; - lfs2_file_rewind(&lfs2, &file[0]) => 0; - lfs2_file_read(&lfs2, &file[0], buffer, size) => size; + lfs2_file_rewind(&lfs2, &file) => 0; + lfs2_file_read(&lfs2, &file, buffer, size) => size; memcmp(buffer, "kittycatcat", size) => 0; - lfs2_file_seek(&lfs2, &file[0], pos, LFS2_SEEK_SET) => pos; - lfs2_file_read(&lfs2, &file[0], buffer, size) => size; + lfs2_file_seek(&lfs2, &file, pos, LFS2_SEEK_SET) => pos; + lfs2_file_read(&lfs2, &file, buffer, size) => size; memcmp(buffer, "doggodogdog", size) => 0; - lfs2_file_seek(&lfs2, &file[0], -size, LFS2_SEEK_END) >= 0 => 1; - lfs2_file_read(&lfs2, &file[0], buffer, size) => size; + lfs2_file_seek(&lfs2, &file, -size, LFS2_SEEK_END) >= 0 => 1; + lfs2_file_read(&lfs2, &file, buffer, size) => size; memcmp(buffer, "kittycatcat", size) => 0; - size = lfs2_file_size(&lfs2, &file[0]); - lfs2_file_seek(&lfs2, &file[0], 0, LFS2_SEEK_CUR) => size; + size = lfs2_file_size(&lfs2, &file); + lfs2_file_seek(&lfs2, &file, 0, LFS2_SEEK_CUR) => size; - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_close(&lfs2, &file) => 0; lfs2_unmount(&lfs2) => 0; TEST echo "--- Boundary seek and write ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; - lfs2_file_open(&lfs2, &file[0], "hello/kitty042", LFS2_O_RDWR) => 0; + lfs2_file_open(&lfs2, &file, "hello/kitty042", LFS2_O_RDWR) => 0; - size = strlen("hedgehoghog"); + lfs2_size_t size = strlen("hedgehoghog"); const lfs2_soff_t offsets[] = {512, 1020, 513, 1021, 511, 1019}; for (unsigned i = 0; i < sizeof(offsets) / sizeof(offsets[0]); i++) { lfs2_soff_t off = offsets[i]; memcpy(buffer, "hedgehoghog", size); - lfs2_file_seek(&lfs2, &file[0], off, LFS2_SEEK_SET) => off; - lfs2_file_write(&lfs2, &file[0], buffer, size) => size; - lfs2_file_seek(&lfs2, &file[0], off, LFS2_SEEK_SET) => off; - lfs2_file_read(&lfs2, &file[0], buffer, size) => size; + lfs2_file_seek(&lfs2, &file, off, LFS2_SEEK_SET) => off; + lfs2_file_write(&lfs2, &file, buffer, size) => size; + lfs2_file_seek(&lfs2, &file, off, LFS2_SEEK_SET) => off; + lfs2_file_read(&lfs2, &file, buffer, size) => size; memcmp(buffer, "hedgehoghog", size) => 0; - lfs2_file_seek(&lfs2, &file[0], 0, LFS2_SEEK_SET) => 0; - lfs2_file_read(&lfs2, &file[0], buffer, size) => size; + lfs2_file_seek(&lfs2, &file, 0, LFS2_SEEK_SET) => 0; + lfs2_file_read(&lfs2, &file, buffer, size) => size; memcmp(buffer, "kittycatcat", size) => 0; - lfs2_file_sync(&lfs2, &file[0]) => 0; + lfs2_file_sync(&lfs2, &file) => 0; } - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_close(&lfs2, &file) => 0; lfs2_unmount(&lfs2) => 0; TEST echo "--- Out-of-bounds seek ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; - lfs2_file_open(&lfs2, &file[0], "hello/kitty042", LFS2_O_RDWR) => 0; + lfs2_file_open(&lfs2, &file, "hello/kitty042", LFS2_O_RDWR) => 0; - size = strlen("kittycatcat"); - lfs2_file_size(&lfs2, &file[0]) => $LARGESIZE*size; - lfs2_file_seek(&lfs2, &file[0], ($LARGESIZE+$SMALLSIZE)*size, + lfs2_size_t size = strlen("kittycatcat"); + lfs2_file_size(&lfs2, &file) => $LARGESIZE*size; + lfs2_file_seek(&lfs2, &file, ($LARGESIZE+$SMALLSIZE)*size, LFS2_SEEK_SET) => ($LARGESIZE+$SMALLSIZE)*size; - lfs2_file_read(&lfs2, &file[0], buffer, size) => 0; + lfs2_file_read(&lfs2, &file, buffer, size) => 0; memcpy(buffer, "porcupineee", size); - lfs2_file_write(&lfs2, &file[0], buffer, size) => size; + lfs2_file_write(&lfs2, &file, buffer, size) => size; - lfs2_file_seek(&lfs2, &file[0], ($LARGESIZE+$SMALLSIZE)*size, + lfs2_file_seek(&lfs2, &file, ($LARGESIZE+$SMALLSIZE)*size, LFS2_SEEK_SET) => ($LARGESIZE+$SMALLSIZE)*size; - lfs2_file_read(&lfs2, &file[0], buffer, size) => size; + lfs2_file_read(&lfs2, &file, buffer, size) => size; memcmp(buffer, "porcupineee", size) => 0; - lfs2_file_seek(&lfs2, &file[0], $LARGESIZE*size, + lfs2_file_seek(&lfs2, &file, $LARGESIZE*size, LFS2_SEEK_SET) => $LARGESIZE*size; - lfs2_file_read(&lfs2, &file[0], buffer, size) => size; + lfs2_file_read(&lfs2, &file, buffer, size) => size; memcmp(buffer, "\0\0\0\0\0\0\0\0\0\0\0", size) => 0; - lfs2_file_seek(&lfs2, &file[0], -(($LARGESIZE+$SMALLSIZE)*size), + lfs2_file_seek(&lfs2, &file, -(($LARGESIZE+$SMALLSIZE)*size), LFS2_SEEK_CUR) => LFS2_ERR_INVAL; - lfs2_file_tell(&lfs2, &file[0]) => ($LARGESIZE+1)*size; + lfs2_file_tell(&lfs2, &file) => ($LARGESIZE+1)*size; - lfs2_file_seek(&lfs2, &file[0], -(($LARGESIZE+2*$SMALLSIZE)*size), + lfs2_file_seek(&lfs2, &file, -(($LARGESIZE+2*$SMALLSIZE)*size), LFS2_SEEK_END) => LFS2_ERR_INVAL; - lfs2_file_tell(&lfs2, &file[0]) => ($LARGESIZE+1)*size; + lfs2_file_tell(&lfs2, &file) => ($LARGESIZE+1)*size; - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_close(&lfs2, &file) => 0; lfs2_unmount(&lfs2) => 0; TEST echo "--- Inline write and seek ---" for SIZE in $SMALLSIZE $MEDIUMSIZE $LARGESIZE do -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; - lfs2_file_open(&lfs2, &file[0], "hello/tinykitty$SIZE", + lfs2_file_open(&lfs2, &file, "hello/tinykitty$SIZE", LFS2_O_RDWR | LFS2_O_CREAT) => 0; int j = 0; int k = 0; memcpy(buffer, "abcdefghijklmnopqrstuvwxyz", 26); for (unsigned i = 0; i < $SIZE; i++) { - lfs2_file_write(&lfs2, &file[0], &buffer[j++ % 26], 1) => 1; - lfs2_file_tell(&lfs2, &file[0]) => i+1; - lfs2_file_size(&lfs2, &file[0]) => i+1; + lfs2_file_write(&lfs2, &file, &buffer[j++ % 26], 1) => 1; + lfs2_file_tell(&lfs2, &file) => i+1; + lfs2_file_size(&lfs2, &file) => i+1; } - lfs2_file_seek(&lfs2, &file[0], 0, LFS2_SEEK_SET) => 0; - lfs2_file_tell(&lfs2, &file[0]) => 0; - lfs2_file_size(&lfs2, &file[0]) => $SIZE; + lfs2_file_seek(&lfs2, &file, 0, LFS2_SEEK_SET) => 0; + lfs2_file_tell(&lfs2, &file) => 0; + lfs2_file_size(&lfs2, &file) => $SIZE; for (unsigned i = 0; i < $SIZE; i++) { uint8_t c; - lfs2_file_read(&lfs2, &file[0], &c, 1) => 1; + lfs2_file_read(&lfs2, &file, &c, 1) => 1; c => buffer[k++ % 26]; } - lfs2_file_sync(&lfs2, &file[0]) => 0; - lfs2_file_tell(&lfs2, &file[0]) => $SIZE; - lfs2_file_size(&lfs2, &file[0]) => $SIZE; + lfs2_file_sync(&lfs2, &file) => 0; + lfs2_file_tell(&lfs2, &file) => $SIZE; + lfs2_file_size(&lfs2, &file) => $SIZE; - lfs2_file_seek(&lfs2, &file[0], 0, LFS2_SEEK_SET) => 0; + lfs2_file_seek(&lfs2, &file, 0, LFS2_SEEK_SET) => 0; for (unsigned i = 0; i < $SIZE; i++) { - lfs2_file_write(&lfs2, &file[0], &buffer[j++ % 26], 1) => 1; - lfs2_file_tell(&lfs2, &file[0]) => i+1; - lfs2_file_size(&lfs2, &file[0]) => $SIZE; - lfs2_file_sync(&lfs2, &file[0]) => 0; - lfs2_file_tell(&lfs2, &file[0]) => i+1; - lfs2_file_size(&lfs2, &file[0]) => $SIZE; + lfs2_file_write(&lfs2, &file, &buffer[j++ % 26], 1) => 1; + lfs2_file_tell(&lfs2, &file) => i+1; + lfs2_file_size(&lfs2, &file) => $SIZE; + lfs2_file_sync(&lfs2, &file) => 0; + lfs2_file_tell(&lfs2, &file) => i+1; + lfs2_file_size(&lfs2, &file) => $SIZE; if (i < $SIZE-2) { uint8_t c[3]; - lfs2_file_seek(&lfs2, &file[0], -1, LFS2_SEEK_CUR) => i; - lfs2_file_read(&lfs2, &file[0], &c, 3) => 3; - lfs2_file_tell(&lfs2, &file[0]) => i+3; - lfs2_file_size(&lfs2, &file[0]) => $SIZE; - lfs2_file_seek(&lfs2, &file[0], i+1, LFS2_SEEK_SET) => i+1; - lfs2_file_tell(&lfs2, &file[0]) => i+1; - lfs2_file_size(&lfs2, &file[0]) => $SIZE; + lfs2_file_seek(&lfs2, &file, -1, LFS2_SEEK_CUR) => i; + lfs2_file_read(&lfs2, &file, &c, 3) => 3; + lfs2_file_tell(&lfs2, &file) => i+3; + lfs2_file_size(&lfs2, &file) => $SIZE; + lfs2_file_seek(&lfs2, &file, i+1, LFS2_SEEK_SET) => i+1; + lfs2_file_tell(&lfs2, &file) => i+1; + lfs2_file_size(&lfs2, &file) => $SIZE; } } - lfs2_file_seek(&lfs2, &file[0], 0, LFS2_SEEK_SET) => 0; - lfs2_file_tell(&lfs2, &file[0]) => 0; - lfs2_file_size(&lfs2, &file[0]) => $SIZE; + lfs2_file_seek(&lfs2, &file, 0, LFS2_SEEK_SET) => 0; + lfs2_file_tell(&lfs2, &file) => 0; + lfs2_file_size(&lfs2, &file) => $SIZE; for (unsigned i = 0; i < $SIZE; i++) { uint8_t c; - lfs2_file_read(&lfs2, &file[0], &c, 1) => 1; + lfs2_file_read(&lfs2, &file, &c, 1) => 1; c => buffer[k++ % 26]; } - lfs2_file_sync(&lfs2, &file[0]) => 0; - lfs2_file_tell(&lfs2, &file[0]) => $SIZE; - lfs2_file_size(&lfs2, &file[0]) => $SIZE; + lfs2_file_sync(&lfs2, &file) => 0; + lfs2_file_tell(&lfs2, &file) => $SIZE; + lfs2_file_size(&lfs2, &file) => $SIZE; - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_close(&lfs2, &file) => 0; lfs2_unmount(&lfs2) => 0; TEST done -echo "--- Results ---" -tests/stats.py +scripts/results.py diff --git a/tests/test_truncate.sh b/tests/test_truncate.sh index 73fd41e..4046222 100755 --- a/tests/test_truncate.sh +++ b/tests/test_truncate.sh @@ -1,156 +1,159 @@ #!/bin/bash set -eu +export TEST_FILE=$0 +trap 'export TEST_LINE=$LINENO' DEBUG + +echo "=== Truncate tests ===" SMALLSIZE=32 MEDIUMSIZE=2048 LARGESIZE=8192 -echo "=== Truncate tests ===" rm -rf blocks -tests/test.py << TEST +scripts/test.py << TEST lfs2_format(&lfs2, &cfg) => 0; TEST echo "--- Simple truncate ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; - lfs2_file_open(&lfs2, &file[0], "baldynoop", + lfs2_file_open(&lfs2, &file, "baldynoop", LFS2_O_WRONLY | LFS2_O_CREAT) => 0; strcpy((char*)buffer, "hair"); - size = strlen((char*)buffer); + lfs2_size_t size = strlen((char*)buffer); for (lfs2_off_t j = 0; j < $LARGESIZE; j += size) { - lfs2_file_write(&lfs2, &file[0], buffer, size) => size; + lfs2_file_write(&lfs2, &file, buffer, size) => size; } - lfs2_file_size(&lfs2, &file[0]) => $LARGESIZE; + lfs2_file_size(&lfs2, &file) => $LARGESIZE; - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_close(&lfs2, &file) => 0; lfs2_unmount(&lfs2) => 0; TEST -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; - lfs2_file_open(&lfs2, &file[0], "baldynoop", LFS2_O_RDWR) => 0; - lfs2_file_size(&lfs2, &file[0]) => $LARGESIZE; + lfs2_file_open(&lfs2, &file, "baldynoop", LFS2_O_RDWR) => 0; + lfs2_file_size(&lfs2, &file) => $LARGESIZE; - lfs2_file_truncate(&lfs2, &file[0], $MEDIUMSIZE) => 0; - lfs2_file_size(&lfs2, &file[0]) => $MEDIUMSIZE; + lfs2_file_truncate(&lfs2, &file, $MEDIUMSIZE) => 0; + lfs2_file_size(&lfs2, &file) => $MEDIUMSIZE; - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_close(&lfs2, &file) => 0; lfs2_unmount(&lfs2) => 0; TEST -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; - lfs2_file_open(&lfs2, &file[0], "baldynoop", LFS2_O_RDONLY) => 0; - lfs2_file_size(&lfs2, &file[0]) => $MEDIUMSIZE; + lfs2_file_open(&lfs2, &file, "baldynoop", LFS2_O_RDONLY) => 0; + lfs2_file_size(&lfs2, &file) => $MEDIUMSIZE; - size = strlen("hair"); + lfs2_size_t size = strlen("hair"); for (lfs2_off_t j = 0; j < $MEDIUMSIZE; j += size) { - lfs2_file_read(&lfs2, &file[0], buffer, size) => size; + lfs2_file_read(&lfs2, &file, buffer, size) => size; memcmp(buffer, "hair", size) => 0; } - lfs2_file_read(&lfs2, &file[0], buffer, size) => 0; + lfs2_file_read(&lfs2, &file, buffer, size) => 0; - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_close(&lfs2, &file) => 0; lfs2_unmount(&lfs2) => 0; TEST echo "--- Truncate and read ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; - lfs2_file_open(&lfs2, &file[0], "baldyread", + lfs2_file_open(&lfs2, &file, "baldyread", LFS2_O_WRONLY | LFS2_O_CREAT) => 0; strcpy((char*)buffer, "hair"); - size = strlen((char*)buffer); + lfs2_size_t size = strlen((char*)buffer); for (lfs2_off_t j = 0; j < $LARGESIZE; j += size) { - lfs2_file_write(&lfs2, &file[0], buffer, size) => size; + lfs2_file_write(&lfs2, &file, buffer, size) => size; } - lfs2_file_size(&lfs2, &file[0]) => $LARGESIZE; + lfs2_file_size(&lfs2, &file) => $LARGESIZE; - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_close(&lfs2, &file) => 0; lfs2_unmount(&lfs2) => 0; TEST -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; - lfs2_file_open(&lfs2, &file[0], "baldyread", LFS2_O_RDWR) => 0; - lfs2_file_size(&lfs2, &file[0]) => $LARGESIZE; + lfs2_file_open(&lfs2, &file, "baldyread", LFS2_O_RDWR) => 0; + lfs2_file_size(&lfs2, &file) => $LARGESIZE; - lfs2_file_truncate(&lfs2, &file[0], $MEDIUMSIZE) => 0; - lfs2_file_size(&lfs2, &file[0]) => $MEDIUMSIZE; + lfs2_file_truncate(&lfs2, &file, $MEDIUMSIZE) => 0; + lfs2_file_size(&lfs2, &file) => $MEDIUMSIZE; - size = strlen("hair"); + lfs2_size_t size = strlen("hair"); for (lfs2_off_t j = 0; j < $MEDIUMSIZE; j += size) { - lfs2_file_read(&lfs2, &file[0], buffer, size) => size; + lfs2_file_read(&lfs2, &file, buffer, size) => size; memcmp(buffer, "hair", size) => 0; } - lfs2_file_read(&lfs2, &file[0], buffer, size) => 0; + lfs2_file_read(&lfs2, &file, buffer, size) => 0; - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_close(&lfs2, &file) => 0; lfs2_unmount(&lfs2) => 0; TEST -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; - lfs2_file_open(&lfs2, &file[0], "baldyread", LFS2_O_RDONLY) => 0; - lfs2_file_size(&lfs2, &file[0]) => $MEDIUMSIZE; + lfs2_file_open(&lfs2, &file, "baldyread", LFS2_O_RDONLY) => 0; + lfs2_file_size(&lfs2, &file) => $MEDIUMSIZE; - size = strlen("hair"); + lfs2_size_t size = strlen("hair"); for (lfs2_off_t j = 0; j < $MEDIUMSIZE; j += size) { - lfs2_file_read(&lfs2, &file[0], buffer, size) => size; + lfs2_file_read(&lfs2, &file, buffer, size) => size; memcmp(buffer, "hair", size) => 0; } - lfs2_file_read(&lfs2, &file[0], buffer, size) => 0; + lfs2_file_read(&lfs2, &file, buffer, size) => 0; - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_close(&lfs2, &file) => 0; lfs2_unmount(&lfs2) => 0; TEST echo "--- Truncate and write ---" -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; - lfs2_file_open(&lfs2, &file[0], "baldywrite", + lfs2_file_open(&lfs2, &file, "baldywrite", LFS2_O_WRONLY | LFS2_O_CREAT) => 0; strcpy((char*)buffer, "hair"); - size = strlen((char*)buffer); + lfs2_size_t size = strlen((char*)buffer); for (lfs2_off_t j = 0; j < $LARGESIZE; j += size) { - lfs2_file_write(&lfs2, &file[0], buffer, size) => size; + lfs2_file_write(&lfs2, &file, buffer, size) => size; } - lfs2_file_size(&lfs2, &file[0]) => $LARGESIZE; + lfs2_file_size(&lfs2, &file) => $LARGESIZE; - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_close(&lfs2, &file) => 0; lfs2_unmount(&lfs2) => 0; TEST -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; - lfs2_file_open(&lfs2, &file[0], "baldywrite", LFS2_O_RDWR) => 0; - lfs2_file_size(&lfs2, &file[0]) => $LARGESIZE; + lfs2_file_open(&lfs2, &file, "baldywrite", LFS2_O_RDWR) => 0; + lfs2_file_size(&lfs2, &file) => $LARGESIZE; - lfs2_file_truncate(&lfs2, &file[0], $MEDIUMSIZE) => 0; - lfs2_file_size(&lfs2, &file[0]) => $MEDIUMSIZE; + lfs2_file_truncate(&lfs2, &file, $MEDIUMSIZE) => 0; + lfs2_file_size(&lfs2, &file) => $MEDIUMSIZE; strcpy((char*)buffer, "bald"); - size = strlen((char*)buffer); + lfs2_size_t size = strlen((char*)buffer); for (lfs2_off_t j = 0; j < $MEDIUMSIZE; j += size) { - lfs2_file_write(&lfs2, &file[0], buffer, size) => size; + lfs2_file_write(&lfs2, &file, buffer, size) => size; } - lfs2_file_size(&lfs2, &file[0]) => $MEDIUMSIZE; + lfs2_file_size(&lfs2, &file) => $MEDIUMSIZE; - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_close(&lfs2, &file) => 0; lfs2_unmount(&lfs2) => 0; TEST -tests/test.py << TEST +scripts/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; - lfs2_file_open(&lfs2, &file[0], "baldywrite", LFS2_O_RDONLY) => 0; - lfs2_file_size(&lfs2, &file[0]) => $MEDIUMSIZE; + lfs2_file_open(&lfs2, &file, "baldywrite", LFS2_O_RDONLY) => 0; + lfs2_file_size(&lfs2, &file) => $MEDIUMSIZE; - size = strlen("bald"); + lfs2_size_t size = strlen("bald"); for (lfs2_off_t j = 0; j < $MEDIUMSIZE; j += size) { - lfs2_file_read(&lfs2, &file[0], buffer, size) => size; + lfs2_file_read(&lfs2, &file, buffer, size) => size; memcmp(buffer, "bald", size) => 0; } - lfs2_file_read(&lfs2, &file[0], buffer, size) => 0; + lfs2_file_read(&lfs2, &file, buffer, size) => 0; - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_close(&lfs2, &file) => 0; lfs2_unmount(&lfs2) => 0; TEST @@ -160,7 +163,7 @@ STARTSIZES="$1" STARTSEEKS="$2" HOTSIZES="$3" COLDSIZES="$4" -tests/test.py << TEST +scripts/test.py << TEST static const lfs2_off_t startsizes[] = {$STARTSIZES}; static const lfs2_off_t startseeks[] = {$STARTSEEKS}; static const lfs2_off_t hotsizes[] = {$HOTSIZES}; @@ -168,31 +171,31 @@ tests/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; for (unsigned i = 0; i < sizeof(startsizes)/sizeof(startsizes[0]); i++) { - sprintf((char*)buffer, "hairyhead%d", i); - lfs2_file_open(&lfs2, &file[0], (const char*)buffer, + sprintf(path, "hairyhead%d", i); + lfs2_file_open(&lfs2, &file, path, LFS2_O_WRONLY | LFS2_O_CREAT | LFS2_O_TRUNC) => 0; strcpy((char*)buffer, "hair"); - size = strlen((char*)buffer); + lfs2_size_t size = strlen((char*)buffer); for (lfs2_off_t j = 0; j < startsizes[i]; j += size) { - lfs2_file_write(&lfs2, &file[0], buffer, size) => size; + lfs2_file_write(&lfs2, &file, buffer, size) => size; } - lfs2_file_size(&lfs2, &file[0]) => startsizes[i]; + lfs2_file_size(&lfs2, &file) => startsizes[i]; if (startseeks[i] != startsizes[i]) { - lfs2_file_seek(&lfs2, &file[0], + lfs2_file_seek(&lfs2, &file, startseeks[i], LFS2_SEEK_SET) => startseeks[i]; } - lfs2_file_truncate(&lfs2, &file[0], hotsizes[i]) => 0; - lfs2_file_size(&lfs2, &file[0]) => hotsizes[i]; + lfs2_file_truncate(&lfs2, &file, hotsizes[i]) => 0; + lfs2_file_size(&lfs2, &file) => hotsizes[i]; - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_close(&lfs2, &file) => 0; } lfs2_unmount(&lfs2) => 0; TEST -tests/test.py << TEST +scripts/test.py << TEST static const lfs2_off_t startsizes[] = {$STARTSIZES}; static const lfs2_off_t hotsizes[] = {$HOTSIZES}; static const lfs2_off_t coldsizes[] = {$COLDSIZES}; @@ -200,31 +203,31 @@ tests/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; for (unsigned i = 0; i < sizeof(startsizes)/sizeof(startsizes[0]); i++) { - sprintf((char*)buffer, "hairyhead%d", i); - lfs2_file_open(&lfs2, &file[0], (const char*)buffer, LFS2_O_RDWR) => 0; - lfs2_file_size(&lfs2, &file[0]) => hotsizes[i]; + sprintf(path, "hairyhead%d", i); + lfs2_file_open(&lfs2, &file, path, LFS2_O_RDWR) => 0; + lfs2_file_size(&lfs2, &file) => hotsizes[i]; - size = strlen("hair"); + lfs2_size_t size = strlen("hair"); lfs2_off_t j = 0; for (; j < startsizes[i] && j < hotsizes[i]; j += size) { - lfs2_file_read(&lfs2, &file[0], buffer, size) => size; + lfs2_file_read(&lfs2, &file, buffer, size) => size; memcmp(buffer, "hair", size) => 0; } for (; j < hotsizes[i]; j += size) { - lfs2_file_read(&lfs2, &file[0], buffer, size) => size; + lfs2_file_read(&lfs2, &file, buffer, size) => size; memcmp(buffer, "\0\0\0\0", size) => 0; } - lfs2_file_truncate(&lfs2, &file[0], coldsizes[i]) => 0; - lfs2_file_size(&lfs2, &file[0]) => coldsizes[i]; + lfs2_file_truncate(&lfs2, &file, coldsizes[i]) => 0; + lfs2_file_size(&lfs2, &file) => coldsizes[i]; - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_close(&lfs2, &file) => 0; } lfs2_unmount(&lfs2) => 0; TEST -tests/test.py << TEST +scripts/test.py << TEST static const lfs2_off_t startsizes[] = {$STARTSIZES}; static const lfs2_off_t hotsizes[] = {$HOTSIZES}; static const lfs2_off_t coldsizes[] = {$COLDSIZES}; @@ -232,24 +235,24 @@ tests/test.py << TEST lfs2_mount(&lfs2, &cfg) => 0; for (unsigned i = 0; i < sizeof(startsizes)/sizeof(startsizes[0]); i++) { - sprintf((char*)buffer, "hairyhead%d", i); - lfs2_file_open(&lfs2, &file[0], (const char*)buffer, LFS2_O_RDONLY) => 0; - lfs2_file_size(&lfs2, &file[0]) => coldsizes[i]; + sprintf(path, "hairyhead%d", i); + lfs2_file_open(&lfs2, &file, path, LFS2_O_RDONLY) => 0; + lfs2_file_size(&lfs2, &file) => coldsizes[i]; - size = strlen("hair"); + lfs2_size_t size = strlen("hair"); lfs2_off_t j = 0; for (; j < startsizes[i] && j < hotsizes[i] && j < coldsizes[i]; j += size) { - lfs2_file_read(&lfs2, &file[0], buffer, size) => size; + lfs2_file_read(&lfs2, &file, buffer, size) => size; memcmp(buffer, "hair", size) => 0; } for (; j < coldsizes[i]; j += size) { - lfs2_file_read(&lfs2, &file[0], buffer, size) => size; + lfs2_file_read(&lfs2, &file, buffer, size) => size; memcmp(buffer, "\0\0\0\0", size) => 0; } - lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_file_close(&lfs2, &file) => 0; } lfs2_unmount(&lfs2) => 0; @@ -298,5 +301,4 @@ truncate_test \ "2*$LARGESIZE, 2*$LARGESIZE, 2*$LARGESIZE, 2*$LARGESIZE, 2*$LARGESIZE" \ "2*$LARGESIZE, 2*$LARGESIZE, 2*$LARGESIZE, 2*$LARGESIZE, 2*$LARGESIZE" -echo "--- Results ---" -tests/stats.py +scripts/results.py