// /************************************************************************************************** * IOWOW library * * MIT License * * Copyright (c) 2012-2020 Softmotions Ltd * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. *************************************************************************************************/ #include "iowow.h" #include "log/iwlog.h" #include "fs/iwexfile.h" #include "utils/iwutils.h" #include "iwcfg.h" #include #include #define UNLINK() \ unlink("iwfs_exfile_test1.dat"); \ unlink("iwfs_exfile_test1_2.dat"); \ unlink("test_mmap1.dat"); \ unlink("test_fibo_inc.dat") int init_suite() { int rc = iw_init(); UNLINK(); return rc; } int clean_suite() { UNLINK(); return 0; } void iwfs_exfile_test1() { iwrc rc = 0; IWFS_EXT ef; const char *path = "iwfs_exfile_test1.dat"; IWFS_EXT_OPTS opts = { .file = { .path = path, .lock_mode = IWP_WLOCK, .omode = IWFS_DEFAULT_OMODE | IWFS_OTRUNC }, .use_locks = 1 }; IWRC(iwfs_exfile_open(&ef, &opts), rc); CU_ASSERT_EQUAL_FATAL(rc, 0); char data[] = "b069a540-bc92-49ba-95e9-d1a2ee9e8c8f"; size_t sp, sp2; // iwrc(*write)(struct IWFS_EXT* f, off_t off, const void *buf, size_t siz, // size_t *sp); IWRC(ef.write(&ef, 0, 0, 0, &sp), rc); CU_ASSERT_EQUAL_FATAL(rc, 0); CU_ASSERT_EQUAL(sp, 0); IWRC(ef.write(&ef, 1, 0, 0, &sp), rc); CU_ASSERT_EQUAL_FATAL(rc, 0); IWP_FILE_STAT fstat; IWRC(iwp_fstat(path, &fstat), rc); CU_ASSERT_EQUAL_FATAL(rc, 0); CU_ASSERT_EQUAL(sp, 0); CU_ASSERT_EQUAL(fstat.size, iwp_alloc_unit()); IWRC(ef.write(&ef, 1, data, sizeof(data), &sp), rc); CU_ASSERT_EQUAL_FATAL(rc, 0); CU_ASSERT_EQUAL(sp, 37); IWRC(ef.close(&ef), rc); CU_ASSERT_EQUAL(rc, 0); // Now reopen the file opts.file.omode = IWFS_OREAD; IWRC(iwfs_exfile_open(&ef, &opts), rc); CU_ASSERT_EQUAL_FATAL(rc, 0); char rdata[37]; // iwrc(*read)(struct IWFS_EXT* f, off_t off, void *buf, size_t siz, size_t // *sp); IWRC(ef.read(&ef, 1, rdata, sp, &sp2), rc); CU_ASSERT_EQUAL_FATAL(rc, 0); CU_ASSERT_EQUAL(sp, sp2); CU_ASSERT_FALSE(strncmp(rdata, data, sizeof(data))); rc = ef.write(&ef, 1, data, sizeof(data), &sp); CU_ASSERT_EQUAL(IW_ERROR_READONLY, rc); size_t ps = iwp_alloc_unit(); rc = 0; IWRC(ef.read(&ef, ps - 1, rdata, 2, &sp2), rc); CU_ASSERT_EQUAL_FATAL(rc, 0); CU_ASSERT_EQUAL(sp2, 1); IWRC(ef.close(&ef), rc); CU_ASSERT_EQUAL(rc, 0); } void iwfs_exfile_test1_2() { iwrc rc = 0; IWFS_EXT f; const char *path = "exfile_test1_2-"; // Temp file prefix IWFS_EXT_OPTS opts = { .file = { .path = path, .omode = IWFS_OTMP | IWFS_OUNLINK } }; rc = iwfs_exfile_open(&f, &opts); CU_ASSERT_EQUAL_FATAL(rc, 0); IWFS_EXT_STATE state; rc = f.state(&f, &state); CU_ASSERT_EQUAL_FATAL(rc, 0); char *tpath = strdup(state.file.opts.path); fprintf(stderr, "\nTmp file: %s\n", tpath); IWP_FILE_STAT fstat; rc = iwp_fstat(tpath, &fstat); CU_ASSERT_EQUAL_FATAL(rc, 0); rc = f.close(&f); CU_ASSERT_EQUAL_FATAL(rc, 0); memset(&fstat, 0, sizeof(fstat)); rc = iwp_fstat(tpath, &fstat); CU_ASSERT_EQUAL_FATAL(rc, IW_ERROR_NOT_EXISTS); free(tpath); } void test_fibo_inc(void) { const char *path = "test_fibo_inc.dat"; IWFS_EXT ef; IWFS_EXT_OPTS opts = { .file = { .path = path, .lock_mode = IWP_WLOCK, .omode = IWFS_DEFAULT_OMODE | IWFS_OTRUNC }, .use_locks = 0, .rspolicy = iw_exfile_szpolicy_fibo }; iwrc rc = 0; size_t sp; uint64_t wd = (uint64_t)(-1); IWRC(iwfs_exfile_open(&ef, &opts), rc); CU_ASSERT_EQUAL_FATAL(rc, 0); // iwrc(*write)(struct IWFS_EXT* f, off_t off, const void *buf, size_t siz, // size_t *sp); IWRC(ef.write(&ef, 0, &wd, 1, &sp), rc); CU_ASSERT_EQUAL_FATAL(rc, 0); size_t psize = iwp_alloc_unit(); IWP_FILE_STAT fstat; IWRC(iwp_fstat(path, &fstat), rc); CU_ASSERT_EQUAL_FATAL(rc, 0); CU_ASSERT_EQUAL_FATAL(fstat.size, psize); IWRC(ef.write(&ef, fstat.size, &wd, 1, &sp), rc); CU_ASSERT_EQUAL_FATAL(rc, 0); IWRC(iwp_fstat(path, &fstat), rc); CU_ASSERT_EQUAL_FATAL(rc, 0); CU_ASSERT_EQUAL_FATAL(fstat.size, 2 * psize); IWRC(ef.write(&ef, fstat.size, &wd, 1, &sp), rc); CU_ASSERT_EQUAL_FATAL(rc, 0); IWRC(iwp_fstat(path, &fstat), rc); CU_ASSERT_EQUAL_FATAL(rc, 0); CU_ASSERT_EQUAL_FATAL(fstat.size, 3 * psize); IWRC(ef.write(&ef, fstat.size, &wd, 1, &sp), rc); CU_ASSERT_EQUAL_FATAL(rc, 0); IWRC(iwp_fstat(path, &fstat), rc); CU_ASSERT_EQUAL_FATAL(rc, 0); CU_ASSERT_EQUAL_FATAL(fstat.size, 5 * psize); IWRC(ef.close(&ef), rc); CU_ASSERT_EQUAL(rc, 0); } void test_mmap1(void) { iwrc rc = 0; size_t psize = iwp_alloc_unit(); size_t sp; const int dsize = psize * 4; uint8_t *data = malloc(dsize); uint8_t *cdata = malloc(dsize); const char *path = "test_mmap1.dat"; IWFS_EXT ef; IWFS_EXT_OPTS opts = {.file = {.path = path, .omode = IWFS_OTRUNC}, .use_locks = 0}; for (int i = 0; i < dsize; ++i) { data[i] = iwu_rand_range(256); } rc = iwfs_exfile_open(&ef, &opts); CU_ASSERT_EQUAL_FATAL(rc, 0); rc = ef.add_mmap(&ef, 2 * psize, psize, 0); CU_ASSERT_EQUAL_FATAL(rc, 0); rc = ef.add_mmap(&ef, psize, psize, 0); CU_ASSERT_EQUAL_FATAL(rc, 0); rc = ef.add_mmap(&ef, 0, psize, 0); CU_ASSERT_EQUAL_FATAL(rc, 0); rc = ef.add_mmap(&ef, psize, 2 * psize, 0); CU_ASSERT_EQUAL_FATAL(rc, IWFS_ERROR_MMAP_OVERLAP); #ifndef IW_32 rc = ef.add_mmap(&ef, 3 * psize, UINT64_MAX, 0); CU_ASSERT_EQUAL_FATAL(rc, 0); #else rc = ef.add_mmap(&ef, 3 * psize, UINT32_MAX >> 1, 0); CU_ASSERT_EQUAL_FATAL(rc, 0); #endif rc = ef.write(&ef, psize / 2, data, psize, &sp); CU_ASSERT_EQUAL_FATAL(rc, 0); CU_ASSERT_EQUAL_FATAL(sp, psize); rc = ef.read(&ef, psize / 2, cdata, psize, &sp); CU_ASSERT_EQUAL_FATAL(rc, 0); CU_ASSERT_EQUAL_FATAL(sp, psize); CU_ASSERT_EQUAL_FATAL(memcmp(data, cdata, psize), 0); for (int i = 0; i < dsize; ++i) { data[i] = iwu_rand_range(256); } // iwrc(*remove_mmap)(struct IWFS_EXT* f, off_t off); rc = ef.remove_mmap(&ef, psize); CU_ASSERT_EQUAL_FATAL(rc, 0); rc = ef.write(&ef, psize / 2, data, psize, &sp); CU_ASSERT_EQUAL_FATAL(rc, 0); CU_ASSERT_EQUAL_FATAL(psize, sp); rc = ef.read(&ef, psize / 2, cdata, psize, &sp); CU_ASSERT_EQUAL_FATAL(rc, 0); CU_ASSERT_EQUAL_FATAL(psize, sp); CU_ASSERT_EQUAL_FATAL(memcmp(data, cdata, psize), 0); for (int i = 0; i < 10; ++i) { rc = ef.write(&ef, psize * i, data, dsize, &sp); CU_ASSERT_EQUAL_FATAL(rc, 0); CU_ASSERT_EQUAL_FATAL(dsize, sp); rc = ef.read(&ef, psize * i, cdata, dsize, &sp); CU_ASSERT_EQUAL_FATAL(rc, 0); CU_ASSERT_EQUAL_FATAL(dsize, sp); CU_ASSERT_EQUAL_FATAL(memcmp(data, cdata, psize), 0); } for (int i = 0; i < dsize; ++i) { data[i] = iwu_rand_range(256); } rc = ef.remove_mmap(&ef, 0); CU_ASSERT_EQUAL_FATAL(rc, 0); for (int i = 0; i < 10; ++i) { rc = ef.write(&ef, psize * i, data, dsize, &sp); CU_ASSERT_EQUAL_FATAL(rc, 0); CU_ASSERT_EQUAL_FATAL(dsize, sp); rc = ef.read(&ef, psize * i, cdata, dsize, &sp); CU_ASSERT_EQUAL_FATAL(rc, 0); CU_ASSERT_EQUAL_FATAL(dsize, sp); CU_ASSERT_EQUAL_FATAL(memcmp(data, cdata, psize), 0); } for (int i = 0; i < dsize; ++i) { data[i] = iwu_rand_range(256); } rc = ef.remove_mmap(&ef, 2 * psize); CU_ASSERT_EQUAL_FATAL(rc, 0); for (int i = 0; i < 10; ++i) { rc = ef.write(&ef, psize * i, data, dsize, &sp); CU_ASSERT_EQUAL_FATAL(rc, 0); CU_ASSERT_EQUAL_FATAL(dsize, sp); rc = ef.read(&ef, psize * i, cdata, dsize, &sp); CU_ASSERT_EQUAL_FATAL(rc, 0); CU_ASSERT_EQUAL_FATAL(dsize, sp); CU_ASSERT_EQUAL_FATAL(memcmp(data, cdata, psize), 0); } for (int i = 0; i < dsize; ++i) { data[i] = iwu_rand_range(256); } rc = ef.remove_mmap(&ef, 3 * psize); CU_ASSERT_EQUAL_FATAL(rc, 0); for (int i = 0; i < 10; ++i) { rc = ef.write(&ef, psize * i, data, dsize, &sp); CU_ASSERT_EQUAL_FATAL(rc, 0); CU_ASSERT_EQUAL_FATAL(dsize, sp); rc = ef.read(&ef, psize * i, cdata, dsize, &sp); CU_ASSERT_EQUAL_FATAL(rc, 0); CU_ASSERT_EQUAL_FATAL(dsize, sp); CU_ASSERT_EQUAL_FATAL(memcmp(data, cdata, psize), 0); } IWRC(ef.close(&ef), rc); CU_ASSERT_EQUAL(rc, 0); free(data); free(cdata); } int main() { CU_pSuite pSuite = NULL; /* Initialize the CUnit test registry */ if (CUE_SUCCESS != CU_initialize_registry()) return CU_get_error(); /* Add a suite to the registry */ pSuite = CU_add_suite("iwfs_test1", init_suite, clean_suite); if (NULL == pSuite) { CU_cleanup_registry(); return CU_get_error(); } /* Add the tests to the suite */ if ((NULL == CU_add_test(pSuite, "iwfs_exfile_test1", iwfs_exfile_test1)) || (NULL == CU_add_test(pSuite, "iwfs_exfile_test1_2", iwfs_exfile_test1_2)) || (NULL == CU_add_test(pSuite, "test_fibo_inc", test_fibo_inc)) || (NULL == CU_add_test(pSuite, "test_mmap1", test_mmap1))) { CU_cleanup_registry(); return CU_get_error(); } /* Run all tests using the CUnit Basic interface */ CU_basic_set_mode(CU_BRM_VERBOSE); CU_basic_run_tests(); int ret = CU_get_error() || CU_get_number_of_failures(); CU_cleanup_registry(); return ret; }