• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 /**************************************************************************************************
3  * IOWOW library
4  *
5  * MIT License
6  *
7  * Copyright (c) 2012-2022 Softmotions Ltd <info@softmotions.com>
8  *
9  * Permission is hereby granted, free of charge, to any person obtaining a copy
10  * of this software and associated documentation files (the "Software"), to deal
11  * in the Software without restriction, including without limitation the rights
12  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13  *  copies of the Software, and to permit persons to whom the Software is
14  * furnished to do so, subject to the following conditions:
15  *
16  * The above copyright notice and this permission notice shall be included in all
17  * copies or substantial portions of the Software.
18  *
19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25  * SOFTWARE.
26  *************************************************************************************************/
27 
28 
29 #include "iowow.h"
30 #include "log/iwlog.h"
31 #include "fs/iwexfile.h"
32 #include "utils/iwutils.h"
33 
34 #include "iwcfg.h"
35 #include <CUnit/Basic.h>
36 #include <unistd.h>
37 
38 #define UNLINK() \
39   unlink("iwfs_exfile_test1.dat"); \
40   unlink("iwfs_exfile_test1_2.dat"); \
41   unlink("test_mmap1.dat"); \
42   unlink("test_fibo_inc.dat")
43 
init_suite()44 int init_suite() {
45   int rc = iw_init();
46   UNLINK();
47   return rc;
48 }
49 
clean_suite()50 int clean_suite() {
51   UNLINK();
52   return 0;
53 }
54 
iwfs_exfile_test1()55 void iwfs_exfile_test1() {
56   iwrc rc = 0;
57   IWFS_EXT ef;
58 
59   const char *path = "iwfs_exfile_test1.dat";
60   IWFS_EXT_OPTS opts = {
61     .file        = {
62       .path      = path,
63       .lock_mode = IWP_WLOCK,
64       .omode     = IWFS_DEFAULT_OMODE | IWFS_OTRUNC
65     },
66     .use_locks   = 1
67   };
68   IWRC(iwfs_exfile_open(&ef, &opts), rc);
69   CU_ASSERT_EQUAL_FATAL(rc, 0);
70 
71   char data[] = "b069a540-bc92-49ba-95e9-d1a2ee9e8c8f";
72   size_t sp, sp2;
73 
74   // iwrc(*write)(struct IWFS_EXT* f, off_t off, const void *buf, size_t siz,
75   // size_t *sp);
76   IWRC(ef.write(&ef, 0, 0, 0, &sp), rc);
77   CU_ASSERT_EQUAL_FATAL(rc, 0);
78   CU_ASSERT_EQUAL(sp, 0);
79 
80   IWRC(ef.write(&ef, 1, 0, 0, &sp), rc);
81   CU_ASSERT_EQUAL_FATAL(rc, 0);
82 
83   IWP_FILE_STAT fstat;
84   IWRC(iwp_fstat(path, &fstat), rc);
85   CU_ASSERT_EQUAL_FATAL(rc, 0);
86   CU_ASSERT_EQUAL(sp, 0);
87   CU_ASSERT_EQUAL(fstat.size, iwp_alloc_unit());
88 
89   IWRC(ef.write(&ef, 1, data, sizeof(data), &sp), rc);
90   CU_ASSERT_EQUAL_FATAL(rc, 0);
91   CU_ASSERT_EQUAL(sp, 37);
92 
93   IWRC(ef.close(&ef), rc);
94   CU_ASSERT_EQUAL(rc, 0);
95 
96   // Now reopen the file
97 
98   opts.file.omode = IWFS_OREAD;
99   IWRC(iwfs_exfile_open(&ef, &opts), rc);
100   CU_ASSERT_EQUAL_FATAL(rc, 0);
101 
102   char rdata[37];
103   // iwrc(*read)(struct IWFS_EXT* f, off_t off, void *buf, size_t siz, size_t
104   // *sp);
105   IWRC(ef.read(&ef, 1, rdata, sp, &sp2), rc);
106   CU_ASSERT_EQUAL_FATAL(rc, 0);
107   CU_ASSERT_EQUAL(sp, sp2);
108   CU_ASSERT_FALSE(strncmp(rdata, data, sizeof(data)));
109 
110   rc = ef.write(&ef, 1, data, sizeof(data), &sp);
111   CU_ASSERT_EQUAL(IW_ERROR_READONLY, rc);
112 
113   size_t ps = iwp_alloc_unit();
114   rc = 0;
115   IWRC(ef.read(&ef, ps - 1, rdata, 2, &sp2), rc);
116   CU_ASSERT_EQUAL_FATAL(rc, 0);
117   CU_ASSERT_EQUAL(sp2, 1);
118 
119   IWRC(ef.close(&ef), rc);
120   CU_ASSERT_EQUAL(rc, 0);
121 }
122 
iwfs_exfile_test1_2()123 void iwfs_exfile_test1_2() {
124   iwrc rc = 0;
125   IWFS_EXT f;
126   const char *path = "exfile_test1_2-"; // Temp file prefix
127   IWFS_EXT_OPTS opts = {
128     .file    = {
129       .path  = path,
130       .omode = IWFS_OTMP | IWFS_OUNLINK
131     }
132   };
133   rc = iwfs_exfile_open(&f, &opts);
134   CU_ASSERT_EQUAL_FATAL(rc, 0);
135 
136   IWFS_EXT_STATE state;
137   rc = f.state(&f, &state);
138   CU_ASSERT_EQUAL_FATAL(rc, 0);
139 
140   char *tpath = strdup(state.file.opts.path);
141   fprintf(stderr, "\nTmp file: %s\n", tpath);
142 
143   IWP_FILE_STAT fstat;
144   rc = iwp_fstat(tpath, &fstat);
145   CU_ASSERT_EQUAL_FATAL(rc, 0);
146 
147   rc = f.close(&f);
148   CU_ASSERT_EQUAL_FATAL(rc, 0);
149 
150   memset(&fstat, 0, sizeof(fstat));
151   rc = iwp_fstat(tpath, &fstat);
152   CU_ASSERT_EQUAL_FATAL(rc, IW_ERROR_NOT_EXISTS);
153 
154   free(tpath);
155 }
156 
test_fibo_inc(void)157 void test_fibo_inc(void) {
158   const char *path = "test_fibo_inc.dat";
159   IWFS_EXT ef;
160   IWFS_EXT_OPTS opts = {
161     .file        = {
162       .path      = path,
163       .lock_mode = IWP_WLOCK,
164       .omode     = IWFS_DEFAULT_OMODE | IWFS_OTRUNC
165     },
166     .use_locks   = 0,
167     .rspolicy    = iw_exfile_szpolicy_fibo
168   };
169   iwrc rc = 0;
170   size_t sp;
171   uint64_t wd = (uint64_t) (-1);
172 
173   IWRC(iwfs_exfile_open(&ef, &opts), rc);
174   CU_ASSERT_EQUAL_FATAL(rc, 0);
175 
176   // iwrc(*write)(struct IWFS_EXT* f, off_t off, const void *buf, size_t siz,
177   // size_t *sp);
178   IWRC(ef.write(&ef, 0, &wd, 1, &sp), rc);
179   CU_ASSERT_EQUAL_FATAL(rc, 0);
180 
181   size_t psize = iwp_alloc_unit();
182   IWP_FILE_STAT fstat;
183   IWRC(iwp_fstat(path, &fstat), rc);
184   CU_ASSERT_EQUAL_FATAL(rc, 0);
185   CU_ASSERT_EQUAL_FATAL(fstat.size, psize);
186 
187   IWRC(ef.write(&ef, fstat.size, &wd, 1, &sp), rc);
188   CU_ASSERT_EQUAL_FATAL(rc, 0);
189 
190   IWRC(iwp_fstat(path, &fstat), rc);
191   CU_ASSERT_EQUAL_FATAL(rc, 0);
192   CU_ASSERT_EQUAL_FATAL(fstat.size, 2 * psize);
193 
194   IWRC(ef.write(&ef, fstat.size, &wd, 1, &sp), rc);
195   CU_ASSERT_EQUAL_FATAL(rc, 0);
196 
197   IWRC(iwp_fstat(path, &fstat), rc);
198   CU_ASSERT_EQUAL_FATAL(rc, 0);
199   CU_ASSERT_EQUAL_FATAL(fstat.size, 3 * psize);
200 
201   IWRC(ef.write(&ef, fstat.size, &wd, 1, &sp), rc);
202   CU_ASSERT_EQUAL_FATAL(rc, 0);
203 
204   IWRC(iwp_fstat(path, &fstat), rc);
205   CU_ASSERT_EQUAL_FATAL(rc, 0);
206   CU_ASSERT_EQUAL_FATAL(fstat.size, 5 * psize);
207 
208   IWRC(ef.close(&ef), rc);
209   CU_ASSERT_EQUAL(rc, 0);
210 }
211 
test_mmap1(void)212 void test_mmap1(void) {
213   iwrc rc = 0;
214   size_t psize = iwp_alloc_unit();
215   size_t sp;
216   const int dsize = psize * 4;
217   uint8_t *data = malloc(dsize);
218   uint8_t *cdata = malloc(dsize);
219 
220   const char *path = "test_mmap1.dat";
221   IWFS_EXT ef;
222   IWFS_EXT_OPTS opts = { .file = { .path = path, .omode = IWFS_OTRUNC }, .use_locks = 0 };
223 
224   for (int i = 0; i < dsize; ++i) {
225     data[i] = iwu_rand_range(256);
226   }
227   rc = iwfs_exfile_open(&ef, &opts);
228   CU_ASSERT_EQUAL_FATAL(rc, 0);
229 
230   rc = ef.add_mmap(&ef, 2 * psize, psize, 0);
231   CU_ASSERT_EQUAL_FATAL(rc, 0);
232 
233   rc = ef.add_mmap(&ef, psize, psize, 0);
234   CU_ASSERT_EQUAL_FATAL(rc, 0);
235 
236   rc = ef.add_mmap(&ef, 0, psize, 0);
237   CU_ASSERT_EQUAL_FATAL(rc, 0);
238 
239   rc = ef.add_mmap(&ef, psize, 2 * psize, 0);
240   CU_ASSERT_EQUAL_FATAL(rc, IWFS_ERROR_MMAP_OVERLAP);
241 
242 #ifndef IW_32
243   rc = ef.add_mmap(&ef, 3 * psize, UINT64_MAX, 0);
244   CU_ASSERT_EQUAL_FATAL(rc, 0);
245 #else
246   rc = ef.add_mmap(&ef, 3 * psize, UINT32_MAX >> 1, 0);
247   CU_ASSERT_EQUAL_FATAL(rc, 0);
248 #endif
249 
250   rc = ef.write(&ef, psize / 2, data, psize, &sp);
251   CU_ASSERT_EQUAL_FATAL(rc, 0);
252   CU_ASSERT_EQUAL_FATAL(sp, psize);
253 
254   rc = ef.read(&ef, psize / 2, cdata, psize, &sp);
255   CU_ASSERT_EQUAL_FATAL(rc, 0);
256   CU_ASSERT_EQUAL_FATAL(sp, psize);
257   CU_ASSERT_EQUAL_FATAL(memcmp(data, cdata, psize), 0);
258 
259   for (int i = 0; i < dsize; ++i) {
260     data[i] = iwu_rand_range(256);
261   }
262 
263   // iwrc(*remove_mmap)(struct IWFS_EXT* f, off_t off);
264   rc = ef.remove_mmap(&ef, psize);
265   CU_ASSERT_EQUAL_FATAL(rc, 0);
266   rc = ef.write(&ef, psize / 2, data, psize, &sp);
267   CU_ASSERT_EQUAL_FATAL(rc, 0);
268   CU_ASSERT_EQUAL_FATAL(psize, sp);
269 
270   rc = ef.read(&ef, psize / 2, cdata, psize, &sp);
271   CU_ASSERT_EQUAL_FATAL(rc, 0);
272   CU_ASSERT_EQUAL_FATAL(psize, sp);
273   CU_ASSERT_EQUAL_FATAL(memcmp(data, cdata, psize), 0);
274 
275   for (int i = 0; i < 10; ++i) {
276     rc = ef.write(&ef, psize * i, data, dsize, &sp);
277     CU_ASSERT_EQUAL_FATAL(rc, 0);
278     CU_ASSERT_EQUAL_FATAL(dsize, sp);
279 
280     rc = ef.read(&ef, psize * i, cdata, dsize, &sp);
281     CU_ASSERT_EQUAL_FATAL(rc, 0);
282     CU_ASSERT_EQUAL_FATAL(dsize, sp);
283     CU_ASSERT_EQUAL_FATAL(memcmp(data, cdata, psize), 0);
284   }
285 
286   for (int i = 0; i < dsize; ++i) {
287     data[i] = iwu_rand_range(256);
288   }
289 
290   rc = ef.remove_mmap(&ef, 0);
291   CU_ASSERT_EQUAL_FATAL(rc, 0);
292   for (int i = 0; i < 10; ++i) {
293     rc = ef.write(&ef, psize * i, data, dsize, &sp);
294     CU_ASSERT_EQUAL_FATAL(rc, 0);
295     CU_ASSERT_EQUAL_FATAL(dsize, sp);
296 
297     rc = ef.read(&ef, psize * i, cdata, dsize, &sp);
298     CU_ASSERT_EQUAL_FATAL(rc, 0);
299     CU_ASSERT_EQUAL_FATAL(dsize, sp);
300     CU_ASSERT_EQUAL_FATAL(memcmp(data, cdata, psize), 0);
301   }
302 
303   for (int i = 0; i < dsize; ++i) {
304     data[i] = iwu_rand_range(256);
305   }
306   rc = ef.remove_mmap(&ef, 2 * psize);
307   CU_ASSERT_EQUAL_FATAL(rc, 0);
308   for (int i = 0; i < 10; ++i) {
309     rc = ef.write(&ef, psize * i, data, dsize, &sp);
310     CU_ASSERT_EQUAL_FATAL(rc, 0);
311     CU_ASSERT_EQUAL_FATAL(dsize, sp);
312 
313     rc = ef.read(&ef, psize * i, cdata, dsize, &sp);
314     CU_ASSERT_EQUAL_FATAL(rc, 0);
315     CU_ASSERT_EQUAL_FATAL(dsize, sp);
316     CU_ASSERT_EQUAL_FATAL(memcmp(data, cdata, psize), 0);
317   }
318 
319   for (int i = 0; i < dsize; ++i) {
320     data[i] = iwu_rand_range(256);
321   }
322   rc = ef.remove_mmap(&ef, 3 * psize);
323   CU_ASSERT_EQUAL_FATAL(rc, 0);
324   for (int i = 0; i < 10; ++i) {
325     rc = ef.write(&ef, psize * i, data, dsize, &sp);
326     CU_ASSERT_EQUAL_FATAL(rc, 0);
327     CU_ASSERT_EQUAL_FATAL(dsize, sp);
328 
329     rc = ef.read(&ef, psize * i, cdata, dsize, &sp);
330     CU_ASSERT_EQUAL_FATAL(rc, 0);
331     CU_ASSERT_EQUAL_FATAL(dsize, sp);
332     CU_ASSERT_EQUAL_FATAL(memcmp(data, cdata, psize), 0);
333   }
334 
335   IWRC(ef.close(&ef), rc);
336   CU_ASSERT_EQUAL(rc, 0);
337 
338   free(data);
339   free(cdata);
340 }
341 
main()342 int main() {
343   CU_pSuite pSuite = NULL;
344 
345   /* Initialize the CUnit test registry */
346   if (CUE_SUCCESS != CU_initialize_registry()) {
347     return CU_get_error();
348   }
349 
350   /* Add a suite to the registry */
351   pSuite = CU_add_suite("iwfs_test1", init_suite, clean_suite);
352 
353   if (NULL == pSuite) {
354     CU_cleanup_registry();
355     return CU_get_error();
356   }
357 
358   /* Add the tests to the suite */
359   if (  (NULL == CU_add_test(pSuite, "iwfs_exfile_test1", iwfs_exfile_test1))
360      || (NULL == CU_add_test(pSuite, "iwfs_exfile_test1_2", iwfs_exfile_test1_2))
361      || (NULL == CU_add_test(pSuite, "test_fibo_inc", test_fibo_inc))
362      || (NULL == CU_add_test(pSuite, "test_mmap1", test_mmap1))) {
363     CU_cleanup_registry();
364     return CU_get_error();
365   }
366 
367   /* Run all tests using the CUnit Basic interface */
368   CU_basic_set_mode(CU_BRM_VERBOSE);
369   CU_basic_run_tests();
370   int ret = CU_get_error() || CU_get_number_of_failures();
371   CU_cleanup_registry();
372   return ret;
373 }
374